Skip to content

Commit

Permalink
Merge branch 'dev/gfdl' into fix_CVMIX_shear_is_used_bug
Browse files Browse the repository at this point in the history
  • Loading branch information
marshallward authored Feb 13, 2023
2 parents a9ee8d3 + ad56b29 commit 84426ff
Show file tree
Hide file tree
Showing 20 changed files with 303 additions and 307 deletions.
4 changes: 2 additions & 2 deletions .gitlab/pipeline-ci-tool.sh
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ nolibs-ocean-only-compile () {
cd $JOB_DIR/$STATS_REPO_DIR/$CONFIGS_DIR
mkdir -p build-ocean-only-nolibs-$1
cd build-ocean-only-nolibs-$1
make -f ../tools/MRS/Makefile.build ./$1/env BUILD=. -s
make -f ../tools/MRS/Makefile.build ./$1/env BUILD=. ENVIRON=../../environ -s
../src/mkmf/bin/list_paths -l ../src/MOM6/config_src/{drivers/solo_driver,memory/dynamic_symmetric,infra/FMS1,ext*} ../src/MOM6/src ../src/FMS1
sed -i '/FMS1\/.*\/test_/d' path_names
../src/mkmf/bin/mkmf -t ../src/mkmf/templates/ncrc-$1.mk -p MOM6 -c"-Duse_libMPI -Duse_netCDF" path_names
Expand All @@ -153,7 +153,7 @@ nolibs-ocean-ice-compile () {
cd $JOB_DIR/$STATS_REPO_DIR/$CONFIGS_DIR
mkdir -p build-ocean-ice-nolibs-$1
cd build-ocean-ice-nolibs-$1
make -f ../tools/MRS/Makefile.build ./$1/env BUILD=. -s
make -f ../tools/MRS/Makefile.build ./$1/env BUILD=. ENVIRON=../../environ -s
../src/mkmf/bin/list_paths -l ../src/MOM6/config_src/{drivers/FMS_cap,memory/dynamic_symmetric,infra/FMS1,ext*} ../src/MOM6/src ../src/SIS2/*src ../src/{FMS1,coupler,icebergs,ice_param,land_null,atmos_null}
sed -i '/FMS1\/.*\/test_/d' path_names
../src/mkmf/bin/mkmf -t ../src/mkmf/templates/ncrc-$1.mk -p MOM6 -c"-Duse_libMPI -Duse_netCDF -D_USE_LEGACY_LAND_ -Duse_AM3_physics" path_names
Expand Down
19 changes: 11 additions & 8 deletions config_src/drivers/FMS_cap/MOM_surface_forcing_gfdl.F90
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ module MOM_surface_forcing_gfdl
!! contributes to ustar [R L Z T-1 ~> Pa]. gust is used when read_gust_2d is true.
real, pointer, dimension(:,:) :: &
ustar_tidal => NULL() !< Tidal contribution to the bottom friction velocity [Z T-1 ~> m s-1]
real :: cd_tides !< Drag coefficient that applies to the tides (nondimensional)
real :: cd_tides !< Drag coefficient that applies to the tides [nondim]
real :: utide !< Constant tidal velocity to use if read_tideamp is false [Z T-1 ~> m s-1].
logical :: read_tideamp !< If true, spatially varying tidal amplitude read from a file.

Expand Down Expand Up @@ -127,7 +127,7 @@ module MOM_surface_forcing_gfdl
logical :: mask_srestore_marginal_seas !< If true, then mask SSS restoring in marginal seas
real :: max_delta_srestore !< Maximum delta salinity used for restoring [S ~> ppt]
real :: max_delta_trestore !< Maximum delta sst used for restoring [C ~> degC]
real, pointer, dimension(:,:) :: basin_mask => NULL() !< Mask for surface salinity restoring by basin
real, pointer, dimension(:,:) :: basin_mask => NULL() !< Mask for surface salinity restoring by basin [nondim]
integer :: answer_date !< The vintage of the order of arithmetic and expressions in the
!! gustiness calculations. Values below 20190101 recover the answers
!! from the end of 2018, while higher values use a simpler expression
Expand All @@ -144,14 +144,14 @@ module MOM_surface_forcing_gfdl
!! salinity restoring fluxes. The masking file should be
!! in inputdir/salt_restore_mask.nc and the field should
!! be named 'mask'
real, pointer, dimension(:,:) :: srestore_mask => NULL() !< mask for SSS restoring
real, pointer, dimension(:,:) :: srestore_mask => NULL() !< mask for SSS restoring [nondim]
character(len=200) :: temp_restore_file !< Filename for sst restoring data
character(len=30) :: temp_restore_var_name !< Name of surface temperature in temp_restore_file
logical :: mask_trestore !< If true, apply a 2-dimensional mask to the surface
!! temperature restoring fluxes. The masking file should be
!! in inputdir/temp_restore_mask.nc and the field should
!! be named 'mask'
real, pointer, dimension(:,:) :: trestore_mask => NULL() !< Mask for SST restoring
real, pointer, dimension(:,:) :: trestore_mask => NULL() !< Mask for SST restoring [nondim]
integer :: id_srestore = -1 !< An id number for time_interp_external.
integer :: id_trestore = -1 !< An id number for time_interp_external.

Expand Down Expand Up @@ -250,7 +250,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
! mass fluxes [R Z s m2 kg-1 T-1 ~> 1]
real :: rhoXcp ! Reference density times heat capacity times unit scaling
! factors [Q R C-1 ~> J m-3 degC-1]
real :: sign_for_net_FW_bug ! Should be +1. but an old bug can be recovered by using -1.
real :: sign_for_net_FW_bug ! Should be +1. but an old bug can be recovered by using -1 [nondim]

call cpu_clock_begin(id_clock_forcing)

Expand Down Expand Up @@ -1169,7 +1169,10 @@ subroutine apply_force_adjustments(G, US, CS, Time, forces)
real, dimension(SZI_(G),SZJ_(G)) :: tempy_at_h ! Delta to meridional wind stress at h points [R Z L T-2 ~> Pa]

integer :: isc, iec, jsc, jec, i, j
real :: dLonDx, dLonDy, rDlon, cosA, sinA, zonal_tau, merid_tau
real :: dLonDx, dLonDy ! The change in longitude across the cell in the x- and y-directions [degrees_E]
real :: rDlon ! The magnitude of the change in longitude [degrees_E] and then its inverse [degrees_E-1]
real :: cosA, sinA ! The cosine and sine of the angle between the grid and true north [nondim]
real :: zonal_tau, merid_tau ! True zonal and meridional wind stresses [R Z L T-2 ~> Pa]
real :: Pa_conversion ! A unit conversion factor from Pa to the internal units [R Z L T-2 Pa-1 ~> 1]
logical :: overrode_x, overrode_y

Expand Down Expand Up @@ -1714,8 +1717,8 @@ end subroutine ice_ocn_bnd_type_chksum
!> Check the values passed by IOB over land are zero
subroutine check_mask_val_consistency(val, mask, i, j, varname, G)

real, intent(in) :: val !< value of flux/variable passed by IOB
real, intent(in) :: mask !< value of ocean mask
real, intent(in) :: val !< value of flux/variable passed by IOB [various]
real, intent(in) :: mask !< value of ocean mask [nondim]
integer, intent(in) :: i !< model grid cell indices
integer, intent(in) :: j !< model grid cell indices
character(len=*), intent(in) :: varname !< variable name
Expand Down
21 changes: 10 additions & 11 deletions config_src/drivers/FMS_cap/ocean_model_MOM.F90
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ subroutine update_ocean_model(Ice_ocean_boundary, OS, Ocean_sfc, time_start_upda
! internal modules.
type(time_type) :: Time1 ! The value of the ocean model's time at the start of a call to step_MOM.
integer :: index_bnds(4) ! The computational domain index bounds in the ice-ocean boundary type.
real :: weight ! Flux accumulation weight of the current fluxes.
real :: weight ! Flux accumulation weight of the current fluxes [nondim].
real :: dt_coupling ! The coupling time step [T ~> s].
real :: dt_therm ! A limited and quantized version of OS%dt_therm [T ~> s].
real :: dt_dyn ! The dynamics time step [T ~> s].
Expand Down Expand Up @@ -834,7 +834,6 @@ subroutine convert_state_to_ocean_type(sfc_state, Ocean_sfc, G, US, patm, press_
real, optional, intent(in) :: press_to_z !< A conversion factor between pressure and ocean
!! depth, usually 1/(rho_0*g) [Z T2 R-1 L-2 ~> m Pa-1]
! Local variables
real :: IgR0
character(len=48) :: val_str
integer :: isc_bnd, iec_bnd, jsc_bnd, jec_bnd
integer :: i, j, i0, j0, is, ie, js, je
Expand Down Expand Up @@ -989,31 +988,31 @@ subroutine Ocean_stock_pe(OS, index, value, time_index)
type(ocean_state_type), pointer :: OS !< A structure containing the internal ocean state.
!! The data in OS is intent in.
integer, intent(in) :: index !< The stock index for the quantity of interest.
real, intent(out) :: value !< Sum returned for the conservation quantity of interest.
real, intent(out) :: value !< Sum returned for the conservation quantity of interest [various]
integer, optional, intent(in) :: time_index !< An unused optional argument, present only for
!! interfacial compatibility with other models.
! Arguments: OS - A structure containing the internal ocean state.
! (in) index - Index of conservation quantity of interest.
! (in) value - Sum returned for the conservation quantity of interest.
! (in,opt) time_index - Index for time level to use if this is necessary.

real :: salt
real :: salt ! The total salt in the ocean [kg]

value = 0.0
if (.not.associated(OS)) return
if (.not.OS%is_ocean_pe) return

select case (index)
case (ISTOCK_WATER) ! Return the mass of fresh water in the ocean in kg.
case (ISTOCK_WATER) ! Return the mass of fresh water in the ocean in [kg].
if (OS%GV%Boussinesq) then
call get_ocean_stocks(OS%MOM_CSp, mass=value, on_PE_only=.true.)
else ! In non-Boussinesq mode, the mass of salt needs to be subtracted.
call get_ocean_stocks(OS%MOM_CSp, mass=value, salt=salt, on_PE_only=.true.)
value = value - salt
endif
case (ISTOCK_HEAT) ! Return the heat content of the ocean in J.
case (ISTOCK_HEAT) ! Return the heat content of the ocean in [J].
call get_ocean_stocks(OS%MOM_CSp, heat=value, on_PE_only=.true.)
case (ISTOCK_SALT) ! Return the mass of the salt in the ocean in kg.
case (ISTOCK_SALT) ! Return the mass of the salt in the ocean in [kg].
call get_ocean_stocks(OS%MOM_CSp, salt=value, on_PE_only=.true.)
case default ; value = 0.0
end select
Expand All @@ -1032,7 +1031,7 @@ subroutine ocean_model_data2D_get(OS, Ocean, name, array2D, isc, jsc)
!! visible ocean surface fields.
character(len=*) , intent(in) :: name !< The name of the field to extract
real, dimension(isc:,jsc:), intent(out):: array2D !< The values of the named field, it must
!! cover only the computational domain
!! cover only the computational domain [various]
integer , intent(in) :: isc !< The starting i-index of array2D
integer , intent(in) :: jsc !< The starting j-index of array2D

Expand Down Expand Up @@ -1092,8 +1091,8 @@ subroutine ocean_model_data1D_get(OS, Ocean, name, value)
!! internal ocean state (intent in).
type(ocean_public_type), intent(in) :: Ocean !< A structure containing various publicly
!! visible ocean surface fields.
character(len=*) , intent(in) :: name !< The name of the field to extract
real , intent(out):: value !< The value of the named field
character(len=*), intent(in) :: name !< The name of the field to extract
real, intent(out):: value !< The value of the named field [various]

if (.not.associated(OS)) return
if (.not.OS%is_ocean_pe) return
Expand Down Expand Up @@ -1155,7 +1154,7 @@ subroutine ocean_model_get_UV_surf(OS, Ocean, name, array2D, isc, jsc)
!! visible ocean surface fields.
character(len=*) , intent(in) :: name !< The name of the current (ua or va) to extract
real, dimension(isc:,jsc:), intent(out):: array2D !< The values of the named field, it must
!! cover only the computational domain
!! cover only the computational domain [L T-1 ~> m s-1]
integer , intent(in) :: isc !< The starting i-index of array2D
integer , intent(in) :: jsc !< The starting j-index of array2D

Expand Down
21 changes: 4 additions & 17 deletions config_src/drivers/nuopc_cap/mom_cap.F90
Original file line number Diff line number Diff line change
Expand Up @@ -754,23 +754,10 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
if (wave_method == "EFACTOR") then
call fld_list_add(fldsToOcn_num, fldsToOcn, "Sw_lamult" , "will provide")
else if (wave_method == "SURFACE_BANDS") then
if (cesm_coupled) then
call fld_list_add(fldsToOcn_num, fldsToOcn, "Sw_pstokes_x", "will provide", &
ungridded_lbound=1, ungridded_ubound=Ice_ocean_boundary%num_stk_bands)
call fld_list_add(fldsToOcn_num, fldsToOcn, "Sw_pstokes_y", "will provide", &
ungridded_lbound=1, ungridded_ubound=Ice_ocean_boundary%num_stk_bands)
else ! below is the old approach of importing partitioned stokes drift components. after the planned ww3 nuopc
! cap unification, this else block should be removed in favor of the more flexible import approach above.
if (Ice_ocean_boundary%num_stk_bands > 3) then
call MOM_error(FATAL, "Number of Stokes Bands > 3, NUOPC cap not set up for this")
endif
call fld_list_add(fldsToOcn_num, fldsToOcn, "eastward_partitioned_stokes_drift_1" , "will provide")
call fld_list_add(fldsToOcn_num, fldsToOcn, "northward_partitioned_stokes_drift_1", "will provide")
call fld_list_add(fldsToOcn_num, fldsToOcn, "eastward_partitioned_stokes_drift_2" , "will provide")
call fld_list_add(fldsToOcn_num, fldsToOcn, "northward_partitioned_stokes_drift_2", "will provide")
call fld_list_add(fldsToOcn_num, fldsToOcn, "eastward_partitioned_stokes_drift_3" , "will provide")
call fld_list_add(fldsToOcn_num, fldsToOcn, "northward_partitioned_stokes_drift_3", "will provide")
endif
call fld_list_add(fldsToOcn_num, fldsToOcn, "Sw_pstokes_x", "will provide", &
ungridded_lbound=1, ungridded_ubound=Ice_ocean_boundary%num_stk_bands)
call fld_list_add(fldsToOcn_num, fldsToOcn, "Sw_pstokes_y", "will provide", &
ungridded_lbound=1, ungridded_ubound=Ice_ocean_boundary%num_stk_bands)
else
call MOM_error(FATAL, "Unsupported WAVE_METHOD encountered in NUOPC cap.")
endif
Expand Down
50 changes: 0 additions & 50 deletions config_src/drivers/nuopc_cap/mom_cap_methods.F90
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ subroutine mom_import(ocean_public, ocean_grid, importState, ice_ocean_boundary,
character(len=128) :: fldname
real(ESMF_KIND_R8), allocatable :: taux(:,:)
real(ESMF_KIND_R8), allocatable :: tauy(:,:)
real(ESMF_KIND_R8), allocatable :: stkx1(:,:),stkx2(:,:),stkx3(:,:)
real(ESMF_KIND_R8), allocatable :: stky1(:,:),stky2(:,:),stky3(:,:)
real(ESMF_KIND_R8), allocatable :: stkx(:,:,:)
real(ESMF_KIND_R8), allocatable :: stky(:,:,:)
character(len=*) , parameter :: subname = '(mom_import)'
Expand Down Expand Up @@ -329,8 +327,6 @@ subroutine mom_import(ocean_public, ocean_grid, importState, ice_ocean_boundary,
! Partitioned Stokes Drift Components
!----
if ( associated(ice_ocean_boundary%ustkb) ) then

if (cesm_coupled) then
nsc = Ice_ocean_boundary%num_stk_bands
allocate(stkx(isc:iec,jsc:jec,1:nsc))
allocate(stky(isc:iec,jsc:jec,1:nsc))
Expand Down Expand Up @@ -358,52 +354,6 @@ subroutine mom_import(ocean_public, ocean_grid, importState, ice_ocean_boundary,
enddo
enddo
deallocate(stkx,stky)

else ! below is the old approach of importing partitioned stokes drift components. after the planned ww3 nuopc
! cap unification, this else block should be removed in favor of the more flexible import approach above.
allocate(stkx1(isc:iec,jsc:jec))
allocate(stky1(isc:iec,jsc:jec))
allocate(stkx2(isc:iec,jsc:jec))
allocate(stky2(isc:iec,jsc:jec))
allocate(stkx3(isc:iec,jsc:jec))
allocate(stky3(isc:iec,jsc:jec))

call state_getimport(importState,'eastward_partitioned_stokes_drift_1' , isc, iec, jsc, jec, stkx1,rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call state_getimport(importState,'northward_partitioned_stokes_drift_1', isc, iec, jsc, jec, stky1,rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call state_getimport(importState,'eastward_partitioned_stokes_drift_2' , isc, iec, jsc, jec, stkx2,rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call state_getimport(importState,'northward_partitioned_stokes_drift_2', isc, iec, jsc, jec, stky2,rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call state_getimport(importState,'eastward_partitioned_stokes_drift_3' , isc, iec, jsc, jec, stkx3,rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call state_getimport(importState,'northward_partitioned_stokes_drift_3', isc, iec, jsc, jec, stky3,rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! rotate from true zonal/meridional to local coordinates
do j = jsc, jec
jg = j + ocean_grid%jsc - jsc
do i = isc, iec
ig = i + ocean_grid%isc - isc
ice_ocean_boundary%ustkb(i,j,1) = ocean_grid%cos_rot(ig,jg)*stkx1(i,j) &
- ocean_grid%sin_rot(ig,jg)*stky1(i,j)
ice_ocean_boundary%vstkb(i,j,1) = ocean_grid%cos_rot(ig,jg)*stky1(i,j) &
+ ocean_grid%sin_rot(ig,jg)*stkx1(i,j)

ice_ocean_boundary%ustkb(i,j,2) = ocean_grid%cos_rot(ig,jg)*stkx2(i,j) &
- ocean_grid%sin_rot(ig,jg)*stky2(i,j)
ice_ocean_boundary%vstkb(i,j,2) = ocean_grid%cos_rot(ig,jg)*stky2(i,j) &
+ ocean_grid%sin_rot(ig,jg)*stkx2(i,j)

ice_ocean_boundary%ustkb(i,j,3) = ocean_grid%cos_rot(ig,jg)*stkx3(i,j) &
- ocean_grid%sin_rot(ig,jg)*stky3(i,j)
ice_ocean_boundary%vstkb(i,j,3) = ocean_grid%cos_rot(ig,jg)*stky3(i,j) &
+ ocean_grid%sin_rot(ig,jg)*stkx3(i,j)
enddo
enddo
deallocate(stkx1,stkx2,stkx3,stky1,stky2,stky3)
endif
endif

end subroutine mom_import
Expand Down
6 changes: 3 additions & 3 deletions config_src/drivers/solo_driver/MOM_surface_forcing.F90
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ module MOM_surface_forcing
logical :: adiabatic !< if true, no diapycnal mass fluxes or surface buoyancy forcing
logical :: variable_winds !< if true, wind stresses vary with time
logical :: variable_buoyforce !< if true, buoyancy forcing varies with time.
real :: south_lat !< southern latitude of the domain
real :: len_lat !< domain length in latitude
real :: south_lat !< southern latitude of the domain [degrees_N] or [km] or [m]
real :: len_lat !< domain length in latitude [degrees_N] or [km] or [m]

real :: Rho0 !< Boussinesq reference density [R ~> kg m-3]
real :: G_Earth !< gravitational acceleration [L2 Z-1 T-2 ~> m s-2]
Expand Down Expand Up @@ -104,7 +104,7 @@ module MOM_surface_forcing
real :: gyres_taux_const !< A constant wind stress [R L Z T-1 ~> Pa].
real :: gyres_taux_sin_amp !< The amplitude of cosine wind stress gyres [R L Z T-1 ~> Pa], if WIND_CONFIG=='gyres'
real :: gyres_taux_cos_amp !< The amplitude of cosine wind stress gyres [R L Z T-1 ~> Pa], if WIND_CONFIG=='gyres'
real :: gyres_taux_n_pis !< The number of sine lobes in the basin if WIND_CONFIG=='gyres'
real :: gyres_taux_n_pis !< The number of sine lobes in the basin if WIND_CONFIG=='gyres' [nondim]
integer :: answer_date !< This 8-digit integer gives the approximate date with which the order
!! of arithmetic and expressions were added to the code.
!! Dates before 20190101 use original answers.
Expand Down
Loading

0 comments on commit 84426ff

Please sign in to comment.