Skip to content

Commit

Permalink
Merge branch 'dev/gfdl' into rescale_predict_MEKE
Browse files Browse the repository at this point in the history
  • Loading branch information
theresa-morrison authored Jan 21, 2025
2 parents 30df138 + 83efb99 commit bf35f31
Show file tree
Hide file tree
Showing 34 changed files with 1,255 additions and 564 deletions.
4 changes: 2 additions & 2 deletions config_src/external/drifters/MOM_particles.F90
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ subroutine particles_init(parts, Grid, Time, dt, u, v, h)
end subroutine particles_init

!> The main driver the steps updates particles
subroutine particles_run(parts, time, uo, vo, ho, tv, use_uh, stagger)
subroutine particles_run(parts, time, uo, vo, ho, tv, dt_adv, use_uh)
! Arguments
type(particles), pointer :: parts !< Container for all types and memory
type(time_type), intent(in) :: time !< Model time
Expand All @@ -40,8 +40,8 @@ subroutine particles_run(parts, time, uo, vo, ho, tv, use_uh, stagger)
!! that are used to advect tracers [H L2 ~> m3 or kg]
real, dimension(:,:,:), intent(in) :: ho !< Ocean layer thickness [H ~> m or kg m-2]
type(thermo_var_ptrs), intent(in) :: tv !< structure containing pointers to available thermodynamic fields
real, intent(in) :: dt_adv !< timestep for advecting particles [s]
logical :: use_uh !< Flag for whether u and v are weighted by thickness
integer, optional, intent(in) :: stagger !< Flag for whether velocities are staggered

end subroutine particles_run

