Skip to content

Commit 7ee13cd

Browse files
adcroftHallberg-NOAA
authored andcommitted
Adds 5 CMIP7 diagnostics for vertically integrated heat/salt content
Five vertically integrated diagnostics are requested in CMIP7. These ultimately are to be for four vertical intervals (0-300m, 300-700m, etc.) but we will handle that through addition of a 4-level diagnostic grid, configured at run-time. This commit handles the conversion from temperature or salt to heat content or salt content (by mass) and registers a "vertically extensive" quantity so that the diagnostics know to re-integrate rather than remap. Changes: - Added diagnostics absscint, pfscint, scint, chcint and phcint - Moved registration of temp_int and salt_int to within an existing `if (use_temperature)` block - Made public 2 GSW conversion functions in MOM_EOS
1 parent bf1716f commit 7ee13cd

2 files changed

Lines changed: 125 additions & 17 deletions

File tree

src/diagnostics/MOM_diagnostics.F90

Lines changed: 123 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ module MOM_diagnostics
2020
use MOM_domains, only : create_group_pass, do_group_pass, group_pass_type
2121
use MOM_domains, only : To_North, To_East
2222
use MOM_EOS, only : calculate_density, calculate_density_derivs, EOS_domain
23-
use MOM_EOS, only : cons_temp_to_pot_temp, abs_saln_to_prac_saln
23+
use MOM_EOS, only : calculate_spec_vol
24+
use MOM_EOS, only : cons_temp_to_pot_temp, pot_temp_to_cons_temp
25+
use MOM_EOS, only : prac_saln_to_abs_saln, abs_saln_to_prac_saln
2426
use MOM_error_handler, only : MOM_error, FATAL, WARNING
2527
use MOM_file_parser, only : get_param, log_version, param_file_type
2628
use MOM_grid, only : ocean_grid_type
@@ -97,6 +99,9 @@ module MOM_diagnostics
9799
integer :: id_cg_ebt = -1, id_Rd_ebt = -1
98100
integer :: id_p_ebt = -1
99101
integer :: id_temp_int = -1, id_salt_int = -1
102+
integer :: id_absscint = -1, id_pfscint = -1
103+
integer :: id_scint = -1
104+
integer :: id_chcint = -1, id_phcint = -1
100105
integer :: id_mass_wt = -1, id_col_mass = -1
101106
integer :: id_masscello = -1, id_masso = -1
102107
integer :: id_volcello = -1
@@ -904,9 +909,11 @@ subroutine calculate_vertical_integrals(h, tv, p_surf, G, GV, US, CS)
904909
! at the ocean surface [R L2 T-2 ~> Pa].
905910
tr_int ! vertical integral of a tracer times density,
906911
! (Rho_0 in a Boussinesq model) [Conc R Z ~> Conc kg m-2].
912+
real :: tmp(SZI_(G),SZJ_(G),SZK_(GV)) ! Temporary array [defined at each usage]
907913
real :: IG_Earth ! Inverse of gravitational acceleration [T2 Z L-2 ~> s2 m-1].
908914

909915
integer :: i, j, k, is, ie, js, je, nz
916+
integer, dimension(2) :: EOSdom ! The i-computational domain for the equation of state
910917
is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke
911918

912919
if (CS%id_mass_wt > 0) then
@@ -951,6 +958,84 @@ subroutine calculate_vertical_integrals(h, tv, p_surf, G, GV, US, CS)
951958
if (CS%id_col_mass > 0) call post_data(CS%id_col_mass, mass, CS%diag)
952959
endif
953960

