Skip to content

Commit

Permalink
(*)Consolidate conversion of 4 salt tendency diags
Browse files Browse the repository at this point in the history
  Collected the conversion factors for the 4 salt tendency diagnostics
diabatic_salt_tendency, diabatic_salt_tendency_2d, boundary_forcing_salt_tendency
and boundary_forcing_heat_tendency_2d out of the calculation of the diagnostics
before they are posted and into the conversion argument in their
register_diag_field calls.  This change simplifies the code where the
diagnostics are calculated, but although all expressions are mathematically
equivalent, there is a change in the order of arithmetic with which these 4
diagnostics are calculated, so answers will change at roundoff, although this is
unlikely to be detected if the diagnostics are being written as 32 bit floats.
All model solutions are bitwise identical.
  • Loading branch information
Hallberg-NOAA committed Feb 23, 2025
1 parent 809d56e commit f486837
Showing 1 changed file with 9 additions and 10 deletions.
19 changes: 9 additions & 10 deletions src/parameterizations/vertical/MOM_diabatic_driver.F90
Original file line number Diff line number Diff line change
Expand Up @@ -2724,7 +2724,6 @@ subroutine diagnose_diabatic_diff_tendency(tv, h, temp_old, saln_old, dt, G, GV,
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: work_3d ! A 3-d work array for diagnostics [various]
real, dimension(SZI_(G),SZJ_(G)) :: work_2d ! A 2-d work array for diagnostics [various]
real :: Idt ! The inverse of the timestep [T-1 ~> s-1]
real :: ppt2mks ! Conversion factor from S to kg/kg [S-1 ~> ppt-1].
integer :: i, j, k, is, ie, js, je, nz
logical :: do_saln_tend ! Calculate salinity-based tendency diagnostics

Expand Down Expand Up @@ -2774,9 +2773,8 @@ subroutine diagnose_diabatic_diff_tendency(tv, h, temp_old, saln_old, dt, G, GV,

! salt tendency
if (CS%id_diabatic_diff_salt_tend > 0 .or. CS%id_diabatic_diff_salt_tend_2d > 0) then
ppt2mks = US%S_to_ppt*0.001
do k=1,nz ; do j=js,je ; do i=is,ie
work_3d(i,j,k) = h(i,j,k)*GV%H_to_RZ * ppt2mks * work_3d(i,j,k)
work_3d(i,j,k) = h(i,j,k) * work_3d(i,j,k)
enddo ; enddo ; enddo
if (CS%id_diabatic_diff_salt_tend > 0) then
call post_data(CS%id_diabatic_diff_salt_tend, work_3d, CS%diag, alt_h=h)
Expand Down Expand Up @@ -2819,7 +2817,6 @@ subroutine diagnose_boundary_forcing_tendency(tv, h, temp_old, saln_old, h_old,
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: work_3d ! A 3-d work array for diagnostics [various]
real, dimension(SZI_(G),SZJ_(G)) :: work_2d ! A 2-d work array for diagnostics [various]
real :: Idt ! The inverse of the timestep [T-1 ~> s-1]
real :: ppt2mks ! Conversion factor from S to kg/kg [S-1 ~> ppt-1].
integer :: i, j, k, is, ie, js, je, nz

is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke
Expand Down Expand Up @@ -2870,9 +2867,8 @@ subroutine diagnose_boundary_forcing_tendency(tv, h, temp_old, saln_old, h_old,

! salt tendency
if (CS%id_boundary_forcing_salt_tend > 0 .or. CS%id_boundary_forcing_salt_tend_2d > 0) then
ppt2mks = US%S_to_ppt*0.001
do k=1,nz ; do j=js,je ; do i=is,ie
work_3d(i,j,k) = GV%H_to_RZ * ppt2mks * Idt * (h(i,j,k) * tv%S(i,j,k) - h_old(i,j,k) * saln_old(i,j,k))
work_3d(i,j,k) = Idt * (h(i,j,k) * tv%S(i,j,k) - h_old(i,j,k) * saln_old(i,j,k))
enddo ; enddo ; enddo
if (CS%id_boundary_forcing_salt_tend > 0) then
call post_data(CS%id_boundary_forcing_salt_tend, work_3d, CS%diag, alt_h=h_old)
Expand Down Expand Up @@ -3372,7 +3368,8 @@ subroutine diabatic_driver_init(Time, G, GV, US, param_file, useALEalgorithm, di
CS%id_diabatic_diff_salt_tend = register_diag_field('ocean_model', &
'diabatic_salt_tendency', diag%axesTL, Time, &
'Diabatic diffusion of salt tendency', &
'kg m-2 s-1', conversion=US%RZ_T_to_kg_m2s, cmor_field_name='osaltdiff', &
'kg m-2 s-1', conversion=US%S_to_ppt*0.001*GV%H_to_RZ*US%RZ_T_to_kg_m2s, &
cmor_field_name='osaltdiff', &
cmor_standard_name='tendency_of_sea_water_salinity_expressed_as_salt_content_'// &
'due_to_parameterized_dianeutral_mixing', &
cmor_long_name='Tendency of sea water salinity expressed as salt content '// &
Expand All @@ -3399,7 +3396,8 @@ subroutine diabatic_driver_init(Time, G, GV, US, param_file, useALEalgorithm, di
CS%id_diabatic_diff_salt_tend_2d = register_diag_field('ocean_model', &
'diabatic_salt_tendency_2d', diag%axesT1, Time, &
'Depth integrated diabatic diffusion salt tendency', &
'kg m-2 s-1', conversion=US%RZ_T_to_kg_m2s, cmor_field_name='osaltdiff_2d', &
'kg m-2 s-1', conversion=US%S_to_ppt*0.001*GV%H_to_RZ*US%RZ_T_to_kg_m2s, &
cmor_field_name='osaltdiff_2d', &
cmor_standard_name='tendency_of_sea_water_salinity_expressed_as_salt_content_'// &
'due_to_parameterized_dianeutral_mixing_depth_integrated', &
cmor_long_name='Tendency of sea water salinity expressed as salt content '// &
Expand Down Expand Up @@ -3446,7 +3444,8 @@ subroutine diabatic_driver_init(Time, G, GV, US, param_file, useALEalgorithm, di

CS%id_boundary_forcing_salt_tend = register_diag_field('ocean_model',&
'boundary_forcing_salt_tendency', diag%axesTL, Time, &
'Boundary forcing salt tendency', 'kg m-2 s-1', conversion=US%RZ_T_to_kg_m2s, &
'Boundary forcing salt tendency', &
'kg m-2 s-1', conversion=US%S_to_ppt*0.001*GV%H_to_RZ*US%RZ_T_to_kg_m2s, &
v_extensive = .true.)
if (CS%id_boundary_forcing_salt_tend > 0) then
CS%boundary_forcing_tendency_diag = .true.
Expand All @@ -3465,7 +3464,7 @@ subroutine diabatic_driver_init(Time, G, GV, US, param_file, useALEalgorithm, di
CS%id_boundary_forcing_salt_tend_2d = register_diag_field('ocean_model',&
'boundary_forcing_salt_tendency_2d', diag%axesT1, Time, &
'Depth integrated boundary forcing of ocean salt', &
'kg m-2 s-1', conversion=US%RZ_T_to_kg_m2s)
'kg m-2 s-1', conversion=US%S_to_ppt*0.001*GV%H_to_RZ*US%RZ_T_to_kg_m2s)
if (CS%id_boundary_forcing_salt_tend_2d > 0) then
CS%boundary_forcing_tendency_diag = .true.
endif
Expand Down

0 comments on commit f486837

Please sign in to comment.