Expand Down
26 changes: 18 additions & 8 deletions src/core/MOM.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,18 @@ subroutine step_MOM_dynamics(forces, p_surf_begin, p_surf_end, dt, dt_thermo, &

endif ! -------------------------------------------------- end SPLIT

if (CS%use_particles .and. CS%do_dynamics .and. (.not. CS%use_uh_particles)) then
if (CS%thickness_diffuse_first) call MOM_error(WARNING,"particles_run: "//&
"Thickness_diffuse_first is true and use_uh_particles is false. "//&
"This is usually a bad combination.")
!Run particles using unweighted velocity
call particles_run(CS%particles, Time_local, CS%u, CS%v, CS%h, &
CS%tv, dt, CS%use_uh_particles)
call particles_to_z_space(CS%particles, h)
endif



! Update the model's current to reflect wind-wave growth
if (Waves%Stokes_DDT .and. (.not.Waves%Passive_Stokes_DDT)) then
do J=jsq,jeq ; do i=is,ie
Expand Down Expand Up @@ -1368,23 +1380,21 @@ subroutine step_MOM_dynamics(forces, p_surf_begin, p_surf_end, dt, dt_thermo, &
endif
call disable_averaging(CS%diag)

! Advance the dynamics time by dt.
CS%t_dyn_rel_adv = CS%t_dyn_rel_adv + dt

if (CS%use_particles .and. CS%do_dynamics .and. CS%use_uh_particles) then
!Run particles using thickness-weighted velocity
call particles_run(CS%particles, Time_local, CS%uhtr, CS%vhtr, CS%h, &
CS%tv, CS%use_uh_particles)
elseif (CS%use_particles .and. CS%do_dynamics) then
!Run particles using unweighted velocity
call particles_run(CS%particles, Time_local, CS%u, CS%v, CS%h, &
CS%tv, CS%use_uh_particles)
CS%tv, CS%t_dyn_rel_adv, CS%use_uh_particles)
endif


! Advance the dynamics time by dt.
CS%t_dyn_rel_adv = CS%t_dyn_rel_adv + dt
CS%n_dyn_steps_in_adv = CS%n_dyn_steps_in_adv + 1
if (CS%alternate_first_direction) then
call set_first_direction(G, MODULO(G%first_direction+1,2))
CS%first_dir_restart = real(G%first_direction)
elseif (CS%use_particles .and. CS%do_dynamics .and. (.not.CS%use_uh_particles)) then
call particles_to_k_space(CS%particles, h)
endif
CS%t_dyn_rel_thermo = CS%t_dyn_rel_thermo + dt
if (abs(CS%t_dyn_rel_thermo) < 1e-6*dt) CS%t_dyn_rel_thermo = 0.0
Expand Down
322 changes: 198 additions & 124 deletions src/core/MOM_PressureForce_FV.F90

Large diffs are not rendered by default.

96 changes: 30 additions & 66 deletions src/core/MOM_barotropic.F90
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ module MOM_barotropic
use MOM_restart, only : query_initialized, MOM_restart_CS
use MOM_self_attr_load, only : scalar_SAL_sensitivity
use MOM_self_attr_load, only : SAL_CS
use MOM_streaming_filter, only : Filt_register, Filt_accum, Filter_CS
use MOM_tidal_forcing, only : tidal_frequency
use MOM_streaming_filter, only : Filt_register, Filt_init, Filt_accum, Filter_CS
use MOM_time_manager, only : time_type, real_to_time, operator(+), operator(-)
use MOM_unit_scaling, only : unit_scale_type
use MOM_variables, only : BT_cont_type, alloc_bt_cont_type
Expand Down Expand Up @@ -250,10 +249,8 @@ module MOM_barotropic
logical :: linearized_BT_PV !< If true, the PV and interface thicknesses used
!! in the barotropic Coriolis calculation is time
!! invariant and linearized.
logical :: use_filter_m2 !< If true, apply streaming band-pass filter for detecting
!! instantaneous tidal signals.
logical :: use_filter_k1 !< If true, apply streaming band-pass filter for detecting
!! instantaneous tidal signals.
logical :: use_filter !< If true, use streaming band-pass filter to detect the
!! instantaneous tidal signals in the simulation.
logical :: use_wide_halos !< If true, use wide halos and march in during the
!! barotropic time stepping for efficiency.
logical :: clip_velocity !< If true, limit any velocity components that are
Expand Down Expand Up @@ -297,10 +294,8 @@ module MOM_barotropic
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
type(Filter_CS) :: Filt_CS_um2, & !< Control structures for the M2 streaming filter
Filt_CS_vm2, & !< Control structures for the M2 streaming filter
Filt_CS_uk1, & !< Control structures for the K1 streaming filter
Filt_CS_vk1 !< Control structures for the K1 streaming filter
type(Filter_CS) :: Filt_CS_u, & !< Control structures for the streaming band-pass filter of ubt
Filt_CS_v !< Control structures for the streaming band-pass filter of vbt
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 @@ -608,8 +603,8 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce,
DCor_v, & ! An averaged total thickness at v points [H ~> m or kg m-2].
Datv ! Basin depth at v-velocity grid points times the x-grid
! spacing [H L ~> m2 or kg m-1].
real, dimension(:,:), pointer :: um2, uk1, vm2, vk1
! M2 and K1 velocities from the output of streaming filters [m s-1]
real, dimension(:,:,:), pointer :: ufilt, vfilt
! Filtered velocities from the output of streaming filters [m s-1]
real, target, dimension(SZIW_(CS),SZJW_(CS)) :: &
eta, & ! The barotropic free surface height anomaly or column mass
! anomaly [H ~> m or kg m-2]
Expand Down Expand Up @@ -1598,15 +1593,11 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce,
endif ; enddo ; enddo
endif

! Here is an example of how the filter equations are time stepped to determine the M2 and K1 velocities.
! The filters are initialized and registered in subroutine barotropic_init.
if (CS%use_filter_m2) then
call Filt_accum(ubt, um2, CS%Time, US, CS%Filt_CS_um2)
call Filt_accum(vbt, vm2, CS%Time, US, CS%Filt_CS_vm2)
endif
if (CS%use_filter_k1) then
call Filt_accum(ubt, uk1, CS%Time, US, CS%Filt_CS_uk1)
call Filt_accum(vbt, vk1, CS%Time, US, CS%Filt_CS_vk1)
! Note that the filtered velocities are only updated during the current predictor step,
! and are calculated using the barotropic velocity from the previous correction step.
if (CS%use_filter) then
call Filt_accum(ubt, ufilt, CS%Time, US, CS%Filt_CS_u)
call Filt_accum(vbt, vfilt, CS%Time, US, CS%Filt_CS_v)
endif

! Zero out the arrays for various time-averaged quantities.
Expand Down Expand Up @@ -4979,6 +4970,12 @@ subroutine barotropic_init(u, v, h, eta, Time, G, GV, US, param_file, diag, CS,
endif ! len_trim(wave_drag_file) > 0
endif ! CS%linear_wave_drag

! Initialize streaming band-pass filters
if (CS%use_filter) then
call Filt_init(param_file, US, CS%Filt_CS_u, restart_CS)
call Filt_init(param_file, US, CS%Filt_CS_v, restart_CS)
endif

CS%dtbt_fraction = 0.98 ; if (dtbt_input < 0.0) CS%dtbt_fraction = -dtbt_input

dtbt_tmp = -1.0
Expand Down Expand Up @@ -5263,9 +5260,8 @@ subroutine register_barotropic_restarts(HI, GV, US, param_file, CS, restart_CS)
! Local variables
type(vardesc) :: vd(3)
character(len=40) :: mdl = "MOM_barotropic" ! This module's name.
integer :: n_filters !< Number of streaming band-pass filters to be used in the simulation.
integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
real :: am2, ak1 !< Bandwidth parameters of the M2 and K1 streaming filters [nondim]
real :: om2, ok1 !< Target frequencies of the M2 and K1 streaming filters [rad T-1 ~> rad s-1]

isd = HI%isd ; ied = HI%ied ; jsd = HI%jsd ; jed = HI%jed
IsdB = HI%IsdB ; IedB = HI%IedB ; JsdB = HI%JsdB ; JedB = HI%JedB
Expand All @@ -5278,33 +5274,6 @@ subroutine register_barotropic_restarts(HI, GV, US, param_file, CS, restart_CS)
"sum(u dh_dt) while also correcting for truncation errors.", &
default=.false., do_not_log=.true.)

call get_param(param_file, mdl, "STREAMING_FILTER_M2", CS%use_filter_m2, &
"If true, turn on streaming band-pass filter for detecting "//&
"instantaneous tidal signals.", default=.false.)
call get_param(param_file, mdl, "STREAMING_FILTER_K1", CS%use_filter_k1, &
"If true, turn on streaming band-pass filter for detecting "//&
"instantaneous tidal signals.", default=.false.)
call get_param(param_file, mdl, "FILTER_ALPHA_M2", am2, &
"Bandwidth parameter of the streaming filter targeting the M2 frequency. "//&
"Must be positive. To turn off filtering, set FILTER_ALPHA_M2 <= 0.0.", &
default=0.0, units="nondim", do_not_log=.not.CS%use_filter_m2)
call get_param(param_file, mdl, "FILTER_ALPHA_K1", ak1, &
"Bandwidth parameter of the streaming filter targeting the K1 frequency. "//&
"Must be positive. To turn off filtering, set FILTER_ALPHA_K1 <= 0.0.", &
default=0.0, units="nondim", do_not_log=.not.CS%use_filter_k1)
call get_param(param_file, mdl, "TIDE_M2_FREQ", om2, &
"Frequency of the M2 tidal constituent. "//&
"This is only used if TIDES and TIDE_M2"// &
" are true, or if OBC_TIDE_N_CONSTITUENTS > 0 and M2"// &
" is in OBC_TIDE_CONSTITUENTS.", units="rad s-1", default=tidal_frequency("M2"), &
scale=US%T_to_s, do_not_log=.true.)
call get_param(param_file, mdl, "TIDE_K1_FREQ", ok1, &
"Frequency of the K1 tidal constituent. "//&
"This is only used if TIDES and TIDE_K1"// &
" are true, or if OBC_TIDE_N_CONSTITUENTS > 0 and K1"// &
" is in OBC_TIDE_CONSTITUENTS.", units="rad s-1", default=tidal_frequency("K1"), &
scale=US%T_to_s, do_not_log=.true.)

ALLOC_(CS%ubtav(IsdB:IedB,jsd:jed)) ; CS%ubtav(:,:) = 0.0
ALLOC_(CS%vbtav(isd:ied,JsdB:JedB)) ; CS%vbtav(:,:) = 0.0
if (CS%gradual_BT_ICs) then
Expand Down Expand Up @@ -5333,22 +5302,17 @@ subroutine register_barotropic_restarts(HI, GV, US, param_file, CS, restart_CS)
call register_restart_field(CS%dtbt, "DTBT", .false., restart_CS, &
longname="Barotropic timestep", units="seconds", conversion=US%T_to_s)

! Initialize and register streaming filters
if (CS%use_filter_m2) then
if (am2 > 0.0 .and. om2 > 0.0) then
call Filt_register(am2, om2, 'u', HI, CS%Filt_CS_um2)
call Filt_register(am2, om2, 'v', HI, CS%Filt_CS_vm2)
else
CS%use_filter_m2 = .false.
endif
endif
if (CS%use_filter_k1) then
if (ak1 > 0.0 .and. ok1 > 0.0) then
call Filt_register(ak1, ok1, 'u', HI, CS%Filt_CS_uk1)
call Filt_register(ak1, ok1, 'v', HI, CS%Filt_CS_vk1)
else
CS%use_filter_k1 = .false.
endif
! Initialize and register streaming band-pass filters
call get_param(param_file, mdl, "USE_FILTER", CS%use_filter, &
"If true, use streaming band-pass filters to detect the "//&
"instantaneous tidal signals in the simulation.", default=.false.)
call get_param(param_file, mdl, "N_FILTERS", n_filters, &
"Number of streaming band-pass filters to be used in the simulation.", &
default=0, do_not_log=.not.CS%use_filter)
if (n_filters<=0) CS%use_filter = .false.
if (CS%use_filter) then
call Filt_register(n_filters, 'ubt', 'u', HI, CS%Filt_CS_u, restart_CS)
call Filt_register(n_filters, 'vbt', 'v', HI, CS%Filt_CS_v, restart_CS)
endif

end subroutine register_barotropic_restarts
Expand Down
16 changes: 11 additions & 5 deletions src/core/MOM_density_integrals.F90
Original file line number Diff line number Diff line change
Expand Up @@ -2001,7 +2001,7 @@ end subroutine diagnose_mass_weight_p

!> Find the depth at which the reconstructed pressure matches P_tgt
subroutine find_depth_of_pressure_in_cell(T_t, T_b, S_t, S_b, z_t, z_b, P_t, P_tgt, &
rho_ref, G_e, EOS, US, P_b, z_out, z_tol)
rho_ref, G_e, EOS, US, P_b, z_out, z_tol, frac_dp_bugfix)
real, intent(in) :: T_t !< Potential temperature at the cell top [C ~> degC]
real, intent(in) :: T_b !< Potential temperature at the cell bottom [C ~> degC]
real, intent(in) :: S_t !< Salinity at the cell top [S ~> ppt]
Expand All @@ -2020,6 +2020,7 @@ subroutine find_depth_of_pressure_in_cell(T_t, T_b, S_t, S_b, z_t, z_b, P_t, P_t
real, intent(out) :: P_b !< Pressure at the bottom of the cell [R L2 T-2 ~> Pa]
real, intent(out) :: z_out !< Absolute depth at which anomalous pressure = p_tgt [Z ~> m]
real, intent(in) :: z_tol !< The tolerance in finding z_out [Z ~> m]
logical, intent(in) :: frac_dp_bugfix !< If true, use bugfix in frac_dp_at_pos

! Local variables
real :: dp ! Pressure thickness of the layer [R L2 T-2 ~> Pa]
Expand All @@ -2032,7 +2033,7 @@ subroutine find_depth_of_pressure_in_cell(T_t, T_b, S_t, S_b, z_t, z_b, P_t, P_t
GxRho = G_e * rho_ref

! Anomalous pressure difference across whole cell
dp = frac_dp_at_pos(T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, G_e, 1.0, EOS)
dp = frac_dp_at_pos(T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, G_e, 1.0, EOS, frac_dp_bugfix)

P_b = P_t + dp ! Anomalous pressure at bottom of cell

Expand Down Expand Up @@ -2063,7 +2064,7 @@ subroutine find_depth_of_pressure_in_cell(T_t, T_b, S_t, S_b, z_t, z_b, P_t, P_t
call MOM_error(FATAL, 'find_depth_of_pressure_in_cell completes too many iterations: '//msg)
endif
z_out = z_t + ( z_b - z_t ) * F_guess
Pa = frac_dp_at_pos(T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, G_e, F_guess, EOS) - ( P_tgt - P_t )
Pa = frac_dp_at_pos(T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, G_e, F_guess, EOS, frac_dp_bugfix) - ( P_tgt - P_t )

if (Pa<Pa_left) then
write(msg,*) Pa_left,Pa,Pa_right,P_t-P_tgt,P_b-P_tgt
Expand Down Expand Up @@ -2119,7 +2120,7 @@ end subroutine avg_specific_vol

!> Returns change in anomalous pressure change from top to non-dimensional
!! position pos between z_t and z_b [R L2 T-2 ~> Pa]
real function frac_dp_at_pos(T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, G_e, pos, EOS)
real function frac_dp_at_pos(T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, G_e, pos, EOS, frac_dp_bugfix)
real, intent(in) :: T_t !< Potential temperature at the cell top [C ~> degC]
real, intent(in) :: T_b !< Potential temperature at the cell bottom [C ~> degC]
real, intent(in) :: S_t !< Salinity at the cell top [S ~> ppt]
Expand All @@ -2131,6 +2132,7 @@ real function frac_dp_at_pos(T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, G_e, pos, EO
real, intent(in) :: G_e !< The Earth's gravitational acceleration [L2 Z-1 T-2 ~> m s-2]
real, intent(in) :: pos !< The fractional vertical position, 0 to 1 [nondim]
type(EOS_type), intent(in) :: EOS !< Equation of state structure
logical, intent(in) :: frac_dp_bugfix !< If true, use bugfix in frac_dp_at_pos

! Local variables
real, parameter :: C1_90 = 1.0/90.0 ! A rational constant [nondim]
Expand All @@ -2150,7 +2152,11 @@ real function frac_dp_at_pos(T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, G_e, pos, EO
! Salinity and temperature points are linearly interpolated
S5(n) = top_weight * S_t + bottom_weight * S_b
T5(n) = top_weight * T_t + bottom_weight * T_b
p5(n) = ( top_weight * z_t + bottom_weight * z_b ) * ( G_e * rho_ref )
if (frac_dp_bugfix) then
p5(n) = (-1) * ( top_weight * z_t + bottom_weight * z_b ) * ( G_e * rho_ref )
else
p5(n) = ( top_weight * z_t + bottom_weight * z_b ) * ( G_e * rho_ref )
endif !bugfix
enddo
call calculate_density(T5, S5, p5, rho5, EOS)
rho5(:) = rho5(:) !- rho_ref ! Work with anomalies relative to rho_ref
Expand Down
2 changes: 1 addition & 1 deletion src/core/MOM_dynamics_split_RK2.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1506,7 +1506,7 @@ subroutine initialize_dyn_split_RK2(u, v, h, tv, uh, vh, eta, Time, G, GV, US, p
call continuity_init(Time, G, GV, US, param_file, diag, CS%continuity_CSp)
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%calculate_SAL) call SAL_init(G, GV, US, param_file, CS%SAL_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
Expand Down
2 changes: 1 addition & 1 deletion src/core/MOM_dynamics_split_RK2b.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1419,7 +1419,7 @@ subroutine initialize_dyn_split_RK2b(u, v, h, tv, uh, vh, eta, Time, G, GV, US,
call continuity_init(Time, G, GV, US, param_file, diag, CS%continuity_CSp)
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%calculate_SAL) call SAL_init(G, GV, US, param_file, CS%SAL_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
Expand Down
2 changes: 1 addition & 1 deletion src/core/MOM_dynamics_unsplit.F90
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ subroutine initialize_dyn_unsplit(u, v, h, Time, G, GV, US, param_file, diag, CS
call continuity_init(Time, G, GV, US, param_file, diag, CS%continuity_CSp)
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%calculate_SAL) call SAL_init(G, GV, US, param_file, CS%SAL_CSp)
if (CS%use_tides) call tidal_forcing_init(Time, G, US, param_file, CS%tides_CSp)
call PressureForce_init(Time, G, GV, US, param_file, diag, CS%PressureForce_CSp, &
CS%SAL_CSp, CS%tides_CSp)
Expand Down
2 changes: 1 addition & 1 deletion src/core/MOM_dynamics_unsplit_RK2.F90
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ subroutine initialize_dyn_unsplit_RK2(u, v, h, Time, G, GV, US, param_file, diag
call continuity_init(Time, G, GV, US, param_file, diag, CS%continuity_CSp)
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%calculate_SAL) call SAL_init(G, GV, US, param_file, CS%SAL_CSp)
if (CS%use_tides) call tidal_forcing_init(Time, G, US, param_file, CS%tides_CSp)
call PressureForce_init(Time, G, GV, US, param_file, diag, CS%PressureForce_CSp, &
CS%SAL_CSp, CS%tides_CSp)
Expand Down
Loading

0 comments on commit bf35f31

Please sign in to comment.