Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into SPEAR_ECDA
Browse files Browse the repository at this point in the history
  • Loading branch information
MJHarrison-GFDL committed Jun 28, 2021
2 parents eca5fd5 + e60e5ba commit 5c0e8db
Show file tree
Hide file tree
Showing 81 changed files with 3,295 additions and 1,810 deletions.
4 changes: 4 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ setup:
- test -d MOM6-examples/src/LM3 || make -f MRS/Makefile.clone clone_gfdl -s
- make -f MRS/Makefile.clone MOM6-examples/.datasets -s
- env > gitlab_session.log
# Show hashes for final setup
- git show --oneline
- git submodule status
- (cd MOM6-examples && git submodule status --recursive src)
# Cache everything under tests to unpack for each subsequent stage
- cd ../ ; time tar zcf $CACHE_DIR/tests_$CI_PIPELINE_ID.tgz tests

Expand Down
3 changes: 2 additions & 1 deletion .testing/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ endif
# Rules

.PHONY: all build.regressions
all: $(foreach b,$(BUILDS),build/$(b)/MOM6)
all: $(foreach b,$(BUILDS),build/$(b)/MOM6) $(VENV_PATH)
build.regressions: $(foreach b,symmetric target,build/$(b)/MOM6)

# Executable
Expand Down Expand Up @@ -361,6 +361,7 @@ check_mom6_api_mct: build/mct/mom_ocean_model_mct.o
work/local-env:
python3 -m venv $@
. $@/bin/activate \
&& python3 -m pip install --upgrade pip \
&& pip3 install wheel \
&& pip3 install cython \
&& pip3 install numpy \
Expand Down
37 changes: 34 additions & 3 deletions ac/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ AS_IF([test "x$with_driver" != "x"],
# used to configure a header based on a template.
#AC_CONFIG_HEADERS(["$MEM_LAYOUT/MOM_memory.h"])

# Select the model framework (default: FMS1)
# NOTE: We can phase this out after the FMS1 I/O has been removed from FMS and
# replace with a detection test. For now, it is a user-defined switch.
MODEL_FRAMEWORK=${srcdir}/config_src/infra/FMS1
AC_ARG_WITH([framework],
AS_HELP_STRING([--with-framework=fms1|fms2], [Select the model framework]))
AS_CASE([with_framework],
[fms1], [MODEL_FRAMEWORK=${srcdir}/config_src/infra/FMS1],
[fms2], [MODEL_FRAMEWORK=${srcdir}/config_src/infra/FMS2],
[MODEL_FRAMEWORK=${srcdir}/config_src/infra/FMS1]
)


# Explicitly assume free-form Fortran
AC_LANG(Fortran)
Expand Down Expand Up @@ -192,6 +204,22 @@ AX_FC_CHECK_LIB([FMS], [fms_init], [fms_mod],
)


# Verify that FMS is at least 2019.01.02
# NOTE: 2019.01.02 introduced two changes:
# - diag_axis_init supports an optional domain_position argument
# - position values NORTH, EAST, CENTER were added to diag_axis_mod
# For our versioning test, we check the second feature.
AC_MSG_CHECKING([if diag_axis_mod supports domain positions])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([], [use diag_axis_mod, only: NORTH, EAST, CENTER])],
[AC_MSG_RESULT([yes])],
[
AC_MSG_RESULT([no])
AC_MSG_ERROR([diag_axis_mod in MOM6 requires FMS 2019.01.02 or newer.])
]
)


