Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
288 commits
Select commit Hold shift + click to select a range
010e266
Code cleanup
jbisits Oct 21, 2025
5bf3c2d
Semicolons not commas, correct order for subroutine call
jbisits Oct 21, 2025
361d933
Use uhtr*Idt insteatd of umo/rho0 (same for v)
jbisits Oct 21, 2025
7d80f8b
Missed reference density
jbisits Oct 21, 2025
19c8b33
Hard code reference density (might have caused the netcdf error)
jbisits Oct 21, 2025
6c3b60b
Try thickness weighted variance only (netcdf error occured again mayb…
jbisits Oct 21, 2025
30aefa6
Use reference density from GV
jbisits Oct 21, 2025
0be62ab
Remove old unit designator
jbisits Oct 21, 2025
e2dcc9d
Remove unnecessary definition of reference density
jbisits Oct 21, 2025
bb846a0
Only zonal fluxes + try scaling the upwind calculation
jbisits Oct 21, 2025
b411d30
Use locally defined and - would be ideal if I could find where they…
jbisits Oct 21, 2025
be86542
Set upwind variables to zero
jbisits Oct 21, 2025
667dee8
Homogenise upwind value definition
jbisits Oct 21, 2025
d2930d3
More specific bracketing in thickness weighted variance change
jbisits Oct 21, 2025
53ef6c8
Only return upwind difference
jbisits Oct 21, 2025
9722ba2
Check non-upwind part of zonal fluxes calculation
jbisits Oct 22, 2025
2eeb3c9
Just look at left upwind i.e. the left tracer values
jbisits Oct 22, 2025
d2aa63f
west upwind values
jbisits Oct 22, 2025
c1ae7b0
Back to east upwind values
jbisits Oct 22, 2025
0e73593
Return the upwind array
jbisits Oct 22, 2025
89cc31b
Make nm same size as upwind for saving
jbisits Oct 22, 2025
42d1e8a
Return nm array to correct size
jbisits Oct 22, 2025
0345cce
Loop over vertices
jbisits Oct 22, 2025
c8a90e0
Zonal fluxes with vertex indexing
jbisits Oct 22, 2025
b0e27a8
Change index to start 1 prior
jbisits Oct 22, 2025
8e71d9f
Temporary resize to save upwind tracer array
jbisits Oct 22, 2025
8ce286d
Temporary changes to return Zonal upwind array
jbisits Oct 22, 2025
5208f2e
Revert to correct units for nm in variable and diagnostic
jbisits Oct 22, 2025
6b9d76a
Online finite differencing - no errors when saving whole array and co…
jbisits Oct 22, 2025
dfdfc85
whole matrix diff?
jbisits Oct 22, 2025
ac622f2
Add zonal upwind diagnostic
jbisits Oct 22, 2025
bb886c0
Homogenise tracer name
jbisits Oct 22, 2025
34f96e9
Correct indexing for upwind variable
jbisits Oct 22, 2025
39970d6
Only access one part of upwind array to check if this is producing se…
jbisits Oct 23, 2025
8fc3c3a
Dont add upwind diagnostic
jbisits Oct 23, 2025
0d33443
Make index 1 longer
jbisits Oct 23, 2025
f66eaf7
Try new method
jbisits Oct 23, 2025
2bf906c
Clear up some bracketing
jbisits Oct 23, 2025
6019b19
Remove unneeded diagnostic definition
jbisits Oct 23, 2025
c4e0825
Check fluxes only
jbisits Oct 23, 2025
703cf7d
Fix brackets
jbisits Oct 23, 2025
4fb76a5
Compute things in different order
jbisits Oct 24, 2025
fe4b251
Try different indexing, matches offline but lines are back
jbisits Oct 24, 2025
fbf21aa
Upwind computation in nm subroutine
jbisits Oct 24, 2025
68a2538
Remove upwind from calculation to check it is still culprit
jbisits Oct 24, 2025
a0c73d5
Revert to previous transport calculation
jbisits Oct 24, 2025
5440b54
Incorrect variable call
jbisits Oct 24, 2025
7a7d25a
transport terms in fluxes correct, check upwind
jbisits Oct 24, 2025
934fde1
Parentheses error
jbisits Oct 24, 2025
c6f0e8d
Upwind looked ok, try whole computation
jbisits Oct 24, 2025
9f562c2
Flux terms computed correctly, check variance
jbisits Oct 24, 2025
1877c6f
Minor difference with variance, check total numerical mixing
jbisits Oct 24, 2025
55eca41
Move tendency calculation into numerical mixing, should be able to ca…
jbisits Oct 26, 2025
a96b69d
Check thickness only
jbisits Oct 26, 2025
883cf3a
Try alternate thickness advection definition
jbisits Oct 26, 2025
53cec98
Forgot to remove variable
jbisits Oct 26, 2025
bd8a95e
Try with previous h_state as h1
jbisits Oct 26, 2025
f6a22c4
use previous tracer value to match using previous thickness value
jbisits Oct 27, 2025
47f9968
Back to variance change as already defined, try to have different sca…
jbisits Oct 27, 2025
dccf73a
Forgot then in if statement
jbisits Oct 27, 2025
2a51d0a
Back to full diagnostic + cleanup
jbisits Oct 27, 2025
28efbe7
Tracer is Tr not C
jbisits Oct 27, 2025
9eb1962
Minor code cleanup
jbisits Oct 29, 2025
faef58c
Try reversing sign of finite difference
jbisits Oct 29, 2025
1d30606
Return to previous sign and fix variable description
jbisits Oct 30, 2025
12deaa8
Post numerical mixing on same grid as other diagnostics
jbisits Oct 30, 2025
224aa20
allocate variables when numerical mixing is called
jbisits Nov 7, 2025
afeec95
Fix a few style things
jbisits Nov 9, 2025
5a173ac
Add numerical mixing module to CMakeLists.txt
jbisits Nov 11, 2025
f311967
Save variance advection and flux for debugging
jbisits Nov 12, 2025
b711c42
Subroutine input variable more general name
jbisits Nov 12, 2025
c30bdbd
Check nm only
jbisits Nov 12, 2025
8db63d2
Forgot this file
jbisits Nov 12, 2025
72268c7
Only save one extra diag
jbisits Nov 12, 2025
c565e4d
Add a new subroutine for variance advection
jbisits Nov 12, 2025
dd8fdea
Missed then
jbisits Nov 12, 2025
0b00b64
Wrong variable name
jbisits Nov 12, 2025
8ad439e
Match variable names
jbisits Nov 13, 2025
ea7dce3
add variance flux subroutine
jbisits Nov 13, 2025
3898065
Accidentally removed required variable
jbisits Nov 13, 2025
81c417d
And define the variable
jbisits Nov 13, 2025
f8586e5
Make sure to import the subroutine
jbisits Nov 13, 2025
316b49c
Correctly call subroutine
jbisits Nov 13, 2025
58d623d
Wrong position for argument in call
jbisits Nov 13, 2025
452df99
Use previous thickness and tracer values
jbisits Nov 13, 2025
3b2e6cd
Correct all instances of variables
jbisits Nov 13, 2025
4c1d8fe
Timestep temperature
jbisits Nov 13, 2025
098a6c5
Try with specific heat capacity not hard coded
jbisits Nov 18, 2025
bb47f71
need to rethink how to access tvs
jbisits Nov 18, 2025
d532921
Missed reference to variable
jbisits Nov 18, 2025
f6c39b1
Correct array indexing and loop iterating style
jbisits Nov 24, 2025
7e060a2
Use inverse tracer scaling and multiply rather than divison
jbisits Nov 24, 2025
9016601
align comment
jbisits Nov 24, 2025
85be956
Move diagnostic to tracer directory
jbisits Nov 27, 2025
e58f17d
Forgot to include a variable
jbisits Nov 27, 2025
87efd4f
Remove old file
jbisits Nov 27, 2025
2773b62
Put back (accidentally) removed declarations
jbisits Nov 27, 2025
77b11b8
Add unit conversion for numerical mixign
jbisits Nov 28, 2025
9e4e855
Remove incorrect scaling of horizontal advective fluxes
jbisits Dec 1, 2025
edd45e9
Correct internal scaling (hopefully)
jbisits Dec 1, 2025
fb6d7b6
Missed a bracket
jbisits Dec 1, 2025
011db1f
Remove whitespace
jbisits Dec 1, 2025
72a61ab
Remove some white space + scale_constant=1 temporarily
jbisits Dec 1, 2025
22a3b51
Missed timestep division in variance flux termsn
jbisits Dec 1, 2025
790fbca
Forgot to pass the new argument
jbisits Dec 1, 2025
5e72a6e
Try checking upwind with accumulated fluxes
jbisits Dec 1, 2025
e086a32
Major clean up of nm module
jbisits Dec 1, 2025
556036c
Correct the subroutine calls
jbisits Dec 1, 2025
2ff2e2f
Fixes after errors in building
jbisits Dec 1, 2025
4d98a3b
Missed a comma
jbisits Dec 1, 2025
d1180c8
Add missing docstring
jbisits Dec 1, 2025
9c900e5
Remove whitespace
jbisits Dec 1, 2025
e4802d4
Use more explicit indexing
jbisits Dec 2, 2025
c3b1e3b
Homogenise spacing before comments
jbisits Dec 2, 2025
cec66df
Remove unneceassary brackets
jbisits Dec 2, 2025
e00e382
Remove code that is now in MOM_tracer_numerical_mixing module
jbisits Dec 2, 2025
c5f8ee3
Use t_prev
jbisits Dec 2, 2025
e7ead16
H_to_m -> H_to_MKS in output conversion
jbisits Dec 2, 2025
8e948cc
Correct unit printing
jbisits Dec 2, 2025
22745d4
The offline variable I use use H_to_Z so maybe that one
jbisits Dec 2, 2025
bebeb90
MKS is the one
jbisits Dec 2, 2025
433e991
t_prev -> t
jbisits Dec 3, 2025
4b6b105
Parantheses in calculation
jbisits Dec 3, 2025
1ed92f5
Convert to Z in variance fluxes
jbisits Dec 4, 2025
1deabe2
Back to thickness
jbisits Dec 4, 2025
51d4b04
Index the online calculation correctly for ANU-TUB
jbisits Dec 5, 2025
d35340f
Adjust the upwind indexing
jbisits Dec 7, 2025
d7c7d04
Revert upwind calcualtion
jbisits Dec 8, 2025
60eba86
H_to_MKS -> H_to_m
jbisits Dec 8, 2025
2ba4bbe
Try with t_prev in the updated scheme
jbisits Dec 8, 2025
99d8c6c
Back to previous indexing to check thickness test
jbisits Dec 8, 2025
1f14cf3
Back to correct nm + try to force update t_prev
jbisits Dec 8, 2025
b46efb5
More explicit operations + fill another halo point
jbisits Dec 8, 2025
c874c2f
First crack at adding group pass for halo updates
jbisits Dec 10, 2025
292da82
Forgot to import constants
jbisits Dec 10, 2025
5b2a65d
Try only update uhtr
jbisits Dec 10, 2025
fe2df7f
Try a different function call
jbisits Dec 10, 2025
c506b7f
specify inout
jbisits Dec 10, 2025
4eb0acb
Missed some in -> inout changes
jbisits Dec 10, 2025
ef079c5
Still missed one
jbisits Dec 10, 2025
c62cacf
Hopefully have caught the last one
jbisits Dec 10, 2025
03713d0
Update halos for tracer array as well
jbisits Dec 10, 2025
3b79943
Undo the halo updating and do somewhere else
jbisits Dec 10, 2025
0b5eb85
Print statement to check value
jbisits Dec 10, 2025
74222ea
Change indexing for adx aand ady + print statements
jbisits Dec 10, 2025
621bec3
Flexible start indexes
jbisits Dec 10, 2025
3fc3a15
More print statements but use 'correct' indexing
jbisits Dec 10, 2025
b6aef69
Avoid halo altogether
jbisits Dec 10, 2025
73b2c6c
Upwind vairable index for transport + 1
jbisits Dec 10, 2025
d3d29ba
Revery upwind indexing + try to fill halos for adx ady
jbisits Dec 10, 2025
1dece79
Correct call to do_group_pass
jbisits Dec 10, 2025
c389b31
Only update for non-symmetric
jbisits Dec 10, 2025
7e5b117
Update halos for thickness transports
jbisits Dec 10, 2025
c5845e7
Needed another inout declaration
jbisits Dec 10, 2025
f1929ac
Remove attempts at halo update + upwind printing
jbisits Dec 11, 2025
103b40e
Remove unneeded inouts and local variables
jbisits Dec 11, 2025
5844157
Remove print statements
jbisits Dec 14, 2025
505b564
Use same uhtr and vhtr values in upwind calculation
jbisits Dec 14, 2025
d8451f5
Print indexes where adx is saved
jbisits Dec 14, 2025
1993ab3
Remove print statements
jbisits Dec 14, 2025
337d7f4
Add pass call before transport diagnostics
jbisits Dec 15, 2025
de20615
Remove added pass_var
jbisits Dec 15, 2025
de39254
Fill more of the t_prev data to avoid finite difference errors
jbisits Dec 15, 2025
dc51899
Forgot then
jbisits Dec 15, 2025
9b2d26d
Wrong upper index
jbisits Dec 15, 2025
88cda8f
Move nm to tracer registry
jbisits Jan 5, 2026
e072497
Comment out code using old method
jbisits Jan 5, 2026
5a26a56
Comment out calls to old subroutines
jbisits Jan 5, 2026
1cc3718
Revert to using nm array
jbisits Jan 5, 2026
b7af477
Reduce the initial t_prev value allocate by 1
jbisits Jan 5, 2026
acf5a17
Try with upwind variable initialised in nm subroutine
jbisits Jan 5, 2026
e2a2ea9
Remove commented out code as it works
jbisits Jan 5, 2026
c795cf8
Temporary saving of east and west u point values
jbisits Mar 9, 2026
d1e1556
Define in variables as arrays
jbisits Mar 9, 2026
4048587
Integer counter and one more array declaration in subroutine
jbisits Mar 9, 2026
925f20b
Tracer registry not ID registry
jbisits Mar 9, 2026
214f093
Incorrect if statement
jbisits Mar 9, 2026
0632d34
Another incorrect if statement
jbisits Mar 9, 2026
0b59790
Incorrectly called new subroutine
jbisits Mar 9, 2026
f36aa18
Pass tracer type instead of pointer
jbisits Mar 9, 2026
8fe4582
Correct subroutine name
jbisits Mar 9, 2026
189c744
Register the east and west advection diags
jbisits Mar 9, 2026
b926c47
Register diag in both cases + pass correct argument to new subroutine
jbisits Mar 9, 2026
b1b5847
Fix east and west locations
jbisits Mar 9, 2026
9d0a883
Initialise to zero
jbisits Mar 9, 2026
e84c4ef
More descriptive functions
jbisits Mar 9, 2026
08641e2
Missed Boolean
jbisits Mar 9, 2026
51c23c6
Try and sort out advection terms first
jbisits Mar 9, 2026
dc5d2ae
Add back diagnostics, I think the error is somewhere else
jbisits Mar 9, 2026
8b76a2f
Remove comment
jbisits Mar 9, 2026
3fc71bb
Remove shape array assumptions, with @angus-g
jbisits Mar 12, 2026
2bf169f
Define GV
jbisits Mar 12, 2026
d667125
Define uhtr after G and GV
jbisits Mar 12, 2026
b0ca0bc
Define nz
jbisits Mar 12, 2026
a907004
Pass correct arguments to subroutine
jbisits Mar 12, 2026
d9bf2d3
Apply @angus-g fix to numerical mixing diagnostic
jbisits Mar 12, 2026
261b118
First go at fixing line length
jbisits Mar 12, 2026
54beffc
Few more long lines
jbisits Mar 12, 2026
f1a191f
Remove whitespace
jbisits Mar 12, 2026
2e7d595
Correct some vhtr indexing + remove all array shape assumptions
jbisits Mar 12, 2026
75c4aad
Remove whitespace + correct another array shape size
jbisits Mar 12, 2026
18df0a8
Grid and vertival grid is first in subroutines
jbisits Mar 12, 2026
76d12b9
Missed close bracket
jbisits Mar 12, 2026
c203a04
More explicit bracketing
jbisits Mar 12, 2026
a020ed1
One more bracketing
jbisits Mar 12, 2026
3c50a17
Remove unneeded variable duplicate
jbisits Mar 13, 2026
6f50dec
More cleanup
jbisits Mar 13, 2026
3b734c0
Remove no longer needed debuggin code
jbisits Mar 13, 2026
c4cc29a
More cleanup
jbisits Mar 13, 2026
8590647
Go back to diag_prev%h_state
jbisits Mar 13, 2026
8049f0b
Correctly pass to subroutine
jbisits Mar 13, 2026
4f15b81
Correctly pass args to transport diags
jbisits Mar 13, 2026
7ae4e5e
Add back diag_ctrl
jbisits Mar 13, 2026
e4c4896
Back to h_diag and fix from here
jbisits Mar 14, 2026
0b91bb1
Forgot to save file
jbisits Mar 14, 2026
2bbf42b
Wrong order of arguments in nm call
jbisits Mar 14, 2026
3e283af
Comment out unneeded modules
jbisits Mar 14, 2026
eadaee1
Simplify twva + specify dimensions for local variables
jbisits Mar 14, 2026
5ab92e9
More consistent local variable names
jbisits Mar 15, 2026
3e73163
Try only twva for thickness test
jbisits Mar 15, 2026
bbcad9e
Test only twzvf
jbisits Mar 15, 2026
1880fe3
Test only twmvf on CI
jbisits Mar 15, 2026
cb277c9
CI check for adx part
jbisits Mar 15, 2026
8b43d03
CI on uhtr + upwind term
jbisits Mar 15, 2026
2cd4ec2
Check xupwind variable
jbisits Mar 15, 2026
1a657e9
Fill more of t_prev?
jbisits Mar 15, 2026
a3a2d86
Try uhtr part with longer t_prev
jbisits Mar 15, 2026
bdcfd04
Try with twva and twmvf, the two that passed individually
jbisits Mar 15, 2026
2853adf
Back to only thickness weighted zonal variance advection, CI passes w…
jbisits Mar 15, 2026
b1a0224
test using pass_var for t_prev
angus-g Mar 16, 2026
d04ea2d
Call all subroutines in numerical_mixing for CI
jbisits Mar 16, 2026
c2f8e0c
Correct docstrings for local variables
jbisits Mar 16, 2026
28ce430
CI on twva + twzvf
jbisits Mar 16, 2026
8031b29
CI on twzvf + twmvf
jbisits Mar 16, 2026
c4736c6
CI on all three subroutines
jbisits Mar 17, 2026
f0b37f9
Try moving zonal and meridional components of nm into single subroutine
jbisits Mar 17, 2026
56adb61
Incorrect arg name in subroutine
jbisits Mar 17, 2026
77e29a1
upwind as local variables?
jbisits Mar 17, 2026
cabcc6f
Fix spelling
jbisits Mar 17, 2026
74bec59
Make upwind variables local to subroutines + CI on three subroutine v…
jbisits Mar 17, 2026
74a582f
Remove whitespace + back to two subroutine version
jbisits Mar 17, 2026
7f2dd57
More white space to be removed
jbisits Mar 17, 2026
2d19f13
Rename diagnostic to advection_scheme_variance_production
jbisits Mar 19, 2026
5b5c4ab
Forgot tracer registry
jbisits Mar 19, 2026
5b7e628
Use single subroutine for variance flux + tidy up docstring spacing
jbisits Jun 1, 2026
5853822
res -> asvp, remove last **2 opertation, change order of subroutines
jbisits Jun 1, 2026
c352fc1
Forgot to add value to existing array
jbisits Jun 1, 2026
816b830
Return to original order + CI only on variance flux
jbisits Jun 1, 2026
eabf510
CI only on variance advection
jbisits Jun 1, 2026
9b1dd04
Include both terms
jbisits Jun 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -274,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
Expand Down
7 changes: 3 additions & 4 deletions src/diagnostics/MOM_diagnostics.F90
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -164,7 +164,6 @@ module MOM_diagnostics
!>@}
end type transport_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, &
Expand Down Expand Up @@ -1654,7 +1653,7 @@ 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
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
Expand Down Expand Up @@ -1705,7 +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%h_state, diag)
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)

