Skip to content

Commit aca2291

Browse files
committed
Alternative method for SAL and tides in Boussinesq
Add an alternative method for SAL and tides in Boussinesq mode. The current method adjusts interface heights with geopotential height anomaly for SAL and tides. For non-Boussinesq mode, the current method is algebraically the same as taking the gradient of SAL and tide geopotential (body forcing). For Boussinesq mode, there is a baroclinic component of tidal forcing and SAL. The alternative method is added to calculate the gradient of tidal forcing and SAL directly at the cost of additional multiplications. The new method is controlled by runtime parameter BOUSSINESQ_SAL_TIDES.
1 parent 55ad253 commit aca2291

File tree

2 files changed

+84
-40
lines changed

2 files changed

+84
-40
lines changed

src/core/MOM_PressureForce_FV.F90

Lines changed: 82 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ module MOM_PressureForce_FV
8282
!! equation of state is 0 to account for the displacement of the sea
8383
!! surface including adjustments for atmospheric or sea-ice pressure.
8484
logical :: use_stanley_pgf !< If true, turn on Stanley parameterization in the PGF
85+
logical :: bq_sal_tides = .false. !< If true, use an alternative method for SAL and tides
86+
!! in Boussinesq mode
8587
integer :: tides_answer_date = 99991231 !< Recover old answers with tides
8688
integer :: id_e_tide = -1 !< Diagnostic identifier
8789
integer :: id_e_tidal_eq = -1 !< Diagnostic identifier
@@ -821,7 +823,12 @@ subroutine PressureForce_FV_nonBouss(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_
821823

822824
! To be consistent with old runs, tidal forcing diagnostic also includes total SAL.
823825
! New diagnostics are given for each individual field.
824-
if (CS%id_e_tide>0) call post_data(CS%id_e_tide, e_sal+e_tidal_eq+e_tidal_sal, CS%diag)
826+
if (CS%id_e_tide>0) then
827+
if (CS%tides_answer_date>20230630) then ; do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
828+
e_sal_and_tide(i,j) = e_sal(i,j) + e_tidal_eq(i,j) + e_tidal_sal(i,j)
829+
enddo ; enddo ; endif
830+
call post_data(CS%id_e_tide, e_sal_and_tide, CS%diag)
831+
endif
825832
if (CS%id_e_sal>0) call post_data(CS%id_e_sal, e_sal, CS%diag)
826833
if (CS%id_e_tidal_eq>0) call post_data(CS%id_e_tidal_eq, e_tidal_eq, CS%diag)
827834
if (CS%id_e_tidal_sal>0) call post_data(CS%id_e_tidal_sal, e_tidal_sal, CS%diag)
@@ -1189,43 +1196,39 @@ subroutine PressureForce_FV_Bouss(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm
11891196
enddo ; enddo
11901197
enddo
11911198

1192-
! Self-attraction and loading (SAL) and tides (new answers)
1193-
if (CS%tides_answer_date>20230630) then
1194-
! SAL
1195-
if (CS%calculate_SAL) then
1196-
if (CS%sal_use_bpa) then
1197-
!$OMP parallel do default(shared)
1198-
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
1199-
pbot_anom(i,j) = pa(i,j,nz+1) * I_g_rho - e(i,j,nz+1)
1200-
enddo ; enddo
1201-
else
1202-
!$OMP parallel do default(shared)
1203-
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
1204-
pbot_anom(i,j) = e(i,j,1) - max(-G%bathyT(i,j) - G%Z_ref, 0.0) ! Remove topogrpahy above sea level
1205-
enddo ; enddo
1206-
endif
1207-
call calc_SAL(pbot_anom, e_sal, G, CS%SAL_CSp, tmp_scale=US%Z_to_m)
1208-
do K=1,nz+1
1209-
!$OMP parallel do default(shared)
1210-
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
1211-
e(i,j,K) = e(i,j,K) - e_sal(i,j)
1212-
pa(i,j,K) = pa(i,j,K) - GxRho * e_sal(i,j)
1213-
enddo ; enddo
1214-
enddo
1199+
! Self-attraction and loading (SAL) (new answers)
1200+
if (CS%calculate_SAL .and. CS%tides_answer_date>20230630) then
1201+
if (CS%sal_use_bpa) then
1202+
!$OMP parallel do default(shared)
1203+
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
1204+
pbot_anom(i,j) = pa(i,j,nz+1) * I_g_rho - e(i,j,nz+1)
1205+
enddo ; enddo
1206+
else
1207+
!$OMP parallel do default(shared)
1208+
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
1209+
pbot_anom(i,j) = e(i,j,1) - max(-G%bathyT(i,j) - G%Z_ref, 0.0) ! Remove topography above sea level
1210+
enddo ; enddo
12151211
endif
1212+
call calc_SAL(pbot_anom, e_sal, G, CS%SAL_CSp, tmp_scale=US%Z_to_m)
1213+
if (.not.CS%bq_sal_tides) then ; do K=1,nz+1
1214+
!$OMP parallel do default(shared)
1215+
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
1216+
e(i,j,K) = e(i,j,K) - e_sal(i,j)
1217+
pa(i,j,K) = pa(i,j,K) - GxRho * e_sal(i,j)
1218+
enddo ; enddo
1219+
enddo ; endif
1220+
endif
12161221

1217-
! Tides
1218-
if (CS%tides) then
1219-
call calc_tidal_forcing(CS%Time, e_tidal_eq, e_tidal_sal, G, US, CS%tides_CSp)
1222+
! Tides (new answers)
1223+
if (CS%tides .and. CS%tides_answer_date>20230630) then
1224+
call calc_tidal_forcing(CS%Time, e_tidal_eq, e_tidal_sal, G, US, CS%tides_CSp)
1225+
if (.not.CS%bq_sal_tides) then ; do K=1,nz+1
12201226
!$OMP parallel do default(shared)
1221-
do K=1,nz+1
1222-
!$OMP parallel do default(shared)
1223-
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
1224-
e(i,j,K) = e(i,j,K) - (e_tidal_eq(i,j) + e_tidal_sal(i,j))
1225-
pa(i,j,K) = pa(i,j,K) - GxRho * (e_tidal_eq(i,j) + e_tidal_sal(i,j))
1226-
enddo ; enddo
1227-
enddo
1228-
endif
1227+
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
1228+
e(i,j,K) = e(i,j,K) - (e_tidal_eq(i,j) + e_tidal_sal(i,j))
1229+
pa(i,j,K) = pa(i,j,K) - GxRho * (e_tidal_eq(i,j) + e_tidal_sal(i,j))
1230+
enddo ; enddo
1231+
enddo ; endif
12291232
endif
12301233

12311234
if (CS%correction_intxpa .or. CS%reset_intxpa_integral) then
@@ -1604,6 +1607,34 @@ subroutine PressureForce_FV_Bouss(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm
16041607
((h(i,j,k) + h(i,j+1,k)) + h_neglect))
16051608
enddo ; enddo ; enddo
16061609

1610+
! Calculate SAL geopotential anomaly and add its gradient to pressure gradient force
1611+
if (CS%calculate_SAL .and. CS%tides_answer_date>20230630 .and. CS%bq_sal_tides) then
1612+
!$OMP parallel do default(shared)
1613+
do k=1,nz
1614+
do j=js,je ; do I=Isq,Ieq
1615+
PFu(I,j,k) = PFu(I,j,k) + (e_sal(i+1,j) - e_sal(i,j)) * GV%g_Earth * G%IdxCu(I,j)
1616+
enddo ; enddo
1617+
do J=Jsq,Jeq ; do i=is,ie
1618+
PFv(i,J,k) = PFv(i,J,k) + (e_sal(i,j+1) - e_sal(i,j)) * GV%g_Earth * G%IdyCv(i,J)
1619+
enddo ; enddo
1620+
enddo
1621+
endif
1622+
1623+
! Calculate tidal geopotential anomaly and add its gradient to pressure gradient force
1624+
if (CS%tides .and. CS%tides_answer_date>20230630 .and. CS%bq_sal_tides) then
1625+
!$OMP parallel do default(shared)
1626+
do k=1,nz
1627+
do j=js,je ; do I=Isq,Ieq
1628+
PFu(I,j,k) = PFu(I,j,k) + ((e_tidal_eq(i+1,j) + e_tidal_sal(i+1,j)) &
1629+
- (e_tidal_eq(i,j) + e_tidal_sal(i,j))) * GV%g_Earth * G%IdxCu(I,j)
1630+
enddo ; enddo
1631+
do J=Jsq,Jeq ; do i=is,ie
1632+
PFv(i,J,k) = PFv(i,J,k) + ((e_tidal_eq(i,j+1) + e_tidal_sal(i,j+1)) &
1633+
- (e_tidal_eq(i,j) + e_tidal_sal(i,j))) * GV%g_Earth * G%IdyCv(i,J)
1634+
enddo ; enddo
1635+
enddo
1636+
endif
1637+
16071638
if (CS%GFS_scale < 1.0) then
16081639
! Adjust the Montgomery potential to make this a reduced gravity model.
16091640
if (use_EOS) then
@@ -1649,7 +1680,7 @@ subroutine PressureForce_FV_Bouss(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm
16491680
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
16501681
eta(i,j) = e(i,j,1)*GV%Z_to_H
16511682
enddo ; enddo
1652-
if (CS%tides) then
1683+
if (CS%tides .and. (.not.CS%bq_sal_tides)) then
16531684
if (CS%tides_answer_date>20230630) then
16541685
!$OMP parallel do default(shared)
16551686
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
@@ -1662,7 +1693,7 @@ subroutine PressureForce_FV_Bouss(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm
16621693
enddo ; enddo
16631694
endif
16641695
endif
1665-
if (CS%calculate_SAL .and. (CS%tides_answer_date>20230630)) then
1696+
if (CS%calculate_SAL .and. (CS%tides_answer_date>20230630) .and. (.not.CS%bq_sal_tides)) then
16661697
!$OMP parallel do default(shared)
16671698
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
16681699
eta(i,j) = eta(i,j) + e_sal(i,j)*GV%Z_to_H
@@ -1709,7 +1740,12 @@ subroutine PressureForce_FV_Bouss(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm
17091740

17101741
! To be consistent with old runs, tidal forcing diagnostic also includes total SAL.
17111742
! New diagnostics are given for each individual field.
1712-
if (CS%id_e_tide>0) call post_data(CS%id_e_tide, e_sal+e_tidal_eq+e_tidal_sal, CS%diag)
1743+
if (CS%id_e_tide>0) then
1744+
if (CS%tides_answer_date>20230630) then ; do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1
1745+
e_sal_and_tide(i,j) = e_sal(i,j) + e_tidal_eq(i,j) + e_tidal_sal(i,j)
1746+
enddo ; enddo ; endif
1747+
call post_data(CS%id_e_tide, e_sal_and_tide, CS%diag)
1748+
endif
17131749
if (CS%id_e_sal>0) call post_data(CS%id_e_sal, e_sal, CS%diag)
17141750
if (CS%id_e_tidal_eq>0) call post_data(CS%id_e_tidal_eq, e_tidal_eq, CS%diag)
17151751
if (CS%id_e_tidal_sal>0) call post_data(CS%id_e_tidal_sal, e_tidal_sal, CS%diag)
@@ -1780,6 +1816,14 @@ subroutine PressureForce_FV_init(Time, G, GV, US, param_file, diag, CS, SAL_CSp,
17801816
if (CS%calculate_SAL) &
17811817
call get_param(param_file, '', "SAL_USE_BPA", CS%sal_use_bpa, default=.false., &
17821818
do_not_log=.true.)
1819+
if ((CS%tides .or. CS%calculate_SAL) .and. GV%Boussinesq) &
1820+
call get_param(param_file, mdl, "BOUSSINESQ_SAL_TIDES", CS%bq_sal_tides, "If true, "//&
1821+
"in Boussinesq mode, use an alternative method to include self-attraction "//&
1822+
"and loading (SAL) and tidal forcings in pressure gradient, in which their "//&
1823+
"gradients are calculated separately, instead of adding geopotential "//&
1824+
"anomalies as corrections to the interface height. This alternative method "//&
1825+
"elimates a baroclinic component of the SAL and tidal forcings.", &
1826+
default=.false.)
17831827
call get_param(param_file, "MOM", "ENABLE_THERMODYNAMICS", use_temperature, &
17841828
"If true, Temperature and salinity are used as state variables.", &
17851829
default=.true., do_not_log=.true.)

src/parameterizations/lateral/MOM_self_attr_load.F90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ module MOM_self_attr_load
4545
real, allocatable :: Love_scaling(:)
4646
!< Dimensional coefficients for harmonic SAL, which are functions of Love numbers
4747
!! [nondim or L2 Z-1 T-2 ~> m s-2 or R-1 ~> m3 kg-1 or L2 Z-1 T-2 R-1 ~> m4 s-2 kg-1]
48-
real, allocatable :: Snm_Re(:), Snm_Im(:)
49-
!< Real and imaginary coefficients for harmonic SAL [Z ~> m or L2 T-2 ~> m2 s-2]
48+
real, allocatable :: Snm_Re(:), & !< Real SHT coefficient for SHT SAL [Z ~> m]
49+
Snm_Im(:) !< Imaginary SHT coefficient for SHT SAL [Z ~> m]
5050
end type SAL_CS
5151

5252
integer :: id_clock_SAL !< CPU clock for self-attraction and loading

0 commit comments

Comments
 (0)