-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nodal modulation #725
base: dev/gfdl
Are you sure you want to change the base?
Nodal modulation #725
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -70,7 +70,9 @@ module MOM_tidal_forcing | |
ampsal(:,:,:), & !< The amplitude of the SAL [Z ~> m]. | ||
cosphase_prev(:,:,:), & !< The cosine of the phase of the amphidromes in the previous tidal solutions [nondim]. | ||
sinphase_prev(:,:,:), & !< The sine of the phase of the amphidromes in the previous tidal solutions [nondim]. | ||
amp_prev(:,:,:) !< The amplitude of the previous tidal solution [Z ~> m]. | ||
amp_prev(:,:,:), & !< The amplitude of the previous tidal solution [Z ~> m]. | ||
tide_fn(:), & !< Amplitude modulation of tides by nodal cycle [nondim]. | ||
tide_un(:) !< Phase modulation of tides by nodal cycle [rad]. | ||
end type tidal_forcing_CS | ||
|
||
integer :: id_clock_tides !< CPU clock for tides | ||
|
@@ -251,9 +253,14 @@ subroutine tidal_forcing_init(Time, G, US, param_file, CS, HA_CS) | |
real, dimension(MAX_CONSTITUENTS) :: amp_def ! Default amplitude for each tidal constituent [m] | ||
real, dimension(MAX_CONSTITUENTS) :: love_def ! Default love number for each constituent [nondim] | ||
integer, dimension(3) :: tide_ref_date !< Reference date (t = 0) for tidal forcing. | ||
integer, dimension(3) :: nodal_ref_date !< Reference date for calculating nodal modulation for tidal forcing. | ||
logical :: use_M2, use_S2, use_N2, use_K2, use_K1, use_O1, use_P1, use_Q1 | ||
logical :: use_MF, use_MM | ||
logical :: tides ! True if a tidal forcing is to be used. | ||
logical :: add_nodal_terms = .false. !< If true, insert terms for the 18.6 year modulation when | ||
!! calculating tidal forcing. | ||
type(time_type) :: nodal_time !< Model time to calculate nodal modulation for. | ||
type(astro_longitudes) :: nodal_longitudes !< Solar and lunar longitudes for tidal forcing | ||
logical :: HA_ssh, HA_ubt, HA_vbt | ||
! This include declares and sets the variable "version". | ||
# include "version_variable.h" | ||
|
@@ -527,8 +534,46 @@ subroutine tidal_forcing_init(Time, G, US, param_file, CS, HA_CS) | |
enddo | ||
endif | ||
|
||
call get_param(param_file, mdl, "TIDE_ADD_NODAL", add_nodal_terms, & | ||
"If true, include 18.6 year nodal modulation in the astronomical tidal forcing.", & | ||
default=.false.) | ||
call get_param(param_file, mdl, "TIDE_NODAL_REF_DATE", nodal_ref_date, & | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reasonable scenario that nodal correction should use a date other than There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is what has been done in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When I wrote the original OBC tide code I wasn't aware of an easy way for MOM6 to know the current date/time when the OBC and tidal forcing were being initialized. If There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the answers! |
||
"Fixed reference date to use for nodal modulation of astronomical tidal forcing.", & | ||
fail_if_missing=.false., default=0) | ||
|
||
! If the nodal correction is based on a different time, initialize that. | ||
! Otherwise, it can use N from the time reference. | ||
if (add_nodal_terms) then | ||
if (sum(nodal_ref_date) /= 0) then | ||
! A reference date was provided for the nodal correction | ||
nodal_time = set_date(nodal_ref_date(1), nodal_ref_date(2), nodal_ref_date(3)) | ||
call astro_longitudes_init(nodal_time, nodal_longitudes) | ||
elseif (CS%use_eq_phase) then | ||
! Astronomical longitudes were already calculated for use in equilibrium phases, | ||
! so use nodal longitude from that. | ||
nodal_longitudes = CS%tidal_longitudes | ||
else | ||
! Tidal reference time is a required parameter, so calculate the longitudes from that. | ||
call astro_longitudes_init(CS%time_ref, nodal_longitudes) | ||
endif | ||
endif | ||
|
||
allocate(CS%tide_fn(nc)) | ||
allocate(CS%tide_un(nc)) | ||
|
||
do c=1,nc | ||
! Find nodal corrections if needed | ||
if (add_nodal_terms) then | ||
call nodal_fu(trim(CS%const_name(c)), nodal_longitudes%N, CS%tide_fn(c), CS%tide_un(c)) | ||
else | ||
CS%tide_fn(c) = 1.0 | ||
CS%tide_un(c) = 0.0 | ||
endif | ||
enddo | ||
|
||
if (present(HA_CS)) then | ||
call HA_init(Time, US, param_file, CS%time_ref, CS%nc, CS%freq, CS%phase0, CS%const_name, HA_CS) | ||
call HA_init(Time, US, param_file, CS%time_ref, CS%nc, CS%freq, CS%phase0, CS%const_name, & | ||
CS%tide_fn, CS%tide_un, HA_CS) | ||
call get_param(param_file, mdl, "HA_SSH", HA_ssh, & | ||
"If true, perform harmonic analysis of sea serface height.", default=.false.) | ||
if (HA_ssh) call HA_register('ssh', 'h', HA_CS) | ||
|
@@ -613,26 +658,26 @@ subroutine calc_tidal_forcing(Time, e_tide_eq, e_tide_sal, G, US, CS) | |
|
||
do c=1,CS%nc | ||
m = CS%struct(c) | ||
amp_cosomegat = CS%amp(c)*CS%love_no(c) * cos(CS%freq(c)*now + CS%phase0(c)) | ||
amp_sinomegat = CS%amp(c)*CS%love_no(c) * sin(CS%freq(c)*now + CS%phase0(c)) | ||
amp_cosomegat = CS%amp(c)*CS%love_no(c)*CS%tide_fn(c) * cos(CS%freq(c)*now + CS%phase0(c) + CS%tide_un(c)) | ||
amp_sinomegat = CS%amp(c)*CS%love_no(c)*CS%tide_fn(c) * sin(CS%freq(c)*now + CS%phase0(c) + CS%tide_un(c)) | ||
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1 | ||
e_tide_eq(i,j) = e_tide_eq(i,j) + (amp_cosomegat*CS%cos_struct(i,j,m) + & | ||
amp_sinomegat*CS%sin_struct(i,j,m)) | ||
enddo ; enddo | ||
enddo | ||
|
||
if (CS%use_tidal_sal_file) then ; do c=1,CS%nc | ||
cosomegat = cos(CS%freq(c)*now) | ||
sinomegat = sin(CS%freq(c)*now) | ||
cosomegat = CS%tide_fn(c) * cos(CS%freq(c)*now + CS%phase0(c) + CS%tide_un(c)) | ||
sinomegat = CS%tide_fn(c) * sin(CS%freq(c)*now + CS%phase0(c) + CS%tide_un(c)) | ||
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1 | ||
e_tide_sal(i,j) = e_tide_sal(i,j) + CS%ampsal(i,j,c) * & | ||
(cosomegat*CS%cosphasesal(i,j,c) + sinomegat*CS%sinphasesal(i,j,c)) | ||
enddo ; enddo | ||
enddo ; endif | ||
|
||
if (CS%use_tidal_sal_prev) then ; do c=1,CS%nc | ||
cosomegat = cos(CS%freq(c)*now) | ||
sinomegat = sin(CS%freq(c)*now) | ||
cosomegat = CS%tide_fn(c) * cos(CS%freq(c)*now + CS%phase0(c) + CS%tide_un(c)) | ||
sinomegat = CS%tide_fn(c) * sin(CS%freq(c)*now + CS%phase0(c) + CS%tide_un(c)) | ||
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1 | ||
e_tide_sal(i,j) = e_tide_sal(i,j) - CS%sal_scalar * CS%amp_prev(i,j,c) * & | ||
(cosomegat*CS%cosphase_prev(i,j,c) + sinomegat*CS%sinphase_prev(i,j,c)) | ||
|
@@ -691,8 +736,8 @@ subroutine calc_tidal_forcing_legacy(Time, e_sal, e_sal_tide, e_tide_eq, e_tide_ | |
|
||
do c=1,CS%nc | ||
m = CS%struct(c) | ||
amp_cosomegat = CS%amp(c)*CS%love_no(c) * cos(CS%freq(c)*now + CS%phase0(c)) | ||
amp_sinomegat = CS%amp(c)*CS%love_no(c) * sin(CS%freq(c)*now + CS%phase0(c)) | ||
amp_cosomegat = CS%amp(c)*CS%love_no(c)*CS%tide_fn(c) * cos(CS%freq(c)*now + CS%phase0(c) + CS%tide_un(c)) | ||
amp_sinomegat = CS%amp(c)*CS%love_no(c)*CS%tide_fn(c) * sin(CS%freq(c)*now + CS%phase0(c) + CS%tide_un(c)) | ||
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1 | ||
amp_cossin = (amp_cosomegat*CS%cos_struct(i,j,m) + amp_sinomegat*CS%sin_struct(i,j,m)) | ||
e_sal_tide(i,j) = e_sal_tide(i,j) + amp_cossin | ||
|
@@ -701,8 +746,8 @@ subroutine calc_tidal_forcing_legacy(Time, e_sal, e_sal_tide, e_tide_eq, e_tide_ | |
enddo | ||
|
||
if (CS%use_tidal_sal_file) then ; do c=1,CS%nc | ||
cosomegat = cos(CS%freq(c)*now) | ||
sinomegat = sin(CS%freq(c)*now) | ||
cosomegat = CS%tide_fn(c) * cos(CS%freq(c)*now + CS%phase0(c) + CS%tide_un(c)) | ||
sinomegat = CS%tide_fn(c) * sin(CS%freq(c)*now + CS%phase0(c) + CS%tide_un(c)) | ||
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1 | ||
amp_cossin = CS%ampsal(i,j,c) & | ||
* (cosomegat*CS%cosphasesal(i,j,c) + sinomegat*CS%sinphasesal(i,j,c)) | ||
|
@@ -712,8 +757,8 @@ subroutine calc_tidal_forcing_legacy(Time, e_sal, e_sal_tide, e_tide_eq, e_tide_ | |
enddo ; endif | ||
|
||
if (CS%use_tidal_sal_prev) then ; do c=1,CS%nc | ||
cosomegat = cos(CS%freq(c)*now) | ||
sinomegat = sin(CS%freq(c)*now) | ||
cosomegat = CS%tide_fn(c) * cos(CS%freq(c)*now + CS%phase0(c) + CS%tide_un(c)) | ||
sinomegat = CS%tide_fn(c) * sin(CS%freq(c)*now + CS%phase0(c) + CS%tide_un(c)) | ||
do j=Jsq,Jeq+1 ; do i=Isq,Ieq+1 | ||
amp_cossin = -CS%sal_scalar * CS%amp_prev(i,j,c) & | ||
* (cosomegat*CS%cosphase_prev(i,j,c) + sinomegat*CS%sinphase_prev(i,j,c)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be more concise if
tidal_forcing_CS
is used as a single input, rather than its members?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because
tidal_forcing_CS
is not transparent andMOM_harmonic_analysis
cannot see what's inside. @Hallberg-NOAA commented on this in his review of the initial PR for inline harmonic analysis.