# Search for mkmf build tools
AC_PATH_PROG([LIST_PATHS], [list_paths])
AS_IF([test -z "$LIST_PATHS"], [
Expand All @@ -216,11 +244,14 @@ AS_IF([test -z "$MKMF"], [
AC_CONFIG_COMMANDS([path_names],
[list_paths -l \
${srcdir}/src \
${srcdir}/config_src/infra/FMS1 \
${MODEL_FRAMEWORK} \
${srcdir}/config_src/ext* \
${DRIVER_DIR} \
${MEM_LAYOUT}
], [MEM_LAYOUT=$MEM_LAYOUT DRIVER_DIR=$DRIVER_DIR])
${MEM_LAYOUT}],
[MODEL_FRAMEWORK=$MODEL_FRAMEWORK
MEM_LAYOUT=$MEM_LAYOUT
DRIVER_DIR=$DRIVER_DIR]
)


AC_CONFIG_COMMANDS([Makefile.mkmf],
Expand Down
49 changes: 29 additions & 20 deletions config_src/drivers/FMS_cap/MOM_surface_forcing_gfdl.F90
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ module MOM_surface_forcing_gfdl
use MOM_grid, only : ocean_grid_type
use MOM_interpolate, only : init_external_field, time_interp_external
use MOM_interpolate, only : time_interp_external_init
use MOM_io, only : slasher, write_version_number, MOM_read_data, stdout
use MOM_io, only : slasher, write_version_number, MOM_read_data
use MOM_io, only : stdout_if_root
use MOM_restart, only : register_restart_field, restart_init, MOM_restart_CS
use MOM_restart, only : restart_init_end, save_restart, restore_state
use MOM_string_functions, only : uppercase
Expand Down Expand Up @@ -110,6 +111,8 @@ module MOM_surface_forcing_gfdl
logical :: restore_temp !< If true, the coupled MOM driver adds a term to restore sea
!! surface temperature to a specified value.
real :: Flux_const !< Piston velocity for surface restoring [Z T-1 ~> m s-1]
real :: Flux_const_salt !< Piston velocity for surface salt restoring [Z T-1 ~> m s-1]
real :: Flux_const_temp !< Piston velocity for surface temp restoring [Z T-1 ~> m s-1]
logical :: salt_restore_as_sflux !< If true, SSS restore as salt flux instead of water flux
logical :: adjust_net_srestore_to_zero !< Adjust srestore to zero (for both salt_flux or vprec)
logical :: adjust_net_srestore_by_scaling !< Adjust srestore w/o moving zero contour
Expand Down Expand Up @@ -290,22 +293,18 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,

call safe_alloc_ptr(fluxes%salt_flux,isd,ied,jsd,jed)
call safe_alloc_ptr(fluxes%salt_flux_in,isd,ied,jsd,jed)
call safe_alloc_ptr(fluxes%salt_flux_added,isd,ied,jsd,jed)

call safe_alloc_ptr(fluxes%TKE_tidal,isd,ied,jsd,jed)
call safe_alloc_ptr(fluxes%ustar_tidal,isd,ied,jsd,jed)

if (CS%allow_flux_adjustments) then
call safe_alloc_ptr(fluxes%heat_added,isd,ied,jsd,jed)
call safe_alloc_ptr(fluxes%salt_flux_added,isd,ied,jsd,jed)
endif
call safe_alloc_ptr(fluxes%heat_added,isd,ied,jsd,jed)
call safe_alloc_ptr(fluxes%salt_flux_added,isd,ied,jsd,jed)

do j=js-2,je+2 ; do i=is-2,ie+2
fluxes%TKE_tidal(i,j) = CS%TKE_tidal(i,j)
fluxes%ustar_tidal(i,j) = CS%ustar_tidal(i,j)
enddo ; enddo

if (CS%restore_temp) call safe_alloc_ptr(fluxes%heat_added,isd,ied,jsd,jed)

endif ! endif for allocation and initialization

Expand Down Expand Up @@ -335,10 +334,8 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
fluxes%fluxes_used = .false.
fluxes%dt_buoy_accum = US%s_to_T*valid_time

if (CS%allow_flux_adjustments) then
fluxes%heat_added(:,:) = 0.0
fluxes%salt_flux_added(:,:) = 0.0
endif
fluxes%heat_added(:,:) = 0.0
fluxes%salt_flux_added(:,:) = 0.0

do j=js,je ; do i=is,ie
fluxes%salt_flux(i,j) = 0.0
Expand All @@ -359,7 +356,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
do j=js,je ; do i=is,ie
delta_sss = data_restore(i,j)- sfc_state%SSS(i,j)
delta_sss = sign(1.0,delta_sss)*min(abs(delta_sss),CS%max_delta_srestore)
fluxes%salt_flux(i,j) = 1.e-3*G%mask2dT(i,j) * (CS%Rho0*CS%Flux_const)* &
fluxes%salt_flux(i,j) = 1.e-3*G%mask2dT(i,j) * (CS%Rho0*CS%Flux_const_salt)* &
(CS%basin_mask(i,j)*open_ocn_mask(i,j)*CS%srestore_mask(i,j)) *delta_sss ! R Z T-1 ~> kg Salt m-2 s-1
enddo ; enddo
if (CS%adjust_net_srestore_to_zero) then
Expand All @@ -369,9 +366,10 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
fluxes%saltFluxGlobalAdj = 0.
else
work_sum(is:ie,js:je) = US%L_to_m**2*US%RZ_T_to_kg_m2s * &
G%areaT(is:ie,js:je)*fluxes%salt_flux(is:ie,js:je)
G%areaT(is:ie,js:je)*fluxes%salt_flux(is:ie,js:je) * G%mask2dT(is:ie,js:je)
fluxes%saltFluxGlobalAdj = reproducing_sum(work_sum(:,:), isr,ier, jsr,jer)/CS%area_surf
fluxes%salt_flux(is:ie,js:je) = fluxes%salt_flux(is:ie,js:je) - kg_m2_s_conversion * fluxes%saltFluxGlobalAdj
fluxes%salt_flux(is:ie,js:je) = fluxes%salt_flux(is:ie,js:je) - &
kg_m2_s_conversion * fluxes%saltFluxGlobalAdj * G%mask2dT(is:ie,js:je)
endif
endif
fluxes%salt_flux_added(is:ie,js:je) = fluxes%salt_flux(is:ie,js:je) ! Diagnostic
Expand All @@ -381,7 +379,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
delta_sss = sfc_state%SSS(i,j) - data_restore(i,j)
delta_sss = sign(1.0,delta_sss)*min(abs(delta_sss),CS%max_delta_srestore)
fluxes%vprec(i,j) = (CS%basin_mask(i,j)*open_ocn_mask(i,j)*CS%srestore_mask(i,j))* &
(CS%Rho0*CS%Flux_const) * &
(CS%Rho0*CS%Flux_const_salt) * &
delta_sss / (0.5*(sfc_state%SSS(i,j) + data_restore(i,j)))
endif
enddo ; enddo
Expand Down Expand Up @@ -409,7 +407,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
delta_sst = data_restore(i,j)- sfc_state%SST(i,j)
delta_sst = sign(1.0,delta_sst)*min(abs(delta_sst),CS%max_delta_trestore)
fluxes%heat_added(i,j) = G%mask2dT(i,j) * CS%trestore_mask(i,j) * &
rhoXcp * delta_sst * CS%Flux_const ! W m-2
rhoXcp * delta_sst * CS%Flux_const_temp ! W m-2
enddo ; enddo
endif

Expand Down Expand Up @@ -1111,7 +1109,7 @@ subroutine apply_flux_adjustments(G, US, CS, Time, fluxes)
type(forcing), intent(inout) :: fluxes !< Surface fluxes structure

! Local variables
real, dimension(SZI_(G),SZJ_(G)) :: temp_at_h ! Various fluxes at h points [W m-2] or [kg m-2 s-1]
real, dimension(G%isc:G%iec,G%jsc:G%jec) :: temp_at_h ! Various fluxes at h points [W m-2] or [kg m-2 s-1]

integer :: isc, iec, jsc, jec, i, j
logical :: overrode_h
Expand Down Expand Up @@ -1251,6 +1249,7 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, wind_stagger)
character(len=48) :: flnam
character(len=240) :: basin_file
integer :: i, j, isd, ied, jsd, jed
real :: unscaled_fluxconst

isd = G%isd ; ied = G%ied ; jsd = G%jsd ; jed = G%jed

Expand Down Expand Up @@ -1374,9 +1373,14 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, wind_stagger)
call get_param(param_file, mdl, "FLUXCONST", CS%Flux_const, &
"The constant that relates the restoring surface fluxes to the relative "//&
"surface anomalies (akin to a piston velocity). Note the non-MKS units.", &
default=0.0, units="m day-1", scale=US%m_to_Z*US%T_to_s)
default=0.0, units="m day-1", scale=US%m_to_Z*US%T_to_s,unscaled=unscaled_fluxconst)
call get_param(param_file, mdl, "FLUXCONST_SALT", CS%Flux_const_salt, &
"The constant that relates the restoring surface salt fluxes to the relative "//&
"surface anomalies (akin to a piston velocity). Note the non-MKS units.", &
fail_if_missing=.false.,default=unscaled_fluxconst, units="m day-1", scale=US%m_to_Z*US%T_to_s)
! Convert CS%Flux_const from m day-1 to m s-1.
CS%Flux_const = CS%Flux_const / 86400.0
CS%Flux_const_salt = CS%Flux_const_salt / 86400.0
call get_param(param_file, mdl, "SALT_RESTORE_FILE", CS%salt_restore_file, &
"A file in which to find the surface salinity to use for restoring.", &
default="salt_restore.nc")
Expand Down Expand Up @@ -1421,9 +1425,14 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, wind_stagger)
call get_param(param_file, mdl, "FLUXCONST", CS%Flux_const, &
"The constant that relates the restoring surface fluxes to the relative "//&
"surface anomalies (akin to a piston velocity). Note the non-MKS units.", &
default=0.0, units="m day-1", scale=US%m_to_Z*US%T_to_s)
default=0.0, units="m day-1", scale=US%m_to_Z*US%T_to_s,unscaled=unscaled_fluxconst)
call get_param(param_file, mdl, "FLUXCONST_TEMP", CS%Flux_const_temp, &
"The constant that relates the restoring surface temperature fluxes to the relative "//&
"surface anomalies (akin to a piston velocity). Note the non-MKS units.", &
fail_if_missing=.false.,default=unscaled_fluxconst, units="m day-1", scale=US%m_to_Z*US%T_to_s)
! Convert CS%Flux_const from m day-1 to m s-1.
CS%Flux_const = CS%Flux_const / 86400.0
CS%Flux_const_temp = CS%Flux_const_temp / 86400.0
call get_param(param_file, mdl, "SST_RESTORE_FILE", CS%temp_restore_file, &
"A file in which to find the surface temperature to use for restoring.", &
default="temp_restore.nc")
Expand Down Expand Up @@ -1628,8 +1637,8 @@ subroutine ice_ocn_bnd_type_chksum(id, timestep, iobt)
logical :: root ! True only on the root PE
integer :: outunit ! The output unit to write to

