From 0389dfcebce3d4234f3254253ba52bb7d7bc51eb Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Wed, 29 Apr 2026 10:44:55 +0100 Subject: [PATCH 01/18] Interim Commit while migrating from FCM branch - XML, namelist and rose-stem changes. --- .../lfric_atm/metadata/axis_def_main.xml | 2 + .../lfric_atm/metadata/field_def_diags.xml | 5 +- .../lfric_atm/metadata/lfric_dictionary.xml | 6 ++ .../file/iodef_gal_nwp_coarse_aero.xml | 1 + .../common/lfric_atm/tasks_lfric_atm.cylc | 24 ++++++ .../site/meto/groups/groups_lfric_atm.cylc | 5 ++ .../lfric-gungho/HEAD/rose-meta.conf | 79 ++++++++++++++++++- 7 files changed, 116 insertions(+), 6 deletions(-) diff --git a/applications/lfric_atm/metadata/axis_def_main.xml b/applications/lfric_atm/metadata/axis_def_main.xml index 2cac976cb..bab29380c 100644 --- a/applications/lfric_atm/metadata/axis_def_main.xml +++ b/applications/lfric_atm/metadata/axis_def_main.xml @@ -34,6 +34,8 @@ + + diff --git a/applications/lfric_atm/metadata/field_def_diags.xml b/applications/lfric_atm/metadata/field_def_diags.xml index a17d884f9..062e65437 100644 --- a/applications/lfric_atm/metadata/field_def_diags.xml +++ b/applications/lfric_atm/metadata/field_def_diags.xml @@ -43,8 +43,9 @@ - - + + + zoomed__orography diff --git a/applications/lfric_atm/metadata/lfric_dictionary.xml b/applications/lfric_atm/metadata/lfric_dictionary.xml index aa5a1efc5..6b713e86b 100644 --- a/applications/lfric_atm/metadata/lfric_dictionary.xml +++ b/applications/lfric_atm/metadata/lfric_dictionary.xml @@ -393,5 +393,11 @@ + + + + + + diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_aero.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_aero.xml index 8eb90dd84..5331afa22 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_aero.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_aero.xml @@ -20,6 +20,7 @@ + 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 a49293d58..7b9ef6dab 100644 --- a/rose-stem/site/common/lfric_atm/tasks_lfric_atm.cylc +++ b/rose-stem/site/common/lfric_atm/tasks_lfric_atm.cylc @@ -284,6 +284,30 @@ "plot_str": "plot_map.py $NODAL_DATA_DIR/lfric_diagnostics.nc $PLOT_DIR", }) %} +{% elif task_ns.conf_name == "nwp_gal9_nudging-era-C48_MG" %} + + {% do task_dict.update({ + "opt_confs": ["nudging-era","um_dump"], + "resolution": "C48_MG", + "DT": 1800, + "tsteps": 12, + "mpi_parts": 24, + "log_level": "debug", + "plot_str": "plot_map.py $NODAL_DATA_DIR/lfric_gal_diagnostics.nc $PLOT_DIR", + }) %} + +{% elif task_ns.conf_name == "nwp_gal9_nudging-era-coarse-C48_MG" %} + + {% do task_dict.update({ + "opt_confs": ["nudging-era-coarse","um_dump"], + "resolution": "C48_MG", + "DT": 1800, + "tsteps": 12, + "mpi_parts": 24, + "log_level": "debug", + "plot_str": "plot_map.py $NODAL_DATA_DIR/lfric_gal_diagnostics.nc $PLOT_DIR", + }) %} + {% elif task_ns.conf_name == "nwp_gal9_coarse_aero_threaded-C48_MG" %} {% do task_dict.update({ diff --git a/rose-stem/site/meto/groups/groups_lfric_atm.cylc b/rose-stem/site/meto/groups/groups_lfric_atm.cylc index ea319d080..53d973c90 100644 --- a/rose-stem/site/meto/groups/groups_lfric_atm.cylc +++ b/rose-stem/site/meto/groups/groups_lfric_atm.cylc @@ -126,6 +126,11 @@ "lfric_atm_nwp_comorph_dev-C12_ex1a_cce_fast-debug-32bit", "lfric_atm_nwp_gal9_mol-C12_ex1a_cce_fast-debug-32bit", ], + "lfric_atm_nudging": [ + "lfric_atm_nwp_gal9_coarse_aero-C48_MG_azspice_gnu_fast-debug-64bit", + "lfric_atm_nwp_gal9_nudging-era-C48_MG_azspice_gnu_fast-debug-64bit", + "lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-64bit", + ], "lfric_atm_nwp_ex1a": [ "lfric_atm_nwp_ex1a_developer", "lfric_atm_nwp_ex1a_extra", diff --git a/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf b/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf index 4380951b7..745a31950 100644 --- a/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf +++ b/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf @@ -1043,14 +1043,19 @@ help=Available forcing options are: = Schneider, T. (2010), Atmospheric Dynamics of Earth-Like Tidally Locked = Aquaplanets, J. Adv. Model. Earth Syst., 2, 13, doi:10.3894/JAMES.2010.2.13. =Temperature tendency profile: apply a specified profile of heating rates + =Nudging: nudges the global spectrum towards that of a specified + = reference state. !kind=default ns=namelist/Science/External Forcing sort-key=A1 trigger=namelist:external_forcing=hs_random: this == "'held_suarez'" ; =namelist:temp_tend_data: this == "'temp_tend'"; =namelist:external_forcing=pc2_force_response: this != "'none'"; -value-titles=None, Held-Suarez, Earth-Like, Tidally Locked Earth, Shallow Hot Jupiter, Deep Hot Jupiter, Temperature Tendency Profile -values='none', 'held_suarez', 'earth_like', 'tidally_locked_earth', 'shallow_hot_jupiter', 'deep_hot_jupiter', 'temp_tend' +value-titles=None, Held-Suarez, Earth-Like, Tidally Locked Earth, + =Shallow Hot Jupiter, Deep Hot Jupiter, Temperature Tendency Profile, + =Nudging +values='none', 'held_suarez', 'earth_like', 'tidally_locked_earth', + ='shallow_hot_jupiter', 'deep_hot_jupiter', 'temp_tend', 'nudging' [namelist:external_forcing=theta_relaxation] compulsory=true @@ -1126,8 +1131,8 @@ trigger=namelist:external_forcing=filtering_order: this == "'filtering'"; =namelist:external_forcing=diffusion_order: this == "'diffusion'"; =namelist:external_forcing=diffusion_coefficient: this == "'diffusion'"; =namelist:wind_forcing: this == "'profile'"; -value-titles=None, Held-Suarez, Filtering, Diffusion, Profile -values='none','held_suarez', 'filtering', 'diffusion', 'profile' +value-titles=None, Held-Suarez, Filtering, Diffusion, Profile, Nudging +values='none','held_suarez', 'filtering', 'diffusion', 'profile', 'nudging' [namelist:files] compulsory=true @@ -1653,6 +1658,22 @@ ns=namelist/Job/IO/Ancils !string_length=filename type=character +[namelist:files=nudging_directory] +compulsory=true +description=Path to nudging directory +help=This directory contains the nudging source file +ns=namelist/Job/IO/Nudging +!string_length=filename +type=character + +[namelist:files=nudging_filename] +compulsory=true +description=Path to lbc file +help=This file contains the nudging source data +ns=namelist/Job/IO/Nudging +!string_length=filename +type=character + [namelist:files=o3_ancil_path] compulsory=true description=Path to O3 (oxidant) file from ancillary files directory @@ -3688,6 +3709,15 @@ help= sort-key=Section-A08 type=logical +[namelist:multires_coupling=coarse_nudging] +compulsory=true +description=Whether to apply nudging on a coarser mesh than that used + =by the dynamical core. +help=The mesh is given by the nudging_mesh_name option. +!kind=default +sort-key=Section-A09 +type=logical + [namelist:multires_coupling=dynamics_mesh_name] compulsory=false description=Tag-name for mesh used by dynamics @@ -3787,6 +3817,47 @@ sort-key=Panel-A07 value-titles=constant, linear values='constant', 'linear' +[namelist:multires_coupling=nudging_mesh_name] +compulsory=false +description=Name of the mesh used for applying nudging. +help= +sort-key=Panel-A09 +!string_length=default +type=character + +#============================================================================== +# NUDGING +#============================================================================== +[namelist:nudging] +compulsory=true +description=Options relating to nudging +ns=namelist/Science/Nudging +sort-key=Section-A14 +title=Nudging + +[namelist:nudging=nudge_data_levels] +compulsory=true +description=Number of levels for the Nudging reference data +help=The number of levels i.e. Z-dimension for the T,U,V reference fields + =to be read from the Nudging input files +!kind=default +ns=namelist/Science/Nudging +sort-key=Panel-A01b +type=integer + +[namelist:nudging=nudging_source] +compulsory=true +description=The source of the reference states for nudging +!enumeration=true +help=Nudging has been implemented to nudge + = (a) using Re-analyses (e.g. ERA) data + = (b) using model (e.g. NWP, M/L) data, or to +!kind=default +ns=namelist/Science/Nudging +sort-key=Panel-A01 +value-titles=ERA, AIFS +values='era', 'aifs' + #============================================================================== # ORBIT #============================================================================== From 388b69ba9eb171866926df103b6584ac10ff6b46 Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Wed, 29 Apr 2026 14:19:18 +0100 Subject: [PATCH 02/18] Second commit transferring changes from FCM: Nudging field and file , time-axis definitions --- .../driver/create_gungho_prognostics_mod.F90 | 8 +- .../gungho/source/driver/create_lbcs_mod.f90 | 8 +- .../driver/create_physics_prognostics_mod.F90 | 152 +++++++++++------- .../gungho/source/driver/field_maker_mod.F90 | 26 ++- .../gungho/source/driver/field_mapper_mod.F90 | 2 + .../gungho/source/driver/field_spec_mod.F90 | 9 +- .../source/driver/gungho_driver_mod.F90 | 42 ++++- .../source/driver/gungho_init_fields_mod.X90 | 51 ++++-- .../gungho/source/driver/gungho_model_mod.F90 | 14 +- .../source/driver/gungho_setup_io_mod.F90 | 18 +++ .../source/driver/gungho_time_axes_mod.f90 | 47 ++++++ .../gungho/source/driver/init_ancils_mod.f90 | 19 ++- .../multidata_field_dimensions_mod.F90 | 8 +- .../source/physics/time_dimensions_mod.F90 | 31 +++- 14 files changed, 321 insertions(+), 114 deletions(-) diff --git a/science/gungho/source/driver/create_gungho_prognostics_mod.F90 b/science/gungho/source/driver/create_gungho_prognostics_mod.F90 index c68673f16..a237a44fc 100644 --- a/science/gungho/source/driver/create_gungho_prognostics_mod.F90 +++ b/science/gungho/source/driver/create_gungho_prognostics_mod.F90 @@ -162,14 +162,10 @@ end subroutine process_gungho_prognostics !> @brief Create empty fields to be used as prognostics by the gungho model !> @param[in] mesh The current 3d mesh !> @param[in] twod_mesh The current 2d mesh - !> @param[in] coarse_mesh The coarse 3d mesh - !> @param[in] coarse_twod_mesh The coarse 2d mesh !> @param[in] mapper Provides access to the field collections !> @param[in] clock The model clock subroutine create_gungho_prognostics(mesh, & twod_mesh, & - coarse_mesh, & - coarse_twod_mesh, & mapper, & clock) @@ -177,8 +173,6 @@ subroutine create_gungho_prognostics(mesh, & type(mesh_type), intent(in), pointer :: mesh type(mesh_type), intent(in), pointer :: twod_mesh - type(mesh_type), intent(in), pointer :: coarse_mesh - type(mesh_type), intent(in), pointer :: coarse_twod_mesh type( field_mapper_type ), intent(in) :: mapper class( clock_type ), intent(in) :: clock @@ -186,7 +180,7 @@ subroutine create_gungho_prognostics(mesh, & call log_event( 'GungHo: Creating prognostics...', LOG_LEVEL_INFO ) - call creator%init(mesh, twod_mesh, coarse_mesh, coarse_twod_mesh, mapper, clock) + call creator%init(mesh, twod_mesh, mapper, clock) call process_gungho_prognostics(creator) diff --git a/science/gungho/source/driver/create_lbcs_mod.f90 b/science/gungho/source/driver/create_lbcs_mod.f90 index fc6f71753..00acaf1af 100644 --- a/science/gungho/source/driver/create_lbcs_mod.f90 +++ b/science/gungho/source/driver/create_lbcs_mod.f90 @@ -140,16 +140,12 @@ end subroutine process_lbc_fields !> limited area model. !> @param[in] mesh The current 3d mesh !> @param[in] twod_mesh The current 2d mesh (not used here) - !> @param[in] coarse_mesh The coarse 3d mesh - !> @param[in] coarse_twod_mesh The coarse 2d mesh !> @param[in] mapper Provides access to the field collections !> @param[in] clock The model clock - subroutine create_lbc_fields(mesh, twod_mesh, coarse_mesh, coarse_twod_mesh, mapper, clock) + subroutine create_lbc_fields(mesh, twod_mesh, mapper, clock) implicit none type(mesh_type), intent(in), pointer :: mesh type(mesh_type), intent(in), pointer :: twod_mesh - type(mesh_type), intent(in), pointer :: coarse_mesh - type(mesh_type), intent(in), pointer :: coarse_twod_mesh type(field_mapper_type), intent(in) :: mapper class(clock_type), intent(in) :: clock @@ -162,7 +158,7 @@ subroutine create_lbc_fields(mesh, twod_mesh, coarse_mesh, coarse_twod_mesh, map gungho_axes => mapper%get_gungho_axes() if (lbc_option /= lbc_option_analytic) call gungho_axes%make_lbc_time_axis() - call creator%init(mesh, twod_mesh, coarse_mesh, coarse_twod_mesh, mapper, clock) + call creator%init(mesh, twod_mesh, mapper, clock) call process_lbc_fields(creator) diff --git a/science/gungho/source/driver/create_physics_prognostics_mod.F90 b/science/gungho/source/driver/create_physics_prognostics_mod.F90 index a7f803c43..3e792dacb 100644 --- a/science/gungho/source/driver/create_physics_prognostics_mod.F90 +++ b/science/gungho/source/driver/create_physics_prognostics_mod.F90 @@ -67,8 +67,15 @@ module create_physics_prognostics_mod use cloud_config_mod, only : scheme, & scheme_pc2 use convection_config_mod, only : cv_scheme, cv_scheme_comorph + use external_forcing_config_mod, only : theta_forcing_nudging, & + theta_forcing, & + wind_forcing_nudging, & + wind_forcing use microphysics_config_mod, only : microphysics_casim - use multires_coupling_config_mod, only : coarse_rad_aerosol + use multires_coupling_config_mod, only : coarse_rad_aerosol, & + coarse_nudging, & + aerosol_mesh_name, & + nudging_mesh_name use jules_surface_config_mod, only : srf_ex_cnv_gust, l_vary_z0m_soil, & l_urban2t @@ -154,6 +161,7 @@ subroutine process_physics_prognostics(processor) logical(l_def) :: is_rad ! Flag for chemistry fields ! that are radiatively active logical(l_def) :: sst_pert_flag + character(len=str_def) :: mesh_name #endif class(clock_type), pointer :: clock @@ -192,6 +200,14 @@ subroutine process_physics_prognostics(processor) end if + if ( theta_forcing == theta_forcing_nudging ) then + call processor%apply(make_spec( & + 'theta_nudging_ref', main%derived, Wtheta, & + coarse=coarse_nudging, & + coarse_mesh_name=nudging_mesh_name & + )) + end if + ! W3 fields call processor%apply(make_spec('u_in_w3', main%derived, W3)) call processor%apply(make_spec('v_in_w3', main%derived, W3)) @@ -208,6 +224,19 @@ subroutine process_physics_prognostics(processor) end if + if ( wind_forcing == wind_forcing_nudging ) then + call processor%apply(make_spec( & + 'u_in_w3_nudging_ref', main%derived, W3, & + coarse=coarse_nudging, & + coarse_mesh_name=nudging_mesh_name & + )) + call processor%apply(make_spec( & + 'v_in_w3_nudging_ref', main%derived, W3, & + coarse=coarse_nudging, & + coarse_mesh_name=nudging_mesh_name & + )) + end if + ! W2 fields call processor%apply(make_spec('u_physics', main%derived, W2)) call processor%apply(make_spec('u_star', main%derived, W2)) @@ -1641,57 +1670,63 @@ subroutine process_physics_prognostics(processor) end if + if (coarse_rad_aerosol) then + mesh_name = aerosol_mesh_name + else + mesh_name = '' + end if + ! Aitken soluble mode number mixing ratio call processor%apply(make_spec('n_ait_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Aitken soluble H2SO4 aerosol mmr call processor%apply(make_spec('ait_sol_su', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Aitken soluble black carbon aerosol mmr call processor%apply(make_spec('ait_sol_bc', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Aitken soluble organic carbon aerosol mmr call processor%apply(make_spec('ait_sol_om', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Accumulation soluble mode number mixing ratio call processor%apply(make_spec('n_acc_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Accumulation soluble H2SO4 aerosol mmr call processor%apply(make_spec('acc_sol_su', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Accumulation soluble black carbon aerosol mmr call processor%apply(make_spec('acc_sol_bc', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Accumulation soluble organic carbon aerosol mmr call processor%apply(make_spec('acc_sol_om', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Accumulation soluble sea salt aerosol mmr call processor%apply(make_spec('acc_sol_ss', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Coarse soluble mode number mixing ratio call processor%apply(make_spec('n_cor_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Coarse soluble H2SO4 aerosol mmr call processor%apply(make_spec('cor_sol_su', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Coarse soluble black carbon aerosol mmr call processor%apply(make_spec('cor_sol_bc', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Coarse soluble organic carbon aerosol mmr call processor%apply(make_spec('cor_sol_om', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Coarse soluble sea salt aerosol mmr call processor%apply(make_spec('cor_sol_ss', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Aitken insoluble mode number mixing ratio call processor%apply(make_spec('n_ait_ins', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Aitken insoluble black carbon aerosol mmr call processor%apply(make_spec('ait_ins_bc', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Aitken insoluble organic carbon aerosol mmr call processor%apply(make_spec('ait_ins_om', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), ckp=checkpoint_flag)) ! Accumulation insoluble mode number mixing ratio call processor%apply(make_spec('n_acc_ins', main%aerosol, Wtheta, coarse=.false., & adv_coll=if_adv(advection_flag_dust, adv%last_con), ckp=checkpoint_flag)) @@ -1717,105 +1752,112 @@ subroutine process_physics_prognostics(processor) ckp=checkpoint_flag)) if (aerosol == aerosol_um) then + + if (coarse_rad_aerosol) then + mesh_name = aerosol_mesh_name + else + mesh_name = '' + end if + ! Dry diameter Aitken mode (Soluble) call processor%apply(make_spec('drydp_ait_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Dry diameter Accumulation mode (Soluble) call processor%apply(make_spec('drydp_acc_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Dry diameter Coarse mode (Soluble) call processor%apply(make_spec('drydp_cor_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Dry diameter Aitken mode (Insoluble) call processor%apply(make_spec('drydp_ait_ins', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Dry diameter Accumulation mode (Insoluble) call processor%apply(make_spec('drydp_acc_ins', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Dry diameter Coarse mode (Insoluble) call processor%apply(make_spec('drydp_cor_ins', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Wet diameter Aitken mode (Soluble) call processor%apply(make_spec('wetdp_ait_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Wet diameter Accumulation mode (Soluble) call processor%apply(make_spec('wetdp_acc_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Wet diameter Coarse mode (Soluble) call processor%apply(make_spec('wetdp_cor_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Particle density Aitken mode (Soluble) call processor%apply(make_spec('rhopar_ait_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Particle density Accumulation mode (Soluble) call processor%apply(make_spec('rhopar_acc_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Particle density Coarse mode (Soluble) call processor%apply(make_spec('rhopar_cor_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Particle density Aitken mode (Insoluble) call processor%apply(make_spec('rhopar_ait_ins', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Particle density Accumulation mode (Insoluble) call processor%apply(make_spec('rhopar_acc_ins', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Particle density Coarse mode (Insoluble) call processor%apply(make_spec('rhopar_cor_ins', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume of water Aitken mode (Soluble) call processor%apply(make_spec('pvol_wat_ait_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume of water Accumulation mode (Soluble) call processor%apply(make_spec('pvol_wat_acc_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume of water Coarse mode (Soluble) call processor%apply(make_spec('pvol_wat_cor_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Sulphate Aitken mode (Soluble) call processor%apply(make_spec('pvol_su_ait_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Black Carbon Aitken mode (Soluble) call processor%apply(make_spec('pvol_bc_ait_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Organic Matter Aitken mode (Soluble) call processor%apply(make_spec('pvol_om_ait_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Sulphate Accumulation mode (Soluble) call processor%apply(make_spec('pvol_su_acc_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Black Carbon Accumulation mode (Soluble) call processor%apply(make_spec('pvol_bc_acc_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Organic Matter Accumulation mode (Soluble) call processor%apply(make_spec('pvol_om_acc_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Sea Salt Accumulation mode (Soluble) call processor%apply(make_spec('pvol_ss_acc_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Sulphate Coarse mode (Soluble) call processor%apply(make_spec('pvol_su_cor_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Black Carbon Coarse mode (Soluble) call processor%apply(make_spec('pvol_bc_cor_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Organic Matter Coarse mode (Soluble) call processor%apply(make_spec('pvol_om_cor_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Sea Salt Coarse mode (Soluble) call processor%apply(make_spec('pvol_ss_cor_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Black Carbon Aitken mode (Insoluble) call processor%apply(make_spec('pvol_bc_ait_ins', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Organic Matter Aitken mode (Insoluble) call processor%apply(make_spec('pvol_om_ait_ins', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Dust Accumulation mode (Insoluble) call processor%apply(make_spec('pvol_du_acc_ins', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Dust Coarse mode (Insoluble) call processor%apply(make_spec('pvol_du_cor_ins', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - ckp=checkpoint_flag)) + coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) end if ! Fields on dust space, might need checkpointing @@ -1907,22 +1949,16 @@ end subroutine process_physics_prognostics !>@brief Routine to initialise the field objects required by the physics !> @param[in] mesh The current 3d mesh !> @param[in] twod_mesh The current 2d mesh - !> @param[in] coarse_mesh The coarse 3d mesh - !> @param[in] coarse_twod_mesh The coarse 2d mesh !> @param[in] field_mapper Provides access to the field collections !> @param[in] clock Model clock subroutine create_physics_prognostics( mesh, & twod_mesh, & - coarse_mesh, & - coarse_twod_mesh, & field_mapper, & clock ) implicit none type( mesh_type ), intent(in), pointer :: mesh type( mesh_type ), intent(in), pointer :: twod_mesh - type( mesh_type ), intent(in), pointer :: coarse_mesh - type( mesh_type ), intent(in), pointer :: coarse_twod_mesh type( field_mapper_type ), intent(in) :: field_mapper class( clock_type ), intent(in) :: clock @@ -1930,7 +1966,7 @@ subroutine create_physics_prognostics( mesh, & call log_event( 'Create physics prognostics', LOG_LEVEL_INFO ) - call creator%init(mesh, twod_mesh, coarse_mesh, coarse_twod_mesh, field_mapper, clock) + call creator%init(mesh, twod_mesh, field_mapper, clock) call field_mapper%sanity_check() diff --git a/science/gungho/source/driver/field_maker_mod.F90 b/science/gungho/source/driver/field_maker_mod.F90 index a468e8335..c83ece54e 100644 --- a/science/gungho/source/driver/field_maker_mod.F90 +++ b/science/gungho/source/driver/field_maker_mod.F90 @@ -11,6 +11,7 @@ module field_maker_mod use constants_mod, only : i_def, l_def, str_def, r_def, & r_second + use extrusion_mod, only : TWOD use log_mod, only : log_event, log_scratch_space, & log_level_error use field_mod, only : field_type @@ -25,6 +26,7 @@ module field_maker_mod use function_space_mod, only : function_space_type use function_space_collection_mod, only : function_space_collection use mesh_mod, only : mesh_type + use mesh_collection_mod, only : mesh_collection use clock_mod, only : clock_type use model_clock_mod, only : model_clock_type use field_spec_mod, only : main_coll_dict, & @@ -64,8 +66,6 @@ module field_maker_mod type, extends(processor_type) :: field_maker_type type(mesh_type), pointer :: mesh type(mesh_type), pointer :: twod_mesh - type(mesh_type), pointer :: coarse_mesh - type(mesh_type), pointer :: coarse_twod_mesh type(field_mapper_type), pointer :: mapper contains private @@ -101,26 +101,19 @@ end function has_xios_io !> @param[inout] self Field maker object !> @param[in] mesh Mesh for spatial fields !> @param[in] twod_mesh Mesh for planar fields - !> @param[in] coarse_mesh Coarse mesh for spatial fields - !> @param[in] coarse_twod_mesh Coarse mesh for planar fields !> @param[in] mapper Provides access to field collections !> @param[in] clock Model clock - subroutine field_maker_init(self, mesh, twod_mesh, coarse_mesh, coarse_twod_mesh, & - mapper, clock) + subroutine field_maker_init(self, mesh, twod_mesh, mapper, clock) implicit none class(field_maker_type), intent(inout) :: self type(mesh_type), intent(in), pointer :: mesh type(mesh_type), intent(in), pointer :: twod_mesh - type(mesh_type), intent(in), pointer :: coarse_mesh - type(mesh_type), intent(in), pointer :: coarse_twod_mesh type(field_mapper_type), target, intent(in) :: mapper class(clock_type), intent(in) :: clock self%mesh => mesh self%twod_mesh => twod_mesh - self%coarse_mesh => coarse_mesh - self%coarse_twod_mesh => coarse_twod_mesh self%mapper => mapper call self%set_clock(clock) end subroutine field_maker_init @@ -145,6 +138,8 @@ subroutine field_maker_apply(self, spec) type(field_collection_type), pointer :: depository => null() type(field_collection_type), pointer :: prognostic_fields => null() type(function_space_type), pointer :: space => null() + type(mesh_type), pointer :: mesh => null() + type(mesh_type), pointer :: twod_mesh => null() type(field_type), pointer :: external_real_field => null() type(time_axis_type), pointer :: time_axis => null() type(integer_field_type), pointer :: external_int_field => null() @@ -177,11 +172,13 @@ subroutine field_maker_apply(self, spec) end if else if (spec%coarse) then + mesh => mesh_collection%get_mesh(spec%mesh_name) if (spec%twod) then - space => function_space_collection%get_fs(self%coarse_twod_mesh, spec%order_h, & + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) + space => function_space_collection%get_fs(twod_mesh, spec%order_h, & spec%order_v, spec%space, ndata) else - space => function_space_collection%get_fs(self%coarse_mesh, spec%order_h, & + space => function_space_collection%get_fs(mesh, spec%order_h, & spec%order_v, spec%space, ndata) end if else @@ -361,14 +358,14 @@ subroutine add_real_field(field_collection, & ! pre-initialise field with window size, add to time axis; ! cf. init_time_axis_mod / setup_field if (associated(vector_space)) then - ! re-create function space, overriding ndata with window size + ! re-create function space, combining ndata with window size window_size_space => & function_space_collection%get_fs( & vector_space%get_mesh(), & vector_space%get_element_order_h(), & vector_space%get_element_order_v(), & vector_space%which(), & - time_axis%get_window_size()) + vector_space%get_ndata() * time_axis%get_window_size()) if (empty) then call new_field_ptr%initialise( window_size_space, name=trim(name), & override_data = empty_real_data ) @@ -376,6 +373,7 @@ subroutine add_real_field(field_collection, & call new_field_ptr%initialise( window_size_space, name=trim(name) ) end if else + ! discover space, overriding ndata with window size call init_field_from_metadata( & new_field_ptr, trim(name), force_order_h=order_h, force_order_v=order_v,& diff --git a/science/gungho/source/driver/field_mapper_mod.F90 b/science/gungho/source/driver/field_mapper_mod.F90 index 8cec69f3d..7a4b50f56 100644 --- a/science/gungho/source/driver/field_mapper_mod.F90 +++ b/science/gungho/source/driver/field_mapper_mod.F90 @@ -384,6 +384,8 @@ function get_time_axis_ptr(self, time_axis) result(axis) axis => self%gungho_axes%lbc_time_axis case (time_axis_dict%ls) axis => self%gungho_axes%lbc_time_axis + case (time_axis_dict%nudging) + axis => self%gungho_axes%nudging_time_axis case (time_axis_dict%none) axis => null() case default diff --git a/science/gungho/source/driver/field_spec_mod.F90 b/science/gungho/source/driver/field_spec_mod.F90 index 48b8eef02..1140494ac 100644 --- a/science/gungho/source/driver/field_spec_mod.F90 +++ b/science/gungho/source/driver/field_spec_mod.F90 @@ -71,11 +71,12 @@ module field_spec_mod integer(i_def) :: none ! field without time axis integer(i_def) :: lbc ! lbc time axis integer(i_def) :: ls ! ls time axis + integer(i_def) :: nudging ! nudging time axis end type time_axis_dict_type !> @brief Map moisture array enumerators to moisture array. type(time_axis_dict_type), parameter :: time_axis_dict & - = time_axis_dict_type(525,529,536) + = time_axis_dict_type(525,529,536,542) ! request function space discovery integer, parameter :: missing_fs = imdi @@ -97,6 +98,7 @@ module field_spec_mod logical(l_def) :: twod = .false. ! Is it two-dimensional? logical(l_def) :: empty = .false. ! Is it empty (with an empty data array)? logical(l_def) :: coarse = .false. ! Is it coarse? + character(str_def) :: mesh_name = '' ! Name of mesh, or blank string logical(l_def) :: is_int = .false. ! Is it an integer field? logical(l_def) :: legacy = .false. ! Is it a field with legacy checkpointing? end type field_spec_type @@ -198,12 +200,13 @@ end subroutine processor_set_clock !> @param[in, optional] twod Is it two-dimensional? !> @param[in, optional] empty Is it empty (with empty data array)? !> @param[in, optional] coarse Is it on a coarse mesh? + !> @param[in, optional] coarse_mesh_name Name of mesh, if coarse !> @param[in, optional] is_int Is it an integer field? !> @param[in, optional] legacy Is it a field with legacy checkpointing? !> @return Specifier returned function make_spec(name, main_coll, space, order_h, order_v, adv_coll, & moist_arr, moist_idx, time_axis, & - mult, ckp, twod, empty, coarse, is_int, legacy) result(field_spec) + mult, ckp, twod, empty, coarse, coarse_mesh_name, is_int, legacy) result(field_spec) implicit none character(*), intent(in) :: name integer(i_def), intent(in) :: main_coll @@ -219,6 +222,7 @@ function make_spec(name, main_coll, space, order_h, order_v, adv_coll, & logical(l_def), optional, intent(in) :: twod logical(l_def), optional, intent(in) :: empty logical(l_def), optional, intent(in) :: coarse + character(*), optional, intent(in) :: coarse_mesh_name logical(l_def), optional, intent(in) :: is_int logical(l_def), optional, intent(in) :: legacy type(field_spec_type) :: field_spec @@ -237,6 +241,7 @@ function make_spec(name, main_coll, space, order_h, order_v, adv_coll, & if (present(twod)) field_spec%twod=twod if (present(empty)) field_spec%empty=empty if (present(coarse)) field_spec%coarse=coarse + if (present(coarse_mesh_name)) field_spec%mesh_name=coarse_mesh_name if (present(is_int)) field_spec%is_int=is_int if (present(legacy)) field_spec%legacy=legacy diff --git a/science/gungho/source/driver/gungho_driver_mod.F90 b/science/gungho/source/driver/gungho_driver_mod.F90 index 2c1e5a37a..69cfaf80b 100644 --- a/science/gungho/source/driver/gungho_driver_mod.F90 +++ b/science/gungho/source/driver/gungho_driver_mod.F90 @@ -55,7 +55,13 @@ module gungho_driver_mod use mesh_mod, only : mesh_type use mesh_collection_mod, only : mesh_collection use multires_coupling_config_mod, & - only : aerosol_mesh_name + only : aerosol_mesh_name, & + nudging_mesh_name, & + coarse_nudging + use nudging_config_mod, only : nudging_source, & + nudging_source_initial + use physics_constants_mod, only : update_nudging_weights + use create_nudging_fields_mod, only : set_nudging_reference_initial use remove_field_collection_mod, only : remove_field_collection use section_choice_config_mod, only : iau, & iau_sst, & @@ -66,9 +72,9 @@ module gungho_driver_mod use time_config_mod, only : timestep_start use timing_mod, only : start_timing, stop_timing, & tik, LPROF + use variable_fields_mod, only : update_variable_fields #ifdef UM_PHYSICS - use variable_fields_mod, only : update_variable_fields use lfric_xios_time_axis_mod, only : regridder use intermesh_mappings_alg_mod, only : map_scalar_intermesh use update_ancils_alg_mod, only : update_ancils_alg @@ -126,6 +132,8 @@ subroutine initialise( program_name, modeldb ) type(mesh_type), pointer :: twod_mesh => null() type(mesh_type), pointer :: aerosol_mesh => null() type(mesh_type), pointer :: aerosol_twod_mesh => null() + type(mesh_type), pointer :: nudging_mesh => null() + type(mesh_type), pointer :: nudging_twod_mesh => null() type(io_value_type) :: temp_corr_io_value type(io_value_type) :: random_seed_io_value @@ -166,6 +174,15 @@ subroutine initialise( program_name, modeldb ) aerosol_twod_mesh => twod_mesh end if + ! If nudging is on a different mesh, get this + if (coarse_nudging) then + nudging_mesh => mesh_collection%get_mesh(nudging_mesh_name) + nudging_twod_mesh => mesh_collection%get_mesh(nudging_mesh, TWOD) + else + nudging_mesh => mesh + nudging_twod_mesh => twod_mesh + end if + ! Rate of temperature adjustment for energy correction call temp_corr_io_value%init("temperature_correction_rate", [0.0_r_def]) call modeldb%values%add_key_value( 'temperature_correction_io_value', & @@ -188,9 +205,10 @@ subroutine initialise( program_name, modeldb ) end if ! Instantiate the fields stored in model_data - call create_model_data( modeldb, & - mesh, twod_mesh, & - aerosol_mesh, aerosol_twod_mesh ) + call create_model_data( modeldb, & + mesh, twod_mesh, & + aerosol_mesh, aerosol_twod_mesh, & + nudging_mesh, nudging_twod_mesh ) ! Set up io for multifile reading if ( multifile_io ) then @@ -293,6 +311,7 @@ subroutine step( modeldb ) type(mesh_type), pointer :: mesh => null() type(mesh_type), pointer :: twod_mesh => null() + type(mesh_type), pointer :: nudging_mesh => null() integer(kind=i_def) :: ts_start, rc integer(tik) :: tid_first, tid_rest @@ -305,6 +324,8 @@ subroutine step( modeldb ) type(gungho_time_axes_type), pointer :: model_axes character(len=*), parameter :: io_context_name = "gungho_atm" + type( field_collection_type ), pointer :: derived_fields + #ifdef UM_PHYSICS procedure(regridder), pointer :: regrid_operation => null() logical(l_def) :: regrid_lowest_order @@ -389,6 +410,17 @@ subroutine step( modeldb ) modeldb%clock, lbc_fields ) endif + ! Spectral nudging update + if (theta_forcing == theta_forcing_nudging & + .or. wind_forcing == wind_forcing_nudging) then + derived_fields => modeldb%fields%get_field_collection("derived_fields") + call update_variable_fields( & + model_axes%nudging_times_list, modeldb%clock, derived_fields & + ) + nudging_mesh => mesh_collection%get_mesh(nudging_mesh_name) + call update_nudging_weights(modeldb%clock, nudging_mesh) + end if + #ifdef UM_PHYSICS ! If IAU is active and increments need to be added over a time window, then do this ! at the start of every ts within the required time window diff --git a/science/gungho/source/driver/gungho_init_fields_mod.X90 b/science/gungho/source/driver/gungho_init_fields_mod.X90 index db9e0d3db..9a4f6ef4b 100644 --- a/science/gungho/source/driver/gungho_init_fields_mod.X90 +++ b/science/gungho/source/driver/gungho_init_fields_mod.X90 @@ -79,6 +79,8 @@ module gungho_init_fields_mod use create_lbcs_mod, only : create_lbc_fields use create_gungho_prognostics_mod, only : create_gungho_prognostics use create_physics_prognostics_mod, only : create_physics_prognostics + use create_nudging_fields_mod, only : create_nudging_fields + use variable_fields_mod, only : update_variable_fields use field_mapper_mod, only : field_mapper_type use map_fd_to_prognostics_alg_mod, only : map_fd_to_prognostics use gungho_init_prognostics_driver_mod, only : init_gungho_prognostics @@ -88,6 +90,10 @@ module gungho_init_fields_mod use derived_config_mod, only : l_esm_couple use ageofair_alg_mod, only : init_ageofair use transport_config_mod, only : transport_ageofair + use external_forcing_config_mod, only : theta_forcing_nudging, & + theta_forcing, & + wind_forcing_nudging, & + wind_forcing #ifdef COUPLED use coupler_mod, only : zero_coupling_send_fields #endif @@ -96,6 +102,7 @@ module gungho_init_fields_mod use map_physics_fields_alg_mod, only : map_physics_fields_alg use set_any_dof_alg_mod, only : set_any_dof_alg use reference_element_mod, only : T + use variable_fields_mod, only : init_variable_fields #ifdef UM_PHYSICS use create_fd_prognostics_mod, only : create_fd_prognostics use init_ancils_mod, only : create_fd_ancils, & @@ -103,7 +110,6 @@ module gungho_init_fields_mod use process_inputs_alg_mod, only : process_inputs_alg use process_urban_alg_mod, only : process_urban_alg use update_tstar_alg_mod, only : update_tstar_alg - use variable_fields_mod, only : init_variable_fields use lfric_xios_time_axis_mod, only : regridder use intermesh_mappings_alg_mod, only : map_scalar_intermesh use iau_config_mod, only : iau_use_pertinc @@ -305,11 +311,15 @@ contains !> @param[in] twod_mesh The current 2d mesh !> @param[in] aerosol_mesh Aerosol 3d mesh !> @param[in] aerosol_twod_mesh Aerosol 2d mesh -subroutine create_model_data( modeldb, & - mesh, & - twod_mesh, & - aerosol_mesh, & - aerosol_twod_mesh ) + !> @param[in] nudging_mesh Nudging 3d mesh + !> @param[in] nudging_twod_mesh Nudging 2d mesh +subroutine create_model_data( modeldb, & + mesh, & + twod_mesh, & + aerosol_mesh, & + aerosol_twod_mesh, & + nudging_mesh, & + nudging_twod_mesh) implicit none @@ -319,6 +329,8 @@ subroutine create_model_data( modeldb, & type( mesh_type ), intent(in), pointer :: twod_mesh type( mesh_type ), intent(in), pointer :: aerosol_mesh type( mesh_type ), intent(in), pointer :: aerosol_twod_mesh + type( mesh_type ), intent(in), pointer :: nudging_mesh + type( mesh_type ), intent(in), pointer :: nudging_twod_mesh type(field_mapper_type), target :: field_mapper @@ -485,14 +497,11 @@ subroutine create_model_data( modeldb, & ! Create gungho prognostics and auxiliary (diagnostic) fields call create_gungho_prognostics( mesh, & twod_mesh, & - aerosol_mesh, & - aerosol_twod_mesh, & field_mapper, & modeldb%clock ) if (limited_area) then - call create_lbc_fields( mesh, twod_mesh, aerosol_mesh, aerosol_twod_mesh, & - field_mapper, modeldb%clock ) + call create_lbc_fields( mesh, twod_mesh, field_mapper, modeldb%clock ) end if if ( iau ) call create_iau_fields( mesh, twod_mesh, & @@ -500,10 +509,16 @@ subroutine create_model_data( modeldb, & prognostic_fields, & modeldb ) + if ( wind_forcing == wind_forcing_nudging .or. & + theta_forcing == theta_forcing_nudging ) then + call create_nudging_fields( & + nudging_mesh, nudging_twod_mesh, field_mapper, modeldb%clock & + ) + end if + ! Create prognostics used by physics if (use_physics) then - call create_physics_prognostics( mesh, twod_mesh, aerosol_mesh, aerosol_twod_mesh, field_mapper, & - modeldb%clock ) + call create_physics_prognostics( mesh, twod_mesh, field_mapper, modeldb%clock ) #ifdef UM_PHYSICS ! Create FD prognostic fields @@ -522,6 +537,8 @@ subroutine create_model_data( modeldb, & mesh, twod_mesh , & aerosol_mesh, & aerosol_twod_mesh, & + nudging_mesh, & + nudging_twod_mesh, & model_axes%ancil_times_list ) case ( ancil_option_idealised ) call create_fd_ancils_idealised( depository, & @@ -831,6 +848,16 @@ subroutine create_model_data( modeldb, & moist_dyn_array%bundle, & derived_fields) + + ! Initialise reading of nudging fields + if ( wind_forcing == wind_forcing_nudging .or. & + theta_forcing == theta_forcing_nudging ) then + ! Initialise time interpolation + call init_variable_fields( & + model_axes%nudging_times_list, modeldb%clock, derived_fields & + ) + end if + #ifdef UM_PHYSICS ! Initialise Casim numbers if they aren't coming from an LFRic dump if (microphysics_casim .and. & diff --git a/science/gungho/source/driver/gungho_model_mod.F90 b/science/gungho/source/driver/gungho_model_mod.F90 index 00c9842f7..e43a01d47 100644 --- a/science/gungho/source/driver/gungho_model_mod.F90 +++ b/science/gungho/source/driver/gungho_model_mod.F90 @@ -27,6 +27,7 @@ module gungho_model_mod use create_gungho_prognostics_mod, only : process_gungho_prognostics use create_lbcs_mod, only : process_lbc_fields use create_mesh_mod, only : create_mesh + use create_nudging_fields_mod, only : process_nudging_fields use create_physics_prognostics_mod, only : & process_physics_prognostics use derived_config_mod, only : set_derived_config, l_esm_couple, & @@ -246,6 +247,10 @@ subroutine before_context_close(clock) use multidata_field_dimensions_mod, only: sync_multidata_field_dimensions use time_dimensions_mod, only: sync_time_dimensions use boundaries_config_mod, only: limited_area + use external_forcing_config_mod, only: theta_forcing, & + theta_forcing_nudging, & + wind_forcing, & + wind_forcing_nudging use formulation_config_mod, only: use_physics use section_choice_config_mod, only: stochastic_physics, & stochastic_physics_um @@ -257,12 +262,16 @@ subroutine before_context_close(clock) class(clock_type), intent(in) :: clock type(persistor_type) :: persistor - - real(r_second) :: DT + real(r_second) :: DT + logical(l_def) :: to_process_nudging_fields DT = clock%get_seconds_per_step() call set_variable("DT", DT, tolerant=.true.) + + to_process_nudging_fields = ( theta_forcing == theta_forcing_nudging & + .or. wind_forcing == wind_forcing_nudging ) + call persistor%init(clock) call process_gungho_prognostics(persistor) ! Add the temperature_correction_rate to the appropriate files @@ -291,6 +300,7 @@ subroutine before_context_close(clock) if (limited_area) call process_lbc_fields(persistor) if (use_physics) then call process_physics_prognostics(persistor) + if (to_process_nudging_fields) call process_nudging_fields(persistor) call sync_multidata_field_dimensions() call sync_time_dimensions() end if diff --git a/science/gungho/source/driver/gungho_setup_io_mod.F90 b/science/gungho/source/driver/gungho_setup_io_mod.F90 index c169f4323..6c18c7f00 100644 --- a/science/gungho/source/driver/gungho_setup_io_mod.F90 +++ b/science/gungho/source/driver/gungho_setup_io_mod.F90 @@ -97,6 +97,8 @@ module gungho_setup_io_mod iau_surf_path, & lbc_filename, & lbc_directory, & + nudging_filename, & + nudging_directory, & ls_filename, & ls_directory, & coarse_ancil_directory, & @@ -140,6 +142,11 @@ module gungho_setup_io_mod timestep_end use derived_config_mod, only: l_couple_sea_ice use lfric_string_mod, only: split_string + use external_forcing_config_mod, & + only: theta_forcing, & + theta_forcing_nudging, & + wind_forcing, & + wind_forcing_nudging #ifdef UM_PHYSICS use jules_surface_config_mod, only: l_vary_z0m_soil, l_urban2t use specified_surface_config_mod, only: internal_flux_method, & @@ -193,6 +200,7 @@ subroutine init_gungho_files( files_list, modeldb ) iau_fname, & iau_surf_fname, & lbc_fname, & + nudging_fname, & ls_fname character(:), allocatable :: split_checkpoint_stem_name(:) real(r_second), allocatable :: all_checkpoint_times(:) @@ -807,6 +815,16 @@ subroutine init_gungho_files( files_list, modeldb ) io_mode=FILE_MODE_READ ) ) endif + ! Setup the nudging file + if ( theta_forcing == theta_forcing_nudging & + .or. wind_forcing == wind_forcing_nudging ) then + write(nudging_fname,'(A)') trim(nudging_directory) //'/'// & + trim(nudging_filename) + call files_list%insert_item( lfric_xios_file_type( nudging_fname, & + xios_id="nudging", & + io_mode=FILE_MODE_READ ) ) + endif + ! Setup the ls file if ( ls_option == ls_option_file ) then write(ls_fname,'(A)') trim(ls_directory)//'/'// & diff --git a/science/gungho/source/driver/gungho_time_axes_mod.f90 b/science/gungho/source/driver/gungho_time_axes_mod.f90 index fd5fdbc1f..740ff7bf9 100644 --- a/science/gungho/source/driver/gungho_time_axes_mod.f90 +++ b/science/gungho/source/driver/gungho_time_axes_mod.f90 @@ -34,6 +34,12 @@ module gungho_time_axes_mod !> Pointer to the LBC time axis object type(time_axis_type), pointer, public :: lbc_time_axis + !> Time varying nudging time axis. + type(linked_list_type), public :: nudging_times_list + + !> Pointer to the nudging time axis object + type(time_axis_type), pointer, public :: nudging_time_axis + !> Time varying linearisation state time axis. !> !> @todo Is this part of the linear model? @@ -49,6 +55,8 @@ module gungho_time_axes_mod procedure, public :: initialise procedure, public :: make_lbc_time_axis procedure, public :: save_lbc_time_axis + procedure, public :: make_nudging_time_axis + procedure, public :: save_nudging_time_axis end type gungho_time_axes_type @@ -66,6 +74,8 @@ subroutine initialise(self) self%lbc_time_axis => null() self%ls_time_axis => null() + self%nudging_time_axis => null() + end subroutine initialise !> @brief Create an lbc time axis @@ -85,6 +95,29 @@ subroutine make_lbc_time_axis(self) interp_flag = interp_flag ) end subroutine make_lbc_time_axis + !> @brief Create the nudging time axis + !> @param[in] self Time axes object + subroutine make_nudging_time_axis(self) + + implicit none + + class(gungho_time_axes_type), intent(inout) :: self + + logical(l_def), parameter :: cyclic=.false. + logical(l_def), parameter :: interp_flag=.true. + + if (associated(self%nudging_time_axis)) then + call log_event('failed to recreate nudging time axis', LOG_LEVEL_ERROR) + end if + + allocate(self%nudging_time_axis) + call self%nudging_time_axis%initialise( & + "nudging_time", file_id="nudging", & + yearly=cyclic, interp_flag=interp_flag & + ) + + end subroutine make_nudging_time_axis + !> @brief Add the lbc time axis if any to the lbc times list !> @param[in,out] self Time axes object subroutine save_lbc_time_axis(self) @@ -95,6 +128,20 @@ subroutine save_lbc_time_axis(self) call self%lbc_times_list%insert_item(self%lbc_time_axis) end subroutine save_lbc_time_axis + !> @brief Add the nudging time axis if any to the nudging times list + !> @param[in,out] self Time axes object + subroutine save_nudging_time_axis(self) + + implicit none + + class(gungho_time_axes_type), intent(inout) :: self + + if (associated(self%nudging_time_axis)) then + call self%nudging_times_list%insert_item(self%nudging_time_axis) + end if + + end subroutine save_nudging_time_axis + !----------------------------------------------------------------------------- ! Non-type-bound helper function !----------------------------------------------------------------------------- diff --git a/science/gungho/source/driver/init_ancils_mod.f90 b/science/gungho/source/driver/init_ancils_mod.f90 index 9d0eb0487..b99d52b82 100644 --- a/science/gungho/source/driver/init_ancils_mod.f90 +++ b/science/gungho/source/driver/init_ancils_mod.f90 @@ -98,12 +98,19 @@ module init_ancils_mod !> @details Organises fields to be read from ancils into ancil_fields ! collection then reads them. - !> @param[in,out] depository The depository field collection - !> @param[in,out] ancil_fields Collection for ancillary fields - !> @param[in] mesh The current 3d mesh - !> @param[in] twod_mesh The current 2d mesh + !> @param[in,out] depository The depository field collection + !> @param[in,out] ancil_fields Collection for ancillary fields + !> @param[in] mesh The current 3d mesh + !> @param[in] twod_mesh The current 2d mesh + !> @param[in] aerosol_mesh Aerosol 3d mesh + !> @param[in] aerosol_twod_mesh Aerosol 2d mesh + !> @param[in] nudging_mesh Nudging 3d mesh + !> @param[in] nudging_twod_mesh Nudging 2d mesh + !> @param[out] ancil_times_list Linked list of time axes for time-varying ancils subroutine create_fd_ancils( depository, ancil_fields, mesh, & - twod_mesh, aerosol_mesh, aerosol_twod_mesh, ancil_times_list ) + twod_mesh, aerosol_mesh, aerosol_twod_mesh, & + nudging_mesh, nudging_twod_mesh, & + ancil_times_list ) implicit none @@ -114,6 +121,8 @@ subroutine create_fd_ancils( depository, ancil_fields, mesh, & type( mesh_type ), intent(in), pointer :: twod_mesh type( mesh_type ), intent(in), pointer :: aerosol_mesh type( mesh_type ), intent(in), pointer :: aerosol_twod_mesh + type( mesh_type ), intent(in), pointer :: nudging_mesh + type( mesh_type ), intent(in), pointer :: nudging_twod_mesh type(linked_list_type), intent(out) :: ancil_times_list diff --git a/science/gungho/source/physics/multidata_field_dimensions_mod.F90 b/science/gungho/source/physics/multidata_field_dimensions_mod.F90 index b53cbfbdf..130fe1be0 100644 --- a/science/gungho/source/physics/multidata_field_dimensions_mod.F90 +++ b/science/gungho/source/physics/multidata_field_dimensions_mod.F90 @@ -28,7 +28,7 @@ module multidata_field_dimensions_mod #ifdef UM_PHYSICS ! 1 2 3 ! 123456789012345678901234567890 - character(30), parameter :: multidata_items(33) = & + character(30), parameter :: multidata_items(34) = & [character(30) :: & 'plant_func_types', & 'sea_ice_categories', & @@ -62,7 +62,8 @@ module multidata_field_dimensions_mod 'lw_bands_radiation_levels', & 'photolysis_pathways', & 'random_seed_size', & - 'photol_species' & + 'photol_species', & + 'ecmwf_levels' & ] #endif @@ -165,6 +166,7 @@ function get_multidata_field_dimension(multidata_item) result (dim) use aerosol_config_mod, only: l_radaer use chemistry_config_mod, only: chem_scheme, chem_scheme_strattrop use um_ukca_init_mod, only: n_phot_spc + use nudging_config_mod, only: nudge_data_levels #endif use log_mod, only: log_event, LOG_LEVEL_ERROR, & @@ -273,6 +275,8 @@ function get_multidata_field_dimension(multidata_item) result (dim) else dim = 1 end if + case ('ecmwf_levels') + dim = nudge_data_levels case ('') dim = 1 ! ordinary (non-multidata) field #endif diff --git a/science/gungho/source/physics/time_dimensions_mod.F90 b/science/gungho/source/physics/time_dimensions_mod.F90 index 7a37fe969..9c3b6a879 100644 --- a/science/gungho/source/physics/time_dimensions_mod.F90 +++ b/science/gungho/source/physics/time_dimensions_mod.F90 @@ -42,7 +42,14 @@ module time_dimensions_mod emiss_so2_high_ancil_path #endif use files_config_mod, only: lbc_dir => lbc_directory, & - lbc_filename + lbc_filename, & + nudging_filename, & + nudging_directory + use external_forcing_config_mod, only : theta_forcing, & + theta_forcing_nudging, & + wind_forcing, & + wind_forcing_nudging + #ifdef UM_PHYSICS use aerosol_config_mod, only: glomap_mode, & glomap_mode_ukca @@ -157,6 +164,9 @@ subroutine sync_time_dimensions() tdim = get_emiss_dim() if (tdim /= 0) & call set_axis_dimension('emiss_axis', tdim, tolerate_missing_axes) + tdim = get_nudging_dim() + if (tdim /= 0) & + call set_axis_dimension('nudging_time_axis', tdim, tolerate_missing_axes) end subroutine sync_time_dimensions !> @brief Source the dimension of the lbc_axis from the lbc file. @@ -229,4 +239,23 @@ function get_emiss_dim() result(tdim) #endif end function get_emiss_dim + !> @brief Source the dimension of the nudging_time_axis from the + !> ancil file being read. + !> + !> @result The dimension of the nudging_time_axis + !> or zero if there is no enabled nudging file. + !> + function get_nudging_dim() result(tdim) + implicit none + integer(i_def) :: tdim + tdim = 0 + + if (theta_forcing == theta_forcing_nudging .or. & + wind_forcing == wind_forcing_nudging) then + + if (.not. get_ancil_dim(nudging_directory, nudging_filename, tdim)) return + + end if + + end function get_nudging_dim end module time_dimensions_mod From 8a745da8bdf5f82e886f685f44688543b720c4a1 Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Thu, 30 Apr 2026 17:07:33 +0100 Subject: [PATCH 03/18] Compilation fixes, mainly updating other calls to setup_model_data for the new arguments --- .../jedi_lfric_linear_modeldb_driver_mod.f90 | 36 ++++++++++++++++--- .../driver/create_physics_prognostics_mod.F90 | 2 +- .../source/driver/gungho_driver_mod.F90 | 13 +++---- .../source/driver/linear_driver_mod.f90 | 36 +++++++++++++++++-- 4 files changed, 71 insertions(+), 16 deletions(-) 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 5a665c30d..f9f3ca420 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 @@ -46,6 +46,10 @@ module jedi_lfric_linear_modeldb_driver_mod use constants_mod, only : r_def, l_def, str_def use driver_config_mod, only : init_config use driver_time_mod, only : init_time, final_time + use external_forcing_config_mod, only : theta_forcing, & + theta_forcing_nudging, & + wind_forcing, & + wind_forcing_nudging use extrusion_mod, only : TWOD use gungho_init_fields_mod, only : create_model_data, & finalise_model_data @@ -102,18 +106,23 @@ subroutine initialise_modeldb( modeldb_name, filename, mpi_obj, modeldb, atl_si_ type( mesh_type ), pointer :: twod_mesh type( mesh_type ), pointer :: aerosol_mesh type( mesh_type ), pointer :: aerosol_twod_mesh + type( mesh_type ), pointer :: nudging_mesh + type( mesh_type ), pointer :: nudging_twod_mesh type( namelist_type ), pointer :: base_mesh_nml type( namelist_type ), pointer :: multires_coupling_nml type( namelist_type ), pointer :: initialization_nml type( lfric_xios_context_type ), pointer :: io_context character( len=str_def ) :: prime_mesh_name character( len=str_def ) :: aerosol_mesh_name + character( len=str_def ) :: nudging_mesh_name logical( kind=l_def ) :: coarse_aerosol_ancil logical( kind=l_def ) :: coarse_ozone_ancil + logical( kind=l_def ) :: coarse_nudging character(len=*), parameter :: io_context_name = "gungho_atm" nullify( mesh, twod_mesh, aerosol_mesh, aerosol_twod_mesh ) + nullify( nudging_mesh, nudging_twod_mesh ) nullify( base_mesh_nml, multires_coupling_nml, initialization_nml ) ! 1. Initialise modeldb field collections, configuration and mpi. @@ -161,16 +170,19 @@ subroutine initialise_modeldb( modeldb_name, filename, mpi_obj, modeldb, atl_si_ mesh => mesh_collection%get_mesh(prime_mesh_name) twod_mesh => mesh_collection%get_mesh(mesh, TWOD) - ! Get aerosol ancillary configuration logical + ! Get aerosol and nudging ancillary configuration logical initialization_nml => modeldb%configuration%get_namelist('initialization') call initialization_nml%get_value( 'coarse_aerosol_ancil', & coarse_aerosol_ancil ) call initialization_nml%get_value( 'coarse_ozone_ancil', & coarse_ozone_ancil ) + multires_coupling_nml => & + modeldb%configuration%get_namelist('multires_coupling') + call multires_coupling_nml%get_value( 'coarse_nudging', & + coarse_nudging ) + if (coarse_aerosol_ancil .or. coarse_ozone_ancil) then ! For now use the coarsest mesh - multires_coupling_nml => & - modeldb%configuration%get_namelist('multires_coupling') call multires_coupling_nml%get_value( 'aerosol_mesh_name', & aerosol_mesh_name ) aerosol_mesh => mesh_collection%get_mesh(aerosol_mesh_name) @@ -183,12 +195,28 @@ subroutine initialise_modeldb( modeldb_name, filename, mpi_obj, modeldb, atl_si_ aerosol_twod_mesh => twod_mesh end if + ! If nudging data is on a different mesh, get this + if (coarse_nudging) then + ! For now use the coarsest mesh + call multires_coupling_nml%get_value( 'nudging_mesh_name', & + nudging_mesh_name ) + nudging_mesh => mesh_collection%get_mesh(nudging_mesh_name) + nudging_twod_mesh => mesh_collection%get_mesh(nudging_mesh, TWOD) + write( log_scratch_space,'(A,A)' ) "nudging mesh name:", nudging_mesh%get_mesh_name() + call log_event( log_scratch_space, LOG_LEVEL_TRACE ) + else + nudging_mesh => mesh + nudging_twod_mesh => twod_mesh + end if + ! Instantiate the fields stored in model_data call create_model_data( modeldb, & mesh, & twod_mesh, & aerosol_mesh, & - aerosol_twod_mesh ) + aerosol_twod_mesh, & + nudging_mesh, & + nudging_twod_mesh ) ! Instantiate the linearisation state call linear_create_ls_analytic( modeldb, mesh, twod_mesh ) diff --git a/science/gungho/source/driver/create_physics_prognostics_mod.F90 b/science/gungho/source/driver/create_physics_prognostics_mod.F90 index 3e792dacb..73803ae2c 100644 --- a/science/gungho/source/driver/create_physics_prognostics_mod.F90 +++ b/science/gungho/source/driver/create_physics_prognostics_mod.F90 @@ -10,7 +10,7 @@ module create_physics_prognostics_mod use energy_correction_config_mod, only : encorr_usage, & encorr_usage_none use clock_mod, only : clock_type - use constants_mod, only : i_def, l_def + use constants_mod, only : i_def, l_def, str_def use field_mod, only : field_type use integer_field_mod, only : integer_field_type use field_spec_mod, only : main_coll_dict, & diff --git a/science/gungho/source/driver/gungho_driver_mod.F90 b/science/gungho/source/driver/gungho_driver_mod.F90 index 69cfaf80b..f93f59695 100644 --- a/science/gungho/source/driver/gungho_driver_mod.F90 +++ b/science/gungho/source/driver/gungho_driver_mod.F90 @@ -23,6 +23,10 @@ module gungho_driver_mod output_model_data, & finalise_model_data use driver_modeldb_mod, only : modeldb_type + use external_forcing_config_mod, only : theta_forcing_nudging, & + theta_forcing, & + wind_forcing_nudging, & + wind_forcing use gungho_model_mod, only : initialise_infrastructure, & initialise_model, & finalise_infrastructure, & @@ -58,10 +62,6 @@ module gungho_driver_mod only : aerosol_mesh_name, & nudging_mesh_name, & coarse_nudging - use nudging_config_mod, only : nudging_source, & - nudging_source_initial - use physics_constants_mod, only : update_nudging_weights - use create_nudging_fields_mod, only : set_nudging_reference_initial use remove_field_collection_mod, only : remove_field_collection use section_choice_config_mod, only : iau, & iau_sst, & @@ -311,7 +311,6 @@ subroutine step( modeldb ) type(mesh_type), pointer :: mesh => null() type(mesh_type), pointer :: twod_mesh => null() - type(mesh_type), pointer :: nudging_mesh => null() integer(kind=i_def) :: ts_start, rc integer(tik) :: tid_first, tid_rest @@ -411,14 +410,12 @@ subroutine step( modeldb ) endif ! Spectral nudging update - if (theta_forcing == theta_forcing_nudging & + if ( theta_forcing == theta_forcing_nudging & .or. wind_forcing == wind_forcing_nudging) then derived_fields => modeldb%fields%get_field_collection("derived_fields") call update_variable_fields( & model_axes%nudging_times_list, modeldb%clock, derived_fields & ) - nudging_mesh => mesh_collection%get_mesh(nudging_mesh_name) - call update_nudging_weights(modeldb%clock, nudging_mesh) end if #ifdef UM_PHYSICS diff --git a/science/linear/source/driver/linear_driver_mod.f90 b/science/linear/source/driver/linear_driver_mod.f90 index c7ac56319..e9097e009 100644 --- a/science/linear/source/driver/linear_driver_mod.f90 +++ b/science/linear/source/driver/linear_driver_mod.f90 @@ -8,6 +8,10 @@ module linear_driver_mod use constants_mod, only : i_def, r_def, imdi, l_def, str_def, & i_medium + use external_forcing_config_mod, only : theta_forcing, & + theta_forcing_nudging, & + wind_forcing, & + wind_forcing_nudging use extrusion_mod, only : TWOD use field_array_mod, only : field_array_type use field_mod, only : field_type @@ -78,6 +82,8 @@ subroutine initialise( program_name, modeldb ) type( mesh_type ), pointer :: twod_mesh type( mesh_type ), pointer :: aerosol_mesh type( mesh_type ), pointer :: aerosol_twod_mesh + type( mesh_type ), pointer :: nudging_mesh + type( mesh_type ), pointer :: nudging_twod_mesh type( namelist_type ), pointer :: base_mesh_nml type( namelist_type ), pointer :: multires_coupling_nml @@ -86,8 +92,10 @@ subroutine initialise( program_name, modeldb ) character( len=str_def ) :: prime_mesh_name character( len=str_def ) :: aerosol_mesh_name + character( len=str_def ) :: nudging_mesh_name logical( kind=l_def ) :: coarse_aerosol_ancil logical( kind=l_def ) :: coarse_ozone_ancil + logical( kind=l_def ) :: coarse_nudging integer( kind=i_def ) :: init_option logical( kind=l_def ) :: nodal_output_on_w3 @@ -101,6 +109,7 @@ subroutine initialise( program_name, modeldb ) real(r_def), allocatable :: real_array(:) nullify( mesh, twod_mesh, aerosol_mesh, aerosol_twod_mesh, depository ) + nullify( nudging_mesh, nudging_twod_mesh ) nullify( base_mesh_nml, multires_coupling_nml, initialization_nml ) depository => modeldb%fields%get_field_collection("depository") @@ -142,11 +151,16 @@ subroutine initialise( program_name, modeldb ) coarse_ozone_ancil ) call initialization_nml%get_value( 'init_option', init_option ) + ! Get information on any multi-resolution meshes + multires_coupling_nml => & + modeldb%configuration%get_namelist('multires_coupling') + + call multires_coupling_nml%get_value( 'coarse_nudging', & + coarse_nudging ) + ! If aerosol data is on a different mesh, get this if (coarse_aerosol_ancil .or. coarse_ozone_ancil) then ! For now use the coarsest mesh - multires_coupling_nml => & - modeldb%configuration%get_namelist('multires_coupling') call multires_coupling_nml%get_value( 'aerosol_mesh_name', & aerosol_mesh_name ) aerosol_mesh => mesh_collection%get_mesh(aerosol_mesh_name) @@ -158,12 +172,28 @@ subroutine initialise( program_name, modeldb ) aerosol_twod_mesh => twod_mesh end if + ! If nudging data is on a different mesh, get this + if (coarse_nudging) then + ! For now use the coarsest mesh + call multires_coupling_nml%get_value( 'nudging_mesh_name', & + nudging_mesh_name ) + nudging_mesh => mesh_collection%get_mesh(nudging_mesh_name) + nudging_twod_mesh => mesh_collection%get_mesh(nudging_mesh, TWOD) + write( log_scratch_space,'(A,A)' ) "nudging mesh name:", nudging_mesh%get_mesh_name() + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + else + nudging_mesh => mesh + nudging_twod_mesh => twod_mesh + end if + ! Instantiate the fields stored in model_data call create_model_data( modeldb, & mesh, & twod_mesh, & aerosol_mesh, & - aerosol_twod_mesh ) + aerosol_twod_mesh, & + nudging_mesh, & + nudging_twod_mesh ) ! Instantiate the fields required to read the initial ! conditions from a file. From e2c68171baf1d563e967fad6aea3fd0ea55156be Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Thu, 30 Apr 2026 17:36:54 +0100 Subject: [PATCH 04/18] Improve trigerring in metadata --- science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf b/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf index 745a31950..fe6d21035 100644 --- a/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf +++ b/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf @@ -1051,6 +1051,7 @@ sort-key=A1 trigger=namelist:external_forcing=hs_random: this == "'held_suarez'" ; =namelist:temp_tend_data: this == "'temp_tend'"; =namelist:external_forcing=pc2_force_response: this != "'none'"; + =namelist:nudging: this == "'nudging'"; value-titles=None, Held-Suarez, Earth-Like, Tidally Locked Earth, =Shallow Hot Jupiter, Deep Hot Jupiter, Temperature Tendency Profile, =Nudging @@ -1130,6 +1131,7 @@ sort-key=C1 trigger=namelist:external_forcing=filtering_order: this == "'filtering'"; =namelist:external_forcing=diffusion_order: this == "'diffusion'"; =namelist:external_forcing=diffusion_coefficient: this == "'diffusion'"; + =namelist:nudging: this == "'nudging'"; =namelist:wind_forcing: this == "'profile'"; value-titles=None, Held-Suarez, Filtering, Diffusion, Profile, Nudging values='none','held_suarez', 'filtering', 'diffusion', 'profile', 'nudging' @@ -3716,6 +3718,7 @@ description=Whether to apply nudging on a coarser mesh than that used help=The mesh is given by the nudging_mesh_name option. !kind=default sort-key=Section-A09 +trigger=namelist:multires_coupling=nudging_mesh_name: true ; type=logical [namelist:multires_coupling=dynamics_mesh_name] @@ -3851,7 +3854,7 @@ description=The source of the reference states for nudging !enumeration=true help=Nudging has been implemented to nudge = (a) using Re-analyses (e.g. ERA) data - = (b) using model (e.g. NWP, M/L) data, or to + = (b) using model (e.g. NWP, M/L) data !kind=default ns=namelist/Science/Nudging sort-key=Panel-A01 From 05b457a7194c1c175c27fff91bc7dde84f795952 Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Fri, 1 May 2026 10:17:22 +0100 Subject: [PATCH 05/18] include files that were not explicitly 'git add'ed --- .../lfric_atm/metadata/grid_def_nudging.xml | 29 +++++ .../metadata/grid_def_nudging_coarse.xml | 29 +++++ .../lfric_atm/file/file_def_diags_nudging.xml | 24 ++++ .../app/lfric_atm/file/file_def_nudging.xml | 12 ++ .../file/iodef_gal_nwp_coarse_nudging.xml | 113 ++++++++++++++++++ .../lfric_atm/file/iodef_gal_nwp_nudging.xml | 113 ++++++++++++++++++ .../opt/rose-app-nudging-era-coarse.conf | 48 ++++++++ .../lfric_atm/opt/rose-app-nudging-era.conf | 40 +++++++ .../driver/create_nudging_fields_mod.f90 | 112 +++++++++++++++++ 9 files changed, 520 insertions(+) create mode 100644 applications/lfric_atm/metadata/grid_def_nudging.xml create mode 100644 applications/lfric_atm/metadata/grid_def_nudging_coarse.xml create mode 100644 rose-stem/app/lfric_atm/file/file_def_diags_nudging.xml create mode 100644 rose-stem/app/lfric_atm/file/file_def_nudging.xml create mode 100644 rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml create mode 100644 rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml create mode 100644 rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf create mode 100644 rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf create mode 100644 science/gungho/source/driver/create_nudging_fields_mod.f90 diff --git a/applications/lfric_atm/metadata/grid_def_nudging.xml b/applications/lfric_atm/metadata/grid_def_nudging.xml new file mode 100644 index 000000000..c1ffb73e9 --- /dev/null +++ b/applications/lfric_atm/metadata/grid_def_nudging.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/lfric_atm/metadata/grid_def_nudging_coarse.xml b/applications/lfric_atm/metadata/grid_def_nudging_coarse.xml new file mode 100644 index 000000000..758827077 --- /dev/null +++ b/applications/lfric_atm/metadata/grid_def_nudging_coarse.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_nudging.xml b/rose-stem/app/lfric_atm/file/file_def_diags_nudging.xml new file mode 100644 index 000000000..71d9840e8 --- /dev/null +++ b/rose-stem/app/lfric_atm/file/file_def_diags_nudging.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rose-stem/app/lfric_atm/file/file_def_nudging.xml b/rose-stem/app/lfric_atm/file/file_def_nudging.xml new file mode 100644 index 000000000..e68d5c714 --- /dev/null +++ b/rose-stem/app/lfric_atm/file/file_def_nudging.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml new file mode 100644 index 000000000..f8f8e3eb3 --- /dev/null +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + performance + 1.0 + + + + true + 50 + true + + + + + diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml new file mode 100644 index 000000000..955b5c3a3 --- /dev/null +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + performance + 1.0 + + + + true + 50 + true + + + + + diff --git a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf new file mode 100644 index 000000000..5650e6e23 --- /dev/null +++ b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf @@ -0,0 +1,48 @@ +[file:iodef.xml] +source=$ROSE_SUITE_DIR/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml + +[namelist:external_forcing] +pc2_force_response=.false. +theta_forcing='nudging' +wind_forcing='nudging' + +[namelist:files] +coarse_ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/C12' +nudging_directory='/data/users/thomas.bendall/nudging/era/C12' +nudging_filename='era5_nudge_L137_C12_2021032400-2706' + +[namelist:formulation] +use_multires_coupling=.true. + +[namelist:initialization] +coarse_aerosol_ancil=.true. +coarse_ozone_ancil=.true. + +[namelist:multires_coupling] +aerosol_mesh_name='multigrid_l2' +coarse_rad_aerosol=.true. +coarse_nudging=.true. +lowest_order_aero_flag=.false. +multires_coupling_mesh_tags='dynamics','multigrid_l2' +orography_mesh_name='dynamics' +physics_mesh_name='dynamics' +nudging_mesh_name='multigrid_l2' + +[namelist:section_choice] +external_forcing=.true. + +[namelist:nudging] +nudge_data_levels=137 +nudging_level_bottom=5 +nudging_level_top=52 +nudging_width_bottom=1 +nudging_width_top=2 +nudging_relax_time=3600.0 +nudging_method='convolution' +convolution_shape='gaussian' +nudging_source='era' +nudging_start_spinup=3600.0 +nudging_end_spinup=7200.0 +spectral_kmax=10 +spectral_kmin=0 +spectral_stencil_extent=1 diff --git a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf new file mode 100644 index 000000000..273b340f3 --- /dev/null +++ b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf @@ -0,0 +1,40 @@ +[file:iodef.xml] +source=$ROSE_SUITE_DIR/app/lfric_atm/file/iodef_gal_nwp_nudging.xml + +[namelist:external_forcing] +pc2_force_response=.false. +theta_forcing='nudging' +wind_forcing='nudging' + +[namelist:files] +nudging_directory='/data/users/thomas.bendall/nudging/era/C48' +nudging_filename='era5_nudge_L137_C48_MG_2021032400-2706' + +[namelist:multires_coupling] +aerosol_mesh_name='dynamics' +coarse_rad_aerosol=.false. +coarse_nudging=.false. +lowest_order_aero_flag=.false. +multires_coupling_mesh_tags='dynamics' +orography_mesh_name='dynamics' +physics_mesh_name='dynamics' +nudging_mesh_name='dynamics' + +[namelist:section_choice] +external_forcing=.true. + +[namelist:nudging] +nudge_data_levels=137 +nudging_level_bottom=5 +nudging_level_top=52 +nudging_width_bottom=1 +nudging_width_top=2 +nudging_relax_time=3600.0 +nudging_method='convolution' +convolution_shape='gaussian' +nudging_source='era' +nudging_start_spinup=3600.0 +nudging_end_spinup=7200.0 +spectral_kmax=10 +spectral_kmin=0 +spectral_stencil_extent=4 diff --git a/science/gungho/source/driver/create_nudging_fields_mod.f90 b/science/gungho/source/driver/create_nudging_fields_mod.f90 new file mode 100644 index 000000000..ddf5cd071 --- /dev/null +++ b/science/gungho/source/driver/create_nudging_fields_mod.f90 @@ -0,0 +1,112 @@ +!----------------------------------------------------------------------------- +! (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 Create fields used for spectral nudging +module create_nudging_fields_mod + + use clock_mod, only : clock_type + use constants_mod, only : i_def, l_def, str_def + use field_mod, only : field_type + use field_collection_mod, only : field_collection_type + use field_mapper_mod, only : field_mapper_type + use field_maker_mod, only : field_maker_type + use fs_continuity_mod, only : W3 + use function_space_mod, only : function_space_type + use gungho_time_axes_mod, only : gungho_time_axes_type + use log_mod, only : log_event, log_scratch_space, & + LOG_LEVEL_INFO, LOG_LEVEL_ERROR + use mesh_mod, only : mesh_type + + use external_forcing_config_mod, only : theta_forcing_nudging, & + theta_forcing, & + wind_forcing_nudging, & + wind_forcing + implicit none + + public :: create_nudging_fields + public :: process_nudging_fields + + contains + + !> @brief Create and add nudging fields. + !> @details Create reference fields to for nudging in the derived field + !! collection. On every timestep these fields will be updated. + !> @param[in] mesh The current 3d mesh + !> @param[in] twod_mesh The current 2d mesh (not used here) + !> @param[in] mapper Provides access to the field collections + !> @param[in] clock The model clock + subroutine create_nudging_fields(mesh, twod_mesh, mapper, clock) + implicit none + type(mesh_type), intent(in), pointer :: mesh + type(mesh_type), intent(in), pointer :: twod_mesh + type(field_mapper_type), intent(in) :: mapper + class(clock_type), intent(in) :: clock + + type(gungho_time_axes_type), pointer :: gungho_axes + + type(field_maker_type) :: creator + + call log_event('GungHo: Creating nudging fields...', LOG_LEVEL_INFO) + + gungho_axes => mapper%get_gungho_axes() + call gungho_axes%make_nudging_time_axis() + + call creator%init(mesh, twod_mesh, mapper, clock) + + call process_nudging_fields(creator) + + call gungho_axes%save_nudging_time_axis() + + end subroutine create_nudging_fields + + !> @brief Iterate over active nudging fields and apply an arbitrary + !! processor to the field specifiers. + subroutine process_nudging_fields(processor) + use field_spec_mod, only : main => main_coll_dict, & + axis => time_axis_dict, & + processor_type, & + make_spec + use multires_coupling_config_mod, only : coarse_nudging, & + nudging_mesh_name + + implicit none + + class(processor_type) :: processor + + !------ Fields updated directly from nudging file----------------- + call processor%apply(make_spec( & + 'surface_pressure_nudging_ext_ref', main%derived, W3, & + coarse=coarse_nudging, & + coarse_mesh_name=nudging_mesh_name, & + twod=.true., time_axis=axis%nudging & + )) + + if ( theta_forcing == theta_forcing_nudging ) then + call processor%apply(make_spec( & + 'temperature_nudging_ext_ref', main%derived, W3, twod=.true., & + coarse=coarse_nudging, & + coarse_mesh_name=nudging_mesh_name, & + mult='ecmwf_levels', time_axis=axis%nudging & + )) + end if + + if ( wind_forcing == wind_forcing_nudging ) then + call processor%apply(make_spec( & + 'u_nudging_ext_ref', main%derived, W3, twod=.true., & + coarse=coarse_nudging, & + coarse_mesh_name=nudging_mesh_name, & + mult='ecmwf_levels', time_axis=axis%nudging & + )) + call processor%apply(make_spec( & + 'v_nudging_ext_ref', main%derived, W3, twod=.true., & + coarse=coarse_nudging, & + coarse_mesh_name=nudging_mesh_name, & + mult='ecmwf_levels', time_axis=axis%nudging & + )) + end if + + end subroutine process_nudging_fields + +end module create_nudging_fields_mod From f1f0ddb3e9d4dc995f8381406d8d7b6268d82342 Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Tue, 5 May 2026 11:13:42 +0100 Subject: [PATCH 06/18] First round of fixes from testing: only handle fields and settings that are defined in source code; implement upgrade macro --- .../lfric_atm/metadata/field_def_diags.xml | 2 + .../lfric_atm/file/file_def_diags_nudging.xml | 24 ----------- .../file/file_def_diags_nudging_ref.xml | 15 +++++++ .../file/iodef_gal_nwp_coarse_nudging.xml | 2 +- .../lfric_atm/file/iodef_gal_nwp_nudging.xml | 2 +- .../opt/rose-app-nudging-era-coarse.conf | 8 ---- .../lfric_atm/opt/rose-app-nudging-era.conf | 8 ---- rose-stem/app/lfric_atm/rose-app.conf | 1 + .../lfric-gungho/HEAD/rose-meta.conf | 41 +++++++++++++++++- .../gungho/rose-meta/lfric-gungho/versions.py | 43 +++++++++++++++++++ 10 files changed, 103 insertions(+), 43 deletions(-) delete mode 100644 rose-stem/app/lfric_atm/file/file_def_diags_nudging.xml create mode 100644 rose-stem/app/lfric_atm/file/file_def_diags_nudging_ref.xml diff --git a/applications/lfric_atm/metadata/field_def_diags.xml b/applications/lfric_atm/metadata/field_def_diags.xml index 062e65437..10f92310e 100644 --- a/applications/lfric_atm/metadata/field_def_diags.xml +++ b/applications/lfric_atm/metadata/field_def_diags.xml @@ -43,6 +43,8 @@ + + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_nudging.xml b/rose-stem/app/lfric_atm/file/file_def_diags_nudging.xml deleted file mode 100644 index 71d9840e8..000000000 --- a/rose-stem/app/lfric_atm/file/file_def_diags_nudging.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_nudging_ref.xml b/rose-stem/app/lfric_atm/file/file_def_diags_nudging_ref.xml new file mode 100644 index 000000000..9331988d9 --- /dev/null +++ b/rose-stem/app/lfric_atm/file/file_def_diags_nudging_ref.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml index f8f8e3eb3..73a604942 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml @@ -36,7 +36,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml index 955b5c3a3..de394f16a 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml @@ -36,7 +36,7 @@ - + diff --git a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf index 5650e6e23..96b78590f 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf @@ -37,12 +37,4 @@ nudging_level_bottom=5 nudging_level_top=52 nudging_width_bottom=1 nudging_width_top=2 -nudging_relax_time=3600.0 -nudging_method='convolution' -convolution_shape='gaussian' nudging_source='era' -nudging_start_spinup=3600.0 -nudging_end_spinup=7200.0 -spectral_kmax=10 -spectral_kmin=0 -spectral_stencil_extent=1 diff --git a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf index 273b340f3..02c20af11 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf @@ -29,12 +29,4 @@ nudging_level_bottom=5 nudging_level_top=52 nudging_width_bottom=1 nudging_width_top=2 -nudging_relax_time=3600.0 -nudging_method='convolution' -convolution_shape='gaussian' nudging_source='era' -nudging_start_spinup=3600.0 -nudging_end_spinup=7200.0 -spectral_kmax=10 -spectral_kmin=0 -spectral_stencil_extent=4 diff --git a/rose-stem/app/lfric_atm/rose-app.conf b/rose-stem/app/lfric_atm/rose-app.conf index bd907a551..426f4c081 100644 --- a/rose-stem/app/lfric_atm/rose-app.conf +++ b/rose-stem/app/lfric_atm/rose-app.conf @@ -68,6 +68,7 @@ source=(namelist:aerosol) = namelist:mixing = (namelist:multigrid) = (namelist:multires_coupling) + = (namelist:nudging) = namelist:esm_couple = (namelist:orbit) = namelist:orography diff --git a/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf b/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf index fe6d21035..f6d781e18 100644 --- a/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf +++ b/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf @@ -53,6 +53,7 @@ import=lfric-driver/HEAD # mixing | Thomas Melvin, Kirsty Hanley # multigrid | Ricky Wong # multires_coupling | Thomas Bendall, Alex Brown +# nudging | Mohit Dalvi, Thomas Bendall # esm_couple | Richard Hill # orbit | James Manners # orography | Iva Kavcic @@ -1670,7 +1671,7 @@ type=character [namelist:files=nudging_filename] compulsory=true -description=Path to lbc file +description=Path to nudging file help=This file contains the nudging source data ns=namelist/Job/IO/Nudging !string_length=filename @@ -3848,6 +3849,26 @@ ns=namelist/Science/Nudging sort-key=Panel-A01b type=integer +[namelist:nudging=nudging_level_bottom] +compulsory=true +description=Bottom level to apply nudging from +fail-if=this < 0; +help= +!kind=default +ns=namelist/Science/Nudging +sort-key=Panel-A05a +type=integer + +[namelist:nudging=nudging_level_top] +compulsory=true +description=Top level to apply nudging from +fail-if=this > namelist:extrusion=number_of_layers; +help= +!kind=default +ns=namelist/Science/Nudging +sort-key=Panel-A05b +type=integer + [namelist:nudging=nudging_source] compulsory=true description=The source of the reference states for nudging @@ -3861,6 +3882,24 @@ sort-key=Panel-A01 value-titles=ERA, AIFS values='era', 'aifs' +[namelist:nudging=nudging_width_bottom] +compulsory=true +description=Width of tapering of nudging at the bottom of the nudging region +help= +!kind=default +ns=namelist/Science/Nudging +sort-key=Panel-A05c +type=integer + +[namelist:nudging=nudging_width_top] +compulsory=true +description=Width of tapering of nudging at the top of the nudging region +help= +!kind=default +ns=namelist/Science/Nudging +sort-key=Panel-A05d +type=integer + #============================================================================== # ORBIT #============================================================================== diff --git a/science/gungho/rose-meta/lfric-gungho/versions.py b/science/gungho/rose-meta/lfric-gungho/versions.py index 01798ad2b..661029725 100644 --- a/science/gungho/rose-meta/lfric-gungho/versions.py +++ b/science/gungho/rose-meta/lfric-gungho/versions.py @@ -31,3 +31,46 @@ def upgrade(self, config, meta_config=None): # Add settings return config, self.reports """ + +class vn3.1_t474(MacroUpgrade): + # Upgrade macro for #474 by Mohit Dalvi + # Add namelist and related items for Nudging functionality + + BEFORE_TAG = "vn3.1" + AFTER_TAG = "vn3.1_t474" + + def upgrade(self, config, meta_config=None): + # Add settings - new items in files and multires_coupling + self.add_setting( config, + ["namelist:files", "nudging_directory"],"''") + self.add_setting( config, + ["namelist:files", "nudging_filename"],"''") + + self.add_setting( config, + ["namelist:multires_coupling", "coarse_nudging"], ".false," ) + self.add_setting( config, + ["namelist:multires_coupling", "nudging_mesh_name"], "''") + + # Add new nudging namelist + # Append after 'multires_coupling' in configuration.nml + source = self.get_setting_value( config, + ["file:configuration.nml","source"] ) + source = re.sub(r'namelist:multires_coupling', + r'namelist:multires_coupling' + '\n' + ' (namelist:nudging)', + source) + self.change_setting_value( config, + ["file:configuration.nml","source"], source ) + + self.add_setting(config, ["namelist:nudging"]) + self.add_setting(config, ["namelist:nudging","nudge_data_levels"], 0 ) + self.add_setting(config, + ["namelist:nudging","nudging_level_bottom"], 0 ) + self.add_setting(config, + ["namelist:nudging","nudging_level_top"], 0 ) + self.add_setting(config, ["namelist:nudging","nudge_source"], "''" ) + self.add_setting(config, + ["namelist:nudging","nudging_width_bottom"], 0 ) + self.add_setting(config, + ["namelist:nudging","nudging_width_top"], 0 ) + + return config, self.reports From dd2ed963f5b5a801fceee8a7ed5643310a96a8bd Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Tue, 12 May 2026 12:28:02 +0100 Subject: [PATCH 07/18] Fixes -mostly aligning field definitions; rationalised tests to use 32bit as done for other azspice runs; remove unused additions to ancil reading code --- .../lfric_atm/metadata/grid_def_nudging.xml | 11 +- .../metadata/grid_def_nudging_coarse.xml | 13 +- .../lfric_atm/metadata/lfric_dictionary.xml | 8 +- dependencies.yaml | 4 +- .../file/file_def_diags_gal_nwp_nudging.xml | 189 ++++++++++++++++++ .../file/file_def_diags_nudging_ref.xml | 15 -- .../app/lfric_atm/file/file_def_nudging.xml | 8 +- .../file/iodef_gal_nwp_coarse_nudging.xml | 2 +- .../lfric_atm/file/iodef_gal_nwp_nudging.xml | 2 +- .../common/lfric_atm/tasks_lfric_atm.cylc | 6 +- .../site/meto/groups/groups_lfric_atm.cylc | 5 +- ...ra-C48_MG_azspice_gnu_fast-debug-32bit.txt | 9 + ...se-C48_MG_azspice_gnu_fast-debug-32bit.txt | 9 + .../physics/external_forcing_alg_mod.X90 | 11 + .../source/driver/gungho_init_fields_mod.X90 | 2 - .../gungho/source/driver/init_ancils_mod.f90 | 9 +- 16 files changed, 244 insertions(+), 59 deletions(-) create mode 100644 rose-stem/app/lfric_atm/file/file_def_diags_gal_nwp_nudging.xml delete mode 100644 rose-stem/app/lfric_atm/file/file_def_diags_nudging_ref.xml create mode 100644 rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-C48_MG_azspice_gnu_fast-debug-32bit.txt create mode 100644 rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit.txt diff --git a/applications/lfric_atm/metadata/grid_def_nudging.xml b/applications/lfric_atm/metadata/grid_def_nudging.xml index c1ffb73e9..4f4d95a86 100644 --- a/applications/lfric_atm/metadata/grid_def_nudging.xml +++ b/applications/lfric_atm/metadata/grid_def_nudging.xml @@ -1,13 +1,13 @@ - + - + @@ -15,12 +15,7 @@ - - - - - - + diff --git a/applications/lfric_atm/metadata/grid_def_nudging_coarse.xml b/applications/lfric_atm/metadata/grid_def_nudging_coarse.xml index 758827077..7c7ce2737 100644 --- a/applications/lfric_atm/metadata/grid_def_nudging_coarse.xml +++ b/applications/lfric_atm/metadata/grid_def_nudging_coarse.xml @@ -1,13 +1,13 @@ - + - + - + @@ -15,12 +15,7 @@ - - - - - - + diff --git a/applications/lfric_atm/metadata/lfric_dictionary.xml b/applications/lfric_atm/metadata/lfric_dictionary.xml index 6b713e86b..dfe2c7bfa 100644 --- a/applications/lfric_atm/metadata/lfric_dictionary.xml +++ b/applications/lfric_atm/metadata/lfric_dictionary.xml @@ -394,10 +394,10 @@ - - - - + + + + diff --git a/dependencies.yaml b/dependencies.yaml index 9bd6b263a..b29f40823 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -30,8 +30,8 @@ lfric_apps: ref: lfric_core: - source: git@github.com:MetOffice/lfric_core.git - ref: 2026.03.2 + source: git@github.com:mcdalvi/lfric_core.git + ref: vn3.1_read_coarse_2d moci: source: git@github.com:MetOffice/moci.git diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_gal_nwp_nudging.xml b/rose-stem/app/lfric_atm/file/file_def_diags_gal_nwp_nudging.xml new file mode 100644 index 000000000..0c84cbe2a --- /dev/null +++ b/rose-stem/app/lfric_atm/file/file_def_diags_gal_nwp_nudging.xml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_nudging_ref.xml b/rose-stem/app/lfric_atm/file/file_def_diags_nudging_ref.xml deleted file mode 100644 index 9331988d9..000000000 --- a/rose-stem/app/lfric_atm/file/file_def_diags_nudging_ref.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/rose-stem/app/lfric_atm/file/file_def_nudging.xml b/rose-stem/app/lfric_atm/file/file_def_nudging.xml index e68d5c714..df871bb83 100644 --- a/rose-stem/app/lfric_atm/file/file_def_nudging.xml +++ b/rose-stem/app/lfric_atm/file/file_def_nudging.xml @@ -3,10 +3,10 @@ - - - - + + + + diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml index 73a604942..b6fb4f16a 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml @@ -33,10 +33,10 @@ + - diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml index de394f16a..66dff0480 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml @@ -33,10 +33,10 @@ + - 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 7b9ef6dab..cc27e161d 100644 --- a/rose-stem/site/common/lfric_atm/tasks_lfric_atm.cylc +++ b/rose-stem/site/common/lfric_atm/tasks_lfric_atm.cylc @@ -292,7 +292,8 @@ "DT": 1800, "tsteps": 12, "mpi_parts": 24, - "log_level": "debug", + "log_level": "info", + "kgo_checks": ["checksum"], "plot_str": "plot_map.py $NODAL_DATA_DIR/lfric_gal_diagnostics.nc $PLOT_DIR", }) %} @@ -304,7 +305,8 @@ "DT": 1800, "tsteps": 12, "mpi_parts": 24, - "log_level": "debug", + "log_level": "info", + "kgo_checks": ["checksum"], "plot_str": "plot_map.py $NODAL_DATA_DIR/lfric_gal_diagnostics.nc $PLOT_DIR", }) %} diff --git a/rose-stem/site/meto/groups/groups_lfric_atm.cylc b/rose-stem/site/meto/groups/groups_lfric_atm.cylc index 53d973c90..10ed30d4a 100644 --- a/rose-stem/site/meto/groups/groups_lfric_atm.cylc +++ b/rose-stem/site/meto/groups/groups_lfric_atm.cylc @@ -127,9 +127,8 @@ "lfric_atm_nwp_gal9_mol-C12_ex1a_cce_fast-debug-32bit", ], "lfric_atm_nudging": [ - "lfric_atm_nwp_gal9_coarse_aero-C48_MG_azspice_gnu_fast-debug-64bit", - "lfric_atm_nwp_gal9_nudging-era-C48_MG_azspice_gnu_fast-debug-64bit", - "lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-64bit", + "lfric_atm_nwp_gal9_nudging-era-C48_MG_azspice_gnu_fast-debug-32bit", + "lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit", ], "lfric_atm_nwp_ex1a": [ "lfric_atm_nwp_ex1a_developer", diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-C48_MG_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-C48_MG_azspice_gnu_fast-debug-32bit.txt new file mode 100644 index 000000000..651a0c653 --- /dev/null +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-C48_MG_azspice_gnu_fast-debug-32bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 48D81340 +Inner product checksum theta = 53948143 +Inner product checksum u = 6AA37242 +Inner product checksum mr1 = 41C961D4 +Inner product checksum mr2 = 39A65F5A +Inner product checksum mr3 = 3773BE6A +Inner product checksum mr4 = 391DE516 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit.txt new file mode 100644 index 000000000..32e339584 --- /dev/null +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 48D81332 +Inner product checksum theta = 53948145 +Inner product checksum u = 6AA371CF +Inner product checksum mr1 = 41C96014 +Inner product checksum mr2 = 39A787F4 +Inner product checksum mr3 = 3776DD7E +Inner product checksum mr4 = 391EE0F5 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/science/gungho/source/algorithm/physics/external_forcing_alg_mod.X90 b/science/gungho/source/algorithm/physics/external_forcing_alg_mod.X90 index a5dc88e87..38101f17c 100644 --- a/science/gungho/source/algorithm/physics/external_forcing_alg_mod.X90 +++ b/science/gungho/source/algorithm/physics/external_forcing_alg_mod.X90 @@ -14,6 +14,7 @@ module external_forcing_alg_mod theta_forcing_shallow_hot_jupiter, & theta_forcing_deep_hot_jupiter, & theta_forcing_temp_tend, & + theta_forcing_nudging, & theta_relaxation, & vapour_forcing, & vapour_forcing_none, & @@ -24,6 +25,7 @@ module external_forcing_alg_mod wind_forcing_filtering, & wind_forcing_diffusion, & wind_forcing_profile, & + wind_forcing_nudging, & vertadvect_forcing, & geostrophic_forcing, & filtering_order, & @@ -221,6 +223,9 @@ contains call temp_tend_profile_alg( dtheta_forcing, exner_in_wth, time_now ) + case(theta_forcing_nudging) + ! DO nothing - placeholder for future, field will not be modified + case default call log_event( 'slow_physics: Incorrect theta_forcing option', & @@ -346,6 +351,12 @@ contains nullify(panel_id, height_w1, height_w2, dx_at_w2) + case ( wind_forcing_nudging ) + + ! Placeholder for future, only initialise forcing field + call du_forcing%initialise( vector_space = u%get_function_space() ) + call invoke(setval_c(du_forcing, 0.0_r_def)) + case( wind_forcing_profile ) call du_forcing%initialise( vector_space = u%get_function_space() ) diff --git a/science/gungho/source/driver/gungho_init_fields_mod.X90 b/science/gungho/source/driver/gungho_init_fields_mod.X90 index 9a4f6ef4b..27190d192 100644 --- a/science/gungho/source/driver/gungho_init_fields_mod.X90 +++ b/science/gungho/source/driver/gungho_init_fields_mod.X90 @@ -537,8 +537,6 @@ subroutine create_model_data( modeldb, & mesh, twod_mesh , & aerosol_mesh, & aerosol_twod_mesh, & - nudging_mesh, & - nudging_twod_mesh, & model_axes%ancil_times_list ) case ( ancil_option_idealised ) call create_fd_ancils_idealised( depository, & diff --git a/science/gungho/source/driver/init_ancils_mod.f90 b/science/gungho/source/driver/init_ancils_mod.f90 index b99d52b82..8d447a4b1 100644 --- a/science/gungho/source/driver/init_ancils_mod.f90 +++ b/science/gungho/source/driver/init_ancils_mod.f90 @@ -104,13 +104,8 @@ module init_ancils_mod !> @param[in] twod_mesh The current 2d mesh !> @param[in] aerosol_mesh Aerosol 3d mesh !> @param[in] aerosol_twod_mesh Aerosol 2d mesh - !> @param[in] nudging_mesh Nudging 3d mesh - !> @param[in] nudging_twod_mesh Nudging 2d mesh - !> @param[out] ancil_times_list Linked list of time axes for time-varying ancils subroutine create_fd_ancils( depository, ancil_fields, mesh, & - twod_mesh, aerosol_mesh, aerosol_twod_mesh, & - nudging_mesh, nudging_twod_mesh, & - ancil_times_list ) + twod_mesh, aerosol_mesh, aerosol_twod_mesh, ancil_times_list ) implicit none @@ -121,8 +116,6 @@ subroutine create_fd_ancils( depository, ancil_fields, mesh, & type( mesh_type ), intent(in), pointer :: twod_mesh type( mesh_type ), intent(in), pointer :: aerosol_mesh type( mesh_type ), intent(in), pointer :: aerosol_twod_mesh - type( mesh_type ), intent(in), pointer :: nudging_mesh - type( mesh_type ), intent(in), pointer :: nudging_twod_mesh type(linked_list_type), intent(out) :: ancil_times_list From 8baec12146e8264d02a6671dd9d8998bed2857ac Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Wed, 13 May 2026 15:50:33 +0100 Subject: [PATCH 08/18] modify path to point to files containing licence information --- rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf | 2 +- rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf index 96b78590f..b7e827d62 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf @@ -8,7 +8,7 @@ wind_forcing='nudging' [namelist:files] coarse_ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/C12' -nudging_directory='/data/users/thomas.bendall/nudging/era/C12' +nudging_directory='/data/users/mohit.dalvi/lfric/data/nudge/TomB/era/C12' nudging_filename='era5_nudge_L137_C12_2021032400-2706' [namelist:formulation] diff --git a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf index 02c20af11..3c1109f67 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf @@ -7,7 +7,7 @@ theta_forcing='nudging' wind_forcing='nudging' [namelist:files] -nudging_directory='/data/users/thomas.bendall/nudging/era/C48' +nudging_directory='/data/users/mohit.dalvi/lfric/data/nudge/TomB/era/C48' nudging_filename='era5_nudge_L137_C48_MG_2021032400-2706' [namelist:multires_coupling] From ea8533160c59f2f185d4acaf46a609f17addcc4c Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Wed, 13 May 2026 17:04:50 +0100 Subject: [PATCH 09/18] Minor fixes, style fixer, update KGOs --- ...ra-C48_MG_azspice_gnu_fast-debug-32bit.txt | 14 ++--- ...se-C48_MG_azspice_gnu_fast-debug-32bit.txt | 12 ++-- .../driver/create_physics_prognostics_mod.F90 | 56 +++++++++---------- .../gungho/source/driver/gungho_model_mod.F90 | 2 +- .../multidata_field_dimensions_mod.F90 | 2 +- .../source/driver/linear_driver_mod.f90 | 7 --- 6 files changed, 43 insertions(+), 50 deletions(-) diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-C48_MG_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-C48_MG_azspice_gnu_fast-debug-32bit.txt index 651a0c653..d036e49f5 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-C48_MG_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-C48_MG_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D81340 -Inner product checksum theta = 53948143 -Inner product checksum u = 6AA37242 -Inner product checksum mr1 = 41C961D4 -Inner product checksum mr2 = 39A65F5A -Inner product checksum mr3 = 3773BE6A -Inner product checksum mr4 = 391DE516 +Inner product checksum rho = 48D81327 +Inner product checksum theta = 53948139 +Inner product checksum u = 6AA3743B +Inner product checksum mr1 = 41C95D15 +Inner product checksum mr2 = 39A8395C +Inner product checksum mr3 = 37753FED +Inner product checksum mr4 = 391E26F0 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit.txt index 32e339584..2437c0d92 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D81332 +Inner product checksum rho = 48D8133B Inner product checksum theta = 53948145 -Inner product checksum u = 6AA371CF -Inner product checksum mr1 = 41C96014 -Inner product checksum mr2 = 39A787F4 -Inner product checksum mr3 = 3776DD7E -Inner product checksum mr4 = 391EE0F5 +Inner product checksum u = 6AA372D7 +Inner product checksum mr1 = 41C95E7C +Inner product checksum mr2 = 39A7957B +Inner product checksum mr3 = 376E1328 +Inner product checksum mr4 = 391E40AA Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/science/gungho/source/driver/create_physics_prognostics_mod.F90 b/science/gungho/source/driver/create_physics_prognostics_mod.F90 index 39156b66c..18271e6f8 100644 --- a/science/gungho/source/driver/create_physics_prognostics_mod.F90 +++ b/science/gungho/source/driver/create_physics_prognostics_mod.F90 @@ -1695,7 +1695,7 @@ subroutine process_physics_prognostics(processor) ckp=checkpoint_flag)) ! Accumulation soluble sea salt aerosol mmr call processor%apply(make_spec('acc_sol_ss', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & - coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), & + coarse_mesh_name=mesh_name, adv_coll=if_adv(advection_flag, adv%last_con), & ckp=checkpoint_flag)) ! Coarse soluble mode number mixing ratio call processor%apply(make_spec('n_cor_sol', main%aerosol, Wtheta, coarse=coarse_rad_aerosol, & @@ -1780,85 +1780,85 @@ subroutine process_physics_prognostics(processor) call processor%apply(make_spec('drydp_cor_ins', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Wet diameter Aitken mode (Soluble) - call processor%apply(make_spec('wetdp_ait_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('wetdp_ait_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Wet diameter Accumulation mode (Soluble) - call processor%apply(make_spec('wetdp_acc_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('wetdp_acc_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Wet diameter Coarse mode (Soluble) - call processor%apply(make_spec('wetdp_cor_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('wetdp_cor_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Particle density Aitken mode (Soluble) - call processor%apply(make_spec('rhopar_ait_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('rhopar_ait_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Particle density Accumulation mode (Soluble) - call processor%apply(make_spec('rhopar_acc_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('rhopar_acc_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Particle density Coarse mode (Soluble) - call processor%apply(make_spec('rhopar_cor_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('rhopar_cor_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Particle density Aitken mode (Insoluble) - call processor%apply(make_spec('rhopar_ait_ins', main%aerosol, Wtheta, & + call processor%apply(make_spec('rhopar_ait_ins', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Particle density Accumulation mode (Insoluble) - call processor%apply(make_spec('rhopar_acc_ins', main%aerosol, Wtheta, & + call processor%apply(make_spec('rhopar_acc_ins', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Particle density Coarse mode (Insoluble) - call processor%apply(make_spec('rhopar_cor_ins', main%aerosol, Wtheta, & + call processor%apply(make_spec('rhopar_cor_ins', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume of water Aitken mode (Soluble) - call processor%apply(make_spec('pvol_wat_ait_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_wat_ait_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume of water Accumulation mode (Soluble) - call processor%apply(make_spec('pvol_wat_acc_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_wat_acc_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume of water Coarse mode (Soluble) - call processor%apply(make_spec('pvol_wat_cor_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_wat_cor_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Sulphate Aitken mode (Soluble) - call processor%apply(make_spec('pvol_su_ait_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_su_ait_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Black Carbon Aitken mode (Soluble) - call processor%apply(make_spec('pvol_bc_ait_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_bc_ait_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Organic Matter Aitken mode (Soluble) - call processor%apply(make_spec('pvol_om_ait_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_om_ait_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Sulphate Accumulation mode (Soluble) - call processor%apply(make_spec('pvol_su_acc_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_su_acc_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Black Carbon Accumulation mode (Soluble) - call processor%apply(make_spec('pvol_bc_acc_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_bc_acc_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Organic Matter Accumulation mode (Soluble) - call processor%apply(make_spec('pvol_om_acc_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_om_acc_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Sea Salt Accumulation mode (Soluble) - call processor%apply(make_spec('pvol_ss_acc_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_ss_acc_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Sulphate Coarse mode (Soluble) - call processor%apply(make_spec('pvol_su_cor_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_su_cor_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Black Carbon Coarse mode (Soluble) - call processor%apply(make_spec('pvol_bc_cor_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_bc_cor_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Organic Matter Coarse mode (Soluble) - call processor%apply(make_spec('pvol_om_cor_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_om_cor_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Sea Salt Coarse mode (Soluble) - call processor%apply(make_spec('pvol_ss_cor_sol', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_ss_cor_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Black Carbon Aitken mode (Insoluble) - call processor%apply(make_spec('pvol_bc_ait_ins', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_bc_ait_ins', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Organic Matter Aitken mode (Insoluble) - call processor%apply(make_spec('pvol_om_ait_ins', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_om_ait_ins', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Dust Accumulation mode (Insoluble) - call processor%apply(make_spec('pvol_du_acc_ins', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_du_acc_ins', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) ! Partial volume component Dust Coarse mode (Insoluble) - call processor%apply(make_spec('pvol_du_cor_ins', main%aerosol, Wtheta, & + call processor%apply(make_spec('pvol_du_cor_ins', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) end if diff --git a/science/gungho/source/driver/gungho_model_mod.F90 b/science/gungho/source/driver/gungho_model_mod.F90 index 20b95dd39..2f6075088 100644 --- a/science/gungho/source/driver/gungho_model_mod.F90 +++ b/science/gungho/source/driver/gungho_model_mod.F90 @@ -272,7 +272,7 @@ subroutine before_context_close(clock) logical(l_def) :: to_process_nudging_fields #ifdef UM_PHYSICS integer(i_def) :: i -#endif +#endif DT = clock%get_seconds_per_step() call set_variable("DT", DT, tolerant=.true.) diff --git a/science/gungho/source/physics/multidata_field_dimensions_mod.F90 b/science/gungho/source/physics/multidata_field_dimensions_mod.F90 index 0f09472cb..ae8c9a72d 100644 --- a/science/gungho/source/physics/multidata_field_dimensions_mod.F90 +++ b/science/gungho/source/physics/multidata_field_dimensions_mod.F90 @@ -28,7 +28,7 @@ module multidata_field_dimensions_mod #ifdef UM_PHYSICS ! 1 2 3 ! 123456789012345678901234567890 - character(30), parameter :: multidata_items(34) = & + character(30), parameter :: multidata_items(35) = & [character(30) :: & 'plant_func_types', & 'sea_ice_categories', & diff --git a/science/linear/source/driver/linear_driver_mod.f90 b/science/linear/source/driver/linear_driver_mod.f90 index bc211857a..1118624c7 100644 --- a/science/linear/source/driver/linear_driver_mod.f90 +++ b/science/linear/source/driver/linear_driver_mod.f90 @@ -142,13 +142,6 @@ subroutine initialise( program_name, modeldb ) coarse_ozone_ancil = modeldb%config%initialization%coarse_ozone_ancil() init_option = modeldb%config%initialization%init_option() - ! Get information on any multi-resolution meshes - multires_coupling_nml => & - modeldb%configuration%get_namelist('multires_coupling') - - call multires_coupling_nml%get_value( 'coarse_nudging', & - coarse_nudging ) - ! If aerosol data is on a different mesh, get this if (coarse_aerosol_ancil .or. coarse_ozone_ancil) then aerosol_mesh_name = modeldb%config%multires_coupling%aerosol_mesh_name() From d4f3adcc3a2f1b4615500cd388fc1d4291ddf11f Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Thu, 14 May 2026 10:43:37 +0100 Subject: [PATCH 10/18] Metadata fiex and re-alignment with configuration variables in modeldb object --- .../jedi_lfric_linear_modeldb_driver_mod.f90 | 24 ++++--- .../opt/rose-app-nudging-era-coarse.conf | 12 ++-- .../lfric_atm/opt/rose-app-nudging-era.conf | 12 ++-- .../lfric-gungho/HEAD/rose-meta.conf | 36 +++++----- .../gungho/rose-meta/lfric-gungho/versions.py | 68 +++++++++---------- .../source/driver/linear_driver_mod.f90 | 22 +++--- 6 files changed, 89 insertions(+), 85 deletions(-) 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 e115b6e7e..e1b5c879c 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 @@ -181,17 +181,19 @@ subroutine initialise_modeldb( modeldb_name, filename, mpi_obj, modeldb, atl_si_ end if ! Get information on nudging and if data is on a different mesh, get this - coarse_nudging = modeldb%config%multires_coupling%coarse_nudging() - if (coarse_nudging) then - ! For now use the coarsest mesh - nudging_mesh_name = modeldb%config%multires_coupling%nudging_mesh_name() - nudging_mesh => mesh_collection%get_mesh(nudging_mesh_name) - nudging_twod_mesh => mesh_collection%get_mesh(nudging_mesh, TWOD) - write( log_scratch_space,'(A,A)' ) "nudging mesh name:", nudging_mesh%get_mesh_name() - call log_event( log_scratch_space, LOG_LEVEL_TRACE ) - else - nudging_mesh => mesh - nudging_twod_mesh => twod_mesh + ! Use prime mesh by default + nudging_mesh => mesh + nudging_twod_mesh => twod_mesh + if ( modeldb%config%formulation%use_multires_coupling() ) then + coarse_nudging = modeldb%config%multires_coupling%coarse_nudging() + if (coarse_nudging) then + ! For now use the coarsest mesh + nudging_mesh_name = modeldb%config%multires_coupling%nudging_mesh_name() + nudging_mesh => mesh_collection%get_mesh(nudging_mesh_name) + nudging_twod_mesh => mesh_collection%get_mesh(nudging_mesh, TWOD) + write( log_scratch_space,'(A,A)' ) "nudging mesh name:", nudging_mesh%get_mesh_name() + call log_event( log_scratch_space, LOG_LEVEL_TRACE ) + end if end if ! Instantiate the fields stored in model_data diff --git a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf index b7e827d62..f21827790 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf @@ -20,21 +20,21 @@ coarse_ozone_ancil=.true. [namelist:multires_coupling] aerosol_mesh_name='multigrid_l2' -coarse_rad_aerosol=.true. coarse_nudging=.true. +coarse_rad_aerosol=.true. lowest_order_aero_flag=.false. multires_coupling_mesh_tags='dynamics','multigrid_l2' +nudging_mesh_name='multigrid_l2' orography_mesh_name='dynamics' physics_mesh_name='dynamics' -nudging_mesh_name='multigrid_l2' - -[namelist:section_choice] -external_forcing=.true. [namelist:nudging] nudge_data_levels=137 nudging_level_bottom=5 nudging_level_top=52 +nudging_source='era' nudging_width_bottom=1 nudging_width_top=2 -nudging_source='era' + +[namelist:section_choice] +external_forcing=.true. diff --git a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf index 3c1109f67..25a1aea81 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf @@ -12,21 +12,21 @@ nudging_filename='era5_nudge_L137_C48_MG_2021032400-2706' [namelist:multires_coupling] aerosol_mesh_name='dynamics' -coarse_rad_aerosol=.false. coarse_nudging=.false. +coarse_rad_aerosol=.false. lowest_order_aero_flag=.false. multires_coupling_mesh_tags='dynamics' +nudging_mesh_name='dynamics' orography_mesh_name='dynamics' physics_mesh_name='dynamics' -nudging_mesh_name='dynamics' - -[namelist:section_choice] -external_forcing=.true. [namelist:nudging] nudge_data_levels=137 nudging_level_bottom=5 nudging_level_top=52 +nudging_source='era' nudging_width_bottom=1 nudging_width_top=2 -nudging_source='era' + +[namelist:section_choice] +external_forcing=.true. diff --git a/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf b/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf index ab9e0eb72..ca218772d 100644 --- a/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf +++ b/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf @@ -3734,16 +3734,6 @@ help=If this is set to true, aerosols will be transported on the coarse aerosol sort-key=Section-A03b type=logical -[namelist:multires_coupling=coarse_rad_aerosol] -compulsory=true -description=Whether to run RADAER, the Jones CDNC calculation, and the - =stratospheric aerosol climatology on a coarse mesh. Resolution of the - =mesh is that of aerosol_mesh_name -help= -!kind=default -sort-key=Section-A08 -type=logical - [namelist:multires_coupling=coarse_nudging] compulsory=true description=Whether to apply nudging on a coarser mesh than that used @@ -3754,6 +3744,16 @@ sort-key=Section-A09 trigger=namelist:multires_coupling=nudging_mesh_name: true ; type=logical +[namelist:multires_coupling=coarse_rad_aerosol] +compulsory=true +description=Whether to run RADAER, the Jones CDNC calculation, and the + =stratospheric aerosol climatology on a coarse mesh. Resolution of the + =mesh is that of aerosol_mesh_name +help= +!kind=default +sort-key=Section-A08 +type=logical + [namelist:multires_coupling=dynamics_mesh_name] compulsory=false description=Tag-name for mesh used by dynamics @@ -3811,6 +3811,14 @@ sort-key=Panel-A05 value-titles=none, one_by_one, consistent values='none', 'one_by_one', 'consistent' +[namelist:multires_coupling=nudging_mesh_name] +compulsory=false +description=Name of the mesh used for applying nudging. +help= +sort-key=Panel-A09 +!string_length=default +type=character + [namelist:multires_coupling=orography_mesh_name] compulsory=false description=Name of the mesh used for reading in orography data @@ -3853,14 +3861,6 @@ sort-key=Panel-A07 value-titles=constant, linear values='constant', 'linear' -[namelist:multires_coupling=nudging_mesh_name] -compulsory=false -description=Name of the mesh used for applying nudging. -help= -sort-key=Panel-A09 -!string_length=default -type=character - #============================================================================== # NUDGING #============================================================================== diff --git a/science/gungho/rose-meta/lfric-gungho/versions.py b/science/gungho/rose-meta/lfric-gungho/versions.py index 63332d2a5..1a2c0aab1 100644 --- a/science/gungho/rose-meta/lfric-gungho/versions.py +++ b/science/gungho/rose-meta/lfric-gungho/versions.py @@ -30,6 +30,7 @@ def upgrade(self, config, meta_config=None): return config, self.reports """ + class vn31_t118(MacroUpgrade): """Upgrade macro for ticket TTTT by Unknown.""" @@ -129,7 +130,6 @@ def upgrade(self, config, meta_config=None): self.add_setting( config, ["namelist:iau_bcorr_io(bcorr1)", "name"], "''" ) - return config, self.reports @@ -144,48 +144,48 @@ def upgrade(self, config, meta_config=None): self.add_setting( config, ["namelist:cloud", "pc2_turb_horiz"], ".false." ) - return config, self.reports + class vn31_t474(MacroUpgrade): - # Upgrade macro for #474 by Mohit Dalvi - # Add namelist and related items for Nudging functionality + """Upgrade macro for ticket #474 by Mohit Dalvi.""" BEFORE_TAG = "vn3.1_t464" AFTER_TAG = "vn3.1_t474" def upgrade(self, config, meta_config=None): - # Add settings - new items in files and multires_coupling - self.add_setting( config, - ["namelist:files", "nudging_directory"],"''") - self.add_setting( config, - ["namelist:files", "nudging_filename"],"''") - - self.add_setting( config, - ["namelist:multires_coupling", "coarse_nudging"], ".false," ) - self.add_setting( config, - ["namelist:multires_coupling", "nudging_mesh_name"], "''") - - # Add new nudging namelist + # Commands From: rose-meta/lfric-gungho + self.add_setting(config, ["namelist:files", "nudging_directory"], "''") + self.add_setting(config, ["namelist:files", "nudging_filename"], "''") + self.add_setting( + config, ["namelist:multires_coupling", "coarse_nudging"], ".false.," + ) + self.add_setting( + config, ["namelist:multires_coupling", "nudging_mesh_name"], "''" + ) + # Add new nudging namelist # Append after 'multires_coupling' in configuration.nml - source = self.get_setting_value( config, - ["file:configuration.nml","source"] ) - source = re.sub(r'(namelist:multires_coupling)', - r'(namelist:multires_coupling)' + '\n' + ' (namelist:nudging)', - source) - self.change_setting_value( config, - ["file:configuration.nml","source"], source ) - + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"(namelist:multires_coupling)", + r"(namelist:multires_coupling)" + "\n" + " (namelist:nudging)", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) self.add_setting(config, ["namelist:nudging"]) - self.add_setting(config, ["namelist:nudging","nudge_data_levels"], 0 ) - self.add_setting(config, - ["namelist:nudging","nudging_level_bottom"], 0 ) - self.add_setting(config, - ["namelist:nudging","nudging_level_top"], 0 ) - self.add_setting(config, ["namelist:nudging","nudge_source"], "''" ) - self.add_setting(config, - ["namelist:nudging","nudging_width_bottom"], 0 ) - self.add_setting(config, - ["namelist:nudging","nudging_width_top"], 0 ) + self.add_setting(config, ["namelist:nudging", "nudge_data_levels"], "0") + self.add_setting( + config, ["namelist:nudging", "nudging_level_bottom"], "0" + ) + self.add_setting(config, ["namelist:nudging", "nudging_level_top"], "0") + self.add_setting(config, ["namelist:nudging", "nudging_source"], "''") + self.add_setting( + config, ["namelist:nudging", "nudging_width_bottom"], "0" + ) + self.add_setting(config, ["namelist:nudging", "nudging_width_top"], "0") return config, self.reports diff --git a/science/linear/source/driver/linear_driver_mod.f90 b/science/linear/source/driver/linear_driver_mod.f90 index 1118624c7..60a0152f4 100644 --- a/science/linear/source/driver/linear_driver_mod.f90 +++ b/science/linear/source/driver/linear_driver_mod.f90 @@ -155,16 +155,18 @@ subroutine initialise( program_name, modeldb ) end if ! Get information on nudging and if data is on a different mesh, get this - coarse_nudging = modeldb%config%multires_coupling%coarse_nudging() - if (coarse_nudging) then - nudging_mesh_name = modeldb%config%multires_coupling%nudging_mesh_name() - nudging_mesh => mesh_collection%get_mesh(nudging_mesh_name) - nudging_twod_mesh => mesh_collection%get_mesh(nudging_mesh, TWOD) - write( log_scratch_space,'(A,A)' ) "nudging mesh name:", nudging_mesh%get_mesh_name() - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - else - nudging_mesh => mesh - nudging_twod_mesh => twod_mesh + ! Use the prim mesh by default + nudging_mesh => mesh + nudging_twod_mesh => twod_mesh + if ( modeldb%config%formulation%use_multires_coupling() ) then + coarse_nudging = modeldb%config%multires_coupling%coarse_nudging() + if (coarse_nudging) then + nudging_mesh_name = modeldb%config%multires_coupling%nudging_mesh_name() + nudging_mesh => mesh_collection%get_mesh(nudging_mesh_name) + nudging_twod_mesh => mesh_collection%get_mesh(nudging_mesh, TWOD) + write( log_scratch_space,'(A,A)' ) "nudging mesh name:", nudging_mesh%get_mesh_name() + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + end if end if ! Instantiate the fields stored in model_data From 50f08f38eeb0274f96550815246f01c8cb17d2d0 Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Thu, 14 May 2026 13:00:12 +0100 Subject: [PATCH 11/18] more metadata and style fixes --- rose-stem/app/lfric_atm/rose-app.conf | 1 - science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf | 2 +- science/gungho/rose-meta/lfric-gungho/versions.py | 4 ++-- science/linear/source/driver/linear_driver_mod.f90 | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/rose-stem/app/lfric_atm/rose-app.conf b/rose-stem/app/lfric_atm/rose-app.conf index 2a83c1f17..ad487da88 100644 --- a/rose-stem/app/lfric_atm/rose-app.conf +++ b/rose-stem/app/lfric_atm/rose-app.conf @@ -68,7 +68,6 @@ source=(namelist:aerosol) = namelist:mixing = (namelist:multigrid) = (namelist:multires_coupling) - = (namelist:nudging) = namelist:esm_couple = (namelist:orbit) = namelist:orography diff --git a/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf b/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf index ca218772d..358da64cc 100644 --- a/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf +++ b/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf @@ -3741,7 +3741,7 @@ description=Whether to apply nudging on a coarser mesh than that used help=The mesh is given by the nudging_mesh_name option. !kind=default sort-key=Section-A09 -trigger=namelist:multires_coupling=nudging_mesh_name: true ; +trigger=namelist:multires_coupling=nudging_mesh_name: .true. ; type=logical [namelist:multires_coupling=coarse_rad_aerosol] diff --git a/science/gungho/rose-meta/lfric-gungho/versions.py b/science/gungho/rose-meta/lfric-gungho/versions.py index 1a2c0aab1..1ab5651e2 100644 --- a/science/gungho/rose-meta/lfric-gungho/versions.py +++ b/science/gungho/rose-meta/lfric-gungho/versions.py @@ -158,7 +158,7 @@ def upgrade(self, config, meta_config=None): self.add_setting(config, ["namelist:files", "nudging_directory"], "''") self.add_setting(config, ["namelist:files", "nudging_filename"], "''") self.add_setting( - config, ["namelist:multires_coupling", "coarse_nudging"], ".false.," + config, ["namelist:multires_coupling", "coarse_nudging"], ".false.", ) self.add_setting( config, ["namelist:multires_coupling", "nudging_mesh_name"], "''" @@ -170,7 +170,7 @@ def upgrade(self, config, meta_config=None): ) source = re.sub( r"(namelist:multires_coupling)", - r"(namelist:multires_coupling)" + "\n" + " (namelist:nudging)", + r"namelist:multires_coupling)" + "\n" + " (namelist:nudging", source, ) self.change_setting_value( diff --git a/science/linear/source/driver/linear_driver_mod.f90 b/science/linear/source/driver/linear_driver_mod.f90 index 60a0152f4..cfef35a93 100644 --- a/science/linear/source/driver/linear_driver_mod.f90 +++ b/science/linear/source/driver/linear_driver_mod.f90 @@ -166,7 +166,7 @@ subroutine initialise( program_name, modeldb ) nudging_twod_mesh => mesh_collection%get_mesh(nudging_mesh, TWOD) write( log_scratch_space,'(A,A)' ) "nudging mesh name:", nudging_mesh%get_mesh_name() call log_event( log_scratch_space, LOG_LEVEL_INFO ) - end if + end if end if ! Instantiate the fields stored in model_data From 772383438dba1de2182d78ffc253a9e34597a95b Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Fri, 15 May 2026 19:29:50 +0100 Subject: [PATCH 12/18] Changes in response to Code owner review: Remove new fields from xml definition and diagnostic list - this requires creating the fields in main%none --- .../lfric_atm/metadata/lfric_dictionary.xml | 5 - .../file/file_def_diags_gal_nwp_nudging.xml | 189 ------------------ .../file/iodef_gal_nwp_coarse_nudging.xml | 2 +- .../lfric_atm/file/iodef_gal_nwp_nudging.xml | 2 +- .../opt/rose-app-nudging-era-coarse.conf | 2 +- .../lfric_atm/opt/rose-app-nudging-era.conf | 2 +- .../common/lfric_atm/tasks_lfric_atm.cylc | 4 +- .../lfric-gungho/HEAD/rose-meta.conf | 9 +- .../gungho/rose-meta/lfric-gungho/versions.py | 12 +- .../driver/create_nudging_fields_mod.f90 | 8 +- .../source/driver/gungho_init_fields_mod.X90 | 1 - 11 files changed, 23 insertions(+), 213 deletions(-) delete mode 100644 rose-stem/app/lfric_atm/file/file_def_diags_gal_nwp_nudging.xml diff --git a/applications/lfric_atm/metadata/lfric_dictionary.xml b/applications/lfric_atm/metadata/lfric_dictionary.xml index 561ade32f..c38579818 100644 --- a/applications/lfric_atm/metadata/lfric_dictionary.xml +++ b/applications/lfric_atm/metadata/lfric_dictionary.xml @@ -399,11 +399,6 @@ - - - - - diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_gal_nwp_nudging.xml b/rose-stem/app/lfric_atm/file/file_def_diags_gal_nwp_nudging.xml deleted file mode 100644 index 0c84cbe2a..000000000 --- a/rose-stem/app/lfric_atm/file/file_def_diags_gal_nwp_nudging.xml +++ /dev/null @@ -1,189 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml index b6fb4f16a..443285ca5 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml @@ -33,7 +33,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml index 66dff0480..502ebabc4 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_nudging.xml @@ -33,7 +33,7 @@ - + diff --git a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf index f21827790..2e60d2242 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf @@ -34,7 +34,7 @@ nudging_level_bottom=5 nudging_level_top=52 nudging_source='era' nudging_width_bottom=1 -nudging_width_top=2 +nudging_width_top=0 [namelist:section_choice] external_forcing=.true. diff --git a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf index 25a1aea81..a53fac6a6 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf @@ -26,7 +26,7 @@ nudging_level_bottom=5 nudging_level_top=52 nudging_source='era' nudging_width_bottom=1 -nudging_width_top=2 +nudging_width_top=0 [namelist:section_choice] external_forcing=.true. 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 f48f743c0..ee879ce7f 100644 --- a/rose-stem/site/common/lfric_atm/tasks_lfric_atm.cylc +++ b/rose-stem/site/common/lfric_atm/tasks_lfric_atm.cylc @@ -282,7 +282,7 @@ "mpi_parts": 24, "log_level": "info", "kgo_checks": ["checksum"], - "plot_str": "plot_map.py $NODAL_DATA_DIR/lfric_gal_diagnostics.nc $PLOT_DIR", + "plot_str": "plot_map.py $NODAL_DATA_DIR/lfric_diagnostics.nc $PLOT_DIR", }) %} {% elif task_ns.conf_name == "nwp_gal9_nudging-era-coarse-C48_MG" %} @@ -295,7 +295,7 @@ "mpi_parts": 24, "log_level": "info", "kgo_checks": ["checksum"], - "plot_str": "plot_map.py $NODAL_DATA_DIR/lfric_gal_diagnostics.nc $PLOT_DIR", + "plot_str": "plot_map.py $NODAL_DATA_DIR/lfric_diagnostics.nc $PLOT_DIR", }) %} {% elif task_ns.conf_name == "nwp_gal9_coarse_aero_threaded-C48_MG" %} diff --git a/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf b/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf index 358da64cc..3939431e1 100644 --- a/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf +++ b/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf @@ -1044,8 +1044,7 @@ help=Available forcing options are: = Schneider, T. (2010), Atmospheric Dynamics of Earth-Like Tidally Locked = Aquaplanets, J. Adv. Model. Earth Syst., 2, 13, doi:10.3894/JAMES.2010.2.13. =Temperature tendency profile: apply a specified profile of heating rates - =Nudging: nudges the global spectrum towards that of a specified - = reference state. + =Nudging: nudges towards a specified reference state. Currently does not modify field, only activates nudging namelist for reference data input. !kind=default ns=namelist/Science/External Forcing sort-key=A1 @@ -1053,6 +1052,9 @@ trigger=namelist:external_forcing=hs_random: this == "'held_suarez'" ; =namelist:temp_tend_data: this == "'temp_tend'"; =namelist:external_forcing=pc2_force_response: this != "'none'"; =namelist:nudging: this == "'nudging'"; + =namelist:multires_coupling=coarse_nudging: this == "'nudging'"; + =namelist:files=nudging_directory: this == "'nudging'"; + =namelist:files=nudging_filename: this == "'nudging'"; value-titles=None, Held-Suarez, Earth-Like, Tidally Locked Earth, =Shallow Hot Jupiter, Deep Hot Jupiter, Temperature Tendency Profile, =Nudging @@ -1133,6 +1135,9 @@ trigger=namelist:external_forcing=filtering_order: this == "'filtering'"; =namelist:external_forcing=diffusion_order: this == "'diffusion'"; =namelist:external_forcing=diffusion_coefficient: this == "'diffusion'"; =namelist:nudging: this == "'nudging'"; + =namelist:multires_coupling=coarse_nudging: this == "'nudging'"; + =namelist:files=nudging_directory: this == "'nudging'"; + =namelist:files=nudging_filename: this == "'nudging'", =namelist:wind_forcing: this == "'profile'"; value-titles=None, Held-Suarez, Filtering, Diffusion, Profile, Nudging values='none','held_suarez', 'filtering', 'diffusion', 'profile', 'nudging' diff --git a/science/gungho/rose-meta/lfric-gungho/versions.py b/science/gungho/rose-meta/lfric-gungho/versions.py index 1ab5651e2..6171fb5bd 100644 --- a/science/gungho/rose-meta/lfric-gungho/versions.py +++ b/science/gungho/rose-meta/lfric-gungho/versions.py @@ -163,7 +163,7 @@ def upgrade(self, config, meta_config=None): self.add_setting( config, ["namelist:multires_coupling", "nudging_mesh_name"], "''" ) - # Add new nudging namelist + # Add new nudging namelist -with sensible default values # Append after 'multires_coupling' in configuration.nml source = self.get_setting_value( config, ["file:configuration.nml", "source"] @@ -177,14 +177,14 @@ def upgrade(self, config, meta_config=None): config, ["file:configuration.nml", "source"], source ) self.add_setting(config, ["namelist:nudging"]) - self.add_setting(config, ["namelist:nudging", "nudge_data_levels"], "0") + self.add_setting(config, ["namelist:nudging", "nudge_data_levels"], "137") self.add_setting( - config, ["namelist:nudging", "nudging_level_bottom"], "0" + config, ["namelist:nudging", "nudging_level_bottom"], "5" ) - self.add_setting(config, ["namelist:nudging", "nudging_level_top"], "0") - self.add_setting(config, ["namelist:nudging", "nudging_source"], "''") + self.add_setting(config, ["namelist:nudging", "nudging_level_top"], "52") + self.add_setting(config, ["namelist:nudging", "nudging_source"], "'era'") self.add_setting( - config, ["namelist:nudging", "nudging_width_bottom"], "0" + config, ["namelist:nudging", "nudging_width_bottom"], "1" ) self.add_setting(config, ["namelist:nudging", "nudging_width_top"], "0") diff --git a/science/gungho/source/driver/create_nudging_fields_mod.f90 b/science/gungho/source/driver/create_nudging_fields_mod.f90 index ddf5cd071..ba799a661 100644 --- a/science/gungho/source/driver/create_nudging_fields_mod.f90 +++ b/science/gungho/source/driver/create_nudging_fields_mod.f90 @@ -77,7 +77,7 @@ subroutine process_nudging_fields(processor) !------ Fields updated directly from nudging file----------------- call processor%apply(make_spec( & - 'surface_pressure_nudging_ext_ref', main%derived, W3, & + 'surface_pressure_nudging_ext_ref', main%none, W3, & coarse=coarse_nudging, & coarse_mesh_name=nudging_mesh_name, & twod=.true., time_axis=axis%nudging & @@ -85,7 +85,7 @@ subroutine process_nudging_fields(processor) if ( theta_forcing == theta_forcing_nudging ) then call processor%apply(make_spec( & - 'temperature_nudging_ext_ref', main%derived, W3, twod=.true., & + 'temperature_nudging_ext_ref', main%none, W3, twod=.true., & coarse=coarse_nudging, & coarse_mesh_name=nudging_mesh_name, & mult='ecmwf_levels', time_axis=axis%nudging & @@ -94,13 +94,13 @@ subroutine process_nudging_fields(processor) if ( wind_forcing == wind_forcing_nudging ) then call processor%apply(make_spec( & - 'u_nudging_ext_ref', main%derived, W3, twod=.true., & + 'u_nudging_ext_ref', main%none, W3, twod=.true., & coarse=coarse_nudging, & coarse_mesh_name=nudging_mesh_name, & mult='ecmwf_levels', time_axis=axis%nudging & )) call processor%apply(make_spec( & - 'v_nudging_ext_ref', main%derived, W3, twod=.true., & + 'v_nudging_ext_ref', main%none, W3, twod=.true., & coarse=coarse_nudging, & coarse_mesh_name=nudging_mesh_name, & mult='ecmwf_levels', time_axis=axis%nudging & diff --git a/science/gungho/source/driver/gungho_init_fields_mod.X90 b/science/gungho/source/driver/gungho_init_fields_mod.X90 index d0e8f44f3..69570038e 100644 --- a/science/gungho/source/driver/gungho_init_fields_mod.X90 +++ b/science/gungho/source/driver/gungho_init_fields_mod.X90 @@ -80,7 +80,6 @@ module gungho_init_fields_mod use create_gungho_prognostics_mod, only : create_gungho_prognostics use create_physics_prognostics_mod, only : create_physics_prognostics use create_nudging_fields_mod, only : create_nudging_fields - use variable_fields_mod, only : update_variable_fields use field_mapper_mod, only : field_mapper_type use map_fd_to_prognostics_alg_mod, only : map_fd_to_prognostics use gungho_init_prognostics_driver_mod, only : init_gungho_prognostics From d48f52415896f7dbbc7408ddabb470f9e216b429 Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Mon, 18 May 2026 12:54:45 +0100 Subject: [PATCH 13/18] Rename test group to reflect target system and add to *lfric_atm_azspice_extra* --- rose-stem/site/meto/groups/groups_lfric_atm.cylc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/rose-stem/site/meto/groups/groups_lfric_atm.cylc b/rose-stem/site/meto/groups/groups_lfric_atm.cylc index 968304d46..f129fd4b7 100644 --- a/rose-stem/site/meto/groups/groups_lfric_atm.cylc +++ b/rose-stem/site/meto/groups/groups_lfric_atm.cylc @@ -63,6 +63,10 @@ "lfric_atm_scm_hd209458b-BiP2x2-50000x50000_azspice_gnu_fast-debug-32bit", "lfric_atm_canned_azspice_gnu_fast-debug-32bit", ], + "lfric_atm_azspice_nudging": [ + "lfric_atm_nwp_gal9_nudging-era-C48_MG_azspice_gnu_fast-debug-32bit", + "lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit", + ], "lfric_atm_azspice_developer": [ "lfric_atm_nwp_azspice_developer", "lfric_atm_clim_gal9-C12_azspice_gnu_fast-debug-32bit", @@ -79,6 +83,7 @@ "lfric_atm_thai_ben1-C48_MG_azspice_gnu_fast-debug-32bit", "lfric_atm_hd209458b-C24_azspice_gnu_fast-debug-32bit", "lfric_atm_camembert_case3_gj1214b-C12_azspice_gnu_fast-debug-32bit", + "lfric_atm_azspice_nudging", ], "lfric_atm_azspice": [ "lfric_atm_azspice_developer", @@ -128,10 +133,6 @@ "lfric_atm_nwp_comorph_dev-C12_ex1a_cce_fast-debug-32bit", "lfric_atm_nwp_gal9_mol-C12_ex1a_cce_fast-debug-32bit", ], - "lfric_atm_nudging": [ - "lfric_atm_nwp_gal9_nudging-era-C48_MG_azspice_gnu_fast-debug-32bit", - "lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit", - ], "lfric_atm_nwp_ex1a": [ "lfric_atm_nwp_ex1a_developer", "lfric_atm_nwp_ex1a_extra", From 642225b128254d9e8adccdd26329121dc8ba2130 Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Tue, 19 May 2026 18:00:09 +0100 Subject: [PATCH 14/18] Changes from review -configure *nudging_era_coarse* test to use coarse mesh only for nudging. Use ERA files inverted from original top-bottom order (level=1=top) to bottom-top order --- applications/lfric_atm/metadata/axis_def_main.xml | 2 +- .../app/lfric_atm/file/iodef_gal_nwp_coarse_aero.xml | 1 - .../lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml | 4 ++-- .../app/lfric_atm/opt/rose-app-nudging-era-coarse.conf | 10 +++------- rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf | 2 +- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/applications/lfric_atm/metadata/axis_def_main.xml b/applications/lfric_atm/metadata/axis_def_main.xml index ae953fe7e..49b923c58 100644 --- a/applications/lfric_atm/metadata/axis_def_main.xml +++ b/applications/lfric_atm/metadata/axis_def_main.xml @@ -33,7 +33,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_aero.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_aero.xml index 3cda0885d..c02613ad8 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_aero.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_aero.xml @@ -20,7 +20,6 @@ - diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml index 443285ca5..d3d40a314 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_nudging.xml @@ -18,8 +18,8 @@ - - + + diff --git a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf index 2e60d2242..c3ca347bb 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era-coarse.conf @@ -8,20 +8,16 @@ wind_forcing='nudging' [namelist:files] coarse_ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/C12' -nudging_directory='/data/users/mohit.dalvi/lfric/data/nudge/TomB/era/C12' +nudging_directory='/data/users/mohit.dalvi/lfric/data/nudge/era/C12' nudging_filename='era5_nudge_L137_C12_2021032400-2706' [namelist:formulation] use_multires_coupling=.true. -[namelist:initialization] -coarse_aerosol_ancil=.true. -coarse_ozone_ancil=.true. - [namelist:multires_coupling] -aerosol_mesh_name='multigrid_l2' +aerosol_mesh_name='dynamics' coarse_nudging=.true. -coarse_rad_aerosol=.true. +coarse_rad_aerosol=.false. lowest_order_aero_flag=.false. multires_coupling_mesh_tags='dynamics','multigrid_l2' nudging_mesh_name='multigrid_l2' diff --git a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf index a53fac6a6..852ff4ec1 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-nudging-era.conf @@ -7,7 +7,7 @@ theta_forcing='nudging' wind_forcing='nudging' [namelist:files] -nudging_directory='/data/users/mohit.dalvi/lfric/data/nudge/TomB/era/C48' +nudging_directory='/data/users/mohit.dalvi/lfric/data/nudge/era/C48' nudging_filename='era5_nudge_L137_C48_MG_2021032400-2706' [namelist:multires_coupling] From 3293ee26bd046463e44312b166918da1487a00ec Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Tue, 19 May 2026 21:20:51 +0100 Subject: [PATCH 15/18] Update KGO for *nudging_coarse* test, now reverted back to main mesh for aerosols --- ...-coarse-C48_MG_azspice_gnu_fast-debug-32bit.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit.txt index 2437c0d92..d036e49f5 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_nudging-era-coarse-C48_MG_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D8133B -Inner product checksum theta = 53948145 -Inner product checksum u = 6AA372D7 -Inner product checksum mr1 = 41C95E7C -Inner product checksum mr2 = 39A7957B -Inner product checksum mr3 = 376E1328 -Inner product checksum mr4 = 391E40AA +Inner product checksum rho = 48D81327 +Inner product checksum theta = 53948139 +Inner product checksum u = 6AA3743B +Inner product checksum mr1 = 41C95D15 +Inner product checksum mr2 = 39A8395C +Inner product checksum mr3 = 37753FED +Inner product checksum mr4 = 391E26F0 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 From b9067723c95bdbc1ce4ed107a4f95118fbff4f68 Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Fri, 29 May 2026 18:40:54 +0100 Subject: [PATCH 16/18] Changes from Review- mainly consistent naming of fields; remove duplication --- .../lfric_atm/metadata/axis_def_main.xml | 2 +- .../lfric_atm/metadata/grid_def_nudging.xml | 4 +-- .../metadata/grid_def_nudging_coarse.xml | 4 +-- .../driver/create_nudging_fields_mod.f90 | 10 ++++---- .../driver/create_physics_prognostics_mod.F90 | 6 ----- .../gungho/source/driver/field_maker_mod.F90 | 25 +++++++++++-------- .../gungho/source/driver/field_spec_mod.F90 | 4 +-- .../multidata_field_dimensions_mod.F90 | 4 +-- 8 files changed, 28 insertions(+), 31 deletions(-) diff --git a/applications/lfric_atm/metadata/axis_def_main.xml b/applications/lfric_atm/metadata/axis_def_main.xml index 49b923c58..e2d89571d 100644 --- a/applications/lfric_atm/metadata/axis_def_main.xml +++ b/applications/lfric_atm/metadata/axis_def_main.xml @@ -36,7 +36,7 @@ - + diff --git a/applications/lfric_atm/metadata/grid_def_nudging.xml b/applications/lfric_atm/metadata/grid_def_nudging.xml index 4f4d95a86..4322ea955 100644 --- a/applications/lfric_atm/metadata/grid_def_nudging.xml +++ b/applications/lfric_atm/metadata/grid_def_nudging.xml @@ -4,7 +4,7 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/applications/lfric_atm/metadata/grid_def_nudging_coarse.xml b/applications/lfric_atm/metadata/grid_def_nudging_coarse.xml index 7c7ce2737..fd870e5eb 100644 --- a/applications/lfric_atm/metadata/grid_def_nudging_coarse.xml +++ b/applications/lfric_atm/metadata/grid_def_nudging_coarse.xml @@ -4,7 +4,7 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/science/gungho/source/driver/create_nudging_fields_mod.f90 b/science/gungho/source/driver/create_nudging_fields_mod.f90 index ba799a661..10a9d600e 100644 --- a/science/gungho/source/driver/create_nudging_fields_mod.f90 +++ b/science/gungho/source/driver/create_nudging_fields_mod.f90 @@ -16,7 +16,7 @@ module create_nudging_fields_mod use function_space_mod, only : function_space_type use gungho_time_axes_mod, only : gungho_time_axes_type use log_mod, only : log_event, log_scratch_space, & - LOG_LEVEL_INFO, LOG_LEVEL_ERROR + LOG_LEVEL_TRACE, LOG_LEVEL_ERROR use mesh_mod, only : mesh_type use external_forcing_config_mod, only : theta_forcing_nudging, & @@ -48,7 +48,7 @@ subroutine create_nudging_fields(mesh, twod_mesh, mapper, clock) type(field_maker_type) :: creator - call log_event('GungHo: Creating nudging fields...', LOG_LEVEL_INFO) + call log_event('GungHo: Creating nudging fields...', LOG_LEVEL_TRACE) gungho_axes => mapper%get_gungho_axes() call gungho_axes%make_nudging_time_axis() @@ -88,7 +88,7 @@ subroutine process_nudging_fields(processor) 'temperature_nudging_ext_ref', main%none, W3, twod=.true., & coarse=coarse_nudging, & coarse_mesh_name=nudging_mesh_name, & - mult='ecmwf_levels', time_axis=axis%nudging & + mult='nudging_levels', time_axis=axis%nudging & )) end if @@ -97,13 +97,13 @@ subroutine process_nudging_fields(processor) 'u_nudging_ext_ref', main%none, W3, twod=.true., & coarse=coarse_nudging, & coarse_mesh_name=nudging_mesh_name, & - mult='ecmwf_levels', time_axis=axis%nudging & + mult='nudging_levels', time_axis=axis%nudging & )) call processor%apply(make_spec( & 'v_nudging_ext_ref', main%none, W3, twod=.true., & coarse=coarse_nudging, & coarse_mesh_name=nudging_mesh_name, & - mult='ecmwf_levels', time_axis=axis%nudging & + mult='nudging_levels', time_axis=axis%nudging & )) end if diff --git a/science/gungho/source/driver/create_physics_prognostics_mod.F90 b/science/gungho/source/driver/create_physics_prognostics_mod.F90 index 18271e6f8..606eae1ac 100644 --- a/science/gungho/source/driver/create_physics_prognostics_mod.F90 +++ b/science/gungho/source/driver/create_physics_prognostics_mod.F90 @@ -1755,12 +1755,6 @@ subroutine process_physics_prognostics(processor) if (aerosol == aerosol_um) then - if (coarse_rad_aerosol) then - mesh_name = aerosol_mesh_name - else - mesh_name = '' - end if - ! Dry diameter Aitken mode (Soluble) call processor%apply(make_spec('drydp_ait_sol', main%aerosol, Wtheta, & coarse=coarse_rad_aerosol, coarse_mesh_name=mesh_name, ckp=checkpoint_flag)) diff --git a/science/gungho/source/driver/field_maker_mod.F90 b/science/gungho/source/driver/field_maker_mod.F90 index c83ece54e..6b0111b88 100644 --- a/science/gungho/source/driver/field_maker_mod.F90 +++ b/science/gungho/source/driver/field_maker_mod.F90 @@ -133,16 +133,16 @@ subroutine field_maker_apply(self, spec) class(field_maker_type), intent(in) :: self type(field_spec_type), intent(in) :: spec - type(field_collection_type), pointer :: main_coll => null() - type(field_collection_type), pointer :: adv_coll => null() - type(field_collection_type), pointer :: depository => null() - type(field_collection_type), pointer :: prognostic_fields => null() - type(function_space_type), pointer :: space => null() - type(mesh_type), pointer :: mesh => null() - type(mesh_type), pointer :: twod_mesh => null() - type(field_type), pointer :: external_real_field => null() - type(time_axis_type), pointer :: time_axis => null() - type(integer_field_type), pointer :: external_int_field => null() + type(field_collection_type), pointer :: main_coll + type(field_collection_type), pointer :: adv_coll + type(field_collection_type), pointer :: depository + type(field_collection_type), pointer :: prognostic_fields + type(function_space_type), pointer :: space + type(mesh_type), pointer :: mesh + type(mesh_type), pointer :: twod_mesh + type(field_type), pointer :: external_real_field + type(time_axis_type), pointer :: time_axis + type(integer_field_type), pointer :: external_int_field logical(l_def) :: advected integer(i_def) :: ndata integer(i_def) :: i @@ -151,6 +151,9 @@ subroutine field_maker_apply(self, spec) class(clock_type), pointer :: clock real(r_second), allocatable :: all_checkpoint_times(:) + nullify(main_coll,adv_coll,depository,prognostic_fields,space) + nullify(mesh,twod_mesh,external_real_field,time_axis,external_int_field) + #ifdef UM_PHYSICS ndata = get_ndata_val(spec%mult) #else @@ -172,7 +175,7 @@ subroutine field_maker_apply(self, spec) end if else if (spec%coarse) then - mesh => mesh_collection%get_mesh(spec%mesh_name) + mesh => mesh_collection%get_mesh(spec%coarse_mesh_name) if (spec%twod) then twod_mesh => mesh_collection%get_mesh(mesh, TWOD) space => function_space_collection%get_fs(twod_mesh, spec%order_h, & diff --git a/science/gungho/source/driver/field_spec_mod.F90 b/science/gungho/source/driver/field_spec_mod.F90 index 1140494ac..a02f7c86b 100644 --- a/science/gungho/source/driver/field_spec_mod.F90 +++ b/science/gungho/source/driver/field_spec_mod.F90 @@ -98,7 +98,7 @@ module field_spec_mod logical(l_def) :: twod = .false. ! Is it two-dimensional? logical(l_def) :: empty = .false. ! Is it empty (with an empty data array)? logical(l_def) :: coarse = .false. ! Is it coarse? - character(str_def) :: mesh_name = '' ! Name of mesh, or blank string + character(str_def) :: coarse_mesh_name = '' ! Name of the coarse mesh, or blank string logical(l_def) :: is_int = .false. ! Is it an integer field? logical(l_def) :: legacy = .false. ! Is it a field with legacy checkpointing? end type field_spec_type @@ -241,7 +241,7 @@ function make_spec(name, main_coll, space, order_h, order_v, adv_coll, & if (present(twod)) field_spec%twod=twod if (present(empty)) field_spec%empty=empty if (present(coarse)) field_spec%coarse=coarse - if (present(coarse_mesh_name)) field_spec%mesh_name=coarse_mesh_name + if (present(coarse_mesh_name)) field_spec%coarse_mesh_name=coarse_mesh_name if (present(is_int)) field_spec%is_int=is_int if (present(legacy)) field_spec%legacy=legacy diff --git a/science/gungho/source/physics/multidata_field_dimensions_mod.F90 b/science/gungho/source/physics/multidata_field_dimensions_mod.F90 index ae8c9a72d..c9b6f96df 100644 --- a/science/gungho/source/physics/multidata_field_dimensions_mod.F90 +++ b/science/gungho/source/physics/multidata_field_dimensions_mod.F90 @@ -64,7 +64,7 @@ module multidata_field_dimensions_mod 'random_seed_size', & 'stph_spectral_dimensions', & 'photol_species', & - 'ecmwf_levels' & + 'nudging_levels' & ] #endif @@ -279,7 +279,7 @@ function get_multidata_field_dimension(multidata_item) result (dim) else dim = 1 end if - case ('ecmwf_levels') + case ('nudging_levels') dim = nudge_data_levels case ('') dim = 1 ! ordinary (non-multidata) field From 6975f0a3366121ce5f790b57ce5d378b5e7da987 Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Fri, 5 Jun 2026 10:45:51 +0100 Subject: [PATCH 17/18] Attempt to get away from hardwired numbers in collection declaration. --- .../gungho/source/driver/field_spec_mod.F90 | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/science/gungho/source/driver/field_spec_mod.F90 b/science/gungho/source/driver/field_spec_mod.F90 index a02f7c86b..0b7c06f06 100644 --- a/science/gungho/source/driver/field_spec_mod.F90 +++ b/science/gungho/source/driver/field_spec_mod.F90 @@ -37,9 +37,33 @@ module field_spec_mod end type main_coll_dict_type !> @brief Map main collection enumerators to collections. + !> Enumerator values need to be unique for each field, and nominally + !> within a specific range for each collection type + integer(i_def), parameter :: enum_derived = 107 + integer(i_def), parameter :: enum_radiation = 120 + integer(i_def), parameter :: enum_microphysics = 129 + integer(i_def), parameter :: enum_electric = 130 + integer(i_def), parameter :: enum_orography = 141 + integer(i_def), parameter :: enum_turbulence = 142 + integer(i_def), parameter :: enum_convection = 152 + integer(i_def), parameter :: enum_cloud = 154 + integer(i_def), parameter :: enum_surface = 160 + integer(i_def), parameter :: enum_soil = 190 + integer(i_def), parameter :: enum_snow = 191 + integer(i_def), parameter :: enum_chemistry = 222 + integer(i_def), parameter :: enum_aerosol = 238 + integer(i_def), parameter :: enum_stph = 241 + integer(i_def), parameter :: enum_lbc = 252 + integer(i_def), parameter :: enum_none = 279 + type(main_coll_dict_type), parameter :: main_coll_dict & = main_coll_dict_type( & - 107,120,129,130,141,142,152,154,160,190,191,222,238,241,252,279) + enum_derived, enum_radiation, enum_microphysics, & + enum_electric, enum_orography, enum_turbulence, & + enum_convection, enum_cloud, enum_surface, enum_soil, & + enum_snow, enum_chemistry, enum_aerosol, enum_stph, & + enum_lbc, enum_none & + ) !> @brief Dictionary of advected field collections type :: adv_coll_dict_type From 344ff2776b41452b3b0e86a042d182d344a1e34c Mon Sep 17 00:00:00 2001 From: Mohit Dalvi Date: Thu, 11 Jun 2026 16:38:30 +0100 Subject: [PATCH 18/18] Revert some changes after review as modeldb may not available in all places where *process_nudging_fields* is called --- .../jedi_lfric_linear_modeldb_driver_mod.f90 | 4 -- .../driver/create_nudging_fields_mod.f90 | 27 ++++++++---- .../gungho/source/driver/field_spec_mod.F90 | 44 ++++++++++++++----- .../source/driver/gungho_init_fields_mod.X90 | 18 ++++++-- .../source/driver/linear_driver_mod.f90 | 10 ++--- 5 files changed, 68 insertions(+), 35 deletions(-) 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 e1b5c879c..4af0cdda9 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 @@ -46,10 +46,6 @@ module jedi_lfric_linear_modeldb_driver_mod use constants_mod, only : r_def, l_def, str_def use driver_config_mod, only : init_config use driver_time_mod, only : init_time, final_time - use external_forcing_config_mod, only : theta_forcing, & - theta_forcing_nudging, & - wind_forcing, & - wind_forcing_nudging use extrusion_mod, only : TWOD use gungho_init_fields_mod, only : create_model_data, & finalise_model_data diff --git a/science/gungho/source/driver/create_nudging_fields_mod.f90 b/science/gungho/source/driver/create_nudging_fields_mod.f90 index 10a9d600e..f63ff0170 100644 --- a/science/gungho/source/driver/create_nudging_fields_mod.f90 +++ b/science/gungho/source/driver/create_nudging_fields_mod.f90 @@ -1,5 +1,5 @@ !----------------------------------------------------------------------------- -! (c) Crown copyright 2025 Met Office. All rights reserved. +! (c) Crown copyright Met Office. All rights reserved. ! The file LICENCE, distributed with this code, contains details of the terms ! under which the code may be used. !----------------------------------------------------------------------------- @@ -8,6 +8,7 @@ module create_nudging_fields_mod use clock_mod, only : clock_type use constants_mod, only : i_def, l_def, str_def + use driver_modeldb_mod, only : modeldb_type use field_mod, only : field_type use field_collection_mod, only : field_collection_type use field_mapper_mod, only : field_mapper_type @@ -23,6 +24,7 @@ module create_nudging_fields_mod theta_forcing, & wind_forcing_nudging, & wind_forcing + implicit none public :: create_nudging_fields @@ -33,16 +35,16 @@ module create_nudging_fields_mod !> @brief Create and add nudging fields. !> @details Create reference fields to for nudging in the derived field !! collection. On every timestep these fields will be updated. + !> @param[in] modeldb The dataset for this run !> @param[in] mesh The current 3d mesh - !> @param[in] twod_mesh The current 2d mesh (not used here) + !> @param[in] twod_mesh The current 2d mesh !> @param[in] mapper Provides access to the field collections - !> @param[in] clock The model clock - subroutine create_nudging_fields(mesh, twod_mesh, mapper, clock) + subroutine create_nudging_fields(modeldb, mesh, twod_mesh, mapper) implicit none + type(modeldb_type), intent(in) :: modeldb type(mesh_type), intent(in), pointer :: mesh type(mesh_type), intent(in), pointer :: twod_mesh type(field_mapper_type), intent(in) :: mapper - class(clock_type), intent(in) :: clock type(gungho_time_axes_type), pointer :: gungho_axes @@ -53,7 +55,7 @@ subroutine create_nudging_fields(mesh, twod_mesh, mapper, clock) gungho_axes => mapper%get_gungho_axes() call gungho_axes%make_nudging_time_axis() - call creator%init(mesh, twod_mesh, mapper, clock) + call creator%init(mesh, twod_mesh, mapper, modeldb%clock) call process_nudging_fields(creator) @@ -63,19 +65,26 @@ end subroutine create_nudging_fields !> @brief Iterate over active nudging fields and apply an arbitrary !! processor to the field specifiers. + !> @param processor Processor to be applied to field specifiers subroutine process_nudging_fields(processor) use field_spec_mod, only : main => main_coll_dict, & axis => time_axis_dict, & processor_type, & make_spec - use multires_coupling_config_mod, only : coarse_nudging, & - nudging_mesh_name + + use multires_coupling_config_mod, only: coarse_nudging, & + nudging_mesh_name implicit none - class(processor_type) :: processor + class(processor_type) :: processor !------ Fields updated directly from nudging file----------------- + + ! The surface pressure field from data file is used to re-create the + ! vertical grid (sigma or pressure-levels) of the source data while + ! remapping from nudging to model grid. Hence this field is needed + ! when any one of theta or wind is forced. call processor%apply(make_spec( & 'surface_pressure_nudging_ext_ref', main%none, W3, & coarse=coarse_nudging, & diff --git a/science/gungho/source/driver/field_spec_mod.F90 b/science/gungho/source/driver/field_spec_mod.F90 index 0b7c06f06..0ba36a2c7 100644 --- a/science/gungho/source/driver/field_spec_mod.F90 +++ b/science/gungho/source/driver/field_spec_mod.F90 @@ -14,6 +14,9 @@ module field_spec_mod implicit none + !> The enumerator values in the collections need to be unique for each field, + !> and nominally within a specific range for each collection type + !> @brief Dictionary of main field collections type :: main_coll_dict_type integer(i_def) :: derived @@ -36,9 +39,6 @@ module field_spec_mod procedure :: check => main_coll_check end type main_coll_dict_type - !> @brief Map main collection enumerators to collections. - !> Enumerator values need to be unique for each field, and nominally - !> within a specific range for each collection type integer(i_def), parameter :: enum_derived = 107 integer(i_def), parameter :: enum_radiation = 120 integer(i_def), parameter :: enum_microphysics = 129 @@ -53,16 +53,17 @@ module field_spec_mod integer(i_def), parameter :: enum_chemistry = 222 integer(i_def), parameter :: enum_aerosol = 238 integer(i_def), parameter :: enum_stph = 241 - integer(i_def), parameter :: enum_lbc = 252 - integer(i_def), parameter :: enum_none = 279 - + integer(i_def), parameter :: enum_main_lbc = 252 + integer(i_def), parameter :: enum_main_none = 279 + + !> @brief Map main collection enumerators to collections. type(main_coll_dict_type), parameter :: main_coll_dict & = main_coll_dict_type( & enum_derived, enum_radiation, enum_microphysics, & enum_electric, enum_orography, enum_turbulence, & enum_convection, enum_cloud, enum_surface, enum_soil, & enum_snow, enum_chemistry, enum_aerosol, enum_stph, & - enum_lbc, enum_none & + enum_main_lbc, enum_main_none & ) !> @brief Dictionary of advected field collections @@ -74,9 +75,17 @@ module field_spec_mod integer(i_def) :: last_con ! Con_fields_last_outer end type adv_coll_dict_type + integer(i_def), parameter :: enum_adv_none = 387 + integer(i_def), parameter :: enum_all_adv = 391 + integer(i_def), parameter :: enum_last_adv = 395 + integer(i_def), parameter :: enum_all_con = 399 + integer(i_def), parameter :: enum_last_con = 412 + !> @brief Map advected field enumerators to collections. type(adv_coll_dict_type), parameter :: adv_coll_dict & - = adv_coll_dict_type(387,391,395,399,412) + = adv_coll_dict_type( enum_adv_none, enum_all_adv, & + enum_last_adv, enum_all_con, & + enum_last_con ) !> @brief Dictionary of moisture field arrays type :: moist_arr_dict_type @@ -86,9 +95,16 @@ module field_spec_mod integer(i_def) :: moist_dyn_ref ! moist_dyn_ref array end type moist_arr_dict_type + integer(i_def), parameter :: enum_moist_none = 445 + integer(i_def), parameter :: enum_mr = 450 + integer(i_def), parameter :: enum_moist_dyn = 454 + integer(i_def), parameter :: enum_moist_dyn_ref = 461 + !> @brief Map moisture array enumerators to moisture array. type(moist_arr_dict_type), parameter :: moist_arr_dict & - = moist_arr_dict_type(445,450,454,461) + = moist_arr_dict_type( enum_moist_none, enum_mr, & + enum_moist_dyn, & + enum_moist_dyn_ref ) !> @brief Dictionary of time axes type :: time_axis_dict_type @@ -98,9 +114,15 @@ module field_spec_mod integer(i_def) :: nudging ! nudging time axis end type time_axis_dict_type + integer(i_def), parameter :: enum_time_none = 525 + integer(i_def), parameter :: enum_time_lbc = 529 + integer(i_def), parameter :: enum_ls = 536 + integer(i_def), parameter :: enum_nudging = 542 + !> @brief Map moisture array enumerators to moisture array. - type(time_axis_dict_type), parameter :: time_axis_dict & - = time_axis_dict_type(525,529,536,542) + type(time_axis_dict_type), parameter :: time_axis_dict & + = time_axis_dict_type( enum_time_none, enum_time_lbc, & + enum_ls, enum_nudging ) ! request function space discovery integer, parameter :: missing_fs = imdi diff --git a/science/gungho/source/driver/gungho_init_fields_mod.X90 b/science/gungho/source/driver/gungho_init_fields_mod.X90 index 69570038e..068a1d90d 100644 --- a/science/gungho/source/driver/gungho_init_fields_mod.X90 +++ b/science/gungho/source/driver/gungho_init_fields_mod.X90 @@ -90,9 +90,7 @@ module gungho_init_fields_mod use ageofair_alg_mod, only : init_ageofair use transport_config_mod, only : transport_ageofair use external_forcing_config_mod, only : theta_forcing_nudging, & - theta_forcing, & - wind_forcing_nudging, & - wind_forcing + wind_forcing_nudging #ifdef COUPLED use coupler_mod, only : zero_coupling_send_fields #endif @@ -375,6 +373,8 @@ subroutine create_model_data( modeldb, & type(gungho_time_axes_type), pointer :: model_axes + integer(i_def) :: theta_forcing + integer(i_def) :: wind_forcing !------------------------------------------------------------------------- ! Select how to initialize model prognostic fields !------------------------------------------------------------------------- @@ -514,10 +514,13 @@ subroutine create_model_data( modeldb, & prognostic_fields, & modeldb ) + theta_forcing = modeldb%config%external_forcing%theta_forcing() + wind_forcing = modeldb%config%external_forcing%wind_forcing() + if ( wind_forcing == wind_forcing_nudging .or. & theta_forcing == theta_forcing_nudging ) then call create_nudging_fields( & - nudging_mesh, nudging_twod_mesh, field_mapper, modeldb%clock & + modeldb, nudging_mesh, nudging_twod_mesh, field_mapper & ) end if @@ -629,6 +632,10 @@ subroutine create_model_data( modeldb, & integer(i_def) :: i integer(i_def) :: random_seed_size integer(i_def), allocatable :: ranseed(:) + + integer(i_def) :: theta_forcing + integer(i_def) :: wind_forcing + #ifdef UM_PHYSICS integer(i_def) :: ensemble_number real(r_def), allocatable :: power_law(:) @@ -875,6 +882,9 @@ subroutine create_model_data( modeldb, & ! Initialise reading of nudging fields + theta_forcing = modeldb%config%external_forcing%theta_forcing() + wind_forcing = modeldb%config%external_forcing%wind_forcing() + if ( wind_forcing == wind_forcing_nudging .or. & theta_forcing == theta_forcing_nudging ) then ! Initialise time interpolation diff --git a/science/linear/source/driver/linear_driver_mod.f90 b/science/linear/source/driver/linear_driver_mod.f90 index cfef35a93..f9f85f30e 100644 --- a/science/linear/source/driver/linear_driver_mod.f90 +++ b/science/linear/source/driver/linear_driver_mod.f90 @@ -8,10 +8,6 @@ module linear_driver_mod use constants_mod, only : i_def, r_def, imdi, l_def, str_def, & i_medium - use external_forcing_config_mod, only : theta_forcing, & - theta_forcing_nudging, & - wind_forcing, & - wind_forcing_nudging use extrusion_mod, only : TWOD use field_array_mod, only : field_array_type use field_mod, only : field_type @@ -42,7 +38,7 @@ module linear_driver_mod use log_mod, only : log_event, & log_scratch_space, & LOG_LEVEL_ALWAYS, & - LOG_LEVEL_INFO + LOG_LEVEL_TRACE use linear_model_data_mod, only : linear_create_ls, & linear_init_ls, & linear_init_pert @@ -148,7 +144,7 @@ subroutine initialise( program_name, modeldb ) aerosol_mesh => mesh_collection%get_mesh(aerosol_mesh_name) aerosol_twod_mesh => mesh_collection%get_mesh(aerosol_mesh, TWOD) write( log_scratch_space,'(A,A)' ) "aerosol mesh name:", aerosol_mesh%get_mesh_name() - call log_event( log_scratch_space, LOG_LEVEL_INFO ) + call log_event( log_scratch_space, LOG_LEVEL_TRACE ) else aerosol_mesh => mesh aerosol_twod_mesh => twod_mesh @@ -165,7 +161,7 @@ subroutine initialise( program_name, modeldb ) nudging_mesh => mesh_collection%get_mesh(nudging_mesh_name) nudging_twod_mesh => mesh_collection%get_mesh(nudging_mesh, TWOD) write( log_scratch_space,'(A,A)' ) "nudging mesh name:", nudging_mesh%get_mesh_name() - call log_event( log_scratch_space, LOG_LEVEL_INFO ) + call log_event( log_scratch_space, LOG_LEVEL_TRACE ) end if end if