From 893167b3909e75e953122ff300faceb4cef331e9 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 19 Sep 2025 15:33:50 +1000 Subject: [PATCH 001/288] Basic design similar to offline julia version --- src/diagnostics/MOM_numerical_mixing.F90 | 75 ++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/diagnostics/MOM_numerical_mixing.F90 diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 new file mode 100644 index 0000000000..11c0c3cd71 --- /dev/null +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -0,0 +1,75 @@ +!> Functions and routines involved in calculating numerical mixing +module MOM_numerical_mixing + +implicit none ; private + +public numerical_mixing + +!< Calculate the numerical mixing of tracer C due to advection +real function numerical_mixing(C, C_adxy, h, h_tendency, dt, C_adx, umo, C_ady, vmo, V, scale_constant, rho_ref) + + real, intent(in) :: C !< Tracer to calculate numerical mixing for + real, intent(in) :: C_adxy !< Explicit horizontal advection of tracer C + real, intent(in) :: h !< Thickness + real, intent(in) :: h_tendency !< Thickness tendency + real, intent(in) :: dt !< Model timestep + real, intent(in) :: C_adx !< Explicit zonal advection of tracer C + real, intent(in) :: umo !< Total zonal mass transport + real, intent(in) :: C_ady !< Explicit meridional advection of tracer C + real, intent(in) :: vmo !< Total meridional mass transport + real, intent(in) :: V !< Volume + real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for temperature + real, intent(in) :: rho_ref !< Reference density + + real :: nm !< Numerical mixing due to advection of tracer C + real :: A !< Area of grid cells, computed from V / h + real :: xupwind !< Upwind index in the zonal direction + real :: yupwind !< Upwind index in the meridional direction + + nm = call thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt) + nm = nm + call zonal_upwind_fluxes(C, C_adx, umo, A, xupwind) + nm = nm + call meridional_upwind_fluxes(C, C_ady, vmo, A, yupwind) + +end function numerical_mixing + +!< Subroutine to calculate the thickness weighted variance change over a timestep +subroutine thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt) + + implicit none + real, intent(in) :: C !< Tracer to calculate numerical mixing for + real, intent(in) :: C_adxy !< Explicit horizontal advection of tracer C + real, intent(in) :: h !< Thickness + real, intent(in) :: h_tendency !< Thickness tendency + +end subroutine thickness_weighted_variance_change + +!< Subroutine to calculate the zonal upwind fluxes +subroutine zonal_upwind_fluxes(C, C_adx, umo, A) + + implicit none + real, intent(in) :: C !< Tracer to calculate numerical mixing for + real, intent(in) :: C_adx !< Explicit zonal advection of tracer C + real, intent(in) :: umo !< Total zonal mass transport + real, intent(in) :: A !< Area of grid cells, computed from V / h + real, intent(in) :: xupwind !< Upwind index in the zonal direction + +end subroutine zonal_upwind_fluxes + +!< Subroutine to calculate the meriodional upwind flues +subroutine meridional_upwind_fluxes(C, C_ady, vmo, A) + + implicit none + real, intent(in) :: C !< Tracer to calculate numerical mixing for + real, intent(in) :: C_ady !< Explicit meridional advection of tracer C + real, intent(in) :: vmo !< Total meridional mass transport + real, intent(in) :: A !< Area of grid cells, computed from V / h + real, intent(in) :: yupwind !< Upwind index in the meridional direction + +end subroutine meridional_upwind_fluxes + +!< Subroutine to caluate upind tracer values for finite difference +subroutine calculate_upwind(Cl, Cr, u) + +end subroutine calculate_upwind + +end module MOM_numerical_mixing \ No newline at end of file From 71b4eb55e56bcd4d778bf5f3be37090b6ffd1a0f Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 24 Sep 2025 14:54:05 +1000 Subject: [PATCH 002/288] Start trying to setup diagnostic --- src/diagnostics/MOM_diagnostics.F90 | 8 + src/diagnostics/MOM_numerical_mixing.F90 | 198 +++++++++++++++++------ 2 files changed, 160 insertions(+), 46 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 8bb85762bb..6f9dca3104 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -35,6 +35,7 @@ module MOM_diagnostics use MOM_variables, only : accel_diag_ptrs, cont_diag_ptrs, surface use MOM_verticalGrid, only : verticalGrid_type, get_thickness_units, get_flux_units use MOM_wave_speed, only : wave_speed, wave_speed_CS, wave_speed_init +use MOM_numerical_mixing, only : numerical_mixing implicit none ; private @@ -164,6 +165,13 @@ module MOM_diagnostics !>@} end type transport_diag_IDs +!> A structure with diagnostic IDs for numerical mixing of salinity and temperature +type, public :: numerical_mixing_diag_IDs ; private + !>@{ + integer :: id_num_mixing_T = -1 + integer :: id_num_mixing_S = -1 + !>@} +end type numerical_mixing_diag_IDs contains !> Diagnostics not more naturally calculated elsewhere are computed here. diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 11c0c3cd71..886206b1b5 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -1,75 +1,181 @@ !> Functions and routines involved in calculating numerical mixing module MOM_numerical_mixing +use MOM_grid, only : ocean_grid_type +use MOM_variables, only : thermo_var_ptrs, ocean_internal_state +use MOM_verticalGrid, only : verticalGrid_type implicit none ; private public numerical_mixing -!< Calculate the numerical mixing of tracer C due to advection -real function numerical_mixing(C, C_adxy, h, h_tendency, dt, C_adx, umo, C_ady, vmo, V, scale_constant, rho_ref) - - real, intent(in) :: C !< Tracer to calculate numerical mixing for - real, intent(in) :: C_adxy !< Explicit horizontal advection of tracer C - real, intent(in) :: h !< Thickness - real, intent(in) :: h_tendency !< Thickness tendency - real, intent(in) :: dt !< Model timestep - real, intent(in) :: C_adx !< Explicit zonal advection of tracer C - real, intent(in) :: umo !< Total zonal mass transport - real, intent(in) :: C_ady !< Explicit meridional advection of tracer C - real, intent(in) :: vmo !< Total meridional mass transport - real, intent(in) :: V !< Volume - real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for temperature - real, intent(in) :: rho_ref !< Reference density - - real :: nm !< Numerical mixing due to advection of tracer C - real :: A !< Area of grid cells, computed from V / h - real :: xupwind !< Upwind index in the zonal direction - real :: yupwind !< Upwind index in the meridional direction - - nm = call thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt) - nm = nm + call zonal_upwind_fluxes(C, C_adx, umo, A, xupwind) - nm = nm + call meridional_upwind_fluxes(C, C_ady, vmo, A, yupwind) - -end function numerical_mixing +contains + +!< Calculate numerical mixing from saved output. +subroutine numerical_mixing(MIS, tv, G, GV, nm) + type(ocean_internal_state), intent(in) :: MIS !< For "MOM Internal State" a set of pointers to + !! the fields and accelerations making up ocean + !! internal physical state. + type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various + !! thermodynamic variables. + type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. + type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. + real, intent(inout) :: nm(:, :, :) !< numerical mxiing output + + !< adjust for correct dimensions + C_adxy = C_adxy / (tv%C_p * rho_ref) !< units: [C]ms⁻¹ + C_adx = C_adx / (tv%C_p * rho_ref) !< units: [C]m⁻²s⁻¹ + C_ady = C_ady / (tv%C_p * rho_ref) !< units: [C]m⁻²s⁻¹ + + call thickness_weighted_variance_change(MIS%T, C_adxy, MIS%h, h_tendency, dt, G%iec, G%jec, GV%ke, nm) + call zonal_upwind_fluxes(MIS%T, C_adx, MIS%uh, G%IareaT, G%iec, G%jec, GV%ke, nm) + call meridional_upwind_fluxes(MIS%T, C_ady, MIS%vh, G%IareaT, G%iec, G%jec, GV%ke, nm) + +end subroutine numerical_mixing !< Subroutine to calculate the thickness weighted variance change over a timestep -subroutine thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt) +subroutine thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, Nx, Ny, Nz, nm) implicit none - real, intent(in) :: C !< Tracer to calculate numerical mixing for - real, intent(in) :: C_adxy !< Explicit horizontal advection of tracer C - real, intent(in) :: h !< Thickness - real, intent(in) :: h_tendency !< Thickness tendency + real, intent(in) :: C(:, :, :, :) !< Tracer to calculate numerical mixing for + real, intent(in) :: C_adxy(:, :, :, :) !< Explicit horizontal advection of tracer C + real, intent(in) :: h(:, :, :, :) !< Thickness + real, intent(in) :: h_tendency(:, :, :, :) !< Thickness tendency + real, intent(in) :: dt !< Model timestep + integer, intent(in) :: Nx, Ny, Nz !< Dimension lengths + real, intent(inout) :: nm(:, :, :) + + integer :: i, j, k + real :: h1, C1, hadv, Cadv + + do i = 2, Nx-2 + do j = 2, Ny-2 + do k = 1, Nz + h1 = h(i, j, k, 1) + hadv = h1 + dt * h_tendency(i, j, k, 1) + C1 = C(i, j, k, 1) + Cadv = (h1 * C1 + dt * C_adxy(i, j, k, 1)) / hadv + nm(i-1, j-1, k) = (hadv * Cadv**2 - h1 * C1**2) / dt + enddo + enddo + enddo end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(C, C_adx, umo, A) +subroutine zonal_upwind_fluxes(C, C_adx, uh, V, Nx, Ny, Nz, nm) implicit none - real, intent(in) :: C !< Tracer to calculate numerical mixing for - real, intent(in) :: C_adx !< Explicit zonal advection of tracer C - real, intent(in) :: umo !< Total zonal mass transport - real, intent(in) :: A !< Area of grid cells, computed from V / h - real, intent(in) :: xupwind !< Upwind index in the zonal direction + real, intent(in) :: C(:, :, :, :) !< Tracer to calculate numerical mixing for + real, intent(in) :: C_adx(:, :, :, :) !< Explicit zonal advection of tracer C + real, intent(in) :: uh(:, :, :, :) !< Zonal mass transport + real, intent(in) :: V(:, :, :, :) !< Area of grid cells, computed from V / h + + integer, intent(in) :: Nx, Ny, Nz !< Dimension lengths + real, intent(inout) :: nm(:, :, :) + + integer :: i, j, k + real :: Cupwind(Nx-2, Ny-3, Nz) + real :: east, west + + call zonal_upwind_values(uh, C, Cupwind) + + do i = 2, Nx-2 + do j = 2, Ny-2 + do k = 1, Nz + east = 2 * C_adx(i, j, k, 1) * Cupwind(i, j, k) - uh(i, j, k, 1) * Cupwind(i, j, k)**2 + west = 2 * C_adx(i-1, j, k, 1) * Cupwind(i-1, j, k) - uh(i-1, j, k, 1) * Cupwind(i-1, j, k)**2 + nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((east - west) / V(i, j, k, 1)) + enddo + enddo + enddo end subroutine zonal_upwind_fluxes +!< Subroutine to calculate upwind values in zonal direction +subroutine zonal_upwind_values(u, C, Cupwind) + + implicit none + real, intent(in) :: u(:, :, :, :) + real, intent(in) :: C(:, :, :, :) + real, intent(inout) :: Cupwind(:, :, :) + + integer :: i, j, k + integer :: xdim, ydim, zdim + + xdim = size(Cupwind, dim = 1) + ydim = size(Cupwind, dim = 2) + zdim = size(Cupwind, dim = 3) + + do i = 1, xdim + do j = 1, ydim + do k = 1, zdim + if (u(i, j, k, 1) >= 0) then + Cupwind(i, j, k) = C(i, j, k, 1) + else if (u(i, j, k, 1) < 0) then + Cupwind(i, j, k) = C(i+1, j, k, 1) + end if + end do + end do + end do + +end subroutine zonal_upwind_values + !< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(C, C_ady, vmo, A) +subroutine meridional_upwind_fluxes(C, C_ady, vh, V, Nx, Ny, Nz, nm ) implicit none - real, intent(in) :: C !< Tracer to calculate numerical mixing for - real, intent(in) :: C_ady !< Explicit meridional advection of tracer C - real, intent(in) :: vmo !< Total meridional mass transport - real, intent(in) :: A !< Area of grid cells, computed from V / h - real, intent(in) :: yupwind !< Upwind index in the meridional direction + real, intent(in) :: C(:, :, :, :) !< Tracer to calculate numerical mixing for + real, intent(in) :: C_ady(:, :, :, :) !< Explicit zonal advection of tracer C + real, intent(in) :: vh(:, :, :, :) !< Meridional transport + real, intent(in) :: V(:, :, :, :) !< Area of grid cells, computed from V / h + + integer, intent(in) :: Nx, Ny, Nz !< Dimension lengths + real, intent(inout) :: nm(:, :, :) + + integer :: i, j, k + real :: Cupwind(Nx-3, Ny-2, Nz) + real :: north, south + + call meridional_upwind_values(vh, C, Cupwind) + + do i = 2, Nx-2 + do j = 2, Ny-2 + do k = 1, Nz + north = 2 * C_ady(i, j, k, 1) * Cupwind(i, j, k) - vh(i, j, k, 1) * Cupwind(i, j, k)**2 + south = 2 * C_ady(i, j-1, k, 1) * Cupwind(i, j-1, k) - vh(i, j-1, k, 1) * Cupwind(i, j-1, k)**2 + nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((north - south) / V(i, j, k, 1)) + enddo + enddo + enddo end subroutine meridional_upwind_fluxes -!< Subroutine to caluate upind tracer values for finite difference -subroutine calculate_upwind(Cl, Cr, u) +subroutine meridional_upwind_values(v, C, Cupwind) -end subroutine calculate_upwind + implicit none + real, intent(in) :: v(:, :, :, :) + real, intent(in) :: C(:, :, :, :) + real, intent(inout) :: Cupwind(:, :, :) + + integer :: i, j, k + integer :: xdim, ydim, zdim + + xdim = size(Cupwind, dim = 1) + ydim = size(Cupwind, dim = 2) + zdim = size(Cupwind, dim = 3) + + do i = 1, xdim + do j = 1, ydim + do k = 1, zdim + if (v(i, j, k, 1) >= 0) then + Cupwind(i, j, k) = C(i, j, k, 1) + else if (v(i, j, k, 1) < 0) then + Cupwind(i, j, k) = C(i, j+1, k, 1) + end if + end do + end do + end do + +end subroutine meridional_upwind_values end module MOM_numerical_mixing \ No newline at end of file From 66b08d9299597b482c84eaf9b7aeefa66d4b4103 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 25 Sep 2025 10:52:05 +1000 Subject: [PATCH 003/288] Put nm call in transport diagnostics --- src/diagnostics/MOM_diagnostics.F90 | 27 ++- src/diagnostics/MOM_numerical_mixing.F90 | 199 ++++++++++++----------- 2 files changed, 122 insertions(+), 104 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 6f9dca3104..c5e51bf2f4 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -162,17 +162,10 @@ module MOM_diagnostics integer :: id_uhtr = -1, id_umo = -1, id_umo_2d = -1 integer :: id_vhtr = -1, id_vmo = -1, id_vmo_2d = -1 integer :: id_dynamics_h = -1, id_dynamics_h_tendency = -1 + integer :: id_numerical_mixing_T = -1, integer :: id_numerical_mixing_S = -1 !>@} end type transport_diag_IDs -!> A structure with diagnostic IDs for numerical mixing of salinity and temperature -type, public :: numerical_mixing_diag_IDs ; private - !>@{ - integer :: id_num_mixing_T = -1 - integer :: id_num_mixing_S = -1 - !>@} -end type numerical_mixing_diag_IDs - contains !> Diagnostics not more naturally calculated elsewhere are computed here. subroutine calculate_diagnostic_fields(u, v, h, uh, vh, tv, ADp, CDp, p_surf, & @@ -1658,6 +1651,8 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: umo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nmT ! Numerical mixing of temperature + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nmS ! Numerical mixing of salinity ! [H T-1 ~> m s-1 or kg m-2 s-1]. real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes @@ -1715,6 +1710,18 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy call post_tracer_transport_diagnostics(G, GV, Reg, diag_pre_dyn%h_state, diag) + ! Post the numerical mixing + if (IDs%id_numerical_mixing_T > 0) then + nmT(:,:,:) = 0. + call numerical_mixing(G, GV, C, C_adxy, h, h_tend, Idt, C_adx, umo, C_ady, vmo, scale_constant, rho_ref, nmT) + call post_data(IDs%id_numerical_mixing_T, nmT, diag) + ! For now just temperature + ! elseif (IDs%id_numerical_mixing_S > 0) then + ! nmS(:,:,:) = 0. + ! call numerical_mixing(C, C_adxy, h, h_tendency, Idt, C_adx, umo, C_ady, vmo, V, scale_constant, rho_ref, nmS) + ! call post_data(IDs%id_numerical_mixing_S, nmS, diag) + endif + call diag_restore_grids(diag) end subroutine post_transport_diagnostics @@ -2247,6 +2254,10 @@ subroutine register_transport_diags(Time, G, GV, US, IDs, diag) IDs%id_dynamics_h_tendency = register_diag_field('ocean_model','dynamics_h_tendency', & diag%axesTl, Time, 'Change in layer thicknesses due to horizontal dynamics', & trim(thickness_units)//" s-1", conversion=GV%H_to_MKS*US%s_to_T, v_extensive=.true.) + IDs%id_numerical_mixing_T = register_diag_field('ocean_model','numerical_mixing_T', & + diag%mask3dT, Time, 'Spurious mixing of temperature due to advection', "C^2ms-1") + IDs%id_numerical_mixing_S = register_diag_field('ocean_model','numerical_mixing_S', & + diag%mask3dT, Time, 'Spurious mixing of salinity due to advection', "[S]^2ms-1") end subroutine register_transport_diags diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 886206b1b5..390d55aabd 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -1,59 +1,74 @@ !> Functions and routines involved in calculating numerical mixing module MOM_numerical_mixing -use MOM_grid, only : ocean_grid_type -use MOM_variables, only : thermo_var_ptrs, ocean_internal_state -use MOM_verticalGrid, only : verticalGrid_type +use MOM_diag_mediator, only : diag_ctrl +use MOM_grid, only : ocean_grid_type +use MOM_variables, only : thermo_var_ptrs, ocean_internal_state +use MOM_verticalGrid, only : verticalGrid_type + implicit none ; private public numerical_mixing contains -!< Calculate numerical mixing from saved output. -subroutine numerical_mixing(MIS, tv, G, GV, nm) - type(ocean_internal_state), intent(in) :: MIS !< For "MOM Internal State" a set of pointers to - !! the fields and accelerations making up ocean - !! internal physical state. - type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various - !! thermodynamic variables. - type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. - type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. - real, intent(inout) :: nm(:, :, :) !< numerical mxiing output +!< Calculate the suprious ``numerical'' mixing of tracer C due to advection. +subroutine numerical_mixing(G, GV, C, C_adxy, h, h_tendency, dt, C_adx, umo, C_ady, vmo, scale_constant, rho_ref, nm) + + implicit none + type(ocean_grid_type), intent(inout) :: G !< ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure + real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for + real, intent(inout) :: C_adxy(:, :, :) !< Explicit horizontal advection of tracer C + real, intent(in) :: h(:, :, :) !< Thickness + real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency + real, intent(in) :: dt !< Model timestep + real, intent(inout) :: C_adx(:, :, :) !< Explicit zonal advection of tracer C + real, intent(inout) :: umo(:, :, :) !< Total zonal mass transport + real, intent(inout) :: C_ady(:, :, :) !< Explicit meridional advection of tracer C + real, intent(inout) :: vmo(:, :, :) !< Total meridional mass transport + real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for temperature + real, intent(in) :: rho_ref !< Reference density + real, intent(inout) :: nm(:, :, :) !< temporary numerical mixing + + integer :: is, ie, js, je, nz !< Grid cell centre indexes + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke !< adjust for correct dimensions - C_adxy = C_adxy / (tv%C_p * rho_ref) !< units: [C]ms⁻¹ - C_adx = C_adx / (tv%C_p * rho_ref) !< units: [C]m⁻²s⁻¹ - C_ady = C_ady / (tv%C_p * rho_ref) !< units: [C]m⁻²s⁻¹ + C_adxy = C_adxy / (scale_constant * rho_ref) !< units: [C]ms⁻¹ + C_adx = C_adx / (scale_constant * rho_ref) !< units: [C]m⁻²s⁻¹ + C_ady = C_ady / (scale_constant * rho_ref) !< units: [C]m⁻²s⁻¹ + umo = umo / rho_ref !< units: m³s⁻¹ + vmo = vmo / rho_ref !< units: m³s⁻¹ - call thickness_weighted_variance_change(MIS%T, C_adxy, MIS%h, h_tendency, dt, G%iec, G%jec, GV%ke, nm) - call zonal_upwind_fluxes(MIS%T, C_adx, MIS%uh, G%IareaT, G%iec, G%jec, GV%ke, nm) - call meridional_upwind_fluxes(MIS%T, C_ady, MIS%vh, G%IareaT, G%iec, G%jec, GV%ke, nm) + call thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, is, ie, js, je, nz, nm) + call zonal_upwind_fluxes(C, C_adx, umo, G%IareaT, is, ie, js, je, nz, nm) + call meridional_upwind_fluxes(C, C_ady, vmo, G%IareaT, is, ie, js, je, nz, nm) end subroutine numerical_mixing !< Subroutine to calculate the thickness weighted variance change over a timestep -subroutine thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, Nx, Ny, Nz, nm) +subroutine thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, is, ie, js, je, nz, nm) implicit none - real, intent(in) :: C(:, :, :, :) !< Tracer to calculate numerical mixing for - real, intent(in) :: C_adxy(:, :, :, :) !< Explicit horizontal advection of tracer C - real, intent(in) :: h(:, :, :, :) !< Thickness - real, intent(in) :: h_tendency(:, :, :, :) !< Thickness tendency - real, intent(in) :: dt !< Model timestep - integer, intent(in) :: Nx, Ny, Nz !< Dimension lengths - real, intent(inout) :: nm(:, :, :) + real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for + real, intent(in) :: C_adxy(:, :, :) !< Explicit horizontal advection of tracer C + real, intent(in) :: h(:, :, :) !< Thickness + real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency + real, intent(in) :: dt !< Model timestep + integer, intent(in) :: is, ie, js, je, nz !< Grid cell centre indexes + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update integer :: i, j, k real :: h1, C1, hadv, Cadv - do i = 2, Nx-2 - do j = 2, Ny-2 - do k = 1, Nz - h1 = h(i, j, k, 1) - hadv = h1 + dt * h_tendency(i, j, k, 1) - C1 = C(i, j, k, 1) - Cadv = (h1 * C1 + dt * C_adxy(i, j, k, 1)) / hadv + do i = is+1, ie-2 + do j = js+1, je-2 + do k = 1, nz + h1 = h(i, j, k) + hadv = h1 + dt * h_tendency(i, j, k) + C1 = C(i, j, k) + Cadv = (h1 * C1 + dt * C_adxy(i, j, k)) / hadv nm(i-1, j-1, k) = (hadv * Cadv**2 - h1 * C1**2) / dt enddo enddo @@ -62,29 +77,29 @@ subroutine thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, Nx, end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(C, C_adx, uh, V, Nx, Ny, Nz, nm) +subroutine zonal_upwind_fluxes(C, C_adx, uh, A, is, ie, js, je, nz, nm) implicit none - real, intent(in) :: C(:, :, :, :) !< Tracer to calculate numerical mixing for - real, intent(in) :: C_adx(:, :, :, :) !< Explicit zonal advection of tracer C - real, intent(in) :: uh(:, :, :, :) !< Zonal mass transport - real, intent(in) :: V(:, :, :, :) !< Area of grid cells, computed from V / h + real, intent(in) :: C(:, :, :) ! < Tracer to calculate numerical mixing for + real, intent(in) :: C_adx(:, :, :) !< Explicit zonal advection of tracer C + real, intent(in) :: uh(:, :, :) !< Zonal transport + real, intent(in) :: A(:, :, :) !< Area of grid cells - integer, intent(in) :: Nx, Ny, Nz !< Dimension lengths - real, intent(inout) :: nm(:, :, :) + integer, intent(in) :: is, ie, js, je, nz !< Grid cell centre indexes + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update integer :: i, j, k - real :: Cupwind(Nx-2, Ny-3, Nz) - real :: east, west + real :: Cupwind(ie-2, je-3, nz) !< Empty variable for the upwind values of C + real :: east, west !< east and west locations for zonal derivative call zonal_upwind_values(uh, C, Cupwind) - do i = 2, Nx-2 - do j = 2, Ny-2 - do k = 1, Nz - east = 2 * C_adx(i, j, k, 1) * Cupwind(i, j, k) - uh(i, j, k, 1) * Cupwind(i, j, k)**2 - west = 2 * C_adx(i-1, j, k, 1) * Cupwind(i-1, j, k) - uh(i-1, j, k, 1) * Cupwind(i-1, j, k)**2 - nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((east - west) / V(i, j, k, 1)) + do i = is+1, ie-2 + do j = js+1, je-2 + do k = 1, nz + east = 2 * C_adx(i, j, k) * Cupwind(i, j, k) - uh(i, j, k) * Cupwind(i, j, k)**2 + west = 2 * C_adx(i-1, j, k) * Cupwind(i-1, j, k) - uh(i-1, j, k) * Cupwind(i-1, j, k)**2 + nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((east - west) / A(i, j, k)) enddo enddo enddo @@ -92,27 +107,23 @@ subroutine zonal_upwind_fluxes(C, C_adx, uh, V, Nx, Ny, Nz, nm) end subroutine zonal_upwind_fluxes !< Subroutine to calculate upwind values in zonal direction -subroutine zonal_upwind_values(u, C, Cupwind) +subroutine zonal_upwind_values(u, C, Cupwind, is, ie, js, je, nz) implicit none - real, intent(in) :: u(:, :, :, :) - real, intent(in) :: C(:, :, :, :) - real, intent(inout) :: Cupwind(:, :, :) + real, intent(in) :: u(:, :, :) !< Zonal transport + real, intent(in) :: C(:, :, :) !< Tracer + integer, intent(in) :: is, ie, js, je, nz !< Grid cell centre indexes + real, intent(inout) :: Cupwind(:, :, :) !< Zonal upwind values of C calculated using u integer :: i, j, k - integer :: xdim, ydim, zdim - - xdim = size(Cupwind, dim = 1) - ydim = size(Cupwind, dim = 2) - zdim = size(Cupwind, dim = 3) - - do i = 1, xdim - do j = 1, ydim - do k = 1, zdim - if (u(i, j, k, 1) >= 0) then - Cupwind(i, j, k) = C(i, j, k, 1) - else if (u(i, j, k, 1) < 0) then - Cupwind(i, j, k) = C(i+1, j, k, 1) + + do i = is, ie-2 + do j = js, je-3 + do k = 1, nz + if (u(i, j, k) >= 0) then + Cupwind(i, j, k) = C(i, j, k) + else if (u(i, j, k) < 0) then + Cupwind(i, j, k) = C(i+1, j, k) end if end do end do @@ -121,56 +132,52 @@ subroutine zonal_upwind_values(u, C, Cupwind) end subroutine zonal_upwind_values !< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(C, C_ady, vh, V, Nx, Ny, Nz, nm ) +subroutine meridional_upwind_fluxes(C, C_ady, vh, A, is, ie, js, je, nz, nm ) implicit none - real, intent(in) :: C(:, :, :, :) !< Tracer to calculate numerical mixing for - real, intent(in) :: C_ady(:, :, :, :) !< Explicit zonal advection of tracer C - real, intent(in) :: vh(:, :, :, :) !< Meridional transport - real, intent(in) :: V(:, :, :, :) !< Area of grid cells, computed from V / h + real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for + real, intent(in) :: C_ady(:, :, :) !< Explicit zonal advection of tracer C + real, intent(in) :: vh(:, :, :) !< Meridional transport + real, intent(in) :: A(:, :, :) !< Area of grid cells - integer, intent(in) :: Nx, Ny, Nz !< Dimension lengths + integer, intent(in) :: is, ie, js, je, nz !< Grid cell centre indexes real, intent(inout) :: nm(:, :, :) integer :: i, j, k - real :: Cupwind(Nx-3, Ny-2, Nz) + real :: Cupwind(ie-3, je-2, nz) real :: north, south call meridional_upwind_values(vh, C, Cupwind) - do i = 2, Nx-2 - do j = 2, Ny-2 - do k = 1, Nz - north = 2 * C_ady(i, j, k, 1) * Cupwind(i, j, k) - vh(i, j, k, 1) * Cupwind(i, j, k)**2 - south = 2 * C_ady(i, j-1, k, 1) * Cupwind(i, j-1, k) - vh(i, j-1, k, 1) * Cupwind(i, j-1, k)**2 - nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((north - south) / V(i, j, k, 1)) + do i = is+1, ie-2 + do j = js+1, je-2 + do k = 1, nz + north = 2 * C_ady(i, j, k) * Cupwind(i, j, k) - vh(i, j, k) * Cupwind(i, j, k)**2 + south = 2 * C_ady(i, j-1, k) * Cupwind(i, j-1, k) - vh(i, j-1, k) * Cupwind(i, j-1, k)**2 + nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((north - south) / A(i, j, k)) enddo enddo enddo end subroutine meridional_upwind_fluxes -subroutine meridional_upwind_values(v, C, Cupwind) +subroutine meridional_upwind_values(v, C, Cupwind, is, ie, js, je, nz) implicit none - real, intent(in) :: v(:, :, :, :) - real, intent(in) :: C(:, :, :, :) - real, intent(inout) :: Cupwind(:, :, :) + real, intent(in) :: v(:, :, :) !< Meridional transport + real, intent(in) :: C(:, :, :) !< Tracer + integer, intent(in) :: is, ie, js, je, nz !< Grid cell centre indexes + real, intent(inout) :: Cupwind(:, :, :) !< Meridional upwind values of C calculated using v integer :: i, j, k - integer :: xdim, ydim, zdim - - xdim = size(Cupwind, dim = 1) - ydim = size(Cupwind, dim = 2) - zdim = size(Cupwind, dim = 3) - - do i = 1, xdim - do j = 1, ydim - do k = 1, zdim - if (v(i, j, k, 1) >= 0) then - Cupwind(i, j, k) = C(i, j, k, 1) - else if (v(i, j, k, 1) < 0) then - Cupwind(i, j, k) = C(i, j+1, k, 1) + + do i = is, ie-3 + do j = js, js-2 + do k = 1, nz + if (v(i, j, k) >= 0) then + Cupwind(i, j, k) = C(i, j, k) + else if (v(i, j, k) < 0) then + Cupwind(i, j, k) = C(i, j+1, k) end if end do end do From 306ca87ecebe085dcc8d505bf894b6bd0ae2e232 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 25 Sep 2025 14:06:20 +1000 Subject: [PATCH 004/288] Have access to a tracer, just not sure which one --- src/diagnostics/MOM_diagnostics.F90 | 6 ++++-- src/diagnostics/MOM_numerical_mixing.F90 | 10 +++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index c5e51bf2f4..168993cbd4 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1710,10 +1710,12 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy call post_tracer_transport_diagnostics(G, GV, Reg, diag_pre_dyn%h_state, diag) - ! Post the numerical mixing + ! Compute and post the numerical mixing if (IDs%id_numerical_mixing_T > 0) then nmT(:,:,:) = 0. - call numerical_mixing(G, GV, C, C_adxy, h, h_tend, Idt, C_adx, umo, C_ady, vmo, scale_constant, rho_ref, nmT) + ! Reg%Tr(1)%ad_x this accesses info from the tracer registry but I am not sure of the order of the tracers + call numerical_mixing(G, GV, C, Reg%Tr(1)%advection_xy, h, h_tend, Idt, Reg%Tr(1)%ad_x, umo, Reg%Tr(1)%ad_y, vmo, & + scale_constant, rho_ref, nmT) call post_data(IDs%id_numerical_mixing_T, nmT, diag) ! For now just temperature ! elseif (IDs%id_numerical_mixing_S > 0) then diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 390d55aabd..7b1ef71165 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -27,7 +27,7 @@ subroutine numerical_mixing(G, GV, C, C_adxy, h, h_tendency, dt, C_adx, umo, C_a real, intent(inout) :: umo(:, :, :) !< Total zonal mass transport real, intent(inout) :: C_ady(:, :, :) !< Explicit meridional advection of tracer C real, intent(inout) :: vmo(:, :, :) !< Total meridional mass transport - real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for temperature + real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T real, intent(in) :: rho_ref !< Reference density real, intent(inout) :: nm(:, :, :) !< temporary numerical mixing @@ -36,8 +36,8 @@ subroutine numerical_mixing(G, GV, C, C_adxy, h, h_tendency, dt, C_adx, umo, C_a !< adjust for correct dimensions C_adxy = C_adxy / (scale_constant * rho_ref) !< units: [C]ms⁻¹ - C_adx = C_adx / (scale_constant * rho_ref) !< units: [C]m⁻²s⁻¹ - C_ady = C_ady / (scale_constant * rho_ref) !< units: [C]m⁻²s⁻¹ + C_adx = C_adx / (scale_constant * rho_ref) !< units: [C]m⁻²s⁻¹ + C_ady = C_ady / (scale_constant * rho_ref) !< units: [C]m⁻²s⁻¹ umo = umo / rho_ref !< units: m³s⁻¹ vmo = vmo / rho_ref !< units: m³s⁻¹ @@ -68,8 +68,8 @@ subroutine thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, is, h1 = h(i, j, k) hadv = h1 + dt * h_tendency(i, j, k) C1 = C(i, j, k) - Cadv = (h1 * C1 + dt * C_adxy(i, j, k)) / hadv - nm(i-1, j-1, k) = (hadv * Cadv**2 - h1 * C1**2) / dt + Cadv = h1 * C1 + dt * C_adxy(i, j, k) + nm(i-1, j-1, k) = (Cadv**2 / hadv - h1 * C1**2) / dt enddo enddo enddo From 2652a57fea8c735640710a53fa86d90fc71ddfab Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 1 Oct 2025 16:11:40 +1000 Subject: [PATCH 005/288] Move most nm aspects to tracer registry --- src/diagnostics/MOM_diagnostics.F90 | 31 +++++++++--------------- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- src/tracer/MOM_tracer_registry.F90 | 4 +++ src/tracer/MOM_tracer_types.F90 | 1 + 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 168993cbd4..03e7ef6c20 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -162,7 +162,6 @@ module MOM_diagnostics integer :: id_uhtr = -1, id_umo = -1, id_umo_2d = -1 integer :: id_vhtr = -1, id_vmo = -1, id_vmo_2d = -1 integer :: id_dynamics_h = -1, id_dynamics_h_tendency = -1 - integer :: id_numerical_mixing_T = -1, integer :: id_numerical_mixing_S = -1 !>@} end type transport_diag_IDs @@ -1651,9 +1650,8 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: umo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nmT ! Numerical mixing of temperature - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nmS ! Numerical mixing of salinity ! [H T-1 ~> m s-1 or kg m-2 s-1]. + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. @@ -1710,19 +1708,16 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy call post_tracer_transport_diagnostics(G, GV, Reg, diag_pre_dyn%h_state, diag) - ! Compute and post the numerical mixing - if (IDs%id_numerical_mixing_T > 0) then - nmT(:,:,:) = 0. - ! Reg%Tr(1)%ad_x this accesses info from the tracer registry but I am not sure of the order of the tracers - call numerical_mixing(G, GV, C, Reg%Tr(1)%advection_xy, h, h_tend, Idt, Reg%Tr(1)%ad_x, umo, Reg%Tr(1)%ad_y, vmo, & - scale_constant, rho_ref, nmT) - call post_data(IDs%id_numerical_mixing_T, nmT, diag) - ! For now just temperature - ! elseif (IDs%id_numerical_mixing_S > 0) then - ! nmS(:,:,:) = 0. - ! call numerical_mixing(C, C_adxy, h, h_tendency, Idt, C_adx, umo, C_ady, vmo, V, scale_constant, rho_ref, nmS) - ! call post_data(IDs%id_numerical_mixing_S, nmS, diag) - endif + do m=1,Reg%ntr ; if (Reg%Tr(m)%registry_diags) then + Tr => Reg%Tr(m) + ! Compute and post the numerical mixing + if (Tr%id_numerical_mixing > 0) then + nm(:,:,:) = 0. + call numerical_mixing(G, GV, C, Tr%advection_xy, h, h_tend, Idt, Tr%ad_x, umo, Tr%ad_y, vmo, & + 3991.86795711963, rho_ref, nm) + call post_data(Tr%numerical_mixing, nm, diag) + endif + endif; enddo call diag_restore_grids(diag) @@ -2256,10 +2251,6 @@ subroutine register_transport_diags(Time, G, GV, US, IDs, diag) IDs%id_dynamics_h_tendency = register_diag_field('ocean_model','dynamics_h_tendency', & diag%axesTl, Time, 'Change in layer thicknesses due to horizontal dynamics', & trim(thickness_units)//" s-1", conversion=GV%H_to_MKS*US%s_to_T, v_extensive=.true.) - IDs%id_numerical_mixing_T = register_diag_field('ocean_model','numerical_mixing_T', & - diag%mask3dT, Time, 'Spurious mixing of temperature due to advection', "C^2ms-1") - IDs%id_numerical_mixing_S = register_diag_field('ocean_model','numerical_mixing_S', & - diag%mask3dT, Time, 'Spurious mixing of salinity due to advection', "[S]^2ms-1") end subroutine register_transport_diags diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 7b1ef71165..72477b2341 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -80,7 +80,7 @@ end subroutine thickness_weighted_variance_change subroutine zonal_upwind_fluxes(C, C_adx, uh, A, is, ie, js, je, nz, nm) implicit none - real, intent(in) :: C(:, :, :) ! < Tracer to calculate numerical mixing for + real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for real, intent(in) :: C_adx(:, :, :) !< Explicit zonal advection of tracer C real, intent(in) :: uh(:, :, :) !< Zonal transport real, intent(in) :: A(:, :, :) !< Area of grid cells diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 50220be343..33041bcaed 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -382,6 +382,8 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "flux from the horizontal boundary diffusion scheme", trim(flux_units), & v_extensive=.true., & x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) + Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"numerical_mixing", & + diag%mask3dT, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", "[C]^2ms-1") else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -407,6 +409,8 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "Horizontal Boundary Diffusive Meridional Flux of "//trim(flux_longname), & flux_units, v_extensive=.true., conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T, & x_cell_method='sum') + Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"numerical_mixing", & + diag%mask3dT, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", "[C]^2ms-1") endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & diff --git a/src/tracer/MOM_tracer_types.F90 b/src/tracer/MOM_tracer_types.F90 index 730a453695..0d608f6f18 100644 --- a/src/tracer/MOM_tracer_types.F90 +++ b/src/tracer/MOM_tracer_types.F90 @@ -120,6 +120,7 @@ module MOM_tracer_types integer :: id_tr_vardec = -1 integer :: id_zint = -1, id_zint_100m = -1, id_surf = -1 integer :: id_net_surfflux = -1, id_NLT_tendency = -1, id_NLT_budget = -1 + integer :: id_numerical_mixing = -1 !>@} end type tracer_type From 9622add14664e058d5ce9598a89f80888e6eeb22 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 2 Oct 2025 14:34:36 +1000 Subject: [PATCH 006/288] file clean up --- src/diagnostics/MOM_diagnostics.F90 | 2 +- src/diagnostics/MOM_numerical_mixing.F90 | 82 +++++++++--------------- 2 files changed, 32 insertions(+), 52 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 03e7ef6c20..5f5b438060 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1713,7 +1713,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy ! Compute and post the numerical mixing if (Tr%id_numerical_mixing > 0) then nm(:,:,:) = 0. - call numerical_mixing(G, GV, C, Tr%advection_xy, h, h_tend, Idt, Tr%ad_x, umo, Tr%ad_y, vmo, & + call numerical_mixing(G, GV, Tr%t, Tr%advection_xy, h, h_tend, Idt, Tr%ad_x, umo, Tr%ad_y, vmo, & 3991.86795711963, rho_ref, nm) call post_data(Tr%numerical_mixing, nm, diag) endif diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 72477b2341..86a3370db7 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -62,17 +62,13 @@ subroutine thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, is, integer :: i, j, k real :: h1, C1, hadv, Cadv - do i = is+1, ie-2 - do j = js+1, je-2 - do k = 1, nz - h1 = h(i, j, k) - hadv = h1 + dt * h_tendency(i, j, k) - C1 = C(i, j, k) - Cadv = h1 * C1 + dt * C_adxy(i, j, k) - nm(i-1, j-1, k) = (Cadv**2 / hadv - h1 * C1**2) / dt - enddo - enddo - enddo + do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz + h1 = h(i, j, k) + hadv = h1 + dt * h_tendency(i, j, k) + C1 = C(i, j, k) + Cadv = h1 * C1 + dt * C_adxy(i, j, k) + nm(i-1, j-1, k) = (Cadv**2 / hadv - h1 * C1**2) / dt + enddo ; enddo ; enddo end subroutine thickness_weighted_variance_change @@ -94,15 +90,11 @@ subroutine zonal_upwind_fluxes(C, C_adx, uh, A, is, ie, js, je, nz, nm) call zonal_upwind_values(uh, C, Cupwind) - do i = is+1, ie-2 - do j = js+1, je-2 - do k = 1, nz - east = 2 * C_adx(i, j, k) * Cupwind(i, j, k) - uh(i, j, k) * Cupwind(i, j, k)**2 - west = 2 * C_adx(i-1, j, k) * Cupwind(i-1, j, k) - uh(i-1, j, k) * Cupwind(i-1, j, k)**2 - nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((east - west) / A(i, j, k)) - enddo - enddo - enddo + do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz + east = 2 * C_adx(i, j, k) * Cupwind(i, j, k) - uh(i, j, k) * Cupwind(i, j, k)**2 + west = 2 * C_adx(i-1, j, k) * Cupwind(i-1, j, k) - uh(i-1, j, k) * Cupwind(i-1, j, k)**2 + nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((east - west) / A(i, j, k)) + enddo ; enddo ; enddo end subroutine zonal_upwind_fluxes @@ -117,17 +109,13 @@ subroutine zonal_upwind_values(u, C, Cupwind, is, ie, js, je, nz) integer :: i, j, k - do i = is, ie-2 - do j = js, je-3 - do k = 1, nz - if (u(i, j, k) >= 0) then - Cupwind(i, j, k) = C(i, j, k) - else if (u(i, j, k) < 0) then - Cupwind(i, j, k) = C(i+1, j, k) - end if - end do - end do - end do + do i = is, ie-2 ; do j = js, je-3 ; do k = 1, nz + if (u(i, j, k) >= 0) then + Cupwind(i, j, k) = C(i, j, k) + elseif (u(i, j, k) < 0) then + Cupwind(i, j, k) = C(i+1, j, k) + endif + enddo ; enddo ; enddo end subroutine zonal_upwind_values @@ -149,15 +137,11 @@ subroutine meridional_upwind_fluxes(C, C_ady, vh, A, is, ie, js, je, nz, nm ) call meridional_upwind_values(vh, C, Cupwind) - do i = is+1, ie-2 - do j = js+1, je-2 - do k = 1, nz - north = 2 * C_ady(i, j, k) * Cupwind(i, j, k) - vh(i, j, k) * Cupwind(i, j, k)**2 - south = 2 * C_ady(i, j-1, k) * Cupwind(i, j-1, k) - vh(i, j-1, k) * Cupwind(i, j-1, k)**2 - nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((north - south) / A(i, j, k)) - enddo - enddo - enddo + do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz + north = 2 * C_ady(i, j, k) * Cupwind(i, j, k) - vh(i, j, k) * Cupwind(i, j, k)**2 + south = 2 * C_ady(i, j-1, k) * Cupwind(i, j-1, k) - vh(i, j-1, k) * Cupwind(i, j-1, k)**2 + nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((north - south) / A(i, j, k)) + enddo ; enddo ; enddo end subroutine meridional_upwind_fluxes @@ -171,17 +155,13 @@ subroutine meridional_upwind_values(v, C, Cupwind, is, ie, js, je, nz) integer :: i, j, k - do i = is, ie-3 - do j = js, js-2 - do k = 1, nz - if (v(i, j, k) >= 0) then - Cupwind(i, j, k) = C(i, j, k) - else if (v(i, j, k) < 0) then - Cupwind(i, j, k) = C(i, j+1, k) - end if - end do - end do - end do + do i = is, ie-3 ; do j = js, js-2 ; do k = 1, nz + if (v(i, j, k) >= 0) then + Cupwind(i, j, k) = C(i, j, k) + elseif (v(i, j, k) < 0) then + Cupwind(i, j, k) = C(i, j+1, k) + endif + enddo ; enddo ; enddo end subroutine meridional_upwind_values From 7013bc263c383834a84aaca820b70c0dd85ead19 Mon Sep 17 00:00:00 2001 From: Josef Bisits Date: Fri, 3 Oct 2025 09:19:18 +1000 Subject: [PATCH 007/288] correct diag axes --- src/tracer/MOM_tracer_registry.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 33041bcaed..756c4ae49f 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -383,7 +383,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u v_extensive=.true., & x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"numerical_mixing", & - diag%mask3dT, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", "[C]^2ms-1") + diag%mask3dTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", "[C]^2ms-1") else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -410,7 +410,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u flux_units, v_extensive=.true., conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T, & x_cell_method='sum') Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"numerical_mixing", & - diag%mask3dT, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", "[C]^2ms-1") + diag%mask3dTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", "[C]^2ms-1") endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & From 0dacffd73add472f0f1addf673d36b43b6f63ae5 Mon Sep 17 00:00:00 2001 From: Josef Bisits Date: Fri, 3 Oct 2025 09:28:57 +1000 Subject: [PATCH 008/288] check branch rename --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 86a3370db7..28177a7990 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -8,7 +8,7 @@ module MOM_numerical_mixing implicit none ; private -public numerical_mixing +public numerical_mixing ! git change contains From 934c84693aea2b2fcbfe0b14cd6fcb84e7b702bc Mon Sep 17 00:00:00 2001 From: Josef Bisits Date: Fri, 3 Oct 2025 09:30:02 +1000 Subject: [PATCH 009/288] all fine - remove temp edit --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 28177a7990..86a3370db7 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -8,7 +8,7 @@ module MOM_numerical_mixing implicit none ; private -public numerical_mixing ! git change +public numerical_mixing contains From da8a013075942d731980c8506aa13e63b1af0b7d Mon Sep 17 00:00:00 2001 From: Josef Bisits Date: Fri, 3 Oct 2025 10:02:30 +1000 Subject: [PATCH 010/288] Pass grid instead of IareaT --- src/diagnostics/MOM_numerical_mixing.F90 | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 86a3370db7..2fb06de9fe 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -16,7 +16,7 @@ module MOM_numerical_mixing subroutine numerical_mixing(G, GV, C, C_adxy, h, h_tendency, dt, C_adx, umo, C_ady, vmo, scale_constant, rho_ref, nm) implicit none - type(ocean_grid_type), intent(inout) :: G !< ocean grid structure + type(ocean_grid_type), intent(in) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for real, intent(inout) :: C_adxy(:, :, :) !< Explicit horizontal advection of tracer C @@ -42,8 +42,8 @@ subroutine numerical_mixing(G, GV, C, C_adxy, h, h_tendency, dt, C_adx, umo, C_a vmo = vmo / rho_ref !< units: m³s⁻¹ call thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, is, ie, js, je, nz, nm) - call zonal_upwind_fluxes(C, C_adx, umo, G%IareaT, is, ie, js, je, nz, nm) - call meridional_upwind_fluxes(C, C_ady, vmo, G%IareaT, is, ie, js, je, nz, nm) + call zonal_upwind_fluxes(C, C_adx, umo, G, is, ie, js, je, nz, nm) + call meridional_upwind_fluxes(C, C_ady, vmo, G, is, ie, js, je, nz, nm) end subroutine numerical_mixing @@ -73,13 +73,13 @@ subroutine thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, is, end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(C, C_adx, uh, A, is, ie, js, je, nz, nm) +subroutine zonal_upwind_fluxes(C, C_adx, uh, G, is, ie, js, je, nz, nm) implicit none real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for real, intent(in) :: C_adx(:, :, :) !< Explicit zonal advection of tracer C real, intent(in) :: uh(:, :, :) !< Zonal transport - real, intent(in) :: A(:, :, :) !< Area of grid cells + type(ocean_grid_type), intent(in) :: G !< ocean grid structure for inverse area integer, intent(in) :: is, ie, js, je, nz !< Grid cell centre indexes real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update @@ -93,7 +93,7 @@ subroutine zonal_upwind_fluxes(C, C_adx, uh, A, is, ie, js, je, nz, nm) do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz east = 2 * C_adx(i, j, k) * Cupwind(i, j, k) - uh(i, j, k) * Cupwind(i, j, k)**2 west = 2 * C_adx(i-1, j, k) * Cupwind(i-1, j, k) - uh(i-1, j, k) * Cupwind(i-1, j, k)**2 - nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((east - west) / A(i, j, k)) + nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((east - west) / G%IareaT(i, j)) enddo ; enddo ; enddo end subroutine zonal_upwind_fluxes @@ -120,13 +120,13 @@ subroutine zonal_upwind_values(u, C, Cupwind, is, ie, js, je, nz) end subroutine zonal_upwind_values !< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(C, C_ady, vh, A, is, ie, js, je, nz, nm ) +subroutine meridional_upwind_fluxes(C, C_ady, vh, G, is, ie, js, je, nz, nm ) implicit none - real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for - real, intent(in) :: C_ady(:, :, :) !< Explicit zonal advection of tracer C - real, intent(in) :: vh(:, :, :) !< Meridional transport - real, intent(in) :: A(:, :, :) !< Area of grid cells + real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for + real, intent(in) :: C_ady(:, :, :) !< Explicit zonal advection of tracer C + real, intent(in) :: vh(:, :, :) !< Meridional transport + type(ocean_grid_type), intent(in) :: G !< ocean grid structure for inverse area integer, intent(in) :: is, ie, js, je, nz !< Grid cell centre indexes real, intent(inout) :: nm(:, :, :) @@ -140,7 +140,7 @@ subroutine meridional_upwind_fluxes(C, C_ady, vh, A, is, ie, js, je, nz, nm ) do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz north = 2 * C_ady(i, j, k) * Cupwind(i, j, k) - vh(i, j, k) * Cupwind(i, j, k)**2 south = 2 * C_ady(i, j-1, k) * Cupwind(i, j-1, k) - vh(i, j-1, k) * Cupwind(i, j-1, k)**2 - nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((north - south) / A(i, j, k)) + nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((north - south) / G%IareaT(i, j)) enddo ; enddo ; enddo end subroutine meridional_upwind_fluxes From f7aec481e9b0e4a8f40aa524fe706e33ca2a500f Mon Sep 17 00:00:00 2001 From: Josef Bisits Date: Fri, 3 Oct 2025 11:01:01 +1000 Subject: [PATCH 011/288] Compiles but some declarations are clumsy --- src/diagnostics/MOM_numerical_mixing.F90 | 106 +++++++++++++---------- 1 file changed, 61 insertions(+), 45 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 2fb06de9fe..532215d417 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -1,4 +1,4 @@ -!> Functions and routines involved in calculating numerical mixing +!> Functions and routines involved in calculating numerical mixing of tracers due to advection module MOM_numerical_mixing use MOM_diag_mediator, only : diag_ctrl @@ -16,8 +16,8 @@ module MOM_numerical_mixing subroutine numerical_mixing(G, GV, C, C_adxy, h, h_tendency, dt, C_adx, umo, C_ady, vmo, scale_constant, rho_ref, nm) implicit none - type(ocean_grid_type), intent(in) :: G !< ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for real, intent(inout) :: C_adxy(:, :, :) !< Explicit horizontal advection of tracer C real, intent(in) :: h(:, :, :) !< Thickness @@ -29,10 +29,10 @@ subroutine numerical_mixing(G, GV, C, C_adxy, h, h_tendency, dt, C_adx, umo, C_a real, intent(inout) :: vmo(:, :, :) !< Total meridional mass transport real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T real, intent(in) :: rho_ref !< Reference density - real, intent(inout) :: nm(:, :, :) !< temporary numerical mixing + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic - integer :: is, ie, js, je, nz !< Grid cell centre indexes - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke + integer :: nz !< Grid cell layer indexes + nz = GV%ke !< adjust for correct dimensions C_adxy = C_adxy / (scale_constant * rho_ref) !< units: [C]ms⁻¹ @@ -41,14 +41,14 @@ subroutine numerical_mixing(G, GV, C, C_adxy, h, h_tendency, dt, C_adx, umo, C_a umo = umo / rho_ref !< units: m³s⁻¹ vmo = vmo / rho_ref !< units: m³s⁻¹ - call thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, is, ie, js, je, nz, nm) - call zonal_upwind_fluxes(C, C_adx, umo, G, is, ie, js, je, nz, nm) - call meridional_upwind_fluxes(C, C_ady, vmo, G, is, ie, js, je, nz, nm) + call thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, G, nz, nm) + call zonal_upwind_fluxes(C, C_adx, umo, G, nz, nm) + call meridional_upwind_fluxes(C, C_ady, vmo, G, nz, nm) end subroutine numerical_mixing !< Subroutine to calculate the thickness weighted variance change over a timestep -subroutine thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, is, ie, js, je, nz, nm) +subroutine thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, G, nz, nm) implicit none real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for @@ -56,11 +56,15 @@ subroutine thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, is, real, intent(in) :: h(:, :, :) !< Thickness real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency real, intent(in) :: dt !< Model timestep - integer, intent(in) :: is, ie, js, je, nz !< Grid cell centre indexes + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + integer, intent(in) :: nz !< Grid cell layer indexes real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update - integer :: i, j, k - real :: h1, C1, hadv, Cadv + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + real :: h1, C1, hadv, Cadv !< Temporary grid cell variables + + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz h1 = h(i, j, k) @@ -73,41 +77,47 @@ subroutine thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, is, end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(C, C_adx, uh, G, is, ie, js, je, nz, nm) +subroutine zonal_upwind_fluxes(C, C_adx, umo, G, nz, nm) implicit none real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for - real, intent(in) :: C_adx(:, :, :) !< Explicit zonal advection of tracer C - real, intent(in) :: uh(:, :, :) !< Zonal transport - type(ocean_grid_type), intent(in) :: G !< ocean grid structure for inverse area - - integer, intent(in) :: is, ie, js, je, nz !< Grid cell centre indexes + real, intent(in) :: C_adx(:, :, :) !< Explicit zonal advection of tracer + real, intent(in) :: umo(:, :, :) !< Zonal mass transport + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update - integer :: i, j, k - real :: Cupwind(ie-2, je-3, nz) !< Empty variable for the upwind values of C - real :: east, west !< east and west locations for zonal derivative + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + real :: Cupwind(G%iec-2, G%jec-3, nz) !< Empty variable for the upwind values of C + real :: east, west !< East and West positions for zonal derivative - call zonal_upwind_values(uh, C, Cupwind) + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec + + call zonal_upwind_values(umo, C, Cupwind, G, nz) do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz - east = 2 * C_adx(i, j, k) * Cupwind(i, j, k) - uh(i, j, k) * Cupwind(i, j, k)**2 - west = 2 * C_adx(i-1, j, k) * Cupwind(i-1, j, k) - uh(i-1, j, k) * Cupwind(i-1, j, k)**2 + east = 2 * C_adx(i, j, k) * Cupwind(i, j, k) - umo(i, j, k) * Cupwind(i, j, k)**2 + west = 2 * C_adx(i-1, j, k) * Cupwind(i-1, j, k) - umo(i-1, j, k) * Cupwind(i-1, j, k)**2 nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((east - west) / G%IareaT(i, j)) enddo ; enddo ; enddo end subroutine zonal_upwind_fluxes !< Subroutine to calculate upwind values in zonal direction -subroutine zonal_upwind_values(u, C, Cupwind, is, ie, js, je, nz) +subroutine zonal_upwind_values(u, C, Cupwind, G, nz) implicit none real, intent(in) :: u(:, :, :) !< Zonal transport real, intent(in) :: C(:, :, :) !< Tracer - integer, intent(in) :: is, ie, js, je, nz !< Grid cell centre indexes - real, intent(inout) :: Cupwind(:, :, :) !< Zonal upwind values of C calculated using u + real, intent(inout) :: Cupwind(:, :, :) !< Zonal upwind values of C calculated using v + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes + + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters - integer :: i, j, k + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do i = is, ie-2 ; do j = js, je-3 ; do k = 1, nz if (u(i, j, k) >= 0) then @@ -120,40 +130,46 @@ subroutine zonal_upwind_values(u, C, Cupwind, is, ie, js, je, nz) end subroutine zonal_upwind_values !< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(C, C_ady, vh, G, is, ie, js, je, nz, nm ) +subroutine meridional_upwind_fluxes(C, C_ady, vmo, G, nz, nm) implicit none real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for - real, intent(in) :: C_ady(:, :, :) !< Explicit zonal advection of tracer C - real, intent(in) :: vh(:, :, :) !< Meridional transport - type(ocean_grid_type), intent(in) :: G !< ocean grid structure for inverse area - - integer, intent(in) :: is, ie, js, je, nz !< Grid cell centre indexes - real, intent(inout) :: nm(:, :, :) + real, intent(in) :: C_ady(:, :, :) !< Explicit meridional advection of tracer + real, intent(in) :: vmo(:, :, :) !< Meridional mass transport + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update - integer :: i, j, k - real :: Cupwind(ie-3, je-2, nz) - real :: north, south + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + real :: Cupwind(G%iec-3, G%jec-2, nz) !< Empty variable for the meridional upwind tracer values + real :: north, south !< North and South positions for meridional derivative + + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - call meridional_upwind_values(vh, C, Cupwind) + call meridional_upwind_values(vmo, C, Cupwind, G, nz) do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz - north = 2 * C_ady(i, j, k) * Cupwind(i, j, k) - vh(i, j, k) * Cupwind(i, j, k)**2 - south = 2 * C_ady(i, j-1, k) * Cupwind(i, j-1, k) - vh(i, j-1, k) * Cupwind(i, j-1, k)**2 + north = 2 * C_ady(i, j, k) * Cupwind(i, j, k) - vmo(i, j, k) * Cupwind(i, j, k)**2 + south = 2 * C_ady(i, j-1, k) * Cupwind(i, j-1, k) - vmo(i, j-1, k) * Cupwind(i, j-1, k)**2 nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((north - south) / G%IareaT(i, j)) enddo ; enddo ; enddo end subroutine meridional_upwind_fluxes -subroutine meridional_upwind_values(v, C, Cupwind, is, ie, js, je, nz) +subroutine meridional_upwind_values(v, C, Cupwind, G, nz) implicit none real, intent(in) :: v(:, :, :) !< Meridional transport real, intent(in) :: C(:, :, :) !< Tracer - integer, intent(in) :: is, ie, js, je, nz !< Grid cell centre indexes real, intent(inout) :: Cupwind(:, :, :) !< Meridional upwind values of C calculated using v + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes + + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters - integer :: i, j, k + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do i = is, ie-3 ; do j = js, js-2 ; do k = 1, nz if (v(i, j, k) >= 0) then From 6115782023543bf449f8dac1f8434eeac5ddfa07 Mon Sep 17 00:00:00 2001 From: Josef Bisits Date: Fri, 3 Oct 2025 11:07:26 +1000 Subject: [PATCH 012/288] Correct dimension of output --- src/tracer/MOM_tracer_registry.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 756c4ae49f..0f85eab8ac 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -383,7 +383,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u v_extensive=.true., & x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"numerical_mixing", & - diag%mask3dTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", "[C]^2ms-1") + diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", "[C]^2ms-1") else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -410,7 +410,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u flux_units, v_extensive=.true., conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T, & x_cell_method='sum') Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"numerical_mixing", & - diag%mask3dTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", "[C]^2ms-1") + diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", "[C]^2ms-1") endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & From f38013f7ad15f7ecfc01d4d7b4b4573f73712b9e Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 3 Oct 2025 12:42:50 +1000 Subject: [PATCH 013/288] Move to use tracer registry in module functions --- src/diagnostics/MOM_numerical_mixing.F90 | 130 +++++++++++------------ 1 file changed, 64 insertions(+), 66 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 532215d417..b242294253 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -3,7 +3,8 @@ module MOM_numerical_mixing use MOM_diag_mediator, only : diag_ctrl use MOM_grid, only : ocean_grid_type -use MOM_variables, only : thermo_var_ptrs, ocean_internal_state +use MOM_tracer_types, only : tracer_type +! use MOM_variables, only : thermo_var_ptrs, ocean_internal_state use MOM_verticalGrid, only : verticalGrid_type implicit none ; private @@ -13,79 +14,76 @@ module MOM_numerical_mixing contains !< Calculate the suprious ``numerical'' mixing of tracer C due to advection. -subroutine numerical_mixing(G, GV, C, C_adxy, h, h_tendency, dt, C_adx, umo, C_ady, vmo, scale_constant, rho_ref, nm) +subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_constant, rho_ref, nm) implicit none type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for - real, intent(inout) :: C_adxy(:, :, :) !< Explicit horizontal advection of tracer C + type(tracer_type), intent(in) :: Tr !< Tracer real, intent(in) :: h(:, :, :) !< Thickness real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency real, intent(in) :: dt !< Model timestep - real, intent(inout) :: C_adx(:, :, :) !< Explicit zonal advection of tracer C real, intent(inout) :: umo(:, :, :) !< Total zonal mass transport - real, intent(inout) :: C_ady(:, :, :) !< Explicit meridional advection of tracer C real, intent(inout) :: vmo(:, :, :) !< Total meridional mass transport real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T real, intent(in) :: rho_ref !< Reference density real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic - integer :: nz !< Grid cell layer indexes + integer :: nz !< Grid cell layer indexes + real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct + ! e.g. for temperature need to divide by specific heat capacity * rho_ref nz = GV%ke + Tr_adv_scale = scale_constant * rho_ref !< adjust for correct dimensions - C_adxy = C_adxy / (scale_constant * rho_ref) !< units: [C]ms⁻¹ - C_adx = C_adx / (scale_constant * rho_ref) !< units: [C]m⁻²s⁻¹ - C_ady = C_ady / (scale_constant * rho_ref) !< units: [C]m⁻²s⁻¹ umo = umo / rho_ref !< units: m³s⁻¹ vmo = vmo / rho_ref !< units: m³s⁻¹ - call thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, G, nz, nm) - call zonal_upwind_fluxes(C, C_adx, umo, G, nz, nm) - call meridional_upwind_fluxes(C, C_ady, vmo, G, nz, nm) + call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, Tr_adv_scale, nz, nm) + call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) + call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) end subroutine numerical_mixing !< Subroutine to calculate the thickness weighted variance change over a timestep -subroutine thickness_weighted_variance_change(C, C_adxy, h, h_tendency, dt, G, nz, nm) +subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) implicit none - real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for - real, intent(in) :: C_adxy(:, :, :) !< Explicit horizontal advection of tracer C - real, intent(in) :: h(:, :, :) !< Thickness - real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency - real, intent(in) :: dt !< Model timestep - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update - - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - real :: h1, C1, hadv, Cadv !< Temporary grid cell variables + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: h(:, :, :) !< Thickness + real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency + real, intent(in) :: dt !< Model timestep + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + real :: h1, C1, hadv, Cadv !< Temporary grid cell variables is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz h1 = h(i, j, k) hadv = h1 + dt * h_tendency(i, j, k) - C1 = C(i, j, k) - Cadv = h1 * C1 + dt * C_adxy(i, j, k) + C1 = Tr%t(i, j, k) + Cadv = h1 * C1 + dt * Tr%advection_xy(i, j, k) / Tr_adv_scale nm(i-1, j-1, k) = (Cadv**2 / hadv - h1 * C1**2) / dt enddo ; enddo ; enddo end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(C, C_adx, umo, G, nz, nm) +subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) implicit none - real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for - real, intent(in) :: C_adx(:, :, :) !< Explicit zonal advection of tracer - real, intent(in) :: umo(:, :, :) !< Zonal mass transport - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: umo(:, :, :) !< Zonal mass transport + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters @@ -94,51 +92,51 @@ subroutine zonal_upwind_fluxes(C, C_adx, umo, G, nz, nm) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - call zonal_upwind_values(umo, C, Cupwind, G, nz) + call zonal_upwind_values(umo, Tr, Cupwind, G, nz) do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz - east = 2 * C_adx(i, j, k) * Cupwind(i, j, k) - umo(i, j, k) * Cupwind(i, j, k)**2 - west = 2 * C_adx(i-1, j, k) * Cupwind(i-1, j, k) - umo(i-1, j, k) * Cupwind(i-1, j, k)**2 + east = 2 * (Tr%ad_x(i, j, k) / Tr_adv_scale) * Cupwind(i, j, k) - umo(i, j, k) * Cupwind(i, j, k)**2 + west = 2 * (Tr%ad_x(i-1, j, k) / Tr_adv_scale) * Cupwind(i-1, j, k) - umo(i-1, j, k) * Cupwind(i-1, j, k)**2 nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((east - west) / G%IareaT(i, j)) enddo ; enddo ; enddo end subroutine zonal_upwind_fluxes !< Subroutine to calculate upwind values in zonal direction -subroutine zonal_upwind_values(u, C, Cupwind, G, nz) +subroutine zonal_upwind_values(u, Tr, Cupwind, G, nz) implicit none - real, intent(in) :: u(:, :, :) !< Zonal transport - real, intent(in) :: C(:, :, :) !< Tracer - real, intent(inout) :: Cupwind(:, :, :) !< Zonal upwind values of C calculated using v - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(in) :: u(:, :, :) !< Zonal transport + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(inout) :: Cupwind(:, :, :) !< Zonal upwind values of C calculated using v + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do i = is, ie-2 ; do j = js, je-3 ; do k = 1, nz if (u(i, j, k) >= 0) then - Cupwind(i, j, k) = C(i, j, k) + Cupwind(i, j, k) = Tr%t(i, j, k) elseif (u(i, j, k) < 0) then - Cupwind(i, j, k) = C(i+1, j, k) + Cupwind(i, j, k) = Tr%t(i+1, j, k) endif enddo ; enddo ; enddo end subroutine zonal_upwind_values !< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(C, C_ady, vmo, G, nz, nm) +subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) implicit none - real, intent(in) :: C(:, :, :) !< Tracer to calculate numerical mixing for - real, intent(in) :: C_ady(:, :, :) !< Explicit meridional advection of tracer - real, intent(in) :: vmo(:, :, :) !< Meridional mass transport - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: vmo(:, :, :) !< Meridional mass transport + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters @@ -147,24 +145,24 @@ subroutine meridional_upwind_fluxes(C, C_ady, vmo, G, nz, nm) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - call meridional_upwind_values(vmo, C, Cupwind, G, nz) + call meridional_upwind_values(vmo, Tr, Cupwind, G, nz) do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz - north = 2 * C_ady(i, j, k) * Cupwind(i, j, k) - vmo(i, j, k) * Cupwind(i, j, k)**2 - south = 2 * C_ady(i, j-1, k) * Cupwind(i, j-1, k) - vmo(i, j-1, k) * Cupwind(i, j-1, k)**2 + north = 2 * (Tr%ad_y(i, j, k) / Tr_adv_scale)* Cupwind(i, j, k) - vmo(i, j, k) * Cupwind(i, j, k)**2 + south = 2 * (Tr%ad_y(i, j-1, k) / Tr_adv_scale)* Cupwind(i, j-1, k) - vmo(i, j-1, k) * Cupwind(i, j-1, k)**2 nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((north - south) / G%IareaT(i, j)) enddo ; enddo ; enddo end subroutine meridional_upwind_fluxes -subroutine meridional_upwind_values(v, C, Cupwind, G, nz) +subroutine meridional_upwind_values(v, Tr, Cupwind, G, nz) implicit none - real, intent(in) :: v(:, :, :) !< Meridional transport - real, intent(in) :: C(:, :, :) !< Tracer - real, intent(inout) :: Cupwind(:, :, :) !< Meridional upwind values of C calculated using v - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(in) :: v(:, :, :) !< Meridional transport + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(inout) :: Cupwind(:, :, :) !< Meridional upwind values of C calculated using v + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters @@ -173,9 +171,9 @@ subroutine meridional_upwind_values(v, C, Cupwind, G, nz) do i = is, ie-3 ; do j = js, js-2 ; do k = 1, nz if (v(i, j, k) >= 0) then - Cupwind(i, j, k) = C(i, j, k) + Cupwind(i, j, k) = Tr%t(i, j, k) elseif (v(i, j, k) < 0) then - Cupwind(i, j, k) = C(i, j+1, k) + Cupwind(i, j, k) = Tr%t(i, j+1, k) endif enddo ; enddo ; enddo From 2d3831f44a99d830de9a7b2b5918b86d65479755 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 3 Oct 2025 12:53:02 +1000 Subject: [PATCH 014/288] All comments 2 spaces --- src/diagnostics/MOM_diagnostics.F90 | 7 +-- src/diagnostics/MOM_numerical_mixing.F90 | 79 ++++++++++++------------ 2 files changed, 42 insertions(+), 44 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 5f5b438060..9a9063f5bf 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1710,12 +1710,11 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy do m=1,Reg%ntr ; if (Reg%Tr(m)%registry_diags) then Tr => Reg%Tr(m) - ! Compute and post the numerical mixing + ! Compute and post the numerical mixing if required if (Tr%id_numerical_mixing > 0) then nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr%t, Tr%advection_xy, h, h_tend, Idt, Tr%ad_x, umo, Tr%ad_y, vmo, & - 3991.86795711963, rho_ref, nm) - call post_data(Tr%numerical_mixing, nm, diag) + call numerical_mixing(G, GV, Tr, h, h_tend, Idt, umo, vmo, 3991.86795711963, rho_ref, nm) + call post_data(Tr%id_numerical_mixing, nm, diag) endif endif; enddo diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index b242294253..e6d1f5aa65 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -4,7 +4,6 @@ module MOM_numerical_mixing use MOM_diag_mediator, only : diag_ctrl use MOM_grid, only : ocean_grid_type use MOM_tracer_types, only : tracer_type -! use MOM_variables, only : thermo_var_ptrs, ocean_internal_state use MOM_verticalGrid, only : verticalGrid_type implicit none ; private @@ -29,15 +28,15 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_consta real, intent(in) :: rho_ref !< Reference density real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic - integer :: nz !< Grid cell layer indexes - real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct - ! e.g. for temperature need to divide by specific heat capacity * rho_ref + integer :: nz !< Grid cell layer indexes + real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct + ! e.g. for temperature need to divide by specific heat capacity * rho_ref nz = GV%ke Tr_adv_scale = scale_constant * rho_ref !< adjust for correct dimensions - umo = umo / rho_ref !< units: m³s⁻¹ - vmo = vmo / rho_ref !< units: m³s⁻¹ + umo = umo / rho_ref !< units: m³s⁻¹ + vmo = vmo / rho_ref !< units: m³s⁻¹ call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, Tr_adv_scale, nz, nm) call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) @@ -58,9 +57,9 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d integer, intent(in) :: nz !< Grid cell layer indexes real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - real :: h1, C1, hadv, Cadv !< Temporary grid cell variables + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + real :: h1, C1, hadv, Cadv !< Temporary grid cell variables is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -78,17 +77,17 @@ end subroutine thickness_weighted_variance_change subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: umo(:, :, :) !< Zonal mass transport - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update - - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - real :: Cupwind(G%iec-2, G%jec-3, nz) !< Empty variable for the upwind values of C - real :: east, west !< East and West positions for zonal derivative + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: umo(:, :, :) !< Zonal mass transport + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + real :: Cupwind(G%iec-2, G%jec-3, nz) !< Empty variable for the upwind values of C + real :: east, west !< East and West positions for zonal derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -106,14 +105,14 @@ end subroutine zonal_upwind_fluxes subroutine zonal_upwind_values(u, Tr, Cupwind, G, nz) implicit none - real, intent(in) :: u(:, :, :) !< Zonal transport - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(inout) :: Cupwind(:, :, :) !< Zonal upwind values of C calculated using v - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(in) :: u(:, :, :) !< Zonal transport + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(inout) :: Cupwind(:, :, :) !< Zonal upwind values of C calculated using v + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -131,17 +130,17 @@ end subroutine zonal_upwind_values subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: vmo(:, :, :) !< Meridional mass transport - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update - - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - real :: Cupwind(G%iec-3, G%jec-2, nz) !< Empty variable for the meridional upwind tracer values - real :: north, south !< North and South positions for meridional derivative + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: vmo(:, :, :) !< Meridional mass transport + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + real :: Cupwind(G%iec-3, G%jec-2, nz) !< Empty variable for the meridional upwind tracer values + real :: north, south !< North and South positions for meridional derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -164,8 +163,8 @@ subroutine meridional_upwind_values(v, Tr, Cupwind, G, nz) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area integer, intent(in) :: nz !< Grid cell layer indexes - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec From ea9ba5c58fbc21e628bb49b000ed6a775755a7c3 Mon Sep 17 00:00:00 2001 From: Josef Bisits Date: Fri, 3 Oct 2025 14:50:12 +1000 Subject: [PATCH 015/288] Correct call to subroutine - compiles --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index e6d1f5aa65..926f91eb39 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -38,7 +38,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_consta umo = umo / rho_ref !< units: m³s⁻¹ vmo = vmo / rho_ref !< units: m³s⁻¹ - call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, Tr_adv_scale, nz, nm) + call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) From 1667e35bd9b20ac20458b8d7656c07e7ea023b4e Mon Sep 17 00:00:00 2001 From: Josef Bisits Date: Fri, 3 Oct 2025 16:12:01 +1000 Subject: [PATCH 016/288] Hard code some things for now - compiles! --- src/diagnostics/MOM_diagnostics.F90 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 9a9063f5bf..1ae7e24871 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -29,7 +29,7 @@ module MOM_diagnostics use MOM_interface_heights, only : find_eta, find_col_mass use MOM_spatial_means, only : global_area_mean, global_layer_mean use MOM_spatial_means, only : global_volume_mean, global_area_integral -use MOM_tracer_registry, only : tracer_registry_type, post_tracer_transport_diagnostics +use MOM_tracer_registry, only : tracer_type, tracer_registry_type, post_tracer_transport_diagnostics use MOM_unit_scaling, only : unit_scale_type use MOM_variables, only : thermo_var_ptrs, ocean_internal_state, p3d use MOM_variables, only : accel_diag_ptrs, cont_diag_ptrs, surface @@ -1655,7 +1655,9 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. - integer :: i, j, k, is, ie, js, je, nz + type(tracer_type), pointer :: Tr !< Tracer type for numerical mixing + real :: scale_constant, rho_ref + integer :: i, j, k, is, ie, js, je, nz, m is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke Idt = 1. / dt_trans @@ -1712,8 +1714,10 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy Tr => Reg%Tr(m) ! Compute and post the numerical mixing if required if (Tr%id_numerical_mixing > 0) then + scale_constant = 3991.86795711963 + rho_ref = 1035.0 nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, h, h_tend, Idt, umo, vmo, 3991.86795711963, rho_ref, nm) + call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, umo, vmo, scale_constant, rho_ref, nm) call post_data(Tr%id_numerical_mixing, nm, diag) endif endif; enddo From 7c4546d6d9bb47aea6092041c144f964b460ac4f Mon Sep 17 00:00:00 2001 From: Josef Bisits Date: Mon, 13 Oct 2025 14:15:10 +1100 Subject: [PATCH 017/288] underscore in nm diag name --- src/tracer/MOM_tracer_registry.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 0f85eab8ac..30fa5cfbf6 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -382,7 +382,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "flux from the horizontal boundary diffusion scheme", trim(flux_units), & v_extensive=.true., & x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) - Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"numerical_mixing", & + Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", "[C]^2ms-1") else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & From fd8dad69fafcbe9948573e7dbdf770fce8af4a80 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 13 Oct 2025 15:49:20 +1100 Subject: [PATCH 018/288] Correct area calculation --- src/diagnostics/MOM_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 926f91eb39..b3929b199f 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -96,7 +96,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz east = 2 * (Tr%ad_x(i, j, k) / Tr_adv_scale) * Cupwind(i, j, k) - umo(i, j, k) * Cupwind(i, j, k)**2 west = 2 * (Tr%ad_x(i-1, j, k) / Tr_adv_scale) * Cupwind(i-1, j, k) - umo(i-1, j, k) * Cupwind(i-1, j, k)**2 - nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((east - west) / G%IareaT(i, j)) + nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo ; enddo end subroutine zonal_upwind_fluxes @@ -149,7 +149,7 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz north = 2 * (Tr%ad_y(i, j, k) / Tr_adv_scale)* Cupwind(i, j, k) - vmo(i, j, k) * Cupwind(i, j, k)**2 south = 2 * (Tr%ad_y(i, j-1, k) / Tr_adv_scale)* Cupwind(i, j-1, k) - vmo(i, j-1, k) * Cupwind(i, j-1, k)**2 - nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((north - south) / G%IareaT(i, j)) + nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((north - south) * G%IareaT(i, j)) enddo ; enddo ; enddo end subroutine meridional_upwind_fluxes From 189d562e0c0777414bc26e1a7de2d261a50de6fd Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 13 Oct 2025 16:14:54 +1100 Subject: [PATCH 019/288] Correct other variable name instance --- src/tracer/MOM_tracer_registry.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 30fa5cfbf6..a90e36bd88 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -409,7 +409,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "Horizontal Boundary Diffusive Meridional Flux of "//trim(flux_longname), & flux_units, v_extensive=.true., conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T, & x_cell_method='sum') - Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"numerical_mixing", & + Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", "[C]^2ms-1") endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & From 57eaea41b191f8c56c168afb14df51f0c7d7099c Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 14 Oct 2025 10:45:25 +1100 Subject: [PATCH 020/288] Try looping through all data - could break due to illegal access --- src/diagnostics/MOM_numerical_mixing.F90 | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index b3929b199f..af693d3dc5 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -63,12 +63,12 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz + do i = is, ie ; do j = js, je ; do k = 1, nz h1 = h(i, j, k) hadv = h1 + dt * h_tendency(i, j, k) C1 = Tr%t(i, j, k) Cadv = h1 * C1 + dt * Tr%advection_xy(i, j, k) / Tr_adv_scale - nm(i-1, j-1, k) = (Cadv**2 / hadv - h1 * C1**2) / dt + nm(i, j, k) = (Cadv**2 / hadv - h1 * C1**2) / dt enddo ; enddo ; enddo end subroutine thickness_weighted_variance_change @@ -86,17 +86,17 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters - real :: Cupwind(G%iec-2, G%jec-3, nz) !< Empty variable for the upwind values of C + real :: Cupwind(G%iec, G%jec, nz) !< Empty variable for the upwind values of C real :: east, west !< East and West positions for zonal derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec call zonal_upwind_values(umo, Tr, Cupwind, G, nz) - do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz + do i = is, ie-1 ; do j = js, je ; do k = 1, nz east = 2 * (Tr%ad_x(i, j, k) / Tr_adv_scale) * Cupwind(i, j, k) - umo(i, j, k) * Cupwind(i, j, k)**2 west = 2 * (Tr%ad_x(i-1, j, k) / Tr_adv_scale) * Cupwind(i-1, j, k) - umo(i-1, j, k) * Cupwind(i-1, j, k)**2 - nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((east - west) * G%IareaT(i, j)) + nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo ; enddo end subroutine zonal_upwind_fluxes @@ -116,7 +116,7 @@ subroutine zonal_upwind_values(u, Tr, Cupwind, G, nz) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - do i = is, ie-2 ; do j = js, je-3 ; do k = 1, nz + do i = is, ie ; do j = js, je ; do k = 1, nz if (u(i, j, k) >= 0) then Cupwind(i, j, k) = Tr%t(i, j, k) elseif (u(i, j, k) < 0) then @@ -139,17 +139,17 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters - real :: Cupwind(G%iec-3, G%jec-2, nz) !< Empty variable for the meridional upwind tracer values + real :: Cupwind(G%iec, G%jec, nz) !< Empty variable for the meridional upwind tracer values real :: north, south !< North and South positions for meridional derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec call meridional_upwind_values(vmo, Tr, Cupwind, G, nz) - do i = is+1, ie-2 ; do j = js+1, je-2 ; do k = 1, nz + do i = is, ie ; do j = js, je ; do k = 1, nz north = 2 * (Tr%ad_y(i, j, k) / Tr_adv_scale)* Cupwind(i, j, k) - vmo(i, j, k) * Cupwind(i, j, k)**2 south = 2 * (Tr%ad_y(i, j-1, k) / Tr_adv_scale)* Cupwind(i, j-1, k) - vmo(i, j-1, k) * Cupwind(i, j-1, k)**2 - nm(i-1, j-1, k) = nm(i-1, j-1, k) + ((north - south) * G%IareaT(i, j)) + nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) enddo ; enddo ; enddo end subroutine meridional_upwind_fluxes @@ -168,7 +168,7 @@ subroutine meridional_upwind_values(v, Tr, Cupwind, G, nz) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - do i = is, ie-3 ; do j = js, js-2 ; do k = 1, nz + do i = is, ie ; do j = js, js ; do k = 1, nz if (v(i, j, k) >= 0) then Cupwind(i, j, k) = Tr%t(i, j, k) elseif (v(i, j, k) < 0) then @@ -178,4 +178,4 @@ subroutine meridional_upwind_values(v, Tr, Cupwind, G, nz) end subroutine meridional_upwind_values -end module MOM_numerical_mixing \ No newline at end of file +end module MOM_numerical_mixing From 57ce69e2acc452d6464472b6d975028323f385f6 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 14 Oct 2025 11:35:53 +1100 Subject: [PATCH 021/288] Align comments --- src/diagnostics/MOM_numerical_mixing.F90 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index af693d3dc5..79ae571c17 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -84,10 +84,10 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) integer, intent(in) :: nz !< Grid cell layer indexes real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - real :: Cupwind(G%iec, G%jec, nz) !< Empty variable for the upwind values of C - real :: east, west !< East and West positions for zonal derivative + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + real :: Cupwind(G%iec, G%jec, nz) !< Empty variable for the upwind values of C + real :: east, west !< East and West positions for zonal derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -137,10 +137,10 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) integer, intent(in) :: nz !< Grid cell layer indexes real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters real :: Cupwind(G%iec, G%jec, nz) !< Empty variable for the meridional upwind tracer values - real :: north, south !< North and South positions for meridional derivative + real :: north, south !< North and South positions for meridional derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec From 19ec52b7b522c630e78e36ec4e0f1b4414fda180 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 14 Oct 2025 14:57:09 +1100 Subject: [PATCH 022/288] i index not correct in zonal --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 79ae571c17..9e25908049 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -93,7 +93,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) call zonal_upwind_values(umo, Tr, Cupwind, G, nz) - do i = is, ie-1 ; do j = js, je ; do k = 1, nz + do i = is, ie ; do j = js, je ; do k = 1, nz east = 2 * (Tr%ad_x(i, j, k) / Tr_adv_scale) * Cupwind(i, j, k) - umo(i, j, k) * Cupwind(i, j, k)**2 west = 2 * (Tr%ad_x(i-1, j, k) / Tr_adv_scale) * Cupwind(i-1, j, k) - umo(i-1, j, k) * Cupwind(i-1, j, k)**2 nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) From 120b8a637227c548af7ae0f09aa49262ea3597f0 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 14 Oct 2025 15:41:12 +1100 Subject: [PATCH 023/288] Try with only variance change --- src/diagnostics/MOM_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 9e25908049..5c0f66442b 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -39,8 +39,8 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_consta vmo = vmo / rho_ref !< units: m³s⁻¹ call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) - call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) - call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) +! call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) +! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) end subroutine numerical_mixing From b62620530d3fa2703c32afa89d88f9e26ba7a378 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 14 Oct 2025 16:15:02 +1100 Subject: [PATCH 024/288] Try with only flux terms --- src/diagnostics/MOM_numerical_mixing.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 5c0f66442b..555e4ff2ae 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -38,9 +38,9 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_consta umo = umo / rho_ref !< units: m³s⁻¹ vmo = vmo / rho_ref !< units: m³s⁻¹ - call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) -! call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) -! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) +! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) + call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) + call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) end subroutine numerical_mixing From 3e54a6e7c7234fdec33b473f4e8b8f5745dea45d Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 15 Oct 2025 09:44:08 +1100 Subject: [PATCH 025/288] z loop on outside + match MOM6 style for faces in counters --- src/diagnostics/MOM_numerical_mixing.F90 | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 555e4ff2ae..69e88542f8 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -93,11 +93,13 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) call zonal_upwind_values(umo, Tr, Cupwind, G, nz) - do i = is, ie ; do j = js, je ; do k = 1, nz - east = 2 * (Tr%ad_x(i, j, k) / Tr_adv_scale) * Cupwind(i, j, k) - umo(i, j, k) * Cupwind(i, j, k)**2 - west = 2 * (Tr%ad_x(i-1, j, k) / Tr_adv_scale) * Cupwind(i-1, j, k) - umo(i-1, j, k) * Cupwind(i-1, j, k)**2 - nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - enddo ; enddo ; enddo + do k =1, nz + do j = js, je ; do i = is, ie + east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(i, j, k) - umo(I, j, k) * Cupwind(i, j, k)**2 + west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(i-1, j, k) - umo(I-1, j, k) * Cupwind(i-1, j, k)**2 + nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + enddo ; enddo + enddo end subroutine zonal_upwind_fluxes @@ -146,11 +148,13 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) call meridional_upwind_values(vmo, Tr, Cupwind, G, nz) - do i = is, ie ; do j = js, je ; do k = 1, nz - north = 2 * (Tr%ad_y(i, j, k) / Tr_adv_scale)* Cupwind(i, j, k) - vmo(i, j, k) * Cupwind(i, j, k)**2 - south = 2 * (Tr%ad_y(i, j-1, k) / Tr_adv_scale)* Cupwind(i, j-1, k) - vmo(i, j-1, k) * Cupwind(i, j-1, k)**2 - nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) - enddo ; enddo ; enddo + do k = 1, nz + do i = is, ie ; do j = js, je + north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale)* Cupwind(i, j, k) - vmo(i, J, k) * Cupwind(i, j, k)**2 + south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale)* Cupwind(i, j-1, k) - vmo(i, J-1, k) * Cupwind(i, J-1, k)**2 + nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) + enddo ; enddo + enddo end subroutine meridional_upwind_fluxes From 4d285e8b9ee6c0858c6bfcc2efa6ec2a38395bfa Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 15 Oct 2025 13:18:13 +1100 Subject: [PATCH 026/288] Try upwind indexing from zero and different upwind indexing --- src/diagnostics/MOM_numerical_mixing.F90 | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 69e88542f8..60eb084e97 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -40,7 +40,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_consta ! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) - call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) +! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) end subroutine numerical_mixing @@ -86,7 +86,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters - real :: Cupwind(G%iec, G%jec, nz) !< Empty variable for the upwind values of C + real :: Cupwind(0:G%iec, G%jec, nz) !< Empty variable for the upwind values of C real :: east, west !< East and West positions for zonal derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -95,8 +95,8 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) do k =1, nz do j = js, je ; do i = is, ie - east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(i, j, k) - umo(I, j, k) * Cupwind(i, j, k)**2 - west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(i-1, j, k) - umo(I-1, j, k) * Cupwind(i-1, j, k)**2 + east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - umo(I, j, k) * Cupwind(I, j, k)**2 + west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - umo(I-1, j, k) * Cupwind(I-1, j, k)**2 nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo enddo @@ -118,13 +118,15 @@ subroutine zonal_upwind_values(u, Tr, Cupwind, G, nz) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - do i = is, ie ; do j = js, je ; do k = 1, nz - if (u(i, j, k) >= 0) then - Cupwind(i, j, k) = Tr%t(i, j, k) - elseif (u(i, j, k) < 0) then - Cupwind(i, j, k) = Tr%t(i+1, j, k) - endif - enddo ; enddo ; enddo + do k = 1, nz + do j = js, je ; do i = is, ie+1 + if (u(I-1, j, k) >= 0) then + Cupwind(I-1, j, k) = Tr%t(i-1, j, k) + elseif (u(I-1, j, k) < 0) then + Cupwind(I-1, j, k) = Tr%t(i, j, k) + endif + enddo ; enddo + enddo end subroutine zonal_upwind_values From 4de218602fc0f4243b015511dab9ef2515c66de8 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 15 Oct 2025 13:51:33 +1100 Subject: [PATCH 027/288] Reorder the loop in thickness weighted variance --- src/diagnostics/MOM_numerical_mixing.F90 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 60eb084e97..e58259b4eb 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -63,13 +63,15 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - do i = is, ie ; do j = js, je ; do k = 1, nz - h1 = h(i, j, k) - hadv = h1 + dt * h_tendency(i, j, k) - C1 = Tr%t(i, j, k) - Cadv = h1 * C1 + dt * Tr%advection_xy(i, j, k) / Tr_adv_scale - nm(i, j, k) = (Cadv**2 / hadv - h1 * C1**2) / dt - enddo ; enddo ; enddo + do k = 1, nz + do j = js, je ; do i = is, ie + h1 = h(i, j, k) + hadv = h1 + dt * h_tendency(i, j, k) + C1 = Tr%t(i, j, k) + Cadv = h1 * C1 + dt * Tr%advection_xy(i, j, k) / Tr_adv_scale + nm(i, j, k) = (Cadv**2 / hadv - h1 * C1**2) / dt + enddo ; enddo + enddo end subroutine thickness_weighted_variance_change From 02f43f7042760173d85c80810b8acea318b4ddb8 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 15 Oct 2025 13:57:18 +1100 Subject: [PATCH 028/288] Change meridional flux to match new zonal version only --- src/diagnostics/MOM_numerical_mixing.F90 | 38 +++++++++++++----------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index e58259b4eb..63ea5fa8f1 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -39,8 +39,8 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_consta vmo = vmo / rho_ref !< units: m³s⁻¹ ! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) - call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) -! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) +! call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) + call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) end subroutine numerical_mixing @@ -86,10 +86,10 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) integer, intent(in) :: nz !< Grid cell layer indexes real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters real :: Cupwind(0:G%iec, G%jec, nz) !< Empty variable for the upwind values of C - real :: east, west !< East and West positions for zonal derivative + real :: east, west !< East and West positions for zonal derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -143,10 +143,10 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) integer, intent(in) :: nz !< Grid cell layer indexes real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - real :: Cupwind(G%iec, G%jec, nz) !< Empty variable for the meridional upwind tracer values - real :: north, south !< North and South positions for meridional derivative + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + real :: Cupwind(G%iec, 0:G%jec, nz) !< Empty variable for the meridional upwind tracer values + real :: north, south !< North and South positions for meridional derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -154,8 +154,8 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) do k = 1, nz do i = is, ie ; do j = js, je - north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale)* Cupwind(i, j, k) - vmo(i, J, k) * Cupwind(i, j, k)**2 - south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale)* Cupwind(i, j-1, k) - vmo(i, J-1, k) * Cupwind(i, J-1, k)**2 + north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale)* Cupwind(i, J, k) - vmo(i, J, k) * Cupwind(i, J, k)**2 + south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale)* Cupwind(i, J-1, k) - vmo(i, J-1, k) * Cupwind(i, J-1, k)**2 nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) enddo ; enddo enddo @@ -176,13 +176,15 @@ subroutine meridional_upwind_values(v, Tr, Cupwind, G, nz) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - do i = is, ie ; do j = js, js ; do k = 1, nz - if (v(i, j, k) >= 0) then - Cupwind(i, j, k) = Tr%t(i, j, k) - elseif (v(i, j, k) < 0) then - Cupwind(i, j, k) = Tr%t(i, j+1, k) - endif - enddo ; enddo ; enddo + do k = 1, nz + do i = is, ie ; do j = js, js+1 + if (v(i, J-1, k) >= 0) then + Cupwind(i, J-1, k) = Tr%t(i, j-1, k) + elseif (v(i, J-1, k) < 0) then + Cupwind(i, J-1, k) = Tr%t(i, j, k) + endif + enddo ; enddo + enddo end subroutine meridional_upwind_values From e3a0c2d13de3e47cf5c13073158dd7357d68575f Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 15 Oct 2025 14:59:26 +1100 Subject: [PATCH 029/288] Change loop order for mupvals + local variable comments --- src/diagnostics/MOM_numerical_mixing.F90 | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 63ea5fa8f1..ee6701cd95 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -28,6 +28,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_consta real, intent(in) :: rho_ref !< Reference density real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic + !< Local variables integer :: nz !< Grid cell layer indexes real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct ! e.g. for temperature need to divide by specific heat capacity * rho_ref @@ -57,6 +58,7 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d integer, intent(in) :: nz !< Grid cell layer indexes real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters real :: h1, C1, hadv, Cadv !< Temporary grid cell variables @@ -86,6 +88,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) integer, intent(in) :: nz !< Grid cell layer indexes real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters real :: Cupwind(0:G%iec, G%jec, nz) !< Empty variable for the upwind values of C @@ -99,7 +102,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) do j = js, je ; do i = is, ie east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - umo(I, j, k) * Cupwind(I, j, k)**2 west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - umo(I-1, j, k) * Cupwind(I-1, j, k)**2 - nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo enddo @@ -115,6 +118,7 @@ subroutine zonal_upwind_values(u, Tr, Cupwind, G, nz) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area integer, intent(in) :: nz !< Grid cell layer indexes + !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters @@ -143,17 +147,18 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) integer, intent(in) :: nz !< Grid cell layer indexes real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters real :: Cupwind(G%iec, 0:G%jec, nz) !< Empty variable for the meridional upwind tracer values real :: north, south !< North and South positions for meridional derivative - + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec call meridional_upwind_values(vmo, Tr, Cupwind, G, nz) do k = 1, nz - do i = is, ie ; do j = js, je + do j = js, je ; do i = is, ie north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale)* Cupwind(i, J, k) - vmo(i, J, k) * Cupwind(i, J, k)**2 south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale)* Cupwind(i, J-1, k) - vmo(i, J-1, k) * Cupwind(i, J-1, k)**2 nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) @@ -171,13 +176,14 @@ subroutine meridional_upwind_values(v, Tr, Cupwind, G, nz) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area integer, intent(in) :: nz !< Grid cell layer indexes + !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do k = 1, nz - do i = is, ie ; do j = js, js+1 + do j = js, je+1 ; do i = is, ie if (v(i, J-1, k) >= 0) then Cupwind(i, J-1, k) = Tr%t(i, j-1, k) elseif (v(i, J-1, k) < 0) then From d5b5e81c6183d33523b1b748530fee5e1ffd4a29 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 16 Oct 2025 09:00:50 +1100 Subject: [PATCH 030/288] All nm terms for a check with updated indexing --- src/diagnostics/MOM_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index ee6701cd95..099fab4df0 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -39,8 +39,8 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_consta umo = umo / rho_ref !< units: m³s⁻¹ vmo = vmo / rho_ref !< units: m³s⁻¹ -! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) -! call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) + call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) + call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) end subroutine numerical_mixing From 36d4318076a4507837bdcc9c68b568e70d060248 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 16 Oct 2025 09:27:17 +1100 Subject: [PATCH 031/288] Only thickness weighted variance change --- src/diagnostics/MOM_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 099fab4df0..5047526193 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -40,8 +40,8 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_consta vmo = vmo / rho_ref !< units: m³s⁻¹ call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) - call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) - call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) +! call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) +! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) end subroutine numerical_mixing From 7a00def55bdfa8046d8ce59d1369e0138ecf4ec4 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 16 Oct 2025 09:33:02 +1100 Subject: [PATCH 032/288] Only fluxes --- src/diagnostics/MOM_numerical_mixing.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 5047526193..bc30fcbc93 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -39,9 +39,9 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_consta umo = umo / rho_ref !< units: m³s⁻¹ vmo = vmo / rho_ref !< units: m³s⁻¹ - call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) -! call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) -! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) +! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) + call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) + call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) end subroutine numerical_mixing From 3704577b74c579081ac41ef9e41dae9faf435e0b Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 10:48:36 +1100 Subject: [PATCH 033/288] Alternate Cupwind local def + alt indexing --- src/diagnostics/MOM_numerical_mixing.F90 | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index bc30fcbc93..99936f1588 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -41,7 +41,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_consta ! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) - call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) + ! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) end subroutine numerical_mixing @@ -89,10 +89,10 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - real :: Cupwind(0:G%iec, G%jec, nz) !< Empty variable for the upwind values of C - real :: east, west !< East and West positions for zonal derivative + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: Cupwind !< Empty variable for the upwind values of C + real :: east, west !< East and West positions for zonal derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -125,11 +125,11 @@ subroutine zonal_upwind_values(u, Tr, Cupwind, G, nz) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do k = 1, nz - do j = js, je ; do i = is, ie+1 - if (u(I-1, j, k) >= 0) then - Cupwind(I-1, j, k) = Tr%t(i-1, j, k) - elseif (u(I-1, j, k) < 0) then - Cupwind(I-1, j, k) = Tr%t(i, j, k) + do j = js, je ; do I = is-1, ie + if (u(I, j, k) >= 0) then + Cupwind(I, j, k) = Tr%t(i, j, k) + elseif (u(I, j, k) < 0) then + Cupwind(I, j, k) = Tr%t(i+1, j, k) endif enddo ; enddo enddo From 09e6e993ab752a9837838948a0b4b1f2bbacd576 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 11:00:03 +1100 Subject: [PATCH 034/288] Cupwind def did not work --- src/diagnostics/MOM_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 99936f1588..8224cfe5dd 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -89,10 +89,10 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: Cupwind !< Empty variable for the upwind values of C - real :: east, west !< East and West positions for zonal derivative + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + real :: Cupwind(SZIB_(G),SZJ_(G),SZK_(GV)) !< Empty variable for the upwind values of C + real :: east, west !< East and West positions for zonal derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec From fd04d406b82562d46cb0c1f9d1a76070d9af27b0 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 11:07:08 +1100 Subject: [PATCH 035/288] Still error in upwind de --- src/diagnostics/MOM_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 8224cfe5dd..8ce2d03b1c 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -89,10 +89,10 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - real :: Cupwind(SZIB_(G),SZJ_(G),SZK_(GV)) !< Empty variable for the upwind values of C - real :: east, west !< East and West positions for zonal derivative + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + real :: Cupwind(SZIB_(G),SZJ_(G),nz) !< Empty variable for the upwind values of C + real :: east, west !< East and West positions for zonal derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec From 9fedea048c18a94732d64c6c3b5d4132469e0320 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 11:13:43 +1100 Subject: [PATCH 036/288] Back to initial method.. --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 8ce2d03b1c..43f523f0bc 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -91,7 +91,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters - real :: Cupwind(SZIB_(G),SZJ_(G),nz) !< Empty variable for the upwind values of C + real :: Cupwind(G%IscB:G%IecB,G%jec,nz) !< Empty variable for the upwind values of C real :: east, west !< East and West positions for zonal derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec From 2b574936c67c8b08fe2670c4bdacfce1648f2bc4 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 11:23:53 +1100 Subject: [PATCH 037/288] Try using tracer units in nm register --- src/tracer/MOM_tracer_registry.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index a90e36bd88..07fa28e9a5 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -383,7 +383,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u v_extensive=.true., & x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", "[C]^2ms-1") + diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -410,7 +410,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u flux_units, v_extensive=.true., conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T, & x_cell_method='sum') Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", "[C]^2ms-1") + diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"[C]^2ms-1") endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & From 55b0c2172f21c18a48f1152df22ec9fbf745abf0 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 13:34:34 +1100 Subject: [PATCH 038/288] Import MOM_memory.h to follow variable setting convention --- src/diagnostics/MOM_numerical_mixing.F90 | 95 ++++++++++++------------ 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 43f523f0bc..311f2d642c 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -8,6 +8,8 @@ module MOM_numerical_mixing implicit none ; private +#include + public numerical_mixing contains @@ -18,7 +20,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_consta implicit none type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Tracer + type(tracer_type), intent(in) :: Tr !< Tracer real, intent(in) :: h(:, :, :) !< Thickness real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency real, intent(in) :: dt !< Model timestep @@ -29,19 +31,17 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_consta real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic !< Local variables - integer :: nz !< Grid cell layer indexes real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct ! e.g. for temperature need to divide by specific heat capacity * rho_ref - nz = GV%ke Tr_adv_scale = scale_constant * rho_ref !< adjust for correct dimensions umo = umo / rho_ref !< units: m³s⁻¹ vmo = vmo / rho_ref !< units: m³s⁻¹ -! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) - call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) - ! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) +! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, GV, nm) + call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, GV, nm) + ! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, GV, nm) end subroutine numerical_mixing @@ -49,21 +49,22 @@ end subroutine numerical_mixing subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: h(:, :, :) !< Thickness - real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency - real, intent(in) :: dt !< Model timestep - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: h(:, :, :) !< Thickness + real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency + real, intent(in) :: dt !< Model timestep + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - real :: h1, C1, hadv, Cadv !< Temporary grid cell variables + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: h1, C1, hadv, Cadv !< Temporary variables for thickness and tracer at current timestep + !< and the changes in thickness and tracer due to advection. - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec, nz = GV%ke do k = 1, nz do j = js, je ; do i = is, ie @@ -78,23 +79,23 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) +subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, GV, nm) implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: umo(:, :, :) !< Zonal mass transport - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: umo(:, :, :) !< Zonal mass transport + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - real :: Cupwind(G%IscB:G%IecB,G%jec,nz) !< Empty variable for the upwind values of C - real :: east, west !< East and West positions for zonal derivative + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: Cupwind !< Empty variable for the upwind values of C + real :: east, west !< East and West positions for zonal derivative - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec, nz = GV%ke call zonal_upwind_values(umo, Tr, Cupwind, G, nz) @@ -109,14 +110,14 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, nz, nm) end subroutine zonal_upwind_fluxes !< Subroutine to calculate upwind values in zonal direction -subroutine zonal_upwind_values(u, Tr, Cupwind, G, nz) +subroutine zonal_upwind_values(u, Tr, G, nz, Cupwind) implicit none - real, intent(in) :: u(:, :, :) !< Zonal transport - type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: u(:, :, :) !< Zonal transport + type(tracer_type), intent(in) :: Tr !< Tracer + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes real, intent(inout) :: Cupwind(:, :, :) !< Zonal upwind values of C calculated using v - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes @@ -137,23 +138,23 @@ subroutine zonal_upwind_values(u, Tr, Cupwind, G, nz) end subroutine zonal_upwind_values !< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, nz, nm) +subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, GV, nm) implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: vmo(:, :, :) !< Meridional mass transport - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: vmo(:, :, :) !< Meridional mass transport + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - real :: Cupwind(G%iec, 0:G%jec, nz) !< Empty variable for the meridional upwind tracer values - real :: north, south !< North and South positions for meridional derivative + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)):: Cupwind !< Empty variable for the meridional upwind tracer values + real :: north, south !< North and South positions for meridional derivative - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec, nz = GV%ke call meridional_upwind_values(vmo, Tr, Cupwind, G, nz) From 010e266fcfd880a5382896454a2a7bd8381532ed Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 13:39:36 +1100 Subject: [PATCH 039/288] Code cleanup --- src/diagnostics/MOM_numerical_mixing.F90 | 38 ++++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 311f2d642c..ffb71a2088 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -18,17 +18,17 @@ module MOM_numerical_mixing subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_constant, rho_ref, nm) implicit none - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: h(:, :, :) !< Thickness - real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency - real, intent(in) :: dt !< Model timestep - real, intent(inout) :: umo(:, :, :) !< Total zonal mass transport - real, intent(inout) :: vmo(:, :, :) !< Total meridional mass transport - real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(in) :: rho_ref !< Reference density - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: h(:, :, :) !< Thickness + real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency + real, intent(in) :: dt !< Model timestep + real, intent(inout) :: umo(:, :, :) !< Total zonal mass transport + real, intent(inout) :: vmo(:, :, :) !< Total meridional mass transport + real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T + real, intent(in) :: rho_ref !< Reference density + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic !< Local variables real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct @@ -46,7 +46,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_consta end subroutine numerical_mixing !< Subroutine to calculate the thickness weighted variance change over a timestep -subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, nz, nm) +subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, GV, nm) implicit none type(tracer_type), intent(in) :: Tr !< Tracer @@ -151,7 +151,7 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, GV, nm) !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)):: Cupwind !< Empty variable for the meridional upwind tracer values + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: Cupwind !< Empty variable for the meridional upwind tracer values real :: north, south !< North and South positions for meridional derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec, nz = GV%ke @@ -168,14 +168,14 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, GV, nm) end subroutine meridional_upwind_fluxes -subroutine meridional_upwind_values(v, Tr, Cupwind, G, nz) +subroutine meridional_upwind_values(v, Tr, G, nz, Cupwind) implicit none - real, intent(in) :: v(:, :, :) !< Meridional transport - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(inout) :: Cupwind(:, :, :) !< Meridional upwind values of C calculated using v - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(in) :: v(:, :, :) !< Meridional transport + type(tracer_type), intent(in) :: Tr !< Tracer + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(inout) :: Cupwind(:, :, :) !< Meridional upwind values of C calculated using v !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes From 5bf3c2d71c9241175343c20dfadac35546dd475b Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 13:44:16 +1100 Subject: [PATCH 040/288] Semicolons not commas, correct order for subroutine call --- src/diagnostics/MOM_numerical_mixing.F90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index ffb71a2088..6cc87e7ab2 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -64,7 +64,7 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d real :: h1, C1, hadv, Cadv !< Temporary variables for thickness and tracer at current timestep !< and the changes in thickness and tracer due to advection. - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec, nz = GV%ke + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke do k = 1, nz do j = js, je ; do i = is, ie @@ -95,9 +95,9 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, GV, nm) real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: Cupwind !< Empty variable for the upwind values of C real :: east, west !< East and West positions for zonal derivative - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec, nz = GV%ke + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call zonal_upwind_values(umo, Tr, Cupwind, G, nz) + call zonal_upwind_values(umo, Tr, G, nz, Cupwind) do k =1, nz do j = js, je ; do i = is, ie @@ -154,9 +154,9 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, GV, nm) real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: Cupwind !< Empty variable for the meridional upwind tracer values real :: north, south !< North and South positions for meridional derivative - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec, nz = GV%ke + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call meridional_upwind_values(vmo, Tr, Cupwind, G, nz) + call meridional_upwind_values(vmo, Tr, G, nz, Cupwind) do k = 1, nz do j = js, je ; do i = is, ie From 361d933c9b949f51d6d1872282d1920510cba6ac Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 14:33:18 +1100 Subject: [PATCH 041/288] Use uhtr*Idt insteatd of umo/rho0 (same for v) --- src/diagnostics/MOM_diagnostics.F90 | 6 +- src/diagnostics/MOM_numerical_mixing.F90 | 116 +++++++++++------------ 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 1ae7e24871..a61baae16a 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1714,10 +1714,10 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy Tr => Reg%Tr(m) ! Compute and post the numerical mixing if required if (Tr%id_numerical_mixing > 0) then - scale_constant = 3991.86795711963 - rho_ref = 1035.0 + scale_constant = 3991.86795711963 !< hard coded (for now) specific heat capacity + !rho_ref = 1035.0 nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, umo, vmo, scale_constant, rho_ref, nm) + call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, Idt, uhtr, vhtr, scale_constant, nm) call post_data(Tr%id_numerical_mixing, nm, diag) endif endif; enddo diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 6cc87e7ab2..159780ceb2 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -15,38 +15,35 @@ module MOM_numerical_mixing contains !< Calculate the suprious ``numerical'' mixing of tracer C due to advection. -subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, umo, vmo, scale_constant, rho_ref, nm) +subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale_constant, nm) implicit none - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: h(:, :, :) !< Thickness - real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency - real, intent(in) :: dt !< Model timestep - real, intent(inout) :: umo(:, :, :) !< Total zonal mass transport - real, intent(inout) :: vmo(:, :, :) !< Total meridional mass transport - real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(in) :: rho_ref !< Reference density - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: h(:, :, :) !< Thickness + real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency + real, intent(in) :: dt !< Model timestep + real, intent(in) :: Idt !< Inverse model timestep + real, intent(in) :: uhtr(:, :, :) !< Total zonal mass transport + real, intent(in) :: vhtr(:, :, :) !< Total meridional mass transport + real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic !< Local variables real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct ! e.g. for temperature need to divide by specific heat capacity * rho_ref Tr_adv_scale = scale_constant * rho_ref - !< adjust for correct dimensions - umo = umo / rho_ref !< units: m³s⁻¹ - vmo = vmo / rho_ref !< units: m³s⁻¹ -! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, GV, nm) - call zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, GV, nm) - ! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, GV, nm) + call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) + call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) + call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, nm) end subroutine numerical_mixing !< Subroutine to calculate the thickness weighted variance change over a timestep -subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, G, GV, nm) +subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) implicit none type(tracer_type), intent(in) :: Tr !< Tracer @@ -54,15 +51,16 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d real, intent(in) :: h(:, :, :) !< Thickness real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency real, intent(in) :: dt !< Model timestep + real, intent(in) :: Idt !< Inverse model timestep type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: h1, C1, hadv, Cadv !< Temporary variables for thickness and tracer at current timestep - !< and the changes in thickness and tracer due to advection. + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: h1, C1, hadv, Cadv !< Temporary variables for thickness and tracer at current timestep + !< and the changes in thickness and tracer due to advection. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke @@ -72,22 +70,23 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d hadv = h1 + dt * h_tendency(i, j, k) C1 = Tr%t(i, j, k) Cadv = h1 * C1 + dt * Tr%advection_xy(i, j, k) / Tr_adv_scale - nm(i, j, k) = (Cadv**2 / hadv - h1 * C1**2) / dt + nm(i, j, k) = (Cadv**2 / hadv - h1 * C1**2) * Idt enddo ; enddo enddo end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, GV, nm) +subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: umo(:, :, :) !< Zonal mass transport - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal fluxes + real, intent(in) :: Idt !< Inverse model timestep + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -97,12 +96,12 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, GV, nm) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call zonal_upwind_values(umo, Tr, G, nz, Cupwind) + call zonal_upwind_values(uhtr, Tr, G, nz, Cupwind) do k =1, nz do j = js, je ; do i = is, ie - east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - umo(I, j, k) * Cupwind(I, j, k)**2 - west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - umo(I-1, j, k) * Cupwind(I-1, j, k)**2 + east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - (uhtr(I, j, k) * Idt) * Cupwind(I, j, k)**2 + west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - (uhtr(I-1, j, k) * Idt) * Cupwind(I-1, j, k)**2 nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo enddo @@ -110,14 +109,14 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, umo, G, GV, nm) end subroutine zonal_upwind_fluxes !< Subroutine to calculate upwind values in zonal direction -subroutine zonal_upwind_values(u, Tr, G, nz, Cupwind) +subroutine zonal_upwind_values(uhtr, Tr, G, nz, Cupwind) implicit none - real, intent(in) :: u(:, :, :) !< Zonal transport + real, intent(in) :: uhtr(:, :, :) !< Accumulates zonal transport type(tracer_type), intent(in) :: Tr !< Tracer type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: Cupwind(:, :, :) !< Zonal upwind values of C calculated using v + real, intent(inout) :: Cupwind(:, :, :) !< Zonal upwind values of C calculated using uhtr !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes @@ -127,9 +126,9 @@ subroutine zonal_upwind_values(u, Tr, G, nz, Cupwind) do k = 1, nz do j = js, je ; do I = is-1, ie - if (u(I, j, k) >= 0) then + if (uhtr(I, j, k) >= 0) then Cupwind(I, j, k) = Tr%t(i, j, k) - elseif (u(I, j, k) < 0) then + elseif (uhtr(I, j, k) < 0) then Cupwind(I, j, k) = Tr%t(i+1, j, k) endif enddo ; enddo @@ -138,44 +137,45 @@ subroutine zonal_upwind_values(u, Tr, G, nz, Cupwind) end subroutine zonal_upwind_values !< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vmo, G, GV, nm) +subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, nm) implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: vmo(:, :, :) !< Meridional mass transport - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: vhtr(:, :, :) !< Meridional mass transport + real, intent(in) :: Idt !< Inverse model timestep + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: Cupwind !< Empty variable for the meridional upwind tracer values - real :: north, south !< North and South positions for meridional derivative + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: Cupwind !< Empty variable for the meridional upwind tracer values + real :: north, south !< North and South positions for meridional derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call meridional_upwind_values(vmo, Tr, G, nz, Cupwind) + call meridional_upwind_values(vhtr, Tr, G, nz, Cupwind) do k = 1, nz do j = js, je ; do i = is, ie - north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale)* Cupwind(i, J, k) - vmo(i, J, k) * Cupwind(i, J, k)**2 - south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale)* Cupwind(i, J-1, k) - vmo(i, J-1, k) * Cupwind(i, J-1, k)**2 + north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * Cupwind(i, J, k) - (vhtr(i, J, k) * Idt) * Cupwind(i, J, k)**2 + south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * Cupwind(i, J-1, k) - (vhtr(i, J-1, k) * Idt) * Cupwind(i, J-1, k)**2 nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) enddo ; enddo enddo end subroutine meridional_upwind_fluxes -subroutine meridional_upwind_values(v, Tr, G, nz, Cupwind) +subroutine meridional_upwind_values(vhtr, Tr, G, nz, Cupwind) implicit none - real, intent(in) :: v(:, :, :) !< Meridional transport + real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport type(tracer_type), intent(in) :: Tr !< Tracer type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: Cupwind(:, :, :) !< Meridional upwind values of C calculated using v + real, intent(inout) :: Cupwind(:, :, :) !< Meridional upwind values of C calculated using vhtr !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes @@ -185,9 +185,9 @@ subroutine meridional_upwind_values(v, Tr, G, nz, Cupwind) do k = 1, nz do j = js, je+1 ; do i = is, ie - if (v(i, J-1, k) >= 0) then + if (vhtr(i, J-1, k) >= 0) then Cupwind(i, J-1, k) = Tr%t(i, j-1, k) - elseif (v(i, J-1, k) < 0) then + elseif (vhtr(i, J-1, k) < 0) then Cupwind(i, J-1, k) = Tr%t(i, j, k) endif enddo ; enddo From 7d80f8b92867957a4c6f3dcd39cdf5bbd18e0c8f Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 14:35:25 +1100 Subject: [PATCH 042/288] Missed reference density --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 159780ceb2..eaed118798 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -33,7 +33,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale !< Local variables real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct ! e.g. for temperature need to divide by specific heat capacity * rho_ref - Tr_adv_scale = scale_constant * rho_ref + Tr_adv_scale = scale_constant * GV%Rho0 call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) From 19c8b336c87c35ba65c2efc4729a07be618e06f7 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 14:44:49 +1100 Subject: [PATCH 043/288] Hard code reference density (might have caused the netcdf error) --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index eaed118798..47855d48d9 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -33,7 +33,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale !< Local variables real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct ! e.g. for temperature need to divide by specific heat capacity * rho_ref - Tr_adv_scale = scale_constant * GV%Rho0 + Tr_adv_scale = scale_constant * 1035 call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) From 6c3b60b0cfb69ead0cec5ef4f4a25ff27ed34f32 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 14:55:23 +1100 Subject: [PATCH 044/288] Try thickness weighted variance only (netcdf error occured again maybe uhtr not good choice) --- src/diagnostics/MOM_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 47855d48d9..f2c6e62509 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -37,8 +37,8 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) - call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) - call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, nm) +! call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) +! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, nm) end subroutine numerical_mixing From 30aefa678bca6d85519e77e130778e204511a6fb Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 15:02:06 +1100 Subject: [PATCH 045/288] Use reference density from GV --- src/diagnostics/MOM_numerical_mixing.F90 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index f2c6e62509..55c6bb777f 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -33,8 +33,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale !< Local variables real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct ! e.g. for temperature need to divide by specific heat capacity * rho_ref - Tr_adv_scale = scale_constant * 1035 - + Tr_adv_scale = scale_constant * GV%Rho0 call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) ! call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) From 0be62ab6c3e04e12d923cf1933a001e4126580d5 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 15:07:56 +1100 Subject: [PATCH 046/288] Remove old unit designator --- src/tracer/MOM_tracer_registry.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 07fa28e9a5..c1d8077312 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -410,7 +410,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u flux_units, v_extensive=.true., conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T, & x_cell_method='sum') Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"[C]^2ms-1") + diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & From e2dcc9d9682ed472ea53d564412037d831a325c1 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 15:31:20 +1100 Subject: [PATCH 047/288] Remove unnecessary definition of reference density --- src/diagnostics/MOM_diagnostics.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index a61baae16a..1da1ddaa4c 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1715,7 +1715,6 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy ! Compute and post the numerical mixing if required if (Tr%id_numerical_mixing > 0) then scale_constant = 3991.86795711963 !< hard coded (for now) specific heat capacity - !rho_ref = 1035.0 nm(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, Idt, uhtr, vhtr, scale_constant, nm) call post_data(Tr%id_numerical_mixing, nm, diag) From bb846a0fe132d23b3891261af7b1a5b6cba90113 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 15:58:43 +1100 Subject: [PATCH 048/288] Only zonal fluxes + try scaling the upwind calculation --- src/diagnostics/MOM_numerical_mixing.F90 | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 55c6bb777f..f009af38df 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -35,8 +35,8 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale ! e.g. for temperature need to divide by specific heat capacity * rho_ref Tr_adv_scale = scale_constant * GV%Rho0 - call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) -! call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) +! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) + call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) ! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, nm) end subroutine numerical_mixing @@ -95,7 +95,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call zonal_upwind_values(uhtr, Tr, G, nz, Cupwind) + call zonal_upwind_values(uhtr, Idt, Tr, G, nz, Cupwind) do k =1, nz do j = js, je ; do i = is, ie @@ -108,10 +108,11 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) end subroutine zonal_upwind_fluxes !< Subroutine to calculate upwind values in zonal direction -subroutine zonal_upwind_values(uhtr, Tr, G, nz, Cupwind) +subroutine zonal_upwind_values(uhtr, Idt, Tr, G, nz, Cupwind) implicit none real, intent(in) :: uhtr(:, :, :) !< Accumulates zonal transport + real, intent(in) :: Idt !< Inverse model timestep type(tracer_type), intent(in) :: Tr !< Tracer type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area integer, intent(in) :: nz !< Grid cell layer indexes @@ -125,9 +126,9 @@ subroutine zonal_upwind_values(uhtr, Tr, G, nz, Cupwind) do k = 1, nz do j = js, je ; do I = is-1, ie - if (uhtr(I, j, k) >= 0) then + if (uhtr(I, j, k)*Idt >= 0) then Cupwind(I, j, k) = Tr%t(i, j, k) - elseif (uhtr(I, j, k) < 0) then + elseif (uhtr(I, j, k)*Idt < 0) then Cupwind(I, j, k) = Tr%t(i+1, j, k) endif enddo ; enddo From b411d30d2e76c65f8f52f44fda3ac7baa4b04842 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 16:17:23 +1100 Subject: [PATCH 049/288] Use locally defined and - would be ideal if I could find where they are --- src/diagnostics/MOM_numerical_mixing.F90 | 38 +++++++++++++----------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index f009af38df..befc86b818 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -25,8 +25,8 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency real, intent(in) :: dt !< Model timestep real, intent(in) :: Idt !< Inverse model timestep - real, intent(in) :: uhtr(:, :, :) !< Total zonal mass transport - real, intent(in) :: vhtr(:, :, :) !< Total meridional mass transport + real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport + real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic @@ -90,17 +90,20 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: uh !< Zonal thickness transport real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: Cupwind !< Empty variable for the upwind values of C real :: east, west !< East and West positions for zonal derivative + uh = uhtr * ((GV%H_to_RZ * Idt) / GV%Rho0) + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call zonal_upwind_values(uhtr, Idt, Tr, G, nz, Cupwind) + call zonal_upwind_values(uh, Tr, G, nz, Cupwind) do k =1, nz do j = js, je ; do i = is, ie - east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - (uhtr(I, j, k) * Idt) * Cupwind(I, j, k)**2 - west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - (uhtr(I-1, j, k) * Idt) * Cupwind(I-1, j, k)**2 + east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 + west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo enddo @@ -108,11 +111,10 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) end subroutine zonal_upwind_fluxes !< Subroutine to calculate upwind values in zonal direction -subroutine zonal_upwind_values(uhtr, Idt, Tr, G, nz, Cupwind) +subroutine zonal_upwind_values(uh, Tr, G, nz, Cupwind) implicit none - real, intent(in) :: uhtr(:, :, :) !< Accumulates zonal transport - real, intent(in) :: Idt !< Inverse model timestep + real, intent(in) :: uh(:, :, :) !< Zonal thickness transport type(tracer_type), intent(in) :: Tr !< Tracer type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area integer, intent(in) :: nz !< Grid cell layer indexes @@ -126,9 +128,9 @@ subroutine zonal_upwind_values(uhtr, Idt, Tr, G, nz, Cupwind) do k = 1, nz do j = js, je ; do I = is-1, ie - if (uhtr(I, j, k)*Idt >= 0) then + if (uh(I, j, k) >= 0) then Cupwind(I, j, k) = Tr%t(i, j, k) - elseif (uhtr(I, j, k)*Idt < 0) then + elseif (uh(I, j, k) < 0) then Cupwind(I, j, k) = Tr%t(i+1, j, k) endif enddo ; enddo @@ -151,27 +153,29 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, nm) !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vh !< Meridional thickness transport real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: Cupwind !< Empty variable for the meridional upwind tracer values real :: north, south !< North and South positions for meridional derivative + vh = vhtr * ((GV%H_to_RZ * Idt) / GV%Rho0) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call meridional_upwind_values(vhtr, Tr, G, nz, Cupwind) + call meridional_upwind_values(vh, Tr, G, nz, Cupwind) do k = 1, nz do j = js, je ; do i = is, ie - north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * Cupwind(i, J, k) - (vhtr(i, J, k) * Idt) * Cupwind(i, J, k)**2 - south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * Cupwind(i, J-1, k) - (vhtr(i, J-1, k) * Idt) * Cupwind(i, J-1, k)**2 + north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * Cupwind(i, J, k) - vh(i, J, k) * Cupwind(i, J, k)**2 + south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * Cupwind(i, J-1, k) - vh(i, J-1, k) * Cupwind(i, J-1, k)**2 nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) enddo ; enddo enddo end subroutine meridional_upwind_fluxes -subroutine meridional_upwind_values(vhtr, Tr, G, nz, Cupwind) +subroutine meridional_upwind_values(vh, Tr, G, nz, Cupwind) implicit none - real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport + real, intent(in) :: vh(:, :, :) !< Meridional transport type(tracer_type), intent(in) :: Tr !< Tracer type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area integer, intent(in) :: nz !< Grid cell layer indexes @@ -185,9 +189,9 @@ subroutine meridional_upwind_values(vhtr, Tr, G, nz, Cupwind) do k = 1, nz do j = js, je+1 ; do i = is, ie - if (vhtr(i, J-1, k) >= 0) then + if (vh(i, J-1, k) >= 0) then Cupwind(i, J-1, k) = Tr%t(i, j-1, k) - elseif (vhtr(i, J-1, k) < 0) then + elseif (vh(i, J-1, k) < 0) then Cupwind(i, J-1, k) = Tr%t(i, j, k) endif enddo ; enddo From be865421fa52d194d403e6968684234304ef6ac1 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 21 Oct 2025 16:22:20 +1100 Subject: [PATCH 050/288] Set upwind variables to zero --- src/diagnostics/MOM_numerical_mixing.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index befc86b818..e28e2cd477 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -95,7 +95,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) real :: east, west !< East and West positions for zonal derivative uh = uhtr * ((GV%H_to_RZ * Idt) / GV%Rho0) - + Cupwind(:, :, :) = 0. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke call zonal_upwind_values(uh, Tr, G, nz, Cupwind) @@ -158,6 +158,7 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, nm) real :: north, south !< North and South positions for meridional derivative vh = vhtr * ((GV%H_to_RZ * Idt) / GV%Rho0) + Cupwind(:, :, :) = 0. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke call meridional_upwind_values(vh, Tr, G, nz, Cupwind) From 667dee8542755a3350432ed915425cba1e67b83c Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 10:14:03 +1100 Subject: [PATCH 051/288] Homogenise upwind value definition --- src/diagnostics/MOM_numerical_mixing.F90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index e28e2cd477..1e0d4afee3 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -189,11 +189,11 @@ subroutine meridional_upwind_values(vh, Tr, G, nz, Cupwind) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do k = 1, nz - do j = js, je+1 ; do i = is, ie - if (vh(i, J-1, k) >= 0) then - Cupwind(i, J-1, k) = Tr%t(i, j-1, k) - elseif (vh(i, J-1, k) < 0) then - Cupwind(i, J-1, k) = Tr%t(i, j, k) + do j = js-1, je ; do i = is, ie + if (vh(i, J, k) >= 0) then + Cupwind(i, J, k) = Tr%t(i, j, k) + elseif (vh(i, J, k) < 0) then + Cupwind(i, J, k) = Tr%t(i, j+1, k) endif enddo ; enddo enddo From d2930d3845a04cac3d1693d0059be1530e0a2270 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 10:33:20 +1100 Subject: [PATCH 052/288] More specific bracketing in thickness weighted variance change --- src/diagnostics/MOM_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 1e0d4afee3..aa8469545c 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -68,8 +68,8 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d h1 = h(i, j, k) hadv = h1 + dt * h_tendency(i, j, k) C1 = Tr%t(i, j, k) - Cadv = h1 * C1 + dt * Tr%advection_xy(i, j, k) / Tr_adv_scale - nm(i, j, k) = (Cadv**2 / hadv - h1 * C1**2) * Idt + Cadv = h1 * C1 + ( dt * Tr%advection_xy(i, j, k) ) / Tr_adv_scale + nm(i, j, k) = ( (Cadv**2 / hadv) - (h1 * C1**2) ) * Idt enddo ; enddo enddo From 53ef6c82c1eb6fa9d5336d1a665334ffaf9f6b44 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 10:39:43 +1100 Subject: [PATCH 053/288] Only return upwind difference --- src/diagnostics/MOM_numerical_mixing.F90 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index aa8469545c..f1129b33b3 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -102,9 +102,10 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) do k =1, nz do j = js, je ; do i = is, ie - east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 - west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 - nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 + ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 + ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + nm(i, j, k) = Cupwind(I, j, k) - Cupwind(I-1, j, k) enddo ; enddo enddo From 9722ba27dac6a8f597dd5a155436b569c1de5de5 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 11:10:31 +1100 Subject: [PATCH 054/288] Check non-upwind part of zonal fluxes calculation --- src/diagnostics/MOM_numerical_mixing.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index f1129b33b3..527e853397 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -98,14 +98,16 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) Cupwind(:, :, :) = 0. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call zonal_upwind_values(uh, Tr, G, nz, Cupwind) + ! call zonal_upwind_values(uh, Tr, G, nz, Cupwind) do k =1, nz do j = js, je ; do i = is, ie ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - nm(i, j, k) = Cupwind(I, j, k) - Cupwind(I-1, j, k) + east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) - uh(I, j, k) + west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) - uh(I-1, j, k) + nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo enddo From 2eeb3c93b2cf2adc42b1c51849d45f7ca70c98e2 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 11:49:03 +1100 Subject: [PATCH 055/288] Just look at left upwind i.e. the left tracer values --- src/diagnostics/MOM_numerical_mixing.F90 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 527e853397..f65250b8d9 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -98,16 +98,14 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) Cupwind(:, :, :) = 0. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - ! call zonal_upwind_values(uh, Tr, G, nz, Cupwind) + call zonal_upwind_values(uh, Tr, G, nz, Cupwind) do k =1, nz do j = js, je ; do i = is, ie ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) - uh(I, j, k) - west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) - uh(I-1, j, k) - nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + nm(i, j, k) = Cupwind(I, j, k) !- Cupwind(I-1, j, k) enddo ; enddo enddo From d2aa63f355c0265a597f334562c253983694b7f7 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 12:05:17 +1100 Subject: [PATCH 056/288] west upwind values --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index f65250b8d9..790b83cef7 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -105,7 +105,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - nm(i, j, k) = Cupwind(I, j, k) !- Cupwind(I-1, j, k) + nm(i, j, k) = Cupwind(I-1, j, k) enddo ; enddo enddo From c1ae7b0a2734b144fe78e6774961a3393cdcb5b5 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 13:27:27 +1100 Subject: [PATCH 057/288] Back to east upwind values --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 790b83cef7..374ae39a0b 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -105,7 +105,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - nm(i, j, k) = Cupwind(I-1, j, k) + nm(i, j, k) = Cupwind(I, j, k) enddo ; enddo enddo From 0e73593ae155b23d67d4f43b7c10ab7e27cc84d9 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 13:40:39 +1100 Subject: [PATCH 058/288] Return the upwind array --- src/diagnostics/MOM_numerical_mixing.F90 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 374ae39a0b..a49bd3d7a2 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -100,14 +100,14 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) call zonal_upwind_values(uh, Tr, G, nz, Cupwind) - do k =1, nz - do j = js, je ; do i = is, ie - ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 - ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 - ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - nm(i, j, k) = Cupwind(I, j, k) - enddo ; enddo - enddo + nm = Cupwind + ! do k =1, nz + ! do j = js, je ; do i = is, ie + ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 + ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 + ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + ! enddo ; enddo + ! enddo end subroutine zonal_upwind_fluxes From 89cc31b21c21c1b6daea44b29d9f94859ec4a78f Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 13:41:49 +1100 Subject: [PATCH 059/288] Make nm same size as upwind for saving --- src/diagnostics/MOM_diagnostics.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 1da1ddaa4c..3bb8f80f6f 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1651,7 +1651,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics ! [H T-1 ~> m s-1 or kg m-2 s-1]. - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. From 42d1e8a59c52e7f34ab55024aedb801035e9efb2 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 13:45:28 +1100 Subject: [PATCH 060/288] Return nm array to correct size --- src/diagnostics/MOM_diagnostics.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 3bb8f80f6f..1da1ddaa4c 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1651,7 +1651,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics ! [H T-1 ~> m s-1 or kg m-2 s-1]. - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. From 0345ccedc386704cdd036669ff12fb68d0bba1c3 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 13:50:38 +1100 Subject: [PATCH 061/288] Loop over vertices --- src/diagnostics/MOM_numerical_mixing.F90 | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index a49bd3d7a2..472c5f8d13 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -100,14 +100,14 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) call zonal_upwind_values(uh, Tr, G, nz, Cupwind) - nm = Cupwind - ! do k =1, nz - ! do j = js, je ; do i = is, ie - ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 - ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 - ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - ! enddo ; enddo - ! enddo + do k =1, nz + do j = js, je ; do i = is, ie + ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 + ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 + ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + nm(i, j, k) = Cupwind(I, j, k) + enddo ; enddo + enddo end subroutine zonal_upwind_fluxes @@ -125,10 +125,10 @@ subroutine zonal_upwind_values(uh, Tr, G, nz, Cupwind) integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec + Is = G%IscB ; Ie = G%IecB ; js = G%jsc ; je = G%jec do k = 1, nz - do j = js, je ; do I = is-1, ie + do j = js, je ; do I = Is, Ie if (uh(I, j, k) >= 0) then Cupwind(I, j, k) = Tr%t(i, j, k) elseif (uh(I, j, k) < 0) then From c8a90e01cd74c7304e1f9da8a322b884bd7ad530 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 14:06:52 +1100 Subject: [PATCH 062/288] Zonal fluxes with vertex indexing --- src/diagnostics/MOM_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 472c5f8d13..df6ef772e4 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -102,10 +102,10 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) do k =1, nz do j = js, je ; do i = is, ie - ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 - ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 - ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - nm(i, j, k) = Cupwind(I, j, k) + east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 + west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 + nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + ! nm(i, j, k) = Cupwind(I, j, k) enddo ; enddo enddo From b0e27a8a78ee2f2cc9bc1020674f68b33e588169 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 14:35:27 +1100 Subject: [PATCH 063/288] Change index to start 1 prior --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index df6ef772e4..c1881f81f7 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -128,7 +128,7 @@ subroutine zonal_upwind_values(uh, Tr, G, nz, Cupwind) Is = G%IscB ; Ie = G%IecB ; js = G%jsc ; je = G%jec do k = 1, nz - do j = js, je ; do I = Is, Ie + do j = js, je ; do I = Is-1, Ie if (uh(I, j, k) >= 0) then Cupwind(I, j, k) = Tr%t(i, j, k) elseif (uh(I, j, k) < 0) then From 8e71d9f996e0d2c1995a8fbd1eef4598e2d62db0 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 15:47:15 +1100 Subject: [PATCH 064/288] Temporary resize to save upwind tracer array --- src/tracer/MOM_tracer_registry.F90 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index c1d8077312..d405f687d1 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -382,8 +382,10 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "flux from the horizontal boundary diffusion scheme", trim(flux_units), & v_extensive=.true., & x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) + ! Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & + ! diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") + diag%axesCuL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -409,8 +411,10 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "Horizontal Boundary Diffusive Meridional Flux of "//trim(flux_longname), & flux_units, v_extensive=.true., conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T, & x_cell_method='sum') + ! Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & + ! diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") + diag%axesCuL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & From 8ce286d688f3290bf8472e720582861a731fc109 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 15:49:40 +1100 Subject: [PATCH 065/288] Temporary changes to return Zonal upwind array --- src/diagnostics/MOM_diagnostics.F90 | 2 +- src/diagnostics/MOM_numerical_mixing.F90 | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 1da1ddaa4c..3bb8f80f6f 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1651,7 +1651,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics ! [H T-1 ~> m s-1 or kg m-2 s-1]. - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index c1881f81f7..27d67d5689 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -100,14 +100,14 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) call zonal_upwind_values(uh, Tr, G, nz, Cupwind) - do k =1, nz - do j = js, je ; do i = is, ie - east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 - west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 - nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - ! nm(i, j, k) = Cupwind(I, j, k) - enddo ; enddo - enddo + nm = nm + Cupwind + ! do k =1, nz + ! do j = js, je ; do i = is, ie + ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 + ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 + ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + ! enddo ; enddo + ! enddo end subroutine zonal_upwind_fluxes From 5208f2ea91811a1b93549c519e5c48591db992e0 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 22 Oct 2025 16:40:58 +1100 Subject: [PATCH 066/288] Revert to correct units for nm in variable and diagnostic --- src/diagnostics/MOM_diagnostics.F90 | 2 +- src/tracer/MOM_tracer_registry.F90 | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 3bb8f80f6f..1da1ddaa4c 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1651,7 +1651,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics ! [H T-1 ~> m s-1 or kg m-2 s-1]. - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index d405f687d1..c1d8077312 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -382,10 +382,8 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "flux from the horizontal boundary diffusion scheme", trim(flux_units), & v_extensive=.true., & x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) - ! Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - ! diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - diag%axesCuL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") + diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -411,10 +409,8 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "Horizontal Boundary Diffusive Meridional Flux of "//trim(flux_longname), & flux_units, v_extensive=.true., conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T, & x_cell_method='sum') - ! Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - ! diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - diag%axesCuL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") + diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & From 6b9d76a6332690967bcfd140c3abe90a77f84de6 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 23 Oct 2025 09:20:54 +1100 Subject: [PATCH 067/288] Online finite differencing - no errors when saving whole array and computing offine --- src/diagnostics/MOM_numerical_mixing.F90 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 27d67d5689..86e66237aa 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -100,14 +100,14 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) call zonal_upwind_values(uh, Tr, G, nz, Cupwind) - nm = nm + Cupwind - ! do k =1, nz - ! do j = js, je ; do i = is, ie - ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 - ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 - ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - ! enddo ; enddo - ! enddo + do k =1, nz + do j = js, je ; do i = is, ie + ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 + ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 + ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + nm(i, j, k) = nm(i, j, k) + Cupwind(I, j, k) - Cupwind(I-1, j, k) + enddo ; enddo + enddo end subroutine zonal_upwind_fluxes From dfdfc8522f7b901710c417ca569cd7478aa7c72c Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 23 Oct 2025 09:38:43 +1100 Subject: [PATCH 068/288] whole matrix diff? --- src/diagnostics/MOM_numerical_mixing.F90 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 86e66237aa..931fcd03d9 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -100,14 +100,14 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) call zonal_upwind_values(uh, Tr, G, nz, Cupwind) - do k =1, nz - do j = js, je ; do i = is, ie - ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 - ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 - ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - nm(i, j, k) = nm(i, j, k) + Cupwind(I, j, k) - Cupwind(I-1, j, k) - enddo ; enddo - enddo + nm = nm + Cupwind(is:ie, :, :) - Cupwind(is-1:ie-1, :, :) + ! do k =1, nz + ! do j = js, je ; do i = is, ie + ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 + ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 + ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + ! enddo ; enddo + ! enddo end subroutine zonal_upwind_fluxes From ac622f2aa0d15852f8374f2585711ca96e4be2f1 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 23 Oct 2025 10:16:49 +1100 Subject: [PATCH 069/288] Add zonal upwind diagnostic --- src/diagnostics/MOM_diagnostics.F90 | 8 +++-- src/diagnostics/MOM_numerical_mixing.F90 | 38 ++++++++++++------------ src/tracer/MOM_tracer_registry.F90 | 4 +++ src/tracer/MOM_tracer_types.F90 | 1 + 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 1da1ddaa4c..7e5d3fb9e3 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1651,12 +1651,13 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics ! [H T-1 ~> m s-1 or kg m-2 s-1]. + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind of tracer real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. type(tracer_type), pointer :: Tr !< Tracer type for numerical mixing - real :: scale_constant, rho_ref + real :: scale_constant !< Scale for numerical mixing e.g. specific heat capacity integer :: i, j, k, is, ie, js, je, nz, m is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke @@ -1712,12 +1713,13 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy do m=1,Reg%ntr ; if (Reg%Tr(m)%registry_diags) then Tr => Reg%Tr(m) - ! Compute and post the numerical mixing if required if (Tr%id_numerical_mixing > 0) then scale_constant = 3991.86795711963 !< hard coded (for now) specific heat capacity + x_upwind(:, :, :) = 0. nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, Idt, uhtr, vhtr, scale_constant, nm) + call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, Idt, uhtr, vhtr, scale_constant, x_upwind, nm) call post_data(Tr%id_numerical_mixing, nm, diag) + if (Tr%id_zonal_upwind > 0) call post_data(Tr%id_zonal_upwind, x_upwind, diag) endif endif; enddo diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 931fcd03d9..f63ffe39e6 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -10,12 +10,12 @@ module MOM_numerical_mixing #include -public numerical_mixing +public numerical_mixing, zonal_upwind_values contains !< Calculate the suprious ``numerical'' mixing of tracer C due to advection. -subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale_constant, nm) +subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale_constant, Tr_x_upwind, nm) implicit none type(ocean_grid_type), intent(in) :: G !< Ocean grid structure @@ -28,6 +28,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T + real, intent(inout) :: Tr_x_upwind(:, :, :) !< Zonal upwind value for tracer real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic !< Local variables @@ -36,7 +37,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale Tr_adv_scale = scale_constant * GV%Rho0 ! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) - call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) + call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, Tr_x_upwind, nm) ! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, nm) end subroutine numerical_mixing @@ -76,7 +77,7 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) +subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, Tr_x_upwind, nm) implicit none type(tracer_type), intent(in) :: Tr !< Tracer @@ -85,41 +86,40 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, nm) real, intent(in) :: Idt !< Inverse model timestep type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: Tr_x_upwind(:, :, :) !< Zonal upwind value for tracer real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: uh !< Zonal thickness transport - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: Cupwind !< Empty variable for the upwind values of C real :: east, west !< East and West positions for zonal derivative uh = uhtr * ((GV%H_to_RZ * Idt) / GV%Rho0) - Cupwind(:, :, :) = 0. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call zonal_upwind_values(uh, Tr, G, nz, Cupwind) + call zonal_upwind_values(uh, Tr, G, nz, Tr_x_upwind) - nm = nm + Cupwind(is:ie, :, :) - Cupwind(is-1:ie-1, :, :) - ! do k =1, nz - ! do j = js, je ; do i = is, ie - ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Cupwind(I, j, k) - uh(I, j, k) * Cupwind(I, j, k)**2 - ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Cupwind(I-1, j, k) - uh(I-1, j, k) * Cupwind(I-1, j, k)**2 - ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - ! enddo ; enddo - ! enddo + do k =1, nz + do j = js, je ; do i = is, ie + ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Tr_x_upwind(I, j, k) - uh(I, j, k) * Tr_x_upwind(I, j, k)**2 + ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Tr_x_upwind(I-1, j, k) - uh(I-1, j, k) * Tr_x_upwind(I-1, j, k)**2 + ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + nm(i, j, k) = nm(i, j, k) + Tr_x_upwind(I, j, k) - Tr_x_upwind(I-1, j, k) + enddo ; enddo + enddo end subroutine zonal_upwind_fluxes !< Subroutine to calculate upwind values in zonal direction -subroutine zonal_upwind_values(uh, Tr, G, nz, Cupwind) +subroutine zonal_upwind_values(uh, Tr, G, nz, Tr_x_upwind) implicit none real, intent(in) :: uh(:, :, :) !< Zonal thickness transport type(tracer_type), intent(in) :: Tr !< Tracer type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: Cupwind(:, :, :) !< Zonal upwind values of C calculated using uhtr + real, intent(inout) :: Tr_x_upwind(:, :, :) !< Zonal upwind values of C calculated using uhtr !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes @@ -130,9 +130,9 @@ subroutine zonal_upwind_values(uh, Tr, G, nz, Cupwind) do k = 1, nz do j = js, je ; do I = Is-1, Ie if (uh(I, j, k) >= 0) then - Cupwind(I, j, k) = Tr%t(i, j, k) + Tr_x_upwind(I, j, k) = Tr%t(i, j, k) elseif (uh(I, j, k) < 0) then - Cupwind(I, j, k) = Tr%t(i+1, j, k) + Tr_x_upwind(I, j, k) = Tr%t(i+1, j, k) endif enddo ; enddo enddo diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index c1d8077312..dd4e37a6f1 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -382,6 +382,8 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "flux from the horizontal boundary diffusion scheme", trim(flux_units), & v_extensive=.true., & x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) + Tr%id_zonal_upwind = register_diag_field("ocean_model", trim(shortnm)//"_zonal_upwind", & + diag%axesCuL, Time, "Zonal upwind values of "//trim(shortnm), trim(Tr%units)) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") else @@ -409,6 +411,8 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "Horizontal Boundary Diffusive Meridional Flux of "//trim(flux_longname), & flux_units, v_extensive=.true., conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T, & x_cell_method='sum') + Tr%id_zonal_upwind = register_diag_field("ocean_model", trim(shortnm)//"_zonal_upwind", & + diag%axesCuL, Time, "Zonal upwind values of "//trim(shortnm), trim(Tr%units)) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") endif diff --git a/src/tracer/MOM_tracer_types.F90 b/src/tracer/MOM_tracer_types.F90 index 0d608f6f18..bb48f861b5 100644 --- a/src/tracer/MOM_tracer_types.F90 +++ b/src/tracer/MOM_tracer_types.F90 @@ -120,6 +120,7 @@ module MOM_tracer_types integer :: id_tr_vardec = -1 integer :: id_zint = -1, id_zint_100m = -1, id_surf = -1 integer :: id_net_surfflux = -1, id_NLT_tendency = -1, id_NLT_budget = -1 + integer :: id_zonal_upwind = -1 integer :: id_numerical_mixing = -1 !>@} end type tracer_type From bb886c0f4fabdbfed2bf114abe262e4025681666 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 23 Oct 2025 10:30:21 +1100 Subject: [PATCH 070/288] Homogenise tracer name --- src/diagnostics/MOM_numerical_mixing.F90 | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index f63ffe39e6..6c6979abaa 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -15,7 +15,7 @@ module MOM_numerical_mixing contains !< Calculate the suprious ``numerical'' mixing of tracer C due to advection. -subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale_constant, Tr_x_upwind, nm) +subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, nm) implicit none type(ocean_grid_type), intent(in) :: G !< Ocean grid structure @@ -28,7 +28,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(inout) :: Tr_x_upwind(:, :, :) !< Zonal upwind value for tracer + real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind value for tracer real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic !< Local variables @@ -37,7 +37,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale Tr_adv_scale = scale_constant * GV%Rho0 ! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) - call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, Tr_x_upwind, nm) + call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, x_upwind, nm) ! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, nm) end subroutine numerical_mixing @@ -77,7 +77,7 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, Tr_x_upwind, nm) +subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, x_upwind, nm) implicit none type(tracer_type), intent(in) :: Tr !< Tracer @@ -86,7 +86,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, Tr_x_upwind, real, intent(in) :: Idt !< Inverse model timestep type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: Tr_x_upwind(:, :, :) !< Zonal upwind value for tracer + real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind value for tracer real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables @@ -98,28 +98,28 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, Tr_x_upwind, uh = uhtr * ((GV%H_to_RZ * Idt) / GV%Rho0) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call zonal_upwind_values(uh, Tr, G, nz, Tr_x_upwind) + call zonal_upwind_values(uh, Tr, G, nz, x_upwind) do k =1, nz do j = js, je ; do i = is, ie - ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * Tr_x_upwind(I, j, k) - uh(I, j, k) * Tr_x_upwind(I, j, k)**2 - ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * Tr_x_upwind(I-1, j, k) - uh(I-1, j, k) * Tr_x_upwind(I-1, j, k)**2 + ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - uh(I, j, k) * x_upwind(I, j, k)**2 + ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - uh(I-1, j, k) * x_upwind(I-1, j, k)**2 ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - nm(i, j, k) = nm(i, j, k) + Tr_x_upwind(I, j, k) - Tr_x_upwind(I-1, j, k) + nm(i, j, k) = nm(i, j, k) + x_upwind(I, j, k) - x_upwind(I-1, j, k) enddo ; enddo enddo end subroutine zonal_upwind_fluxes !< Subroutine to calculate upwind values in zonal direction -subroutine zonal_upwind_values(uh, Tr, G, nz, Tr_x_upwind) +subroutine zonal_upwind_values(uh, Tr, G, nz, x_upwind) implicit none real, intent(in) :: uh(:, :, :) !< Zonal thickness transport type(tracer_type), intent(in) :: Tr !< Tracer type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: Tr_x_upwind(:, :, :) !< Zonal upwind values of C calculated using uhtr + real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values of C calculated using uhtr !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes @@ -130,9 +130,9 @@ subroutine zonal_upwind_values(uh, Tr, G, nz, Tr_x_upwind) do k = 1, nz do j = js, je ; do I = Is-1, Ie if (uh(I, j, k) >= 0) then - Tr_x_upwind(I, j, k) = Tr%t(i, j, k) + x_upwind(I, j, k) = Tr%t(i, j, k) elseif (uh(I, j, k) < 0) then - Tr_x_upwind(I, j, k) = Tr%t(i+1, j, k) + x_upwind(I, j, k) = Tr%t(i+1, j, k) endif enddo ; enddo enddo From 34f96e9bd16e426f8b94baf8d1867a74447887b5 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 23 Oct 2025 10:45:39 +1100 Subject: [PATCH 071/288] Correct indexing for upwind variable --- src/diagnostics/MOM_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 6c6979abaa..265b151f89 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -10,7 +10,7 @@ module MOM_numerical_mixing #include -public numerical_mixing, zonal_upwind_values +public numerical_mixing contains @@ -128,7 +128,7 @@ subroutine zonal_upwind_values(uh, Tr, G, nz, x_upwind) Is = G%IscB ; Ie = G%IecB ; js = G%jsc ; je = G%jec do k = 1, nz - do j = js, je ; do I = Is-1, Ie + do j = js, je ; do I = Is, Ie if (uh(I, j, k) >= 0) then x_upwind(I, j, k) = Tr%t(i, j, k) elseif (uh(I, j, k) < 0) then From 39970d6ca230d3339ab0724ce6777115a2565d92 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 23 Oct 2025 11:00:48 +1100 Subject: [PATCH 072/288] Only access one part of upwind array to check if this is producing seg fault --- src/diagnostics/MOM_numerical_mixing.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 265b151f89..f6201261d1 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -105,7 +105,8 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, x_upwind, nm) ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - uh(I, j, k) * x_upwind(I, j, k)**2 ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - uh(I-1, j, k) * x_upwind(I-1, j, k)**2 ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - nm(i, j, k) = nm(i, j, k) + x_upwind(I, j, k) - x_upwind(I-1, j, k) + ! nm(i, j, k) = nm(i, j, k) + x_upwind(I, j, k) - x_upwind(I-1, j, k) + nm(i, j, k) = nm(i, j, k) + x_upwind(I, j, k) enddo ; enddo enddo From 8fc3c3a20ff29e535dc36187e22333816a60160c Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 23 Oct 2025 11:19:30 +1100 Subject: [PATCH 073/288] Dont add upwind diagnostic --- src/diagnostics/MOM_diagnostics.F90 | 2 +- src/diagnostics/MOM_numerical_mixing.F90 | 3 +-- src/tracer/MOM_tracer_registry.F90 | 8 ++++---- src/tracer/MOM_tracer_types.F90 | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 7e5d3fb9e3..cb253ac784 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1719,7 +1719,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy nm(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, Idt, uhtr, vhtr, scale_constant, x_upwind, nm) call post_data(Tr%id_numerical_mixing, nm, diag) - if (Tr%id_zonal_upwind > 0) call post_data(Tr%id_zonal_upwind, x_upwind, diag) + ! if (Tr%id_zonal_upwind > 0) call post_data(Tr%id_zonal_upwind, x_upwind, diag) endif endif; enddo diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index f6201261d1..265b151f89 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -105,8 +105,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, x_upwind, nm) ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - uh(I, j, k) * x_upwind(I, j, k)**2 ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - uh(I-1, j, k) * x_upwind(I-1, j, k)**2 ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - ! nm(i, j, k) = nm(i, j, k) + x_upwind(I, j, k) - x_upwind(I-1, j, k) - nm(i, j, k) = nm(i, j, k) + x_upwind(I, j, k) + nm(i, j, k) = nm(i, j, k) + x_upwind(I, j, k) - x_upwind(I-1, j, k) enddo ; enddo enddo diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index dd4e37a6f1..86ca08198c 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -382,8 +382,8 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "flux from the horizontal boundary diffusion scheme", trim(flux_units), & v_extensive=.true., & x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) - Tr%id_zonal_upwind = register_diag_field("ocean_model", trim(shortnm)//"_zonal_upwind", & - diag%axesCuL, Time, "Zonal upwind values of "//trim(shortnm), trim(Tr%units)) + ! Tr%id_zonal_upwind = register_diag_field("ocean_model", trim(shortnm)//"_zonal_upwind", & + ! diag%axesCuL, Time, "Zonal upwind values of "//trim(shortnm), trim(Tr%units)) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") else @@ -411,8 +411,8 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "Horizontal Boundary Diffusive Meridional Flux of "//trim(flux_longname), & flux_units, v_extensive=.true., conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T, & x_cell_method='sum') - Tr%id_zonal_upwind = register_diag_field("ocean_model", trim(shortnm)//"_zonal_upwind", & - diag%axesCuL, Time, "Zonal upwind values of "//trim(shortnm), trim(Tr%units)) + ! Tr%id_zonal_upwind = register_diag_field("ocean_model", trim(shortnm)//"_zonal_upwind", & + ! diag%axesCuL, Time, "Zonal upwind values of "//trim(shortnm), trim(Tr%units)) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") endif diff --git a/src/tracer/MOM_tracer_types.F90 b/src/tracer/MOM_tracer_types.F90 index bb48f861b5..7dbef3370b 100644 --- a/src/tracer/MOM_tracer_types.F90 +++ b/src/tracer/MOM_tracer_types.F90 @@ -120,7 +120,7 @@ module MOM_tracer_types integer :: id_tr_vardec = -1 integer :: id_zint = -1, id_zint_100m = -1, id_surf = -1 integer :: id_net_surfflux = -1, id_NLT_tendency = -1, id_NLT_budget = -1 - integer :: id_zonal_upwind = -1 + ! integer :: id_zonal_upwind = -1 integer :: id_numerical_mixing = -1 !>@} end type tracer_type From 0d334437696e0f9ffb2ff615e50a9d3dadf92fba Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 23 Oct 2025 11:31:37 +1100 Subject: [PATCH 074/288] Make index 1 longer --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 265b151f89..3acbaddbfe 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -128,7 +128,7 @@ subroutine zonal_upwind_values(uh, Tr, G, nz, x_upwind) Is = G%IscB ; Ie = G%IecB ; js = G%jsc ; je = G%jec do k = 1, nz - do j = js, je ; do I = Is, Ie + do j = js, je ; do I = Is-1, Ie if (uh(I, j, k) >= 0) then x_upwind(I, j, k) = Tr%t(i, j, k) elseif (uh(I, j, k) < 0) then From f66eaf7f613d5f6065ab1bcc02d76db5991c0e03 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 23 Oct 2025 11:50:31 +1100 Subject: [PATCH 075/288] Try new method --- src/diagnostics/MOM_diagnostics.F90 | 7 +- src/diagnostics/MOM_numerical_mixing.F90 | 85 ++++++++++++------------ 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index cb253ac784..b742930343 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1651,7 +1651,8 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics ! [H T-1 ~> m s-1 or kg m-2 s-1]. - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind of tracer + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes @@ -1716,10 +1717,10 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy if (Tr%id_numerical_mixing > 0) then scale_constant = 3991.86795711963 !< hard coded (for now) specific heat capacity x_upwind(:, :, :) = 0. + y_upwind(:, :, :) = 0. nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, Idt, uhtr, vhtr, scale_constant, x_upwind, nm) + call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) call post_data(Tr%id_numerical_mixing, nm, diag) - ! if (Tr%id_zonal_upwind > 0) call post_data(Tr%id_zonal_upwind, x_upwind, diag) endif endif; enddo diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 3acbaddbfe..14cc083d93 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -15,7 +15,7 @@ module MOM_numerical_mixing contains !< Calculate the suprious ``numerical'' mixing of tracer C due to advection. -subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, nm) +subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) implicit none type(ocean_grid_type), intent(in) :: G !< Ocean grid structure @@ -28,7 +28,8 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind value for tracer + real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values for tracer + real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values for tracer real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic !< Local variables @@ -36,9 +37,9 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale ! e.g. for temperature need to divide by specific heat capacity * rho_ref Tr_adv_scale = scale_constant * GV%Rho0 -! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) + call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, x_upwind, nm) -! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, nm) + call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, y_upwind, nm) end subroutine numerical_mixing @@ -80,14 +81,14 @@ end subroutine thickness_weighted_variance_change subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, x_upwind, nm) implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal fluxes - real, intent(in) :: Idt !< Inverse model timestep - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind value for tracer - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal fluxes + real, intent(in) :: Idt !< Inverse model timestep + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind value for tracer + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -102,10 +103,9 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, x_upwind, nm) do k =1, nz do j = js, je ; do i = is, ie - ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - uh(I, j, k) * x_upwind(I, j, k)**2 - ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - uh(I-1, j, k) * x_upwind(I-1, j, k)**2 - ! nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - nm(i, j, k) = nm(i, j, k) + x_upwind(I, j, k) - x_upwind(I-1, j, k) + east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - uh(I, j, k) * x_upwind(I, j, k)**2 + west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - uh(I-1, j, k) * x_upwind(I-1, j, k)**2 + nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo enddo @@ -115,10 +115,10 @@ end subroutine zonal_upwind_fluxes subroutine zonal_upwind_values(uh, Tr, G, nz, x_upwind) implicit none - real, intent(in) :: uh(:, :, :) !< Zonal thickness transport - type(tracer_type), intent(in) :: Tr !< Tracer - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(in) :: uh(:, :, :) !< Zonal thickness transport + type(tracer_type), intent(in) :: Tr !< Tracer + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values of C calculated using uhtr !< Local variables @@ -140,61 +140,60 @@ subroutine zonal_upwind_values(uh, Tr, G, nz, x_upwind) end subroutine zonal_upwind_values !< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, nm) +subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, y_upwind, nm) implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: vhtr(:, :, :) !< Meridional mass transport - real, intent(in) :: Idt !< Inverse model timestep - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: vhtr(:, :, :) !< Meridional mass transport + real, intent(in) :: Idt !< Inverse model timestep + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind tracer values + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vh !< Meridional thickness transport - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: Cupwind !< Empty variable for the meridional upwind tracer values real :: north, south !< North and South positions for meridional derivative vh = vhtr * ((GV%H_to_RZ * Idt) / GV%Rho0) - Cupwind(:, :, :) = 0. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call meridional_upwind_values(vh, Tr, G, nz, Cupwind) + call meridional_upwind_values(vh, Tr, G, nz, y_upwind) do k = 1, nz do j = js, je ; do i = is, ie - north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * Cupwind(i, J, k) - vh(i, J, k) * Cupwind(i, J, k)**2 - south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * Cupwind(i, J-1, k) - vh(i, J-1, k) * Cupwind(i, J-1, k)**2 + north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - vh(i, J, k) * y_upwind(i, J, k)**2 + south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * y_upwind(i, J-1, k) - vh(i, J-1, k) * y_upwind(i, J-1, k)**2 nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) enddo ; enddo enddo end subroutine meridional_upwind_fluxes -subroutine meridional_upwind_values(vh, Tr, G, nz, Cupwind) +subroutine meridional_upwind_values(vh, Tr, G, nz, y_upwind) implicit none - real, intent(in) :: vh(:, :, :) !< Meridional transport - type(tracer_type), intent(in) :: Tr !< Tracer - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: Cupwind(:, :, :) !< Meridional upwind values of C calculated using vhtr + real, intent(in) :: vh(:, :, :) !< Meridional transport + type(tracer_type), intent(in) :: Tr !< Tracer + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values of C calculated using vhtr !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec + is = G%isc ; ie = G%iec ; Js = G%JscB ; Je = G%JecB do k = 1, nz - do j = js-1, je ; do i = is, ie + do J = Js-1, Je ; do i = is, ie if (vh(i, J, k) >= 0) then - Cupwind(i, J, k) = Tr%t(i, j, k) + y_upwind(i, J, k) = Tr%t(i, j, k) elseif (vh(i, J, k) < 0) then - Cupwind(i, J, k) = Tr%t(i, j+1, k) + y_upwind(i, J, k) = Tr%t(i, j+1, k) endif enddo ; enddo enddo From 2bf906ce3389161220f631d2697626d27f6b99cf Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 23 Oct 2025 12:58:29 +1100 Subject: [PATCH 076/288] Clear up some bracketing --- src/diagnostics/MOM_numerical_mixing.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 14cc083d93..0a82c218cc 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -70,7 +70,7 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d h1 = h(i, j, k) hadv = h1 + dt * h_tendency(i, j, k) C1 = Tr%t(i, j, k) - Cadv = h1 * C1 + ( dt * Tr%advection_xy(i, j, k) ) / Tr_adv_scale + Cadv = h1 * C1 + dt * (Tr%advection_xy(i, j, k) / Tr_adv_scale) nm(i, j, k) = ( (Cadv**2 / hadv) - (h1 * C1**2) ) * Idt enddo ; enddo enddo @@ -96,7 +96,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, x_upwind, nm) real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: uh !< Zonal thickness transport real :: east, west !< East and West positions for zonal derivative - uh = uhtr * ((GV%H_to_RZ * Idt) / GV%Rho0) + uh = (uhtr * (GV%H_to_RZ * Idt) / GV%Rho0 is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke call zonal_upwind_values(uh, Tr, G, nz, x_upwind) @@ -158,7 +158,7 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, y_upwind real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vh !< Meridional thickness transport real :: north, south !< North and South positions for meridional derivative - vh = vhtr * ((GV%H_to_RZ * Idt) / GV%Rho0) + vh = (vhtr * (GV%H_to_RZ * Idt)) / GV%Rho0 is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke call meridional_upwind_values(vh, Tr, G, nz, y_upwind) From 6019b1916b3c06f723addce4fd000533077ffaae Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 23 Oct 2025 13:52:11 +1100 Subject: [PATCH 077/288] Remove unneeded diagnostic definition --- src/tracer/MOM_tracer_registry.F90 | 4 ---- src/tracer/MOM_tracer_types.F90 | 1 - 2 files changed, 5 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 86ca08198c..c1d8077312 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -382,8 +382,6 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "flux from the horizontal boundary diffusion scheme", trim(flux_units), & v_extensive=.true., & x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) - ! Tr%id_zonal_upwind = register_diag_field("ocean_model", trim(shortnm)//"_zonal_upwind", & - ! diag%axesCuL, Time, "Zonal upwind values of "//trim(shortnm), trim(Tr%units)) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") else @@ -411,8 +409,6 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "Horizontal Boundary Diffusive Meridional Flux of "//trim(flux_longname), & flux_units, v_extensive=.true., conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T, & x_cell_method='sum') - ! Tr%id_zonal_upwind = register_diag_field("ocean_model", trim(shortnm)//"_zonal_upwind", & - ! diag%axesCuL, Time, "Zonal upwind values of "//trim(shortnm), trim(Tr%units)) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") endif diff --git a/src/tracer/MOM_tracer_types.F90 b/src/tracer/MOM_tracer_types.F90 index 7dbef3370b..0d608f6f18 100644 --- a/src/tracer/MOM_tracer_types.F90 +++ b/src/tracer/MOM_tracer_types.F90 @@ -120,7 +120,6 @@ module MOM_tracer_types integer :: id_tr_vardec = -1 integer :: id_zint = -1, id_zint_100m = -1, id_surf = -1 integer :: id_net_surfflux = -1, id_NLT_tendency = -1, id_NLT_budget = -1 - ! integer :: id_zonal_upwind = -1 integer :: id_numerical_mixing = -1 !>@} end type tracer_type From c4e0825cbcd54c4339506b9746d743fd0f096631 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 24 Oct 2025 10:00:36 +1100 Subject: [PATCH 078/288] Check fluxes only --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 0a82c218cc..88d3dd39b5 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -37,7 +37,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale ! e.g. for temperature need to divide by specific heat capacity * rho_ref Tr_adv_scale = scale_constant * GV%Rho0 - call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) + ! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, x_upwind, nm) call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, y_upwind, nm) From 703cf7d2dc719f7b3d8b9f2b6a70800a25d423b4 Mon Sep 17 00:00:00 2001 From: Josef Bisits Date: Fri, 24 Oct 2025 10:03:46 +1100 Subject: [PATCH 079/288] Fix brackets --- src/diagnostics/MOM_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 88d3dd39b5..e085ae6a77 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -96,7 +96,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, x_upwind, nm) real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: uh !< Zonal thickness transport real :: east, west !< East and West positions for zonal derivative - uh = (uhtr * (GV%H_to_RZ * Idt) / GV%Rho0 + uh = (uhtr * GV%H_to_RZ * Idt) / GV%Rho0 is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke call zonal_upwind_values(uh, Tr, G, nz, x_upwind) @@ -158,7 +158,7 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, y_upwind real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vh !< Meridional thickness transport real :: north, south !< North and South positions for meridional derivative - vh = (vhtr * (GV%H_to_RZ * Idt)) / GV%Rho0 + vh = (vhtr * GV%H_to_RZ * Idt) / GV%Rho0 is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke call meridional_upwind_values(vh, Tr, G, nz, y_upwind) From 4fb76a56d7ebf7e0d5d6a88e2dc7bd42ef1b6f21 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 24 Oct 2025 11:25:05 +1100 Subject: [PATCH 080/288] Compute things in different order --- src/diagnostics/MOM_diagnostics.F90 | 20 +++++++- src/diagnostics/MOM_numerical_mixing.F90 | 61 +++++++++++------------- 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index b742930343..a607ea5ebd 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -35,7 +35,7 @@ module MOM_diagnostics use MOM_variables, only : accel_diag_ptrs, cont_diag_ptrs, surface use MOM_verticalGrid, only : verticalGrid_type, get_thickness_units, get_flux_units use MOM_wave_speed, only : wave_speed, wave_speed_CS, wave_speed_init -use MOM_numerical_mixing, only : numerical_mixing +use MOM_numerical_mixing, only : numerical_mixing, zonal_upwind_values, meridional_upwind_values implicit none ; private @@ -1651,7 +1651,9 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics ! [H T-1 ~> m s-1 or kg m-2 s-1]. + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: u_trans ! zonal transport real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: v_trans ! meridional transport real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer real :: Idt ! The inverse of the time interval [T-1 ~> s-1] @@ -1716,10 +1718,24 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy Tr => Reg%Tr(m) if (Tr%id_numerical_mixing > 0) then scale_constant = 3991.86795711963 !< hard coded (for now) specific heat capacity + + u_trans(:, :, :) = 0. + do k=1,nz ; do j=js,je ; do I=is-1,ie + u_trans(I,j,k) = uhtr(I,j,k) * H_to_RZ_dt / GV%Rho0 + enddo ; enddo ; enddo + + v_trans(:, :, :) = 0. + do k=1,nz ; do J=js-1,je ; do i=is,ie + v_trans(i,J,k) = vhtr(i,J,k) * H_to_RZ_dt / GV%Rho0 + enddo ; enddo ; enddo + x_upwind(:, :, :) = 0. + call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) y_upwind(:, :, :) = 0. + call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) + nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) + call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, Idt, u_trans, v_trans, scale_constant, x_upwind, y_upwind, nm) call post_data(Tr%id_numerical_mixing, nm, diag) endif endif; enddo diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index e085ae6a77..05afffeea2 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -10,12 +10,12 @@ module MOM_numerical_mixing #include -public numerical_mixing +public numerical_mixing, zonal_upwind_values, meridional_upwind_values contains !< Calculate the suprious ``numerical'' mixing of tracer C due to advection. -subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) +subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, u_trans, v_trans, scale_constant, x_upwind, y_upwind, nm) implicit none type(ocean_grid_type), intent(in) :: G !< Ocean grid structure @@ -25,8 +25,8 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency real, intent(in) :: dt !< Model timestep real, intent(in) :: Idt !< Inverse model timestep - real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport - real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport + real, intent(in) :: u_trans(:, :, :) !< Zonal transport + real, intent(in) :: v_trans(:, :, :) !< Meridional transport real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values for tracer real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values for tracer @@ -38,8 +38,8 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale Tr_adv_scale = scale_constant * GV%Rho0 ! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) - call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, x_upwind, nm) - call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, y_upwind, nm) + call zonal_upwind_fluxes(Tr, Tr_adv_scale, u_trans, G, GV, x_upwind, nm) + call meridional_upwind_fluxes(Tr, Tr_adv_scale, v_trans, Idt, G, GV, y_upwind, nm) end subroutine numerical_mixing @@ -78,33 +78,30 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, x_upwind, nm) +subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, u_trans, G, GV, x_upwind, nm) implicit none type(tracer_type), intent(in) :: Tr !< Tracer real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal fluxes - real, intent(in) :: Idt !< Inverse model timestep + real, intent(in) :: u_trans(:, :, :) !< Zonal transport type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind value for tracer + real, intent(in) :: x_upwind(:, :, :) !< Zonal upwind value for tracer real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: uh !< Zonal thickness transport real :: east, west !< East and West positions for zonal derivative - uh = (uhtr * GV%H_to_RZ * Idt) / GV%Rho0 is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call zonal_upwind_values(uh, Tr, G, nz, x_upwind) + ! call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) do k =1, nz do j = js, je ; do i = is, ie - east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - uh(I, j, k) * x_upwind(I, j, k)**2 - west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - uh(I-1, j, k) * x_upwind(I-1, j, k)**2 + east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - u_trans(I, j, k) * x_upwind(I, j, k)**2 + west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - u_trans(I-1, j, k) * x_upwind(I-1, j, k)**2 nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo enddo @@ -112,14 +109,14 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, Idt, G, GV, x_upwind, nm) end subroutine zonal_upwind_fluxes !< Subroutine to calculate upwind values in zonal direction -subroutine zonal_upwind_values(uh, Tr, G, nz, x_upwind) +subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) implicit none - real, intent(in) :: uh(:, :, :) !< Zonal thickness transport type(tracer_type), intent(in) :: Tr !< Tracer type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values of C calculated using uhtr + real, intent(in) :: u_trans(:, :, :) !< Zonal transport + real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values of C calculated using u_trans !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes @@ -129,9 +126,9 @@ subroutine zonal_upwind_values(uh, Tr, G, nz, x_upwind) do k = 1, nz do j = js, je ; do I = Is-1, Ie - if (uh(I, j, k) >= 0) then + if (u_trans(I, j, k) >= 0) then x_upwind(I, j, k) = Tr%t(i, j, k) - elseif (uh(I, j, k) < 0) then + elseif (u_trans(I, j, k) < 0) then x_upwind(I, j, k) = Tr%t(i+1, j, k) endif enddo ; enddo @@ -140,47 +137,45 @@ subroutine zonal_upwind_values(uh, Tr, G, nz, x_upwind) end subroutine zonal_upwind_values !< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, Idt, G, GV, y_upwind, nm) +subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, v_trans, Idt, G, GV, y_upwind, nm) implicit none type(tracer_type), intent(in) :: Tr !< Tracer real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: vhtr(:, :, :) !< Meridional mass transport + real, intent(in) :: v_trans(:, :, :) !< Meridional transport real, intent(in) :: Idt !< Inverse model timestep type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind tracer values + real, intent(in) :: y_upwind(:, :, :) !< Meridional upwind tracer values real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vh !< Meridional thickness transport real :: north, south !< North and South positions for meridional derivative - vh = (vhtr * GV%H_to_RZ * Idt) / GV%Rho0 is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call meridional_upwind_values(vh, Tr, G, nz, y_upwind) + ! call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) do k = 1, nz do j = js, je ; do i = is, ie - north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - vh(i, J, k) * y_upwind(i, J, k)**2 - south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * y_upwind(i, J-1, k) - vh(i, J-1, k) * y_upwind(i, J-1, k)**2 + north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - v_trans(i, J, k) * y_upwind(i, J, k)**2 + south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * y_upwind(i, J-1, k) - v_trans(i, J-1, k) * y_upwind(i, J-1, k)**2 nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) enddo ; enddo enddo end subroutine meridional_upwind_fluxes -subroutine meridional_upwind_values(vh, Tr, G, nz, y_upwind) +subroutine meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) implicit none - real, intent(in) :: vh(:, :, :) !< Meridional transport type(tracer_type), intent(in) :: Tr !< Tracer type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values of C calculated using vhtr + real, intent(in) :: v_trans(:, :, :) !< Meridional transport + real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values of C calculated using v_trans !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes @@ -190,9 +185,9 @@ subroutine meridional_upwind_values(vh, Tr, G, nz, y_upwind) do k = 1, nz do J = Js-1, Je ; do i = is, ie - if (vh(i, J, k) >= 0) then + if (v_trans(i, J, k) >= 0) then y_upwind(i, J, k) = Tr%t(i, j, k) - elseif (vh(i, J, k) < 0) then + elseif (v_trans(i, J, k) < 0) then y_upwind(i, J, k) = Tr%t(i, j+1, k) endif enddo ; enddo From fe4b251bd10eac717e06406b8d10dbe7e270ad24 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 24 Oct 2025 11:49:40 +1100 Subject: [PATCH 081/288] Try different indexing, matches offline but lines are back --- src/diagnostics/MOM_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 05afffeea2..bcb66d572e 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -28,8 +28,8 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, u_trans, v_trans, real, intent(in) :: u_trans(:, :, :) !< Zonal transport real, intent(in) :: v_trans(:, :, :) !< Meridional transport real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values for tracer - real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values for tracer + real, intent(in) :: x_upwind(:, :, :) !< Zonal upwind values for tracer + real, intent(in) :: y_upwind(:, :, :) !< Meridional upwind values for tracer real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic !< Local variables @@ -125,7 +125,7 @@ subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) Is = G%IscB ; Ie = G%IecB ; js = G%jsc ; je = G%jec do k = 1, nz - do j = js, je ; do I = Is-1, Ie + do j = js, je ; do I = Is, Ie if (u_trans(I, j, k) >= 0) then x_upwind(I, j, k) = Tr%t(i, j, k) elseif (u_trans(I, j, k) < 0) then @@ -184,7 +184,7 @@ subroutine meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) is = G%isc ; ie = G%iec ; Js = G%JscB ; Je = G%JecB do k = 1, nz - do J = Js-1, Je ; do i = is, ie + do J = Js, Je ; do i = is, ie if (v_trans(i, J, k) >= 0) then y_upwind(i, J, k) = Tr%t(i, j, k) elseif (v_trans(i, J, k) < 0) then From fbf21aab944fbfe651bdb30b8503d73077ac501b Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 24 Oct 2025 12:12:35 +1100 Subject: [PATCH 082/288] Upwind computation in nm subroutine --- src/diagnostics/MOM_diagnostics.F90 | 4 ++-- src/diagnostics/MOM_numerical_mixing.F90 | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index a607ea5ebd..04e8acb08b 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1730,9 +1730,9 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy enddo ; enddo ; enddo x_upwind(:, :, :) = 0. - call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) + ! call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) y_upwind(:, :, :) = 0. - call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) + ! call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) nm(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, Idt, u_trans, v_trans, scale_constant, x_upwind, y_upwind, nm) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index bcb66d572e..e5a21f66f0 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -28,8 +28,8 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, u_trans, v_trans, real, intent(in) :: u_trans(:, :, :) !< Zonal transport real, intent(in) :: v_trans(:, :, :) !< Meridional transport real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(in) :: x_upwind(:, :, :) !< Zonal upwind values for tracer - real, intent(in) :: y_upwind(:, :, :) !< Meridional upwind values for tracer + real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values for tracer + real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values for tracer real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic !< Local variables @@ -86,7 +86,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, u_trans, G, GV, x_upwind, nm) real, intent(in) :: u_trans(:, :, :) !< Zonal transport type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(in) :: x_upwind(:, :, :) !< Zonal upwind value for tracer + real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind value for tracer real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables @@ -96,7 +96,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, u_trans, G, GV, x_upwind, nm) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - ! call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) + call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) do k =1, nz do j = js, je ; do i = is, ie @@ -146,7 +146,7 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, v_trans, Idt, G, GV, y_upw real, intent(in) :: Idt !< Inverse model timestep type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(in) :: y_upwind(:, :, :) !< Meridional upwind tracer values + real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind tracer values real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables @@ -156,7 +156,7 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, v_trans, Idt, G, GV, y_upw is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - ! call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) + call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) do k = 1, nz do j = js, je ; do i = is, ie From 68a2538c5370d4e2625ca16bd3a4a32ab0595ea3 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 24 Oct 2025 13:44:17 +1100 Subject: [PATCH 083/288] Remove upwind from calculation to check it is still culprit --- src/diagnostics/MOM_numerical_mixing.F90 | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index e5a21f66f0..0fbc6366fd 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -100,8 +100,10 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, u_trans, G, GV, x_upwind, nm) do k =1, nz do j = js, je ; do i = is, ie - east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - u_trans(I, j, k) * x_upwind(I, j, k)**2 - west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - u_trans(I-1, j, k) * x_upwind(I-1, j, k)**2 + ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - u_trans(I, j, k) * x_upwind(I, j, k)**2 + ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - u_trans(I-1, j, k) * x_upwind(I-1, j, k)**2 + east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) - u_trans(I, j, k) + west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) - u_trans(I-1, j, k) nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo enddo @@ -160,8 +162,10 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, v_trans, Idt, G, GV, y_upw do k = 1, nz do j = js, je ; do i = is, ie - north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - v_trans(i, J, k) * y_upwind(i, J, k)**2 - south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * y_upwind(i, J-1, k) - v_trans(i, J-1, k) * y_upwind(i, J-1, k)**2 + ! north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - v_trans(i, J, k) * y_upwind(i, J, k)**2 + ! south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * y_upwind(i, J-1, k) - v_trans(i, J-1, k) * y_upwind(i, J-1, k)**2 + north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) - v_trans(i, J, k) + south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) - v_trans(i, J-1, k) nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) enddo ; enddo enddo From a0c73d58f7f42ad908a92695cb10843177562ff9 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 24 Oct 2025 14:25:55 +1100 Subject: [PATCH 084/288] Revert to previous transport calculation --- src/diagnostics/MOM_diagnostics.F90 | 22 ++------- src/diagnostics/MOM_numerical_mixing.F90 | 62 +++++++++++++++--------- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 04e8acb08b..aab8a102a7 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -35,7 +35,7 @@ module MOM_diagnostics use MOM_variables, only : accel_diag_ptrs, cont_diag_ptrs, surface use MOM_verticalGrid, only : verticalGrid_type, get_thickness_units, get_flux_units use MOM_wave_speed, only : wave_speed, wave_speed_CS, wave_speed_init -use MOM_numerical_mixing, only : numerical_mixing, zonal_upwind_values, meridional_upwind_values +use MOM_numerical_mixing, only : numerical_mixing implicit none ; private @@ -1651,9 +1651,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics ! [H T-1 ~> m s-1 or kg m-2 s-1]. - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: u_trans ! zonal transport real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: v_trans ! meridional transport real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer real :: Idt ! The inverse of the time interval [T-1 ~> s-1] @@ -1718,24 +1716,12 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy Tr => Reg%Tr(m) if (Tr%id_numerical_mixing > 0) then scale_constant = 3991.86795711963 !< hard coded (for now) specific heat capacity - - u_trans(:, :, :) = 0. - do k=1,nz ; do j=js,je ; do I=is-1,ie - u_trans(I,j,k) = uhtr(I,j,k) * H_to_RZ_dt / GV%Rho0 - enddo ; enddo ; enddo - - v_trans(:, :, :) = 0. - do k=1,nz ; do J=js-1,je ; do i=is,ie - v_trans(i,J,k) = vhtr(i,J,k) * H_to_RZ_dt / GV%Rho0 - enddo ; enddo ; enddo - x_upwind(:, :, :) = 0. - ! call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) y_upwind(:, :, :) = 0. - ! call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) - nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, Idt, u_trans, v_trans, scale_constant, x_upwind, y_upwind, nm) + call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) + ! The call to numerical mixing requires other variables that may not be registered. Don't know what best practice is + ! but one option is to add another to condition to the loops so it is computed, then another condition to post? call post_data(Tr%id_numerical_mixing, nm, diag) endif endif; enddo diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 0fbc6366fd..1b707db372 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -10,12 +10,12 @@ module MOM_numerical_mixing #include -public numerical_mixing, zonal_upwind_values, meridional_upwind_values +public numerical_mixing contains !< Calculate the suprious ``numerical'' mixing of tracer C due to advection. -subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, u_trans, v_trans, scale_constant, x_upwind, y_upwind, nm) +subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) implicit none type(ocean_grid_type), intent(in) :: G !< Ocean grid structure @@ -25,8 +25,8 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, u_trans, v_trans, real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency real, intent(in) :: dt !< Model timestep real, intent(in) :: Idt !< Inverse model timestep - real, intent(in) :: u_trans(:, :, :) !< Zonal transport - real, intent(in) :: v_trans(:, :, :) !< Meridional transport + real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport + real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values for tracer real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values for tracer @@ -35,11 +35,13 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, u_trans, v_trans, !< Local variables real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct ! e.g. for temperature need to divide by specific heat capacity * rho_ref + real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. Tr_adv_scale = scale_constant * GV%Rho0 + mass_transport_scale =(Idt * GV%H_to_RZ) / GV%Rho0 ! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) - call zonal_upwind_fluxes(Tr, Tr_adv_scale, u_trans, G, GV, x_upwind, nm) - call meridional_upwind_fluxes(Tr, Tr_adv_scale, v_trans, Idt, G, GV, y_upwind, nm) + call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) + call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) end subroutine numerical_mixing @@ -78,23 +80,30 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, u_trans, G, GV, x_upwind, nm) +subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: u_trans(:, :, :) !< Zonal transport - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind value for tracer - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport + real, intent(in) :: mass_transport_scale !< Inverse model timestep + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind value for tracer + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters real :: east, west !< East and West positions for zonal derivative + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: u_trans !< Zonal transport is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke + + u_trans(:, :, :) = 0. + do k=1,nz ; do j=js,je ; do I=is-1,ie + u_trans(I,j,k) = uhtr(I,j,k) * mass_transport_scale + enddo ; enddo ; enddo call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) @@ -139,27 +148,34 @@ subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) end subroutine zonal_upwind_values !< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, v_trans, Idt, G, GV, y_upwind, nm) +subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, v_trans, mass_transport_scale, G, GV, y_upwind, nm) implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: v_trans(:, :, :) !< Meridional transport - real, intent(in) :: Idt !< Inverse model timestep - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind tracer values - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: v_trans(:, :, :) !< Meridional transport + real, intent(in) :: mass_transport_scale !< Scaling for mass transport + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind tracer values + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters real :: north, south !< North and South positions for meridional derivative + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: v_trans !< Meridional transport is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke + v_trans(:, :, :) = 0. + do k=1,nz ; do J=js-1,je ; do i=is,ie + v_trans(i,J,k) = vhtr(i,J,k) * H_to_RZ_dt / GV%Rho0 + enddo ; enddo ; enddo + call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) + do k = 1, nz do j = js, je ; do i = is, ie ! north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - v_trans(i, J, k) * y_upwind(i, J, k)**2 From 5440b54cc969239ca644503d7c245e812a2a9ceb Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 24 Oct 2025 14:30:44 +1100 Subject: [PATCH 085/288] Incorrect variable call --- src/diagnostics/MOM_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 1b707db372..57eea46085 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -148,12 +148,12 @@ subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) end subroutine zonal_upwind_values !< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, v_trans, mass_transport_scale, G, GV, y_upwind, nm) +subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) implicit none type(tracer_type), intent(in) :: Tr !< Tracer real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: v_trans(:, :, :) !< Meridional transport + real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport real, intent(in) :: mass_transport_scale !< Scaling for mass transport type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure @@ -165,12 +165,12 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, v_trans, mass_transport_sc integer :: i, j, k !< Counters real :: north, south !< North and South positions for meridional derivative real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: v_trans !< Meridional transport - + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke v_trans(:, :, :) = 0. do k=1,nz ; do J=js-1,je ; do i=is,ie - v_trans(i,J,k) = vhtr(i,J,k) * H_to_RZ_dt / GV%Rho0 + v_trans(i,J,k) = vhtr(i,J,k) * mass_transport_scale enddo ; enddo ; enddo call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) From 7a7d25a2504fca3c8eb1da167ca21bdb326d7f17 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 24 Oct 2025 14:50:19 +1100 Subject: [PATCH 086/288] transport terms in fluxes correct, check upwind --- src/diagnostics/MOM_numerical_mixing.F90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 57eea46085..703a056442 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -99,7 +99,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: u_trans !< Zonal transport is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - + u_trans(:, :, :) = 0. do k=1,nz ; do j=js,je ; do I=is-1,ie u_trans(I,j,k) = uhtr(I,j,k) * mass_transport_scale @@ -111,8 +111,8 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, do j = js, je ; do i = is, ie ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - u_trans(I, j, k) * x_upwind(I, j, k)**2 ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - u_trans(I-1, j, k) * x_upwind(I-1, j, k)**2 - east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) - u_trans(I, j, k) - west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) - u_trans(I-1, j, k) + east = 2 * x_upwind(I, j, k) + west = 2 * x_upwind(I-1, j, k)) nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo enddo @@ -180,8 +180,8 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale do j = js, je ; do i = is, ie ! north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - v_trans(i, J, k) * y_upwind(i, J, k)**2 ! south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * y_upwind(i, J-1, k) - v_trans(i, J-1, k) * y_upwind(i, J-1, k)**2 - north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) - v_trans(i, J, k) - south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) - v_trans(i, J-1, k) + north = 2 * y_upwind(i, J, k) + south = 2 * y_upwind(i, J-1, k) nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) enddo ; enddo enddo From 934fde1b1aafbe008f6822a62acb01dd36a4ae6c Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 24 Oct 2025 14:52:43 +1100 Subject: [PATCH 087/288] Parentheses error --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 703a056442..31b8c8ddeb 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -112,7 +112,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - u_trans(I, j, k) * x_upwind(I, j, k)**2 ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - u_trans(I-1, j, k) * x_upwind(I-1, j, k)**2 east = 2 * x_upwind(I, j, k) - west = 2 * x_upwind(I-1, j, k)) + west = 2 * x_upwind(I-1, j, k) nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo enddo From c6f0e8d717bcc09e8acf2361d888ecdd09f4e960 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 24 Oct 2025 15:38:58 +1100 Subject: [PATCH 088/288] Upwind looked ok, try whole computation --- src/diagnostics/MOM_numerical_mixing.F90 | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 31b8c8ddeb..8ea4d0eb52 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -109,10 +109,8 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, do k =1, nz do j = js, je ; do i = is, ie - ! east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - u_trans(I, j, k) * x_upwind(I, j, k)**2 - ! west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - u_trans(I-1, j, k) * x_upwind(I-1, j, k)**2 - east = 2 * x_upwind(I, j, k) - west = 2 * x_upwind(I-1, j, k) + east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - u_trans(I, j, k) * x_upwind(I, j, k)**2 + west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - u_trans(I-1, j, k) * x_upwind(I-1, j, k)**2 nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo enddo @@ -178,10 +176,8 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale do k = 1, nz do j = js, je ; do i = is, ie - ! north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - v_trans(i, J, k) * y_upwind(i, J, k)**2 - ! south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * y_upwind(i, J-1, k) - v_trans(i, J-1, k) * y_upwind(i, J-1, k)**2 - north = 2 * y_upwind(i, J, k) - south = 2 * y_upwind(i, J-1, k) + north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - v_trans(i, J, k) * y_upwind(i, J, k)**2 + south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * y_upwind(i, J-1, k) - v_trans(i, J-1, k) * y_upwind(i, J-1, k)**2 nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) enddo ; enddo enddo From 9f562c274502a5e7d1e521ce7b8930bc37263ea6 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 24 Oct 2025 15:58:23 +1100 Subject: [PATCH 089/288] Flux terms computed correctly, check variance --- src/diagnostics/MOM_numerical_mixing.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 8ea4d0eb52..2e621304f0 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -39,9 +39,9 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale Tr_adv_scale = scale_constant * GV%Rho0 mass_transport_scale =(Idt * GV%H_to_RZ) / GV%Rho0 - ! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) - call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) - call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) + call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) + ! call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) + ! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) end subroutine numerical_mixing From 1877c6f9d58918abdb38f2c00b91bbafeadcda4a Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 24 Oct 2025 16:19:37 +1100 Subject: [PATCH 090/288] Minor difference with variance, check total numerical mixing --- src/diagnostics/MOM_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 2e621304f0..4d3f417ef7 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -40,8 +40,8 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale mass_transport_scale =(Idt * GV%H_to_RZ) / GV%Rho0 call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) - ! call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) - ! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) + call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) + call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) end subroutine numerical_mixing From 55eca4119fa6e8aacce227c89115ca24276117ba Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 27 Oct 2025 09:41:15 +1100 Subject: [PATCH 091/288] Move tendency calculation into numerical mixing, should be able to call without needing to save other variables --- src/diagnostics/MOM_diagnostics.F90 | 2 +- src/diagnostics/MOM_numerical_mixing.F90 | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index aab8a102a7..ac413ece39 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1719,7 +1719,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy x_upwind(:, :, :) = 0. y_upwind(:, :, :) = 0. nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, h, h_tend, dt_trans, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) + call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) ! The call to numerical mixing requires other variables that may not be registered. Don't know what best practice is ! but one option is to add another to condition to the loops so it is computed, then another condition to post? call post_data(Tr%id_numerical_mixing, nm, diag) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 4d3f417ef7..180de57523 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -1,7 +1,7 @@ !> Functions and routines involved in calculating numerical mixing of tracers due to advection module MOM_numerical_mixing -use MOM_diag_mediator, only : diag_ctrl +use MOM_diag_mediator, only : diag_ctrl, diag_grid_storage use MOM_grid, only : ocean_grid_type use MOM_tracer_types, only : tracer_type use MOM_verticalGrid, only : verticalGrid_type @@ -15,14 +15,14 @@ module MOM_numerical_mixing contains !< Calculate the suprious ``numerical'' mixing of tracer C due to advection. -subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) + subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) implicit none type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Tracer real, intent(in) :: h(:, :, :) !< Thickness - real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt !< Model timestep real, intent(in) :: Idt !< Inverse model timestep real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport @@ -39,20 +39,20 @@ subroutine numerical_mixing(G, GV, Tr, h, h_tendency, dt, Idt, uhtr, vhtr, scale Tr_adv_scale = scale_constant * GV%Rho0 mass_transport_scale =(Idt * GV%H_to_RZ) / GV%Rho0 - call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) + call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) end subroutine numerical_mixing !< Subroutine to calculate the thickness weighted variance change over a timestep -subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, dt, Idt, G, GV, nm) +subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) implicit none type(tracer_type), intent(in) :: Tr !< Tracer real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection real, intent(in) :: h(:, :, :) !< Thickness - real, intent(in) :: h_tendency(:, :, :) !< Thickness tendency + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt !< Model timestep real, intent(in) :: Idt !< Inverse model timestep type(ocean_grid_type), intent(in) :: G !< Ocean grid structure @@ -64,13 +64,19 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, h_tendency, d integer :: i, j, k !< Counters real :: h1, C1, hadv, Cadv !< Temporary variables for thickness and tracer at current timestep !< and the changes in thickness and tracer due to advection. + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend !< Thickness tendenccy is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke + h_tend(:,:,:) = 0. + do k=1,nz ; do j=js,je ; do i=is,ie + h_tend(i,j,k) = (h(i,j,k) - diag_pre_dyn%h_state(i,j,k))*Idt + enddo ; enddo ; enddo + do k = 1, nz do j = js, je ; do i = is, ie h1 = h(i, j, k) - hadv = h1 + dt * h_tendency(i, j, k) + hadv = h1 + dt * h_tend(i, j, k) C1 = Tr%t(i, j, k) Cadv = h1 * C1 + dt * (Tr%advection_xy(i, j, k) / Tr_adv_scale) nm(i, j, k) = ( (Cadv**2 / hadv) - (h1 * C1**2) ) * Idt From a96b69d5aaa6d008e8ffe90ffb8410408c2eb231 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 27 Oct 2025 10:05:41 +1100 Subject: [PATCH 092/288] Check thickness only --- src/diagnostics/MOM_numerical_mixing.F90 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 180de57523..4510f6b501 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -40,8 +40,8 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca mass_transport_scale =(Idt * GV%H_to_RZ) / GV%Rho0 call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) - call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) - call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) + ! call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) + ! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) end subroutine numerical_mixing @@ -72,11 +72,12 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, do k=1,nz ; do j=js,je ; do i=is,ie h_tend(i,j,k) = (h(i,j,k) - diag_pre_dyn%h_state(i,j,k))*Idt enddo ; enddo ; enddo - + do k = 1, nz do j = js, je ; do i = is, ie h1 = h(i, j, k) hadv = h1 + dt * h_tend(i, j, k) + ! hadv = 2*h1 - diag_pre_dyn%h_state(i,j,k) C1 = Tr%t(i, j, k) Cadv = h1 * C1 + dt * (Tr%advection_xy(i, j, k) / Tr_adv_scale) nm(i, j, k) = ( (Cadv**2 / hadv) - (h1 * C1**2) ) * Idt From 883cf3a34b59d3ef6325720eb436a857a14c0c42 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 27 Oct 2025 10:23:25 +1100 Subject: [PATCH 093/288] Try alternate thickness advection definition --- src/diagnostics/MOM_numerical_mixing.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 4510f6b501..7bdf5632f3 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -64,7 +64,7 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, integer :: i, j, k !< Counters real :: h1, C1, hadv, Cadv !< Temporary variables for thickness and tracer at current timestep !< and the changes in thickness and tracer due to advection. - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend !< Thickness tendenccy + ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend !< Thickness tendenccy is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke @@ -76,8 +76,8 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, do k = 1, nz do j = js, je ; do i = is, ie h1 = h(i, j, k) - hadv = h1 + dt * h_tend(i, j, k) - ! hadv = 2*h1 - diag_pre_dyn%h_state(i,j,k) + ! hadv = h1 + dt * h_tend(i, j, k) + hadv = 2*h1 - diag_pre_dyn%h_state(i,j,k) C1 = Tr%t(i, j, k) Cadv = h1 * C1 + dt * (Tr%advection_xy(i, j, k) / Tr_adv_scale) nm(i, j, k) = ( (Cadv**2 / hadv) - (h1 * C1**2) ) * Idt From 53cec981334c4592129a374e597769155c30cd33 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 27 Oct 2025 10:25:07 +1100 Subject: [PATCH 094/288] Forgot to remove variable --- src/diagnostics/MOM_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 7bdf5632f3..a792eb83eb 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -68,10 +68,10 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - h_tend(:,:,:) = 0. - do k=1,nz ; do j=js,je ; do i=is,ie - h_tend(i,j,k) = (h(i,j,k) - diag_pre_dyn%h_state(i,j,k))*Idt - enddo ; enddo ; enddo + ! h_tend(:,:,:) = 0. + ! do k=1,nz ; do j=js,je ; do i=is,ie + ! h_tend(i,j,k) = (h(i,j,k) - diag_pre_dyn%h_state(i,j,k))*Idt + ! enddo ; enddo ; enddo do k = 1, nz do j = js, je ; do i = is, ie From bd8a95efba2d8db8188fe9650dee5df669dbd183 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 27 Oct 2025 10:42:59 +1100 Subject: [PATCH 095/288] Try with previous h_state as h1 --- src/diagnostics/MOM_numerical_mixing.F90 | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index a792eb83eb..360ad19b85 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -64,20 +64,16 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, integer :: i, j, k !< Counters real :: h1, C1, hadv, Cadv !< Temporary variables for thickness and tracer at current timestep !< and the changes in thickness and tracer due to advection. - ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend !< Thickness tendenccy is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - ! h_tend(:,:,:) = 0. - ! do k=1,nz ; do j=js,je ; do i=is,ie - ! h_tend(i,j,k) = (h(i,j,k) - diag_pre_dyn%h_state(i,j,k))*Idt - ! enddo ; enddo ; enddo - do k = 1, nz do j = js, je ; do i = is, ie - h1 = h(i, j, k) + ! h1 = h(i, j, k) ! hadv = h1 + dt * h_tend(i, j, k) - hadv = 2*h1 - diag_pre_dyn%h_state(i,j,k) + ! hadv = 2*h1 - diag_pre_dyn%h_state(i,j,k) ! hadv = h1 + dt * h_tend(i, j, k) = + h1 = diag_pre_dyn%h_state(i, j, k) + hadv = h(i, j, k) C1 = Tr%t(i, j, k) Cadv = h1 * C1 + dt * (Tr%advection_xy(i, j, k) / Tr_adv_scale) nm(i, j, k) = ( (Cadv**2 / hadv) - (h1 * C1**2) ) * Idt From f6a22c4c6a87a4abc79de9c657fa2ab159ac3a1e Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 27 Oct 2025 11:08:14 +1100 Subject: [PATCH 096/288] use previous tracer value to match using previous thickness value --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 360ad19b85..a8f39515f2 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -74,7 +74,7 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, ! hadv = 2*h1 - diag_pre_dyn%h_state(i,j,k) ! hadv = h1 + dt * h_tend(i, j, k) = h1 = diag_pre_dyn%h_state(i, j, k) hadv = h(i, j, k) - C1 = Tr%t(i, j, k) + C1 = Tr%t_prev(i, j, k) Cadv = h1 * C1 + dt * (Tr%advection_xy(i, j, k) / Tr_adv_scale) nm(i, j, k) = ( (Cadv**2 / hadv) - (h1 * C1**2) ) * Idt enddo ; enddo From 47f99683d9fb4c6d819c6e1dc488c3b03790f5c1 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 27 Oct 2025 11:26:15 +1100 Subject: [PATCH 097/288] Back to variance change as already defined, try to have different scale_constants --- src/diagnostics/MOM_diagnostics.F90 | 10 +++++++--- src/diagnostics/MOM_numerical_mixing.F90 | 13 ++++++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index ac413ece39..e962251a36 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1715,13 +1715,17 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy do m=1,Reg%ntr ; if (Reg%Tr(m)%registry_diags) then Tr => Reg%Tr(m) if (Tr%id_numerical_mixing > 0) then - scale_constant = 3991.86795711963 !< hard coded (for now) specific heat capacity + if (Tr%name == "T") + scale_constant = 3991.86795711963 !< hard coded (for now) specific heat capacity + elseif (Tr%name == "S") + scale_constant = 1000 !< g -> kg + else + scale_constant = 1 !< any other tracer is unscaled + endif x_upwind(:, :, :) = 0. y_upwind(:, :, :) = 0. nm(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) - ! The call to numerical mixing requires other variables that may not be registered. Don't know what best practice is - ! but one option is to add another to condition to the loops so it is computed, then another condition to post? call post_data(Tr%id_numerical_mixing, nm, diag) endif endif; enddo diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index a8f39515f2..7a20cf52b5 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -69,12 +69,15 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, do k = 1, nz do j = js, je ; do i = is, ie - ! h1 = h(i, j, k) + ! Should the previous state be used here? h is the updated thickness values so below might be what we want + ! h1 = diag_pre_dyn%h_state(i, j, k) + ! hadv = h(i, j, k) + ! C1 = Tr%t_prev(i, j, k) + h1 = h(i, j, k) ! hadv = h1 + dt * h_tend(i, j, k) - ! hadv = 2*h1 - diag_pre_dyn%h_state(i,j,k) ! hadv = h1 + dt * h_tend(i, j, k) = - h1 = diag_pre_dyn%h_state(i, j, k) - hadv = h(i, j, k) - C1 = Tr%t_prev(i, j, k) + ! = h(i, j, k) + dt * Idt * (h(i, j, k) - diag_pre_dyn%h_state(i, j, k)) + hadv = 2*h1 - diag_pre_dyn%h_state(i,j,k) + C1 = Tr%t(i, j, k) Cadv = h1 * C1 + dt * (Tr%advection_xy(i, j, k) / Tr_adv_scale) nm(i, j, k) = ( (Cadv**2 / hadv) - (h1 * C1**2) ) * Idt enddo ; enddo From dccf73a5a269080a719e8438058d32a21a64f66b Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 27 Oct 2025 11:29:03 +1100 Subject: [PATCH 098/288] Forgot then in if statement --- src/diagnostics/MOM_diagnostics.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index e962251a36..22fa416962 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1715,9 +1715,9 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy do m=1,Reg%ntr ; if (Reg%Tr(m)%registry_diags) then Tr => Reg%Tr(m) if (Tr%id_numerical_mixing > 0) then - if (Tr%name == "T") + if (Tr%name == "T") then scale_constant = 3991.86795711963 !< hard coded (for now) specific heat capacity - elseif (Tr%name == "S") + elseif (Tr%name == "S") then scale_constant = 1000 !< g -> kg else scale_constant = 1 !< any other tracer is unscaled From 2a51d0acb1168555a3ab3352db2d713867d815a1 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 27 Oct 2025 11:37:39 +1100 Subject: [PATCH 099/288] Back to full diagnostic + cleanup --- src/diagnostics/MOM_numerical_mixing.F90 | 55 ++++++++++++------------ 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 7a20cf52b5..655d5031d2 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -18,30 +18,31 @@ module MOM_numerical_mixing subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) implicit none - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: h(:, :, :) !< Thickness - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt !< Model timestep - real, intent(in) :: Idt !< Inverse model timestep - real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport - real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport - real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values for tracer - real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values for tracer - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: h(:, :, :) !< Thickness + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt !< Model timestep + real, intent(in) :: Idt !< Inverse model timestep + real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport + real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport + real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T + real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values for tracer + real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values for tracer + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic !< Local variables - real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct - ! e.g. for temperature need to divide by specific heat capacity * rho_ref - real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. + real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct + !< e.g. for temperature need to divide by specific heat capacity * rho_ref + real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. + Tr_adv_scale = scale_constant * GV%Rho0 mass_transport_scale =(Idt * GV%H_to_RZ) / GV%Rho0 call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) - ! call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) - ! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) + call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) + call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) end subroutine numerical_mixing @@ -49,15 +50,15 @@ end subroutine numerical_mixing subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: h(:, :, :) !< Thickness - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt !< Model timestep - real, intent(in) :: Idt !< Inverse model timestep - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: h(:, :, :) !< Thickness + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt !< Model timestep + real, intent(in) :: Idt !< Inverse model timestep + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes From 28efbe7f4a393919aa5d91ae70ab08f104a0647e Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 27 Oct 2025 12:22:47 +1100 Subject: [PATCH 100/288] Tracer is Tr not C --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 655d5031d2..c2b93a3be6 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -14,7 +14,7 @@ module MOM_numerical_mixing contains -!< Calculate the suprious ``numerical'' mixing of tracer C due to advection. +!< Calculate the suprious ``numerical'' mixing of tracer Tr due to advection. subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) implicit none From 9eb19628cfbe0664a148e9454028ebf441fc912c Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 29 Oct 2025 14:35:13 +1100 Subject: [PATCH 101/288] Minor code cleanup --- src/diagnostics/MOM_numerical_mixing.F90 | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index c2b93a3be6..4f03a25884 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -38,7 +38,7 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. Tr_adv_scale = scale_constant * GV%Rho0 - mass_transport_scale =(Idt * GV%H_to_RZ) / GV%Rho0 + mass_transport_scale = (Idt * GV%H_to_RZ) / GV%Rho0 call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) @@ -70,10 +70,6 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, do k = 1, nz do j = js, je ; do i = is, ie - ! Should the previous state be used here? h is the updated thickness values so below might be what we want - ! h1 = diag_pre_dyn%h_state(i, j, k) - ! hadv = h(i, j, k) - ! C1 = Tr%t_prev(i, j, k) h1 = h(i, j, k) ! hadv = h1 + dt * h_tend(i, j, k) ! = h(i, j, k) + dt * Idt * (h(i, j, k) - diag_pre_dyn%h_state(i, j, k)) @@ -180,7 +176,6 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) - do k = 1, nz do j = js, je ; do i = is, ie north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - v_trans(i, J, k) * y_upwind(i, J, k)**2 From faef58c92ecc107c094c3221f59f37968541507f Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 29 Oct 2025 15:55:34 +1100 Subject: [PATCH 102/288] Try reversing sign of finite difference --- src/diagnostics/MOM_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 4f03a25884..6512083fdd 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -114,7 +114,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, do j = js, je ; do i = is, ie east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - u_trans(I, j, k) * x_upwind(I, j, k)**2 west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - u_trans(I-1, j, k) * x_upwind(I-1, j, k)**2 - nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + nm(i, j, k) = nm(i, j, k) - ((east - west) * G%IareaT(i, j)) enddo ; enddo enddo @@ -180,7 +180,7 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale do j = js, je ; do i = is, ie north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - v_trans(i, J, k) * y_upwind(i, J, k)**2 south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * y_upwind(i, J-1, k) - v_trans(i, J-1, k) * y_upwind(i, J-1, k)**2 - nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) + nm(i, j, k) = nm(i, j, k) - ((north - south) * G%IareaT(i, j)) enddo ; enddo enddo From 1d30606d8622a185b9913cd46969af09aac4322a Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 30 Oct 2025 14:41:17 +1100 Subject: [PATCH 103/288] Return to previous sign and fix variable description --- src/diagnostics/MOM_numerical_mixing.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 6512083fdd..f4646ef9c7 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -89,7 +89,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, type(tracer_type), intent(in) :: Tr !< Tracer real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport - real, intent(in) :: mass_transport_scale !< Inverse model timestep + real, intent(in) :: mass_transport_scale !< Scaling for mass transport type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind value for tracer @@ -114,7 +114,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, do j = js, je ; do i = is, ie east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - u_trans(I, j, k) * x_upwind(I, j, k)**2 west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - u_trans(I-1, j, k) * x_upwind(I-1, j, k)**2 - nm(i, j, k) = nm(i, j, k) - ((east - west) * G%IareaT(i, j)) + nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo enddo @@ -180,7 +180,7 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale do j = js, je ; do i = is, ie north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - v_trans(i, J, k) * y_upwind(i, J, k)**2 south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * y_upwind(i, J-1, k) - v_trans(i, J-1, k) * y_upwind(i, J-1, k)**2 - nm(i, j, k) = nm(i, j, k) - ((north - south) * G%IareaT(i, j)) + nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) enddo ; enddo enddo From 12deaa8b3ea7a52ef20f5e8c9347b792b8138f93 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 31 Oct 2025 09:46:08 +1100 Subject: [PATCH 104/288] Post numerical mixing on same grid as other diagnostics --- src/diagnostics/MOM_diagnostics.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 22fa416962..6ed1cca757 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1726,7 +1726,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy y_upwind(:, :, :) = 0. nm(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) - call post_data(Tr%id_numerical_mixing, nm, diag) + call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) endif endif; enddo From 224aa2079fb25e7ae414a9c761f03e09005709f5 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 7 Nov 2025 14:06:59 +1100 Subject: [PATCH 105/288] allocate variables when numerical mixing is called --- src/tracer/MOM_tracer_registry.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index c1d8077312..fd803ae36a 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -422,8 +422,8 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u trim(units) // " m") Tr%id_surf = register_diag_field("ocean_model", trim(shortnm)//"_SURF", & diag%axesT1, Time, "Surface values of "// trim(longname), trim(units)) - if (Tr%id_adx > 0) call safe_alloc_ptr(Tr%ad_x,IsdB,IedB,jsd,jed,nz) - if (Tr%id_ady > 0) call safe_alloc_ptr(Tr%ad_y,isd,ied,JsdB,JedB,nz) + if ((Tr%id_adx > 0) .or. (Tr%id_numerical_mixing > 0)) call safe_alloc_ptr(Tr%ad_x,IsdB,IedB,jsd,jed,nz) + if ((Tr%id_ady > 0) .or. (Tr%id_numerical_mixing > 0)) call safe_alloc_ptr(Tr%ad_y,isd,ied,JsdB,JedB,nz) if (Tr%id_dfx > 0) call safe_alloc_ptr(Tr%df_x,IsdB,IedB,jsd,jed,nz) if (Tr%id_dfy > 0) call safe_alloc_ptr(Tr%df_y,isd,ied,JsdB,JedB,nz) if (Tr%id_hbd_dfx > 0) call safe_alloc_ptr(Tr%hbd_dfx,IsdB,IedB,jsd,jed,nz) @@ -472,7 +472,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u diag%axesT1, Time, & 'Vertical sum of horizontal convergence of residual mean advective fluxes of '//& trim(lowercase(flux_longname)), conv_units, conversion=Tr%conv_scale*US%s_to_T) - if ((Tr%id_adv_xy > 0) .or. (Tr%id_adv_xy_2d > 0)) & + if ((Tr%id_adv_xy > 0) .or. (Tr%id_adv_xy_2d > 0) .or. (Tr%id_numerical_mixing > 0)) & call safe_alloc_ptr(Tr%advection_xy,isd,ied,jsd,jed,nz) Tr%id_tendency = register_diag_field('ocean_model', trim(shortnm)//'_tendency', & From afeec95fe9a810ac46c874bc33a8def77fcd057f Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 10 Nov 2025 09:50:40 +1100 Subject: [PATCH 106/288] Fix a few style things --- src/diagnostics/MOM_diagnostics.F90 | 3 +- src/diagnostics/MOM_numerical_mixing.F90 | 63 +++++++++++------------- src/tracer/MOM_tracer_registry.F90 | 4 +- 3 files changed, 32 insertions(+), 38 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 6ed1cca757..5e4ac32414 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1725,7 +1725,8 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy x_upwind(:, :, :) = 0. y_upwind(:, :, :) = 0. nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) + call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & + scale_constant, x_upwind, y_upwind, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) endif endif; enddo diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index f4646ef9c7..3a07d16509 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -15,7 +15,7 @@ module MOM_numerical_mixing contains !< Calculate the suprious ``numerical'' mixing of tracer Tr due to advection. - subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) +subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) implicit none type(ocean_grid_type), intent(in) :: G !< Ocean grid structure @@ -36,7 +36,7 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct !< e.g. for temperature need to divide by specific heat capacity * rho_ref real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. - + Tr_adv_scale = scale_constant * GV%Rho0 mass_transport_scale = (Idt * GV%H_to_RZ) / GV%Rho0 @@ -110,13 +110,11 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) - do k =1, nz - do j = js, je ; do i = is, ie - east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) - u_trans(I, j, k) * x_upwind(I, j, k)**2 - west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - u_trans(I-1, j, k) * x_upwind(I-1, j, k)**2 - nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) - enddo ; enddo - enddo + do k = 1, nz ; do j = js, je ; do i = is, ie + east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) -u_trans(I, j, k) * x_upwind(I, j, k)**2 + west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - u_trans(I-1, j, k) * x_upwind(I-1, j, k)**2 + nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + enddo ; enddo; enddo end subroutine zonal_upwind_fluxes @@ -136,15 +134,13 @@ subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) Is = G%IscB ; Ie = G%IecB ; js = G%jsc ; je = G%jec - do k = 1, nz - do j = js, je ; do I = Is, Ie - if (u_trans(I, j, k) >= 0) then - x_upwind(I, j, k) = Tr%t(i, j, k) - elseif (u_trans(I, j, k) < 0) then - x_upwind(I, j, k) = Tr%t(i+1, j, k) - endif - enddo ; enddo - enddo + do k = 1, nz ; do j = js, je ; do I = Is, Ie + if (u_trans(I, j, k) >= 0) then + x_upwind(I, j, k) = Tr%t(i, j, k) + elseif (u_trans(I, j, k) < 0) then + x_upwind(I, j, k) = Tr%t(i+1, j, k) + endif + enddo ; enddo ; enddo end subroutine zonal_upwind_values @@ -166,7 +162,7 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale integer :: i, j, k !< Counters real :: north, south !< North and South positions for meridional derivative real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: v_trans !< Meridional transport - + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke v_trans(:, :, :) = 0. @@ -176,16 +172,15 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) - do k = 1, nz - do j = js, je ; do i = is, ie - north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - v_trans(i, J, k) * y_upwind(i, J, k)**2 - south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * y_upwind(i, J-1, k) - v_trans(i, J-1, k) * y_upwind(i, J-1, k)**2 - nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) - enddo ; enddo - enddo + do k = 1, nz ; do j = js, je ; do i = is, ie + north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - v_trans(i, J, k) * y_upwind(i, J, k)**2 + south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * y_upwind(i, J-1, k) - v_trans(i, J-1, k) * y_upwind(i, J-1, k)**2 + nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) + enddo ; enddo ; enddo end subroutine meridional_upwind_fluxes +!< Subroutine to calculate upwind value in the meridional direction subroutine meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) implicit none @@ -201,15 +196,13 @@ subroutine meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) is = G%isc ; ie = G%iec ; Js = G%JscB ; Je = G%JecB - do k = 1, nz - do J = Js, Je ; do i = is, ie - if (v_trans(i, J, k) >= 0) then - y_upwind(i, J, k) = Tr%t(i, j, k) - elseif (v_trans(i, J, k) < 0) then - y_upwind(i, J, k) = Tr%t(i, j+1, k) - endif - enddo ; enddo - enddo + do k = 1, nz ; do J = Js, Je ; do i = is, ie + if (v_trans(i, J, k) >= 0) then + y_upwind(i, J, k) = Tr%t(i, j, k) + elseif (v_trans(i, J, k) < 0) then + y_upwind(i, J, k) = Tr%t(i, j+1, k) + endif + enddo ; enddo ; enddo end subroutine meridional_upwind_values diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index fd803ae36a..0bc541c2d5 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -383,7 +383,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u v_extensive=.true., & x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") + diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -410,7 +410,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u flux_units, v_extensive=.true., conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T, & x_cell_method='sum') Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") + diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & From 5a173ac5594b8ef316612c97ef00d04c041b9f56 Mon Sep 17 00:00:00 2001 From: Josef Bisits Date: Tue, 11 Nov 2025 17:04:03 +1100 Subject: [PATCH 107/288] Add numerical mixing module to CMakeLists.txt --- src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e167054cb6..3a5c718600 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -92,6 +92,7 @@ target_sources(mom6shared PRIVATE diagnostics/MOM_diagnose_MLD.F90 diagnostics/MOM_diagnostics.F90 diagnostics/MOM_harmonic_analysis.F90 + diagnostics/MOM_numerical_mixing.F90 diagnostics/MOM_obsolete_diagnostics.F90 diagnostics/MOM_obsolete_params.F90 diagnostics/MOM_PointAccel.F90 From f3119670440c3b7614eb4ec0f9cf6489f5c6efd3 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 09:26:41 +1100 Subject: [PATCH 108/288] Save variance advection and flux for debugging --- src/diagnostics/MOM_diagnostics.F90 | 8 +++++++- src/diagnostics/MOM_numerical_mixing.F90 | 8 +++++++- src/tracer/MOM_tracer_registry.F90 | 8 ++++++++ src/tracer/MOM_tracer_types.F90 | 1 + 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 5e4ac32414..e5f660a6e9 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1654,6 +1654,8 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Variance advection (remove after nm sorted) + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Flux of variance (remove after nm sorted) real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. @@ -1725,9 +1727,13 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy x_upwind(:, :, :) = 0. y_upwind(:, :, :) = 0. nm(:,:,:) = 0. + va(:,:,:) = 0. + vf(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & - scale_constant, x_upwind, y_upwind, nm) + scale_constant, x_upwind, y_upwind, nm, va, vf) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) + call post_data(Tr%id_variance_adv, va, diag, alt_h=diag_pre_dyn%h_state) + call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) endif endif; enddo diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 3a07d16509..1415a28968 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -15,7 +15,7 @@ module MOM_numerical_mixing contains !< Calculate the suprious ``numerical'' mixing of tracer Tr due to advection. -subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) +subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm, va, vf) implicit none type(ocean_grid_type), intent(in) :: G !< Ocean grid structure @@ -31,6 +31,8 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values for tracer real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values for tracer real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic + real, intent(inout) :: va(:, :, :) !< Variance advection (removed after nm sorted) + real, intent(inout) :: vf(:, :, :) !< Variance flux (remove after nm sorted) !< Local variables real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct @@ -43,6 +45,10 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) + !< Temporary for sorting out numerical mixing + call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, va) + call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, vf) + call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, vf) end subroutine numerical_mixing diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 0bc541c2d5..97efc628fa 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -384,6 +384,10 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") + Tr%id_variance_adv = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & + diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", trim(Tr%units)//"^2ms-1") + Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & + diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", trim(Tr%units)//"^2ms-1") else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -411,6 +415,10 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum') Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") + Tr%id_variance_adv = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & + diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", trim(Tr%units)//"^2ms-1") + Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & + diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", trim(Tr%units)//"^2ms-1") endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & diff --git a/src/tracer/MOM_tracer_types.F90 b/src/tracer/MOM_tracer_types.F90 index 0d608f6f18..a878df2d50 100644 --- a/src/tracer/MOM_tracer_types.F90 +++ b/src/tracer/MOM_tracer_types.F90 @@ -121,6 +121,7 @@ module MOM_tracer_types integer :: id_zint = -1, id_zint_100m = -1, id_surf = -1 integer :: id_net_surfflux = -1, id_NLT_tendency = -1, id_NLT_budget = -1 integer :: id_numerical_mixing = -1 + integer :: id_variance_adv = -1, id_variance_flux = -1 !>@} end type tracer_type From b711c42fc4816c24c36ec0f9474fcf5252a2e907 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 10:04:48 +1100 Subject: [PATCH 109/288] Subroutine input variable more general name --- src/diagnostics/MOM_numerical_mixing.F90 | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 1415a28968..3837d9e77f 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -45,7 +45,7 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) - !< Temporary for sorting out numerical mixing + !< temporaray call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, va) call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, vf) call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, vf) @@ -53,7 +53,7 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca end subroutine numerical_mixing !< Subroutine to calculate the thickness weighted variance change over a timestep -subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) +subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, res) implicit none type(tracer_type), intent(in) :: Tr !< Tracer @@ -64,7 +64,7 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, real, intent(in) :: Idt !< Inverse model timestep type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + real, intent(inout) :: res(:, :, :) !< Array to store result in !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -82,14 +82,14 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, hadv = 2*h1 - diag_pre_dyn%h_state(i,j,k) C1 = Tr%t(i, j, k) Cadv = h1 * C1 + dt * (Tr%advection_xy(i, j, k) / Tr_adv_scale) - nm(i, j, k) = ( (Cadv**2 / hadv) - (h1 * C1**2) ) * Idt + res(i, j, k) = ( (Cadv**2 / hadv) - (h1 * C1**2) ) * Idt enddo ; enddo enddo end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) +subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, res) implicit none type(tracer_type), intent(in) :: Tr !< Tracer @@ -99,7 +99,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind value for tracer - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + real, intent(inout) :: res(:, :, :) !< Array to store the result in !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -119,7 +119,7 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, do k = 1, nz ; do j = js, je ; do i = is, ie east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) -u_trans(I, j, k) * x_upwind(I, j, k)**2 west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - u_trans(I-1, j, k) * x_upwind(I-1, j, k)**2 - nm(i, j, k) = nm(i, j, k) + ((east - west) * G%IareaT(i, j)) + res(i, j, k) = res(i, j, k) + ((east - west) * G%IareaT(i, j)) enddo ; enddo; enddo end subroutine zonal_upwind_fluxes @@ -151,7 +151,7 @@ subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) end subroutine zonal_upwind_values !< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) +subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, res) implicit none type(tracer_type), intent(in) :: Tr !< Tracer @@ -161,7 +161,7 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind tracer values - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic to update + real, intent(inout) :: res(:, :, :) !< Array to store the result in !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -181,7 +181,7 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale do k = 1, nz ; do j = js, je ; do i = is, ie north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - v_trans(i, J, k) * y_upwind(i, J, k)**2 south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * y_upwind(i, J-1, k) - v_trans(i, J-1, k) * y_upwind(i, J-1, k)**2 - nm(i, j, k) = nm(i, j, k) + ((north - south) * G%IareaT(i, j)) + res(i, j, k) = res(i, j, k) + ((north - south) * G%IareaT(i, j)) enddo ; enddo ; enddo end subroutine meridional_upwind_fluxes From c30bdbdd84cbd87605af44b3720c439b0b05be16 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 10:13:05 +1100 Subject: [PATCH 110/288] Check nm only --- src/diagnostics/MOM_numerical_mixing.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 3837d9e77f..42e26dd377 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -15,7 +15,7 @@ module MOM_numerical_mixing contains !< Calculate the suprious ``numerical'' mixing of tracer Tr due to advection. -subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm, va, vf) +subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm)!<, va, vf) implicit none type(ocean_grid_type), intent(in) :: G !< Ocean grid structure @@ -31,8 +31,8 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values for tracer real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values for tracer real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic - real, intent(inout) :: va(:, :, :) !< Variance advection (removed after nm sorted) - real, intent(inout) :: vf(:, :, :) !< Variance flux (remove after nm sorted) + ! real, intent(inout) :: va(:, :, :) !< Variance advection (removed after nm sorted) + ! real, intent(inout) :: vf(:, :, :) !< Variance flux (remove after nm sorted) !< Local variables real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct @@ -46,9 +46,9 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) !< temporaray - call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, va) - call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, vf) - call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, vf) + ! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, va) + ! call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, vf) + ! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, vf) end subroutine numerical_mixing From 8db63d2ecc132b0885bb5d014e355d3793ceca2e Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 10:14:30 +1100 Subject: [PATCH 111/288] Forgot this file --- src/diagnostics/MOM_diagnostics.F90 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index e5f660a6e9..b4084aefae 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1654,8 +1654,8 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Variance advection (remove after nm sorted) - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Flux of variance (remove after nm sorted) + ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Variance advection (remove after nm sorted) + ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Flux of variance (remove after nm sorted) real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. @@ -1727,13 +1727,13 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy x_upwind(:, :, :) = 0. y_upwind(:, :, :) = 0. nm(:,:,:) = 0. - va(:,:,:) = 0. - vf(:,:,:) = 0. + ! va(:,:,:) = 0. + ! vf(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & - scale_constant, x_upwind, y_upwind, nm, va, vf) + scale_constant, x_upwind, y_upwind, nm)!<, va, vf) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) - call post_data(Tr%id_variance_adv, va, diag, alt_h=diag_pre_dyn%h_state) - call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) + ! call post_data(Tr%id_variance_adv, va, diag, alt_h=diag_pre_dyn%h_state) + ! call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) endif endif; enddo From 72268c7acb8a0ec8057abed06b7286839074eea8 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 10:23:36 +1100 Subject: [PATCH 112/288] Only save one extra diag --- src/diagnostics/MOM_diagnostics.F90 | 8 ++++---- src/diagnostics/MOM_numerical_mixing.F90 | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index b4084aefae..2f58d06874 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1654,7 +1654,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer - ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Variance advection (remove after nm sorted) + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Variance advection (remove after nm sorted) ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Flux of variance (remove after nm sorted) real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes @@ -1727,12 +1727,12 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy x_upwind(:, :, :) = 0. y_upwind(:, :, :) = 0. nm(:,:,:) = 0. - ! va(:,:,:) = 0. + va(:,:,:) = 0. ! vf(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & - scale_constant, x_upwind, y_upwind, nm)!<, va, vf) + scale_constant, x_upwind, y_upwind, nm, va)!<, vf) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) - ! call post_data(Tr%id_variance_adv, va, diag, alt_h=diag_pre_dyn%h_state) + call post_data(Tr%id_variance_adv, va, diag, alt_h=diag_pre_dyn%h_state) ! call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) endif endif; enddo diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 42e26dd377..cb74f595d2 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -15,7 +15,7 @@ module MOM_numerical_mixing contains !< Calculate the suprious ``numerical'' mixing of tracer Tr due to advection. -subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm)!<, va, vf) +subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm, va)!<, vf) implicit none type(ocean_grid_type), intent(in) :: G !< Ocean grid structure @@ -31,7 +31,7 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values for tracer real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values for tracer real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic - ! real, intent(inout) :: va(:, :, :) !< Variance advection (removed after nm sorted) + real, intent(inout) :: va(:, :, :) !< Variance advection (removed after nm sorted) ! real, intent(inout) :: vf(:, :, :) !< Variance flux (remove after nm sorted) !< Local variables @@ -46,7 +46,7 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) !< temporaray - ! call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, va) + call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, va) ! call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, vf) ! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, vf) From c565e4d0601e7dbab66fc2a4d514c6d4085097e5 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 10:43:24 +1100 Subject: [PATCH 113/288] Add a new subroutine for variance advection --- src/diagnostics/MOM_diagnostics.F90 | 11 +++++--- src/diagnostics/MOM_numerical_mixing.F90 | 34 ++++++++++++++++++------ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 2f58d06874..314f4bc141 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -35,7 +35,7 @@ module MOM_diagnostics use MOM_variables, only : accel_diag_ptrs, cont_diag_ptrs, surface use MOM_verticalGrid, only : verticalGrid_type, get_thickness_units, get_flux_units use MOM_wave_speed, only : wave_speed, wave_speed_CS, wave_speed_init -use MOM_numerical_mixing, only : numerical_mixing +use MOM_numerical_mixing, only : numerical_mixing, variance_advection implicit none ; private @@ -1727,12 +1727,15 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy x_upwind(:, :, :) = 0. y_upwind(:, :, :) = 0. nm(:,:,:) = 0. - va(:,:,:) = 0. ! vf(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & - scale_constant, x_upwind, y_upwind, nm, va)!<, vf) + scale_constant, x_upwind, y_upwind, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) - call post_data(Tr%id_variance_adv, va, diag, alt_h=diag_pre_dyn%h_state) + if (Tr%id_variance_adv > 0) + va(:,:,:) = 0. + call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, scale_constant, va) + call post_data(Tr%id_variance_adv, va, diag, alt_h=diag_pre_dyn%h_state) + endif ! call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) endif endif; enddo diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index cb74f595d2..192075db56 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -10,12 +10,12 @@ module MOM_numerical_mixing #include -public numerical_mixing +public numerical_mixing, variance_advection contains !< Calculate the suprious ``numerical'' mixing of tracer Tr due to advection. -subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm, va)!<, vf) +subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) implicit none type(ocean_grid_type), intent(in) :: G !< Ocean grid structure @@ -31,8 +31,6 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values for tracer real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values for tracer real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic - real, intent(inout) :: va(:, :, :) !< Variance advection (removed after nm sorted) - ! real, intent(inout) :: vf(:, :, :) !< Variance flux (remove after nm sorted) !< Local variables real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct @@ -45,13 +43,33 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) - !< temporaray - call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, va) - ! call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, vf) - ! call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, vf) end subroutine numerical_mixing +subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, scale_constant, va) + + implicit none + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: h(:, :, :) !< Thickness + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt !< Model timestep + real, intent(in) :: Idt !< Inverse model timestep + real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T + real, intent(inout) :: va(:, :, :) !< Variance advection (removed after nm sorted) + + !< Local variables + real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct + !< e.g. for temperature need to divide by specific heat capacity * rho_ref + + Tr_adv_scale = scale_constant * GV%Rho0 + + call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, va) + +end subroutine variance_advection + + !< Subroutine to calculate the thickness weighted variance change over a timestep subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, res) From dd8fdea3cadca694b8f75f4f1a79a5b9f33fe3fe Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 10:45:24 +1100 Subject: [PATCH 114/288] Missed then --- src/diagnostics/MOM_diagnostics.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 314f4bc141..16b5ed7c17 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1731,7 +1731,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & scale_constant, x_upwind, y_upwind, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) - if (Tr%id_variance_adv > 0) + if (Tr%id_variance_adv > 0) then va(:,:,:) = 0. call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, scale_constant, va) call post_data(Tr%id_variance_adv, va, diag, alt_h=diag_pre_dyn%h_state) From 0b00b64fa797bd9157a1ebb00ed06bf8be4cf419 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 10:47:04 +1100 Subject: [PATCH 115/288] Wrong variable name --- src/diagnostics/MOM_diagnostics.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 16b5ed7c17..deb50ea64d 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1733,7 +1733,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) if (Tr%id_variance_adv > 0) then va(:,:,:) = 0. - call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, scale_constant, va) + call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, scale_constant, va) call post_data(Tr%id_variance_adv, va, diag, alt_h=diag_pre_dyn%h_state) endif ! call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) From 8ad439edc1d5d2056924825f2b7be884a77492d1 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 11:03:15 +1100 Subject: [PATCH 116/288] Match variable names --- src/diagnostics/MOM_diagnostics.F90 | 4 ++-- src/tracer/MOM_tracer_registry.F90 | 4 ++-- src/tracer/MOM_tracer_types.F90 | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index deb50ea64d..29d6a4abbf 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1731,10 +1731,10 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & scale_constant, x_upwind, y_upwind, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) - if (Tr%id_variance_adv > 0) then + if (Tr%id_variance_advection > 0) then va(:,:,:) = 0. call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, scale_constant, va) - call post_data(Tr%id_variance_adv, va, diag, alt_h=diag_pre_dyn%h_state) + call post_data(Tr%id_variance_advection, va, diag, alt_h=diag_pre_dyn%h_state) endif ! call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) endif diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 97efc628fa..248448b409 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -384,7 +384,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") - Tr%id_variance_adv = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & + Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", trim(Tr%units)//"^2ms-1") Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", trim(Tr%units)//"^2ms-1") @@ -415,7 +415,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum') Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") - Tr%id_variance_adv = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & + Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", trim(Tr%units)//"^2ms-1") Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", trim(Tr%units)//"^2ms-1") diff --git a/src/tracer/MOM_tracer_types.F90 b/src/tracer/MOM_tracer_types.F90 index a878df2d50..fcbfbaf53a 100644 --- a/src/tracer/MOM_tracer_types.F90 +++ b/src/tracer/MOM_tracer_types.F90 @@ -121,7 +121,7 @@ module MOM_tracer_types integer :: id_zint = -1, id_zint_100m = -1, id_surf = -1 integer :: id_net_surfflux = -1, id_NLT_tendency = -1, id_NLT_budget = -1 integer :: id_numerical_mixing = -1 - integer :: id_variance_adv = -1, id_variance_flux = -1 + integer :: id_variance_advection = -1, id_variance_flux = -1 !>@} end type tracer_type From ea7dce306b149d9cba39125d974a780f01590923 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 11:28:31 +1100 Subject: [PATCH 117/288] add variance flux subroutine --- src/diagnostics/MOM_diagnostics.F90 | 9 ++++++- src/diagnostics/MOM_numerical_mixing.F90 | 31 ++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 29d6a4abbf..aadc22943c 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1736,7 +1736,14 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, scale_constant, va) call post_data(Tr%id_variance_advection, va, diag, alt_h=diag_pre_dyn%h_state) endif - ! call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) + if (Tr%id_variance_flux > 0) then + !< Overkill to caclulate these again but I plan on removing once numerical mixing is sorted + x_upwind(:, :, :) = 0. + y_upwind(:, :, :) = 0. + vf(:,:,:) = 0. + call variance_flux(G, GV, Tr, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) + call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) + endif endif endif; enddo diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 192075db56..6102ab6bd8 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -10,7 +10,7 @@ module MOM_numerical_mixing #include -public numerical_mixing, variance_advection +public numerical_mixing, variance_advection, variance_flux contains @@ -46,6 +46,7 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca end subroutine numerical_mixing +!< Subroutine for only the variance advection, likely will remove once numerical mixing is sorted out subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, scale_constant, va) implicit none @@ -57,7 +58,7 @@ subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, scale_constan real, intent(in) :: dt !< Model timestep real, intent(in) :: Idt !< Inverse model timestep real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(inout) :: va(:, :, :) !< Variance advection (removed after nm sorted) + real, intent(inout) :: va(:, :, :) !< Variance advection !< Local variables real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct @@ -69,6 +70,32 @@ subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, scale_constan end subroutine variance_advection +!< Subroutine for only the variance flux, likely will remove once numerical mixing is sorted out +subroutine variance_flux(G, GV, Tr, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) + + implicit none + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport + real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport + real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T + real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values for tracer + real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values for tracer + real, intent(inout) :: vf(:, :, :) !< Variance fluxes + + !< Local variables + real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct + !< e.g. for temperature need to divide by specific heat capacity * rho_ref + real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. + + Tr_adv_scale = scale_constant * GV%Rho0 + mass_transport_scale = (Idt * GV%H_to_RZ) / GV%Rho0 + + call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, vf) + call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, vf) + +end subroutine variance_flux !< Subroutine to calculate the thickness weighted variance change over a timestep subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, res) From 3898065f42b3a058ede31e69c060db657d60f087 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 11:32:30 +1100 Subject: [PATCH 118/288] Accidentally removed required variable --- src/diagnostics/MOM_numerical_mixing.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 6102ab6bd8..a73b391d28 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -71,12 +71,13 @@ subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, scale_constan end subroutine variance_advection !< Subroutine for only the variance flux, likely will remove once numerical mixing is sorted out -subroutine variance_flux(G, GV, Tr, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) +subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) implicit none type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Idt !< Inverse model timestep real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T From 81c417ddb8e93fd1b339fbf8e6659a5ac401a13b Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 11:33:49 +1100 Subject: [PATCH 119/288] And define the variable --- src/diagnostics/MOM_diagnostics.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index aadc22943c..865d39bfd2 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1655,7 +1655,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Variance advection (remove after nm sorted) - ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Flux of variance (remove after nm sorted) + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Flux of variance (remove after nm sorted) real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. From f8586e550b78fc6f7e2e919acb3445573623ef12 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 11:37:02 +1100 Subject: [PATCH 120/288] Make sure to import the subroutine --- src/diagnostics/MOM_diagnostics.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 865d39bfd2..947969c6ff 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -35,7 +35,7 @@ module MOM_diagnostics use MOM_variables, only : accel_diag_ptrs, cont_diag_ptrs, surface use MOM_verticalGrid, only : verticalGrid_type, get_thickness_units, get_flux_units use MOM_wave_speed, only : wave_speed, wave_speed_CS, wave_speed_init -use MOM_numerical_mixing, only : numerical_mixing, variance_advection +use MOM_numerical_mixing, only : numerical_mixing, variance_advection, variance_flux implicit none ; private From 316b49cc985007b031743e811f6048f49cfb0968 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 11:38:36 +1100 Subject: [PATCH 121/288] Correctly call subroutine --- src/diagnostics/MOM_diagnostics.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 947969c6ff..eaf2d40fb4 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1741,7 +1741,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy x_upwind(:, :, :) = 0. y_upwind(:, :, :) = 0. vf(:,:,:) = 0. - call variance_flux(G, GV, Tr, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) + call variance_flux(G, GV, Idt, Tr, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) endif endif From 58d623db85d6fdc36fc844b0673c865a34c0f58f Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 11:40:32 +1100 Subject: [PATCH 122/288] Wrong position for argument in call --- src/diagnostics/MOM_diagnostics.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index eaf2d40fb4..c8049a1f04 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1741,7 +1741,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy x_upwind(:, :, :) = 0. y_upwind(:, :, :) = 0. vf(:,:,:) = 0. - call variance_flux(G, GV, Idt, Tr, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) + call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) endif endif From 452df99bdf2577b3d7650a8b23940183e147dd36 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 13:54:15 +1100 Subject: [PATCH 123/288] Use previous thickness and tracer values --- src/diagnostics/MOM_numerical_mixing.F90 | 37 ++++++++++++------------ src/tracer/MOM_tracer_registry.F90 | 2 +- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index a73b391d28..97a6d65f15 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -113,24 +113,23 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, real, intent(inout) :: res(:, :, :) !< Array to store result in !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: h1, C1, hadv, Cadv !< Temporary variables for thickness and tracer at current timestep - !< and the changes in thickness and tracer due to advection. + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: h_prev, C_prve, hadv, Cadv !< Thickness and tracer at previous timestep and the + !< changes in thickness and tracer after advection. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - do k = 1, nz - do j = js, je ; do i = is, ie - h1 = h(i, j, k) - ! hadv = h1 + dt * h_tend(i, j, k) - ! = h(i, j, k) + dt * Idt * (h(i, j, k) - diag_pre_dyn%h_state(i, j, k)) - hadv = 2*h1 - diag_pre_dyn%h_state(i,j,k) - C1 = Tr%t(i, j, k) - Cadv = h1 * C1 + dt * (Tr%advection_xy(i, j, k) / Tr_adv_scale) - res(i, j, k) = ( (Cadv**2 / hadv) - (h1 * C1**2) ) * Idt - enddo ; enddo - enddo + do k = 1, nz ; do j = js, je ; do i = is, ie + h_prev = diag_pre_dyn%h_state(i, j, k) + ! hadv = h_prev + dt * (h_tend) + ! = h_prev + dt * (Idt * (h(i, j, k) - h_prev)) + ! = h(i, j, k) + hadv = h(i, j, k) + C_prev = Tr%t_prev(i, j, k) + Cadv = h1 * C1 + dt * (Tr%advection_xy(i, j, k) / Tr_adv_scale) + res(i, j, k) = ( (Cadv**2 / hadv) - (h1 * C1**2) ) * Idt + enddo ; enddo ; enddo end subroutine thickness_weighted_variance_change @@ -188,9 +187,9 @@ subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) do k = 1, nz ; do j = js, je ; do I = Is, Ie if (u_trans(I, j, k) >= 0) then - x_upwind(I, j, k) = Tr%t(i, j, k) + x_upwind(I, j, k) = Tr%t_prev(i, j, k) elseif (u_trans(I, j, k) < 0) then - x_upwind(I, j, k) = Tr%t(i+1, j, k) + x_upwind(I, j, k) = Tr%t_prev(i+1, j, k) endif enddo ; enddo ; enddo @@ -250,9 +249,9 @@ subroutine meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) do k = 1, nz ; do J = Js, Je ; do i = is, ie if (v_trans(i, J, k) >= 0) then - y_upwind(i, J, k) = Tr%t(i, j, k) + y_upwind(i, J, k) = Tr%t_prev(i, j, k) elseif (v_trans(i, J, k) < 0) then - y_upwind(i, J, k) = Tr%t(i, j+1, k) + y_upwind(i, J, k) = Tr%t_prev(i, j+1, k) endif enddo ; enddo ; enddo diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 248448b409..f723cd7f0e 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -488,7 +488,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u 'Net time tendency for '//trim(lowercase(longname)), & trim(units)//' s-1', conversion=Tr%conc_scale*US%s_to_T) - if (Tr%id_tendency > 0) then + if ((Tr%id_tendency > 0) .or. (Tr%id_numerical_mixing > 0)) then call safe_alloc_ptr(Tr%t_prev,isd,ied,jsd,jed,nz) do k=1,nz ; do j=js,je ; do i=is,ie Tr%t_prev(i,j,k) = Tr%t(i,j,k) From 3b2e6cd4e53225738db097020215cb19a1811595 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 15:12:05 +1100 Subject: [PATCH 124/288] Correct all instances of variables --- src/diagnostics/MOM_numerical_mixing.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 97a6d65f15..bf58280bc7 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -115,7 +115,7 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters - real :: h_prev, C_prve, hadv, Cadv !< Thickness and tracer at previous timestep and the + real :: h_prev, C_prev, hadv, Cadv !< Thickness and tracer at previous timestep and the !< changes in thickness and tracer after advection. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke @@ -127,8 +127,8 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, ! = h(i, j, k) hadv = h(i, j, k) C_prev = Tr%t_prev(i, j, k) - Cadv = h1 * C1 + dt * (Tr%advection_xy(i, j, k) / Tr_adv_scale) - res(i, j, k) = ( (Cadv**2 / hadv) - (h1 * C1**2) ) * Idt + Cadv = h_prev * C_prev + dt * (Tr%advection_xy(i, j, k) / Tr_adv_scale) + res(i, j, k) = ( (Cadv**2 / hadv) - (h_prev * C_prev**2) ) * Idt enddo ; enddo ; enddo end subroutine thickness_weighted_variance_change From 4c1d8fe7bb3f37d0fe7f7f2071b7c27b7286ad64 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 13 Nov 2025 16:13:44 +1100 Subject: [PATCH 125/288] Timestep temperature --- src/diagnostics/MOM_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index bf58280bc7..0a78176118 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -187,9 +187,9 @@ subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) do k = 1, nz ; do j = js, je ; do I = Is, Ie if (u_trans(I, j, k) >= 0) then - x_upwind(I, j, k) = Tr%t_prev(i, j, k) + x_upwind(I, j, k) = Tr%t(i, j, k) elseif (u_trans(I, j, k) < 0) then - x_upwind(I, j, k) = Tr%t_prev(i+1, j, k) + x_upwind(I, j, k) = Tr%t(i+1, j, k) endif enddo ; enddo ; enddo @@ -249,9 +249,9 @@ subroutine meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) do k = 1, nz ; do J = Js, Je ; do i = is, ie if (v_trans(i, J, k) >= 0) then - y_upwind(i, J, k) = Tr%t_prev(i, j, k) + y_upwind(i, J, k) = Tr%t(i, j, k) elseif (v_trans(i, J, k) < 0) then - y_upwind(i, J, k) = Tr%t_prev(i, j+1, k) + y_upwind(i, J, k) = Tr%t(i, j+1, k) endif enddo ; enddo ; enddo From 098a6c576b50af09808ad6982c44c996df279748 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 18 Nov 2025 13:30:58 +1100 Subject: [PATCH 126/288] Try with specific heat capacity not hard coded --- src/diagnostics/MOM_diagnostics.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index c8049a1f04..0b37105759 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1628,7 +1628,7 @@ end subroutine post_surface_thermo_diags !> This routine posts diagnostics of the transports, including the subgridscale !! contributions. subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dyn, & - diag, dt_trans, Reg) + diag, dt_trans, Reg, tv) type(ocean_grid_type), intent(inout) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type @@ -1643,6 +1643,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy type(diag_ctrl), intent(inout) :: diag !< regulates diagnostic output real, intent(in) :: dt_trans !< total time step associated with the transports [T ~> s]. type(tracer_registry_type), pointer :: Reg !< Pointer to the tracer registry + type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various thermodynamic variables ! Local variables real, dimension(SZIB_(G),SZJ_(G)) :: umo2d ! Diagnostics of integrated mass transport [R Z L2 T-1 ~> kg s-1] @@ -1718,7 +1719,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy Tr => Reg%Tr(m) if (Tr%id_numerical_mixing > 0) then if (Tr%name == "T") then - scale_constant = 3991.86795711963 !< hard coded (for now) specific heat capacity + scale_constant = tv%C_p ! 3991.86795711963 !< hard coded (for now) specific heat capacity elseif (Tr%name == "S") then scale_constant = 1000 !< g -> kg else @@ -1727,7 +1728,6 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy x_upwind(:, :, :) = 0. y_upwind(:, :, :) = 0. nm(:,:,:) = 0. - ! vf(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & scale_constant, x_upwind, y_upwind, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) From bb47f71b24d5f04fa2927866114199068fe192ea Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 18 Nov 2025 13:34:24 +1100 Subject: [PATCH 127/288] need to rethink how to access tvs --- src/diagnostics/MOM_diagnostics.F90 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 0b37105759..70b00ecf8a 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1628,7 +1628,7 @@ end subroutine post_surface_thermo_diags !> This routine posts diagnostics of the transports, including the subgridscale !! contributions. subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dyn, & - diag, dt_trans, Reg, tv) + diag, dt_trans, Reg) type(ocean_grid_type), intent(inout) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type @@ -1643,7 +1643,6 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy type(diag_ctrl), intent(inout) :: diag !< regulates diagnostic output real, intent(in) :: dt_trans !< total time step associated with the transports [T ~> s]. type(tracer_registry_type), pointer :: Reg !< Pointer to the tracer registry - type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various thermodynamic variables ! Local variables real, dimension(SZIB_(G),SZJ_(G)) :: umo2d ! Diagnostics of integrated mass transport [R Z L2 T-1 ~> kg s-1] From d5329217585f22306b4d3ebe91380fae3fda54b7 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 18 Nov 2025 13:36:05 +1100 Subject: [PATCH 128/288] Missed reference to variable --- src/diagnostics/MOM_diagnostics.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 70b00ecf8a..00f00fe9ba 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1718,7 +1718,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy Tr => Reg%Tr(m) if (Tr%id_numerical_mixing > 0) then if (Tr%name == "T") then - scale_constant = tv%C_p ! 3991.86795711963 !< hard coded (for now) specific heat capacity + scale_constant = 3991.86795711963 !< hard coded (for now) specific heat capacity elseif (Tr%name == "S") then scale_constant = 1000 !< g -> kg else From f6c39b1b7a409f7f185a44a3672669da79c513f1 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 24 Nov 2025 11:50:13 +1100 Subject: [PATCH 129/288] Correct array indexing and loop iterating style --- src/diagnostics/MOM_numerical_mixing.F90 | 153 +++++++++++------------ 1 file changed, 74 insertions(+), 79 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 0a78176118..0022b53f8a 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -14,23 +14,22 @@ module MOM_numerical_mixing contains -!< Calculate the suprious ``numerical'' mixing of tracer Tr due to advection. +!< Calculate the spurious ``numerical'' mixing of tracer Tr due to advection. subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) - implicit none - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: h(:, :, :) !< Thickness - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt !< Model timestep - real, intent(in) :: Idt !< Inverse model timestep - real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport - real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport - real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values for tracer - real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values for tracer - real, intent(inout) :: nm(:, :, :) !< Numerical mixing diagnostic + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: h(:,:,:) !< Thickness + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt !< Model timestep + real, intent(in) :: Idt !< Inverse model timestep + real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport + real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional transport + real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer + real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic !< Local variables real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct @@ -49,16 +48,15 @@ end subroutine numerical_mixing !< Subroutine for only the variance advection, likely will remove once numerical mixing is sorted out subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, scale_constant, va) - implicit none - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: h(:, :, :) !< Thickness - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt !< Model timestep - real, intent(in) :: Idt !< Inverse model timestep - real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(inout) :: va(:, :, :) !< Variance advection + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: h(:,:,:) !< Thickness + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt !< Model timestep + real, intent(in) :: Idt !< Inverse model timestep + real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T + real, intent(inout) :: va(:,:,:) !< Variance advection !< Local variables real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct @@ -73,17 +71,16 @@ end subroutine variance_advection !< Subroutine for only the variance flux, likely will remove once numerical mixing is sorted out subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) - implicit none - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Idt !< Inverse model timestep - real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport - real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport - real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values for tracer - real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values for tracer - real, intent(inout) :: vf(:, :, :) !< Variance fluxes + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Idt !< Inverse model timestep + real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport + real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional transport + real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer + real, intent(inout) :: vf(:,:,:) !< Variance fluxes !< Local variables real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct @@ -101,16 +98,15 @@ end subroutine variance_flux !< Subroutine to calculate the thickness weighted variance change over a timestep subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, res) - implicit none type(tracer_type), intent(in) :: Tr !< Tracer real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: h(:, :, :) !< Thickness + real, intent(in) :: h(:,:,:) !< Thickness type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt !< Model timestep real, intent(in) :: Idt !< Inverse model timestep type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: res(:, :, :) !< Array to store result in + real, intent(inout) :: res(:,:,:) !< Array to store result in !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -120,15 +116,15 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - do k = 1, nz ; do j = js, je ; do i = is, ie - h_prev = diag_pre_dyn%h_state(i, j, k) + do k=1,nz ; do j=js,je ; do i=is,ie + h_prev = diag_pre_dyn%h_state(i,j,k) ! hadv = h_prev + dt * (h_tend) ! = h_prev + dt * (Idt * (h(i, j, k) - h_prev)) ! = h(i, j, k) hadv = h(i, j, k) - C_prev = Tr%t_prev(i, j, k) - Cadv = h_prev * C_prev + dt * (Tr%advection_xy(i, j, k) / Tr_adv_scale) - res(i, j, k) = ( (Cadv**2 / hadv) - (h_prev * C_prev**2) ) * Idt + C_prev = Tr%t_prev(i,j,k) + Cadv = h_prev * C_prev + dt * (Tr%advection_xy(i,j,k) / Tr_adv_scale) + res(i,j,k) = ( (Cadv**2 / hadv) - (h_prev * C_prev**2) ) * Idt enddo ; enddo ; enddo end subroutine thickness_weighted_variance_change @@ -136,15 +132,14 @@ end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, res) - implicit none type(tracer_type), intent(in) :: Tr !< Tracer real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: uhtr(:, :, :) !< Accumulated zonal transport + real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport real, intent(in) :: mass_transport_scale !< Scaling for mass transport type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind value for tracer - real, intent(inout) :: res(:, :, :) !< Array to store the result in + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind value for tracer + real, intent(inout) :: res(:,:,:) !< Array to store the result in !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -161,10 +156,10 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) - do k = 1, nz ; do j = js, je ; do i = is, ie - east = 2 * (Tr%ad_x(I, j, k) / Tr_adv_scale) * x_upwind(I, j, k) -u_trans(I, j, k) * x_upwind(I, j, k)**2 - west = 2 * (Tr%ad_x(I-1, j, k) / Tr_adv_scale) * x_upwind(I-1, j, k) - u_trans(I-1, j, k) * x_upwind(I-1, j, k)**2 - res(i, j, k) = res(i, j, k) + ((east - west) * G%IareaT(i, j)) + do k=1,nz ; do j=js,je ; do i=is,ie + east = 2 * (Tr%ad_x(I,j,k) / Tr_adv_scale) * x_upwind(I,j,k) - u_trans(I,j,k) * x_upwind(I,j,k)**2 + west = 2 * (Tr%ad_x(I-1,j,k) / Tr_adv_scale) * x_upwind(I-1,j,k) - u_trans(I-1,j,k) * x_upwind(I-1,j,k)**2 + res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo end subroutine zonal_upwind_fluxes @@ -173,11 +168,11 @@ end subroutine zonal_upwind_fluxes subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(in) :: u_trans(:, :, :) !< Zonal transport - real, intent(inout) :: x_upwind(:, :, :) !< Zonal upwind values of C calculated using u_trans + type(tracer_type), intent(in) :: Tr !< Tracer + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(in) :: u_trans(:,:,:) !< Zonal transport + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values of C calculated using u_trans !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes @@ -185,11 +180,11 @@ subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) Is = G%IscB ; Ie = G%IecB ; js = G%jsc ; je = G%jec - do k = 1, nz ; do j = js, je ; do I = Is, Ie - if (u_trans(I, j, k) >= 0) then - x_upwind(I, j, k) = Tr%t(i, j, k) - elseif (u_trans(I, j, k) < 0) then - x_upwind(I, j, k) = Tr%t(i+1, j, k) + do k=1,nz ; do j=js,je ; do I=Is,Ie + if (u_trans(I,j,k) >= 0) then + x_upwind(I,j,k) = Tr%t(i,j,k) + elseif (u_trans(I,j,k) < 0) then + x_upwind(I,j,k) = Tr%t(i+1,j,k) endif enddo ; enddo ; enddo @@ -201,12 +196,12 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale implicit none type(tracer_type), intent(in) :: Tr !< Tracer real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: vhtr(:, :, :) !< Accumulated meridional transport + real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional transport real, intent(in) :: mass_transport_scale !< Scaling for mass transport type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind tracer values - real, intent(inout) :: res(:, :, :) !< Array to store the result in + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind tracer values + real, intent(inout) :: res(:,:,:) !< Array to store the result in !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -223,10 +218,10 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) - do k = 1, nz ; do j = js, je ; do i = is, ie - north = 2 * (Tr%ad_y(i, J, k) / Tr_adv_scale) * y_upwind(i, J, k) - v_trans(i, J, k) * y_upwind(i, J, k)**2 - south = 2 * (Tr%ad_y(i, J-1, k) / Tr_adv_scale) * y_upwind(i, J-1, k) - v_trans(i, J-1, k) * y_upwind(i, J-1, k)**2 - res(i, j, k) = res(i, j, k) + ((north - south) * G%IareaT(i, j)) + do k=1,nz ; do j=js,je ; do i=is,ie + north = 2 * (Tr%ad_y(i,J,k) / Tr_adv_scale) * y_upwind(i,J,k) - v_trans(i,J,k) * y_upwind(i,J,k)**2 + south = 2 * (Tr%ad_y(i,J-1,k) / Tr_adv_scale) * y_upwind(i,J-1,k) - v_trans(i,J-1,k) * y_upwind(i,J-1,k)**2 + res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo end subroutine meridional_upwind_fluxes @@ -235,11 +230,11 @@ end subroutine meridional_upwind_fluxes subroutine meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(in) :: v_trans(:, :, :) !< Meridional transport - real, intent(inout) :: y_upwind(:, :, :) !< Meridional upwind values of C calculated using v_trans + type(tracer_type), intent(in) :: Tr !< Tracer + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(in) :: v_trans(:,:,:) !< Meridional transport + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values of C calculated using v_trans !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes @@ -247,11 +242,11 @@ subroutine meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) is = G%isc ; ie = G%iec ; Js = G%JscB ; Je = G%JecB - do k = 1, nz ; do J = Js, Je ; do i = is, ie - if (v_trans(i, J, k) >= 0) then - y_upwind(i, J, k) = Tr%t(i, j, k) - elseif (v_trans(i, J, k) < 0) then - y_upwind(i, J, k) = Tr%t(i, j+1, k) + do k=1,nz ; do J=Js,Je ; do i=is,ie + if (v_trans(i,J,k) >= 0) then + y_upwind(i,J,k) = Tr%t(i,j,k) + elseif (v_trans(i,J,k) < 0) then + y_upwind(i,J,k) = Tr%t(i,j+1,k) endif enddo ; enddo ; enddo From 7e060a2e11a3b56f0812a1d512ee419effb86903 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 24 Nov 2025 11:56:58 +1100 Subject: [PATCH 130/288] Use inverse tracer scaling and multiply rather than divison --- src/diagnostics/MOM_numerical_mixing.F90 | 65 ++++++++++++------------ 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 0022b53f8a..1f45d88113 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -32,16 +32,17 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic !< Local variables - real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct + real :: ITR_adv_scale !< Scaling required for advection terms to ensure dimensions are correct !< e.g. for temperature need to divide by specific heat capacity * rho_ref + !< This is an inverse quantity to avoid division. real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. - Tr_adv_scale = scale_constant * GV%Rho0 + ITR_adv_scale = 1 / (scale_constant * GV%Rho0) mass_transport_scale = (Idt * GV%H_to_RZ) / GV%Rho0 - call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) - call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) - call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) + call thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) + call zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) + call meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) end subroutine numerical_mixing @@ -59,12 +60,12 @@ subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, scale_constan real, intent(inout) :: va(:,:,:) !< Variance advection !< Local variables - real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct + real :: ITR_adv_scale !< Scaling required for advection terms to ensure dimensions are correct !< e.g. for temperature need to divide by specific heat capacity * rho_ref - Tr_adv_scale = scale_constant * GV%Rho0 + ITR_adv_scale = 1 / (scale_constant * GV%Rho0) - call thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, va) + call thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, va) end subroutine variance_advection @@ -83,30 +84,30 @@ subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, scale_constant, x_upwind, y real, intent(inout) :: vf(:,:,:) !< Variance fluxes !< Local variables - real :: Tr_adv_scale !< Scaling required for advection terms to ensure dimensions are correct + real :: ITR_adv_scale !< Scaling required for advection terms to ensure dimensions are correct !< e.g. for temperature need to divide by specific heat capacity * rho_ref real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. - Tr_adv_scale = scale_constant * GV%Rho0 + ITR_adv_scale = 1 / (scale_constant * GV%Rho0) mass_transport_scale = (Idt * GV%H_to_RZ) / GV%Rho0 - call zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, vf) - call meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, vf) + call zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, vf) + call meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, vf) end subroutine variance_flux !< Subroutine to calculate the thickness weighted variance change over a timestep -subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, res) - - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection - real, intent(in) :: h(:,:,:) !< Thickness - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt !< Model timestep - real, intent(in) :: Idt !< Inverse model timestep - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: res(:,:,:) !< Array to store result in +subroutine thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, res) + + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: ITR_adv_scale !< Scaling for tracer advection + real, intent(in) :: h(:,:,:) !< Thickness + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt !< Model timestep + real, intent(in) :: Idt !< Inverse model timestep + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: res(:,:,:) !< Array to store result in !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -123,17 +124,17 @@ subroutine thickness_weighted_variance_change(Tr, Tr_adv_scale, h, diag_pre_dyn, ! = h(i, j, k) hadv = h(i, j, k) C_prev = Tr%t_prev(i,j,k) - Cadv = h_prev * C_prev + dt * (Tr%advection_xy(i,j,k) / Tr_adv_scale) + Cadv = h_prev * C_prev + dt * (Tr%advection_xy(i,j,k) * ITR_adv_scale) res(i,j,k) = ( (Cadv**2 / hadv) - (h_prev * C_prev**2) ) * Idt enddo ; enddo ; enddo end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, res) +subroutine zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, res) type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: ITR_adv_scale !< Scaling for tracer advection real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport real, intent(in) :: mass_transport_scale !< Scaling for mass transport type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area @@ -157,8 +158,8 @@ subroutine zonal_upwind_fluxes(Tr, Tr_adv_scale, uhtr, mass_transport_scale, G, call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - east = 2 * (Tr%ad_x(I,j,k) / Tr_adv_scale) * x_upwind(I,j,k) - u_trans(I,j,k) * x_upwind(I,j,k)**2 - west = 2 * (Tr%ad_x(I-1,j,k) / Tr_adv_scale) * x_upwind(I-1,j,k) - u_trans(I-1,j,k) * x_upwind(I-1,j,k)**2 + east = 2 * (Tr%ad_x(I,j,k) * ITR_adv_scale) * x_upwind(I,j,k) - u_trans(I,j,k) * x_upwind(I,j,k)**2 + west = 2 * (Tr%ad_x(I-1,j,k) * ITR_adv_scale) * x_upwind(I-1,j,k) - u_trans(I-1,j,k) * x_upwind(I-1,j,k)**2 res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo @@ -191,11 +192,11 @@ subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) end subroutine zonal_upwind_values !< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, res) +subroutine meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, res) implicit none type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Tr_adv_scale !< Scaling for tracer advection + real, intent(in) :: ITR_adv_scale !< Scaling for tracer advection real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional transport real, intent(in) :: mass_transport_scale !< Scaling for mass transport type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area @@ -219,8 +220,8 @@ subroutine meridional_upwind_fluxes(Tr, Tr_adv_scale, vhtr, mass_transport_scale call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - north = 2 * (Tr%ad_y(i,J,k) / Tr_adv_scale) * y_upwind(i,J,k) - v_trans(i,J,k) * y_upwind(i,J,k)**2 - south = 2 * (Tr%ad_y(i,J-1,k) / Tr_adv_scale) * y_upwind(i,J-1,k) - v_trans(i,J-1,k) * y_upwind(i,J-1,k)**2 + north = 2 * (Tr%ad_y(i,J,k) * ITR_adv_scale) * y_upwind(i,J,k) - v_trans(i,J,k) * y_upwind(i,J,k)**2 + south = 2 * (Tr%ad_y(i,J-1,k) * ITR_adv_scale) * y_upwind(i,J-1,k) - v_trans(i,J-1,k) * y_upwind(i,J-1,k)**2 res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo From 901660144580fe205ae5cee377c3fda6a4b3d5f3 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 24 Nov 2025 12:06:12 +1100 Subject: [PATCH 131/288] align comment --- src/diagnostics/MOM_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 index 1f45d88113..56a86ce282 100644 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ b/src/diagnostics/MOM_numerical_mixing.F90 @@ -84,7 +84,7 @@ subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, scale_constant, x_upwind, y real, intent(inout) :: vf(:,:,:) !< Variance fluxes !< Local variables - real :: ITR_adv_scale !< Scaling required for advection terms to ensure dimensions are correct + real :: ITR_adv_scale !< Scaling required for advection terms to ensure dimensions are correct !< e.g. for temperature need to divide by specific heat capacity * rho_ref real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. From 85be956d24042e9c0214fa7db0ce810f10c40ebb Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 27 Nov 2025 16:17:04 +1100 Subject: [PATCH 132/288] Move diagnostic to tracer directory --- src/CMakeLists.txt | 2 +- src/diagnostics/MOM_diagnostics.F90 | 82 +++---- src/tracer/MOM_tracer_numerical_mixing.F90 | 256 +++++++++++++++++++++ src/tracer/MOM_tracer_registry.F90 | 56 ++++- 4 files changed, 347 insertions(+), 49 deletions(-) create mode 100644 src/tracer/MOM_tracer_numerical_mixing.F90 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3a5c718600..ccfc5f4a7e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -92,7 +92,6 @@ target_sources(mom6shared PRIVATE diagnostics/MOM_diagnose_MLD.F90 diagnostics/MOM_diagnostics.F90 diagnostics/MOM_harmonic_analysis.F90 - diagnostics/MOM_numerical_mixing.F90 diagnostics/MOM_obsolete_diagnostics.F90 diagnostics/MOM_obsolete_params.F90 diagnostics/MOM_PointAccel.F90 @@ -275,6 +274,7 @@ target_sources(mom6shared PRIVATE tracer/MOM_tracer_diabatic.F90 tracer/MOM_tracer_flow_control.F90 tracer/MOM_tracer_hor_diff.F90 + tracer/MOM_tracer_numerical_mixing.F90 tracer/MOM_tracer_registry.F90 tracer/MOM_tracer_types.F90 tracer/MOM_tracer_Z_init.F90 diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 00f00fe9ba..13f29554d3 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -35,7 +35,6 @@ module MOM_diagnostics use MOM_variables, only : accel_diag_ptrs, cont_diag_ptrs, surface use MOM_verticalGrid, only : verticalGrid_type, get_thickness_units, get_flux_units use MOM_wave_speed, only : wave_speed, wave_speed_CS, wave_speed_init -use MOM_numerical_mixing, only : numerical_mixing, variance_advection, variance_flux implicit none ; private @@ -1645,22 +1644,9 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy type(tracer_registry_type), pointer :: Reg !< Pointer to the tracer registry ! Local variables - real, dimension(SZIB_(G),SZJ_(G)) :: umo2d ! Diagnostics of integrated mass transport [R Z L2 T-1 ~> kg s-1] - real, dimension(SZI_(G),SZJB_(G)) :: vmo2d ! Diagnostics of integrated mass transport [R Z L2 T-1 ~> kg s-1] - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: umo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics - ! [H T-1 ~> m s-1 or kg m-2 s-1]. - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Variance advection (remove after nm sorted) - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Flux of variance (remove after nm sorted) real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. - type(tracer_type), pointer :: Tr !< Tracer type for numerical mixing - real :: scale_constant !< Scale for numerical mixing e.g. specific heat capacity integer :: i, j, k, is, ie, js, je, nz, m is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke @@ -1712,39 +1698,41 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy call post_data(IDs%id_dynamics_h_tendency, h_tend, diag, alt_h=diag_pre_dyn%h_state) endif - call post_tracer_transport_diagnostics(G, GV, Reg, diag_pre_dyn%h_state, diag) - - do m=1,Reg%ntr ; if (Reg%Tr(m)%registry_diags) then - Tr => Reg%Tr(m) - if (Tr%id_numerical_mixing > 0) then - if (Tr%name == "T") then - scale_constant = 3991.86795711963 !< hard coded (for now) specific heat capacity - elseif (Tr%name == "S") then - scale_constant = 1000 !< g -> kg - else - scale_constant = 1 !< any other tracer is unscaled - endif - x_upwind(:, :, :) = 0. - y_upwind(:, :, :) = 0. - nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & - scale_constant, x_upwind, y_upwind, nm) - call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) - if (Tr%id_variance_advection > 0) then - va(:,:,:) = 0. - call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, scale_constant, va) - call post_data(Tr%id_variance_advection, va, diag, alt_h=diag_pre_dyn%h_state) - endif - if (Tr%id_variance_flux > 0) then - !< Overkill to caclulate these again but I plan on removing once numerical mixing is sorted - x_upwind(:, :, :) = 0. - y_upwind(:, :, :) = 0. - vf(:,:,:) = 0. - call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) - call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) - endif - endif - endif; enddo + call post_tracer_transport_diagnostics(G, GV, Reg, diag_pre_dyn%h_state, diag_pre_dyn, & + diag, dt_trans, Idt, uhtr, vhtr) + + ! Once everything builds and works as it was previously did remove this section + ! do m=1,Reg%ntr ; if (Reg%Tr(m)%registry_diags) then + ! Tr => Reg%Tr(m) + ! if (Tr%id_numerical_mixing > 0) then + ! if (Tr%name == "T") then + ! scale_constant = 3991.86795711963 !< hard coded (for now) specific heat capacity + ! elseif (Tr%name == "S") then + ! scale_constant = 1000 !< g -> kg + ! else + ! scale_constant = 1 !< any other tracer is unscaled + ! endif + ! x_upwind(:, :, :) = 0. + ! y_upwind(:, :, :) = 0. + ! nm(:,:,:) = 0. + ! call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & + ! scale_constant, x_upwind, y_upwind, nm) + ! call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) + ! if (Tr%id_variance_advection > 0) then + ! va(:,:,:) = 0. + ! call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, scale_constant, va) + ! call post_data(Tr%id_variance_advection, va, diag, alt_h=diag_pre_dyn%h_state) + ! endif + ! if (Tr%id_variance_flux > 0) then + ! !< Overkill to caclulate these again but I plan on removing once numerical mixing is sorted + ! x_upwind(:, :, :) = 0. + ! y_upwind(:, :, :) = 0. + ! vf(:,:,:) = 0. + ! call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) + ! call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) + ! endif + ! endif + ! endif; enddo call diag_restore_grids(diag) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 new file mode 100644 index 0000000000..6eb1a58a72 --- /dev/null +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -0,0 +1,256 @@ +!> Functions and routines involved in calculating numerical mixing of tracers due to advection +module MOM_tracer_numerical_mixing + +use MOM_diag_mediator, only : diag_ctrl, diag_grid_storage +use MOM_grid, only : ocean_grid_type +use MOM_tracer_types, only : tracer_type +use MOM_verticalGrid, only : verticalGrid_type + +implicit none ; private + +#include + +public numerical_mixing, variance_advection, variance_flux + +contains + +!< Calculate the spurious ``numerical'' mixing of tracer Tr due to advection. +subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) + + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: h(:,:,:) !< Thickness + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt !< Model timestep + real, intent(in) :: Idt !< Inverse model timestep + real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport + real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional transport + real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer + real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic + + !< Local variables + real :: ITR_adv_scale !< Scaling required for advection terms to ensure dimensions are correct + !< e.g. for temperature need to divide by specific heat capacity * rho_ref + !< This is an inverse quantity to avoid division. + real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. + + ITR_adv_scale = 1 / (scale_constant * GV%Rho0) + mass_transport_scale = (Idt * GV%H_to_RZ) / GV%Rho0 + + call thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) + call zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) + call meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) + +end subroutine numerical_mixing + +!< Subroutine for only the variance advection, likely will remove once numerical mixing is sorted out +subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, scale_constant, va) + + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: h(:,:,:) !< Thickness + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt !< Model timestep + real, intent(in) :: Idt !< Inverse model timestep + real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T + real, intent(inout) :: va(:,:,:) !< Variance advection + + !< Local variables + real :: ITR_adv_scale !< Scaling required for advection terms to ensure dimensions are correct + !< e.g. for temperature need to divide by specific heat capacity * rho_ref + + ITR_adv_scale = 1 / (scale_constant * GV%Rho0) + + call thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, va) + +end subroutine variance_advection + +!< Subroutine for only the variance flux, likely will remove once numerical mixing is sorted out +subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) + + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: Idt !< Inverse model timestep + real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport + real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional transport + real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer + real, intent(inout) :: vf(:,:,:) !< Variance fluxes + + !< Local variables + real :: ITR_adv_scale !< Scaling required for advection terms to ensure dimensions are correct + !< e.g. for temperature need to divide by specific heat capacity * rho_ref + real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. + + ITR_adv_scale = 1 / (scale_constant * GV%Rho0) + mass_transport_scale = (Idt * GV%H_to_RZ) / GV%Rho0 + + call zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, vf) + call meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, vf) + +end subroutine variance_flux + +!< Subroutine to calculate the thickness weighted variance change over a timestep +subroutine thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, res) + + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: ITR_adv_scale !< Scaling for tracer advection + real, intent(in) :: h(:,:,:) !< Thickness + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt !< Model timestep + real, intent(in) :: Idt !< Inverse model timestep + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: res(:,:,:) !< Array to store result in + + !< Local variables + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: h_prev, C_prev, hadv, Cadv !< Thickness and tracer at previous timestep and the + !< changes in thickness and tracer after advection. + + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke + + do k=1,nz ; do j=js,je ; do i=is,ie + h_prev = diag_pre_dyn%h_state(i,j,k) + ! hadv = h_prev + dt * (h_tend) + ! = h_prev + dt * (Idt * (h(i, j, k) - h_prev)) + ! = h(i, j, k) + hadv = h(i, j, k) + C_prev = Tr%t_prev(i,j,k) + Cadv = h_prev * C_prev + dt * (Tr%advection_xy(i,j,k) * ITR_adv_scale) + res(i,j,k) = ( (Cadv**2 / hadv) - (h_prev * C_prev**2) ) * Idt + enddo ; enddo ; enddo + +end subroutine thickness_weighted_variance_change + +!< Subroutine to calculate the zonal upwind fluxes +subroutine zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, res) + + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: ITR_adv_scale !< Scaling for tracer advection + real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport + real, intent(in) :: mass_transport_scale !< Scaling for mass transport + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind value for tracer + real, intent(inout) :: res(:,:,:) !< Array to store the result in + + !< Local variables + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: east, west !< East and West positions for zonal derivative + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: u_trans !< Zonal transport + + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke + + u_trans(:, :, :) = 0. + do k=1,nz ; do j=js,je ; do I=is-1,ie + u_trans(I,j,k) = uhtr(I,j,k) * mass_transport_scale + enddo ; enddo ; enddo + + call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) + + do k=1,nz ; do j=js,je ; do i=is,ie + east = 2 * (Tr%ad_x(I,j,k) * ITR_adv_scale) * x_upwind(I,j,k) - u_trans(I,j,k) * x_upwind(I,j,k)**2 + west = 2 * (Tr%ad_x(I-1,j,k) * ITR_adv_scale) * x_upwind(I-1,j,k) - u_trans(I-1,j,k) * x_upwind(I-1,j,k)**2 + res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) + enddo ; enddo; enddo + +end subroutine zonal_upwind_fluxes + +!< Subroutine to calculate upwind values in zonal direction +subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) + + implicit none + type(tracer_type), intent(in) :: Tr !< Tracer + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(in) :: u_trans(:,:,:) !< Zonal transport + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values of C calculated using u_trans + + !< Local variables + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + + Is = G%IscB ; Ie = G%IecB ; js = G%jsc ; je = G%jec + + do k=1,nz ; do j=js,je ; do I=Is,Ie + if (u_trans(I,j,k) >= 0) then + x_upwind(I,j,k) = Tr%t(i,j,k) + elseif (u_trans(I,j,k) < 0) then + x_upwind(I,j,k) = Tr%t(i+1,j,k) + endif + enddo ; enddo ; enddo + +end subroutine zonal_upwind_values + +!< Subroutine to calculate the meriodional upwind flues +subroutine meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, res) + + implicit none + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: ITR_adv_scale !< Scaling for tracer advection + real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional transport + real, intent(in) :: mass_transport_scale !< Scaling for mass transport + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind tracer values + real, intent(inout) :: res(:,:,:) !< Array to store the result in + + !< Local variables + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: north, south !< North and South positions for meridional derivative + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: v_trans !< Meridional transport + + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke + + v_trans(:, :, :) = 0. + do k=1,nz ; do J=js-1,je ; do i=is,ie + v_trans(i,J,k) = vhtr(i,J,k) * mass_transport_scale + enddo ; enddo ; enddo + + call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) + + do k=1,nz ; do j=js,je ; do i=is,ie + north = 2 * (Tr%ad_y(i,J,k) * ITR_adv_scale) * y_upwind(i,J,k) - v_trans(i,J,k) * y_upwind(i,J,k)**2 + south = 2 * (Tr%ad_y(i,J-1,k) * ITR_adv_scale) * y_upwind(i,J-1,k) - v_trans(i,J-1,k) * y_upwind(i,J-1,k)**2 + res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) + enddo ; enddo ; enddo + +end subroutine meridional_upwind_fluxes + +!< Subroutine to calculate upwind value in the meridional direction +subroutine meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) + + implicit none + type(tracer_type), intent(in) :: Tr !< Tracer + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area + integer, intent(in) :: nz !< Grid cell layer indexes + real, intent(in) :: v_trans(:,:,:) !< Meridional transport + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values of C calculated using v_trans + + !< Local variables + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + + is = G%isc ; ie = G%iec ; Js = G%JscB ; Je = G%JecB + + do k=1,nz ; do J=Js,Je ; do i=is,ie + if (v_trans(i,J,k) >= 0) then + y_upwind(i,J,k) = Tr%t(i,j,k) + elseif (v_trans(i,J,k) < 0) then + y_upwind(i,J,k) = Tr%t(i,j+1,k) + endif + enddo ; enddo ; enddo + +end subroutine meridional_upwind_values + +end module MOM_tracer_numerical_mixing diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index f723cd7f0e..770838bd24 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -25,6 +25,7 @@ module MOM_tracer_registry use MOM_unit_scaling, only : unit_scale_type use MOM_verticalGrid, only : verticalGrid_type use MOM_tracer_types, only : tracer_type, tracer_registry_type +use MOM_tracer_numerical_mixing, only : numerical_mixing, variance_advection, variance_flux implicit none ; private @@ -766,13 +767,22 @@ subroutine post_tracer_diagnostics_at_sync(Reg, h, diag_prev, diag, G, GV, dt) end subroutine post_tracer_diagnostics_at_sync !> Post the advective and diffusive tendencies -subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag) +subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, diag, uhtr, vhtr, dt_trans, Idt) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(tracer_registry_type), pointer :: Reg !< pointer to the tracer registry real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: h_diag !< Layer thicknesses on which to post fields [H ~> m or kg m-2] + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics type(diag_ctrl), intent(in) :: diag !< structure to regulate diagnostic output + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), & + intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), & + intent(in) :: vhtr !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(in) :: dt_trans ! The transport time interval [T ~> s] + real, intent(in) :: Idt ! The inverse of the time interval [T-1 ~> s-1] integer :: i, j, k, is, ie, js, je, nz, m, khi real :: work2d(SZI_(G),SZJ_(G)) ! The vertically integrated convergence of lateral advective @@ -780,9 +790,21 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag) real :: frac_under_100m(SZI_(G),SZJ_(G),SZK_(GV)) ! weights used to compute 100m vertical integrals [nondim] real :: ztop(SZI_(G),SZJ_(G)) ! position of the top interface [H ~> m or kg m-2] real :: zbot(SZI_(G),SZJ_(G)) ! position of the bottom interface [H ~> m or kg m-2] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer [CU2 H T-1 ~> conc2 m s-1] + ! va and vf will be removed but are needed in the debugging process + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Variance advection [CU2 H T-1 ~> conc2 m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Flux of variance [CU2 H T-1 ~> conc2 m s-1] + real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes + ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. + real :: scale_constant !< Scale for numerical mixing e.g. specific heat capacity. + !! The dimensions are dependent on the tracer so they are specified + !! where the value is defined. type(tracer_type), pointer :: Tr=>NULL() is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke + H_to_RZ_dt = GV%H_to_RZ * Idt ! If any tracers are posting 100m vertical integrals, compute weights frac_under_100m(:,:,:) = 0.0 @@ -833,6 +855,38 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag) call post_data(Tr%id_adv_xy_2d, work2d, diag) endif + if (Tr%id_numerical_mixing > 0) then + if (Tr%name == "T") then + scale_constant = 3991.86795711963 !< specific heat capacity [Q C-1 ~> J degC-1 kg-1] + ! elseif (Tr%name == "S") then + ! scale_constant = 1000 !< I am not sure about this conversion when S is practical salintiy + !< need to check with Jan what he had.. + ! else + ! scale_constant = 1 !< any other tracer is unscaled + endif + x_upwind(:,:,:) = 0. + y_upwind(:,:,:) = 0. + nm(:,:,:) = 0. + call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & + scale_constant, x_upwind, y_upwind, nm) + call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) + + !< The below is here while debuggin; to be removed once numerical mixing is all sorted + if (Tr%id_variance_advection > 0) then + va(:,:,:) = 0. + call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, scale_constant, va) + call post_data(Tr%id_variance_advection, va, diag, alt_h=diag_pre_dyn%h_state) + endif + if (Tr%id_variance_flux > 0) then + !< Overkill to caclulate these again but I plan on removing once numerical mixing is sorted + x_upwind(:,:,:) = 0. + y_upwind(:,:,:) = 0. + vf(:,:,:) = 0. + call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) + call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) + endif + endif + ! A few diagnostics introduce with MARBL driver ! Compute full-depth vertical integral if (Tr%id_zint > 0) then From e58f17d02a1459e3deb8ba75ee6f20dfa130521d Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 27 Nov 2025 16:27:34 +1100 Subject: [PATCH 133/288] Forgot to include a variable --- src/diagnostics/MOM_diagnostics.F90 | 2 +- src/tracer/MOM_tracer_registry.F90 | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 13f29554d3..1eebc18ce0 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1699,7 +1699,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy endif call post_tracer_transport_diagnostics(G, GV, Reg, diag_pre_dyn%h_state, diag_pre_dyn, & - diag, dt_trans, Idt, uhtr, vhtr) + diag, uhtr, vhtr, h, dt_trans, Idt) ! Once everything builds and works as it was previously did remove this section ! do m=1,Reg%ntr ; if (Reg%Tr(m)%registry_diags) then diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 770838bd24..41e07f7399 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -767,7 +767,7 @@ subroutine post_tracer_diagnostics_at_sync(Reg, h, diag_prev, diag, G, GV, dt) end subroutine post_tracer_diagnostics_at_sync !> Post the advective and diffusive tendencies -subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, diag, uhtr, vhtr, dt_trans, Idt) +subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, diag, uhtr, vhtr, h, dt_trans, Idt) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(tracer_registry_type), pointer :: Reg !< pointer to the tracer registry @@ -781,6 +781,8 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), & intent(in) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & + intent(in) :: h !< The updated layer thicknesses [H ~> m or kg m-2] real, intent(in) :: dt_trans ! The transport time interval [T ~> s] real, intent(in) :: Idt ! The inverse of the time interval [T-1 ~> s-1] From 87efd4f23050fdb377af8791c182c0a25a92a437 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 27 Nov 2025 16:31:04 +1100 Subject: [PATCH 134/288] Remove old file --- src/diagnostics/MOM_numerical_mixing.F90 | 256 ----------------------- 1 file changed, 256 deletions(-) delete mode 100644 src/diagnostics/MOM_numerical_mixing.F90 diff --git a/src/diagnostics/MOM_numerical_mixing.F90 b/src/diagnostics/MOM_numerical_mixing.F90 deleted file mode 100644 index 56a86ce282..0000000000 --- a/src/diagnostics/MOM_numerical_mixing.F90 +++ /dev/null @@ -1,256 +0,0 @@ -!> Functions and routines involved in calculating numerical mixing of tracers due to advection -module MOM_numerical_mixing - -use MOM_diag_mediator, only : diag_ctrl, diag_grid_storage -use MOM_grid, only : ocean_grid_type -use MOM_tracer_types, only : tracer_type -use MOM_verticalGrid, only : verticalGrid_type - -implicit none ; private - -#include - -public numerical_mixing, variance_advection, variance_flux - -contains - -!< Calculate the spurious ``numerical'' mixing of tracer Tr due to advection. -subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) - - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: h(:,:,:) !< Thickness - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt !< Model timestep - real, intent(in) :: Idt !< Inverse model timestep - real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport - real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional transport - real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer - real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic - - !< Local variables - real :: ITR_adv_scale !< Scaling required for advection terms to ensure dimensions are correct - !< e.g. for temperature need to divide by specific heat capacity * rho_ref - !< This is an inverse quantity to avoid division. - real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. - - ITR_adv_scale = 1 / (scale_constant * GV%Rho0) - mass_transport_scale = (Idt * GV%H_to_RZ) / GV%Rho0 - - call thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) - call zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) - call meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) - -end subroutine numerical_mixing - -!< Subroutine for only the variance advection, likely will remove once numerical mixing is sorted out -subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, scale_constant, va) - - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: h(:,:,:) !< Thickness - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt !< Model timestep - real, intent(in) :: Idt !< Inverse model timestep - real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(inout) :: va(:,:,:) !< Variance advection - - !< Local variables - real :: ITR_adv_scale !< Scaling required for advection terms to ensure dimensions are correct - !< e.g. for temperature need to divide by specific heat capacity * rho_ref - - ITR_adv_scale = 1 / (scale_constant * GV%Rho0) - - call thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, va) - -end subroutine variance_advection - -!< Subroutine for only the variance flux, likely will remove once numerical mixing is sorted out -subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) - - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Idt !< Inverse model timestep - real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport - real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional transport - real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer - real, intent(inout) :: vf(:,:,:) !< Variance fluxes - - !< Local variables - real :: ITR_adv_scale !< Scaling required for advection terms to ensure dimensions are correct - !< e.g. for temperature need to divide by specific heat capacity * rho_ref - real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. - - ITR_adv_scale = 1 / (scale_constant * GV%Rho0) - mass_transport_scale = (Idt * GV%H_to_RZ) / GV%Rho0 - - call zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, vf) - call meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, vf) - -end subroutine variance_flux - -!< Subroutine to calculate the thickness weighted variance change over a timestep -subroutine thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, res) - - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: ITR_adv_scale !< Scaling for tracer advection - real, intent(in) :: h(:,:,:) !< Thickness - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt !< Model timestep - real, intent(in) :: Idt !< Inverse model timestep - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: res(:,:,:) !< Array to store result in - - !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: h_prev, C_prev, hadv, Cadv !< Thickness and tracer at previous timestep and the - !< changes in thickness and tracer after advection. - - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - - do k=1,nz ; do j=js,je ; do i=is,ie - h_prev = diag_pre_dyn%h_state(i,j,k) - ! hadv = h_prev + dt * (h_tend) - ! = h_prev + dt * (Idt * (h(i, j, k) - h_prev)) - ! = h(i, j, k) - hadv = h(i, j, k) - C_prev = Tr%t_prev(i,j,k) - Cadv = h_prev * C_prev + dt * (Tr%advection_xy(i,j,k) * ITR_adv_scale) - res(i,j,k) = ( (Cadv**2 / hadv) - (h_prev * C_prev**2) ) * Idt - enddo ; enddo ; enddo - -end subroutine thickness_weighted_variance_change - -!< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, res) - - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: ITR_adv_scale !< Scaling for tracer advection - real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport - real, intent(in) :: mass_transport_scale !< Scaling for mass transport - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind value for tracer - real, intent(inout) :: res(:,:,:) !< Array to store the result in - - !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: east, west !< East and West positions for zonal derivative - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: u_trans !< Zonal transport - - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - - u_trans(:, :, :) = 0. - do k=1,nz ; do j=js,je ; do I=is-1,ie - u_trans(I,j,k) = uhtr(I,j,k) * mass_transport_scale - enddo ; enddo ; enddo - - call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) - - do k=1,nz ; do j=js,je ; do i=is,ie - east = 2 * (Tr%ad_x(I,j,k) * ITR_adv_scale) * x_upwind(I,j,k) - u_trans(I,j,k) * x_upwind(I,j,k)**2 - west = 2 * (Tr%ad_x(I-1,j,k) * ITR_adv_scale) * x_upwind(I-1,j,k) - u_trans(I-1,j,k) * x_upwind(I-1,j,k)**2 - res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) - enddo ; enddo; enddo - -end subroutine zonal_upwind_fluxes - -!< Subroutine to calculate upwind values in zonal direction -subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) - - implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(in) :: u_trans(:,:,:) !< Zonal transport - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values of C calculated using u_trans - - !< Local variables - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - - Is = G%IscB ; Ie = G%IecB ; js = G%jsc ; je = G%jec - - do k=1,nz ; do j=js,je ; do I=Is,Ie - if (u_trans(I,j,k) >= 0) then - x_upwind(I,j,k) = Tr%t(i,j,k) - elseif (u_trans(I,j,k) < 0) then - x_upwind(I,j,k) = Tr%t(i+1,j,k) - endif - enddo ; enddo ; enddo - -end subroutine zonal_upwind_values - -!< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, res) - - implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: ITR_adv_scale !< Scaling for tracer advection - real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional transport - real, intent(in) :: mass_transport_scale !< Scaling for mass transport - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind tracer values - real, intent(inout) :: res(:,:,:) !< Array to store the result in - - !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: north, south !< North and South positions for meridional derivative - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: v_trans !< Meridional transport - - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - - v_trans(:, :, :) = 0. - do k=1,nz ; do J=js-1,je ; do i=is,ie - v_trans(i,J,k) = vhtr(i,J,k) * mass_transport_scale - enddo ; enddo ; enddo - - call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) - - do k=1,nz ; do j=js,je ; do i=is,ie - north = 2 * (Tr%ad_y(i,J,k) * ITR_adv_scale) * y_upwind(i,J,k) - v_trans(i,J,k) * y_upwind(i,J,k)**2 - south = 2 * (Tr%ad_y(i,J-1,k) * ITR_adv_scale) * y_upwind(i,J-1,k) - v_trans(i,J-1,k) * y_upwind(i,J-1,k)**2 - res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) - enddo ; enddo ; enddo - -end subroutine meridional_upwind_fluxes - -!< Subroutine to calculate upwind value in the meridional direction -subroutine meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) - - implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(in) :: v_trans(:,:,:) !< Meridional transport - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values of C calculated using v_trans - - !< Local variables - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - - is = G%isc ; ie = G%iec ; Js = G%JscB ; Je = G%JecB - - do k=1,nz ; do J=Js,Je ; do i=is,ie - if (v_trans(i,J,k) >= 0) then - y_upwind(i,J,k) = Tr%t(i,j,k) - elseif (v_trans(i,J,k) < 0) then - y_upwind(i,J,k) = Tr%t(i,j+1,k) - endif - enddo ; enddo ; enddo - -end subroutine meridional_upwind_values - -end module MOM_numerical_mixing From 2773b6203170ca8ce53d4cedb521100df6b2f14a Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 27 Nov 2025 16:33:49 +1100 Subject: [PATCH 135/288] Put back (accidentally) removed declarations --- src/diagnostics/MOM_diagnostics.F90 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 1eebc18ce0..054673f26b 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1644,6 +1644,12 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy type(tracer_registry_type), pointer :: Reg !< Pointer to the tracer registry ! Local variables + real, dimension(SZIB_(G),SZJ_(G)) :: umo2d ! Diagnostics of integrated mass transport [R Z L2 T-1 ~> kg s-1] + real, dimension(SZI_(G),SZJB_(G)) :: vmo2d ! Diagnostics of integrated mass transport [R Z L2 T-1 ~> kg s-1] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: umo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics + ! [H T-1 ~> m s-1 or kg m-2 s-1]. real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. From 77b11b87851be3e8c33ad54329a27a644a228056 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 28 Nov 2025 15:25:20 +1100 Subject: [PATCH 136/288] Add unit conversion for numerical mixign --- src/tracer/MOM_tracer_registry.F90 | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 41e07f7399..23c6c942e0 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -384,11 +384,14 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u v_extensive=.true., & x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") + diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & + trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & - diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", trim(Tr%units)//"^2ms-1") + diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & + trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & - diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", trim(Tr%units)//"^2ms-1") + diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & + trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -415,11 +418,14 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u flux_units, v_extensive=.true., conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T, & x_cell_method='sum') Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", trim(Tr%units)//"^2ms-1") + diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & + trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & - diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", trim(Tr%units)//"^2ms-1") + diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & + trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & - diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", trim(Tr%units)//"^2ms-1") + diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & + trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & From 9e4e855f460df56dd92a3efc12389145f1ff5da0 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 1 Dec 2025 11:28:00 +1100 Subject: [PATCH 137/288] Remove incorrect scaling of horizontal advective fluxes --- src/tracer/MOM_tracer_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 6eb1a58a72..3746d4cc23 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -124,7 +124,7 @@ subroutine thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn ! = h(i, j, k) hadv = h(i, j, k) C_prev = Tr%t_prev(i,j,k) - Cadv = h_prev * C_prev + dt * (Tr%advection_xy(i,j,k) * ITR_adv_scale) + Cadv = h_prev * C_prev + dt * Tr%advection_xy(i,j,k) res(i,j,k) = ( (Cadv**2 / hadv) - (h_prev * C_prev**2) ) * Idt enddo ; enddo ; enddo From edd45e9b64799a7bb2af61661df19a8c504f119e Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 1 Dec 2025 12:21:32 +1100 Subject: [PATCH 138/288] Correct internal scaling (hopefully) --- src/tracer/MOM_tracer_numerical_mixing.F90 | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 3746d4cc23..fb7b403db1 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -158,8 +158,10 @@ subroutine zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - east = 2 * (Tr%ad_x(I,j,k) * ITR_adv_scale) * x_upwind(I,j,k) - u_trans(I,j,k) * x_upwind(I,j,k)**2 - west = 2 * (Tr%ad_x(I-1,j,k) * ITR_adv_scale) * x_upwind(I-1,j,k) - u_trans(I-1,j,k) * x_upwind(I-1,j,k)**2 + ! east = 2 * (Tr%ad_x(I,j,k) * ITR_adv_scale) * x_upwind(I,j,k) - u_trans(I,j,k) * x_upwind(I,j,k)**2 + ! west = 2 * (Tr%ad_x(I-1,j,k) * ITR_adv_scale) * x_upwind(I-1,j,k) - u_trans(I-1,j,k) * x_upwind(I-1,j,k)**2 + east = 2 * (Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - uhtr(I,j,k) * x_upwind(I,j,k)**2 + west = 2 * (Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k) - uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2 res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo @@ -220,8 +222,10 @@ subroutine meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scal call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - north = 2 * (Tr%ad_y(i,J,k) * ITR_adv_scale) * y_upwind(i,J,k) - v_trans(i,J,k) * y_upwind(i,J,k)**2 - south = 2 * (Tr%ad_y(i,J-1,k) * ITR_adv_scale) * y_upwind(i,J-1,k) - v_trans(i,J-1,k) * y_upwind(i,J-1,k)**2 + ! north = 2 * (Tr%ad_y(i,J,k) * ITR_adv_scale) * y_upwind(i,J,k) - v_trans(i,J,k) * y_upwind(i,J,k)**2 + ! south = 2 * (Tr%ad_y(i,J-1,k) * ITR_adv_scale) * y_upwind(i,J-1,k) - v_trans(i,J-1,k) * y_upwind(i,J-1,k)**2 + north = 2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - vhtr(i,J,k) * y_upwind(i,J,k)**2 + south = 2 * (Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2 res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo From fb6d7b69c6b3929cd7d2f4b102e69376ed7d2831 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 1 Dec 2025 13:19:56 +1100 Subject: [PATCH 139/288] Missed a bracket --- src/tracer/MOM_tracer_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index fb7b403db1..2e5506dcdb 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -161,7 +161,7 @@ subroutine zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, ! east = 2 * (Tr%ad_x(I,j,k) * ITR_adv_scale) * x_upwind(I,j,k) - u_trans(I,j,k) * x_upwind(I,j,k)**2 ! west = 2 * (Tr%ad_x(I-1,j,k) * ITR_adv_scale) * x_upwind(I-1,j,k) - u_trans(I-1,j,k) * x_upwind(I-1,j,k)**2 east = 2 * (Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - uhtr(I,j,k) * x_upwind(I,j,k)**2 - west = 2 * (Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k) - uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2 + west = 2 * (Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2 res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo From 011db1f331f5ff95a16f54e62d1d1a825866987f Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 1 Dec 2025 13:27:50 +1100 Subject: [PATCH 140/288] Remove whitespace --- src/tracer/MOM_tracer_registry.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 23c6c942e0..b7c4d36a61 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -384,7 +384,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u v_extensive=.true., & x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & + diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & @@ -784,7 +784,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), & intent(in) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), & + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), & intent(in) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & From 72a61abc806c1a6991ce7bc9d0c1277ac1034b60 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 1 Dec 2025 13:36:22 +1100 Subject: [PATCH 141/288] Remove some white space + scale_constant=1 temporarily --- src/tracer/MOM_tracer_registry.F90 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index b7c4d36a61..a794d2b854 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -864,14 +864,15 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d endif if (Tr%id_numerical_mixing > 0) then - if (Tr%name == "T") then - scale_constant = 3991.86795711963 !< specific heat capacity [Q C-1 ~> J degC-1 kg-1] + scale_constant = 1 + ! if (Tr%name == "T") then + ! scale_constant = 3991.86795711963 !< specific heat capacity [Q C-1 ~> J degC-1 kg-1] ! elseif (Tr%name == "S") then ! scale_constant = 1000 !< I am not sure about this conversion when S is practical salintiy !< need to check with Jan what he had.. ! else ! scale_constant = 1 !< any other tracer is unscaled - endif + ! endif x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. nm(:,:,:) = 0. From 22a3b516ec7255e0a23664cd7d048ca7ab0eff51 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 1 Dec 2025 14:11:28 +1100 Subject: [PATCH 142/288] Missed timestep division in variance flux termsn --- src/tracer/MOM_tracer_numerical_mixing.F90 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 2e5506dcdb..67e272a618 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -131,7 +131,7 @@ subroutine thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn end subroutine thickness_weighted_variance_change !< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, res) +subroutine zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, Idt, x_upwind, res) type(tracer_type), intent(in) :: Tr !< Tracer real, intent(in) :: ITR_adv_scale !< Scaling for tracer advection @@ -139,6 +139,7 @@ subroutine zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, real, intent(in) :: mass_transport_scale !< Scaling for mass transport type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(in) :: Idt !< Inverse model timestep real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind value for tracer real, intent(inout) :: res(:,:,:) !< Array to store the result in @@ -160,8 +161,8 @@ subroutine zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, do k=1,nz ; do j=js,je ; do i=is,ie ! east = 2 * (Tr%ad_x(I,j,k) * ITR_adv_scale) * x_upwind(I,j,k) - u_trans(I,j,k) * x_upwind(I,j,k)**2 ! west = 2 * (Tr%ad_x(I-1,j,k) * ITR_adv_scale) * x_upwind(I-1,j,k) - u_trans(I-1,j,k) * x_upwind(I-1,j,k)**2 - east = 2 * (Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - uhtr(I,j,k) * x_upwind(I,j,k)**2 - west = 2 * (Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2 + east = 2 * (Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2 + west = 2 * (Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2 res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo @@ -194,7 +195,7 @@ subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) end subroutine zonal_upwind_values !< Subroutine to calculate the meriodional upwind flues -subroutine meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, res) + subroutine meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, Idt, y_upwind, res) implicit none type(tracer_type), intent(in) :: Tr !< Tracer @@ -203,6 +204,7 @@ subroutine meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scal real, intent(in) :: mass_transport_scale !< Scaling for mass transport type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(in) :: Idt !< Inverse model timestep real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind tracer values real, intent(inout) :: res(:,:,:) !< Array to store the result in @@ -224,8 +226,8 @@ subroutine meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scal do k=1,nz ; do j=js,je ; do i=is,ie ! north = 2 * (Tr%ad_y(i,J,k) * ITR_adv_scale) * y_upwind(i,J,k) - v_trans(i,J,k) * y_upwind(i,J,k)**2 ! south = 2 * (Tr%ad_y(i,J-1,k) * ITR_adv_scale) * y_upwind(i,J-1,k) - v_trans(i,J-1,k) * y_upwind(i,J-1,k)**2 - north = 2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - vhtr(i,J,k) * y_upwind(i,J,k)**2 - south = 2 * (Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2 + north = 2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2 + south = 2 * (Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2 res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo From 790fbcaa72c43b91bd6f9c651175135cd90b062a Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 1 Dec 2025 14:17:13 +1100 Subject: [PATCH 143/288] Forgot to pass the new argument --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 67e272a618..79ecb0c445 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -41,8 +41,8 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, sca mass_transport_scale = (Idt * GV%H_to_RZ) / GV%Rho0 call thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) - call zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, nm) - call meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, nm) + call zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, Idt, x_upwind, nm) + call meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, Idt, y_upwind, nm) end subroutine numerical_mixing @@ -91,8 +91,8 @@ subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, scale_constant, x_upwind, y ITR_adv_scale = 1 / (scale_constant * GV%Rho0) mass_transport_scale = (Idt * GV%H_to_RZ) / GV%Rho0 - call zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, x_upwind, vf) - call meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, y_upwind, vf) + call zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, Idt, x_upwind, vf) + call meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, Idt, y_upwind, vf) end subroutine variance_flux From 5e72a6ec6846ee16a7ca3475be616fa63761e428 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 1 Dec 2025 15:09:09 +1100 Subject: [PATCH 144/288] Try checking upwind with accumulated fluxes --- src/tracer/MOM_tracer_numerical_mixing.F90 | 37 ++++++++++------------ 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 79ecb0c445..b1923b4ac8 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -112,20 +112,17 @@ subroutine thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters - real :: h_prev, C_prev, hadv, Cadv !< Thickness and tracer at previous timestep and the - !< changes in thickness and tracer after advection. + real :: h_prev, C_prev, Ihadv, Cadv !< Thickness and tracer at previous timestep, inverse + !< updated thickness and non-invers tracer after advection. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke do k=1,nz ; do j=js,je ; do i=is,ie h_prev = diag_pre_dyn%h_state(i,j,k) - ! hadv = h_prev + dt * (h_tend) - ! = h_prev + dt * (Idt * (h(i, j, k) - h_prev)) - ! = h(i, j, k) - hadv = h(i, j, k) + Ihadv = 1 / h(i,j,k) C_prev = Tr%t_prev(i,j,k) - Cadv = h_prev * C_prev + dt * Tr%advection_xy(i,j,k) - res(i,j,k) = ( (Cadv**2 / hadv) - (h_prev * C_prev**2) ) * Idt + Cadv = h_prev * C_prev + dt * Tr%advection_xy(i,j,k) + res(i,j,k) = ( (Ihadv * Cadv**2) - (h_prev * C_prev**2) ) * Idt enddo ; enddo ; enddo end subroutine thickness_weighted_variance_change @@ -147,16 +144,16 @@ subroutine zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters real :: east, west !< East and West positions for zonal derivative - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: u_trans !< Zonal transport + ! real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: u_trans !< Zonal transport is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - u_trans(:, :, :) = 0. - do k=1,nz ; do j=js,je ; do I=is-1,ie - u_trans(I,j,k) = uhtr(I,j,k) * mass_transport_scale - enddo ; enddo ; enddo + ! u_trans(:,:,:) = 0. + ! do k=1,nz ; do j=js,je ; do I=is-1,ie + ! u_trans(I,j,k) = uhtr(I,j,k) * mass_transport_scale + ! enddo ; enddo ; enddo - call zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) + call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie ! east = 2 * (Tr%ad_x(I,j,k) * ITR_adv_scale) * x_upwind(I,j,k) - u_trans(I,j,k) * x_upwind(I,j,k)**2 @@ -212,16 +209,16 @@ subroutine meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scal integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters real :: north, south !< North and South positions for meridional derivative - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: v_trans !< Meridional transport + ! real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: v_trans !< Meridional transport is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - v_trans(:, :, :) = 0. - do k=1,nz ; do J=js-1,je ; do i=is,ie - v_trans(i,J,k) = vhtr(i,J,k) * mass_transport_scale - enddo ; enddo ; enddo + ! v_trans(:, :, :) = 0. + ! do k=1,nz ; do J=js-1,je ; do i=is,ie + ! v_trans(i,J,k) = vhtr(i,J,k) * mass_transport_scale + ! enddo ; enddo ; enddo - call meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) + call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie ! north = 2 * (Tr%ad_y(i,J,k) * ITR_adv_scale) * y_upwind(i,J,k) - v_trans(i,J,k) * y_upwind(i,J,k)**2 From e086a32d23571cc06bad6d70e651a3531c3964db Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 2 Dec 2025 10:07:27 +1100 Subject: [PATCH 145/288] Major clean up of nm module --- src/tracer/MOM_tracer_numerical_mixing.F90 | 235 +++++++++------------ 1 file changed, 94 insertions(+), 141 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index b1923b4ac8..994523abd5 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -14,100 +14,79 @@ module MOM_tracer_numerical_mixing contains -!< Calculate the spurious ``numerical'' mixing of tracer Tr due to advection. -subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, nm) +!< Calculate the spurious ``numerical'' mixing of tracer due to advection. +subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, x_upwind, y_upwind, nm) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: h(:,:,:) !< Thickness + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt !< Model timestep - real, intent(in) :: Idt !< Inverse model timestep - real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport - real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional transport - real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer - real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic - - !< Local variables - real :: ITR_adv_scale !< Scaling required for advection terms to ensure dimensions are correct - !< e.g. for temperature need to divide by specific heat capacity * rho_ref - !< This is an inverse quantity to avoid division. - real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. - - ITR_adv_scale = 1 / (scale_constant * GV%Rho0) - mass_transport_scale = (Idt * GV%H_to_RZ) / GV%Rho0 - - call thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, nm) - call zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, Idt, x_upwind, nm) - call meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, Idt, y_upwind, nm) + real, intent(in) :: dt_trans !< The transport time interval [T ~> s] + real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] + real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] + real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic [CU2 H T-1 ~> conc2 m s-1] + + call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, nm) + call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, nm) + call thickness_weighted_meridional_variance_flux(Tr, G, GV, Idt, y_upwind, nm) end subroutine numerical_mixing -!< Subroutine for only the variance advection, likely will remove once numerical mixing is sorted out -subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, scale_constant, va) - - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: h(:,:,:) !< Thickness - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt !< Model timestep - real, intent(in) :: Idt !< Inverse model timestep - real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(inout) :: va(:,:,:) !< Variance advection - - !< Local variables - real :: ITR_adv_scale !< Scaling required for advection terms to ensure dimensions are correct - !< e.g. for temperature need to divide by specific heat capacity * rho_ref +!< Subroutine for the variance advection, likely will remove once numerical mixing is sorted out +subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) - ITR_adv_scale = 1 / (scale_constant * GV%Rho0) + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt_trans !< The transport time interval [T ~> s] + real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] + real, intent(inout) :: va(:,:,:) !< Thickness weighted variance advection + !! [CU2 H T-1 ~> conc2 m s-1] - call thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, va) + call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, va) end subroutine variance_advection -!< Subroutine for only the variance flux, likely will remove once numerical mixing is sorted out -subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) +!< Subroutine for the horizontal variance flux, likely will remove once numerical mixing is sorted out +subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: Idt !< Inverse model timestep - real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport - real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional transport - real, intent(in) :: scale_constant !< Scaling for tracer e.g. Specific heat capacity for T - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer - real, intent(inout) :: vf(:,:,:) !< Variance fluxes - - !< Local variables - real :: ITR_adv_scale !< Scaling required for advection terms to ensure dimensions are correct - !< e.g. for temperature need to divide by specific heat capacity * rho_ref - real :: mass_transport_scale !< Scaling required for transforming accumulated fluxes into m3 s-1. - - ITR_adv_scale = 1 / (scale_constant * GV%Rho0) - mass_transport_scale = (Idt * GV%H_to_RZ) / GV%Rho0 - - call zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, Idt, x_upwind, vf) - call meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, Idt, y_upwind, vf) + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] + real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] + real, intent(inout) :: vf(:,:,:) !< Horizontal thickness weighted variance flux + !! [CU2 H T-1 ~> conc2 m s-1] + + call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, vf) + call thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, vf) end subroutine variance_flux -!< Subroutine to calculate the thickness weighted variance change over a timestep -subroutine thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn, dt, Idt, G, GV, res) +!< Subroutine to calculate the thickness weighted variance advection over the transport timestep. +subroutine thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt, Idt, G, GV, res) - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: ITR_adv_scale !< Scaling for tracer advection - real, intent(in) :: h(:,:,:) !< Thickness - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt !< Model timestep - real, intent(in) :: Idt !< Inverse model timestep - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: res(:,:,:) !< Array to store result in + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt !< The transport time interval [T ~> s] + real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(inout) :: res(:,:,:) !< Array to store result in [CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -125,120 +104,94 @@ subroutine thickness_weighted_variance_change(Tr, ITR_adv_scale, h, diag_pre_dyn res(i,j,k) = ( (Ihadv * Cadv**2) - (h_prev * C_prev**2) ) * Idt enddo ; enddo ; enddo -end subroutine thickness_weighted_variance_change - -!< Subroutine to calculate the zonal upwind fluxes -subroutine zonal_upwind_fluxes(Tr, ITR_adv_scale, uhtr, mass_transport_scale, G, GV, Idt, x_upwind, res) +end subroutine thickness_weighted_variance_advection - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: ITR_adv_scale !< Scaling for tracer advection - real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport - real, intent(in) :: mass_transport_scale !< Scaling for mass transport - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(in) :: Idt !< Inverse model timestep - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind value for tracer - real, intent(inout) :: res(:,:,:) !< Array to store the result in +!< Subroutine to calculate the thickness weigthed zonal variance flux. The spatial derivatives are calucated +!! from upwind values. +subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, res) - !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: east, west !< East and West positions for zonal derivative - ! real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: u_trans !< Zonal transport + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(in) :: Idt !< Inverse transport time intervale [T-1 ~> s-1] + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind tracer value [CU ~> conc] + real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - ! u_trans(:,:,:) = 0. - ! do k=1,nz ; do j=js,je ; do I=is-1,ie - ! u_trans(I,j,k) = uhtr(I,j,k) * mass_transport_scale - ! enddo ; enddo ; enddo - call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - ! east = 2 * (Tr%ad_x(I,j,k) * ITR_adv_scale) * x_upwind(I,j,k) - u_trans(I,j,k) * x_upwind(I,j,k)**2 - ! west = 2 * (Tr%ad_x(I-1,j,k) * ITR_adv_scale) * x_upwind(I-1,j,k) - u_trans(I-1,j,k) * x_upwind(I-1,j,k)**2 east = 2 * (Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2 west = 2 * (Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2 res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo -end subroutine zonal_upwind_fluxes +end subroutine thickness_weighted_zonal_variance_flux !< Subroutine to calculate upwind values in zonal direction -subroutine zonal_upwind_values(Tr, G, nz, u_trans, x_upwind) +subroutine zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) - implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(in) :: u_trans(:,:,:) !< Zonal transport - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values of C calculated using u_trans - - !< Local variables - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + integer, intent(in) :: nz !< Vertical extent of domain + real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values [CU ~> conc] Is = G%IscB ; Ie = G%IecB ; js = G%jsc ; je = G%jec do k=1,nz ; do j=js,je ; do I=Is,Ie - if (u_trans(I,j,k) >= 0) then + if (uhtr(I,j,k) >= 0) then x_upwind(I,j,k) = Tr%t(i,j,k) - elseif (u_trans(I,j,k) < 0) then + elseif (uhtr(I,j,k) < 0) then x_upwind(I,j,k) = Tr%t(i+1,j,k) endif enddo ; enddo ; enddo end subroutine zonal_upwind_values -!< Subroutine to calculate the meriodional upwind flues - subroutine meridional_upwind_fluxes(Tr, ITR_adv_scale, vhtr, mass_transport_scale, G, GV, Idt, y_upwind, res) +!< Subroutine to calculate the thickness weighted meriodional variance flux. The spatial derivative is calculated +!! from upwind values. +subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, res) - implicit none - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: ITR_adv_scale !< Scaling for tracer advection - real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional transport - real, intent(in) :: mass_transport_scale !< Scaling for mass transport - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(in) :: Idt !< Inverse model timestep - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind tracer values - real, intent(inout) :: res(:,:,:) !< Array to store the result in + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, intent(in) :: Idt !< Inverse model timestep + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind tracer values [CU ~> conc] + real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters real :: north, south !< North and South positions for meridional derivative - ! real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: v_trans !< Meridional transport is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - ! v_trans(:, :, :) = 0. - ! do k=1,nz ; do J=js-1,je ; do i=is,ie - ! v_trans(i,J,k) = vhtr(i,J,k) * mass_transport_scale - ! enddo ; enddo ; enddo - call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - ! north = 2 * (Tr%ad_y(i,J,k) * ITR_adv_scale) * y_upwind(i,J,k) - v_trans(i,J,k) * y_upwind(i,J,k)**2 - ! south = 2 * (Tr%ad_y(i,J-1,k) * ITR_adv_scale) * y_upwind(i,J-1,k) - v_trans(i,J-1,k) * y_upwind(i,J-1,k)**2 north = 2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2 south = 2 * (Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2 res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo -end subroutine meridional_upwind_fluxes +end subroutine thickness_weighted_meridional_variance_flux !< Subroutine to calculate upwind value in the meridional direction -subroutine meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) +subroutine meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) - implicit none type(tracer_type), intent(in) :: Tr !< Tracer type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(in) :: v_trans(:,:,:) !< Meridional transport - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values of C calculated using v_trans + real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values of C [CU ~> conc] !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes @@ -247,9 +200,9 @@ subroutine meridional_upwind_values(Tr, G, nz, v_trans, y_upwind) is = G%isc ; ie = G%iec ; Js = G%JscB ; Je = G%JecB do k=1,nz ; do J=Js,Je ; do i=is,ie - if (v_trans(i,J,k) >= 0) then + if (vhtr(i,J,k) >= 0) then y_upwind(i,J,k) = Tr%t(i,j,k) - elseif (v_trans(i,J,k) < 0) then + elseif (vhtr(i,J,k) < 0) then y_upwind(i,J,k) = Tr%t(i,j+1,k) endif enddo ; enddo ; enddo From 556036c0a8c198e00311b93cf872adc6fb37ca3e Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 2 Dec 2025 10:10:24 +1100 Subject: [PATCH 146/288] Correct the subroutine calls --- src/tracer/MOM_tracer_registry.F90 | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index a794d2b854..ea7cd779a3 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -864,26 +864,17 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d endif if (Tr%id_numerical_mixing > 0) then - scale_constant = 1 - ! if (Tr%name == "T") then - ! scale_constant = 3991.86795711963 !< specific heat capacity [Q C-1 ~> J degC-1 kg-1] - ! elseif (Tr%name == "S") then - ! scale_constant = 1000 !< I am not sure about this conversion when S is practical salintiy - !< need to check with Jan what he had.. - ! else - ! scale_constant = 1 !< any other tracer is unscaled - ! endif x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. nm(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & - scale_constant, x_upwind, y_upwind, nm) + x_upwind, y_upwind, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) !< The below is here while debuggin; to be removed once numerical mixing is all sorted if (Tr%id_variance_advection > 0) then va(:,:,:) = 0. - call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, scale_constant, va) + call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) call post_data(Tr%id_variance_advection, va, diag, alt_h=diag_pre_dyn%h_state) endif if (Tr%id_variance_flux > 0) then @@ -891,7 +882,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. vf(:,:,:) = 0. - call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) + call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) endif endif From 2ff2e2f71f4fd604f8de327b63a8df2d3ce14212 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 2 Dec 2025 10:15:54 +1100 Subject: [PATCH 147/288] Fixes after errors in building --- src/tracer/MOM_tracer_numerical_mixing.F90 | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 994523abd5..fa8f57f98f 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -34,7 +34,7 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, nm) call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, nm) - call thickness_weighted_meridional_variance_flux(Tr, G, GV, Idt, y_upwind, nm) + call thickness_weighted_meridional_variance_flux(Tr, vhtr G, GV, Idt, y_upwind, nm) end subroutine numerical_mixing @@ -119,6 +119,11 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind tracer value [CU ~> conc] real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] + !< Local variables + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: east, west !< East and West for zonal derivative [CU2 H T-1 ~> conc2 m s-1] + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) @@ -141,6 +146,10 @@ subroutine zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) !! used to advect tracers [H L2 ~> m3 or kg] real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values [CU ~> conc] + !< Local variables + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + Is = G%IscB ; Ie = G%IecB ; js = G%jsc ; je = G%jec do k=1,nz ; do j=js,je ; do I=Is,Ie From 4d98a3bb699e5c9ef22a18e22dcdff36926c4b1a Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 2 Dec 2025 10:20:18 +1100 Subject: [PATCH 148/288] Missed a comma --- src/tracer/MOM_tracer_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index fa8f57f98f..6924ca93d3 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -34,7 +34,7 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, nm) call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, nm) - call thickness_weighted_meridional_variance_flux(Tr, vhtr G, GV, Idt, y_upwind, nm) + call thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, nm) end subroutine numerical_mixing From d1180c88cb1e07ab4ec465aec1efcdbd86655412 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 2 Dec 2025 10:28:12 +1100 Subject: [PATCH 149/288] Add missing docstring --- src/tracer/MOM_tracer_registry.F90 | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index ea7cd779a3..090d5576ef 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -789,8 +789,8 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: h !< The updated layer thicknesses [H ~> m or kg m-2] - real, intent(in) :: dt_trans ! The transport time interval [T ~> s] - real, intent(in) :: Idt ! The inverse of the time interval [T-1 ~> s-1] + real, intent(in) :: dt_trans !< The transport time interval [T ~> s] + real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] integer :: i, j, k, is, ie, js, je, nz, m, khi real :: work2d(SZI_(G),SZJ_(G)) ! The vertically integrated convergence of lateral advective @@ -802,13 +802,12 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer [CU2 H T-1 ~> conc2 m s-1] ! va and vf will be removed but are needed in the debugging process - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Variance advection [CU2 H T-1 ~> conc2 m s-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Flux of variance [CU2 H T-1 ~> conc2 m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Thickness weighted variance advection + ! [CU2 H T-1 ~> conc2 m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Horizontal thickness weighted variance flux + ! [CU2 H T-1 ~> conc2 m s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. - real :: scale_constant !< Scale for numerical mixing e.g. specific heat capacity. - !! The dimensions are dependent on the tracer so they are specified - !! where the value is defined. type(tracer_type), pointer :: Tr=>NULL() is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke From 9c900e5ee75dd98bb1e6da3d262e391f06e00dec Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 2 Dec 2025 10:32:22 +1100 Subject: [PATCH 150/288] Remove whitespace --- src/tracer/MOM_tracer_registry.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 090d5576ef..58d8e3d5a1 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -802,7 +802,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer [CU2 H T-1 ~> conc2 m s-1] ! va and vf will be removed but are needed in the debugging process - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Thickness weighted variance advection + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Thickness weighted variance advection ! [CU2 H T-1 ~> conc2 m s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Horizontal thickness weighted variance flux ! [CU2 H T-1 ~> conc2 m s-1] From e4802d4e782c241808b7228c6379c9f9e659bbb5 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 2 Dec 2025 11:08:59 +1100 Subject: [PATCH 151/288] Use more explicit indexing --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 6924ca93d3..c2c039338b 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -150,9 +150,9 @@ subroutine zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters - Is = G%IscB ; Ie = G%IecB ; js = G%jsc ; je = G%jec + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - do k=1,nz ; do j=js,je ; do I=Is,Ie + do k=1,nz ; do j=js,je ; do I=is-1,ie if (uhtr(I,j,k) >= 0) then x_upwind(I,j,k) = Tr%t(i,j,k) elseif (uhtr(I,j,k) < 0) then @@ -206,9 +206,9 @@ subroutine meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) integer :: is, ie, js, je !< Grid cell centre indexes integer :: i, j, k !< Counters - is = G%isc ; ie = G%iec ; Js = G%JscB ; Je = G%JecB + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - do k=1,nz ; do J=Js,Je ; do i=is,ie + do k=1,nz ; do J=js-1,je ; do i=is,ie if (vhtr(i,J,k) >= 0) then y_upwind(i,J,k) = Tr%t(i,j,k) elseif (vhtr(i,J,k) < 0) then From c3b1e3b7e1fe3d911e46f2a570cb7c51f61b526e Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 2 Dec 2025 12:36:46 +1100 Subject: [PATCH 152/288] Homogenise spacing before comments --- src/tracer/MOM_tracer_numerical_mixing.F90 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index c2c039338b..4c74659d2e 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -89,10 +89,10 @@ subroutine thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt, Idt, G real, intent(inout) :: res(:,:,:) !< Array to store result in [CU2 H T-1 ~> conc2 m s-1] !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: h_prev, C_prev, Ihadv, Cadv !< Thickness and tracer at previous timestep, inverse - !< updated thickness and non-invers tracer after advection. + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: h_prev, C_prev, Ihadv, Cadv !< Thickness and tracer at previous timestep, inverse + !< updated thickness and non-invers tracer after advection. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke @@ -176,9 +176,9 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: north, south !< North and South positions for meridional derivative + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: north, south !< North and South positions for meridional derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke From cec66dfdc78e70d819345ea249351668aa495cba Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 2 Dec 2025 12:53:34 +1100 Subject: [PATCH 153/288] Remove unneceassary brackets --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 4c74659d2e..c1d93b75a5 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -129,8 +129,8 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - east = 2 * (Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2 - west = 2 * (Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2 + east = 2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k) - Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2 + west = 2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k) - Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2 res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo @@ -185,8 +185,8 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - north = 2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2 - south = 2 * (Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2 + north = 2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k) - Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2 + south = 2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k) - Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2 res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo From e00e3821abb14ba60ff41ff09d99f6c3766a986f Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 2 Dec 2025 12:57:22 +1100 Subject: [PATCH 154/288] Remove code that is now in MOM_tracer_numerical_mixing module --- src/diagnostics/MOM_diagnostics.F90 | 33 ----------------------------- 1 file changed, 33 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 054673f26b..28ec06dae6 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1707,39 +1707,6 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy call post_tracer_transport_diagnostics(G, GV, Reg, diag_pre_dyn%h_state, diag_pre_dyn, & diag, uhtr, vhtr, h, dt_trans, Idt) - ! Once everything builds and works as it was previously did remove this section - ! do m=1,Reg%ntr ; if (Reg%Tr(m)%registry_diags) then - ! Tr => Reg%Tr(m) - ! if (Tr%id_numerical_mixing > 0) then - ! if (Tr%name == "T") then - ! scale_constant = 3991.86795711963 !< hard coded (for now) specific heat capacity - ! elseif (Tr%name == "S") then - ! scale_constant = 1000 !< g -> kg - ! else - ! scale_constant = 1 !< any other tracer is unscaled - ! endif - ! x_upwind(:, :, :) = 0. - ! y_upwind(:, :, :) = 0. - ! nm(:,:,:) = 0. - ! call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & - ! scale_constant, x_upwind, y_upwind, nm) - ! call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) - ! if (Tr%id_variance_advection > 0) then - ! va(:,:,:) = 0. - ! call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, scale_constant, va) - ! call post_data(Tr%id_variance_advection, va, diag, alt_h=diag_pre_dyn%h_state) - ! endif - ! if (Tr%id_variance_flux > 0) then - ! !< Overkill to caclulate these again but I plan on removing once numerical mixing is sorted - ! x_upwind(:, :, :) = 0. - ! y_upwind(:, :, :) = 0. - ! vf(:,:,:) = 0. - ! call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, scale_constant, x_upwind, y_upwind, vf) - ! call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) - ! endif - ! endif - ! endif; enddo - call diag_restore_grids(diag) end subroutine post_transport_diagnostics From c5f8ee3e1778619c9fab05d1b2187fc14cfd1820 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 2 Dec 2025 13:37:22 +1100 Subject: [PATCH 155/288] Use t_prev --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index c1d93b75a5..727e46621c 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -154,9 +154,9 @@ subroutine zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do I=is-1,ie if (uhtr(I,j,k) >= 0) then - x_upwind(I,j,k) = Tr%t(i,j,k) + x_upwind(I,j,k) = Tr%t_prev(i,j,k) elseif (uhtr(I,j,k) < 0) then - x_upwind(I,j,k) = Tr%t(i+1,j,k) + x_upwind(I,j,k) = Tr%t_prev(i+1,j,k) endif enddo ; enddo ; enddo @@ -210,9 +210,9 @@ subroutine meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do J=js-1,je ; do i=is,ie if (vhtr(i,J,k) >= 0) then - y_upwind(i,J,k) = Tr%t(i,j,k) + y_upwind(i,J,k) = Tr%t_prev(i,j,k) elseif (vhtr(i,J,k) < 0) then - y_upwind(i,J,k) = Tr%t(i,j+1,k) + y_upwind(i,J,k) = Tr%t_prev(i,j+1,k) endif enddo ; enddo ; enddo From e7ead167ca0fabf700c5a8eae1a5594b4e9b40c1 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 3 Dec 2025 10:20:50 +1100 Subject: [PATCH 156/288] H_to_m -> H_to_MKS in output conversion --- src/tracer/MOM_tracer_registry.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 58d8e3d5a1..09c5502b36 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -385,13 +385,13 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & - trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) + trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & - trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) + trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & - trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) + trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -419,13 +419,13 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum') Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & - trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) + trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & - trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) + trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & - trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) + trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & From 8e948cc4b02d0e599504d339208740bd92fb826d Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 3 Dec 2025 10:30:37 +1100 Subject: [PATCH 157/288] Correct unit printing --- src/tracer/MOM_tracer_registry.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 09c5502b36..e04f78bba4 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -385,13 +385,13 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & - trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & - trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & - trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//" 2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -419,13 +419,13 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum') Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & - trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & - trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & - trim(Tr%units)//"^2ms-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & From 22745d405c8c71a9ff6308ea9988894867782ca3 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 3 Dec 2025 10:38:08 +1100 Subject: [PATCH 158/288] The offline variable I use use H_to_Z so maybe that one --- src/tracer/MOM_tracer_registry.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index e04f78bba4..273fb8d063 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -385,13 +385,13 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_Z*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_Z*US%s_to_T) Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & - trim(Tr%units)//" 2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//" 2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_Z*US%s_to_T) else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -419,13 +419,13 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum') Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_Z*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_Z*US%s_to_T) Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_Z*US%s_to_T) endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & From bebeb9068776c4265efe4f8c21441d71e0501ae6 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 3 Dec 2025 10:49:44 +1100 Subject: [PATCH 159/288] MKS is the one --- src/tracer/MOM_tracer_registry.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 273fb8d063..e04f78bba4 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -385,13 +385,13 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_Z*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_Z*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & - trim(Tr%units)//" 2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_Z*US%s_to_T) + trim(Tr%units)//" 2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -419,13 +419,13 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum') Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_Z*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_Z*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_Z*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & From 433e991e3e900881a99a44c3bae35b478fd6572c Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 3 Dec 2025 11:51:16 +1100 Subject: [PATCH 160/288] t_prev -> t --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 727e46621c..c1d93b75a5 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -154,9 +154,9 @@ subroutine zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do I=is-1,ie if (uhtr(I,j,k) >= 0) then - x_upwind(I,j,k) = Tr%t_prev(i,j,k) + x_upwind(I,j,k) = Tr%t(i,j,k) elseif (uhtr(I,j,k) < 0) then - x_upwind(I,j,k) = Tr%t_prev(i+1,j,k) + x_upwind(I,j,k) = Tr%t(i+1,j,k) endif enddo ; enddo ; enddo @@ -210,9 +210,9 @@ subroutine meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do J=js-1,je ; do i=is,ie if (vhtr(i,J,k) >= 0) then - y_upwind(i,J,k) = Tr%t_prev(i,j,k) + y_upwind(i,J,k) = Tr%t(i,j,k) elseif (vhtr(i,J,k) < 0) then - y_upwind(i,J,k) = Tr%t_prev(i,j+1,k) + y_upwind(i,J,k) = Tr%t(i,j+1,k) endif enddo ; enddo ; enddo From 4b6b1053157df5bb9b1349e2c8973234cb89c4c7 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 3 Dec 2025 14:13:27 +1100 Subject: [PATCH 161/288] Parantheses in calculation --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index c1d93b75a5..77fc83c965 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -129,8 +129,8 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - east = 2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k) - Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2 - west = 2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k) - Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2 + east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) + west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo @@ -185,8 +185,8 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - north = 2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k) - Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2 - south = 2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k) - Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2 + north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) + south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo From 1ed92f59e3ff235d2130c0ede766365849f50c96 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 4 Dec 2025 15:14:56 +1100 Subject: [PATCH 162/288] Convert to Z in variance fluxes --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 77fc83c965..70af5f144c 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -131,7 +131,7 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind do k=1,nz ; do j=js,je ; do i=is,ie east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2) - res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) + res(i,j,k) = res(i,j,k) + (GV%H_to_Z * (east - west) * G%IareaT(i,j)) enddo ; enddo; enddo end subroutine thickness_weighted_zonal_variance_flux @@ -187,7 +187,7 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u do k=1,nz ; do j=js,je ; do i=is,ie north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2) - res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) + res(i,j,k) = res(i,j,k) + (GV%H_to_Z * (north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo end subroutine thickness_weighted_meridional_variance_flux From 1deabe26a775570bc87a6bdcfbbd3cb1e5efc951 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 4 Dec 2025 15:27:39 +1100 Subject: [PATCH 163/288] Back to thickness --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 70af5f144c..77fc83c965 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -131,7 +131,7 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind do k=1,nz ; do j=js,je ; do i=is,ie east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2) - res(i,j,k) = res(i,j,k) + (GV%H_to_Z * (east - west) * G%IareaT(i,j)) + res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo end subroutine thickness_weighted_zonal_variance_flux @@ -187,7 +187,7 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u do k=1,nz ; do j=js,je ; do i=is,ie north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2) - res(i,j,k) = res(i,j,k) + (GV%H_to_Z * (north - south) * G%IareaT(i,j)) + res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo end subroutine thickness_weighted_meridional_variance_flux From 51d4b0414eb6a89462c1d1fe48732a1f0ac23e62 Mon Sep 17 00:00:00 2001 From: Josef Bisits Date: Fri, 5 Dec 2025 13:41:36 +1100 Subject: [PATCH 164/288] Index the online calculation correctly for ANU-TUB --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 77fc83c965..ff2343c558 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -129,8 +129,8 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) - west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2) + east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I+1,j,k) * x_upwind(I,j,k)**2) + west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I-1,j,k)**2) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo @@ -185,8 +185,8 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) - south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2) + north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J+1,k) * y_upwind(i,J,k)**2) + south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J-1,k)**2) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo From d35340fb130443aff660d2ef7425edc52b01cbb5 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 8 Dec 2025 10:53:46 +1100 Subject: [PATCH 165/288] Adjust the upwind indexing --- src/tracer/MOM_tracer_numerical_mixing.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index ff2343c558..ad06a58ac4 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -129,8 +129,8 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I+1,j,k) * x_upwind(I,j,k)**2) - west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I-1,j,k)**2) + east = (2 * Tr%ad_x(I,j,k) * x_upwind(I+1,j,k)) - (Idt * uhtr(I+1,j,k) * x_upwind(I+1,j,k)**2) + west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo @@ -152,7 +152,7 @@ subroutine zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - do k=1,nz ; do j=js,je ; do I=is-1,ie + do k=1,nz ; do j=js,je ; do I=is,ie+1 if (uhtr(I,j,k) >= 0) then x_upwind(I,j,k) = Tr%t(i,j,k) elseif (uhtr(I,j,k) < 0) then @@ -185,8 +185,8 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J+1,k) * y_upwind(i,J,k)**2) - south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J-1,k)**2) + north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J+1,k)) - (Idt * vhtr(i,J+1,k) * y_upwind(i,J+1,k)**2) + south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo @@ -208,7 +208,7 @@ subroutine meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - do k=1,nz ; do J=js-1,je ; do i=is,ie + do k=1,nz ; do J=js,je+1 ; do i=is,ie if (vhtr(i,J,k) >= 0) then y_upwind(i,J,k) = Tr%t(i,j,k) elseif (vhtr(i,J,k) < 0) then From d7c7d04d18910bf153afd6d0ffb9e0b03afc2d09 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 8 Dec 2025 11:22:05 +1100 Subject: [PATCH 166/288] Revert upwind calcualtion --- src/tracer/MOM_tracer_numerical_mixing.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index ad06a58ac4..1f33a8820f 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -129,8 +129,8 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - east = (2 * Tr%ad_x(I,j,k) * x_upwind(I+1,j,k)) - (Idt * uhtr(I+1,j,k) * x_upwind(I+1,j,k)**2) - west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) + east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I+1,j,k) * x_upwind(I,j,k)**2) + west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I-1,j,k)**2) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo @@ -152,7 +152,7 @@ subroutine zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - do k=1,nz ; do j=js,je ; do I=is,ie+1 + do k=1,nz ; do j=js,je ; do I=is-1,ie if (uhtr(I,j,k) >= 0) then x_upwind(I,j,k) = Tr%t(i,j,k) elseif (uhtr(I,j,k) < 0) then @@ -185,8 +185,8 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J+1,k)) - (Idt * vhtr(i,J+1,k) * y_upwind(i,J+1,k)**2) - south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) + north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J+1,k) * y_upwind(i,J,k)**2) + south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J-1,k)**2) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo @@ -208,7 +208,7 @@ subroutine meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - do k=1,nz ; do J=js,je+1 ; do i=is,ie + do k=1,nz ; do J=js-1,je ; do i=is,ie if (vhtr(i,J,k) >= 0) then y_upwind(i,J,k) = Tr%t(i,j,k) elseif (vhtr(i,J,k) < 0) then From 60eba8690392972aa87716e8a350a24786f6d73f Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 8 Dec 2025 11:32:32 +1100 Subject: [PATCH 167/288] H_to_MKS -> H_to_m --- src/tracer/MOM_tracer_registry.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index e04f78bba4..555ee81153 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -385,13 +385,13 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & - trim(Tr%units)//" 2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//" 2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -419,13 +419,13 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum') Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & From 2ba4bbe2834cd6383ce537d33bf26de19d9d01ca Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 8 Dec 2025 11:45:57 +1100 Subject: [PATCH 168/288] Try with t_prev in the updated scheme --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 1f33a8820f..119c250cef 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -154,9 +154,9 @@ subroutine zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do I=is-1,ie if (uhtr(I,j,k) >= 0) then - x_upwind(I,j,k) = Tr%t(i,j,k) + x_upwind(I,j,k) = Tr%t_prev(i,j,k) elseif (uhtr(I,j,k) < 0) then - x_upwind(I,j,k) = Tr%t(i+1,j,k) + x_upwind(I,j,k) = Tr%t_prev(i+1,j,k) endif enddo ; enddo ; enddo @@ -210,9 +210,9 @@ subroutine meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do J=js-1,je ; do i=is,ie if (vhtr(i,J,k) >= 0) then - y_upwind(i,J,k) = Tr%t(i,j,k) + y_upwind(i,J,k) = Tr%t_prev(i,j,k) elseif (vhtr(i,J,k) < 0) then - y_upwind(i,J,k) = Tr%t(i,j+1,k) + y_upwind(i,J,k) = Tr%t_prev(i,j+1,k) endif enddo ; enddo ; enddo From 99d8c6c5b3639eea60358d23575f164737d284c2 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 8 Dec 2025 13:02:43 +1100 Subject: [PATCH 169/288] Back to previous indexing to check thickness test --- src/tracer/MOM_tracer_numerical_mixing.F90 | 20 ++++++++++++-------- src/tracer/MOM_tracer_registry.F90 | 12 ++++++------ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 119c250cef..688f02bd95 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -129,8 +129,10 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I+1,j,k) * x_upwind(I,j,k)**2) - west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I-1,j,k)**2) + ! east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I+1,j,k) * x_upwind(I,j,k)**2) + ! west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I-1,j,k)**2) + east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) + west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo @@ -154,9 +156,9 @@ subroutine zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do I=is-1,ie if (uhtr(I,j,k) >= 0) then - x_upwind(I,j,k) = Tr%t_prev(i,j,k) + x_upwind(I,j,k) = Tr%t(i,j,k) elseif (uhtr(I,j,k) < 0) then - x_upwind(I,j,k) = Tr%t_prev(i+1,j,k) + x_upwind(I,j,k) = Tr%t(i+1,j,k) endif enddo ; enddo ; enddo @@ -185,8 +187,10 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J+1,k) * y_upwind(i,J,k)**2) - south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J-1,k)**2) + ! north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J+1,k) * y_upwind(i,J,k)**2) + ! south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J-1,k)**2) + north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) + south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo @@ -210,9 +214,9 @@ subroutine meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do J=js-1,je ; do i=is,ie if (vhtr(i,J,k) >= 0) then - y_upwind(i,J,k) = Tr%t_prev(i,j,k) + y_upwind(i,J,k) = Tr%t(i,j,k) elseif (vhtr(i,J,k) < 0) then - y_upwind(i,J,k) = Tr%t_prev(i,j+1,k) + y_upwind(i,J,k) = Tr%t(i,j+1,k) endif enddo ; enddo ; enddo diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 555ee81153..e04f78bba4 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -385,13 +385,13 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & - trim(Tr%units)//" 2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) + trim(Tr%units)//" 2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & @@ -419,13 +419,13 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u x_cell_method='sum') Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_m*US%s_to_T) + trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & From 1f14cf3e4f38987dabf4738ccb03ab4bb07e9ed7 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 8 Dec 2025 13:52:31 +1100 Subject: [PATCH 170/288] Back to correct nm + try to force update t_prev --- src/tracer/MOM_tracer_numerical_mixing.F90 | 26 ++++++++++++---------- src/tracer/MOM_tracer_registry.F90 | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 688f02bd95..e915c87ec3 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -129,11 +129,12 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - ! east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I+1,j,k) * x_upwind(I,j,k)**2) - ! west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I-1,j,k)**2) - east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) - west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2) + east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I+1,j,k) * x_upwind(I,j,k)**2) + west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I-1,j,k)**2) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) + ! This code passes the thickness dimensional test but does not accurately calculate numerical mixing + ! east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) + ! west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2) enddo ; enddo; enddo end subroutine thickness_weighted_zonal_variance_flux @@ -156,9 +157,9 @@ subroutine zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do I=is-1,ie if (uhtr(I,j,k) >= 0) then - x_upwind(I,j,k) = Tr%t(i,j,k) + x_upwind(I,j,k) = Tr%t_prev(i,j,k) elseif (uhtr(I,j,k) < 0) then - x_upwind(I,j,k) = Tr%t(i+1,j,k) + x_upwind(I,j,k) = Tr%t_prev(i+1,j,k) endif enddo ; enddo ; enddo @@ -187,11 +188,12 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - ! north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J+1,k) * y_upwind(i,J,k)**2) - ! south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J-1,k)**2) - north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) - south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2) + north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J+1,k) * y_upwind(i,J,k)**2) + south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J-1,k)**2) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) + ! This code passes the thickness dimensional test but is not correct for the numerical mixing diagnostic + ! north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) + ! south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2) enddo ; enddo ; enddo end subroutine thickness_weighted_meridional_variance_flux @@ -214,9 +216,9 @@ subroutine meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do J=js-1,je ; do i=is,ie if (vhtr(i,J,k) >= 0) then - y_upwind(i,J,k) = Tr%t(i,j,k) + y_upwind(i,J,k) = Tr%t_prev(i,j,k) elseif (vhtr(i,J,k) < 0) then - y_upwind(i,J,k) = Tr%t(i,j+1,k) + y_upwind(i,J,k) = Tr%t_prev(i,j+1,k) endif enddo ; enddo ; enddo diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index e04f78bba4..e74a7d2380 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -497,7 +497,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u if ((Tr%id_tendency > 0) .or. (Tr%id_numerical_mixing > 0)) then call safe_alloc_ptr(Tr%t_prev,isd,ied,jsd,jed,nz) - do k=1,nz ; do j=js,je ; do i=is,ie + do k=1,nz ; do j=js-1,je+1 ; do i=is-1,ie+1 Tr%t_prev(i,j,k) = Tr%t(i,j,k) enddo ; enddo ; enddo endif From b46efb546c5171e50ea4f6ba186809d56d34294a Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 9 Dec 2025 10:02:55 +1100 Subject: [PATCH 171/288] More explicit operations + fill another halo point --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- src/tracer/MOM_tracer_registry.F90 | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index e915c87ec3..85b32c76e9 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -129,8 +129,8 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I+1,j,k) * x_upwind(I,j,k)**2) - west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I-1,j,k)**2) + east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) + west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but does not accurately calculate numerical mixing ! east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) @@ -188,8 +188,8 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J+1,k) * y_upwind(i,J,k)**2) - south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J-1,k)**2) + north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) + south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but is not correct for the numerical mixing diagnostic ! north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index e74a7d2380..5dc5178d71 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -497,7 +497,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u if ((Tr%id_tendency > 0) .or. (Tr%id_numerical_mixing > 0)) then call safe_alloc_ptr(Tr%t_prev,isd,ied,jsd,jed,nz) - do k=1,nz ; do j=js-1,je+1 ; do i=is-1,ie+1 + do k=1,nz ; do j=js-2,je+2 ; do i=is-2,ie+2 Tr%t_prev(i,j,k) = Tr%t(i,j,k) enddo ; enddo ; enddo endif From c874c2f6c2effb3304c90168db5895f21e485b86 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 11:05:44 +1100 Subject: [PATCH 172/288] First crack at adding group pass for halo updates --- src/tracer/MOM_tracer_numerical_mixing.F90 | 25 ++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 85b32c76e9..b71a00c6cb 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -5,6 +5,7 @@ module MOM_tracer_numerical_mixing use MOM_grid, only : ocean_grid_type use MOM_tracer_types, only : tracer_type use MOM_verticalGrid, only : verticalGrid_type +use MOM_domains, only : create_group_pass, do_group_pass, group_pass_type implicit none ; private @@ -120,12 +121,18 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: east, west !< East and West for zonal derivative [CU2 H T-1 ~> conc2 m s-1] + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: east, west !< East and West for zonal derivative [CU2 H T-1 ~> conc2 m s-1] + type(group_pass_type) :: pass_uhtr_adx !< A handle used for group halo passes is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke + if (.not.G%symmetric) then + call create_group_pass(pass_uhtr_adx, uhtr, Tr%ad_x, G%Domain, To_North+To_East) + call do_group_pass(pass_uhtr_adx, G%domain) + endif + call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie @@ -179,12 +186,18 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: north, south !< North and South positions for meridional derivative + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: north, south !< North and South positions for meridional derivative + type(group_pass_type) :: pass_vhtr_ady !< A handle used for group halo passes is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke + if (.not.G%symmetric) then + call create_group_pass(pass_vhtr_ady, vhtr, Tr%ad_y, G%Domain, To_North+To_East) + call do_group_pass(pass_vhtr_ady, G%domain) + endif + call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie From 292da827d8497e34e6503926a5bbf95c8064d0eb Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 11:08:39 +1100 Subject: [PATCH 173/288] Forgot to import constants --- src/tracer/MOM_tracer_numerical_mixing.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index b71a00c6cb..2c781f4523 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -6,6 +6,7 @@ module MOM_tracer_numerical_mixing use MOM_tracer_types, only : tracer_type use MOM_verticalGrid, only : verticalGrid_type use MOM_domains, only : create_group_pass, do_group_pass, group_pass_type +use MOM_domains, only : To_North, To_East implicit none ; private From 5b2a65d708f701594753890a9d3a8503db509cee Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 12:00:03 +1100 Subject: [PATCH 174/288] Try only update uhtr --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 2c781f4523..d4775d7b18 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -130,7 +130,7 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke if (.not.G%symmetric) then - call create_group_pass(pass_uhtr_adx, uhtr, Tr%ad_x, G%Domain, To_North+To_East) + call create_group_pass(pass_uhtr_adx, uhtr, G%Domain, To_North+To_East) call do_group_pass(pass_uhtr_adx, G%domain) endif @@ -195,7 +195,7 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke if (.not.G%symmetric) then - call create_group_pass(pass_vhtr_ady, vhtr, Tr%ad_y, G%Domain, To_North+To_East) + call create_group_pass(pass_vhtr_ady, vhtr, G%Domain, To_North+To_East) call do_group_pass(pass_vhtr_ady, G%domain) endif From fe2df7f724da4cd4437d1618034bbef68dd4a041 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 12:18:36 +1100 Subject: [PATCH 175/288] Try a different function call --- src/tracer/MOM_tracer_numerical_mixing.F90 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index d4775d7b18..9b4f58ce91 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -6,7 +6,6 @@ module MOM_tracer_numerical_mixing use MOM_tracer_types, only : tracer_type use MOM_verticalGrid, only : verticalGrid_type use MOM_domains, only : create_group_pass, do_group_pass, group_pass_type -use MOM_domains, only : To_North, To_East implicit none ; private @@ -130,7 +129,7 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke if (.not.G%symmetric) then - call create_group_pass(pass_uhtr_adx, uhtr, G%Domain, To_North+To_East) + call create_group_pass(pass_uhtr_adx, uhtr, G%Domain) call do_group_pass(pass_uhtr_adx, G%domain) endif @@ -195,7 +194,7 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke if (.not.G%symmetric) then - call create_group_pass(pass_vhtr_ady, vhtr, G%Domain, To_North+To_East) + call create_group_pass(pass_vhtr_ady, vhtr, G%Domain) call do_group_pass(pass_vhtr_ady, G%domain) endif From c506b7fb1607e6329ef40c025bfceed2679839d1 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 12:24:06 +1100 Subject: [PATCH 176/288] specify inout --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 9b4f58ce91..bf6efa9dd8 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -112,7 +112,7 @@ end subroutine thickness_weighted_variance_advection subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, res) type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes + real, intent(inout) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure @@ -177,7 +177,7 @@ end subroutine zonal_upwind_values subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, res) type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes + real, intent(inout) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure From 4eb0acbda62dfeb9b954a2013b4e0f9bd6a60bf0 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 12:27:50 +1100 Subject: [PATCH 177/288] Missed some in -> inout changes --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index bf6efa9dd8..b52471d561 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -25,9 +25,9 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt_trans !< The transport time interval [T ~> s] real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] - real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes + real, intent(inout) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes + real, intent(inout) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] @@ -63,9 +63,9 @@ subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] - real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes + real, intent(inout) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes + real, intent(inout) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] From ef079c5afe4390ca4031ac10e6a35c153b8a4431 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 12:30:22 +1100 Subject: [PATCH 178/288] Still missed one --- src/tracer/MOM_tracer_registry.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 5dc5178d71..704c44bfe2 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -782,10 +782,10 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics type(diag_ctrl), intent(in) :: diag !< structure to regulate diagnostic output real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: uhtr !< Accumulated zonal thickness fluxes + intent(inout) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), & - intent(in) :: vhtr !< Accumulated meridional thickness fluxes + intent(inout) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: h !< The updated layer thicknesses [H ~> m or kg m-2] From c62cacfcb42ff3845087331f4946f3a882478cea Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 12:34:05 +1100 Subject: [PATCH 179/288] Hopefully have caught the last one --- src/diagnostics/MOM_diagnostics.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 28ec06dae6..b0773fde15 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1631,9 +1631,9 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy type(ocean_grid_type), intent(inout) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: h !< The updated layer thicknesses [H ~> m or kg m-2] From 03713d050b78be4966d70f4de5ba2807fe2e5b52 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 12:44:47 +1100 Subject: [PATCH 180/288] Update halos for tracer array as well --- src/tracer/MOM_tracer_numerical_mixing.F90 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index b52471d561..c7ddd4b17f 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -20,7 +20,7 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer regsitry real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt_trans !< The transport time interval [T ~> s] @@ -44,7 +44,7 @@ subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer regsitry real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt_trans !< The transport time interval [T ~> s] @@ -61,7 +61,7 @@ subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer regsitry real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] real, intent(inout) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] @@ -80,7 +80,7 @@ end subroutine variance_flux !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. subroutine thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt, Idt, G, GV, res) - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer registry real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt !< The transport time interval [T ~> s] @@ -111,7 +111,7 @@ end subroutine thickness_weighted_variance_advection !! from upwind values. subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, res) - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer registry real, intent(inout) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] type(ocean_grid_type), intent(in) :: G !< Ocean grid structure @@ -130,6 +130,7 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind if (.not.G%symmetric) then call create_group_pass(pass_uhtr_adx, uhtr, G%Domain) + call create_group_pass(pass_uhtr_adx, Tr%ad_x, G%Domain) call do_group_pass(pass_uhtr_adx, G%domain) endif @@ -176,7 +177,7 @@ end subroutine zonal_upwind_values !! from upwind values. subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, res) - type(tracer_type), intent(in) :: Tr !< Tracer + type(tracer_type), intent(inout) :: Tr !< Tracer real, intent(inout) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] type(ocean_grid_type), intent(in) :: G !< Ocean grid structure @@ -195,6 +196,7 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u if (.not.G%symmetric) then call create_group_pass(pass_vhtr_ady, vhtr, G%Domain) + call create_group_pass(pass_vhtr_ady, Tr%ad_y, G%Domain) call do_group_pass(pass_vhtr_ady, G%domain) endif From 3b799438ee0c75a098c49bf28c060187165aaec4 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 13:40:39 +1100 Subject: [PATCH 181/288] Undo the halo updating and do somewhere else --- src/diagnostics/MOM_diagnostics.F90 | 4 +-- src/tracer/MOM_tracer_numerical_mixing.F90 | 39 +++++++--------------- src/tracer/MOM_tracer_registry.F90 | 4 +-- 3 files changed, 16 insertions(+), 31 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index b0773fde15..28ec06dae6 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1631,9 +1631,9 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy type(ocean_grid_type), intent(inout) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr !< Accumulated zonal thickness fluxes + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: vhtr !< Accumulated meridional thickness fluxes + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: h !< The updated layer thicknesses [H ~> m or kg m-2] diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index c7ddd4b17f..9f2b5298c7 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -5,7 +5,6 @@ module MOM_tracer_numerical_mixing use MOM_grid, only : ocean_grid_type use MOM_tracer_types, only : tracer_type use MOM_verticalGrid, only : verticalGrid_type -use MOM_domains, only : create_group_pass, do_group_pass, group_pass_type implicit none ; private @@ -20,14 +19,14 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer regsitry + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt_trans !< The transport time interval [T ~> s] real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] - real, intent(inout) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes + real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes + real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] @@ -44,7 +43,7 @@ subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer regsitry + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt_trans !< The transport time interval [T ~> s] @@ -61,11 +60,11 @@ subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer regsitry + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] - real, intent(inout) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes + real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes + real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] @@ -80,7 +79,7 @@ end subroutine variance_flux !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. subroutine thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt, Idt, G, GV, res) - type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer registry + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt !< The transport time interval [T ~> s] @@ -111,8 +110,8 @@ end subroutine thickness_weighted_variance_advection !! from upwind values. subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, res) - type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer registry - real, intent(inout) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure @@ -124,16 +123,9 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters real :: east, west !< East and West for zonal derivative [CU2 H T-1 ~> conc2 m s-1] - type(group_pass_type) :: pass_uhtr_adx !< A handle used for group halo passes is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - if (.not.G%symmetric) then - call create_group_pass(pass_uhtr_adx, uhtr, G%Domain) - call create_group_pass(pass_uhtr_adx, Tr%ad_x, G%Domain) - call do_group_pass(pass_uhtr_adx, G%domain) - endif - call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie @@ -177,8 +169,8 @@ end subroutine zonal_upwind_values !! from upwind values. subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, res) - type(tracer_type), intent(inout) :: Tr !< Tracer - real, intent(inout) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes + type(tracer_type), intent(in) :: Tr !< Tracer + real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure @@ -190,16 +182,9 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters real :: north, south !< North and South positions for meridional derivative - type(group_pass_type) :: pass_vhtr_ady !< A handle used for group halo passes is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - if (.not.G%symmetric) then - call create_group_pass(pass_vhtr_ady, vhtr, G%Domain) - call create_group_pass(pass_vhtr_ady, Tr%ad_y, G%Domain) - call do_group_pass(pass_vhtr_ady, G%domain) - endif - call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 704c44bfe2..5dc5178d71 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -782,10 +782,10 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics type(diag_ctrl), intent(in) :: diag !< structure to regulate diagnostic output real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), & - intent(inout) :: uhtr !< Accumulated zonal thickness fluxes + intent(in) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), & - intent(inout) :: vhtr !< Accumulated meridional thickness fluxes + intent(in) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: h !< The updated layer thicknesses [H ~> m or kg m-2] From 0b5eb85361f05cb6fa8b4b6c46907f073c57fc6e Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 14:12:47 +1100 Subject: [PATCH 182/288] Print statement to check value --- src/tracer/MOM_tracer_numerical_mixing.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 9f2b5298c7..13d0b29191 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -128,6 +128,8 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) + print *, "uhtr(0, 1, 1) = ", uhtr(0,1,1) + print *, "Tr%ad_x(0,1,1) = ", Tr%ad_x(0,1,1) do k=1,nz ; do j=js,je ; do i=is,ie east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) From 74222eac8b307c8a38d25dcdc39a06142ef97dae Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 14:18:02 +1100 Subject: [PATCH 183/288] Change indexing for adx aand ady + print statements --- src/tracer/MOM_tracer_numerical_mixing.F90 | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 13d0b29191..18da123459 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -131,8 +131,8 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind print *, "uhtr(0, 1, 1) = ", uhtr(0,1,1) print *, "Tr%ad_x(0,1,1) = ", Tr%ad_x(0,1,1) do k=1,nz ; do j=js,je ; do i=is,ie - east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) - west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) + east = (2 * (Tr%ad_x(I+1,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) + west = (2 * (Tr%ad_x(I,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but does not accurately calculate numerical mixing ! east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) @@ -189,9 +189,11 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) + print *, "vhtr(0, 1, 1) = ", vhtr(0,1,1) + print *, "Tr%ad_y(0,1,1) = ", Tr%ad_y(0,1,1) do k=1,nz ; do j=js,je ; do i=is,ie - north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) - south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) + north = (2 * (Tr%ad_y(i,J+1,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) + south = (2 * (Tr%ad_y(i,J,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but is not correct for the numerical mixing diagnostic ! north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) From 621bec3ff085dd7803b7f8a78c69146dff4e8e23 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 14:25:41 +1100 Subject: [PATCH 184/288] Flexible start indexes --- src/tracer/MOM_tracer_numerical_mixing.F90 | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 18da123459..1fa3ae9f29 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -128,8 +128,10 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) - print *, "uhtr(0, 1, 1) = ", uhtr(0,1,1) - print *, "Tr%ad_x(0,1,1) = ", Tr%ad_x(0,1,1) + print *, "uhtr(is-1, js, 1) = ", uhtr(is-1,js,1) + print *, "uhtr(is+1, js, 1) = ", uhtr(is+1,js,1) + print *, "Tr%ad_x(is-1,js,1) = ", Tr%ad_x(is-1,js,1) + print *, "Tr%ad_x(is+1,js,1) = ", Tr%ad_x(is+1,js,1) do k=1,nz ; do j=js,je ; do i=is,ie east = (2 * (Tr%ad_x(I+1,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) west = (2 * (Tr%ad_x(I,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) @@ -189,8 +191,10 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) - print *, "vhtr(0, 1, 1) = ", vhtr(0,1,1) - print *, "Tr%ad_y(0,1,1) = ", Tr%ad_y(0,1,1) + print *, "vhtr(is, js-1, 1) = ", vhtr(is,js-1,1) + print *, "vhtr(is, js+1, 1) = ", vhtr(is,js+1,1) + print *, "Tr%ad_y(is,js-1,1) = ", Tr%ad_y(is,js-1,1) + print *, "Tr%ad_y(is,js+1,1) = ", Tr%ad_y(is,js+1,1) do k=1,nz ; do j=js,je ; do i=is,ie north = (2 * (Tr%ad_y(i,J+1,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) south = (2 * (Tr%ad_y(i,J,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) From 3fc3a151ac858c715b05d47efc9d6fe824641267 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 14:52:13 +1100 Subject: [PATCH 185/288] More print statements but use 'correct' indexing --- src/tracer/MOM_tracer_numerical_mixing.F90 | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 1fa3ae9f29..4e8bcab636 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -130,11 +130,15 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind print *, "uhtr(is-1, js, 1) = ", uhtr(is-1,js,1) print *, "uhtr(is+1, js, 1) = ", uhtr(is+1,js,1) + print *, "uhtr(ie-1, js, 1) = ", uhtr(ie-1,js,1) + print *, "uhtr(ie+1, js, 1) = ", uhtr(ie+1,js,1) print *, "Tr%ad_x(is-1,js,1) = ", Tr%ad_x(is-1,js,1) print *, "Tr%ad_x(is+1,js,1) = ", Tr%ad_x(is+1,js,1) + print *, "Tr%ad_x(ie-1,js,1) = ", Tr%ad_x(ie-1,js,1) + print *, "Tr%ad_x(ie+1,js,1) = ", Tr%ad_x(ie+1,js,1) do k=1,nz ; do j=js,je ; do i=is,ie - east = (2 * (Tr%ad_x(I+1,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) - west = (2 * (Tr%ad_x(I,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) + east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) + west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but does not accurately calculate numerical mixing ! east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) @@ -191,13 +195,17 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) - print *, "vhtr(is, js-1, 1) = ", vhtr(is,js-1,1) + print *, "vhtr(is, js, 1) = ", vhtr(is,js,1) print *, "vhtr(is, js+1, 1) = ", vhtr(is,js+1,1) + print *, "vhtr(is, je, 1) = ", vhtr(is,je,1) + print *, "vhtr(is, je+1, 1) = ", vhtr(is,je+1,1) print *, "Tr%ad_y(is,js-1,1) = ", Tr%ad_y(is,js-1,1) print *, "Tr%ad_y(is,js+1,1) = ", Tr%ad_y(is,js+1,1) + print *, "Tr%ad_y(is,je-1,1) = ", Tr%ad_y(is,je-1,1) + print *, "Tr%ad_y(is,je+1,1) = ", Tr%ad_y(is,je+1,1) do k=1,nz ; do j=js,je ; do i=is,ie - north = (2 * (Tr%ad_y(i,J+1,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) - south = (2 * (Tr%ad_y(i,J,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) + north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) + south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but is not correct for the numerical mixing diagnostic ! north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) From b6aef69eb53a0ce3532ed9277eb358f69217bb57 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 15:07:12 +1100 Subject: [PATCH 186/288] Avoid halo altogether --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 4e8bcab636..f17dd64ce7 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -136,7 +136,7 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind print *, "Tr%ad_x(is+1,js,1) = ", Tr%ad_x(is+1,js,1) print *, "Tr%ad_x(ie-1,js,1) = ", Tr%ad_x(ie-1,js,1) print *, "Tr%ad_x(ie+1,js,1) = ", Tr%ad_x(ie+1,js,1) - do k=1,nz ; do j=js,je ; do i=is,ie + do k=1,nz ; do j=js,je ; do i=is+1,ie-1 east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) @@ -203,7 +203,7 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u print *, "Tr%ad_y(is,js+1,1) = ", Tr%ad_y(is,js+1,1) print *, "Tr%ad_y(is,je-1,1) = ", Tr%ad_y(is,je-1,1) print *, "Tr%ad_y(is,je+1,1) = ", Tr%ad_y(is,je+1,1) - do k=1,nz ; do j=js,je ; do i=is,ie + do k=1,nz ; do j=js+1,je-1 ; do i=is,ie north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) From 73b2c6cd130b8924e12a3e131ff94f149e6d5069 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 15:44:03 +1100 Subject: [PATCH 187/288] Upwind vairable index for transport + 1 --- src/tracer/MOM_tracer_numerical_mixing.F90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index f17dd64ce7..c3aa39c4d2 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -136,7 +136,7 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind print *, "Tr%ad_x(is+1,js,1) = ", Tr%ad_x(is+1,js,1) print *, "Tr%ad_x(ie-1,js,1) = ", Tr%ad_x(ie-1,js,1) print *, "Tr%ad_x(ie+1,js,1) = ", Tr%ad_x(ie+1,js,1) - do k=1,nz ; do j=js,je ; do i=is+1,ie-1 + do k=1,nz ; do j=js,je ; do i=is,ie east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) @@ -164,9 +164,9 @@ subroutine zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do k=1,nz ; do j=js,je ; do I=is-1,ie - if (uhtr(I,j,k) >= 0) then + if (uhtr(I+1,j,k) >= 0) then x_upwind(I,j,k) = Tr%t_prev(i,j,k) - elseif (uhtr(I,j,k) < 0) then + elseif (uhtr(I+1,j,k) < 0) then x_upwind(I,j,k) = Tr%t_prev(i+1,j,k) endif enddo ; enddo ; enddo @@ -203,7 +203,7 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u print *, "Tr%ad_y(is,js+1,1) = ", Tr%ad_y(is,js+1,1) print *, "Tr%ad_y(is,je-1,1) = ", Tr%ad_y(is,je-1,1) print *, "Tr%ad_y(is,je+1,1) = ", Tr%ad_y(is,je+1,1) - do k=1,nz ; do j=js+1,je-1 ; do i=is,ie + do k=1,nz ; do j=js,je ; do i=is,ie north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) @@ -231,9 +231,9 @@ subroutine meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do k=1,nz ; do J=js-1,je ; do i=is,ie - if (vhtr(i,J,k) >= 0) then + if (vhtr(i,J+1,k) >= 0) then y_upwind(i,J,k) = Tr%t_prev(i,j,k) - elseif (vhtr(i,J,k) < 0) then + elseif (vhtr(i,J+1,k) < 0) then y_upwind(i,J,k) = Tr%t_prev(i,j+1,k) endif enddo ; enddo ; enddo From d3d29ba32c4326bcd50a77d868f153dc185b4573 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 21:51:41 +1100 Subject: [PATCH 188/288] Revery upwind indexing + try to fill halos for adx ady --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- src/tracer/MOM_tracer_registry.F90 | 5 +++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index c3aa39c4d2..4e8bcab636 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -164,9 +164,9 @@ subroutine zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do k=1,nz ; do j=js,je ; do I=is-1,ie - if (uhtr(I+1,j,k) >= 0) then + if (uhtr(I,j,k) >= 0) then x_upwind(I,j,k) = Tr%t_prev(i,j,k) - elseif (uhtr(I+1,j,k) < 0) then + elseif (uhtr(I,j,k) < 0) then x_upwind(I,j,k) = Tr%t_prev(i+1,j,k) endif enddo ; enddo ; enddo @@ -231,9 +231,9 @@ subroutine meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do k=1,nz ; do J=js-1,je ; do i=is,ie - if (vhtr(i,J+1,k) >= 0) then + if (vhtr(i,J,k) >= 0) then y_upwind(i,J,k) = Tr%t_prev(i,j,k) - elseif (vhtr(i,J+1,k) < 0) then + elseif (vhtr(i,J,k) < 0) then y_upwind(i,J,k) = Tr%t_prev(i,j+1,k) endif enddo ; enddo ; enddo diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 5dc5178d71..997fea78d0 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -14,6 +14,7 @@ module MOM_tracer_registry use MOM_diag_mediator, only : diag_ctrl, register_diag_field, post_data, safe_alloc_ptr use MOM_diag_mediator, only : diag_grid_storage use MOM_diag_mediator, only : diag_copy_storage_to_diag, diag_save_grids, diag_restore_grids +use MOM_domains, only : create_group_pass, do_group_pass, group_pass_type use MOM_error_handler, only : MOM_error, FATAL, WARNING, MOM_mesg, is_root_pe use MOM_file_parser, only : get_param, log_version, param_file_type use MOM_hor_index, only : hor_index_type @@ -809,6 +810,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. type(tracer_type), pointer :: Tr=>NULL() + type(group_pass_type) :: pass_adx_ady is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke H_to_RZ_dt = GV%H_to_RZ * Idt @@ -866,6 +868,9 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. nm(:,:,:) = 0. + call create_group_pass(pass_adx_ady, Tr%ad_x, G%Domain) + call create_group_pass(pass_adx_ady, Tr%ad_y, G%Domain) + call do_group_pass(pass_adx_ady, Tr%ad_x, G%Domain) call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & x_upwind, y_upwind, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) From 1dece796c08cfc287ea0eb8b236495c0e40757c8 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 21:54:47 +1100 Subject: [PATCH 189/288] Correct call to do_group_pass --- src/tracer/MOM_tracer_registry.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 997fea78d0..4360973578 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -870,7 +870,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d nm(:,:,:) = 0. call create_group_pass(pass_adx_ady, Tr%ad_x, G%Domain) call create_group_pass(pass_adx_ady, Tr%ad_y, G%Domain) - call do_group_pass(pass_adx_ady, Tr%ad_x, G%Domain) + call do_group_pass(pass_adx_ady, G%Domain) call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & x_upwind, y_upwind, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) From c389b319a059b5d4151eec6de3f9bdcddffbbd06 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 22:07:35 +1100 Subject: [PATCH 190/288] Only update for non-symmetric --- src/tracer/MOM_tracer_registry.F90 | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 4360973578..14c0900339 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -14,7 +14,8 @@ module MOM_tracer_registry use MOM_diag_mediator, only : diag_ctrl, register_diag_field, post_data, safe_alloc_ptr use MOM_diag_mediator, only : diag_grid_storage use MOM_diag_mediator, only : diag_copy_storage_to_diag, diag_save_grids, diag_restore_grids -use MOM_domains, only : create_group_pass, do_group_pass, group_pass_type +use MOM_domains, only : create_group_pass, do_group_pass, group_pass_type +! use MOM_domains, only : To_North, To_East use MOM_error_handler, only : MOM_error, FATAL, WARNING, MOM_mesg, is_root_pe use MOM_file_parser, only : get_param, log_version, param_file_type use MOM_hor_index, only : hor_index_type @@ -868,9 +869,11 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. nm(:,:,:) = 0. - call create_group_pass(pass_adx_ady, Tr%ad_x, G%Domain) - call create_group_pass(pass_adx_ady, Tr%ad_y, G%Domain) - call do_group_pass(pass_adx_ady, G%Domain) + if (.not.G%symmetric) then + call create_group_pass(pass_adx_ady, Tr%ad_x, G%Domain) + call create_group_pass(pass_adx_ady, Tr%ad_y, G%Domain) + call do_group_pass(pass_adx_ady, G%Domain) + endif call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & x_upwind, y_upwind, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) From 7e5b117574cf7f254d77004bf5ab649091076923 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 22:20:01 +1100 Subject: [PATCH 191/288] Update halos for thickness transports --- src/tracer/MOM_tracer_registry.F90 | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 14c0900339..f60defc06f 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -15,7 +15,7 @@ module MOM_tracer_registry use MOM_diag_mediator, only : diag_grid_storage use MOM_diag_mediator, only : diag_copy_storage_to_diag, diag_save_grids, diag_restore_grids use MOM_domains, only : create_group_pass, do_group_pass, group_pass_type -! use MOM_domains, only : To_North, To_East +! use MOM_domains, only : To_South, To_West use MOM_error_handler, only : MOM_error, FATAL, WARNING, MOM_mesg, is_root_pe use MOM_file_parser, only : get_param, log_version, param_file_type use MOM_hor_index, only : hor_index_type @@ -784,10 +784,10 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics type(diag_ctrl), intent(in) :: diag !< structure to regulate diagnostic output real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: uhtr !< Accumulated zonal thickness fluxes + intent(inout) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), & - intent(in) :: vhtr !< Accumulated meridional thickness fluxes + intent(inout) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: h !< The updated layer thicknesses [H ~> m or kg m-2] @@ -811,7 +811,8 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. type(tracer_type), pointer :: Tr=>NULL() - type(group_pass_type) :: pass_adx_ady + type(group_pass_type) :: pass_uhtr_adx + type(group_pass_type) :: pass_vhtr_ady is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke H_to_RZ_dt = GV%H_to_RZ * Idt @@ -870,9 +871,12 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d y_upwind(:,:,:) = 0. nm(:,:,:) = 0. if (.not.G%symmetric) then - call create_group_pass(pass_adx_ady, Tr%ad_x, G%Domain) - call create_group_pass(pass_adx_ady, Tr%ad_y, G%Domain) - call do_group_pass(pass_adx_ady, G%Domain) + call create_group_pass(pass_uhtr_adx, uhtr, G%Domain) !To_South+To_West + call create_group_pass(pass_uhtr_adx, Tr%ad_x, G%Domain) + call do_group_pass(pass_uhtr_adx, G%Domain) + call create_group_pass(pass_vhtr_ady, vhtr, G%Domain) !To_South+To_West + call create_group_pass(pass_vhtr_ady, Tr%ad_y, G%Domain) + call do_group_pass(pass_vhtr_ady, G%Domain) endif call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & x_upwind, y_upwind, nm) From c5845e7ea235718887b2d671e4fa644040f18121 Mon Sep 17 00:00:00 2001 From: jbisits Date: Wed, 10 Dec 2025 22:24:50 +1100 Subject: [PATCH 192/288] Needed another inout declaration --- src/diagnostics/MOM_diagnostics.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 28ec06dae6..b0773fde15 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1631,9 +1631,9 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy type(ocean_grid_type), intent(inout) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: h !< The updated layer thicknesses [H ~> m or kg m-2] From f1929acc0d1950d7bc596ff24021c30313941f5d Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 11 Dec 2025 11:03:35 +1100 Subject: [PATCH 193/288] Remove attempts at halo update + upwind printing --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++++++ src/tracer/MOM_tracer_registry.F90 | 10 ---------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 4e8bcab636..55ac8b2e45 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -136,6 +136,10 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind print *, "Tr%ad_x(is+1,js,1) = ", Tr%ad_x(is+1,js,1) print *, "Tr%ad_x(ie-1,js,1) = ", Tr%ad_x(ie-1,js,1) print *, "Tr%ad_x(ie+1,js,1) = ", Tr%ad_x(ie+1,js,1) + print *, "xupwind(is-1,js,1) = ", x_upwind(is-1,js,1) + print *, "xupwind(is+1,js,1) = ", x_upwind(is+1,js,1) + print *, "xupwind(ie-1,js,1) = ", x_upwind(ie-1,js,1) + print *, "xupwind(ie+1,js,1) = ", x_upwind(ie+1,js,1) do k=1,nz ; do j=js,je ; do i=is,ie east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) @@ -203,6 +207,10 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u print *, "Tr%ad_y(is,js+1,1) = ", Tr%ad_y(is,js+1,1) print *, "Tr%ad_y(is,je-1,1) = ", Tr%ad_y(is,je-1,1) print *, "Tr%ad_y(is,je+1,1) = ", Tr%ad_y(is,je+1,1) + print *, "yupwind(is-1,js,1) = ", y_upwind(is-1,js,1) + print *, "yupwind(is+1,js,1) = ", y_upwind(is+1,js,1) + print *, "yupwind(ie-1,js,1) = ", y_upwind(ie-1,js,1) + print *, "yupwind(ie+1,js,1) = ", y_upwind(ie+1,js,1) do k=1,nz ; do j=js,je ; do i=is,ie north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index f60defc06f..0fc6919db0 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -14,8 +14,6 @@ module MOM_tracer_registry use MOM_diag_mediator, only : diag_ctrl, register_diag_field, post_data, safe_alloc_ptr use MOM_diag_mediator, only : diag_grid_storage use MOM_diag_mediator, only : diag_copy_storage_to_diag, diag_save_grids, diag_restore_grids -use MOM_domains, only : create_group_pass, do_group_pass, group_pass_type -! use MOM_domains, only : To_South, To_West use MOM_error_handler, only : MOM_error, FATAL, WARNING, MOM_mesg, is_root_pe use MOM_file_parser, only : get_param, log_version, param_file_type use MOM_hor_index, only : hor_index_type @@ -870,14 +868,6 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. nm(:,:,:) = 0. - if (.not.G%symmetric) then - call create_group_pass(pass_uhtr_adx, uhtr, G%Domain) !To_South+To_West - call create_group_pass(pass_uhtr_adx, Tr%ad_x, G%Domain) - call do_group_pass(pass_uhtr_adx, G%Domain) - call create_group_pass(pass_vhtr_ady, vhtr, G%Domain) !To_South+To_West - call create_group_pass(pass_vhtr_ady, Tr%ad_y, G%Domain) - call do_group_pass(pass_vhtr_ady, G%Domain) - endif call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & x_upwind, y_upwind, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) From 103b40e445fb4d5d3e65dcea8fd3f69eb5eb80ca Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 11 Dec 2025 11:09:22 +1100 Subject: [PATCH 194/288] Remove unneeded inouts and local variables --- src/diagnostics/MOM_diagnostics.F90 | 4 ++-- src/tracer/MOM_tracer_registry.F90 | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index b0773fde15..28ec06dae6 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1631,9 +1631,9 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy type(ocean_grid_type), intent(inout) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr !< Accumulated zonal thickness fluxes + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: vhtr !< Accumulated meridional thickness fluxes + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: h !< The updated layer thicknesses [H ~> m or kg m-2] diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 0fc6919db0..5dc5178d71 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -782,10 +782,10 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics type(diag_ctrl), intent(in) :: diag !< structure to regulate diagnostic output real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), & - intent(inout) :: uhtr !< Accumulated zonal thickness fluxes + intent(in) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), & - intent(inout) :: vhtr !< Accumulated meridional thickness fluxes + intent(in) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: h !< The updated layer thicknesses [H ~> m or kg m-2] @@ -809,8 +809,6 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. type(tracer_type), pointer :: Tr=>NULL() - type(group_pass_type) :: pass_uhtr_adx - type(group_pass_type) :: pass_vhtr_ady is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke H_to_RZ_dt = GV%H_to_RZ * Idt From 58441575e11c581bfb2291e440bb00c04b8fc7ce Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 15 Dec 2025 10:14:38 +1100 Subject: [PATCH 195/288] Remove print statements --- src/tracer/MOM_tracer_numerical_mixing.F90 | 24 ---------------------- 1 file changed, 24 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 55ac8b2e45..9f2b5298c7 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -128,18 +128,6 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) - print *, "uhtr(is-1, js, 1) = ", uhtr(is-1,js,1) - print *, "uhtr(is+1, js, 1) = ", uhtr(is+1,js,1) - print *, "uhtr(ie-1, js, 1) = ", uhtr(ie-1,js,1) - print *, "uhtr(ie+1, js, 1) = ", uhtr(ie+1,js,1) - print *, "Tr%ad_x(is-1,js,1) = ", Tr%ad_x(is-1,js,1) - print *, "Tr%ad_x(is+1,js,1) = ", Tr%ad_x(is+1,js,1) - print *, "Tr%ad_x(ie-1,js,1) = ", Tr%ad_x(ie-1,js,1) - print *, "Tr%ad_x(ie+1,js,1) = ", Tr%ad_x(ie+1,js,1) - print *, "xupwind(is-1,js,1) = ", x_upwind(is-1,js,1) - print *, "xupwind(is+1,js,1) = ", x_upwind(is+1,js,1) - print *, "xupwind(ie-1,js,1) = ", x_upwind(ie-1,js,1) - print *, "xupwind(ie+1,js,1) = ", x_upwind(ie+1,js,1) do k=1,nz ; do j=js,je ; do i=is,ie east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) @@ -199,18 +187,6 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) - print *, "vhtr(is, js, 1) = ", vhtr(is,js,1) - print *, "vhtr(is, js+1, 1) = ", vhtr(is,js+1,1) - print *, "vhtr(is, je, 1) = ", vhtr(is,je,1) - print *, "vhtr(is, je+1, 1) = ", vhtr(is,je+1,1) - print *, "Tr%ad_y(is,js-1,1) = ", Tr%ad_y(is,js-1,1) - print *, "Tr%ad_y(is,js+1,1) = ", Tr%ad_y(is,js+1,1) - print *, "Tr%ad_y(is,je-1,1) = ", Tr%ad_y(is,je-1,1) - print *, "Tr%ad_y(is,je+1,1) = ", Tr%ad_y(is,je+1,1) - print *, "yupwind(is-1,js,1) = ", y_upwind(is-1,js,1) - print *, "yupwind(is+1,js,1) = ", y_upwind(is+1,js,1) - print *, "yupwind(ie-1,js,1) = ", y_upwind(ie-1,js,1) - print *, "yupwind(ie+1,js,1) = ", y_upwind(ie+1,js,1) do k=1,nz ; do j=js,je ; do i=is,ie north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) From 505b56432447a5ae5361dd70a92eff0b1289a33f Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 15 Dec 2025 10:36:06 +1100 Subject: [PATCH 196/288] Use same uhtr and vhtr values in upwind calculation --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 9f2b5298c7..ae66da80fb 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -156,9 +156,9 @@ subroutine zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do k=1,nz ; do j=js,je ; do I=is-1,ie - if (uhtr(I,j,k) >= 0) then + if (uhtr(I+1,j,k) >= 0) then x_upwind(I,j,k) = Tr%t_prev(i,j,k) - elseif (uhtr(I,j,k) < 0) then + elseif (uhtr(I+1,j,k) < 0) then x_upwind(I,j,k) = Tr%t_prev(i+1,j,k) endif enddo ; enddo ; enddo @@ -215,9 +215,9 @@ subroutine meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do k=1,nz ; do J=js-1,je ; do i=is,ie - if (vhtr(i,J,k) >= 0) then + if (vhtr(i,J+1,k) >= 0) then y_upwind(i,J,k) = Tr%t_prev(i,j,k) - elseif (vhtr(i,J,k) < 0) then + elseif (vhtr(i,J+1,k) < 0) then y_upwind(i,J,k) = Tr%t_prev(i,j+1,k) endif enddo ; enddo ; enddo From d8451f5e6f5aa18056ee53290fda4c76fde326c2 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 15 Dec 2025 10:39:52 +1100 Subject: [PATCH 197/288] Print indexes where adx is saved --- src/tracer/MOM_tracer_advect.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tracer/MOM_tracer_advect.F90 b/src/tracer/MOM_tracer_advect.F90 index a2d43e80a9..606fdb73fe 100644 --- a/src/tracer/MOM_tracer_advect.F90 +++ b/src/tracer/MOM_tracer_advect.F90 @@ -707,6 +707,7 @@ subroutine advect_x(Tr, hprev, uhr, uh_neglect, OBC, domore_u, ntr, Idt, & ! diagnostics if (associated(Tr(m)%ad_x)) then ; do I=is-1,ie ; if (do_i(i,j) .or. do_i(i+1,j)) then + print *, "I index for adx data = ", I Tr(m)%ad_x(I,j,k) = Tr(m)%ad_x(I,j,k) + flux_x(I,j,m)*Idt endif ; enddo ; endif @@ -1137,6 +1138,7 @@ subroutine advect_y(Tr, hprev, vhr, vh_neglect, OBC, domore_v, ntr, Idt, & do m=1,ntr ; if (associated(Tr(m)%ad_y)) then do J=js-1,je ; if (domore_v_initial(J)) then do i=is,ie ; if (do_i(i,j) .or. do_i(i,j+1)) then + print *, "J index for ady loop = ", J Tr(m)%ad_y(i,J,k) = Tr(m)%ad_y(i,J,k) + flux_y(i,m,J)*Idt endif ; enddo endif ; enddo From 1993ab37460912176b02210c122184da92df9c58 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 15 Dec 2025 10:54:05 +1100 Subject: [PATCH 198/288] Remove print statements --- src/tracer/MOM_tracer_advect.F90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tracer/MOM_tracer_advect.F90 b/src/tracer/MOM_tracer_advect.F90 index 606fdb73fe..a2d43e80a9 100644 --- a/src/tracer/MOM_tracer_advect.F90 +++ b/src/tracer/MOM_tracer_advect.F90 @@ -707,7 +707,6 @@ subroutine advect_x(Tr, hprev, uhr, uh_neglect, OBC, domore_u, ntr, Idt, & ! diagnostics if (associated(Tr(m)%ad_x)) then ; do I=is-1,ie ; if (do_i(i,j) .or. do_i(i+1,j)) then - print *, "I index for adx data = ", I Tr(m)%ad_x(I,j,k) = Tr(m)%ad_x(I,j,k) + flux_x(I,j,m)*Idt endif ; enddo ; endif @@ -1138,7 +1137,6 @@ subroutine advect_y(Tr, hprev, vhr, vh_neglect, OBC, domore_v, ntr, Idt, & do m=1,ntr ; if (associated(Tr(m)%ad_y)) then do J=js-1,je ; if (domore_v_initial(J)) then do i=is,ie ; if (do_i(i,j) .or. do_i(i,j+1)) then - print *, "J index for ady loop = ", J Tr(m)%ad_y(i,J,k) = Tr(m)%ad_y(i,J,k) + flux_y(i,m,J)*Idt endif ; enddo endif ; enddo From 337d7f4005e20890c765f6cf5e9e439bb8fb62b3 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 15 Dec 2025 13:45:33 +1100 Subject: [PATCH 199/288] Add pass call before transport diagnostics --- src/core/MOM.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/MOM.F90 b/src/core/MOM.F90 index c79b47f5db..5ba7cf01a9 100644 --- a/src/core/MOM.F90 +++ b/src/core/MOM.F90 @@ -1523,6 +1523,7 @@ subroutine step_MOM_tracer_dyn(CS, G, GV, US, h, Time_local) call cpu_clock_end(id_clock_tracer) ; call cpu_clock_end(id_clock_thermo) call cpu_clock_begin(id_clock_other) ; call cpu_clock_begin(id_clock_diagnostics) + call pass_vector(CS%uhtr, CS%vhtr, G%Domain) call post_transport_diagnostics(G, GV, US, CS%uhtr, CS%vhtr, h, CS%transport_IDs, & CS%diag_pre_dyn, CS%diag, CS%t_dyn_rel_adv, CS%tracer_reg) ! Rebuild the remap grids now that we've posted the fields which rely on thicknesses From de206154b9a260436ec8f80328be7cceb8cd2106 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 15 Dec 2025 14:27:16 +1100 Subject: [PATCH 200/288] Remove added pass_var --- src/core/MOM.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/MOM.F90 b/src/core/MOM.F90 index 5ba7cf01a9..c79b47f5db 100644 --- a/src/core/MOM.F90 +++ b/src/core/MOM.F90 @@ -1523,7 +1523,6 @@ subroutine step_MOM_tracer_dyn(CS, G, GV, US, h, Time_local) call cpu_clock_end(id_clock_tracer) ; call cpu_clock_end(id_clock_thermo) call cpu_clock_begin(id_clock_other) ; call cpu_clock_begin(id_clock_diagnostics) - call pass_vector(CS%uhtr, CS%vhtr, G%Domain) call post_transport_diagnostics(G, GV, US, CS%uhtr, CS%vhtr, h, CS%transport_IDs, & CS%diag_pre_dyn, CS%diag, CS%t_dyn_rel_adv, CS%tracer_reg) ! Rebuild the remap grids now that we've posted the fields which rely on thicknesses From de39254b84245373437225159a87c375e31b3df8 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 15 Dec 2025 20:19:53 +1100 Subject: [PATCH 201/288] Fill more of the t_prev data to avoid finite difference errors --- src/tracer/MOM_tracer_registry.F90 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 5dc5178d71..7ae6810bf1 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -752,6 +752,11 @@ subroutine post_tracer_diagnostics_at_sync(Reg, h, diag_prev, diag, G, GV, dt) enddo ; enddo ; enddo call post_data(Tr%id_tendency, work3d, diag, alt_h=diag_prev%h_state) endif + if (Tr%id_numerical_mixing > 0) + do k=1,nz ; do j=js-1,je-1 ; do i=is-1,ie-1 + tr%t_prev(i,j,k) = Tr%t(i,j,k) + enddo ; enddo ; enddo + endif if ((Tr%id_trxh_tendency > 0) .or. (Tr%id_trxh_tendency_2d > 0)) then do k=1,nz ; do j=js,je ; do i=is,ie work3d(i,j,k) = (Tr%t(i,j,k)*h(i,j,k) - Tr%Trxh_prev(i,j,k)) * Idt From dc5189914053a367adf453c6fb4c5f0210b00f99 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 15 Dec 2025 20:28:07 +1100 Subject: [PATCH 202/288] Forgot then --- src/tracer/MOM_tracer_registry.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 7ae6810bf1..a4709b0b88 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -752,7 +752,7 @@ subroutine post_tracer_diagnostics_at_sync(Reg, h, diag_prev, diag, G, GV, dt) enddo ; enddo ; enddo call post_data(Tr%id_tendency, work3d, diag, alt_h=diag_prev%h_state) endif - if (Tr%id_numerical_mixing > 0) + if (Tr%id_numerical_mixing > 0) then do k=1,nz ; do j=js-1,je-1 ; do i=is-1,ie-1 tr%t_prev(i,j,k) = Tr%t(i,j,k) enddo ; enddo ; enddo From 9b2d26de593643666549307ed5f6ac4bcf4af781 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 15 Dec 2025 21:06:24 +1100 Subject: [PATCH 203/288] Wrong upper index --- src/tracer/MOM_tracer_registry.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index a4709b0b88..32513c2f40 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -753,7 +753,7 @@ subroutine post_tracer_diagnostics_at_sync(Reg, h, diag_prev, diag, G, GV, dt) call post_data(Tr%id_tendency, work3d, diag, alt_h=diag_prev%h_state) endif if (Tr%id_numerical_mixing > 0) then - do k=1,nz ; do j=js-1,je-1 ; do i=is-1,ie-1 + do k=1,nz ; do j=js-1,je+1 ; do i=is-1,ie+1 tr%t_prev(i,j,k) = Tr%t(i,j,k) enddo ; enddo ; enddo endif From 88cda8f495724354f353210f818051aa6b9160f0 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 5 Jan 2026 13:52:12 +1100 Subject: [PATCH 204/288] Move nm to tracer registry --- src/tracer/MOM_tracer_numerical_mixing.F90 | 42 ++++++++++-------- src/tracer/MOM_tracer_registry.F90 | 51 ++++++++++++---------- src/tracer/MOM_tracer_types.F90 | 3 ++ 3 files changed, 53 insertions(+), 43 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index ae66da80fb..238d541d6c 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -15,11 +15,11 @@ module MOM_tracer_numerical_mixing contains !< Calculate the spurious ``numerical'' mixing of tracer due to advection. -subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, x_upwind, y_upwind, nm) +subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, x_upwind, y_upwind) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + ! type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt_trans !< The transport time interval [T ~> s] @@ -30,11 +30,12 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht !! used to advect tracers [H L2 ~> m3 or kg] real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] - real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic [CU2 H T-1 ~> conc2 m s-1] + type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer regsitry + ! real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic [CU2 H T-1 ~> conc2 m s-1] - call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, nm) - call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, nm) - call thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, nm) + call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV) + call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind) + call thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind) end subroutine numerical_mixing @@ -77,16 +78,17 @@ subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) end subroutine variance_flux !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. -subroutine thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt, Idt, G, GV, res) +subroutine thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt, Idt, G, GV) - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + ! type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt !< The transport time interval [T ~> s] real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: res(:,:,:) !< Array to store result in [CU2 H T-1 ~> conc2 m s-1] + type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer registry + ! real, intent(inout) :: res(:,:,:) !< Array to store result in [CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -100,24 +102,25 @@ subroutine thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt, Idt, G h_prev = diag_pre_dyn%h_state(i,j,k) Ihadv = 1 / h(i,j,k) C_prev = Tr%t_prev(i,j,k) - Cadv = h_prev * C_prev + dt * Tr%advection_xy(i,j,k) - res(i,j,k) = ( (Ihadv * Cadv**2) - (h_prev * C_prev**2) ) * Idt + Cadv = (h_prev * C_prev) + (dt * Tr%advection_xy(i,j,k)) + Tr%numerical_mixing(i,j,k) = ((Ihadv * Cadv**2) - (h_prev * C_prev**2)) * Idt enddo ; enddo ; enddo end subroutine thickness_weighted_variance_advection !< Subroutine to calculate the thickness weigthed zonal variance flux. The spatial derivatives are calucated !! from upwind values. -subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, res) +subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind) - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + ! type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, intent(in) :: Idt !< Inverse transport time intervale [T-1 ~> s-1] real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind tracer value [CU ~> conc] - real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] + type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer registry + ! real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -131,7 +134,7 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind do k=1,nz ; do j=js,je ; do i=is,ie east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) - res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) + Tr%numerical_mixing(i,j,k) = Tr%numerical_mixing(i,j,k) + ((east - west) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but does not accurately calculate numerical mixing ! east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) ! west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2) @@ -167,16 +170,17 @@ end subroutine zonal_upwind_values !< Subroutine to calculate the thickness weighted meriodional variance flux. The spatial derivative is calculated !! from upwind values. -subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, res) +subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind) - type(tracer_type), intent(in) :: Tr !< Tracer + ! type(tracer_type), intent(in) :: Tr !< Tracer real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, intent(in) :: Idt !< Inverse model timestep real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind tracer values [CU ~> conc] - real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] + type(tracer_type), intent(inout) :: Tr !< Tracer + ! real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -190,7 +194,7 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u do k=1,nz ; do j=js,je ; do i=is,ie north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) - res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) + Tr%numerical_mixing(i,j,k) = Tr%numerical_mixing(i,j,k) + ((north - south) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but is not correct for the numerical mixing diagnostic ! north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) ! south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 32513c2f40..e172e80c3f 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -502,6 +502,8 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u enddo ; enddo ; enddo endif + if (Tr%id_numerical_mixing > 0) call safe_alloc_ptr(TR%numerical_mixing,isd,ied,jsd,jed,nz) + ! Neutral/Horizontal diffusion convergence tendencies if (Tr%diag_form == 1) then Tr%id_dfxy_cont = register_diag_field("ocean_model", trim(shortnm)//'_dfxy_cont_tendency', & @@ -805,12 +807,12 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d real :: zbot(SZI_(G),SZJ_(G)) ! position of the bottom interface [H ~> m or kg m-2] real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer [CU2 H T-1 ~> conc2 m s-1] - ! va and vf will be removed but are needed in the debugging process - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Thickness weighted variance advection - ! [CU2 H T-1 ~> conc2 m s-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Horizontal thickness weighted variance flux - ! [CU2 H T-1 ~> conc2 m s-1] + ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer [CU2 H T-1 ~> conc2 m s-1] + ! ! va and vf will be removed but are needed in the debugging process + ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Thickness weighted variance advection + ! ! [CU2 H T-1 ~> conc2 m s-1] + ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Horizontal thickness weighted variance flux + ! ! [CU2 H T-1 ~> conc2 m s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. type(tracer_type), pointer :: Tr=>NULL() @@ -870,25 +872,26 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d if (Tr%id_numerical_mixing > 0) then x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. - nm(:,:,:) = 0. + ! nm(:,:,:) = 0. + Tr%numerical_mixing(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & - x_upwind, y_upwind, nm) - call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) - - !< The below is here while debuggin; to be removed once numerical mixing is all sorted - if (Tr%id_variance_advection > 0) then - va(:,:,:) = 0. - call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) - call post_data(Tr%id_variance_advection, va, diag, alt_h=diag_pre_dyn%h_state) - endif - if (Tr%id_variance_flux > 0) then - !< Overkill to caclulate these again but I plan on removing once numerical mixing is sorted - x_upwind(:,:,:) = 0. - y_upwind(:,:,:) = 0. - vf(:,:,:) = 0. - call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) - call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) - endif + x_upwind, y_upwind) + call post_data(Tr%id_numerical_mixing, Tr%numerical_mixing, diag, alt_h=diag_pre_dyn%h_state) + + ! !< The below is here while debuggin; to be removed once numerical mixing is all sorted + ! if (Tr%id_variance_advection > 0) then + ! va(:,:,:) = 0. + ! call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) + ! call post_data(Tr%id_variance_advection, va, diag, alt_h=diag_pre_dyn%h_state) + ! endif + ! if (Tr%id_variance_flux > 0) then + ! !< Overkill to caclulate these again but I plan on removing once numerical mixing is sorted + ! x_upwind(:,:,:) = 0. + ! y_upwind(:,:,:) = 0. + ! vf(:,:,:) = 0. + ! call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) + ! call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) + ! endif endif ! A few diagnostics introduce with MARBL driver diff --git a/src/tracer/MOM_tracer_types.F90 b/src/tracer/MOM_tracer_types.F90 index fcbfbaf53a..9b34eb94ae 100644 --- a/src/tracer/MOM_tracer_types.F90 +++ b/src/tracer/MOM_tracer_types.F90 @@ -62,6 +62,9 @@ module MOM_tracer_types real, dimension(:,:,:), pointer :: Trxh_prev => NULL() !< layer integrated tracer concentration array !! at a previous timestep used for diagnostics !! [CU H ~> conc m or conc kg m-2] + real, dimension(:,:,:), pointer :: numerical_mixing => NULL() !< numerical mixing of the tracer due to + !! lateral advection + !! [CU2 H T-1 ~> conc2 m s-1] character(len=32) :: name !< tracer name used for diagnostics and error messages character(len=64) :: units !< Physical dimensions of the tracer concentration From e0724976c1baf59754cf6857c92fb89e635723b9 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 5 Jan 2026 13:55:35 +1100 Subject: [PATCH 205/288] Comment out code using old method --- src/tracer/MOM_tracer_numerical_mixing.F90 | 76 +++++++++++----------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 238d541d6c..0616965eae 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -10,7 +10,7 @@ module MOM_tracer_numerical_mixing #include -public numerical_mixing, variance_advection, variance_flux +public numerical_mixing!, variance_advection, variance_flux contains @@ -39,43 +39,43 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht end subroutine numerical_mixing -!< Subroutine for the variance advection, likely will remove once numerical mixing is sorted out -subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) - - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt_trans !< The transport time interval [T ~> s] - real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] - real, intent(inout) :: va(:,:,:) !< Thickness weighted variance advection - !! [CU2 H T-1 ~> conc2 m s-1] - - call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, va) - -end subroutine variance_advection - -!< Subroutine for the horizontal variance flux, likely will remove once numerical mixing is sorted out -subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) - - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] - real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] - real, intent(inout) :: vf(:,:,:) !< Horizontal thickness weighted variance flux - !! [CU2 H T-1 ~> conc2 m s-1] - - call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, vf) - call thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, vf) - -end subroutine variance_flux +! !< Subroutine for the variance advection, likely will remove once numerical mixing is sorted out +! subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) +! +! type(ocean_grid_type), intent(in) :: G !< Ocean grid structure +! type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure +! type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry +! real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] +! type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics +! real, intent(in) :: dt_trans !< The transport time interval [T ~> s] +! real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] +! real, intent(inout) :: va(:,:,:) !< Thickness weighted variance advection +! !! [CU2 H T-1 ~> conc2 m s-1] +! +! call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, va) +! +! end subroutine variance_advection +! +! !< Subroutine for the horizontal variance flux, likely will remove once numerical mixing is sorted out +! subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) +! +! type(ocean_grid_type), intent(in) :: G !< Ocean grid structure +! type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure +! type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry +! real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] +! real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes +! !! used to advect tracers [H L2 ~> m3 or kg] +! real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes +! !! used to advect tracers [H L2 ~> m3 or kg] +! real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] +! real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] +! real, intent(inout) :: vf(:,:,:) !< Horizontal thickness weighted variance flux +! !! [CU2 H T-1 ~> conc2 m s-1] +! +! call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, vf) +! call thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, vf) +! +! end subroutine variance_flux !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. subroutine thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt, Idt, G, GV) From 5a26a5639114040714ccdf240cc757c260f4386a Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 5 Jan 2026 13:58:25 +1100 Subject: [PATCH 206/288] Comment out calls to old subroutines --- src/tracer/MOM_tracer_registry.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index e172e80c3f..a07cbccf64 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -25,7 +25,7 @@ module MOM_tracer_registry use MOM_unit_scaling, only : unit_scale_type use MOM_verticalGrid, only : verticalGrid_type use MOM_tracer_types, only : tracer_type, tracer_registry_type -use MOM_tracer_numerical_mixing, only : numerical_mixing, variance_advection, variance_flux +use MOM_tracer_numerical_mixing, only : numerical_mixing!, variance_advection, variance_flux implicit none ; private From 1cc37182be8ea8583a85e702d24ae8f3539d353a Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 5 Jan 2026 14:37:48 +1100 Subject: [PATCH 207/288] Revert to using nm array --- src/tracer/MOM_tracer_numerical_mixing.F90 | 118 ++++++++++----------- src/tracer/MOM_tracer_registry.F90 | 53 +++++---- src/tracer/MOM_tracer_types.F90 | 3 - 3 files changed, 82 insertions(+), 92 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 0616965eae..ae66da80fb 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -10,16 +10,16 @@ module MOM_tracer_numerical_mixing #include -public numerical_mixing!, variance_advection, variance_flux +public numerical_mixing, variance_advection, variance_flux contains !< Calculate the spurious ``numerical'' mixing of tracer due to advection. -subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, x_upwind, y_upwind) +subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, x_upwind, y_upwind, nm) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - ! type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt_trans !< The transport time interval [T ~> s] @@ -30,65 +30,63 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht !! used to advect tracers [H L2 ~> m3 or kg] real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] - type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer regsitry - ! real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic [CU2 H T-1 ~> conc2 m s-1] + real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic [CU2 H T-1 ~> conc2 m s-1] - call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV) - call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind) - call thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind) + call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, nm) + call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, nm) + call thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, nm) end subroutine numerical_mixing -! !< Subroutine for the variance advection, likely will remove once numerical mixing is sorted out -! subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) -! -! type(ocean_grid_type), intent(in) :: G !< Ocean grid structure -! type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure -! type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry -! real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] -! type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics -! real, intent(in) :: dt_trans !< The transport time interval [T ~> s] -! real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] -! real, intent(inout) :: va(:,:,:) !< Thickness weighted variance advection -! !! [CU2 H T-1 ~> conc2 m s-1] -! -! call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, va) -! -! end subroutine variance_advection -! -! !< Subroutine for the horizontal variance flux, likely will remove once numerical mixing is sorted out -! subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) -! -! type(ocean_grid_type), intent(in) :: G !< Ocean grid structure -! type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure -! type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry -! real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] -! real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes -! !! used to advect tracers [H L2 ~> m3 or kg] -! real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes -! !! used to advect tracers [H L2 ~> m3 or kg] -! real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] -! real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] -! real, intent(inout) :: vf(:,:,:) !< Horizontal thickness weighted variance flux -! !! [CU2 H T-1 ~> conc2 m s-1] -! -! call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, vf) -! call thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, vf) -! -! end subroutine variance_flux +!< Subroutine for the variance advection, likely will remove once numerical mixing is sorted out +subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) + + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt_trans !< The transport time interval [T ~> s] + real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] + real, intent(inout) :: va(:,:,:) !< Thickness weighted variance advection + !! [CU2 H T-1 ~> conc2 m s-1] + + call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, va) + +end subroutine variance_advection + +!< Subroutine for the horizontal variance flux, likely will remove once numerical mixing is sorted out +subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) + + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] + real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] + real, intent(inout) :: vf(:,:,:) !< Horizontal thickness weighted variance flux + !! [CU2 H T-1 ~> conc2 m s-1] + + call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, vf) + call thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, vf) + +end subroutine variance_flux !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. -subroutine thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt, Idt, G, GV) +subroutine thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt, Idt, G, GV, res) - ! type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt !< The transport time interval [T ~> s] real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer registry - ! real, intent(inout) :: res(:,:,:) !< Array to store result in [CU2 H T-1 ~> conc2 m s-1] + real, intent(inout) :: res(:,:,:) !< Array to store result in [CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -102,25 +100,24 @@ subroutine thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt, Idt, G h_prev = diag_pre_dyn%h_state(i,j,k) Ihadv = 1 / h(i,j,k) C_prev = Tr%t_prev(i,j,k) - Cadv = (h_prev * C_prev) + (dt * Tr%advection_xy(i,j,k)) - Tr%numerical_mixing(i,j,k) = ((Ihadv * Cadv**2) - (h_prev * C_prev**2)) * Idt + Cadv = h_prev * C_prev + dt * Tr%advection_xy(i,j,k) + res(i,j,k) = ( (Ihadv * Cadv**2) - (h_prev * C_prev**2) ) * Idt enddo ; enddo ; enddo end subroutine thickness_weighted_variance_advection !< Subroutine to calculate the thickness weigthed zonal variance flux. The spatial derivatives are calucated !! from upwind values. -subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind) +subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, res) - ! type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, intent(in) :: Idt !< Inverse transport time intervale [T-1 ~> s-1] real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind tracer value [CU ~> conc] - type(tracer_type), intent(inout) :: Tr !< Pointer to the tracer registry - ! real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] + real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -134,7 +131,7 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind do k=1,nz ; do j=js,je ; do i=is,ie east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) - Tr%numerical_mixing(i,j,k) = Tr%numerical_mixing(i,j,k) + ((east - west) * G%IareaT(i,j)) + res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but does not accurately calculate numerical mixing ! east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) ! west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2) @@ -170,17 +167,16 @@ end subroutine zonal_upwind_values !< Subroutine to calculate the thickness weighted meriodional variance flux. The spatial derivative is calculated !! from upwind values. -subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind) +subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, res) - ! type(tracer_type), intent(in) :: Tr !< Tracer + type(tracer_type), intent(in) :: Tr !< Tracer real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, intent(in) :: Idt !< Inverse model timestep real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind tracer values [CU ~> conc] - type(tracer_type), intent(inout) :: Tr !< Tracer - ! real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] + real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -194,7 +190,7 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_u do k=1,nz ; do j=js,je ; do i=is,ie north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) - Tr%numerical_mixing(i,j,k) = Tr%numerical_mixing(i,j,k) + ((north - south) * G%IareaT(i,j)) + res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but is not correct for the numerical mixing diagnostic ! north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) ! south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index a07cbccf64..32513c2f40 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -25,7 +25,7 @@ module MOM_tracer_registry use MOM_unit_scaling, only : unit_scale_type use MOM_verticalGrid, only : verticalGrid_type use MOM_tracer_types, only : tracer_type, tracer_registry_type -use MOM_tracer_numerical_mixing, only : numerical_mixing!, variance_advection, variance_flux +use MOM_tracer_numerical_mixing, only : numerical_mixing, variance_advection, variance_flux implicit none ; private @@ -502,8 +502,6 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u enddo ; enddo ; enddo endif - if (Tr%id_numerical_mixing > 0) call safe_alloc_ptr(TR%numerical_mixing,isd,ied,jsd,jed,nz) - ! Neutral/Horizontal diffusion convergence tendencies if (Tr%diag_form == 1) then Tr%id_dfxy_cont = register_diag_field("ocean_model", trim(shortnm)//'_dfxy_cont_tendency', & @@ -807,12 +805,12 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d real :: zbot(SZI_(G),SZJ_(G)) ! position of the bottom interface [H ~> m or kg m-2] real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] - ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer [CU2 H T-1 ~> conc2 m s-1] - ! ! va and vf will be removed but are needed in the debugging process - ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Thickness weighted variance advection - ! ! [CU2 H T-1 ~> conc2 m s-1] - ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Horizontal thickness weighted variance flux - ! ! [CU2 H T-1 ~> conc2 m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer [CU2 H T-1 ~> conc2 m s-1] + ! va and vf will be removed but are needed in the debugging process + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Thickness weighted variance advection + ! [CU2 H T-1 ~> conc2 m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Horizontal thickness weighted variance flux + ! [CU2 H T-1 ~> conc2 m s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. type(tracer_type), pointer :: Tr=>NULL() @@ -872,26 +870,25 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d if (Tr%id_numerical_mixing > 0) then x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. - ! nm(:,:,:) = 0. - Tr%numerical_mixing(:,:,:) = 0. + nm(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & - x_upwind, y_upwind) - call post_data(Tr%id_numerical_mixing, Tr%numerical_mixing, diag, alt_h=diag_pre_dyn%h_state) - - ! !< The below is here while debuggin; to be removed once numerical mixing is all sorted - ! if (Tr%id_variance_advection > 0) then - ! va(:,:,:) = 0. - ! call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) - ! call post_data(Tr%id_variance_advection, va, diag, alt_h=diag_pre_dyn%h_state) - ! endif - ! if (Tr%id_variance_flux > 0) then - ! !< Overkill to caclulate these again but I plan on removing once numerical mixing is sorted - ! x_upwind(:,:,:) = 0. - ! y_upwind(:,:,:) = 0. - ! vf(:,:,:) = 0. - ! call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) - ! call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) - ! endif + x_upwind, y_upwind, nm) + call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) + + !< The below is here while debuggin; to be removed once numerical mixing is all sorted + if (Tr%id_variance_advection > 0) then + va(:,:,:) = 0. + call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) + call post_data(Tr%id_variance_advection, va, diag, alt_h=diag_pre_dyn%h_state) + endif + if (Tr%id_variance_flux > 0) then + !< Overkill to caclulate these again but I plan on removing once numerical mixing is sorted + x_upwind(:,:,:) = 0. + y_upwind(:,:,:) = 0. + vf(:,:,:) = 0. + call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) + call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) + endif endif ! A few diagnostics introduce with MARBL driver diff --git a/src/tracer/MOM_tracer_types.F90 b/src/tracer/MOM_tracer_types.F90 index 9b34eb94ae..fcbfbaf53a 100644 --- a/src/tracer/MOM_tracer_types.F90 +++ b/src/tracer/MOM_tracer_types.F90 @@ -62,9 +62,6 @@ module MOM_tracer_types real, dimension(:,:,:), pointer :: Trxh_prev => NULL() !< layer integrated tracer concentration array !! at a previous timestep used for diagnostics !! [CU H ~> conc m or conc kg m-2] - real, dimension(:,:,:), pointer :: numerical_mixing => NULL() !< numerical mixing of the tracer due to - !! lateral advection - !! [CU2 H T-1 ~> conc2 m s-1] character(len=32) :: name !< tracer name used for diagnostics and error messages character(len=64) :: units !< Physical dimensions of the tracer concentration From b7af47789990d4c0c7b1285c85a77c1885030752 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 5 Jan 2026 14:46:32 +1100 Subject: [PATCH 208/288] Reduce the initial t_prev value allocate by 1 --- src/tracer/MOM_tracer_registry.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 32513c2f40..1144204530 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -497,7 +497,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u if ((Tr%id_tendency > 0) .or. (Tr%id_numerical_mixing > 0)) then call safe_alloc_ptr(Tr%t_prev,isd,ied,jsd,jed,nz) - do k=1,nz ; do j=js-2,je+2 ; do i=is-2,ie+2 + do k=1,nz ; do j=js-1,je+1 ; do i=is-1,ie+1 Tr%t_prev(i,j,k) = Tr%t(i,j,k) enddo ; enddo ; enddo endif From acf5a17bf235e4ed95a1bbae3b40b128d7fa90b7 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 5 Jan 2026 14:54:40 +1100 Subject: [PATCH 209/288] Try with upwind variable initialised in nm subroutine --- src/tracer/MOM_tracer_numerical_mixing.F90 | 25 ++++++++++++++++------ src/tracer/MOM_tracer_registry.F90 | 16 +++++++------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index ae66da80fb..7a705ad630 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -15,7 +15,7 @@ module MOM_tracer_numerical_mixing contains !< Calculate the spurious ``numerical'' mixing of tracer due to advection. -subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, x_upwind, y_upwind, nm) +subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, nm) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure @@ -28,10 +28,17 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht !! used to advect tracers [H L2 ~> m3 or kg] real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] + ! real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] + ! real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic [CU2 H T-1 ~> conc2 m s-1] + ! Try with local variables + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] + + x_upwind(:,:,:) = 0. + y_upwind(:,:,:) = 0. + call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, nm) call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, nm) call thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, nm) @@ -56,7 +63,7 @@ subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) end subroutine variance_advection !< Subroutine for the horizontal variance flux, likely will remove once numerical mixing is sorted out -subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) +subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, vf) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure @@ -66,10 +73,16 @@ subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) !! used to advect tracers [H L2 ~> m3 or kg] real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] + ! real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] + ! real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] real, intent(inout) :: vf(:,:,:) !< Horizontal thickness weighted variance flux !! [CU2 H T-1 ~> conc2 m s-1] + ! Try with local variables + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] + + x_upwind(:,:,:) = 0. + y_upwind(:,:,:) = 0. call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, vf) call thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, vf) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 1144204530..f945202c60 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -803,8 +803,8 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d real :: frac_under_100m(SZI_(G),SZJ_(G),SZK_(GV)) ! weights used to compute 100m vertical integrals [nondim] real :: ztop(SZI_(G),SZJ_(G)) ! position of the top interface [H ~> m or kg m-2] real :: zbot(SZI_(G),SZJ_(G)) ! position of the bottom interface [H ~> m or kg m-2] - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] + ! real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] + ! real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer [CU2 H T-1 ~> conc2 m s-1] ! va and vf will be removed but are needed in the debugging process real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Thickness weighted variance advection @@ -868,11 +868,11 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d endif if (Tr%id_numerical_mixing > 0) then - x_upwind(:,:,:) = 0. - y_upwind(:,:,:) = 0. + ! x_upwind(:,:,:) = 0. + ! y_upwind(:,:,:) = 0. nm(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & - x_upwind, y_upwind, nm) + nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) !< The below is here while debuggin; to be removed once numerical mixing is all sorted @@ -883,10 +883,10 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d endif if (Tr%id_variance_flux > 0) then !< Overkill to caclulate these again but I plan on removing once numerical mixing is sorted - x_upwind(:,:,:) = 0. - y_upwind(:,:,:) = 0. + ! x_upwind(:,:,:) = 0. + ! y_upwind(:,:,:) = 0. vf(:,:,:) = 0. - call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, x_upwind, y_upwind, vf) + call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, vf) call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) endif endif From e2a2ea92694479b7282a327595e8e235389c9f2a Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 5 Jan 2026 15:23:08 +1100 Subject: [PATCH 210/288] Remove commented out code as it works --- src/tracer/MOM_tracer_numerical_mixing.F90 | 6 +----- src/tracer/MOM_tracer_registry.F90 | 10 +--------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 7a705ad630..08b5afef14 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -28,11 +28,9 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht !! used to advect tracers [H L2 ~> m3 or kg] real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - ! real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] - ! real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic [CU2 H T-1 ~> conc2 m s-1] - ! Try with local variables + ! Upwind variables real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] @@ -73,8 +71,6 @@ subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, vf) !! used to advect tracers [H L2 ~> m3 or kg] real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - ! real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values for tracer [CU ~> conc] - ! real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values for tracer [CU ~> conc] real, intent(inout) :: vf(:,:,:) !< Horizontal thickness weighted variance flux !! [CU2 H T-1 ~> conc2 m s-1] ! Try with local variables diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index f945202c60..2fc32b18ef 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -803,8 +803,6 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d real :: frac_under_100m(SZI_(G),SZJ_(G),SZK_(GV)) ! weights used to compute 100m vertical integrals [nondim] real :: ztop(SZI_(G),SZJ_(G)) ! position of the top interface [H ~> m or kg m-2] real :: zbot(SZI_(G),SZJ_(G)) ! position of the bottom interface [H ~> m or kg m-2] - ! real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] - ! real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer [CU2 H T-1 ~> conc2 m s-1] ! va and vf will be removed but are needed in the debugging process real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Thickness weighted variance advection @@ -868,11 +866,8 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d endif if (Tr%id_numerical_mixing > 0) then - ! x_upwind(:,:,:) = 0. - ! y_upwind(:,:,:) = 0. nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, & - nm) + call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) !< The below is here while debuggin; to be removed once numerical mixing is all sorted @@ -882,9 +877,6 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d call post_data(Tr%id_variance_advection, va, diag, alt_h=diag_pre_dyn%h_state) endif if (Tr%id_variance_flux > 0) then - !< Overkill to caclulate these again but I plan on removing once numerical mixing is sorted - ! x_upwind(:,:,:) = 0. - ! y_upwind(:,:,:) = 0. vf(:,:,:) = 0. call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, vf) call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) From c795cf80f8d0b436fd3df3e4e81c8fb4e272c205 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 11:52:17 +1100 Subject: [PATCH 211/288] Temporary saving of east and west u point values --- src/diagnostics/MOM_diagnostics.F90 | 20 ++++++++++++++++ src/tracer/MOM_tracer_numerical_mixing.F90 | 28 +++++++++++++++++++++- src/tracer/MOM_tracer_registry.F90 | 11 +++++++++ src/tracer/MOM_tracer_types.F90 | 1 + 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 28ec06dae6..54f9d3587e 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -35,6 +35,7 @@ module MOM_diagnostics use MOM_variables, only : accel_diag_ptrs, cont_diag_ptrs, surface use MOM_verticalGrid, only : verticalGrid_type, get_thickness_units, get_flux_units use MOM_wave_speed, only : wave_speed, wave_speed_CS, wave_speed_init +use MOM_tracer_numerical_mixing, only : east_west_upoints implicit none ; private @@ -159,6 +160,7 @@ module MOM_diagnostics type, public :: transport_diag_IDs ; private !>@{ Diagnostics for tracer horizontal transport integer :: id_uhtr = -1, id_umo = -1, id_umo_2d = -1 + integer :: id_uhtr_eu = -1, id_uhtr_wu = -1 integer :: id_vhtr = -1, id_vmo = -1, id_vmo_2d = -1 integer :: id_dynamics_h = -1, id_dynamics_h_tendency = -1 !>@} @@ -1649,6 +1651,13 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: umo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics + ! Temporary variables for saving east and west u point uhtr values + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: uhtr_eu !< East u point value of accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: uhtr_wu !< West u point value of accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + ! [H T-1 ~> m s-1 or kg m-2 s-1]. real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes @@ -1692,6 +1701,11 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy endif if (IDs%id_uhtr > 0) call post_data(IDs%id_uhtr, uhtr, diag, alt_h=diag_pre_dyn%h_state) + if (IDs%id_uhtr_eu > 0) + call east_west_u_points(uhtr, G, nz, uhtr_eu, uhtr_wu) + call post_data(IDS%id_uhtr_eu, uhtr_eu, diag, alt_h=diag_pre_dyn%h_state) + call post_data(IDS%id_uhtr_wu, uhtr_wu, diag, alt_h=diag_pre_dyn%h_state) + endif if (IDs%id_vhtr > 0) call post_data(IDs%id_vhtr, vhtr, diag, alt_h=diag_pre_dyn%h_state) if (IDs%id_dynamics_h > 0) call post_data(IDs%id_dynamics_h, diag_pre_dyn%h_state, diag, & alt_h=diag_pre_dyn%h_state) @@ -2214,6 +2228,12 @@ subroutine register_transport_diags(Time, G, GV, US, IDs, diag) IDs%id_uhtr = register_diag_field('ocean_model', 'uhtr', diag%axesCuL, Time, & 'Accumulated zonal thickness fluxes to advect tracers', & accum_flux_units, y_cell_method='sum', v_extensive=.true., conversion=GV%H_to_MKS*US%L_to_m**2) + IDs%id_uhtr_eu = register_diag_field('ocean_model', 'uhtr_eu', diag%axesTL, Time, & + 'East u point value of accumulated zonal thickness fluxes to advect tracers', & + accum_flux_units, y_cell_method='sum', v_extensive=.true., conversion=GV%H_to_MKS*US%L_to_m**2) + IDs%id_uhtr_wu = register_diag_field('ocean_model', 'uhtr_wu', diag%axesTL, Time, & + 'West u point value of accumulated zonal thickness fluxes to advect tracers', & + accum_flux_units, y_cell_method='sum', v_extensive=.true., conversion=GV%H_to_MKS*US%L_to_m**2) IDs%id_vhtr = register_diag_field('ocean_model', 'vhtr', diag%axesCvL, Time, & 'Accumulated meridional thickness fluxes to advect tracers', & accum_flux_units, x_cell_method='sum', v_extensive=.true., conversion=GV%H_to_MKS*US%L_to_m**2) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 08b5afef14..38d100c8ed 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -10,7 +10,7 @@ module MOM_tracer_numerical_mixing #include -public numerical_mixing, variance_advection, variance_flux +public numerical_mixing, variance_advection, variance_flux, east_west_upoints contains @@ -233,4 +233,30 @@ subroutine meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) end subroutine meridional_upwind_values +! Subroutine to construct a MWE that demonstrates the hack that I have above where I have the `uhtr` variable +! indexed one value higher than `TR%ad_x`. I should then be able to compare this output to the equivalent +! saved variables and demonstrate that the index online and offline does not seem to match. Or in doing this I will +! find the error in my ways! +subroutine east_west_upoints(var, G, nz, eu, wu) + + real, intent(in) :: var !< the variable to save the east faces of + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for indexes + real, intent(in) :: nz !< number of vertical levels + + real, intent(inout) :: eu !< The east u point value of `var` + real, intent(inout) :: wu !< The west u point value of `var` + + !< Local variables + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec + + do k=1,nz ; do j=js,je ; do i=is,ie + eu(i,j,k) = var(i-1,j,k) + wu(i,j,k) = var(i,j,k) + enddo ; enddo; enddo + +end subroutine east_west_upoints + end module MOM_tracer_numerical_mixing diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 2fc32b18ef..2f90d1c39f 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -813,6 +813,12 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. type(tracer_type), pointer :: Tr=>NULL() + ! Temporary local varaibles for saving east and west u point ad_x values + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: adx_eu !< East u value of diagnostic x-advective flux + !! [CU H L2 T-1 ~> conc m3 s-1 or conc kg s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: adx_wu !< West u value of diagnostic x-advective flux + !! [CU H L2 T-1 ~> conc m3 s-1 or conc kg s-1] + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke H_to_RZ_dt = GV%H_to_RZ * Idt @@ -849,6 +855,11 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d Tr => Reg%Tr(m) if (Tr%id_tr_post_horzn> 0) call post_data(Tr%id_tr_post_horzn, Tr%t, diag) if (Tr%id_adx > 0) call post_data(Tr%id_adx, Tr%ad_x, diag, alt_h=h_diag) + if (IDs%id_adx_eu > 0) + call east_west_u_points(Tr%ad_x, G, nz, adx_eu, adx_wu) + call post_data(IDS%id_adx_eu, adx_eu, diag, alt_h=diag_pre_dyn%h_state) + call post_data(IDS%id_adx_wu, adx_wu, diag, alt_h=diag_pre_dyn%h_state) + endif if (Tr%id_ady > 0) call post_data(Tr%id_ady, Tr%ad_y, diag, alt_h=h_diag) if (Tr%id_dfx > 0) call post_data(Tr%id_dfx, Tr%df_x, diag, alt_h=h_diag) if (Tr%id_dfy > 0) call post_data(Tr%id_dfy, Tr%df_y, diag, alt_h=h_diag) diff --git a/src/tracer/MOM_tracer_types.F90 b/src/tracer/MOM_tracer_types.F90 index fcbfbaf53a..b0d8f2a657 100644 --- a/src/tracer/MOM_tracer_types.F90 +++ b/src/tracer/MOM_tracer_types.F90 @@ -109,6 +109,7 @@ module MOM_tracer_types !>@{ Diagnostic IDs integer :: id_tr = -1, id_tr_post_horzn = -1 integer :: id_adx = -1, id_ady = -1, id_dfx = -1, id_dfy = -1 + integer :: id_adx_eu = -1, id_adx_wu = -1 integer :: id_hbd_dfx = -1, id_hbd_dfy = -1 integer :: id_hbd_dfx_2d = -1, id_hbd_dfy_2d = -1 integer :: id_adx_2d = -1, id_ady_2d = -1, id_dfx_2d = -1, id_dfy_2d = -1 From d1e155632e0eee45cf78d80b936db608cd551c89 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 11:56:30 +1100 Subject: [PATCH 212/288] Define in variables as arrays --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 38d100c8ed..869572d69e 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -243,8 +243,8 @@ subroutine east_west_upoints(var, G, nz, eu, wu) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for indexes real, intent(in) :: nz !< number of vertical levels - real, intent(inout) :: eu !< The east u point value of `var` - real, intent(inout) :: wu !< The west u point value of `var` + real, intent(inout) :: eu(:,:,:) !< The east u point value of `var` + real, intent(inout) :: wu(:,:,:) !< The west u point value of `var` !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes From 40485879a9678d528daba350a562f0e745bf64ce Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 12:02:00 +1100 Subject: [PATCH 213/288] Integer counter and one more array declaration in subroutine --- src/tracer/MOM_tracer_numerical_mixing.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 869572d69e..f7cb88fe66 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -239,9 +239,9 @@ end subroutine meridional_upwind_values ! find the error in my ways! subroutine east_west_upoints(var, G, nz, eu, wu) - real, intent(in) :: var !< the variable to save the east faces of - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for indexes - real, intent(in) :: nz !< number of vertical levels + real, intent(in) :: var(:,:,:) !< the variable to save the east faces of + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for indexes + integer, intent(in) :: nz !< number of vertical levels real, intent(inout) :: eu(:,:,:) !< The east u point value of `var` real, intent(inout) :: wu(:,:,:) !< The west u point value of `var` From 925f20b4a136cec6025fff35430c460f08740067 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 12:07:32 +1100 Subject: [PATCH 214/288] Tracer registry not ID registry --- src/tracer/MOM_tracer_registry.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 2f90d1c39f..59b0cf51f0 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -855,10 +855,10 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d Tr => Reg%Tr(m) if (Tr%id_tr_post_horzn> 0) call post_data(Tr%id_tr_post_horzn, Tr%t, diag) if (Tr%id_adx > 0) call post_data(Tr%id_adx, Tr%ad_x, diag, alt_h=h_diag) - if (IDs%id_adx_eu > 0) + if (Tr%id_adx_eu > 0) call east_west_u_points(Tr%ad_x, G, nz, adx_eu, adx_wu) - call post_data(IDS%id_adx_eu, adx_eu, diag, alt_h=diag_pre_dyn%h_state) - call post_data(IDS%id_adx_wu, adx_wu, diag, alt_h=diag_pre_dyn%h_state) + call post_data(Tr%id_adx_eu, adx_eu, diag, alt_h=diag_pre_dyn%h_state) + call post_data(Tr%id_adx_wu, adx_wu, diag, alt_h=diag_pre_dyn%h_state) endif if (Tr%id_ady > 0) call post_data(Tr%id_ady, Tr%ad_y, diag, alt_h=h_diag) if (Tr%id_dfx > 0) call post_data(Tr%id_dfx, Tr%df_x, diag, alt_h=h_diag) From 214f093a018eb4f1a57d8e88e564dad72d37c40f Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 12:12:28 +1100 Subject: [PATCH 215/288] Incorrect if statement --- src/tracer/MOM_tracer_registry.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 59b0cf51f0..a65bac422f 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -855,7 +855,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d Tr => Reg%Tr(m) if (Tr%id_tr_post_horzn> 0) call post_data(Tr%id_tr_post_horzn, Tr%t, diag) if (Tr%id_adx > 0) call post_data(Tr%id_adx, Tr%ad_x, diag, alt_h=h_diag) - if (Tr%id_adx_eu > 0) + if (Tr%id_adx_eu > 0) then call east_west_u_points(Tr%ad_x, G, nz, adx_eu, adx_wu) call post_data(Tr%id_adx_eu, adx_eu, diag, alt_h=diag_pre_dyn%h_state) call post_data(Tr%id_adx_wu, adx_wu, diag, alt_h=diag_pre_dyn%h_state) From 0632d34315e36a1d0bfe292c9d257e770f7fe86f Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 12:16:00 +1100 Subject: [PATCH 216/288] Another incorrect if statement --- src/diagnostics/MOM_diagnostics.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 54f9d3587e..43d0dc19b4 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1701,7 +1701,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy endif if (IDs%id_uhtr > 0) call post_data(IDs%id_uhtr, uhtr, diag, alt_h=diag_pre_dyn%h_state) - if (IDs%id_uhtr_eu > 0) + if (IDs%id_uhtr_eu > 0) then call east_west_u_points(uhtr, G, nz, uhtr_eu, uhtr_wu) call post_data(IDS%id_uhtr_eu, uhtr_eu, diag, alt_h=diag_pre_dyn%h_state) call post_data(IDS%id_uhtr_wu, uhtr_wu, diag, alt_h=diag_pre_dyn%h_state) From 0b5979061e4c972711d0242add5f0d90d2eab9f0 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 12:25:14 +1100 Subject: [PATCH 217/288] Incorrectly called new subroutine --- src/diagnostics/MOM_diagnostics.F90 | 2 +- src/tracer/MOM_tracer_registry.F90 | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 43d0dc19b4..201437d75d 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1702,7 +1702,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy if (IDs%id_uhtr > 0) call post_data(IDs%id_uhtr, uhtr, diag, alt_h=diag_pre_dyn%h_state) if (IDs%id_uhtr_eu > 0) then - call east_west_u_points(uhtr, G, nz, uhtr_eu, uhtr_wu) + call east_west_upoints(uhtr, G, nz, uhtr_eu, uhtr_wu) call post_data(IDS%id_uhtr_eu, uhtr_eu, diag, alt_h=diag_pre_dyn%h_state) call post_data(IDS%id_uhtr_wu, uhtr_wu, diag, alt_h=diag_pre_dyn%h_state) endif diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index a65bac422f..911b602570 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -25,7 +25,7 @@ module MOM_tracer_registry use MOM_unit_scaling, only : unit_scale_type use MOM_verticalGrid, only : verticalGrid_type use MOM_tracer_types, only : tracer_type, tracer_registry_type -use MOM_tracer_numerical_mixing, only : numerical_mixing, variance_advection, variance_flux +use MOM_tracer_numerical_mixing, only : numerical_mixing, variance_advection, variance_flux, east_west_upoints implicit none ; private @@ -856,7 +856,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d if (Tr%id_tr_post_horzn> 0) call post_data(Tr%id_tr_post_horzn, Tr%t, diag) if (Tr%id_adx > 0) call post_data(Tr%id_adx, Tr%ad_x, diag, alt_h=h_diag) if (Tr%id_adx_eu > 0) then - call east_west_u_points(Tr%ad_x, G, nz, adx_eu, adx_wu) + call east_west_upoints(Tr%ad_x, G, nz, adx_eu, adx_wu) call post_data(Tr%id_adx_eu, adx_eu, diag, alt_h=diag_pre_dyn%h_state) call post_data(Tr%id_adx_wu, adx_wu, diag, alt_h=diag_pre_dyn%h_state) endif From f36aa18639ae4b9b0eaa0132c2f3a8487029d38c Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 14:26:54 +1100 Subject: [PATCH 218/288] Pass tracer type instead of pointer --- src/tracer/MOM_tracer_numerical_mixing.F90 | 24 +++++++++++++++++++++- src/tracer/MOM_tracer_registry.F90 | 4 ++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index f7cb88fe66..de0db5eeb3 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -10,7 +10,7 @@ module MOM_tracer_numerical_mixing #include -public numerical_mixing, variance_advection, variance_flux, east_west_upoints +public numerical_mixing, variance_advection, variance_flux, east_west_upoints, Tr_east_west_upoints contains @@ -259,4 +259,26 @@ subroutine east_west_upoints(var, G, nz, eu, wu) end subroutine east_west_upoints +subroutine Tr_east_west_upoints(Tr, G, nz, eu, wu) + + type(tracer_type), intent(in) :: Tr !< Tracer + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for indexes + integer, intent(in) :: nz !< number of vertical levels + + real, intent(inout) :: eu(:,:,:) !< The east u point value of `var` + real, intent(inout) :: wu(:,:,:) !< The west u point value of `var` + + !< Local variables + integer :: is, ie, js, je !< Grid cell centre indexes + integer :: i, j, k !< Counters + + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec + + do k=1,nz ; do j=js,je ; do i=is,ie + eu(i,j,k) = Tr%ad_x(i-1,j,k) + wu(i,j,k) = Tr%ad_x(i,j,k) + enddo ; enddo; enddo + +end subroutine east_west_upoints + end module MOM_tracer_numerical_mixing diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 911b602570..11ab7d6e36 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -25,7 +25,7 @@ module MOM_tracer_registry use MOM_unit_scaling, only : unit_scale_type use MOM_verticalGrid, only : verticalGrid_type use MOM_tracer_types, only : tracer_type, tracer_registry_type -use MOM_tracer_numerical_mixing, only : numerical_mixing, variance_advection, variance_flux, east_west_upoints +use MOM_tracer_numerical_mixing, only : numerical_mixing, variance_advection, variance_flux, Tr_east_west_upoints implicit none ; private @@ -856,7 +856,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d if (Tr%id_tr_post_horzn> 0) call post_data(Tr%id_tr_post_horzn, Tr%t, diag) if (Tr%id_adx > 0) call post_data(Tr%id_adx, Tr%ad_x, diag, alt_h=h_diag) if (Tr%id_adx_eu > 0) then - call east_west_upoints(Tr%ad_x, G, nz, adx_eu, adx_wu) + call Tr_east_west_upoints(Tr, G, nz, adx_eu, adx_wu) call post_data(Tr%id_adx_eu, adx_eu, diag, alt_h=diag_pre_dyn%h_state) call post_data(Tr%id_adx_wu, adx_wu, diag, alt_h=diag_pre_dyn%h_state) endif From 8fe458208a38c7a655304888f5287383eb014acd Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 14:29:54 +1100 Subject: [PATCH 219/288] Correct subroutine name --- src/tracer/MOM_tracer_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index de0db5eeb3..5e4d16a851 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -279,6 +279,6 @@ subroutine Tr_east_west_upoints(Tr, G, nz, eu, wu) wu(i,j,k) = Tr%ad_x(i,j,k) enddo ; enddo; enddo -end subroutine east_west_upoints +end subroutine Tr_east_west_upoints end module MOM_tracer_numerical_mixing From 189c744eeaa1ff9cf7309d49a7a5e72718025d6b Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 14:49:50 +1100 Subject: [PATCH 220/288] Register the east and west advection diags --- src/tracer/MOM_tracer_registry.F90 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 11ab7d6e36..90dbc14b6f 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -396,6 +396,12 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & flux_units, v_extensive=.true., conversion=Tr%flux_scale*(US%L_to_m**2)*US%s_to_T, y_cell_method='sum') + Tr%id_adx_eu = register_diag_field("ocean_model", trim(shortnm)//"_adx_eu", & + diag%axesTL, Time, "East upoint Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & + flux_units, v_extensive=.true., conversion=Tr%flux_scale*(US%L_to_m**2)*US%s_to_T, y_cell_method='sum') + Tr%id_adx_wu = register_diag_field("ocean_model", trim(shortnm)//"_adx_wu", & + diag%axesTL, Time, "West upoint Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & + flux_units, v_extensive=.true., conversion=Tr%flux_scale*(US%L_to_m**2)*US%s_to_T, y_cell_method='sum') Tr%id_ady = register_diag_field("ocean_model", trim(shortnm)//"_ady", & diag%axesCvL, Time, "Advective (by residual mean) Meridional Flux of "//trim(flux_longname), & flux_units, v_extensive=.true., conversion=Tr%flux_scale*(US%L_to_m**2)*US%s_to_T, x_cell_method='sum') @@ -856,7 +862,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d if (Tr%id_tr_post_horzn> 0) call post_data(Tr%id_tr_post_horzn, Tr%t, diag) if (Tr%id_adx > 0) call post_data(Tr%id_adx, Tr%ad_x, diag, alt_h=h_diag) if (Tr%id_adx_eu > 0) then - call Tr_east_west_upoints(Tr, G, nz, adx_eu, adx_wu) + call Tr_east_west_upoints(Tr%ad_x, G, nz, adx_eu, adx_wu) call post_data(Tr%id_adx_eu, adx_eu, diag, alt_h=diag_pre_dyn%h_state) call post_data(Tr%id_adx_wu, adx_wu, diag, alt_h=diag_pre_dyn%h_state) endif From b926c470cd6b5f15be6d6e6d40299ca76adb4542 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 14:53:52 +1100 Subject: [PATCH 221/288] Register diag in both cases + pass correct argument to new subroutine --- src/tracer/MOM_tracer_registry.F90 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 90dbc14b6f..b43fd1397d 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -362,6 +362,12 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u diag%axesCuL, Time, trim(flux_longname)//" advective zonal flux" , & trim(flux_units), v_extensive=.true., y_cell_method='sum', & conversion=Tr%flux_scale*(US%L_to_m**2)*US%s_to_T) + Tr%id_adx_eu = register_diag_field("ocean_model", trim(shortnm)//"_adx_eu", & + diag%axesTL, Time, "East upoint Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & + flux_units, v_extensive=.true., conversion=Tr%flux_scale*(US%L_to_m**2)*US%s_to_T, y_cell_method='sum') + Tr%id_adx_wu = register_diag_field("ocean_model", trim(shortnm)//"_adx_wu", & + diag%axesTL, Time, "West upoint Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & + flux_units, v_extensive=.true., conversion=Tr%flux_scale*(US%L_to_m**2)*US%s_to_T, y_cell_method='sum') Tr%id_ady = register_diag_field("ocean_model", trim(shortnm)//"_ady", & diag%axesCvL, Time, trim(flux_longname)//" advective meridional flux" , & trim(flux_units), v_extensive=.true., x_cell_method='sum', & @@ -862,7 +868,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d if (Tr%id_tr_post_horzn> 0) call post_data(Tr%id_tr_post_horzn, Tr%t, diag) if (Tr%id_adx > 0) call post_data(Tr%id_adx, Tr%ad_x, diag, alt_h=h_diag) if (Tr%id_adx_eu > 0) then - call Tr_east_west_upoints(Tr%ad_x, G, nz, adx_eu, adx_wu) + call Tr_east_west_upoints(Tr, G, nz, adx_eu, adx_wu) call post_data(Tr%id_adx_eu, adx_eu, diag, alt_h=diag_pre_dyn%h_state) call post_data(Tr%id_adx_wu, adx_wu, diag, alt_h=diag_pre_dyn%h_state) endif From b1b584733d6cb2c78eaea63bad4a71755d70625a Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 15:15:03 +1100 Subject: [PATCH 222/288] Fix east and west locations --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 5e4d16a851..506ee1bff5 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -253,8 +253,8 @@ subroutine east_west_upoints(var, G, nz, eu, wu) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do k=1,nz ; do j=js,je ; do i=is,ie - eu(i,j,k) = var(i-1,j,k) - wu(i,j,k) = var(i,j,k) + wu(i,j,k) = var(I-1,j,k) + eu(i,j,k) = var(I,j,k) enddo ; enddo; enddo end subroutine east_west_upoints @@ -275,8 +275,8 @@ subroutine Tr_east_west_upoints(Tr, G, nz, eu, wu) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do k=1,nz ; do j=js,je ; do i=is,ie - eu(i,j,k) = Tr%ad_x(i-1,j,k) - wu(i,j,k) = Tr%ad_x(i,j,k) + wu(i,j,k) = Tr%ad_x(I-1,j,k) + eu(i,j,k) = Tr%ad_x(I,j,k) enddo ; enddo; enddo end subroutine Tr_east_west_upoints From 9d0a883a4646e1c0bd8c994eb240f412b626104c Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 15:31:46 +1100 Subject: [PATCH 223/288] Initialise to zero --- src/diagnostics/MOM_diagnostics.F90 | 4 +++- src/tracer/MOM_tracer_registry.F90 | 9 +++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 201437d75d..9c908a20b0 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1701,7 +1701,9 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy endif if (IDs%id_uhtr > 0) call post_data(IDs%id_uhtr, uhtr, diag, alt_h=diag_pre_dyn%h_state) - if (IDs%id_uhtr_eu > 0) then + if (IDs%id_uhtr_eu > 0 .and. IDs%id_uhtr_wu > 0) then + uhtr_eu(:,:,:) = 0. + uhtr_wu(:,:,:) = 0. call east_west_upoints(uhtr, G, nz, uhtr_eu, uhtr_wu) call post_data(IDS%id_uhtr_eu, uhtr_eu, diag, alt_h=diag_pre_dyn%h_state) call post_data(IDS%id_uhtr_wu, uhtr_wu, diag, alt_h=diag_pre_dyn%h_state) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index b43fd1397d..c5a5dec143 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -821,15 +821,14 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d ! [CU2 H T-1 ~> conc2 m s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Horizontal thickness weighted variance flux ! [CU2 H T-1 ~> conc2 m s-1] - real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes - ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. - type(tracer_type), pointer :: Tr=>NULL() - ! Temporary local varaibles for saving east and west u point ad_x values real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: adx_eu !< East u value of diagnostic x-advective flux !! [CU H L2 T-1 ~> conc m3 s-1 or conc kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: adx_wu !< West u value of diagnostic x-advective flux !! [CU H L2 T-1 ~> conc m3 s-1 or conc kg s-1] + real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes + ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. + type(tracer_type), pointer :: Tr=>NULL() is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke H_to_RZ_dt = GV%H_to_RZ * Idt @@ -868,6 +867,8 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d if (Tr%id_tr_post_horzn> 0) call post_data(Tr%id_tr_post_horzn, Tr%t, diag) if (Tr%id_adx > 0) call post_data(Tr%id_adx, Tr%ad_x, diag, alt_h=h_diag) if (Tr%id_adx_eu > 0) then + adx_eu(:,:,:) = 0. + adx_wu(:,:,:) = 0. call Tr_east_west_upoints(Tr, G, nz, adx_eu, adx_wu) call post_data(Tr%id_adx_eu, adx_eu, diag, alt_h=diag_pre_dyn%h_state) call post_data(Tr%id_adx_wu, adx_wu, diag, alt_h=diag_pre_dyn%h_state) From e84c4ef145d98c05141079125df07be5305d9996 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 15:42:09 +1100 Subject: [PATCH 224/288] More descriptive functions --- src/diagnostics/MOM_diagnostics.F90 | 2 +- src/tracer/MOM_tracer_numerical_mixing.F90 | 22 +++++++++++----------- src/tracer/MOM_tracer_registry.F90 | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 9c908a20b0..d27036bacc 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1701,7 +1701,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy endif if (IDs%id_uhtr > 0) call post_data(IDs%id_uhtr, uhtr, diag, alt_h=diag_pre_dyn%h_state) - if (IDs%id_uhtr_eu > 0 .and. IDs%id_uhtr_wu > 0) then + if (IDs%id_uhtr_eu > 0 .or. IDs%id_uhtr_wu > 0) then uhtr_eu(:,:,:) = 0. uhtr_wu(:,:,:) = 0. call east_west_upoints(uhtr, G, nz, uhtr_eu, uhtr_wu) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 506ee1bff5..147e5749d4 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -237,14 +237,14 @@ end subroutine meridional_upwind_values ! indexed one value higher than `TR%ad_x`. I should then be able to compare this output to the equivalent ! saved variables and demonstrate that the index online and offline does not seem to match. Or in doing this I will ! find the error in my ways! -subroutine east_west_upoints(var, G, nz, eu, wu) +subroutine east_west_upoints(uhtr, G, nz, uhtr_eu, uhtr_wu) - real, intent(in) :: var(:,:,:) !< the variable to save the east faces of + real, intent(in) :: uhtr(:,:,:) !< the variable to save the east faces of type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for indexes integer, intent(in) :: nz !< number of vertical levels - real, intent(inout) :: eu(:,:,:) !< The east u point value of `var` - real, intent(inout) :: wu(:,:,:) !< The west u point value of `var` + real, intent(inout) :: uhtr_eu(:,:,:) !< The east u point value of `var` + real, intent(inout) :: uhtr_wu(:,:,:) !< The west u point value of `var` !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes @@ -253,20 +253,20 @@ subroutine east_west_upoints(var, G, nz, eu, wu) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do k=1,nz ; do j=js,je ; do i=is,ie - wu(i,j,k) = var(I-1,j,k) - eu(i,j,k) = var(I,j,k) + uhtr_wu(i,j,k) = uhtr(I-1,j,k) + uhtr_eu(i,j,k) = uhtr(I,j,k) enddo ; enddo; enddo end subroutine east_west_upoints -subroutine Tr_east_west_upoints(Tr, G, nz, eu, wu) +subroutine Tr_east_west_upoints(Tr, G, nz, adx_eu, adx_wu) type(tracer_type), intent(in) :: Tr !< Tracer type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for indexes integer, intent(in) :: nz !< number of vertical levels - real, intent(inout) :: eu(:,:,:) !< The east u point value of `var` - real, intent(inout) :: wu(:,:,:) !< The west u point value of `var` + real, intent(inout) :: adx_eu(:,:,:) !< The east u point value of `var` + real, intent(inout) :: adx_wu(:,:,:) !< The west u point value of `var` !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes @@ -275,8 +275,8 @@ subroutine Tr_east_west_upoints(Tr, G, nz, eu, wu) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec do k=1,nz ; do j=js,je ; do i=is,ie - wu(i,j,k) = Tr%ad_x(I-1,j,k) - eu(i,j,k) = Tr%ad_x(I,j,k) + adx_wu(i,j,k) = Tr%ad_x(I-1,j,k) + adx_eu(i,j,k) = Tr%ad_x(I,j,k) enddo ; enddo; enddo end subroutine Tr_east_west_upoints diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index c5a5dec143..e54f88e406 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -866,7 +866,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d Tr => Reg%Tr(m) if (Tr%id_tr_post_horzn> 0) call post_data(Tr%id_tr_post_horzn, Tr%t, diag) if (Tr%id_adx > 0) call post_data(Tr%id_adx, Tr%ad_x, diag, alt_h=h_diag) - if (Tr%id_adx_eu > 0) then + if (Tr%id_adx_eu > 0 .or. Tr%id_adx_wu) then adx_eu(:,:,:) = 0. adx_wu(:,:,:) = 0. call Tr_east_west_upoints(Tr, G, nz, adx_eu, adx_wu) From 08641e29b7fca9c6c2cc079a28c275f5fce0d4b3 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 9 Mar 2026 15:45:02 +1100 Subject: [PATCH 225/288] Missed Boolean --- src/tracer/MOM_tracer_registry.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index e54f88e406..a26a4212bd 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -866,7 +866,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d Tr => Reg%Tr(m) if (Tr%id_tr_post_horzn> 0) call post_data(Tr%id_tr_post_horzn, Tr%t, diag) if (Tr%id_adx > 0) call post_data(Tr%id_adx, Tr%ad_x, diag, alt_h=h_diag) - if (Tr%id_adx_eu > 0 .or. Tr%id_adx_wu) then + if (Tr%id_adx_eu > 0 .or. Tr%id_adx_wu > 0) then adx_eu(:,:,:) = 0. adx_wu(:,:,:) = 0. call Tr_east_west_upoints(Tr, G, nz, adx_eu, adx_wu) From 51c23c6e42ba373ccd70ce10d985c84e71ff4e28 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 10 Mar 2026 09:25:20 +1100 Subject: [PATCH 226/288] Try and sort out advection terms first --- src/diagnostics/MOM_diagnostics.F90 | 26 +++++++++++++------------- src/tracer/MOM_tracer_registry.F90 | 15 ++++++++------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index d27036bacc..cb600735f0 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -35,7 +35,7 @@ module MOM_diagnostics use MOM_variables, only : accel_diag_ptrs, cont_diag_ptrs, surface use MOM_verticalGrid, only : verticalGrid_type, get_thickness_units, get_flux_units use MOM_wave_speed, only : wave_speed, wave_speed_CS, wave_speed_init -use MOM_tracer_numerical_mixing, only : east_west_upoints +! use MOM_tracer_numerical_mixing, only : east_west_upoints implicit none ; private @@ -1652,11 +1652,11 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics ! Temporary variables for saving east and west u point uhtr values - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: uhtr_eu !< East u point value of accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: uhtr_wu !< West u point value of accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] + ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: uhtr_eu !< East u point value of accumulated zonal thickness fluxes + ! !! used to advect tracers [H L2 ~> m3 or kg] + ! + ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: uhtr_wu !< West u point value of accumulated zonal thickness fluxes + ! !! used to advect tracers [H L2 ~> m3 or kg] ! [H T-1 ~> m s-1 or kg m-2 s-1]. real :: Idt ! The inverse of the time interval [T-1 ~> s-1] @@ -1701,13 +1701,13 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy endif if (IDs%id_uhtr > 0) call post_data(IDs%id_uhtr, uhtr, diag, alt_h=diag_pre_dyn%h_state) - if (IDs%id_uhtr_eu > 0 .or. IDs%id_uhtr_wu > 0) then - uhtr_eu(:,:,:) = 0. - uhtr_wu(:,:,:) = 0. - call east_west_upoints(uhtr, G, nz, uhtr_eu, uhtr_wu) - call post_data(IDS%id_uhtr_eu, uhtr_eu, diag, alt_h=diag_pre_dyn%h_state) - call post_data(IDS%id_uhtr_wu, uhtr_wu, diag, alt_h=diag_pre_dyn%h_state) - endif + ! if (IDs%id_uhtr_eu > 0 .or. IDs%id_uhtr_wu > 0) then + ! uhtr_eu(:,:,:) = 0. + ! uhtr_wu(:,:,:) = 0. + ! call east_west_upoints(uhtr, G, nz, uhtr_eu, uhtr_wu) + ! call post_data(IDS%id_uhtr_eu, uhtr_eu, diag, alt_h=diag_pre_dyn%h_state) + ! call post_data(IDS%id_uhtr_wu, uhtr_wu, diag, alt_h=diag_pre_dyn%h_state) + ! endif if (IDs%id_vhtr > 0) call post_data(IDs%id_vhtr, vhtr, diag, alt_h=diag_pre_dyn%h_state) if (IDs%id_dynamics_h > 0) call post_data(IDs%id_dynamics_h, diag_pre_dyn%h_state, diag, & alt_h=diag_pre_dyn%h_state) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index a26a4212bd..d6d6f28f75 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -866,13 +866,6 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d Tr => Reg%Tr(m) if (Tr%id_tr_post_horzn> 0) call post_data(Tr%id_tr_post_horzn, Tr%t, diag) if (Tr%id_adx > 0) call post_data(Tr%id_adx, Tr%ad_x, diag, alt_h=h_diag) - if (Tr%id_adx_eu > 0 .or. Tr%id_adx_wu > 0) then - adx_eu(:,:,:) = 0. - adx_wu(:,:,:) = 0. - call Tr_east_west_upoints(Tr, G, nz, adx_eu, adx_wu) - call post_data(Tr%id_adx_eu, adx_eu, diag, alt_h=diag_pre_dyn%h_state) - call post_data(Tr%id_adx_wu, adx_wu, diag, alt_h=diag_pre_dyn%h_state) - endif if (Tr%id_ady > 0) call post_data(Tr%id_ady, Tr%ad_y, diag, alt_h=h_diag) if (Tr%id_dfx > 0) call post_data(Tr%id_dfx, Tr%df_x, diag, alt_h=h_diag) if (Tr%id_dfy > 0) call post_data(Tr%id_dfy, Tr%df_y, diag, alt_h=h_diag) @@ -906,6 +899,14 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) endif endif + ! My check for the indexing hack used in numiercal_mixing + if (Tr%id_adx_eu > 0 .or. Tr%id_adx_wu > 0) then + adx_eu(:,:,:) = 0. + adx_wu(:,:,:) = 0. + call Tr_east_west_upoints(Tr, G, nz, adx_eu, adx_wu) + call post_data(Tr%id_adx_eu, adx_eu, diag, alt_h=diag_pre_dyn%h_state) + call post_data(Tr%id_adx_wu, adx_wu, diag, alt_h=diag_pre_dyn%h_state) + endif ! A few diagnostics introduce with MARBL driver ! Compute full-depth vertical integral From dc5d2ae6a1cc2fb3166d95d0af3c5dc59433f155 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 10 Mar 2026 09:57:32 +1100 Subject: [PATCH 227/288] Add back diagnostics, I think the error is somewhere else --- src/diagnostics/MOM_diagnostics.F90 | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index cb600735f0..d39b73659d 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1652,11 +1652,11 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics ! Temporary variables for saving east and west u point uhtr values - ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: uhtr_eu !< East u point value of accumulated zonal thickness fluxes - ! !! used to advect tracers [H L2 ~> m3 or kg] - ! - ! real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: uhtr_wu !< West u point value of accumulated zonal thickness fluxes - ! !! used to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: uhtr_eu !< East u point value of accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: uhtr_wu !< West u point value of accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] ! [H T-1 ~> m s-1 or kg m-2 s-1]. real :: Idt ! The inverse of the time interval [T-1 ~> s-1] @@ -1701,13 +1701,13 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy endif if (IDs%id_uhtr > 0) call post_data(IDs%id_uhtr, uhtr, diag, alt_h=diag_pre_dyn%h_state) - ! if (IDs%id_uhtr_eu > 0 .or. IDs%id_uhtr_wu > 0) then - ! uhtr_eu(:,:,:) = 0. - ! uhtr_wu(:,:,:) = 0. - ! call east_west_upoints(uhtr, G, nz, uhtr_eu, uhtr_wu) - ! call post_data(IDS%id_uhtr_eu, uhtr_eu, diag, alt_h=diag_pre_dyn%h_state) - ! call post_data(IDS%id_uhtr_wu, uhtr_wu, diag, alt_h=diag_pre_dyn%h_state) - ! endif + if (IDs%id_uhtr_eu > 0 .or. IDs%id_uhtr_wu > 0) then + uhtr_eu(:,:,:) = 0. + uhtr_wu(:,:,:) = 0. + call east_west_upoints(uhtr, G, nz, uhtr_eu, uhtr_wu) + call post_data(IDS%id_uhtr_eu, uhtr_eu, diag, alt_h=diag_pre_dyn%h_state) + call post_data(IDS%id_uhtr_wu, uhtr_wu, diag, alt_h=diag_pre_dyn%h_state) + endif if (IDs%id_vhtr > 0) call post_data(IDs%id_vhtr, vhtr, diag, alt_h=diag_pre_dyn%h_state) if (IDs%id_dynamics_h > 0) call post_data(IDs%id_dynamics_h, diag_pre_dyn%h_state, diag, & alt_h=diag_pre_dyn%h_state) From 8b76a2f49bf14c92c06463b200b74168eb34a6bd Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 10 Mar 2026 10:05:06 +1100 Subject: [PATCH 228/288] Remove comment --- src/diagnostics/MOM_diagnostics.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index d39b73659d..d27036bacc 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -35,7 +35,7 @@ module MOM_diagnostics use MOM_variables, only : accel_diag_ptrs, cont_diag_ptrs, surface use MOM_verticalGrid, only : verticalGrid_type, get_thickness_units, get_flux_units use MOM_wave_speed, only : wave_speed, wave_speed_CS, wave_speed_init -! use MOM_tracer_numerical_mixing, only : east_west_upoints +use MOM_tracer_numerical_mixing, only : east_west_upoints implicit none ; private From 3fc71bbb11e0447ddb9a49248566adad3542a34d Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 11:28:27 +1100 Subject: [PATCH 229/288] Remove shape array assumptions, with @angus-g --- src/tracer/MOM_tracer_numerical_mixing.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 147e5749d4..65599482e0 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -239,12 +239,12 @@ end subroutine meridional_upwind_values ! find the error in my ways! subroutine east_west_upoints(uhtr, G, nz, uhtr_eu, uhtr_wu) - real, intent(in) :: uhtr(:,:,:) !< the variable to save the east faces of + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< the variable to save the east faces of type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for indexes integer, intent(in) :: nz !< number of vertical levels - real, intent(inout) :: uhtr_eu(:,:,:) !< The east u point value of `var` - real, intent(inout) :: uhtr_wu(:,:,:) !< The west u point value of `var` + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr_eu !< The east u point value of `var` + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr_wu !< The west u point value of `var` !< Local variables integer :: is, ie, js, je !< Grid cell centre indexes From 2bf169ffd5c5ffa8673fe2c8374bac7d0e5f1dc2 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 11:38:13 +1100 Subject: [PATCH 230/288] Define GV --- src/tracer/MOM_tracer_numerical_mixing.F90 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 65599482e0..27b1e5bff9 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -237,12 +237,11 @@ end subroutine meridional_upwind_values ! indexed one value higher than `TR%ad_x`. I should then be able to compare this output to the equivalent ! saved variables and demonstrate that the index online and offline does not seem to match. Or in doing this I will ! find the error in my ways! -subroutine east_west_upoints(uhtr, G, nz, uhtr_eu, uhtr_wu) +subroutine east_west_upoints(uhtr, G, GV, uhtr_eu, uhtr_wu) real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< the variable to save the east faces of type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for indexes - integer, intent(in) :: nz !< number of vertical levels - + type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr_eu !< The east u point value of `var` real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr_wu !< The west u point value of `var` From d667125d0e8895021aff0fe131e9b1c99ff44035 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 11:39:37 +1100 Subject: [PATCH 231/288] Define uhtr after G and GV --- src/tracer/MOM_tracer_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 27b1e5bff9..221a2ba848 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -239,9 +239,9 @@ end subroutine meridional_upwind_values ! find the error in my ways! subroutine east_west_upoints(uhtr, G, GV, uhtr_eu, uhtr_wu) - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< the variable to save the east faces of type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for indexes type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< the variable to save the east faces of real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr_eu !< The east u point value of `var` real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr_wu !< The west u point value of `var` From b0ca0bcb4c37e878ee061448296166eb815dde5d Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 11:43:36 +1100 Subject: [PATCH 232/288] Define nz --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 221a2ba848..fe2c213614 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -246,10 +246,10 @@ subroutine east_west_upoints(uhtr, G, GV, uhtr_eu, uhtr_wu) real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr_wu !< The west u point value of `var` !< Local variables - integer :: is, ie, js, je !< Grid cell centre indexes + integer :: is, ie, js, je, nz !< Grid cell centre indexes integer :: i, j, k !< Counters - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke do k=1,nz ; do j=js,je ; do i=is,ie uhtr_wu(i,j,k) = uhtr(I-1,j,k) From a907004c8e7ba2e52c4a7f38f5780bb257d2bbb2 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 11:47:41 +1100 Subject: [PATCH 233/288] Pass correct arguments to subroutine --- src/diagnostics/MOM_diagnostics.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index d27036bacc..420b44d314 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1704,7 +1704,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy if (IDs%id_uhtr_eu > 0 .or. IDs%id_uhtr_wu > 0) then uhtr_eu(:,:,:) = 0. uhtr_wu(:,:,:) = 0. - call east_west_upoints(uhtr, G, nz, uhtr_eu, uhtr_wu) + call east_west_upoints(uhtr, G, GV, uhtr_eu, uhtr_wu) call post_data(IDS%id_uhtr_eu, uhtr_eu, diag, alt_h=diag_pre_dyn%h_state) call post_data(IDS%id_uhtr_wu, uhtr_wu, diag, alt_h=diag_pre_dyn%h_state) endif From d9bf2d3ca8b7d326045468dbd1f348bc5f8c35be Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 13:58:55 +1100 Subject: [PATCH 234/288] Apply @angus-g fix to numerical mixing diagnostic --- src/tracer/MOM_tracer_numerical_mixing.F90 | 174 +++++++++++---------- 1 file changed, 88 insertions(+), 86 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index fe2c213614..c76a733e55 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -17,18 +17,18 @@ module MOM_tracer_numerical_mixing !< Calculate the spurious ``numerical'' mixing of tracer due to advection. subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, nm) - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt_trans !< The transport time interval [T ~> s] - real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] - real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic [CU2 H T-1 ~> conc2 m s-1] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt_trans !< The transport time interval [T ~> s] + real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic [CU2 H T-1 ~> conc2 m s-1] ! Upwind variables real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] @@ -38,8 +38,8 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht y_upwind(:,:,:) = 0. call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, nm) - call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, nm) - call thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, nm) + call thickness_weighted_zonal_variance_flux(Tr, G, GV, uhtr, Idt, x_upwind, nm) + call thickness_weighted_meridional_variance_flux(Tr, G, GV, vhtr, Idt, y_upwind, nm) end subroutine numerical_mixing @@ -63,16 +63,16 @@ end subroutine variance_advection !< Subroutine for the horizontal variance flux, likely will remove once numerical mixing is sorted out subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, vf) - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] - real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: vf(:,:,:) !< Horizontal thickness weighted variance flux - !! [CU2 H T-1 ~> conc2 m s-1] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(inout) :: vf(:,:,:) !< Horizontal thickness weighted variance flux + !! [CU2 H T-1 ~> conc2 m s-1] ! Try with local variables real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] @@ -80,8 +80,8 @@ subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, vf) x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. - call thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, vf) - call thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, vf) + call thickness_weighted_zonal_variance_flux(Tr, G, GV, uhtr, Idt, x_upwind, vf) + call thickness_weighted_meridional_variance_flux(Tr, G, GV, vhtr, Idt, y_upwind, vf) end subroutine variance_flux @@ -117,57 +117,58 @@ end subroutine thickness_weighted_variance_advection !< Subroutine to calculate the thickness weigthed zonal variance flux. The spatial derivatives are calucated !! from upwind values. -subroutine thickness_weighted_zonal_variance_flux(Tr, uhtr, G, GV, Idt, x_upwind, res) +subroutine thickness_weighted_zonal_variance_flux(Tr, G, GV, uhtr, Idt, x_upwind, res) - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(in) :: Idt !< Inverse transport time intervale [T-1 ~> s-1] - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind tracer value [CU ~> conc] - real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(in) :: Idt !< Inverse transport time intervale [T-1 ~> s-1] + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind tracer value [CU ~> conc] + real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: east, west !< East and West for zonal derivative [CU2 H T-1 ~> conc2 m s-1] + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: east, west !< East and West for zonal derivative [CU2 H T-1 ~> conc2 m s-1] is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) + call zonal_upwind_values(Tr, G, GV, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) - west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) - res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) + ! east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) + ! west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) + ! res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but does not accurately calculate numerical mixing - ! east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) - ! west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2) + east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) + west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2) + res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo end subroutine thickness_weighted_zonal_variance_flux !< Subroutine to calculate upwind values in zonal direction -subroutine zonal_upwind_values(Tr, G, nz, uhtr, x_upwind) +subroutine zonal_upwind_values(Tr, G, GV, uhtr, x_upwind) - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - integer, intent(in) :: nz !< Vertical extent of domain - real, intent(in) :: uhtr(:,:,:) !< Accumulated zonal transport - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values [CU ~> conc] + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values [CU ~> conc] !< Local variables - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters + integer :: is, ie, js, je, nz !< Grid cell centre indexes + integer :: i, j, k !< Counters - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke do k=1,nz ; do j=js,je ; do I=is-1,ie - if (uhtr(I+1,j,k) >= 0) then + if (uhtr(I,j,k) >= 0) then x_upwind(I,j,k) = Tr%t_prev(i,j,k) - elseif (uhtr(I+1,j,k) < 0) then + elseif (uhtr(I,j,k) < 0) then x_upwind(I,j,k) = Tr%t_prev(i+1,j,k) endif enddo ; enddo ; enddo @@ -176,57 +177,58 @@ end subroutine zonal_upwind_values !< Subroutine to calculate the thickness weighted meriodional variance flux. The spatial derivative is calculated !! from upwind values. -subroutine thickness_weighted_meridional_variance_flux(Tr, vhtr, G, GV, Idt, y_upwind, res) +subroutine thickness_weighted_meridional_variance_flux(Tr, G, GV, vhtr, Idt, y_upwind, res) - type(tracer_type), intent(in) :: Tr !< Tracer - real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(in) :: Idt !< Inverse model timestep - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind tracer values [CU ~> conc] - real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] + type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(in) :: Idt !< Inverse model timestep + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind tracer values [CU ~> conc] + real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: north, south !< North and South positions for meridional derivative + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: north, south !< North and South positions for meridional derivative is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) + call meridional_upwind_values(Tr, G, GV, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) - south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) - res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) + ! north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) + ! south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) + ! res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but is not correct for the numerical mixing diagnostic - ! north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) - ! south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2) + north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) + south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2) + res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo end subroutine thickness_weighted_meridional_variance_flux !< Subroutine to calculate upwind value in the meridional direction -subroutine meridional_upwind_values(Tr, G, nz, vhtr, y_upwind) +subroutine meridional_upwind_values(Tr, G, GV, vhtr, y_upwind) - type(tracer_type), intent(in) :: Tr !< Tracer - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for inverse area - integer, intent(in) :: nz !< Grid cell layer indexes - real, intent(in) :: vhtr(:,:,:) !< Accumulated meridional thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values of C [CU ~> conc] + type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values of C [CU ~> conc] !< Local variables - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters + integer :: is, ie, js, je, nz !< Grid cell centre indexes + integer :: i, j, k !< Counters - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke do k=1,nz ; do J=js-1,je ; do i=is,ie - if (vhtr(i,J+1,k) >= 0) then + if (vhtr(i,J,k) >= 0) then y_upwind(i,J,k) = Tr%t_prev(i,j,k) - elseif (vhtr(i,J+1,k) < 0) then + elseif (vhtr(i,J,k) < 0) then y_upwind(i,J,k) = Tr%t_prev(i,j+1,k) endif enddo ; enddo ; enddo From 261b1185fc97ebcd63fbcf2e0ca72d211d039505 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 14:15:35 +1100 Subject: [PATCH 235/288] First go at fixing line length --- src/tracer/MOM_tracer_numerical_mixing.F90 | 45 ++++++++++++---------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index c76a733e55..2a79a46a34 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -1,4 +1,4 @@ -!> Functions and routines involved in calculating numerical mixing of tracers due to advection +!> Functions and routines involved in calculating numerical mixing of tracers due to advection schemes. module MOM_tracer_numerical_mixing use MOM_diag_mediator, only : diag_ctrl, diag_grid_storage @@ -14,21 +14,21 @@ module MOM_tracer_numerical_mixing contains -!< Calculate the spurious ``numerical'' mixing of tracer due to advection. +!< Calculate the spurious ``numerical'' mixing of tracer due to advection schemes. subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, nm) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] + real, intent(in) :: h(:,:,:) !< Updated layer thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt_trans !< The transport time interval [T ~> s] - real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: nm(:,:,:) !< Numerical mixing diagnostic [CU2 H T-1 ~> conc2 m s-1] + real, intent(inout) :: nm(:,:,:) !< Numerical mixing [CU2 H T-1 ~> conc2 m s-1] ! Upwind variables real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] @@ -122,11 +122,11 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, G, GV, uhtr, Idt, x_upwind type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: Idt !< Inverse transport time intervale [T-1 ~> s-1] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes used + !! to advect tracers [H L2 ~> m3 or kg] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind tracer value [CU ~> conc] - real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] + real, intent(inout) :: res(:,:,:) !< Result [CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -155,8 +155,8 @@ subroutine zonal_upwind_values(Tr, G, GV, uhtr, x_upwind) type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes used + !! to advect tracers [H L2 ~> m3 or kg] real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values [CU ~> conc] !< Local variables @@ -182,11 +182,13 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, G, GV, vhtr, Idt, y_u type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: Idt !< Inverse model timestep - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind tracer values [CU ~> conc] - real, intent(inout) :: res(:,:,:) !< Array to store the result in [CU2 H T-1 ~> conc2 m s-1] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness + !! fluxes used to advect + !! tracers [H L2 ~> m3 or kg] + real, intent(in) :: Idt !< Inverse model timestep [T-1 ~> S-1] + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind + !! tracer values [CU ~> conc] + real, intent(inout) :: res(:,:,:) !< Result [CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -198,8 +200,8 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, G, GV, vhtr, Idt, y_u call meridional_upwind_values(Tr, G, GV, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - ! north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) - ! south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) + ! north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) **2)) + ! south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)**2)) ! res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but is not correct for the numerical mixing diagnostic north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) @@ -215,9 +217,10 @@ subroutine meridional_upwind_values(Tr, G, GV, vhtr, y_upwind) type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values of C [CU ~> conc] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness + !! fluxes used to + !! advect tracers [H L2 ~> m3 or kg] + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values [CU ~> conc] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre indexes From 54beffc223c16f21ddb78dd54dee829c24bbce19 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 14:20:27 +1100 Subject: [PATCH 236/288] Few more long lines --- src/tracer/MOM_tracer_numerical_mixing.F90 | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 2a79a46a34..a5503d4c1e 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -20,7 +20,8 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, intent(in) :: h(:,:,:) !< Updated layer thicknesses [H ~> m or kg m-2] + real, intent(in) :: h(:,:,:) !< Updated layer + !! thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt_trans !< The transport time interval [T ~> s] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] @@ -28,7 +29,8 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: nm(:,:,:) !< Numerical mixing [CU2 H T-1 ~> conc2 m s-1] + real, intent(inout) :: nm(:,:,:) !< Numerical mixing + !! diagnostic [CU2 H T-1 ~> conc2 m s-1] ! Upwind variables real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] @@ -66,7 +68,7 @@ subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, vf) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes @@ -122,8 +124,9 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, G, GV, uhtr, Idt, x_upwind type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes used - !! to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect + !! tracers [H L2 ~> m3 or kg] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind tracer value [CU ~> conc] real, intent(inout) :: res(:,:,:) !< Result [CU2 H T-1 ~> conc2 m s-1] @@ -155,8 +158,9 @@ subroutine zonal_upwind_values(Tr, G, GV, uhtr, x_upwind) type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes used - !! to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect + !! tracers [H L2 ~> m3 or kg] real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values [CU ~> conc] !< Local variables From f1a191f75a6ee51c9ed2c003c5f09f12d374bd09 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 14:27:22 +1100 Subject: [PATCH 237/288] Remove whitespace --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index a5503d4c1e..e4b6fa87b9 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -190,7 +190,7 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, G, GV, vhtr, Idt, y_u !! fluxes used to advect !! tracers [H L2 ~> m3 or kg] real, intent(in) :: Idt !< Inverse model timestep [T-1 ~> S-1] - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind + real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind !! tracer values [CU ~> conc] real, intent(inout) :: res(:,:,:) !< Result [CU2 H T-1 ~> conc2 m s-1] @@ -221,7 +221,7 @@ subroutine meridional_upwind_values(Tr, G, GV, vhtr, y_upwind) type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness !! fluxes used to !! advect tracers [H L2 ~> m3 or kg] real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values [CU ~> conc] From 2e7d595007786bc6fe7cf5e5e8d0ba0bb76d7917 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 19:24:49 +1100 Subject: [PATCH 238/288] Correct some vhtr indexing + remove all array shape assumptions --- src/tracer/MOM_tracer_numerical_mixing.F90 | 137 ++++++++++----------- 1 file changed, 67 insertions(+), 70 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index e4b6fa87b9..286311f05b 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -20,17 +20,16 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, intent(in) :: h(:,:,:) !< Updated layer - !! thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt_trans !< The transport time interval [T ~> s] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: nm(:,:,:) !< Numerical mixing - !! diagnostic [CU2 H T-1 ~> conc2 m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(inout) :: nm !< Numerical mixing diagnostic + !! [CU2 H T-1 ~> conc2 m s-1] ! Upwind variables real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] @@ -48,15 +47,15 @@ end subroutine numerical_mixing !< Subroutine for the variance advection, likely will remove once numerical mixing is sorted out subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt_trans !< The transport time interval [T ~> s] - real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] - real, intent(inout) :: va(:,:,:) !< Thickness weighted variance advection - !! [CU2 H T-1 ~> conc2 m s-1] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt_trans !< The transport time interval [T ~> s] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: va !< Thickness weighted variance advection + !! [CU2 H T-1 ~> conc2 m s-1] call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, va) @@ -65,16 +64,16 @@ end subroutine variance_advection !< Subroutine for the horizontal variance flux, likely will remove once numerical mixing is sorted out subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, vf) - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: vf(:,:,:) !< Horizontal thickness weighted variance flux - !! [CU2 H T-1 ~> conc2 m s-1] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)),intent(inout) :: vf !< Horizontal thickness weighted variance flux + !! [CU2 H T-1 ~> conc2 m s-1] ! Try with local variables real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] @@ -90,14 +89,15 @@ end subroutine variance_flux !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. subroutine thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt, Idt, G, GV, res) - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - real, intent(in) :: h(:,:,:) !< The updated layer thicknesses [H ~> m or kg m-2] - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt !< The transport time interval [T ~> s] - real, intent(in) :: Idt !< The inverse of the time interval [T-1 ~> s-1] - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, intent(inout) :: res(:,:,:) !< Array to store result in [CU2 H T-1 ~> conc2 m s-1] + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt !< Transport time interval [T ~> s] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(inout) :: res !< Array to store result in + !![CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -121,15 +121,15 @@ end subroutine thickness_weighted_variance_advection !! from upwind values. subroutine thickness_weighted_zonal_variance_flux(Tr, G, GV, uhtr, Idt, x_upwind, res) - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes - !! used to advect - !! tracers [H L2 ~> m3 or kg] - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind tracer value [CU ~> conc] - real, intent(inout) :: res(:,:,:) !< Result [CU2 H T-1 ~> conc2 m s-1] + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real,dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + real,dimension(SZIB_(G),SZJ_(G),SZK_(GV)),intent(inout) :: x_upwind !< Zonal upwind tracer [CU ~> conc] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(inout) :: res !< Array to store result in + !![CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -145,8 +145,8 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, G, GV, uhtr, Idt, x_upwind ! west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) ! res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but does not accurately calculate numerical mixing - east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * x_upwind(I,j,k)**2) - west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I-1,j,k) * x_upwind(I-1,j,k)**2) + east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * (x_upwind(I,j,k)**2)) + west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I-1,j,k) * (x_upwind(I-1,j,k)**2)) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo @@ -155,13 +155,12 @@ end subroutine thickness_weighted_zonal_variance_flux !< Subroutine to calculate upwind values in zonal direction subroutine zonal_upwind_values(Tr, G, GV, uhtr, x_upwind) - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes - !! used to advect - !! tracers [H L2 ~> m3 or kg] - real, intent(inout) :: x_upwind(:,:,:) !< Zonal upwind values [CU ~> conc] + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real,dimension(SZIB_(G),SZJ_(G),SZK_(GV)),intent(inout) :: x_upwind !< zonal upwind tracer [CU ~> conc] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre indexes @@ -183,16 +182,15 @@ end subroutine zonal_upwind_values !! from upwind values. subroutine thickness_weighted_meridional_variance_flux(Tr, G, GV, vhtr, Idt, y_upwind, res) - type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness - !! fluxes used to advect - !! tracers [H L2 ~> m3 or kg] - real, intent(in) :: Idt !< Inverse model timestep [T-1 ~> S-1] - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind - !! tracer values [CU ~> conc] - real, intent(inout) :: res(:,:,:) !< Result [CU2 H T-1 ~> conc2 m s-1] + type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes used + !! to advect tracers [H L2 ~> m3 or kg] + real, intent(in) :: Idt !< Inverse timestep [T-1 ~> S-1] + real,dimension(SZI_(G),SZJB_(G),SZK_(GV)),intent(inout) :: y_upwind !< Meridional upwind tracer values [CU ~> conc] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(inout) :: res !< Array to store result in + !![CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -208,8 +206,8 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, G, GV, vhtr, Idt, y_u ! south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)**2)) ! res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but is not correct for the numerical mixing diagnostic - north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * y_upwind(i,J,k)**2) - south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * y_upwind(i,J-1,k)**2) + north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * (y_upwind(i,J,k)**2)) + south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * (y_upwind(i,J-1,k)**2) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo @@ -218,13 +216,12 @@ end subroutine thickness_weighted_meridional_variance_flux !< Subroutine to calculate upwind value in the meridional direction subroutine meridional_upwind_values(Tr, G, GV, vhtr, y_upwind) - type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness - !! fluxes used to - !! advect tracers [H L2 ~> m3 or kg] - real, intent(inout) :: y_upwind(:,:,:) !< Meridional upwind values [CU ~> conc] + type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes used + !! to advect tracers [H L2 ~> m3 or kg] + real,dimension(SZI_(G),SZJB_(G),SZK_(GV)),intent(inout) :: y_upwind !< Meridional upwind tracer values [CU ~> conc] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre indexes From 75c4aad1f3e5b4c300bea3069d43c45ee9c62cc4 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 19:28:06 +1100 Subject: [PATCH 239/288] Remove whitespace + correct another array shape size --- src/tracer/MOM_tracer_numerical_mixing.F90 | 56 +++++++++++----------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 286311f05b..8f037e9e24 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -72,7 +72,7 @@ subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, vf) !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)),intent(inout) :: vf !< Horizontal thickness weighted variance flux + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: vf !< Horizontal thickness weighted variance flux !! [CU2 H T-1 ~> conc2 m s-1] ! Try with local variables real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] @@ -89,14 +89,14 @@ end subroutine variance_flux !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. subroutine thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt, Idt, G, GV, res) - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt !< Transport time interval [T ~> s] - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(inout) :: res !< Array to store result in + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] + type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics + real, intent(in) :: dt !< Transport time interval [T ~> s] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in !![CU2 H T-1 ~> conc2 m s-1] !< Local variables @@ -121,14 +121,14 @@ end subroutine thickness_weighted_variance_advection !! from upwind values. subroutine thickness_weighted_zonal_variance_flux(Tr, G, GV, uhtr, Idt, x_upwind, res) - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real,dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real,dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real,dimension(SZIB_(G),SZJ_(G),SZK_(GV)),intent(inout) :: x_upwind !< Zonal upwind tracer [CU ~> conc] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(inout) :: res !< Array to store result in + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + real,dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: x_upwind !< Zonal upwind tracer [CU ~> conc] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in !![CU2 H T-1 ~> conc2 m s-1] !< Local variables @@ -155,12 +155,12 @@ end subroutine thickness_weighted_zonal_variance_flux !< Subroutine to calculate upwind values in zonal direction subroutine zonal_upwind_values(Tr, G, GV, uhtr, x_upwind) - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real,dimension(SZIB_(G),SZJ_(G),SZK_(GV)),intent(inout) :: x_upwind !< zonal upwind tracer [CU ~> conc] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: x_upwind !< zonal upwind tracer [CU ~> conc] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre indexes @@ -182,14 +182,14 @@ end subroutine zonal_upwind_values !! from upwind values. subroutine thickness_weighted_meridional_variance_flux(Tr, G, GV, vhtr, Idt, y_upwind, res) - type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes used + type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes used !! to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: Idt !< Inverse timestep [T-1 ~> S-1] - real,dimension(SZI_(G),SZJB_(G),SZK_(GV)),intent(inout) :: y_upwind !< Meridional upwind tracer values [CU ~> conc] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(inout) :: res !< Array to store result in + real, intent(in) :: Idt !< Inverse timestep [T-1 ~> S-1] + real,dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: y_upwind !< Meridional upwind tracer values [CU ~> conc] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in !![CU2 H T-1 ~> conc2 m s-1] !< Local variables From 18df0a8fa8eacc5195c9919234b8d6ac6efb3030 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 19:37:10 +1100 Subject: [PATCH 240/288] Grid and vertival grid is first in subroutines --- src/tracer/MOM_tracer_numerical_mixing.F90 | 38 +++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 8f037e9e24..fe20159874 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -38,9 +38,9 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. - call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, nm) - call thickness_weighted_zonal_variance_flux(Tr, G, GV, uhtr, Idt, x_upwind, nm) - call thickness_weighted_meridional_variance_flux(Tr, G, GV, vhtr, Idt, y_upwind, nm) + call thickness_weighted_variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, nm) + call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) + call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) end subroutine numerical_mixing @@ -57,7 +57,7 @@ subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: va !< Thickness weighted variance advection !! [CU2 H T-1 ~> conc2 m s-1] - call thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt_trans, Idt, G, GV, va) + call thickness_weighted_variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) end subroutine variance_advection @@ -81,21 +81,21 @@ subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, vf) x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. - call thickness_weighted_zonal_variance_flux(Tr, G, GV, uhtr, Idt, x_upwind, vf) - call thickness_weighted_meridional_variance_flux(Tr, G, GV, vhtr, Idt, y_upwind, vf) + call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, vf) + call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, vf) end subroutine variance_flux !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. -subroutine thickness_weighted_variance_advection(Tr, h, diag_pre_dyn, dt, Idt, G, GV, res) +subroutine thickness_weighted_variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, res) + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics real, intent(in) :: dt !< Transport time interval [T ~> s] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in !![CU2 H T-1 ~> conc2 m s-1] @@ -119,11 +119,11 @@ end subroutine thickness_weighted_variance_advection !< Subroutine to calculate the thickness weigthed zonal variance flux. The spatial derivatives are calucated !! from upwind values. -subroutine thickness_weighted_zonal_variance_flux(Tr, G, GV, uhtr, Idt, x_upwind, res) +subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, res) - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry real,dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] @@ -138,7 +138,7 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, G, GV, uhtr, Idt, x_upwind is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call zonal_upwind_values(Tr, G, GV, uhtr, x_upwind) + call zonal_upwind_values(G, GV, Tr, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie ! east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) @@ -153,11 +153,11 @@ subroutine thickness_weighted_zonal_variance_flux(Tr, G, GV, uhtr, Idt, x_upwind end subroutine thickness_weighted_zonal_variance_flux !< Subroutine to calculate upwind values in zonal direction -subroutine zonal_upwind_values(Tr, G, GV, uhtr, x_upwind) +subroutine zonal_upwind_values(G, GV, Tr, uhtr, x_upwind) - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: x_upwind !< zonal upwind tracer [CU ~> conc] @@ -180,11 +180,11 @@ end subroutine zonal_upwind_values !< Subroutine to calculate the thickness weighted meriodional variance flux. The spatial derivative is calculated !! from upwind values. -subroutine thickness_weighted_meridional_variance_flux(Tr, G, GV, vhtr, Idt, y_upwind, res) +subroutine thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, res) - type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes used !! to advect tracers [H L2 ~> m3 or kg] real, intent(in) :: Idt !< Inverse timestep [T-1 ~> S-1] @@ -199,7 +199,7 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, G, GV, vhtr, Idt, y_u is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - call meridional_upwind_values(Tr, G, GV, vhtr, y_upwind) + call meridional_upwind_values(G, GV, Tr, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie ! north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) **2)) @@ -214,11 +214,11 @@ subroutine thickness_weighted_meridional_variance_flux(Tr, G, GV, vhtr, Idt, y_u end subroutine thickness_weighted_meridional_variance_flux !< Subroutine to calculate upwind value in the meridional direction -subroutine meridional_upwind_values(Tr, G, GV, vhtr, y_upwind) +subroutine meridional_upwind_values(G, GV, Tr, vhtr, y_upwind) - type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes used !! to advect tracers [H L2 ~> m3 or kg] real,dimension(SZI_(G),SZJB_(G),SZK_(GV)),intent(inout) :: y_upwind !< Meridional upwind tracer values [CU ~> conc] From 76d12b964c4494c29820246c0b079d1b64b9f77b Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 19:42:02 +1100 Subject: [PATCH 241/288] Missed close bracket --- src/tracer/MOM_tracer_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index fe20159874..8320f2a46b 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -207,7 +207,7 @@ subroutine thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_u ! res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but is not correct for the numerical mixing diagnostic north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * (y_upwind(i,J,k)**2)) - south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * (y_upwind(i,J-1,k)**2) + south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * (y_upwind(i,J-1,k)**2)) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo From c203a04eb272c39bd663d6a418ccd4f3a5389a2f Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 21:53:54 +1100 Subject: [PATCH 242/288] More explicit bracketing --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 8320f2a46b..5adcb20bf4 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -145,8 +145,8 @@ subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind ! west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) ! res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but does not accurately calculate numerical mixing - east = (2 * Tr%ad_x(I,j,k) * x_upwind(I,j,k)) - (Idt * uhtr(I,j,k) * (x_upwind(I,j,k)**2)) - west = (2 * Tr%ad_x(I-1,j,k) * x_upwind(I-1,j,k)) - (Idt * uhtr(I-1,j,k) * (x_upwind(I-1,j,k)**2)) + east = (2 * (Tr%ad_x(I,j,k)*x_upwind(I,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k)*x_upwind(I,j,k))) + west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo @@ -206,8 +206,8 @@ subroutine thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_u ! south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)**2)) ! res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but is not correct for the numerical mixing diagnostic - north = (2 * Tr%ad_y(i,J,k) * y_upwind(i,J,k)) - (Idt * vhtr(i,J,k) * (y_upwind(i,J,k)**2)) - south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - (Idt * vhtr(i,J-1,k) * (y_upwind(i,J-1,k)**2)) + north = (2 * (Tr%ad_y(i,J,k)*y_upwind(i,J,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J,k)*y_upwind(i,J,k))) + south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - ((Idt*vhtr(i,J-1,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo From a020ed183af8aee063b8b2c62795e4957baa97de Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 12 Mar 2026 21:57:34 +1100 Subject: [PATCH 243/288] One more bracketing --- src/tracer/MOM_tracer_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 5adcb20bf4..2072bc8ec6 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -207,7 +207,7 @@ subroutine thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_u ! res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) ! This code passes the thickness dimensional test but is not correct for the numerical mixing diagnostic north = (2 * (Tr%ad_y(i,J,k)*y_upwind(i,J,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J,k)*y_upwind(i,J,k))) - south = (2 * Tr%ad_y(i,J-1,k) * y_upwind(i,J-1,k)) - ((Idt*vhtr(i,J-1,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) + south = (2 * (Tr%ad_y(i,J-1,k)*y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J-1,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo From 3c50a174b27711a14b74601f3ddb4c4c24c8c09d Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 13 Mar 2026 13:31:25 +1100 Subject: [PATCH 244/288] Remove unneeded variable duplicate --- src/diagnostics/MOM_diagnostics.F90 | 3 +- src/tracer/MOM_tracer_numerical_mixing.F90 | 87 +++++++++++----------- src/tracer/MOM_tracer_registry.F90 | 17 ++--- 3 files changed, 54 insertions(+), 53 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 420b44d314..b8bbda7f58 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1720,8 +1720,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy call post_data(IDs%id_dynamics_h_tendency, h_tend, diag, alt_h=diag_pre_dyn%h_state) endif - call post_tracer_transport_diagnostics(G, GV, Reg, diag_pre_dyn%h_state, diag_pre_dyn, & - diag, uhtr, vhtr, h, dt_trans, Idt) + call post_tracer_transport_diagnostics(G, GV, Reg, diag_pre_dyn%h_state, diag, uhtr, vhtr, h, dt_trans, Idt) call diag_restore_grids(diag) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 2072bc8ec6..aaa7b877fe 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -15,21 +15,22 @@ module MOM_tracer_numerical_mixing contains !< Calculate the spurious ``numerical'' mixing of tracer due to advection schemes. -subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, nm) - - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt_trans !< The transport time interval [T ~> s] - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(inout) :: nm !< Numerical mixing diagnostic - !! [CU2 H T-1 ~> conc2 m s-1] +subroutine numerical_mixing(G, GV, Tr, h, h_diag, dt_trans, Idt, uhtr, vhtr, nm) + + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated layer thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_diag !< Layer thicknesses prior to + !! dynamics [H ~> m or kg m-2] + real, intent(in) :: dt_trans !< The transport time interval [T ~> s] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(inout) :: nm !< Numerical mixing diagnostic + !! [CU2 H T-1 ~> conc2 m s-1] ! Upwind variables real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] @@ -38,26 +39,27 @@ subroutine numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vht x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. - call thickness_weighted_variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, nm) + call thickness_weighted_variance_advection(G, GV, Tr, h, h_diag, dt_trans, Idt, nm) call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) end subroutine numerical_mixing !< Subroutine for the variance advection, likely will remove once numerical mixing is sorted out -subroutine variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) +subroutine variance_advection(G, GV, Tr, h, h_diag, dt_trans, Idt, va) - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt_trans !< The transport time interval [T ~> s] - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: va !< Thickness weighted variance advection - !! [CU2 H T-1 ~> conc2 m s-1] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_diag !< Layer thicknesses prior to + !! dynamics [H ~> m or kg m-2] + real, intent(in) :: dt_trans !< The transport time interval [T ~> s] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: va !< Thickness weighted variance advection + !! [CU2 H T-1 ~> conc2 m s-1] - call thickness_weighted_variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) + call thickness_weighted_variance_advection(G, GV, Tr, h, h_diag, dt_trans, Idt, va) end subroutine variance_advection @@ -87,17 +89,18 @@ subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, vf) end subroutine variance_flux !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. -subroutine thickness_weighted_variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, Idt, res) - - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics - real, intent(in) :: dt !< Transport time interval [T ~> s] - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in - !![CU2 H T-1 ~> conc2 m s-1] +subroutine thickness_weighted_variance_advection(G, GV, Tr, h, h_diag, dt, Idt, res) + + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_diag !< Layer thicknesses prior to + !! dynamics [H ~> m or kg m-2] + real, intent(in) :: dt !< Transport time interval [T ~> s] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in + !! [CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -108,7 +111,7 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h, diag_pre_dyn, dt, is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke do k=1,nz ; do j=js,je ; do i=is,ie - h_prev = diag_pre_dyn%h_state(i,j,k) + h_prev = h_diag(i,j,k) Ihadv = 1 / h(i,j,k) C_prev = Tr%t_prev(i,j,k) Cadv = h_prev * C_prev + dt * Tr%advection_xy(i,j,k) @@ -159,7 +162,7 @@ subroutine zonal_upwind_values(G, GV, Tr, uhtr, x_upwind) type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] + !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: x_upwind !< zonal upwind tracer [CU ~> conc] !< Local variables @@ -186,11 +189,11 @@ subroutine thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_u type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes used - !! to advect tracers [H L2 ~> m3 or kg] + !! to advect tracers [H L2 ~> m3 or kg] real, intent(in) :: Idt !< Inverse timestep [T-1 ~> S-1] real,dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: y_upwind !< Meridional upwind tracer values [CU ~> conc] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in - !![CU2 H T-1 ~> conc2 m s-1] + !![CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index d6d6f28f75..fe8f4109f2 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -790,13 +790,12 @@ subroutine post_tracer_diagnostics_at_sync(Reg, h, diag_prev, diag, G, GV, dt) end subroutine post_tracer_diagnostics_at_sync !> Post the advective and diffusive tendencies -subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, diag, uhtr, vhtr, h, dt_trans, Idt) +subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag, uhtr, vhtr, h, dt_trans, Idt) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(tracer_registry_type), pointer :: Reg !< pointer to the tracer registry real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: h_diag !< Layer thicknesses on which to post fields [H ~> m or kg m-2] - type(diag_grid_storage), intent(in) :: diag_pre_dyn !< Stored grids from before dynamics type(diag_ctrl), intent(in) :: diag !< structure to regulate diagnostic output real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), & intent(in) :: uhtr !< Accumulated zonal thickness fluxes @@ -884,19 +883,19 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d if (Tr%id_numerical_mixing > 0) then nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, uhtr, vhtr, nm) - call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=diag_pre_dyn%h_state) + call numerical_mixing(G, GV, Tr, h, h_diag, dt_trans, Idt, uhtr, vhtr, nm) + call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=h_diag) !< The below is here while debuggin; to be removed once numerical mixing is all sorted if (Tr%id_variance_advection > 0) then va(:,:,:) = 0. - call variance_advection(G, GV, Tr, h, diag_pre_dyn, dt_trans, Idt, va) - call post_data(Tr%id_variance_advection, va, diag, alt_h=diag_pre_dyn%h_state) + call variance_advection(G, GV, Tr, h, h_diag, dt_trans, Idt, va) + call post_data(Tr%id_variance_advection, va, diag, alt_h=h_diag) endif if (Tr%id_variance_flux > 0) then vf(:,:,:) = 0. call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, vf) - call post_data(Tr%id_variance_flux, vf, diag, alt_h=diag_pre_dyn%h_state) + call post_data(Tr%id_variance_flux, vf, diag, alt_h=h_diag) endif endif ! My check for the indexing hack used in numiercal_mixing @@ -904,8 +903,8 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag_pre_dyn, d adx_eu(:,:,:) = 0. adx_wu(:,:,:) = 0. call Tr_east_west_upoints(Tr, G, nz, adx_eu, adx_wu) - call post_data(Tr%id_adx_eu, adx_eu, diag, alt_h=diag_pre_dyn%h_state) - call post_data(Tr%id_adx_wu, adx_wu, diag, alt_h=diag_pre_dyn%h_state) + call post_data(Tr%id_adx_eu, adx_eu, diag, alt_h=h_diag) + call post_data(Tr%id_adx_wu, adx_wu, diag, alt_h=h_diag) endif ! A few diagnostics introduce with MARBL driver From 6f50dec6a7b23b6eaac7aa21574af03ce44ea68e Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 13 Mar 2026 16:08:49 +1100 Subject: [PATCH 245/288] More cleanup --- src/tracer/MOM_tracer_numerical_mixing.F90 | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index aaa7b877fe..a4d284eefa 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -20,7 +20,7 @@ subroutine numerical_mixing(G, GV, Tr, h, h_diag, dt_trans, Idt, uhtr, vhtr, nm) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated layer thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated layer thicknesses [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_diag !< Layer thicknesses prior to !! dynamics [H ~> m or kg m-2] real, intent(in) :: dt_trans !< The transport time interval [T ~> s] @@ -128,11 +128,11 @@ subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry real,dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] + !! used to advect tracers [H L2 ~> m3 or kg] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] real,dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: x_upwind !< Zonal upwind tracer [CU ~> conc] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in - !![CU2 H T-1 ~> conc2 m s-1] + !![CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -144,11 +144,7 @@ subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind call zonal_upwind_values(G, GV, Tr, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - ! east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I+1,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) - ! west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) - ! res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) - ! This code passes the thickness dimensional test but does not accurately calculate numerical mixing - east = (2 * (Tr%ad_x(I,j,k)*x_upwind(I,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k)*x_upwind(I,j,k))) + east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo @@ -205,11 +201,7 @@ subroutine thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_u call meridional_upwind_values(G, GV, Tr, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - ! north = (2 * (Tr%ad_y(i,J,k) * y_upwind(i,J,k))) - ((Idt*vhtr(i,J+1,k)) * (y_upwind(i,J,k) **2)) - ! south = (2 * (Tr%ad_y(i,J-1,k)* y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J-1,k)**2)) - ! res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) - ! This code passes the thickness dimensional test but is not correct for the numerical mixing diagnostic - north = (2 * (Tr%ad_y(i,J,k)*y_upwind(i,J,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J,k)*y_upwind(i,J,k))) + north = (2 * (Tr%ad_y(i,J,k) *y_upwind(i,J,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) south = (2 * (Tr%ad_y(i,J-1,k)*y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J-1,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) enddo ; enddo ; enddo From 3b734c0b75fc6f395279eeaecbd4167388ffd305 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 13 Mar 2026 16:25:13 +1100 Subject: [PATCH 246/288] Remove no longer needed debuggin code --- src/diagnostics/MOM_diagnostics.F90 | 22 ----- src/tracer/MOM_tracer_numerical_mixing.F90 | 94 +--------------------- src/tracer/MOM_tracer_registry.F90 | 56 +------------ src/tracer/MOM_tracer_types.F90 | 2 - 4 files changed, 3 insertions(+), 171 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index b8bbda7f58..bd5d74d6d9 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -35,7 +35,6 @@ module MOM_diagnostics use MOM_variables, only : accel_diag_ptrs, cont_diag_ptrs, surface use MOM_verticalGrid, only : verticalGrid_type, get_thickness_units, get_flux_units use MOM_wave_speed, only : wave_speed, wave_speed_CS, wave_speed_init -use MOM_tracer_numerical_mixing, only : east_west_upoints implicit none ; private @@ -160,7 +159,6 @@ module MOM_diagnostics type, public :: transport_diag_IDs ; private !>@{ Diagnostics for tracer horizontal transport integer :: id_uhtr = -1, id_umo = -1, id_umo_2d = -1 - integer :: id_uhtr_eu = -1, id_uhtr_wu = -1 integer :: id_vhtr = -1, id_vmo = -1, id_vmo_2d = -1 integer :: id_dynamics_h = -1, id_dynamics_h_tendency = -1 !>@} @@ -1651,13 +1649,6 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: umo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: vmo ! Diagnostics of layer mass transport [R Z L2 T-1 ~> kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_tend ! Change in layer thickness due to dynamics - ! Temporary variables for saving east and west u point uhtr values - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: uhtr_eu !< East u point value of accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: uhtr_wu !< West u point value of accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - ! [H T-1 ~> m s-1 or kg m-2 s-1]. real :: Idt ! The inverse of the time interval [T-1 ~> s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes @@ -1701,13 +1692,6 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy endif if (IDs%id_uhtr > 0) call post_data(IDs%id_uhtr, uhtr, diag, alt_h=diag_pre_dyn%h_state) - if (IDs%id_uhtr_eu > 0 .or. IDs%id_uhtr_wu > 0) then - uhtr_eu(:,:,:) = 0. - uhtr_wu(:,:,:) = 0. - call east_west_upoints(uhtr, G, GV, uhtr_eu, uhtr_wu) - call post_data(IDS%id_uhtr_eu, uhtr_eu, diag, alt_h=diag_pre_dyn%h_state) - call post_data(IDS%id_uhtr_wu, uhtr_wu, diag, alt_h=diag_pre_dyn%h_state) - endif if (IDs%id_vhtr > 0) call post_data(IDs%id_vhtr, vhtr, diag, alt_h=diag_pre_dyn%h_state) if (IDs%id_dynamics_h > 0) call post_data(IDs%id_dynamics_h, diag_pre_dyn%h_state, diag, & alt_h=diag_pre_dyn%h_state) @@ -2229,12 +2213,6 @@ subroutine register_transport_diags(Time, G, GV, US, IDs, diag) IDs%id_uhtr = register_diag_field('ocean_model', 'uhtr', diag%axesCuL, Time, & 'Accumulated zonal thickness fluxes to advect tracers', & accum_flux_units, y_cell_method='sum', v_extensive=.true., conversion=GV%H_to_MKS*US%L_to_m**2) - IDs%id_uhtr_eu = register_diag_field('ocean_model', 'uhtr_eu', diag%axesTL, Time, & - 'East u point value of accumulated zonal thickness fluxes to advect tracers', & - accum_flux_units, y_cell_method='sum', v_extensive=.true., conversion=GV%H_to_MKS*US%L_to_m**2) - IDs%id_uhtr_wu = register_diag_field('ocean_model', 'uhtr_wu', diag%axesTL, Time, & - 'West u point value of accumulated zonal thickness fluxes to advect tracers', & - accum_flux_units, y_cell_method='sum', v_extensive=.true., conversion=GV%H_to_MKS*US%L_to_m**2) IDs%id_vhtr = register_diag_field('ocean_model', 'vhtr', diag%axesCvL, Time, & 'Accumulated meridional thickness fluxes to advect tracers', & accum_flux_units, x_cell_method='sum', v_extensive=.true., conversion=GV%H_to_MKS*US%L_to_m**2) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index a4d284eefa..2d40b17792 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -1,7 +1,7 @@ !> Functions and routines involved in calculating numerical mixing of tracers due to advection schemes. module MOM_tracer_numerical_mixing -use MOM_diag_mediator, only : diag_ctrl, diag_grid_storage +use MOM_diag_mediator, only : diag_ctrl use MOM_grid, only : ocean_grid_type use MOM_tracer_types, only : tracer_type use MOM_verticalGrid, only : verticalGrid_type @@ -10,7 +10,7 @@ module MOM_tracer_numerical_mixing #include -public numerical_mixing, variance_advection, variance_flux, east_west_upoints, Tr_east_west_upoints +public numerical_mixing contains @@ -45,49 +45,6 @@ subroutine numerical_mixing(G, GV, Tr, h, h_diag, dt_trans, Idt, uhtr, vhtr, nm) end subroutine numerical_mixing -!< Subroutine for the variance advection, likely will remove once numerical mixing is sorted out -subroutine variance_advection(G, GV, Tr, h, h_diag, dt_trans, Idt, va) - - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_diag !< Layer thicknesses prior to - !! dynamics [H ~> m or kg m-2] - real, intent(in) :: dt_trans !< The transport time interval [T ~> s] - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: va !< Thickness weighted variance advection - !! [CU2 H T-1 ~> conc2 m s-1] - - call thickness_weighted_variance_advection(G, GV, Tr, h, h_diag, dt_trans, Idt, va) - -end subroutine variance_advection - -!< Subroutine for the horizontal variance flux, likely will remove once numerical mixing is sorted out -subroutine variance_flux(G, GV, Tr, Idt, uhtr, vhtr, vf) - - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: vf !< Horizontal thickness weighted variance flux - !! [CU2 H T-1 ~> conc2 m s-1] - ! Try with local variables - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] - - x_upwind(:,:,:) = 0. - y_upwind(:,:,:) = 0. - - call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, vf) - call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, vf) - -end subroutine variance_flux - !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. subroutine thickness_weighted_variance_advection(G, GV, Tr, h, h_diag, dt, Idt, res) @@ -234,51 +191,4 @@ subroutine meridional_upwind_values(G, GV, Tr, vhtr, y_upwind) end subroutine meridional_upwind_values -! Subroutine to construct a MWE that demonstrates the hack that I have above where I have the `uhtr` variable -! indexed one value higher than `TR%ad_x`. I should then be able to compare this output to the equivalent -! saved variables and demonstrate that the index online and offline does not seem to match. Or in doing this I will -! find the error in my ways! -subroutine east_west_upoints(uhtr, G, GV, uhtr_eu, uhtr_wu) - - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for indexes - type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< the variable to save the east faces of - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr_eu !< The east u point value of `var` - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: uhtr_wu !< The west u point value of `var` - - !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre indexes - integer :: i, j, k !< Counters - - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - - do k=1,nz ; do j=js,je ; do i=is,ie - uhtr_wu(i,j,k) = uhtr(I-1,j,k) - uhtr_eu(i,j,k) = uhtr(I,j,k) - enddo ; enddo; enddo - -end subroutine east_west_upoints - -subroutine Tr_east_west_upoints(Tr, G, nz, adx_eu, adx_wu) - - type(tracer_type), intent(in) :: Tr !< Tracer - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure for indexes - integer, intent(in) :: nz !< number of vertical levels - - real, intent(inout) :: adx_eu(:,:,:) !< The east u point value of `var` - real, intent(inout) :: adx_wu(:,:,:) !< The west u point value of `var` - - !< Local variables - integer :: is, ie, js, je !< Grid cell centre indexes - integer :: i, j, k !< Counters - - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - - do k=1,nz ; do j=js,je ; do i=is,ie - adx_wu(i,j,k) = Tr%ad_x(I-1,j,k) - adx_eu(i,j,k) = Tr%ad_x(I,j,k) - enddo ; enddo; enddo - -end subroutine Tr_east_west_upoints - end module MOM_tracer_numerical_mixing diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index fe8f4109f2..81050e41df 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -25,7 +25,7 @@ module MOM_tracer_registry use MOM_unit_scaling, only : unit_scale_type use MOM_verticalGrid, only : verticalGrid_type use MOM_tracer_types, only : tracer_type, tracer_registry_type -use MOM_tracer_numerical_mixing, only : numerical_mixing, variance_advection, variance_flux, Tr_east_west_upoints +use MOM_tracer_numerical_mixing, only : numerical_mixing implicit none ; private @@ -362,12 +362,6 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u diag%axesCuL, Time, trim(flux_longname)//" advective zonal flux" , & trim(flux_units), v_extensive=.true., y_cell_method='sum', & conversion=Tr%flux_scale*(US%L_to_m**2)*US%s_to_T) - Tr%id_adx_eu = register_diag_field("ocean_model", trim(shortnm)//"_adx_eu", & - diag%axesTL, Time, "East upoint Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & - flux_units, v_extensive=.true., conversion=Tr%flux_scale*(US%L_to_m**2)*US%s_to_T, y_cell_method='sum') - Tr%id_adx_wu = register_diag_field("ocean_model", trim(shortnm)//"_adx_wu", & - diag%axesTL, Time, "West upoint Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & - flux_units, v_extensive=.true., conversion=Tr%flux_scale*(US%L_to_m**2)*US%s_to_T, y_cell_method='sum') Tr%id_ady = register_diag_field("ocean_model", trim(shortnm)//"_ady", & diag%axesCvL, Time, trim(flux_longname)//" advective meridional flux" , & trim(flux_units), v_extensive=.true., x_cell_method='sum', & @@ -392,22 +386,10 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) - Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & - diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) - Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & - diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & - trim(Tr%units)//" 2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & flux_units, v_extensive=.true., conversion=Tr%flux_scale*(US%L_to_m**2)*US%s_to_T, y_cell_method='sum') - Tr%id_adx_eu = register_diag_field("ocean_model", trim(shortnm)//"_adx_eu", & - diag%axesTL, Time, "East upoint Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & - flux_units, v_extensive=.true., conversion=Tr%flux_scale*(US%L_to_m**2)*US%s_to_T, y_cell_method='sum') - Tr%id_adx_wu = register_diag_field("ocean_model", trim(shortnm)//"_adx_wu", & - diag%axesTL, Time, "West upoint Advective (by residual mean) Zonal Flux of "//trim(flux_longname), & - flux_units, v_extensive=.true., conversion=Tr%flux_scale*(US%L_to_m**2)*US%s_to_T, y_cell_method='sum') Tr%id_ady = register_diag_field("ocean_model", trim(shortnm)//"_ady", & diag%axesCvL, Time, "Advective (by residual mean) Meridional Flux of "//trim(flux_longname), & flux_units, v_extensive=.true., conversion=Tr%flux_scale*(US%L_to_m**2)*US%s_to_T, x_cell_method='sum') @@ -432,12 +414,6 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) - Tr%id_variance_advection = register_diag_field("ocean_model", trim(shortnm)//"_variance_advection", & - diag%axesTL, Time, "Advection of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) - Tr%id_variance_flux = register_diag_field("ocean_model", trim(shortnm)//"_variance_flux", & - diag%axesTL, Time, "Flux of "//trim(shortnm)//" variance", & - trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & diag%axesT1, Time, & @@ -815,16 +791,6 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag, uhtr, vht real :: ztop(SZI_(G),SZJ_(G)) ! position of the top interface [H ~> m or kg m-2] real :: zbot(SZI_(G),SZJ_(G)) ! position of the bottom interface [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer [CU2 H T-1 ~> conc2 m s-1] - ! va and vf will be removed but are needed in the debugging process - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: va ! Thickness weighted variance advection - ! [CU2 H T-1 ~> conc2 m s-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: vf ! Horizontal thickness weighted variance flux - ! [CU2 H T-1 ~> conc2 m s-1] - ! Temporary local varaibles for saving east and west u point ad_x values - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: adx_eu !< East u value of diagnostic x-advective flux - !! [CU H L2 T-1 ~> conc m3 s-1 or conc kg s-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: adx_wu !< West u value of diagnostic x-advective flux - !! [CU H L2 T-1 ~> conc m3 s-1 or conc kg s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. type(tracer_type), pointer :: Tr=>NULL() @@ -885,26 +851,6 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag, uhtr, vht nm(:,:,:) = 0. call numerical_mixing(G, GV, Tr, h, h_diag, dt_trans, Idt, uhtr, vhtr, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=h_diag) - - !< The below is here while debuggin; to be removed once numerical mixing is all sorted - if (Tr%id_variance_advection > 0) then - va(:,:,:) = 0. - call variance_advection(G, GV, Tr, h, h_diag, dt_trans, Idt, va) - call post_data(Tr%id_variance_advection, va, diag, alt_h=h_diag) - endif - if (Tr%id_variance_flux > 0) then - vf(:,:,:) = 0. - call variance_flux(G, GV, Tr, Idt, uhtr, vhtr, vf) - call post_data(Tr%id_variance_flux, vf, diag, alt_h=h_diag) - endif - endif - ! My check for the indexing hack used in numiercal_mixing - if (Tr%id_adx_eu > 0 .or. Tr%id_adx_wu > 0) then - adx_eu(:,:,:) = 0. - adx_wu(:,:,:) = 0. - call Tr_east_west_upoints(Tr, G, nz, adx_eu, adx_wu) - call post_data(Tr%id_adx_eu, adx_eu, diag, alt_h=h_diag) - call post_data(Tr%id_adx_wu, adx_wu, diag, alt_h=h_diag) endif ! A few diagnostics introduce with MARBL driver diff --git a/src/tracer/MOM_tracer_types.F90 b/src/tracer/MOM_tracer_types.F90 index b0d8f2a657..0d608f6f18 100644 --- a/src/tracer/MOM_tracer_types.F90 +++ b/src/tracer/MOM_tracer_types.F90 @@ -109,7 +109,6 @@ module MOM_tracer_types !>@{ Diagnostic IDs integer :: id_tr = -1, id_tr_post_horzn = -1 integer :: id_adx = -1, id_ady = -1, id_dfx = -1, id_dfy = -1 - integer :: id_adx_eu = -1, id_adx_wu = -1 integer :: id_hbd_dfx = -1, id_hbd_dfy = -1 integer :: id_hbd_dfx_2d = -1, id_hbd_dfy_2d = -1 integer :: id_adx_2d = -1, id_ady_2d = -1, id_dfx_2d = -1, id_dfy_2d = -1 @@ -122,7 +121,6 @@ module MOM_tracer_types integer :: id_zint = -1, id_zint_100m = -1, id_surf = -1 integer :: id_net_surfflux = -1, id_NLT_tendency = -1, id_NLT_budget = -1 integer :: id_numerical_mixing = -1 - integer :: id_variance_advection = -1, id_variance_flux = -1 !>@} end type tracer_type From c4cc29ae10db83a4ef19a603dcde59451878393f Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 13 Mar 2026 21:48:43 +1100 Subject: [PATCH 247/288] More cleanup --- src/tracer/MOM_tracer_numerical_mixing.F90 | 73 +++++++++++----------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 2d40b17792..ddb5c0a444 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -1,7 +1,6 @@ !> Functions and routines involved in calculating numerical mixing of tracers due to advection schemes. module MOM_tracer_numerical_mixing -use MOM_diag_mediator, only : diag_ctrl use MOM_grid, only : ocean_grid_type use MOM_tracer_types, only : tracer_type use MOM_verticalGrid, only : verticalGrid_type @@ -17,20 +16,20 @@ module MOM_tracer_numerical_mixing !< Calculate the spurious ``numerical'' mixing of tracer due to advection schemes. subroutine numerical_mixing(G, GV, Tr, h, h_diag, dt_trans, Idt, uhtr, vhtr, nm) - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated layer thicknesses [H ~> m or kg m-2] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_diag !< Layer thicknesses prior to - !! dynamics [H ~> m or kg m-2] - real, intent(in) :: dt_trans !< The transport time interval [T ~> s] - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(inout) :: nm !< Numerical mixing diagnostic - !! [CU2 H T-1 ~> conc2 m s-1] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated layer thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_diag !< Layer thicknesses prior to + !! dynamics [H ~> m or kg m-2] + real, intent(in) :: dt_trans !< The transport time interval [T ~> s] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: nm !< Numerical mixing diagnostic + !! [CU2 H T-1 ~> conc2 m s-1] ! Upwind variables real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] @@ -81,15 +80,15 @@ end subroutine thickness_weighted_variance_advection !! from upwind values. subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, res) - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - real,dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real,dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: x_upwind !< Zonal upwind tracer [CU ~> conc] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in - !![CU2 H T-1 ~> conc2 m s-1] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: x_upwind !< Zonal upwind tracer [CU ~> conc] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in + !![CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -138,14 +137,14 @@ end subroutine zonal_upwind_values !! from upwind values. subroutine thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, res) - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes used + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes used !! to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: Idt !< Inverse timestep [T-1 ~> S-1] - real,dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: y_upwind !< Meridional upwind tracer values [CU ~> conc] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in + real, intent(in) :: Idt !< Inverse timestep [T-1 ~> S-1] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: y_upwind !< Meridional upwind tracer values [CU ~> conc] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in !![CU2 H T-1 ~> conc2 m s-1] !< Local variables @@ -168,12 +167,12 @@ end subroutine thickness_weighted_meridional_variance_flux !< Subroutine to calculate upwind value in the meridional direction subroutine meridional_upwind_values(G, GV, Tr, vhtr, y_upwind) - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes used - !! to advect tracers [H L2 ~> m3 or kg] - real,dimension(SZI_(G),SZJB_(G),SZK_(GV)),intent(inout) :: y_upwind !< Meridional upwind tracer values [CU ~> conc] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes used + !! to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)),intent(inout) :: y_upwind !< Meridional upwind tracer values [CU ~> conc] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre indexes From 8590647a44939d2cfae0e0076533b972402bb759 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 13 Mar 2026 22:02:09 +1100 Subject: [PATCH 248/288] Go back to diag_prev%h_state --- src/tracer/MOM_tracer_numerical_mixing.F90 | 15 +++++++-------- src/tracer/MOM_tracer_registry.F90 | 3 ++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index ddb5c0a444..9c01fc02c6 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -1,6 +1,7 @@ !> Functions and routines involved in calculating numerical mixing of tracers due to advection schemes. module MOM_tracer_numerical_mixing +use MOM_diag_mediator, only : diag_grid_storage use MOM_grid, only : ocean_grid_type use MOM_tracer_types, only : tracer_type use MOM_verticalGrid, only : verticalGrid_type @@ -14,14 +15,13 @@ module MOM_tracer_numerical_mixing contains !< Calculate the spurious ``numerical'' mixing of tracer due to advection schemes. -subroutine numerical_mixing(G, GV, Tr, h, h_diag, dt_trans, Idt, uhtr, vhtr, nm) +subroutine numerical_mixing(G, GV, Tr, diag_prev, h, dt_trans, Idt, uhtr, vhtr, nm) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry + type(diag_grid_storage), intent(in) :: diag_prev !< Diagnostic grids from previous timestep real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated layer thicknesses [H ~> m or kg m-2] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_diag !< Layer thicknesses prior to - !! dynamics [H ~> m or kg m-2] real, intent(in) :: dt_trans !< The transport time interval [T ~> s] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes @@ -38,21 +38,20 @@ subroutine numerical_mixing(G, GV, Tr, h, h_diag, dt_trans, Idt, uhtr, vhtr, nm) x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. - call thickness_weighted_variance_advection(G, GV, Tr, h, h_diag, dt_trans, Idt, nm) + call thickness_weighted_variance_advection(G, GV, Tr, diag_prev, h, dt_trans, Idt, nm) call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) end subroutine numerical_mixing !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. -subroutine thickness_weighted_variance_advection(G, GV, Tr, h, h_diag, dt, Idt, res) +subroutine thickness_weighted_variance_advection(G, GV, Tr, diag_prev, h, dt, Idt, res) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + type(diag_grid_storage), intent(in) :: diag_prev !< Diagnostic grids from previous timestep real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_diag !< Layer thicknesses prior to - !! dynamics [H ~> m or kg m-2] real, intent(in) :: dt !< Transport time interval [T ~> s] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in @@ -67,7 +66,7 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h, h_diag, dt, Idt, is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke do k=1,nz ; do j=js,je ; do i=is,ie - h_prev = h_diag(i,j,k) + h_prev = diag_prev%h_state(i,j,k) Ihadv = 1 / h(i,j,k) C_prev = Tr%t_prev(i,j,k) Cadv = h_prev * C_prev + dt * Tr%advection_xy(i,j,k) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 81050e41df..b09655bf5e 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -766,10 +766,11 @@ subroutine post_tracer_diagnostics_at_sync(Reg, h, diag_prev, diag, G, GV, dt) end subroutine post_tracer_diagnostics_at_sync !> Post the advective and diffusive tendencies -subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag, uhtr, vhtr, h, dt_trans, Idt) +subroutine post_tracer_transport_diagnostics(G, GV, Reg, diag_prev, h_diag, diag, uhtr, vhtr, h, dt_trans, Idt) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(tracer_registry_type), pointer :: Reg !< pointer to the tracer registry + type(diag_grid_storage), intent(in) :: diag_prev !< Contains diagnostic grids from previous timestep real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: h_diag !< Layer thicknesses on which to post fields [H ~> m or kg m-2] type(diag_ctrl), intent(in) :: diag !< structure to regulate diagnostic output From 8049f0bb966faa896a4ec8d169a472b8e22e131d Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 13 Mar 2026 22:03:10 +1100 Subject: [PATCH 249/288] Correctly pass to subroutine --- src/tracer/MOM_tracer_registry.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index b09655bf5e..aa4350a360 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -850,7 +850,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, diag_prev, h_diag, diag if (Tr%id_numerical_mixing > 0) then nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, h, h_diag, dt_trans, Idt, uhtr, vhtr, nm) + call numerical_mixing(G, GV, Tr, diag_prev, h, dt_trans, Idt, uhtr, vhtr, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=h_diag) endif From 4f15b8134cdbea482fa81d92e5c1792c6d611e22 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 13 Mar 2026 22:09:26 +1100 Subject: [PATCH 250/288] Correctly pass args to transport diags --- src/diagnostics/MOM_diagnostics.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index bd5d74d6d9..728ce39f46 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1704,7 +1704,8 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy call post_data(IDs%id_dynamics_h_tendency, h_tend, diag, alt_h=diag_pre_dyn%h_state) endif - call post_tracer_transport_diagnostics(G, GV, Reg, diag_pre_dyn%h_state, diag, uhtr, vhtr, h, dt_trans, Idt) + call post_tracer_transport_diagnostics(G, GV, Reg, diag_pre_dyn, diag_pre_dyn%h_state, diag, & + uhtr, vhtr, h, dt_trans, Idt) call diag_restore_grids(diag) From 7ae4e5ebc238d582e263795c6d9ecbc73735c151 Mon Sep 17 00:00:00 2001 From: jbisits Date: Fri, 13 Mar 2026 22:42:54 +1100 Subject: [PATCH 251/288] Add back diag_ctrl --- src/tracer/MOM_tracer_numerical_mixing.F90 | 29 +++++++++++----------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 9c01fc02c6..7d2ba23969 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -1,7 +1,7 @@ !> Functions and routines involved in calculating numerical mixing of tracers due to advection schemes. module MOM_tracer_numerical_mixing -use MOM_diag_mediator, only : diag_grid_storage +use MOM_diag_mediator, only : diag_ctrl, diag_grid_storage use MOM_grid, only : ocean_grid_type use MOM_tracer_types, only : tracer_type use MOM_verticalGrid, only : verticalGrid_type @@ -47,15 +47,15 @@ end subroutine numerical_mixing !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. subroutine thickness_weighted_variance_advection(G, GV, Tr, diag_prev, h, dt, Idt, res) - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - type(diag_grid_storage), intent(in) :: diag_prev !< Diagnostic grids from previous timestep - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] - real, intent(in) :: dt !< Transport time interval [T ~> s] - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in - !! [CU2 H T-1 ~> conc2 m s-1] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + type(diag_grid_storage), intent(in) :: diag_prev !< Diagnostic grids from previous timestep + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] + real, intent(in) :: dt !< Transport time interval [T ~> s] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in + !! [CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -139,12 +139,13 @@ subroutine thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_u type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes used - !! to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] real, intent(in) :: Idt !< Inverse timestep [T-1 ~> S-1] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: y_upwind !< Meridional upwind tracer values [CU ~> conc] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: y_upwind !< Meridional upwind tracer values + !! [CU ~> conc] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in - !![CU2 H T-1 ~> conc2 m s-1] + !![CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes From e4c4896a13ebb147ad40d53f387be1a5ee1c582f Mon Sep 17 00:00:00 2001 From: jbisits Date: Sat, 14 Mar 2026 19:51:04 +1100 Subject: [PATCH 252/288] Back to h_diag and fix from here --- src/diagnostics/MOM_diagnostics.F90 | 3 +-- src/tracer/MOM_tracer_numerical_mixing.F90 | 12 ++++++------ src/tracer/MOM_tracer_registry.F90 | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 728ce39f46..bd5d74d6d9 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -1704,8 +1704,7 @@ subroutine post_transport_diagnostics(G, GV, US, uhtr, vhtr, h, IDs, diag_pre_dy call post_data(IDs%id_dynamics_h_tendency, h_tend, diag, alt_h=diag_pre_dyn%h_state) endif - call post_tracer_transport_diagnostics(G, GV, Reg, diag_pre_dyn, diag_pre_dyn%h_state, diag, & - uhtr, vhtr, h, dt_trans, Idt) + call post_tracer_transport_diagnostics(G, GV, Reg, diag_pre_dyn%h_state, diag, uhtr, vhtr, h, dt_trans, Idt) call diag_restore_grids(diag) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 7d2ba23969..ffdf577109 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -15,12 +15,12 @@ module MOM_tracer_numerical_mixing contains !< Calculate the spurious ``numerical'' mixing of tracer due to advection schemes. -subroutine numerical_mixing(G, GV, Tr, diag_prev, h, dt_trans, Idt, uhtr, vhtr, nm) +subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry - type(diag_grid_storage), intent(in) :: diag_prev !< Diagnostic grids from previous timestep + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_diag !< Previous thicknesses [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated layer thicknesses [H ~> m or kg m-2] real, intent(in) :: dt_trans !< The transport time interval [T ~> s] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] @@ -38,19 +38,19 @@ subroutine numerical_mixing(G, GV, Tr, diag_prev, h, dt_trans, Idt, uhtr, vhtr, x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. - call thickness_weighted_variance_advection(G, GV, Tr, diag_prev, h, dt_trans, Idt, nm) + call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) end subroutine numerical_mixing !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. -subroutine thickness_weighted_variance_advection(G, GV, Tr, diag_prev, h, dt, Idt, res) +subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, res) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - type(diag_grid_storage), intent(in) :: diag_prev !< Diagnostic grids from previous timestep + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_diag !< Previous thicknesses [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] real, intent(in) :: dt !< Transport time interval [T ~> s] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] @@ -66,7 +66,7 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, diag_prev, h, dt, Id is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke do k=1,nz ; do j=js,je ; do i=is,ie - h_prev = diag_prev%h_state(i,j,k) + h_prev = h_diag(i,j,k) Ihadv = 1 / h(i,j,k) C_prev = Tr%t_prev(i,j,k) Cadv = h_prev * C_prev + dt * Tr%advection_xy(i,j,k) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index aa4350a360..b09655bf5e 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -850,7 +850,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, diag_prev, h_diag, diag if (Tr%id_numerical_mixing > 0) then nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, diag_prev, h, dt_trans, Idt, uhtr, vhtr, nm) + call numerical_mixing(G, GV, Tr, h, h_diag, dt_trans, Idt, uhtr, vhtr, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=h_diag) endif From 0b91bb1939428c106a2527d2cbbfb898c31222d3 Mon Sep 17 00:00:00 2001 From: jbisits Date: Sat, 14 Mar 2026 20:02:25 +1100 Subject: [PATCH 253/288] Forgot to save file --- src/tracer/MOM_tracer_registry.F90 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index b09655bf5e..81050e41df 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -766,11 +766,10 @@ subroutine post_tracer_diagnostics_at_sync(Reg, h, diag_prev, diag, G, GV, dt) end subroutine post_tracer_diagnostics_at_sync !> Post the advective and diffusive tendencies -subroutine post_tracer_transport_diagnostics(G, GV, Reg, diag_prev, h_diag, diag, uhtr, vhtr, h, dt_trans, Idt) +subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag, uhtr, vhtr, h, dt_trans, Idt) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(tracer_registry_type), pointer :: Reg !< pointer to the tracer registry - type(diag_grid_storage), intent(in) :: diag_prev !< Contains diagnostic grids from previous timestep real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: h_diag !< Layer thicknesses on which to post fields [H ~> m or kg m-2] type(diag_ctrl), intent(in) :: diag !< structure to regulate diagnostic output From 2bbf42bad86e5c8c092c4368be647a546b440591 Mon Sep 17 00:00:00 2001 From: jbisits Date: Sat, 14 Mar 2026 20:21:53 +1100 Subject: [PATCH 254/288] Wrong order of arguments in nm call --- src/tracer/MOM_tracer_registry.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 81050e41df..0660db59c7 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -849,7 +849,7 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag, uhtr, vht if (Tr%id_numerical_mixing > 0) then nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, h, h_diag, dt_trans, Idt, uhtr, vhtr, nm) + call numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=h_diag) endif From 3e283af8382d19bfc0fb51604d7f7ba1db053549 Mon Sep 17 00:00:00 2001 From: jbisits Date: Sat, 14 Mar 2026 21:43:10 +1100 Subject: [PATCH 255/288] Comment out unneeded modules --- src/tracer/MOM_tracer_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index ffdf577109..babee0bd6b 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -1,7 +1,7 @@ !> Functions and routines involved in calculating numerical mixing of tracers due to advection schemes. module MOM_tracer_numerical_mixing -use MOM_diag_mediator, only : diag_ctrl, diag_grid_storage +! use MOM_diag_mediator, only : diag_ctrl, diag_grid_storage use MOM_grid, only : ocean_grid_type use MOM_tracer_types, only : tracer_type use MOM_verticalGrid, only : verticalGrid_type From eadaee124ddad46413f4093967c8821396dc8d57 Mon Sep 17 00:00:00 2001 From: jbisits Date: Sun, 15 Mar 2026 10:57:00 +1100 Subject: [PATCH 256/288] Simplify twva + specify dimensions for local variables --- src/tracer/MOM_tracer_numerical_mixing.F90 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index babee0bd6b..8dbdb0724a 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -58,19 +58,19 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, !! [CU2 H T-1 ~> conc2 m s-1] !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: h_prev, C_prev, Ihadv, Cadv !< Thickness and tracer at previous timestep, inverse - !< updated thickness and non-invers tracer after advection. + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: Ihadv !< Inverse updated thickness [H-1 ~> m-1] + real :: ht_prev !< Thickness weighted tracer prior to dynamics [CU H ~> conc m] + real :: t_adv !< Thickness weighted tracer after lateral advection [CU H ~> conc m] is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke do k=1,nz ; do j=js,je ; do i=is,ie - h_prev = h_diag(i,j,k) Ihadv = 1 / h(i,j,k) - C_prev = Tr%t_prev(i,j,k) - Cadv = h_prev * C_prev + dt * Tr%advection_xy(i,j,k) - res(i,j,k) = ( (Ihadv * Cadv**2) - (h_prev * C_prev**2) ) * Idt + ht_prev = h_diag(i,j,k) * Tr%t_prev(i,j,k) + Cadv = ht_prev + dt * Tr%advection_xy(i,j,k) + res(i,j,k) = ( (Ihadv * Cadv**2) - (ht_prev * Tr%t_prev(i,j,k)) ) * Idt enddo ; enddo ; enddo end subroutine thickness_weighted_variance_advection From 5ab92e902616024a7d6aa68287e1a6cf9274de75 Mon Sep 17 00:00:00 2001 From: jbisits Date: Sun, 15 Mar 2026 12:43:08 +1100 Subject: [PATCH 257/288] More consistent local variable names --- src/tracer/MOM_tracer_numerical_mixing.F90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 8dbdb0724a..b6f5cfc067 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -60,17 +60,17 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters - real :: Ihadv !< Inverse updated thickness [H-1 ~> m-1] + real :: Ih !< Inverse updated thickness [H-1 ~> m-1] real :: ht_prev !< Thickness weighted tracer prior to dynamics [CU H ~> conc m] - real :: t_adv !< Thickness weighted tracer after lateral advection [CU H ~> conc m] + real :: ht_adv !< Thickness weighted tracer after lateral advection [CU H ~> conc m] is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke do k=1,nz ; do j=js,je ; do i=is,ie - Ihadv = 1 / h(i,j,k) + Ih = 1 / h(i,j,k) ht_prev = h_diag(i,j,k) * Tr%t_prev(i,j,k) - Cadv = ht_prev + dt * Tr%advection_xy(i,j,k) - res(i,j,k) = ( (Ihadv * Cadv**2) - (ht_prev * Tr%t_prev(i,j,k)) ) * Idt + ht_adv = ht_prev + dt * Tr%advection_xy(i,j,k) + res(i,j,k) = ( (Ih * ht_adv**2) - (ht_prev * Tr%t_prev(i,j,k)) ) * Idt enddo ; enddo ; enddo end subroutine thickness_weighted_variance_advection From 3e731637b8016acb843071f27c98f16f80cb31ca Mon Sep 17 00:00:00 2001 From: jbisits Date: Sun, 15 Mar 2026 13:31:58 +1100 Subject: [PATCH 258/288] Try only twva for thickness test --- src/tracer/MOM_tracer_numerical_mixing.F90 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index b6f5cfc067..19b2a6d45c 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -1,7 +1,6 @@ !> Functions and routines involved in calculating numerical mixing of tracers due to advection schemes. module MOM_tracer_numerical_mixing -! use MOM_diag_mediator, only : diag_ctrl, diag_grid_storage use MOM_grid, only : ocean_grid_type use MOM_tracer_types, only : tracer_type use MOM_verticalGrid, only : verticalGrid_type @@ -39,8 +38,8 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) y_upwind(:,:,:) = 0. call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) - call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) - call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) + ! call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) + ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) end subroutine numerical_mixing From bbcad9e435c5b0ef6b3603786f8867405b72f3ae Mon Sep 17 00:00:00 2001 From: jbisits Date: Sun, 15 Mar 2026 13:40:17 +1100 Subject: [PATCH 259/288] Test only twzvf --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 19b2a6d45c..8f2eeab165 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -37,8 +37,8 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. - call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) - ! call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) + ! call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) + call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) end subroutine numerical_mixing From 1880fe326ed36283e2e569009fd4994d267d3af2 Mon Sep 17 00:00:00 2001 From: jbisits Date: Sun, 15 Mar 2026 13:47:13 +1100 Subject: [PATCH 260/288] Test only twmvf on CI --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 8f2eeab165..4b8d4b851e 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -38,8 +38,8 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) y_upwind(:,:,:) = 0. ! call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) - call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) - ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) + ! call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) + call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) end subroutine numerical_mixing From cb277c91f63de320642cf9a9350bfb130b858a18 Mon Sep 17 00:00:00 2001 From: jbisits Date: Sun, 15 Mar 2026 20:08:41 +1100 Subject: [PATCH 261/288] CI check for adx part --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 4b8d4b851e..87edcb87e2 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -38,8 +38,8 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) y_upwind(:,:,:) = 0. ! call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) - ! call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) - call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) + call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) + ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) end subroutine numerical_mixing @@ -98,8 +98,8 @@ subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind call zonal_upwind_values(G, GV, Tr, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) - west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) + east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) !- ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) + west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) !- ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo From 8b43d03bae65d2a319c32915d9f354710f4d1c7f Mon Sep 17 00:00:00 2001 From: jbisits Date: Sun, 15 Mar 2026 20:16:34 +1100 Subject: [PATCH 262/288] CI on uhtr + upwind term --- src/tracer/MOM_tracer_numerical_mixing.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 87edcb87e2..538b2809de 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -98,8 +98,10 @@ subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind call zonal_upwind_values(G, GV, Tr, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) !- ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) - west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) !- ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) + ! east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) + ! west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) + east = - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) + west = - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo From 2cd4ec2671e42f07043b7ce7592c30487b9df23d Mon Sep 17 00:00:00 2001 From: jbisits Date: Sun, 15 Mar 2026 20:46:30 +1100 Subject: [PATCH 263/288] Check xupwind variable --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 538b2809de..282e27c9c2 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -100,8 +100,8 @@ subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind do k=1,nz ; do j=js,je ; do i=is,ie ! east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) ! west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) - east = - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) - west = - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) + east = - x_upwind(I,j,k) + west = - x_upwind(I-1,j,k) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo From 1a657e9e3ba35f499106762e22b41e85219dc2d6 Mon Sep 17 00:00:00 2001 From: jbisits Date: Sun, 15 Mar 2026 20:53:50 +1100 Subject: [PATCH 264/288] Fill more of t_prev? --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- src/tracer/MOM_tracer_registry.F90 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 282e27c9c2..b5e603460d 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -100,8 +100,8 @@ subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind do k=1,nz ; do j=js,je ; do i=is,ie ! east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) ! west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) - east = - x_upwind(I,j,k) - west = - x_upwind(I-1,j,k) + east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) + west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 0660db59c7..c11aed91db 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -485,7 +485,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u if ((Tr%id_tendency > 0) .or. (Tr%id_numerical_mixing > 0)) then call safe_alloc_ptr(Tr%t_prev,isd,ied,jsd,jed,nz) - do k=1,nz ; do j=js-1,je+1 ; do i=is-1,ie+1 + do k=1,nz ; do j=js-2,je+2 ; do i=is-2,ie+2 Tr%t_prev(i,j,k) = Tr%t(i,j,k) enddo ; enddo ; enddo endif @@ -741,7 +741,7 @@ subroutine post_tracer_diagnostics_at_sync(Reg, h, diag_prev, diag, G, GV, dt) call post_data(Tr%id_tendency, work3d, diag, alt_h=diag_prev%h_state) endif if (Tr%id_numerical_mixing > 0) then - do k=1,nz ; do j=js-1,je+1 ; do i=is-1,ie+1 + do k=1,nz ; do j=js-2,je+2 ; do i=is-2,ie+2 tr%t_prev(i,j,k) = Tr%t(i,j,k) enddo ; enddo ; enddo endif From a3a2d86049fdbe1e61af3663c1469ea67a4424c0 Mon Sep 17 00:00:00 2001 From: jbisits Date: Sun, 15 Mar 2026 21:03:47 +1100 Subject: [PATCH 265/288] Try uhtr part with longer t_prev --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index b5e603460d..411790e8f0 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -100,8 +100,8 @@ subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind do k=1,nz ; do j=js,je ; do i=is,ie ! east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) ! west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) - east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) + east = - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k)*x_upwind(I,j,k))) + west = - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo From bdcfd04ef08618e16aebc32083d31f5afb0fc4e4 Mon Sep 17 00:00:00 2001 From: jbisits Date: Sun, 15 Mar 2026 21:11:29 +1100 Subject: [PATCH 266/288] Try with twva and twmvf, the two that passed individually --- src/tracer/MOM_tracer_numerical_mixing.F90 | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 411790e8f0..6e357400e1 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -37,9 +37,9 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. - ! call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) - call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) - ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) + call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) + ! call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) + call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) end subroutine numerical_mixing @@ -98,10 +98,8 @@ subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind call zonal_upwind_values(G, GV, Tr, uhtr, x_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - ! east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) - ! west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) - east = - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k)*x_upwind(I,j,k))) - west = - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) + east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) + west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) enddo ; enddo; enddo From 2853adfe42fadd0e4e4bb66a07e2eb4da7880a82 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 16 Mar 2026 08:59:12 +1100 Subject: [PATCH 267/288] Back to only thickness weighted zonal variance advection, CI passes without this part --- src/tracer/MOM_tracer_numerical_mixing.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 6e357400e1..8f2eeab165 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -37,9 +37,9 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. - call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) - ! call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) - call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) + ! call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) + call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) + ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) end subroutine numerical_mixing From b1a0224886e2e04f0381f274a231d8afaffdb07e Mon Sep 17 00:00:00 2001 From: Angus Gibson Date: Mon, 16 Mar 2026 12:42:06 +1100 Subject: [PATCH 268/288] test using pass_var for t_prev --- src/tracer/MOM_tracer_registry.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index c11aed91db..4fbb61ff22 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -14,6 +14,7 @@ module MOM_tracer_registry use MOM_diag_mediator, only : diag_ctrl, register_diag_field, post_data, safe_alloc_ptr use MOM_diag_mediator, only : diag_grid_storage use MOM_diag_mediator, only : diag_copy_storage_to_diag, diag_save_grids, diag_restore_grids +use MOM_domains, only : pass_var use MOM_error_handler, only : MOM_error, FATAL, WARNING, MOM_mesg, is_root_pe use MOM_file_parser, only : get_param, log_version, param_file_type use MOM_hor_index, only : hor_index_type @@ -741,6 +742,7 @@ subroutine post_tracer_diagnostics_at_sync(Reg, h, diag_prev, diag, G, GV, dt) call post_data(Tr%id_tendency, work3d, diag, alt_h=diag_prev%h_state) endif if (Tr%id_numerical_mixing > 0) then + call pass_var(Tr%t, G%Domain, halo=2) do k=1,nz ; do j=js-2,je+2 ; do i=is-2,ie+2 tr%t_prev(i,j,k) = Tr%t(i,j,k) enddo ; enddo ; enddo From d04ea2d1c688a5c3e62381a585d57877601ebfa1 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 16 Mar 2026 13:42:40 +1100 Subject: [PATCH 269/288] Call all subroutines in numerical_mixing for CI --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 8f2eeab165..c91515c99a 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -37,9 +37,9 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. - ! call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) + call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) - ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) + call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) end subroutine numerical_mixing From c2f8e0ca12e2c67d1afdef5e2238fdb7d7daa10b Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 16 Mar 2026 14:07:07 +1100 Subject: [PATCH 270/288] Correct docstrings for local variables --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index c91515c99a..03f66411b5 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -91,7 +91,7 @@ subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters - real :: east, west !< East and West for zonal derivative [CU2 H T-1 ~> conc2 m s-1] + real :: east, west !< East and west faces of h point is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke @@ -149,7 +149,7 @@ subroutine thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_u !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters - real :: north, south !< North and South positions for meridional derivative + real :: north, south !< North and south faces of h point is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke From 28ce430150554d81ef574b42ef5ab83f2ce93aae Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 17 Mar 2026 10:33:45 +1100 Subject: [PATCH 271/288] CI on twva + twzvf --- src/tracer/MOM_tracer_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 03f66411b5..2e56b466cc 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -39,7 +39,7 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) - call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) + ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) end subroutine numerical_mixing From 8031b29be7307a223f9b2e8d2bc6a1e227ecdafd Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 17 Mar 2026 10:50:25 +1100 Subject: [PATCH 272/288] CI on twzvf + twmvf --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 2e56b466cc..66726a0387 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -37,9 +37,9 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. - call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) + ! call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) - ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) + call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) end subroutine numerical_mixing From c4736c65d9fb5692c201a73519af733913b5a391 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 17 Mar 2026 11:04:17 +1100 Subject: [PATCH 273/288] CI on all three subroutines --- src/tracer/MOM_tracer_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 66726a0387..03f66411b5 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -37,7 +37,7 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. - ! call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) + call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) From f0b37f92baf8578a7b2a56070550509bb9c4448e Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 17 Mar 2026 13:39:17 +1100 Subject: [PATCH 274/288] Try moving zonal and meridional components of nm into single subroutine --- src/tracer/MOM_tracer_numerical_mixing.F90 | 41 ++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 03f66411b5..62dbe59eee 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -38,8 +38,9 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) y_upwind(:,:,:) = 0. call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) - call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) - call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) + ! call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) + ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) + call thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, x_upwind, y_upwind, nm) end subroutine numerical_mixing @@ -74,6 +75,42 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, end subroutine thickness_weighted_variance_advection +subroutine thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, x_upwind, y_upwind, nm) + + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: x_upwind !< Zonal upwind tracer [CU ~> conc] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: y_upwind !< Meridional upwind tracer values + !! [CU ~> conc] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: nm !< Array to store result in + !![CU2 H T-1 ~> conc2 m s-1] + + !< Local variables + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: east, west, north, south !< North and south faces of h point + + is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke + + call zonal_upwind_values(G, GV, Tr, uhtr, x_upwind) + call meridional_upwind_values(G, GV, Tr, vhtr, y_upwind) + + do k=1,nz ; do j=js,je ; do i=is,ie + east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) + west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) + north = (2 * (Tr%ad_y(i,J,k) *y_upwind(i,J,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) + south = (2 * (Tr%ad_y(i,J-1,k)*y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J-1,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) + res(i,j,k) = res(i,j,k) + (((east - west) + (north - south)) * G%IareaT(i,j)) + enddo ; enddo; enddo + +end subroutine thickness_weighted_variance_flux_divergance + !< Subroutine to calculate the thickness weigthed zonal variance flux. The spatial derivatives are calucated !! from upwind values. subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, res) From 56adb61d7e4f2c98d364de034dc51feb9f562821 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 17 Mar 2026 13:42:40 +1100 Subject: [PATCH 275/288] Incorrect arg name in subroutine --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 62dbe59eee..72981c0491 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -75,7 +75,7 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, end subroutine thickness_weighted_variance_advection -subroutine thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, x_upwind, y_upwind, nm) +subroutine thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, x_upwind, y_upwind, res) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure @@ -88,7 +88,7 @@ subroutine thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Id real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: x_upwind !< Zonal upwind tracer [CU ~> conc] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: y_upwind !< Meridional upwind tracer values !! [CU ~> conc] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: nm !< Array to store result in + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in !![CU2 H T-1 ~> conc2 m s-1] !< Local variables From 77e29a1221c10a1229709d7e62e05f5b2522883a Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 17 Mar 2026 13:54:02 +1100 Subject: [PATCH 276/288] upwind as local variables? --- src/tracer/MOM_tracer_numerical_mixing.F90 | 33 +++++++++++++--------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 72981c0491..35e14ba192 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -30,17 +30,18 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: nm !< Numerical mixing diagnostic !! [CU2 H T-1 ~> conc2 m s-1] - ! Upwind variables - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] - - x_upwind(:,:,:) = 0. - y_upwind(:,:,:) = 0. + ! ! Upwind variables + ! real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] + ! real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] + ! + ! x_upwind(:,:,:) = 0. + ! y_upwind(:,:,:) = 0. call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) ! call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) - call thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, x_upwind, y_upwind, nm) + ! call thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, x_upwind, y_upwind, nm) + call thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, nm) end subroutine numerical_mixing @@ -75,7 +76,8 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, end subroutine thickness_weighted_variance_advection -subroutine thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, x_upwind, y_upwind, res) +! subroutine thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, x_upwind, y_upwind, res) +subroutine thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, res) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure @@ -85,9 +87,9 @@ subroutine thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Id real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: x_upwind !< Zonal upwind tracer [CU ~> conc] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: y_upwind !< Meridional upwind tracer values - !! [CU ~> conc] + ! real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: x_upwind !< Zonal upwind tracer [CU ~> conc] + ! real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: y_upwind !< Meridional upwind tracer values + ! !! [CU ~> conc] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in !![CU2 H T-1 ~> conc2 m s-1] @@ -95,6 +97,11 @@ subroutine thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Id integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters real :: east, west, north, south !< North and south faces of h point + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] + + x_upwind(:,:,:) = 0. + y_upwind(:,:,:) = 0. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke @@ -102,8 +109,8 @@ subroutine thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Id call meridional_upwind_values(G, GV, Tr, vhtr, y_upwind) do k=1,nz ; do j=js,je ; do i=is,ie - east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) - west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) + east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) + west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) north = (2 * (Tr%ad_y(i,J,k) *y_upwind(i,J,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) south = (2 * (Tr%ad_y(i,J-1,k)*y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J-1,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) res(i,j,k) = res(i,j,k) + (((east - west) + (north - south)) * G%IareaT(i,j)) From cabcc6fcb8c78f0a7d2a325ab42b6537ca9110f4 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 17 Mar 2026 14:06:43 +1100 Subject: [PATCH 277/288] Fix spelling --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 35e14ba192..7d6627ffed 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -40,8 +40,8 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) ! call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) - ! call thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, x_upwind, y_upwind, nm) - call thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, nm) + ! call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, x_upwind, y_upwind, nm) + call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, nm) end subroutine numerical_mixing @@ -77,7 +77,7 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, end subroutine thickness_weighted_variance_advection ! subroutine thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, x_upwind, y_upwind, res) -subroutine thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, res) +subroutine thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, res) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure @@ -116,7 +116,7 @@ subroutine thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Id res(i,j,k) = res(i,j,k) + (((east - west) + (north - south)) * G%IareaT(i,j)) enddo ; enddo; enddo -end subroutine thickness_weighted_variance_flux_divergance +end subroutine thickness_weighted_variance_flux_divergence !< Subroutine to calculate the thickness weigthed zonal variance flux. The spatial derivatives are calucated !! from upwind values. From 74bec59b863f8000647dbd8ac4dbfc8331f3cd3a Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 17 Mar 2026 20:02:20 +1100 Subject: [PATCH 278/288] Make upwind variables local to subroutines + CI on three subroutine version --- src/tracer/MOM_tracer_numerical_mixing.F90 | 90 ++++++++++------------ 1 file changed, 41 insertions(+), 49 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 7d6627ffed..7a82cd4b8d 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -30,18 +30,10 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: nm !< Numerical mixing diagnostic !! [CU2 H T-1 ~> conc2 m s-1] - ! ! Upwind variables - ! real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] - ! real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] - ! - ! x_upwind(:,:,:) = 0. - ! y_upwind(:,:,:) = 0. - call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) - ! call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, nm) - ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, nm) - ! call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, x_upwind, y_upwind, nm) - call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, nm) + call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, nm) + call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, nm) + ! call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, nm) end subroutine numerical_mixing @@ -76,29 +68,26 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, end subroutine thickness_weighted_variance_advection -! subroutine thickness_weighted_variance_flux_divergance(G, Gv, Tr, uhtr, vhtr, Idt, x_upwind, y_upwind, res) +!< Subroutine to calculate the divergence of the variance due to the advection scheme subroutine thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, res) - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - ! real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: x_upwind !< Zonal upwind tracer [CU ~> conc] - ! real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: y_upwind !< Meridional upwind tracer values - ! !! [CU ~> conc] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in - !![CU2 H T-1 ~> conc2 m s-1] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in + !![CU2 H T-1 ~> conc2 m s-1] !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: east, west, north, south !< North and south faces of h point - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind ! zonal upwind values for tracer [CU ~> conc] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind ! meridional upwind values for tracer [CU ~> conc] + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: east, west, north, south !< North and south faces of h point + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind !< Zonal upwind values for tracer [CU ~> conc] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind !< Meridional upwind values for tracer [CU ~> conc] x_upwind(:,:,:) = 0. y_upwind(:,:,:) = 0. @@ -120,7 +109,7 @@ end subroutine thickness_weighted_variance_flux_divergence !< Subroutine to calculate the thickness weigthed zonal variance flux. The spatial derivatives are calucated !! from upwind values. -subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind, res) +subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, res) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure @@ -128,14 +117,16 @@ subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, x_upwind real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: x_upwind !< Zonal upwind tracer [CU ~> conc] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in !![CU2 H T-1 ~> conc2 m s-1] !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: east, west !< East and west faces of h point + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: east, west !< East and west faces of h point + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind !< Zonal upwind values for tracer [CU ~> conc] + + x_upwind(:,:,:) = 0. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke @@ -177,23 +168,24 @@ end subroutine zonal_upwind_values !< Subroutine to calculate the thickness weighted meriodional variance flux. The spatial derivative is calculated !! from upwind values. -subroutine thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, y_upwind, res) +subroutine thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, res) - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: Idt !< Inverse timestep [T-1 ~> S-1] - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: y_upwind !< Meridional upwind tracer values - !! [CU ~> conc] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in - !![CU2 H T-1 ~> conc2 m s-1] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes + !! used to advect tracers [H L2 ~> m3 or kg] + real, intent(in) :: Idt !< Inverse timestep [T-1 ~> S-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in + !![CU2 H T-1 ~> conc2 m s-1] !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: north, south !< North and south faces of h point + integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes + integer :: i, j, k !< Counters + real :: north, south !< North and south faces of h point + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind !< Meridional upwind values for tracer [CU ~> conc] + + y_upwind(:,:,:) = 0. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke From 74a582fc263894e1b5b9f7eb29bae4aef794056e Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 17 Mar 2026 20:12:48 +1100 Subject: [PATCH 279/288] Remove whitespace + back to two subroutine version --- src/tracer/MOM_tracer_numerical_mixing.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 7a82cd4b8d..0b8d6c6513 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -31,9 +31,9 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) !! [CU2 H T-1 ~> conc2 m s-1] call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) - call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, nm) - call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, nm) - ! call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, nm) + ! call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, nm) + ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, nm) + call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, nm) end subroutine numerical_mixing @@ -176,7 +176,7 @@ subroutine thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, res real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, intent(in) :: Idt !< Inverse timestep [T-1 ~> S-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in !![CU2 H T-1 ~> conc2 m s-1] !< Local variables From 7f2dd57e00d269754d59af06b5620563f957fa15 Mon Sep 17 00:00:00 2001 From: jbisits Date: Tue, 17 Mar 2026 20:18:04 +1100 Subject: [PATCH 280/288] More white space to be removed --- src/tracer/MOM_tracer_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 0b8d6c6513..68f9fba8ad 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -184,7 +184,7 @@ subroutine thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, res integer :: i, j, k !< Counters real :: north, south !< North and south faces of h point real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind !< Meridional upwind values for tracer [CU ~> conc] - + y_upwind(:,:,:) = 0. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke From 2d19f136ab2e8a3dcc11a9b263cc450911abdb53 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 19 Mar 2026 15:18:07 +1100 Subject: [PATCH 281/288] Rename diagnostic to advection_scheme_variance_production --- src/tracer/MOM_tracer_numerical_mixing.F90 | 20 ++++++++++---------- src/tracer/MOM_tracer_types.F90 | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 68f9fba8ad..1ce2fec13e 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -9,12 +9,12 @@ module MOM_tracer_numerical_mixing #include -public numerical_mixing +public advection_scheme_variance_production contains -!< Calculate the spurious ``numerical'' mixing of tracer due to advection schemes. -subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) +!< Calculate the spurious variance production of tracer `Tr` due to the advection schemes. +subroutine advection_scheme_variance_production(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, asvp) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure @@ -27,15 +27,15 @@ subroutine numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) !! used to advect tracers [H L2 ~> m3 or kg] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: nm !< Numerical mixing diagnostic - !! [CU2 H T-1 ~> conc2 m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: asvp !< Advection scheme varianve production + !! diagnostic [CU2 H T-1 ~> conc2 m s-1] - call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, nm) - ! call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, nm) - ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, nm) - call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, nm) + call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, asvp) + ! call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, asvp) + ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, asvp) + call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, asvp) -end subroutine numerical_mixing +end subroutine advection_scheme_variance_production !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, res) diff --git a/src/tracer/MOM_tracer_types.F90 b/src/tracer/MOM_tracer_types.F90 index 0d608f6f18..2c43d4829a 100644 --- a/src/tracer/MOM_tracer_types.F90 +++ b/src/tracer/MOM_tracer_types.F90 @@ -120,7 +120,7 @@ module MOM_tracer_types integer :: id_tr_vardec = -1 integer :: id_zint = -1, id_zint_100m = -1, id_surf = -1 integer :: id_net_surfflux = -1, id_NLT_tendency = -1, id_NLT_budget = -1 - integer :: id_numerical_mixing = -1 + integer :: id_advection_scheme_variance_production = -1 !>@} end type tracer_type From 5b5c4ab7224a3449ce9e2260419830d6921623f4 Mon Sep 17 00:00:00 2001 From: jbisits Date: Thu, 19 Mar 2026 15:18:45 +1100 Subject: [PATCH 282/288] Forgot tracer registry --- src/tracer/MOM_tracer_registry.F90 | 35 +++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 4fbb61ff22..c647c4afda 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -26,7 +26,7 @@ module MOM_tracer_registry use MOM_unit_scaling, only : unit_scale_type use MOM_verticalGrid, only : verticalGrid_type use MOM_tracer_types, only : tracer_type, tracer_registry_type -use MOM_tracer_numerical_mixing, only : numerical_mixing +use MOM_tracer_numerical_mixing, only : advection_scheme_variance_production implicit none ; private @@ -384,8 +384,9 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "flux from the horizontal boundary diffusion scheme", trim(flux_units), & v_extensive=.true., & x_cell_method='sum', conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T) - Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & + Tr%id_advection_scheme_variance_production = register_diag_field("ocean_model", & + trim(shortnm)//"_advection_scheme_variance_production", diag%axesTL, Time, & + "Spurious variance production of "//trim(shortnm)//" variance due to advection", & trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) else Tr%id_adx = register_diag_field("ocean_model", trim(shortnm)//"_adx", & @@ -412,8 +413,9 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u "Horizontal Boundary Diffusive Meridional Flux of "//trim(flux_longname), & flux_units, v_extensive=.true., conversion=(US%L_to_m**2)*Tr%flux_scale*US%s_to_T, & x_cell_method='sum') - Tr%id_numerical_mixing = register_diag_field("ocean_model", trim(shortnm)//"_numerical_mixing", & - diag%axesTL, Time, "Spurious mixing of "//trim(shortnm)//" due to advection", & + Tr%id_advection_scheme_variance_production = register_diag_field("ocean_model", & + trim(shortnm)//"_advection_scheme_variance_production", diag%axesTL, Time, & + "Spurious variance production of "//trim(shortnm)//" variance due to advection", & trim(Tr%units)//"2 m s-1", conversion=(TR%conc_scale**2)*GV%H_to_MKS*US%s_to_T) endif Tr%id_zint = register_diag_field("ocean_model", trim(shortnm)//"_zint", & @@ -426,8 +428,10 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u trim(units) // " m") Tr%id_surf = register_diag_field("ocean_model", trim(shortnm)//"_SURF", & diag%axesT1, Time, "Surface values of "// trim(longname), trim(units)) - if ((Tr%id_adx > 0) .or. (Tr%id_numerical_mixing > 0)) call safe_alloc_ptr(Tr%ad_x,IsdB,IedB,jsd,jed,nz) - if ((Tr%id_ady > 0) .or. (Tr%id_numerical_mixing > 0)) call safe_alloc_ptr(Tr%ad_y,isd,ied,JsdB,JedB,nz) + if ((Tr%id_adx > 0) .or. (Tr%id_advection_scheme_variance_production > 0)) & + call safe_alloc_ptr(Tr%ad_x,IsdB,IedB,jsd,jed,nz) + if ((Tr%id_ady > 0) .or. (Tr%id_advection_scheme_variance_production > 0)) & + call safe_alloc_ptr(Tr%ad_y,isd,ied,JsdB,JedB,nz) if (Tr%id_dfx > 0) call safe_alloc_ptr(Tr%df_x,IsdB,IedB,jsd,jed,nz) if (Tr%id_dfy > 0) call safe_alloc_ptr(Tr%df_y,isd,ied,JsdB,JedB,nz) if (Tr%id_hbd_dfx > 0) call safe_alloc_ptr(Tr%hbd_dfx,IsdB,IedB,jsd,jed,nz) @@ -476,7 +480,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u diag%axesT1, Time, & 'Vertical sum of horizontal convergence of residual mean advective fluxes of '//& trim(lowercase(flux_longname)), conv_units, conversion=Tr%conv_scale*US%s_to_T) - if ((Tr%id_adv_xy > 0) .or. (Tr%id_adv_xy_2d > 0) .or. (Tr%id_numerical_mixing > 0)) & + if ((Tr%id_adv_xy > 0) .or. (Tr%id_adv_xy_2d > 0) .or. (Tr%id_advection_scheme_variance_production > 0)) & call safe_alloc_ptr(Tr%advection_xy,isd,ied,jsd,jed,nz) Tr%id_tendency = register_diag_field('ocean_model', trim(shortnm)//'_tendency', & @@ -484,7 +488,7 @@ subroutine register_tracer_diagnostics(Reg, h, Time, diag, G, GV, US, use_ALE, u 'Net time tendency for '//trim(lowercase(longname)), & trim(units)//' s-1', conversion=Tr%conc_scale*US%s_to_T) - if ((Tr%id_tendency > 0) .or. (Tr%id_numerical_mixing > 0)) then + if ((Tr%id_tendency > 0) .or. (Tr%id_advection_scheme_variance_production > 0)) then call safe_alloc_ptr(Tr%t_prev,isd,ied,jsd,jed,nz) do k=1,nz ; do j=js-2,je+2 ; do i=is-2,ie+2 Tr%t_prev(i,j,k) = Tr%t(i,j,k) @@ -741,7 +745,7 @@ subroutine post_tracer_diagnostics_at_sync(Reg, h, diag_prev, diag, G, GV, dt) enddo ; enddo ; enddo call post_data(Tr%id_tendency, work3d, diag, alt_h=diag_prev%h_state) endif - if (Tr%id_numerical_mixing > 0) then + if (Tr%id_advection_scheme_variance_production > 0) then call pass_var(Tr%t, G%Domain, halo=2) do k=1,nz ; do j=js-2,je+2 ; do i=is-2,ie+2 tr%t_prev(i,j,k) = Tr%t(i,j,k) @@ -792,7 +796,8 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag, uhtr, vht real :: frac_under_100m(SZI_(G),SZJ_(G),SZK_(GV)) ! weights used to compute 100m vertical integrals [nondim] real :: ztop(SZI_(G),SZJ_(G)) ! position of the top interface [H ~> m or kg m-2] real :: zbot(SZI_(G),SZJ_(G)) ! position of the bottom interface [H ~> m or kg m-2] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: nm ! Numerical mixing of a tracer [CU2 H T-1 ~> conc2 m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: asvp ! Advection scheme varianve production of a + ! tracer [CU2 H T-1 ~> conc2 m s-1] real :: H_to_RZ_dt ! A conversion factor from accumulated transports to fluxes ! [R Z H-1 T-1 ~> kg m-3 s-1 or s-1]. type(tracer_type), pointer :: Tr=>NULL() @@ -849,10 +854,10 @@ subroutine post_tracer_transport_diagnostics(G, GV, Reg, h_diag, diag, uhtr, vht call post_data(Tr%id_adv_xy_2d, work2d, diag) endif - if (Tr%id_numerical_mixing > 0) then - nm(:,:,:) = 0. - call numerical_mixing(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, nm) - call post_data(Tr%id_numerical_mixing, nm, diag, alt_h=h_diag) + if (Tr%id_advection_scheme_variance_production > 0) then + asvp(:,:,:) = 0. + call advection_scheme_variance_production(G, GV, Tr, h_diag, h, dt_trans, Idt, uhtr, vhtr, asvp) + call post_data(Tr%id_advection_scheme_variance_production, asvp, diag, alt_h=h_diag) endif ! A few diagnostics introduce with MARBL driver From 5b7e628a6daf6422abeb27b134fc1a668779b785 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 1 Jun 2026 10:22:42 +1000 Subject: [PATCH 283/288] Use single subroutine for variance flux + tidy up docstring spacing --- src/tracer/MOM_tracer_numerical_mixing.F90 | 90 +++------------------- 1 file changed, 11 insertions(+), 79 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 1ce2fec13e..64c407ef6b 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -31,8 +31,6 @@ subroutine advection_scheme_variance_production(G, GV, Tr, h_diag, h, dt_trans, !! diagnostic [CU2 H T-1 ~> conc2 m s-1] call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, asvp) - ! call thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, asvp) - ! call thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, asvp) call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, asvp) end subroutine advection_scheme_variance_production @@ -40,15 +38,15 @@ end subroutine advection_scheme_variance_production !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, res) - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_diag !< Previous thicknesses [H ~> m or kg m-2] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] - real, intent(in) :: dt !< Transport time interval [T ~> s] - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in - !! [CU2 H T-1 ~> conc2 m s-1] + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_diag !< Previous thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] + real, intent(in) :: dt !< Transport time interval [T ~> s] + real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in + !! [CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes @@ -68,7 +66,7 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, end subroutine thickness_weighted_variance_advection -!< Subroutine to calculate the divergence of the variance due to the advection scheme +!< Subroutine to calculate the divergence of the variance flux due to the advection scheme subroutine thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, res) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure @@ -107,39 +105,6 @@ subroutine thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Id end subroutine thickness_weighted_variance_flux_divergence -!< Subroutine to calculate the thickness weigthed zonal variance flux. The spatial derivatives are calucated -!! from upwind values. -subroutine thickness_weighted_zonal_variance_flux(G, GV, Tr, uhtr, Idt, res) - - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to the tracer registry - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in - !![CU2 H T-1 ~> conc2 m s-1] - - !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: east, west !< East and west faces of h point - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind !< Zonal upwind values for tracer [CU ~> conc] - - x_upwind(:,:,:) = 0. - - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - - call zonal_upwind_values(G, GV, Tr, uhtr, x_upwind) - - do k=1,nz ; do j=js,je ; do i=is,ie - east = (2 * (Tr%ad_x(I,j,k) *x_upwind(I,j,k))) - ((Idt*uhtr(I,j,k)) * (x_upwind(I,j,k) *x_upwind(I,j,k))) - west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) - res(i,j,k) = res(i,j,k) + ((east - west) * G%IareaT(i,j)) - enddo ; enddo; enddo - -end subroutine thickness_weighted_zonal_variance_flux - !< Subroutine to calculate upwind values in zonal direction subroutine zonal_upwind_values(G, GV, Tr, uhtr, x_upwind) @@ -166,40 +131,7 @@ subroutine zonal_upwind_values(G, GV, Tr, uhtr, x_upwind) end subroutine zonal_upwind_values -!< Subroutine to calculate the thickness weighted meriodional variance flux. The spatial derivative is calculated -!! from upwind values. -subroutine thickness_weighted_meridional_variance_flux(G, GV, Tr, vhtr, Idt, res) - - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - type(tracer_type), intent(in) :: Tr !< Pointer to tracer registry - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes - !! used to advect tracers [H L2 ~> m3 or kg] - real, intent(in) :: Idt !< Inverse timestep [T-1 ~> S-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in - !![CU2 H T-1 ~> conc2 m s-1] - - !< Local variables - integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes - integer :: i, j, k !< Counters - real :: north, south !< North and south faces of h point - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind !< Meridional upwind values for tracer [CU ~> conc] - - y_upwind(:,:,:) = 0. - - is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke - - call meridional_upwind_values(G, GV, Tr, vhtr, y_upwind) - - do k=1,nz ; do j=js,je ; do i=is,ie - north = (2 * (Tr%ad_y(i,J,k) *y_upwind(i,J,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) - south = (2 * (Tr%ad_y(i,J-1,k)*y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J-1,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) - res(i,j,k) = res(i,j,k) + ((north - south) * G%IareaT(i,j)) - enddo ; enddo ; enddo - -end subroutine thickness_weighted_meridional_variance_flux - -!< Subroutine to calculate upwind value in the meridional direction +!< Subroutine to calculate upwind values in the meridional direction subroutine meridional_upwind_values(G, GV, Tr, vhtr, y_upwind) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure From 58538227f3114d72f8a41d8fe3cb59a9d55257e1 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 1 Jun 2026 10:36:01 +1000 Subject: [PATCH 284/288] res -> asvp, remove last **2 opertation, change order of subroutines --- src/tracer/MOM_tracer_numerical_mixing.F90 | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 64c407ef6b..28305e73b8 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -30,13 +30,14 @@ subroutine advection_scheme_variance_production(G, GV, Tr, h_diag, h, dt_trans, real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: asvp !< Advection scheme varianve production !! diagnostic [CU2 H T-1 ~> conc2 m s-1] - call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, asvp) call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, asvp) + call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, asvp) + ! call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, asvp) end subroutine advection_scheme_variance_production !< Subroutine to calculate the thickness weighted variance advection over the transport timestep. -subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, res) +subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, asvp) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure @@ -45,7 +46,7 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] real, intent(in) :: dt !< Transport time interval [T ~> s] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: asvp !< Array to store asvp in !! [CU2 H T-1 ~> conc2 m s-1] !< Local variables @@ -61,13 +62,13 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, Ih = 1 / h(i,j,k) ht_prev = h_diag(i,j,k) * Tr%t_prev(i,j,k) ht_adv = ht_prev + dt * Tr%advection_xy(i,j,k) - res(i,j,k) = ( (Ih * ht_adv**2) - (ht_prev * Tr%t_prev(i,j,k)) ) * Idt + asvp(i,j,k) = ( (Ih * ht_adv*ht_adv) - (ht_prev * Tr%t_prev(i,j,k)) ) * Idt enddo ; enddo ; enddo end subroutine thickness_weighted_variance_advection !< Subroutine to calculate the divergence of the variance flux due to the advection scheme -subroutine thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, res) +subroutine thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, asvp) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure @@ -77,13 +78,13 @@ subroutine thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Id real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes !! used to advect tracers [H L2 ~> m3 or kg] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: res !< Array to store result in - !![CU2 H T-1 ~> conc2 m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: asvp !< Array to store asvp in + !! [CU2 H T-1 ~> conc2 m s-1] !< Local variables integer :: is, ie, js, je, nz !< Grid cell centre and layer indexes integer :: i, j, k !< Counters - real :: east, west, north, south !< North and south faces of h point + real :: east, west, north, south !< east, west, north and south faces of h point real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)) :: x_upwind !< Zonal upwind values for tracer [CU ~> conc] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)) :: y_upwind !< Meridional upwind values for tracer [CU ~> conc] @@ -100,7 +101,7 @@ subroutine thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Id west = (2 * (Tr%ad_x(I-1,j,k)*x_upwind(I-1,j,k))) - ((Idt*uhtr(I-1,j,k)) * (x_upwind(I-1,j,k)*x_upwind(I-1,j,k))) north = (2 * (Tr%ad_y(i,J,k) *y_upwind(i,J,k))) - ((Idt*vhtr(i,J,k)) * (y_upwind(i,J,k) *y_upwind(i,J,k))) south = (2 * (Tr%ad_y(i,J-1,k)*y_upwind(i,J-1,k))) - ((Idt*vhtr(i,J-1,k)) * (y_upwind(i,J-1,k)*y_upwind(i,J-1,k))) - res(i,j,k) = res(i,j,k) + (((east - west) + (north - south)) * G%IareaT(i,j)) + asvp(i,j,k) = asvp(i,j,k) + (((east - west) + (north - south)) * G%IareaT(i,j)) enddo ; enddo; enddo end subroutine thickness_weighted_variance_flux_divergence From c352fc11ef13ac54d7e81b9bc7c91f3c51e1bb70 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 1 Jun 2026 11:25:29 +1000 Subject: [PATCH 285/288] Forgot to add value to existing array --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 28305e73b8..622726a941 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -46,7 +46,7 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Updated thicknesses [H ~> m or kg m-2] real, intent(in) :: dt !< Transport time interval [T ~> s] real, intent(in) :: Idt !< Inverse time interval [T-1 ~> s-1] - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: asvp !< Array to store asvp in + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: asvp !< Array to store asvp in !! [CU2 H T-1 ~> conc2 m s-1] !< Local variables @@ -62,7 +62,7 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, Ih = 1 / h(i,j,k) ht_prev = h_diag(i,j,k) * Tr%t_prev(i,j,k) ht_adv = ht_prev + dt * Tr%advection_xy(i,j,k) - asvp(i,j,k) = ( (Ih * ht_adv*ht_adv) - (ht_prev * Tr%t_prev(i,j,k)) ) * Idt + asvp(i,j,k) = asvp(i,j,k) + ( (Ih * (ht_adv*ht_adv)) - (ht_prev * Tr%t_prev(i,j,k)) ) * Idt enddo ; enddo ; enddo end subroutine thickness_weighted_variance_advection From 816b83096b63a311d95e17dd2cf3e2d0bd210fc8 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 1 Jun 2026 11:35:19 +1000 Subject: [PATCH 286/288] Return to original order + CI only on variance flux --- src/tracer/MOM_tracer_numerical_mixing.F90 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 622726a941..1a57a20604 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -30,9 +30,8 @@ subroutine advection_scheme_variance_production(G, GV, Tr, h_diag, h, dt_trans, real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: asvp !< Advection scheme varianve production !! diagnostic [CU2 H T-1 ~> conc2 m s-1] + ! call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, asvp) call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, asvp) - call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, asvp) - ! call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, asvp) end subroutine advection_scheme_variance_production @@ -62,7 +61,7 @@ subroutine thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt, Idt, Ih = 1 / h(i,j,k) ht_prev = h_diag(i,j,k) * Tr%t_prev(i,j,k) ht_adv = ht_prev + dt * Tr%advection_xy(i,j,k) - asvp(i,j,k) = asvp(i,j,k) + ( (Ih * (ht_adv*ht_adv)) - (ht_prev * Tr%t_prev(i,j,k)) ) * Idt + asvp(i,j,k) = ( (Ih * (ht_adv*ht_adv)) - (ht_prev * Tr%t_prev(i,j,k)) ) * Idt enddo ; enddo ; enddo end subroutine thickness_weighted_variance_advection From eabf510657e6c3984530f99e8cc97dd571650e74 Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 1 Jun 2026 11:45:56 +1000 Subject: [PATCH 287/288] CI only on variance advection --- src/tracer/MOM_tracer_numerical_mixing.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 1a57a20604..7be7ab09d7 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -30,8 +30,8 @@ subroutine advection_scheme_variance_production(G, GV, Tr, h_diag, h, dt_trans, real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: asvp !< Advection scheme varianve production !! diagnostic [CU2 H T-1 ~> conc2 m s-1] - ! call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, asvp) - call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, asvp) + call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, asvp) + ! call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, asvp) end subroutine advection_scheme_variance_production From 9b1dd0431d1eeb77af730251fbf847a80d89817c Mon Sep 17 00:00:00 2001 From: jbisits Date: Mon, 1 Jun 2026 11:56:33 +1000 Subject: [PATCH 288/288] Include both terms --- src/tracer/MOM_tracer_numerical_mixing.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracer/MOM_tracer_numerical_mixing.F90 b/src/tracer/MOM_tracer_numerical_mixing.F90 index 7be7ab09d7..90cbffba95 100644 --- a/src/tracer/MOM_tracer_numerical_mixing.F90 +++ b/src/tracer/MOM_tracer_numerical_mixing.F90 @@ -31,7 +31,7 @@ subroutine advection_scheme_variance_production(G, GV, Tr, h_diag, h, dt_trans, !! diagnostic [CU2 H T-1 ~> conc2 m s-1] call thickness_weighted_variance_advection(G, GV, Tr, h_diag, h, dt_trans, Idt, asvp) - ! call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, asvp) + call thickness_weighted_variance_flux_divergence(G, Gv, Tr, uhtr, vhtr, Idt, asvp) end subroutine advection_scheme_variance_production