Expand Down
160 changes: 160 additions & 0 deletions src/tracer/MOM_tracer_numerical_mixing.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
!> Functions and routines involved in calculating numerical mixing of tracers due to advection schemes.
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

implicit none ; private

#include <MOM_memory.h>

public advection_scheme_variance_production

contains

!< 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
type(tracer_type), intent(in) :: Tr !< Pointer to the tracer regsitry
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]
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) :: 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)

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, asvp)

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) :: 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 :: Ih !< Inverse updated thickness [H-1 ~> m-1]
real :: ht_prev !< Thickness weighted tracer prior to dynamics [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
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
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, asvp)

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) :: 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 !< 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]

x_upwind(:,:,:) = 0.
y_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)
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)))
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

!< Subroutine to calculate upwind values in zonal direction
subroutine zonal_upwind_values(G, GV, Tr, uhtr, x_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 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]

!< 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-1,ie
if (uhtr(I,j,k) >= 0) then
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_prev(i+1,j,k)
endif
enddo ; enddo ; enddo

end subroutine zonal_upwind_values

!< 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
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
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-1,je ; do i=is,ie
if (vhtr(i,J,k) >= 0) then
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_prev(i,j+1,k)
endif
enddo ; enddo ; enddo

end subroutine meridional_upwind_values