961+
! Practical salinity expressed as salt mass content
962+
if (CS%id_scint > 0) then
963+
EOSdom(:) = EOS_domain(G%HI)
964+
if (tv%S_is_absS) then
965+
do k=1,nz ; do j=js,je
966+
call abs_saln_to_prac_saln(tv%S(:,j,k), tmp(:,j,k), tv%eqn_of_state, EOSdom) ! "tmp" [S ~> psu]
967+
do i=is,ie
968+
tmp(i,j,k) = ( GV%H_to_RZ * h(i,j,k) ) * tmp(i,j,k) ! "tmp" [R Z S ~> kg m-2]
969+
enddo
970+
enddo ; enddo
971+
else
972+
do k=1,nz ; do j=js,je ; do i=is,ie
973+
tmp(i,j,k) = ( GV%H_to_RZ * h(i,j,k) ) * tv%S(i,j,k) ! "tmp" [R Z S ~> kg m-2]
974+
enddo ; enddo ; enddo
975+
endif
976+
call post_data(CS%id_scint, tmp, CS%diag)
977+
endif
978+
! Absolute salinities expressed as salt mass content
979+
if (CS%id_absscint > 0 .or. CS%id_pfscint > 0) then
980+
EOSdom(:) = EOS_domain(G%HI)
981+
if (tv%S_is_absS) then
982+
do k=1,nz ; do j=js,je ; do i=is,ie
983+
tmp(i,j,k) = ( GV%H_to_RZ * h(i,j,k) ) * tv%S(i,j,k) ! "tmp" [R Z S ~> kg m-2]
984+
enddo ; enddo ; enddo
985+
else
986+
do k=1,nz ; do j=js,je
987+
call prac_saln_to_abs_saln(tv%S(:,j,k), tmp(:,j,k), tv%eqn_of_state, EOSdom) ! "tmp" [S ~> ppt]
988+
do i=is,ie
989+
tmp(i,j,k) = ( GV%H_to_RZ * h(i,j,k) ) * tmp(i,j,k) ! [R Z S ~> kg m-2]
990+
enddo
991+
enddo ; enddo
992+
endif
993+
if (CS%id_absscint > 0) call post_data(CS%id_absscint, tmp, CS%diag)
994+
! Based on the definitions in https://www.teos-10.org/pubs/gsw/pdf/TEOS-10_Manual.pdf
995+
! The preformed salinity, S*, is the conserved salinity used in models (page 8).
996+
! Although we appear to be labeling tv%S absolute salinity, we do not use the function
997+
! that calculates the "absolute salinity anomaly ratio" which accounts for the
998+
! geographic variations in the types of dissolved salts.
999+
! Hence, I think there is no difference between preformed and absolute salinity
1000+
! for the current implementation of TEOS-10 and so we post the same data for
1001+
! absscint and pfscint. -AJA
1002+
if (CS%id_pfscint > 0) call post_data(CS%id_pfscint, tmp, CS%diag)
1003+
endif
1004+
! Potential temperature expressed as heat content
1005+
if (CS%id_phcint > 0) then
1006+
EOSdom(:) = EOS_domain(G%HI)
1007+
if (tv%T_is_conT) then
1008+
do k=1,nz ; do j=js,je
1009+
call cons_temp_to_pot_temp(tv%T(:,j,k), tv%S(:,j,k), tmp(:,j,k), tv%eqn_of_state, EOSdom) ! "tmp" [C ~> degC]
1010+
do i=is,ie
1011+
tmp(i,j,k) = ( ( tv%C_p * GV%H_to_RZ ) * h(i,j,k) ) * tmp(i,j,k) ! "tmp" [ Q R Z ~> J m-2]
1012+
enddo
1013+
enddo ; enddo
1014+
else
1015+
do k=1,nz ; do j=js,je ; do i=is,ie
1016+
tmp(i,j,k) = ( ( tv%C_p * GV%H_to_RZ ) * h(i,j,k) ) * tv%T(i,j,k) ! "tmp" [Q R Z ~> J m-2]
1017+
enddo ; enddo ; enddo
1018+
endif
1019+
call post_data(CS%id_phcint, tmp, CS%diag)
1020+
endif
1021+
! Conservative temperature expressed as heat content
1022+
if (CS%id_chcint > 0) then
1023+
EOSdom(:) = EOS_domain(G%HI)
1024+
if (tv%T_is_conT) then
1025+
do k=1,nz ; do j=js,je ; do i=is,ie
1026+
tmp(i,j,k) = ( ( tv%C_p * GV%H_to_RZ ) * h(i,j,k) ) * tv%T(i,j,k) ! "tmp" [Q R Z ~> J m-2]
1027+
enddo ; enddo ; enddo
1028+
else
1029+
do k=1,nz ; do j=js,je
1030+
call pot_temp_to_cons_temp(tv%T(:,j,k), tv%S(:,j,k), tmp(:,j,k), tv%eqn_of_state, EOSdom) ! "tmp" [C ~> degC]
1031+
do i=is,ie
1032+
tmp(i,j,k) = ( ( tv%C_p * GV%H_to_RZ ) * h(i,j,k) ) * tmp(i,j,k) ! "tmp" [ Q R Z ~> J m-2]
1033+
enddo
1034+
enddo ; enddo
1035+
endif
1036+
call post_data(CS%id_chcint, tmp, CS%diag)
1037+
endif
1038+
9541039
end subroutine calculate_vertical_integrals
9551040