outunit = stdout
root = is_root_pe()
outunit = stdout_if_root()

if (root) write(outunit,*) "BEGIN CHECKSUM(ice_ocean_boundary_type):: ", id, timestep
chks = field_chksum( iobt%u_flux ) ; if (root) write(outunit,100) 'iobt%u_flux ', chks
Expand Down
16 changes: 7 additions & 9 deletions config_src/drivers/FMS_cap/ocean_model_MOM.F90
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ module ocean_model_mod
use MOM_forcing_type, only : forcing_diagnostics, mech_forcing_diags
use MOM_get_input, only : Get_MOM_Input, directories
use MOM_grid, only : ocean_grid_type
use MOM_io, only : write_version_number, stdout
use MOM_io, only : write_version_number, stdout_if_root
use MOM_marine_ice, only : iceberg_forces, iceberg_fluxes, marine_ice_init, marine_ice_CS
use MOM_restart, only : MOM_restart_CS, save_restart
use MOM_string_functions, only : uppercase
Expand All @@ -55,7 +55,7 @@ module ocean_model_mod
use MOM_ice_shelf, only : initialize_ice_shelf, shelf_calc_flux, ice_shelf_CS
use MOM_ice_shelf, only : add_shelf_forces, ice_shelf_end, ice_shelf_save_restart
use MOM_wave_interface, only: wave_parameters_CS, MOM_wave_interface_init
use MOM_wave_interface, only: MOM_wave_interface_init_lite, Update_Surface_Waves
use MOM_wave_interface, only: Update_Surface_Waves
use iso_fortran_env, only : int64

