Skip to content

Commit 99b95df

Browse files
committed
+Optionally use SSH in calculate density for PGF
Added the option of including the atmospheric or ice pressure and sea surface height displacements from the global reference height in the pressures used in the density calculations for Boussinesq pressure gradient calculations. Note that the full pressures were already being used everywhere apart from the calculation of the equation of state. This capability is controlled by the new runtime parameter SSH_IN_EOS_PRESSURE_FOR_PGF. This commit changes the Z_0p argument to int_density_dz and 8 other routines (int_density_dz_generic_pcm, int_density_dz_generic_plm, int_density_dz_generic_ppm, analytic_int_density_dz, int_density_dz_wright, int_density_dz_wright_full, int_density_dz_wright_red and int_density_dz_linear) from scalars into 2-d arrays, as were the internal z0pres arrays in most of these routines. By default, all answers are bitwise identical, but there is a new runtime parameter in the MOM_parameter_doc files for Boussinesq cases.
1 parent 1b39d07 commit 99b95df

File tree

6 files changed

+111
-41
lines changed

6 files changed

+111
-41
lines changed

src/core/MOM_PressureForce_FV.F90

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ module MOM_PressureForce_FV
6363
!! for the finite volume pressure gradient calculation.
6464
!! By the default (1) is for a piecewise linear method
6565