end module MOM_tracer_numerical_mixing
51 changes: 45 additions & 6 deletions src/tracer/MOM_tracer_registry.F90
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -25,6 +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 : advection_scheme_variance_production

implicit none ; private

Expand Down Expand Up @@ -382,6 +384,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_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", &
diag%axesCuL, Time, "Advective (by residual mean) Zonal Flux of "//trim(flux_longname), &
Expand All @@ -407,6 +413,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_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", &
diag%axesT1, Time, &
Expand All @@ -418,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) 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_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)
Expand Down Expand Up @@ -468,17 +480,17 @@ 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_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', &
diag%axesTL, Time, &
'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_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,je ; do i=is,ie
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
Expand Down Expand Up @@ -733,6 +745,12 @@ 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_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)
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
Expand All @@ -754,23 +772,38 @@ 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, 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_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, 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]

integer :: i, j, k, is, ie, js, je, nz, m, khi
real :: work2d(SZI_(G),SZJ_(G)) ! The vertically integrated convergence of lateral advective
! tracer fluxes [CU H T-1 ~> conc m s-1 or conc kg m-2 s-1]
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)) :: 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()

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
Expand Down Expand Up @@ -821,6 +854,12 @@ 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_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
! Compute full-depth vertical integral
if (Tr%id_zint > 0) then
Expand Down
Loading
Loading