Skip to content

Commit

Permalink
Inline harmonic analysis
Browse files Browse the repository at this point in the history
The module MOM_harmonic_analysis computes the constant coefficients
of sine/cosine functions for the SSH and barotropic velocity fields
of each tidal constituent.
  • Loading branch information
c2xu authored and Hallberg-NOAA committed Jul 24, 2024
1 parent 2c1a9d3 commit 75db4be
Show file tree
Hide file tree
Showing 6 changed files with 496 additions and 11 deletions.
9 changes: 7 additions & 2 deletions src/core/MOM.F90
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ module MOM
use MOM_forcing_type, only : homogenize_forcing, homogenize_mech_forcing
use MOM_grid, only : ocean_grid_type, MOM_grid_init, MOM_grid_end
use MOM_grid, only : set_first_direction
use MOM_harmonic_analysis, only : HA_accum_FtF, HA_accum_FtSSH, harmonic_analysis_CS
use MOM_hor_index, only : hor_index_type, hor_index_init
use MOM_hor_index, only : rotate_hor_index
use MOM_interface_heights, only : find_eta, calc_derived_thermo, thickness_to_dz
Expand Down Expand Up @@ -389,6 +390,8 @@ module MOM
!< Pointer to the control structure used for the mode-split RK2 dynamics
type(MOM_dyn_split_RK2b_CS), pointer :: dyn_split_RK2b_CSp => NULL()
!< Pointer to the control structure used for an alternate version of the mode-split RK2 dynamics
type(harmonic_analysis_CS), pointer :: HA_CSp => NULL()
!< Pointer to the control structure for harmonic analysis
type(thickness_diffuse_CS) :: thickness_diffuse_CSp
!< Pointer to the control structure used for the isopycnal height diffusive transport.
!! This is also common referred to as Gent-McWilliams diffusion
Expand Down Expand Up @@ -911,6 +914,7 @@ subroutine step_MOM(forces_in, fluxes_in, sfc_state, Time_start, time_int_in, CS
enddo ; enddo
endif

if (associated(CS%HA_CSp)) call HA_accum_FtF(Time_Local, CS%HA_CSp)

call step_MOM_dynamics(forces, CS%p_surf_begin, CS%p_surf_end, dt, &
dt_therm_here, bbl_time_int, CS, &
Expand Down Expand Up @@ -1020,6 +1024,7 @@ subroutine step_MOM(forces_in, fluxes_in, sfc_state, Time_start, time_int_in, CS
ssh(i,j) = CS%ssh_rint(i,j)*I_wt_ssh
CS%ave_ssh_ibc(i,j) = ssh(i,j)
enddo ; enddo
if (associated(CS%HA_CSp)) call HA_accum_FtSSH('ssh', ssh, Time_local, G, CS%HA_CSp)
if (do_dyn) then
call adjust_ssh_for_p_atm(CS%tv, G, GV, US, CS%ave_ssh_ibc, forces%p_surf_SSH, &
CS%calc_rho_for_sea_lev)
Expand Down Expand Up @@ -3247,13 +3252,13 @@ subroutine initialize_MOM(Time, Time_init, param_file, dirs, CS, &
allocate(eta(SZI_(G),SZJ_(G)), source=0.0)
if (CS%use_alt_split) then
call initialize_dyn_split_RK2b(CS%u, CS%v, CS%h, CS%tv, CS%uh, CS%vh, eta, Time, &
G, GV, US, param_file, diag, CS%dyn_split_RK2b_CSp, restart_CSp, &
G, GV, US, param_file, diag, CS%dyn_split_RK2b_CSp, CS%HA_CSp, restart_CSp, &
CS%dt, CS%ADp, CS%CDp, MOM_internal_state, CS%VarMix, CS%MEKE, &
CS%thickness_diffuse_CSp, CS%OBC, CS%update_OBC_CSp, CS%ALE_CSp, CS%set_visc_CSp, &
CS%visc, dirs, CS%ntrunc, CS%pbv, calc_dtbt=calc_dtbt, cont_stencil=CS%cont_stencil)
else
call initialize_dyn_split_RK2(CS%u, CS%v, CS%h, CS%tv, CS%uh, CS%vh, eta, Time, &
G, GV, US, param_file, diag, CS%dyn_split_RK2_CSp, restart_CSp, &
G, GV, US, param_file, diag, CS%dyn_split_RK2_CSp, CS%HA_CSp, restart_CSp, &
CS%dt, CS%ADp, CS%CDp, MOM_internal_state, CS%VarMix, CS%MEKE, &
CS%thickness_diffuse_CSp, CS%OBC, CS%update_OBC_CSp, CS%ALE_CSp, CS%set_visc_CSp, &
CS%visc, dirs, CS%ntrunc, CS%pbv, calc_dtbt=calc_dtbt, cont_stencil=CS%cont_stencil)
Expand Down
16 changes: 15 additions & 1 deletion src/core/MOM_barotropic.F90
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module MOM_barotropic
use MOM_file_parser, only : get_param, log_param, log_version, param_file_type
use MOM_forcing_type, only : mech_forcing
use MOM_grid, only : ocean_grid_type
use MOM_harmonic_analysis, only : HA_accum_FtSSH, harmonic_analysis_CS
use MOM_hor_index, only : hor_index_type
use MOM_io, only : vardesc, var_desc, MOM_read_data, slasher
use MOM_open_boundary, only : ocean_OBC_type, OBC_NONE, open_boundary_query
Expand Down Expand Up @@ -289,6 +290,7 @@ module MOM_barotropic
type(MOM_domain_type), pointer :: BT_Domain => NULL() !< Barotropic MOM domain
type(hor_index_type), pointer :: debug_BT_HI => NULL() !< debugging copy of horizontal index_type
type(SAL_CS), pointer :: SAL_CSp => NULL() !< Control structure for SAL
type(harmonic_analysis_CS), pointer :: HA_CSp => NULL() !< Control structure for harmonic analysis
logical :: module_is_initialized = .false. !< If true, module has been initialized

integer :: isdw !< The lower i-memory limit for the wide halo arrays.
Expand Down Expand Up @@ -2551,6 +2553,13 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce,
eta_out(i,j) = eta_wtd(i,j) * I_sum_wt_eta
enddo ; enddo

! Accumulator is updated at the end of every baroclinic time step.
! Harmonic analysis will not be performed of a field that is not registered.
if (associated(CS%HA_CSp) .and. find_etaav) then
call HA_accum_FtSSH('ubt', ubt, CS%Time, G, CS%HA_CSp)
call HA_accum_FtSSH('vbt', vbt, CS%Time, G, CS%HA_CSp)
endif

if (id_clock_calc_post > 0) call cpu_clock_end(id_clock_calc_post)
if (id_clock_pass_post > 0) call cpu_clock_begin(id_clock_pass_post)
if (G%nonblocking_updates) then
Expand Down Expand Up @@ -4402,7 +4411,7 @@ end subroutine bt_mass_source
!! barotropic calculation and initializes any barotropic fields that have not
!! already been initialized.
subroutine barotropic_init(u, v, h, eta, Time, G, GV, US, param_file, diag, CS, &
restart_CS, calc_dtbt, BT_cont, SAL_CSp)
restart_CS, calc_dtbt, BT_cont, SAL_CSp, HA_CSp)
type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure.
type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
Expand All @@ -4428,6 +4437,8 @@ subroutine barotropic_init(u, v, h, eta, Time, G, GV, US, param_file, diag, CS,
!! barotropic flow.
type(SAL_CS), target, optional :: SAL_CSp !< A pointer to the control structure of the
!! SAL module.
type(harmonic_analysis_CS), target, optional :: HA_CSp !< A pointer to the control structure of the
!! harmonic analysis module

! This include declares and sets the variable "version".
# include "version_variable.h"
Expand Down Expand Up @@ -4489,6 +4500,9 @@ subroutine barotropic_init(u, v, h, eta, Time, G, GV, US, param_file, diag, CS,
if (present(SAL_CSp)) then
CS%SAL_CSp => SAL_CSp
endif
if (present(HA_CSp)) then
CS%HA_CSp => HA_CSp
endif

! Read all relevant parameters and write them to the model log.
call get_param(param_file, mdl, "SPLIT", CS%split, default=.true., do_not_log=.true.)
Expand Down
17 changes: 13 additions & 4 deletions src/core/MOM_dynamics_split_RK2.F90
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ module MOM_dynamics_split_RK2
use MOM_CoriolisAdv, only : CoriolisAdv_init, CoriolisAdv_end
use MOM_debugging, only : check_redundant
use MOM_grid, only : ocean_grid_type
use MOM_harmonic_analysis, only : harmonic_analysis_CS
use MOM_hor_index, only : hor_index_type
use MOM_hor_visc, only : horizontal_viscosity, hor_visc_CS
use MOM_hor_visc, only : hor_visc_init, hor_visc_end
Expand Down Expand Up @@ -242,6 +243,8 @@ module MOM_dynamics_split_RK2
type(SAL_CS) :: SAL_CSp
!> A pointer to the tidal forcing control structure
type(tidal_forcing_CS) :: tides_CSp
!> A pointer to the harmonic analysis control structure
type(harmonic_analysis_CS) :: HA_CSp
!> A pointer to the ALE control structure.
type(ALE_CS), pointer :: ALE_CSp => NULL()

Expand Down Expand Up @@ -482,7 +485,6 @@ subroutine step_MOM_dyn_split_RK2(u_inst, v_inst, h, tv, visc, Time_local, dt, f
call cpu_clock_end(id_clock_pass)
!--- end set up for group halo pass


! PFu = d/dx M(h,T,S)
! pbce = dM/deta
if (CS%begw == 0.0) call enable_averages(dt, Time_local, CS%diag)
Expand Down Expand Up @@ -1308,7 +1310,7 @@ end subroutine remap_dyn_split_RK2_aux_vars
!> This subroutine initializes all of the variables that are used by this
!! dynamic core, including diagnostics and the cpu clocks.
subroutine initialize_dyn_split_RK2(u, v, h, tv, uh, vh, eta, Time, G, GV, US, param_file, &
diag, CS, restart_CS, dt, Accel_diag, Cont_diag, MIS, &
diag, CS, HA_CSp, restart_CS, dt, Accel_diag, Cont_diag, MIS, &
VarMix, MEKE, thickness_diffuse_CSp, &
OBC, update_OBC_CSp, ALE_CSp, set_visc, &
visc, dirs, ntrunc, pbv, calc_dtbt, cont_stencil)
Expand All @@ -1331,6 +1333,8 @@ subroutine initialize_dyn_split_RK2(u, v, h, tv, uh, vh, eta, Time, G, GV, US, p
type(param_file_type), intent(in) :: param_file !< parameter file for parsing
type(diag_ctrl), target, intent(inout) :: diag !< to control diagnostics
type(MOM_dyn_split_RK2_CS), pointer :: CS !< module control structure
type(harmonic_analysis_CS), pointer :: HA_CSp !< A pointer to the control structure of the
!! harmonic analysis module
type(MOM_restart_CS), intent(inout) :: restart_CS !< MOM restart control structure
real, intent(in) :: dt !< time step [T ~> s]
type(accel_diag_ptrs), target, intent(inout) :: Accel_diag !< points to momentum equation terms for
Expand Down Expand Up @@ -1504,7 +1508,12 @@ subroutine initialize_dyn_split_RK2(u, v, h, tv, uh, vh, eta, Time, G, GV, US, p
cont_stencil = continuity_stencil(CS%continuity_CSp)
call CoriolisAdv_init(Time, G, GV, US, param_file, diag, CS%ADp, CS%CoriolisAdv)
if (CS%calculate_SAL) call SAL_init(G, US, param_file, CS%SAL_CSp)
if (CS%use_tides) call tidal_forcing_init(Time, G, US, param_file, CS%tides_CSp)
if (CS%use_tides) then
call tidal_forcing_init(Time, G, US, param_file, CS%tides_CSp, CS%HA_CSp)
HA_CSp => CS%HA_CSp
else
HA_CSp => NULL()
endif
call PressureForce_init(Time, G, GV, US, param_file, diag, CS%PressureForce_CSp, &
CS%SAL_CSp, CS%tides_CSp)
call hor_visc_init(Time, G, GV, US, param_file, diag, CS%hor_visc, ADp=CS%ADp)
Expand Down Expand Up @@ -1538,7 +1547,7 @@ subroutine initialize_dyn_split_RK2(u, v, h, tv, uh, vh, eta, Time, G, GV, US, p
do j=js,je ; do i=is,ie ; eta(i,j) = CS%eta(i,j) ; enddo ; enddo

call barotropic_init(u, v, h, CS%eta, Time, G, GV, US, param_file, diag, &
CS%barotropic_CSp, restart_CS, calc_dtbt, CS%BT_cont, CS%SAL_CSp)
CS%barotropic_CSp, restart_CS, calc_dtbt, CS%BT_cont, CS%SAL_CSp, CS%HA_CSp)

if (.not. query_initialized(CS%diffu, "diffu", restart_CS) .or. &
.not. query_initialized(CS%diffv, "diffv", restart_CS)) then
Expand Down
16 changes: 13 additions & 3 deletions src/core/MOM_dynamics_split_RK2b.F90
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ module MOM_dynamics_split_RK2b
use MOM_CoriolisAdv, only : CoriolisAdv_init, CoriolisAdv_end
use MOM_debugging, only : check_redundant
use MOM_grid, only : ocean_grid_type
use MOM_harmonic_analysis, only : harmonic_analysis_CS
use MOM_hor_index, only : hor_index_type
use MOM_hor_visc, only : horizontal_viscosity, hor_visc_CS
use MOM_hor_visc, only : hor_visc_init, hor_visc_end
Expand Down Expand Up @@ -239,6 +240,8 @@ module MOM_dynamics_split_RK2b
type(SAL_CS) :: SAL_CSp
!> A pointer to the tidal forcing control structure
type(tidal_forcing_CS) :: tides_CSp
!> A pointer to the harmonic analysis control structure
type(harmonic_analysis_CS) :: HA_CSp
!> A pointer to the ALE control structure.
type(ALE_CS), pointer :: ALE_CSp => NULL()

Expand Down Expand Up @@ -1233,7 +1236,7 @@ end subroutine remap_dyn_split_RK2b_aux_vars
!> This subroutine initializes all of the variables that are used by this
!! dynamic core, including diagnostics and the cpu clocks.
subroutine initialize_dyn_split_RK2b(u, v, h, tv, uh, vh, eta, Time, G, GV, US, param_file, &
diag, CS, restart_CS, dt, Accel_diag, Cont_diag, MIS, &
diag, CS, HA_CSp, restart_CS, dt, Accel_diag, Cont_diag, MIS, &
VarMix, MEKE, thickness_diffuse_CSp, &
OBC, update_OBC_CSp, ALE_CSp, set_visc, &
visc, dirs, ntrunc, pbv, calc_dtbt, cont_stencil)
Expand All @@ -1256,6 +1259,8 @@ subroutine initialize_dyn_split_RK2b(u, v, h, tv, uh, vh, eta, Time, G, GV, US,
type(param_file_type), intent(in) :: param_file !< parameter file for parsing
type(diag_ctrl), target, intent(inout) :: diag !< to control diagnostics
type(MOM_dyn_split_RK2b_CS), pointer :: CS !< module control structure
type(harmonic_analysis_CS), pointer :: HA_CSp !< A pointer to the control structure of the
!! harmonic analysis module
type(MOM_restart_CS), intent(inout) :: restart_CS !< MOM restart control structure
real, intent(in) :: dt !< time step [T ~> s]
type(accel_diag_ptrs), target, intent(inout) :: Accel_diag !< points to momentum equation terms for
Expand Down Expand Up @@ -1415,7 +1420,12 @@ subroutine initialize_dyn_split_RK2b(u, v, h, tv, uh, vh, eta, Time, G, GV, US,
cont_stencil = continuity_stencil(CS%continuity_CSp)
call CoriolisAdv_init(Time, G, GV, US, param_file, diag, CS%ADp, CS%CoriolisAdv)
if (CS%calculate_SAL) call SAL_init(G, US, param_file, CS%SAL_CSp)
if (CS%use_tides) call tidal_forcing_init(Time, G, US, param_file, CS%tides_CSp)
if (CS%use_tides) then
call tidal_forcing_init(Time, G, US, param_file, CS%tides_CSp, CS%HA_CSp)
HA_CSp => CS%HA_CSp
else
HA_CSp => NULL()
endif
call PressureForce_init(Time, G, GV, US, param_file, diag, CS%PressureForce_CSp, &
CS%SAL_CSp, CS%tides_CSp)
call hor_visc_init(Time, G, GV, US, param_file, diag, CS%hor_visc, ADp=CS%ADp)
Expand Down Expand Up @@ -1453,7 +1463,7 @@ subroutine initialize_dyn_split_RK2b(u, v, h, tv, uh, vh, eta, Time, G, GV, US,

call barotropic_init(u, v, h, CS%eta, Time, G, GV, US, param_file, diag, &
CS%barotropic_CSp, restart_CS, calc_dtbt, CS%BT_cont, &
CS%SAL_CSp)
CS%SAL_CSp, CS%HA_CSp)

flux_units = get_flux_units(GV)
thickness_units = get_thickness_units(GV)
Expand Down
Loading

0 comments on commit 75db4be

Please sign in to comment.