#include <MOM_memory.h>
Expand Down Expand Up @@ -205,7 +205,7 @@ module ocean_model_mod
marine_ice_CSp => NULL() !< A pointer to the control structure for the
!! marine ice effects module.
type(wave_parameters_cs), pointer :: &
Waves !< A structure containing pointers to the surface wave fields
Waves => NULL() !< A pointer to the surface wave control structure
type(surface_forcing_CS), pointer :: &
forcing_CSp => NULL() !< A pointer to the MOM forcing control structure
type(MOM_restart_CS), pointer :: &
Expand Down Expand Up @@ -382,11 +382,9 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, wind_stagger, gas

call get_param(param_file, mdl, "USE_WAVES", OS%Use_Waves, &
"If true, enables surface wave modules.", default=.false.)
if (OS%use_waves) then
call MOM_wave_interface_init(OS%Time, OS%grid, OS%GV, OS%US, param_file, OS%Waves, OS%diag)
else
call MOM_wave_interface_init_lite(param_file)
endif
! MOM_wave_interface_init is called regardless of the value of USE_WAVES because
! it also initializes statistical waves.
call MOM_wave_interface_init(OS%Time, OS%grid, OS%GV, OS%US, param_file, OS%Waves, OS%diag)

call initialize_ocean_public_type(OS%grid%Domain, Ocean_sfc, OS%diag, &
gas_fields_ocn=gas_fields_ocn)
Expand Down Expand Up @@ -1107,8 +1105,8 @@ subroutine ocean_public_type_chksum(id, timestep, ocn)
logical :: root ! True only on the root PE
integer :: outunit ! The output unit to write to