66+
logical :: use_SSH_in_Z0p !< If true, adjust the height at which the pressure used in the
67+
!! equation of state is 0 to account for the displacement of the sea
68+
!! surface including adjustments for atmospheric or sea-ice pressure.
6669
logical :: use_stanley_pgf !< If true, turn on Stanley parameterization in the PGF
6770
integer :: tides_answer_date !< Recover old answers with tides in Boussinesq mode
6871
integer :: id_e_tide = -1 !< Diagnostic identifier
@@ -522,6 +525,7 @@ subroutine PressureForce_FV_Bouss(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm
522525
! [Z ~> m].
523526
e_tide_sal, & ! The bottom geopotential anomaly due to harmonic self-attraction and loading
524527
! specific to tides [Z ~> m].
528+
Z_0p, & ! The height at which the pressure used in the equation of state is 0 [Z ~> m]
525529
SSH, & ! The sea surface height anomaly, in depth units [Z ~> m].
526530
dM ! The barotropic adjustment to the Montgomery potential to
527531
! account for a reduced gravity model [L2 T-2 ~> m2 s-2].
@@ -577,6 +581,7 @@ subroutine PressureForce_FV_Bouss(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm
577581
! in roundoff and can be neglected [H ~> m].
578582
real :: I_Rho0 ! The inverse of the Boussinesq reference density [R-1 ~> m3 kg-1].
579583
real :: G_Rho0 ! G_Earth / Rho0 in [L2 Z-1 T-2 R-1 ~> m4 s-2 kg-1].
584+
real :: I_g_rho ! The inverse of the density times the gravitational acceleration [Z T2 L-2 R-1 ~> m Pa-1]
580585
real :: rho_ref ! The reference density [R ~> kg m-3].
581586
real :: dz_neglect ! A minimal thickness [Z ~> m], like e.
582587
real :: H_to_RL2_T2 ! A factor to convert from thickness units (H) to pressure
@@ -753,6 +758,21 @@ subroutine PressureForce_FV_Bouss(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm
753758
enddo ; enddo
754759
endif
755760

761+
if (CS%use_SSH_in_Z0p .and. use_p_atm) then
762+
I_g_rho = 1.0 / (CS%rho0*GV%g_Earth)
763+
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
764+
Z_0p(i,j) = e(i,j,1) + p_atm(i,j) * I_g_rho
765+
enddo ; enddo
766+
elseif (CS%use_SSH_in_Z0p) then
767+
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
768+
Z_0p(i,j) = e(i,j,1)
769+
enddo ; enddo
770+
else
771+
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
772+
Z_0p(i,j) = G%Z_ref
773+
enddo ; enddo
774+
endif
775+
756776
do k=1,nz
757777
! Calculate 4 integrals through the layer that are required in the
758778
! subsequent calculation.
@@ -769,19 +789,19 @@ subroutine PressureForce_FV_Bouss(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm
769789
G%HI, GV, tv%eqn_of_state, US, CS%use_stanley_pgf, dpa(:,:,k), intz_dpa(:,:,k), &
770790
intx_dpa(:,:,k), inty_dpa(:,:,k), &
771791
MassWghtInterp=CS%MassWghtInterp, &
772-
use_inaccurate_form=CS%use_inaccurate_pgf_rho_anom, Z_0p=G%Z_ref)
792+
use_inaccurate_form=CS%use_inaccurate_pgf_rho_anom, Z_0p=Z_0p)
773793
elseif ( CS%Recon_Scheme == 2 ) then
774794
call int_density_dz_generic_ppm(k, tv, T_t, T_b, S_t, S_b, e, &
775795
rho_ref, CS%Rho0, GV%g_Earth, dz_neglect, G%bathyT, &
776796
G%HI, GV, tv%eqn_of_state, US, CS%use_stanley_pgf, dpa(:,:,k), intz_dpa(:,:,k), &
777797
intx_dpa(:,:,k), inty_dpa(:,:,k), &
778-
MassWghtInterp=CS%MassWghtInterp, Z_0p=G%Z_ref)
798+
MassWghtInterp=CS%MassWghtInterp, Z_0p=Z_0p)
779799
endif
780800
else
781801
call int_density_dz(tv_tmp%T(:,:,k), tv_tmp%S(:,:,k), e(:,:,K), e(:,:,K+1), &
782802
rho_ref, CS%Rho0, GV%g_Earth, G%HI, tv%eqn_of_state, US, dpa(:,:,k), &
783803
intz_dpa(:,:,k), intx_dpa(:,:,k), inty_dpa(:,:,k), G%bathyT, dz_neglect, &
784-
CS%MassWghtInterp, Z_0p=G%Z_ref)
804+
CS%MassWghtInterp, Z_0p=Z_0p)
785805
endif
786806
if (GV%Z_to_H /= 1.0) then
787807
!$OMP parallel do default(shared)
@@ -1042,6 +1062,12 @@ subroutine PressureForce_FV_init(Time, G, GV, US, param_file, diag, CS, SAL_CSp,
10421062
endif
10431063
call get_param(param_file, mdl, "CALCULATE_SAL", CS%calculate_SAL, &
10441064
"If true, calculate self-attraction and loading.", default=CS%tides)
1065+
call get_param(param_file, mdl, "SSH_IN_EOS_PRESSURE_FOR_PGF", CS%use_SSH_in_Z0p, &
1066+
"If true, include contributions from the sea surface height in the height-based "//&
1067+
"pressure used in the equation of state calculations for the Boussinesq pressure "//&
1068+
"gradient forces, including adjustments for atmospheric or sea-ice pressure.", &
1069+
default=.false., do_not_log=.not.GV%Boussinesq)
1070+
10451071
call get_param(param_file, "MOM", "USE_REGRIDDING", use_ALE, &
10461072
"If True, use the ALE algorithm (regridding/remapping). "//&
10471073
"If False, use the layered isopycnal algorithm.", default=.false. )

src/core/MOM_density_integrals.F90

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ subroutine int_density_dz(T, S, z_t, z_b, rho_ref, rho_0, G_e, HI, EOS, US, dpa,
8080
real, optional, intent(in) :: dz_neglect !< A minuscule thickness change [Z ~> m]
8181
integer, optional, intent(in) :: MassWghtInterp !< A flag indicating whether and how to use
8282
!! mass weighting to interpolate T/S in integrals
83-
real, optional, intent(in) :: Z_0p !< The height at which the pressure is 0 [Z ~> m]
83+
real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
84+
optional, intent(in) :: Z_0p !< The height at which the pressure is 0 [Z ~> m]
8485

8586
if (EOS_quadrature(EOS)) then
8687
call int_density_dz_generic_pcm(T, S, z_t, z_b, rho_ref, rho_0, G_e, HI, EOS, US, dpa, &
@@ -139,7 +140,8 @@ subroutine int_density_dz_generic_pcm(T, S, z_t, z_b, rho_ref, rho_0, G_e, HI, &
139140
!! mass weighting to interpolate T/S in integrals
140141
logical, optional, intent(in) :: use_inaccurate_form !< If true, uses an inaccurate form of
141142
!! density anomalies, as was used prior to March 2018.
142-
real, optional, intent(in) :: Z_0p !< The height at which the pressure is 0 [Z ~> m]
143+
real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
144+
optional, intent(in) :: Z_0p !< The height at which the pressure is 0 [Z ~> m]
143145

144146
! Local variables
145147
real :: T5((5*HI%iscB+1):(5*(HI%iecB+2))) ! Temperatures along a line of subgrid locations [C ~> degC]
@@ -157,7 +159,7 @@ subroutine int_density_dz_generic_pcm(T, S, z_t, z_b, rho_ref, rho_0, G_e, HI, &
157159
real :: dz ! The layer thickness [Z ~> m]
158160
real :: dz_x(5,HI%iscB:HI%iecB) ! Layer thicknesses along an x-line of subgrid locations [Z ~> m]
159161
real :: dz_y(5,HI%isc:HI%iec) ! Layer thicknesses along a y-line of subgrid locations [Z ~> m]
160-
real :: z0pres ! The height at which the pressure is zero [Z ~> m]
162+
real :: z0pres(HI%isd:HI%ied,HI%jsd:HI%jed) ! The height at which the pressure is zero [Z ~> m]
161163
real :: hWght ! A pressure-thickness below topography [Z ~> m]
162164
real :: hL, hR ! Pressure-thicknesses of the columns to the left and right [Z ~> m]
163165
real :: iDenom ! The inverse of the denominator in the weights [Z-2 ~> m-2]
@@ -184,7 +186,13 @@ subroutine int_density_dz_generic_pcm(T, S, z_t, z_b, rho_ref, rho_0, G_e, HI, &
184186

185187
GxRho = G_e * rho_0
186188
I_Rho = 1.0 / rho_0
187-
z0pres = 0.0 ; if (present(Z_0p)) z0pres = Z_0p
189+
if (present(Z_0p)) then
190+
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
191+
z0pres(i,j) = Z_0p(i,j)
192+
enddo ; enddo
193+
else
194+
z0pres(:,:) = 0.0
195+
endif
188196
use_rho_ref = .true.
189197
if (present(use_inaccurate_form)) then
190198
if (use_inaccurate_form) use_rho_ref = .not. use_inaccurate_form
@@ -209,7 +217,7 @@ subroutine int_density_dz_generic_pcm(T, S, z_t, z_b, rho_ref, rho_0, G_e, HI, &
209217
dz = z_t(i,j) - z_b(i,j)
210218
do n=1,5
211219
T5(i*5+n) = T(i,j) ; S5(i*5+n) = S(i,j)
212-
p5(i*5+n) = -GxRho*((z_t(i,j) - z0pres) - 0.25*real(n-1)*dz)
220+
p5(i*5+n) = -GxRho*((z_t(i,j) - z0pres(i,j)) - 0.25*real(n-1)*dz)
213221
enddo
214222
enddo
215223

@@ -260,7 +268,7 @@ subroutine int_density_dz_generic_pcm(T, S, z_t, z_b, rho_ref, rho_0, G_e, HI, &
260268
pos = i*15+(m-2)*5
261269
T15(pos+1) = wtT_L*T(i,j) + wtT_R*T(i+1,j)
262270
S15(pos+1) = wtT_L*S(i,j) + wtT_R*S(i+1,j)
263-
p15(pos+1) = -GxRho*((wt_L*z_t(i,j) + wt_R*z_t(i+1,j)) - z0pres)
271+
p15(pos+1) = -GxRho*((wt_L*z_t(i,j) + wt_R*z_t(i+1,j)) - z0pres(i,j))
264272
do n=2,5
265273
T15(pos+n) = T15(pos+1) ; S15(pos+n) = S15(pos+1)
266274
p15(pos+n) = p15(pos+n-1) + GxRho*0.25*dz_x(m,i)
@@ -326,7 +334,7 @@ subroutine int_density_dz_generic_pcm(T, S, z_t, z_b, rho_ref, rho_0, G_e, HI, &
326334
pos = i*15+(m-2)*5
327335
T15(pos+1) = wtT_L*T(i,j) + wtT_R*T(i,j+1)
328336
S15(pos+1) = wtT_L*S(i,j) + wtT_R*S(i,j+1)
329-
p15(pos+1) = -GxRho*((wt_L*z_t(i,j) + wt_R*z_t(i,j+1)) - z0pres)
337+
p15(pos+1) = -GxRho*((wt_L*z_t(i,j) + wt_R*z_t(i,j+1)) - z0pres(i,j))
330338
do n=2,5
331339
T15(pos+n) = T15(pos+1) ; S15(pos+n) = S15(pos+1)
332340
p15(pos+n) = p15(pos+n-1) + GxRho*0.25*dz_y(m,i)
@@ -414,7 +422,8 @@ subroutine int_density_dz_generic_plm(k, tv, T_t, T_b, S_t, S_b, e, rho_ref, &
414422
!! mass weighting to interpolate T/S in integrals
415423
logical, optional, intent(in) :: use_inaccurate_form !< If true, uses an inaccurate form of
416424
!! density anomalies, as was used prior to March 2018.
417-
real, optional, intent(in) :: Z_0p !< The height at which the pressure is 0 [Z ~> m]
425+
real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
426+
optional, intent(in) :: Z_0p !< The height at which the pressure is 0 [Z ~> m]
418427

419428
! This subroutine calculates (by numerical quadrature) integrals of
420429
! pressure anomalies across layers, which are required for calculating the
@@ -464,7 +473,7 @@ subroutine int_density_dz_generic_plm(k, tv, T_t, T_b, S_t, S_b, e, rho_ref, &
464473
real :: massWeightToggle ! A non-dimensional toggle factor (0 or 1) [nondim]
465474
real :: Ttl, Tbl, Ttr, Tbr ! Temperatures at the velocity cell corners [C ~> degC]
466475
real :: Stl, Sbl, Str, Sbr ! Salinities at the velocity cell corners [S ~> ppt]
467-
real :: z0pres ! The height at which the pressure is zero [Z ~> m]
476+
real :: z0pres(HI%isd:HI%ied,HI%jsd:HI%jed) ! The height at which the pressure is zero [Z ~> m]
468477
real :: hWght ! A topographically limited thickness weight [Z ~> m]
469478
real :: hL, hR ! Thicknesses to the left and right [Z ~> m]
470479
real :: iDenom ! The denominator of the thickness weight expressions [Z-2 ~> m-2]
@@ -480,7 +489,13 @@ subroutine int_density_dz_generic_plm(k, tv, T_t, T_b, S_t, S_b, e, rho_ref, &
480489

481490
GxRho = G_e * rho_0
482491
I_Rho = 1.0 / rho_0
483-
z0pres = 0.0 ; if (present(Z_0p)) z0pres = Z_0p
492+
if (present(Z_0p)) then
493+
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
494+
z0pres(i,j) = Z_0p(i,j)
495+
enddo ; enddo
496+
else
497+
z0pres(:,:) = 0.0
498+
endif
484499
massWeightToggle = 0.
485500
if (present(MassWghtInterp)) then ; if (BTEST(MassWghtInterp, 0)) massWeightToggle = 1. ; endif
486501
use_rho_ref = .true.
@@ -517,7 +532,7 @@ subroutine int_density_dz_generic_plm(k, tv, T_t, T_b, S_t, S_b, e, rho_ref, &
517532
do i = Isq,Ieq+1
518533
dz(i) = e(i,j,K) - e(i,j,K+1)
519534
do n=1,5
520-
p5(i*5+n) = -GxRho*((e(i,j,K) - z0pres) - 0.25*real(n-1)*dz(i))
535+
p5(i*5+n) = -GxRho*((e(i,j,K) - z0pres(i,j)) - 0.25*real(n-1)*dz(i))
521536
! Salinity and temperature points are linearly interpolated
522537
S5(i*5+n) = wt_t(n) * S_t(i,j,k) + wt_b(n) * S_b(i,j,k)
523538
T5(i*5+n) = wt_t(n) * T_t(i,j,k) + wt_b(n) * T_b(i,j,k)
@@ -610,7 +625,7 @@ subroutine int_density_dz_generic_plm(k, tv, T_t, T_b, S_t, S_b, e, rho_ref, &
610625
S15(pos+1) = w_left*Stl + w_right*Str
611626
S15(pos+5) = w_left*Sbl + w_right*Sbr
612627

613-
p15(pos+1) = -GxRho*((w_left*e(i,j,K) + w_right*e(i+1,j,K)) - z0pres)
628+
p15(pos+1) = -GxRho*((w_left*e(i,j,K) + w_right*e(i+1,j,K)) - z0pres(i,j))
614629

615630
! Pressure
616631
do n=2,5
@@ -706,7 +721,7 @@ subroutine int_density_dz_generic_plm(k, tv, T_t, T_b, S_t, S_b, e, rho_ref, &
706721
S15(pos+1) = w_left*Stl + w_right*Str
707722
S15(pos+5) = w_left*Sbl + w_right*Sbr
708723

709-
p15(pos+1) = -GxRho*((w_left*e(i,j,K) + w_right*e(i,j+1,K)) - z0pres)
724+
p15(pos+1) = -GxRho*((w_left*e(i,j,K) + w_right*e(i,j+1,K)) - z0pres(i,j))
710725

711726
! Pressure
712727
do n=2,5
@@ -812,7 +827,8 @@ subroutine int_density_dz_generic_ppm(k, tv, T_t, T_b, S_t, S_b, e, &
812827
!! divided by the y grid spacing [R L2 T-2 ~> Pa]
813828
integer, optional, intent(in) :: MassWghtInterp !< A flag indicating whether and how to use
814829
!! mass weighting to interpolate T/S in integrals
815-
real, optional, intent(in) :: Z_0p !< The height at which the pressure is 0 [Z ~> m]
830+
real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
831+
optional, intent(in) :: Z_0p !< The height at which the pressure is 0 [Z ~> m]
816832

817833
! This subroutine calculates (by numerical quadrature) integrals of
818834
! pressure anomalies across layers, which are required for calculating the
@@ -864,7 +880,7 @@ subroutine int_density_dz_generic_ppm(k, tv, T_t, T_b, S_t, S_b, e, &
864880
real :: t6 ! PPM curvature coefficient for T [C ~> degC]
865881
real :: T_top, T_mn, T_bot ! Left edge, cell mean and right edge values used in PPM reconstructions of T [C ~> degC]
866882
real :: S_top, S_mn, S_bot ! Left edge, cell mean and right edge values used in PPM reconstructions of S [S ~> ppt]
867-
real :: z0pres ! The height at which the pressure is zero [Z ~> m]
883+
real :: z0pres(HI%isd:HI%ied,HI%jsd:HI%jed) ! The height at which the pressure is zero [Z ~> m]
868884
real :: hWght ! A topographically limited thickness weight [Z ~> m]
869885
real :: hL, hR ! Thicknesses to the left and right [Z ~> m]
870886
real :: iDenom ! The denominator of the thickness weight expressions [Z-2 ~> m-2]
@@ -879,7 +895,13 @@ subroutine int_density_dz_generic_ppm(k, tv, T_t, T_b, S_t, S_b, e, &
879895

880896
GxRho = G_e * rho_0
881897
I_Rho = 1.0 / rho_0
882-
z0pres = 0.0 ; if (present(Z_0p)) z0pres = Z_0p
898+
if (present(Z_0p)) then
899+
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
900+
z0pres(i,j) = Z_0p(i,j)
901+
enddo ; enddo
902+
else
903+
z0pres(:,:) = 0.0
904+
endif
883905
massWeightToggle = 0.
884906
if (present(MassWghtInterp)) then ; if (BTEST(MassWghtInterp, 0)) massWeightToggle = 1. ; endif
885907

@@ -924,7 +946,7 @@ subroutine int_density_dz_generic_ppm(k, tv, T_t, T_b, S_t, S_b, e, &
924946
endif
925947
dz = e(i,j,K) - e(i,j,K+1)
926948
do n=1,5
927-
p5(I*5+n) = -GxRho*((e(i,j,K) - z0pres) - 0.25*real(n-1)*dz)
949+
p5(I*5+n) = -GxRho*((e(i,j,K) - z0pres(i,j)) - 0.25*real(n-1)*dz)
928950
! Salinity and temperature points are reconstructed with PPM
929951
S5(I*5+n) = wt_t(n) * S_t(i,j,k) + wt_b(n) * ( S_b(i,j,k) + s6 * wt_t(n) )
930952
T5(I*5+n) = wt_t(n) * T_t(i,j,k) + wt_b(n) * ( T_b(i,j,k) + t6 * wt_t(n) )
@@ -1011,7 +1033,7 @@ subroutine int_density_dz_generic_ppm(k, tv, T_t, T_b, S_t, S_b, e, &
10111033
dz_x(m,i) = w_left*(e(i,j,K) - e(i,j,K+1)) + w_right*(e(i+1,j,K) - e(i+1,j,K+1))
10121034

10131035
pos = i*15+(m-2)*5
1014-
p15(pos+1) = -GxRho*((w_left*e(i,j,K) + w_right*e(i+1,j,K)) - z0pres)
1036+
p15(pos+1) = -GxRho*((w_left*e(i,j,K) + w_right*e(i+1,j,K)) - z0pres(i,j))
10151037
do n=2,5
10161038
p15(pos+n) = p15(pos+n-1) + GxRho*0.25*dz_x(m,i)
10171039
enddo
@@ -1116,7 +1138,7 @@ subroutine int_density_dz_generic_ppm(k, tv, T_t, T_b, S_t, S_b, e, &
11161138
dz_y(m,i) = w_left*(e(i,j,K) - e(i,j,K+1)) + w_right*(e(i,j+1,K) - e(i,j+1,K+1))
11171139

11181140
pos = i*15+(m-2)*5
1119-
p15(pos+1) = -GxRho*((w_left*e(i,j,K) + w_right*e(i,j+1,K)) - z0pres)
1141+
p15(pos+1) = -GxRho*((w_left*e(i,j,K) + w_right*e(i,j+1,K)) - z0pres(i,j))
11201142
do n=2,5
11211143
p15(pos+n) = p15(pos+n-1) + GxRho*0.25*dz_y(m,i)
11221144
enddo

src/equation_of_state/MOM_EOS.F90

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1345,7 +1345,8 @@ subroutine analytic_int_density_dz(T, S, z_t, z_b, rho_ref, rho_0, G_e, HI, EOS,
13451345
real, optional, intent(in) :: dz_neglect !< A miniscule thickness change [Z ~> m]
13461346
integer, optional, intent(in) :: MassWghtInterp !< A flag indicating whether and how to use
13471347
!! mass weighting to interpolate T/S in integrals
1348-
real, optional, intent(in) :: Z_0p !< The height at which the pressure is 0 [Z ~> m]
1348+
real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), &
1349+
optional, intent(in) :: Z_0p !< The height at which the pressure is 0 [Z ~> m]
13491350

13501351
! Local variables
13511352
real :: rho_scale ! A multiplicative factor by which to scale density from kg m-3 to the

0 commit comments

Comments
 (0)