9561041
!> This subroutine calculates terms in the mechanical energy budget.
@@ -1891,6 +1976,43 @@ subroutine MOM_diagnostics_init(MIS, ADp, CDp, Time, G, GV, US, param_file, diag
18911976
CS%id_abssosga = register_scalar_field('ocean_model', 'ssabss_global', Time, diag, &
18921977
long_name='Global Area Average Sea Surface Absolute Salinity', &
18931978
units='psu', conversion=US%S_to_ppt, standard_name='sea_surface_absolute_salinity')
1979+
1980+
! 2d column integrated
1981+
CS%id_temp_int = register_diag_field('ocean_model', 'temp_int', diag%axesT1, Time, &
1982+
'Density weighted column integrated potential temperature', &
1983+
'degC kg m-2', conversion=US%C_to_degC*US%RZ_to_kg_m2, &
1984+
cmor_field_name='opottempmint', &
1985+
cmor_long_name='integral_wrt_depth_of_product_of_sea_water_density_and_potential_temperature', &
1986+
cmor_standard_name='Depth integrated density times potential temperature')
1987+
CS%id_salt_int = register_diag_field('ocean_model', 'salt_int', diag%axesT1, Time, &
1988+
'Density weighted column integrated salinity', &
1989+
'psu kg m-2', conversion=US%S_to_ppt*US%RZ_to_kg_m2, v_extensive=.true., &
1990+
cmor_field_name='somint', &
1991+
cmor_long_name='integral_wrt_depth_of_product_of_sea_water_density_and_salinity', &
1992+
cmor_standard_name='Depth integrated density times salinity')
1993+
1994+
! 3d vertically integrated
1995+
CS%id_absscint = register_diag_field('ocean_model', 'absscint', diag%axesTL, Time, &
1996+
'Integral wrt depth of seawater absolute salinity expressed as salt mass content', &
1997+
units='kg m-2', conversion=US%S_to_ppt*US%RZ_to_kg_m2, v_extensive=.true., &
1998+
standard_name='integral_wrt_depth_of_sea_water_absolute_salinity_expressed_as_salt_mass_content')
1999+
CS%id_pfscint = register_diag_field('ocean_model', 'pfscint', diag%axesTL, Time, &
2000+
' Integral wrt depth of seawater preformed salinity expressed as salt mass content', &
2001+
units='kg m-2', conversion=US%S_to_ppt*US%RZ_to_kg_m2, v_extensive=.true., &
2002+
standard_name='integral_wrt_depth_of_sea_water_preformed_salinity_expressed_as_salt_mass_content')
2003+
CS%id_scint = register_diag_field('ocean_model', 'scint', diag%axesTL, Time, &
2004+
'Integral wrt depth of seawater practical salinity expressed as salt mass content', &
2005+
units='kg m-2', conversion=US%S_to_ppt*US%RZ_to_kg_m2, v_extensive=.true., &
2006+
standard_name='integral_wrt_depth_of_sea_water_practical_salinity_expressed_as_salt_mass_content')
2007+
CS%id_chcint = register_diag_field('ocean_model', 'chcint', diag%axesTL, Time, &
2008+
'Depth Integrated Seawater Conservative Temperature Expressed As Heat Content', &
2009+
units='J m-2', conversion=US%Q_to_J_kg*US%RZ_to_kg_m2, v_extensive=.true., &
2010+
standard_name='integral_wrt_depth_of_sea_water_conservative_temperature_expressed_as_heat_content')
2011+
CS%id_phcint = register_diag_field('ocean_model', 'phcint', diag%axesTL, Time, &
2012+
'Integrated Ocean Heat Content from Potential Temperature', &
2013+
units='J m-2', conversion=US%Q_to_J_kg*US%RZ_to_kg_m2, v_extensive=.true., &
2014+
standard_name='integral_wrt_depth_of_sea_water_potential_temperature_expressed_as_heat_content')
2015+
18942016
endif
18952017

18962018
CS%id_u = register_diag_field('ocean_model', 'u', diag%axesCuL, Time, &
@@ -2077,22 +2199,6 @@ subroutine MOM_diagnostics_init(MIS, ADp, CDp, Time, G, GV, US, param_file, diag
20772199
CS%id_mass_wt = register_diag_field('ocean_model', 'mass_wt', diag%axesT1, Time, &
20782200
'The column mass for calculating mass-weighted average properties', 'kg m-2', conversion=US%RZ_to_kg_m2)
20792201

2080-
if (use_temperature) then
2081-
CS%id_temp_int = register_diag_field('ocean_model', 'temp_int', diag%axesT1, Time, &
2082-
'Density weighted column integrated potential temperature', &
2083-
'degC kg m-2', conversion=US%C_to_degC*US%RZ_to_kg_m2, &
2084-
cmor_field_name='opottempmint', &
2085-
cmor_long_name='integral_wrt_depth_of_product_of_sea_water_density_and_potential_temperature', &
2086-
cmor_standard_name='Depth integrated density times potential temperature')
2087-
2088-
CS%id_salt_int = register_diag_field('ocean_model', 'salt_int', diag%axesT1, Time, &
2089-
'Density weighted column integrated salinity', &
2090-
'psu kg m-2', conversion=US%S_to_ppt*US%RZ_to_kg_m2, &
2091-
cmor_field_name='somint', &
2092-
cmor_long_name='integral_wrt_depth_of_product_of_sea_water_density_and_salinity', &
2093-
cmor_standard_name='Depth integrated density times salinity')
2094-
endif
2095-
20962202
CS%id_col_mass = register_diag_field('ocean_model', 'col_mass', diag%axesT1, Time, &
20972203
'The column integrated in situ density', 'kg m-2', conversion=US%RZ_to_kg_m2)
20982204

src/equation_of_state/MOM_EOS.F90

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ module MOM_EOS
5050
public calculate_TFreeze
5151
public convert_temp_salt_for_TEOS10
5252
public cons_temp_to_pot_temp
53+
public pot_temp_to_cons_temp
5354
public abs_saln_to_prac_saln
55+
public prac_saln_to_abs_saln
5456
public gsw_sp_from_sr
5557
public gsw_sr_from_sp
5658
public gsw_pt_from_ct

0 commit comments

Comments
 (0)