outunit = stdout
root = is_root_pe()
outunit = stdout_if_root()

if (root) write(outunit,*) "BEGIN CHECKSUM(ocean_type):: ", id, timestep
chks = field_chksum(ocn%t_surf ) ; if (root) write(outunit,100) 'ocean%t_surf ', chks
Expand Down
12 changes: 5 additions & 7 deletions config_src/drivers/mct_cap/mom_ocean_model_mct.F90
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ module MOM_ocean_model_mct
use mpp_mod, only : mpp_chksum
use MOM_EOS, only : gsw_sp_from_sr, gsw_pt_from_ct
use MOM_wave_interface, only : wave_parameters_CS, MOM_wave_interface_init
use MOM_wave_interface, only : MOM_wave_interface_init_lite, Update_Surface_Waves
use MOM_wave_interface, only : Update_Surface_Waves
use time_interp_external_mod, only : time_interp_external_init

! MCT specfic routines
Expand Down Expand Up @@ -205,7 +205,7 @@ module MOM_ocean_model_mct
marine_ice_CSp => NULL() !< A pointer to the control structure for the
!! marine ice effects module.
type(wave_parameters_cs), pointer :: &
Waves !< A structure containing pointers to the surface wave fields
Waves => NULL() !< A pointer to the surface wave control structure
type(surface_forcing_CS), pointer :: &
forcing_CSp => NULL() !< A pointer to the MOM forcing control structure
type(MOM_restart_CS), pointer :: &
Expand Down Expand Up @@ -383,11 +383,9 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, gas_fields_ocn, i

call get_param(param_file, mdl, "USE_WAVES", OS%Use_Waves, &
"If true, enables surface wave modules.", default=.false.)
if (OS%use_waves) then
call MOM_wave_interface_init(OS%Time, OS%grid, OS%GV, OS%US, param_file, OS%Waves, OS%diag)
else
call MOM_wave_interface_init_lite(param_file)
endif
! MOM_wave_interface_init is called regardless of the value of USE_WAVES because
! it also initializes statistical waves.
call MOM_wave_interface_init(OS%Time, OS%grid, OS%GV, OS%US, param_file, OS%Waves, OS%diag)

if (associated(OS%grid%Domain%maskmap)) then
call initialize_ocean_public_type(OS%grid%Domain%mpp_domain, Ocean_sfc, &
Expand Down
Loading

0 comments on commit 5c0e8db

Please sign in to comment.