Skip to content

Ice shelf-specific forcing depths - #113

Open
angus-g wants to merge 5 commits into
2026.05from
angus-g/shelf-forcing
Open

angus-g wants to merge 5 commits into
2026.05from
angus-g/shelf-forcing

Conversation

@angus-g

@angus-g angus-g commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator

Allow specification of different depths for a) the calculation of the surface boundary layer that feeds into the melt parameterisation; b) the application of the melt fluxes. There are three new parameters:

  1. SHELF_FORCING_DEPTH: the equivalent to MINIMUM_FORCING_DEPTH applied in shelf regions;
  2. HMIX_SHELF_PROP; the equivalent to HMIX_SFC_PROP (for T/S) applied in shelf regions;
  3. HMIX_UV_SHELF_PROP; the equivalent to HMIX_UV_SFC_PROP (for velocity) applied in shelf regions.

Supersedes #78.

The boundary layer used for the melt parameterisation must match the
depth over which the forcing is applied. The only controls for these
are global: HMIX_SFC_PROP/HMIX_UV_SFC_PROP control the boundary layer
for computing the parameterisation, and MINIMUM_FORCING_DEPTH controls
the depth over which the melt is applied.

We introduce new optional parameters to applyBoundaryFluxesInOut() to
modify IforcingDepthScale to use a different `shelf_forcing_depth`
according to the fraction of the cell covered by ice shelf.
This is the analogue to MINIMUM_FORCING_DEPTH, applied under ice
shelves. It is only read when an ice shelf coverage field is provided
to the diabatic driver initialisation routine.
This only affects the path when using the non-legacy ALE diabatic
driver. In this case, the frac_shelf_h array is passed through, and
used to apply a different forcing depth as required.
This adds HMIX_SHELF_PROP and HMIX_UV_SHELF_PROP, which are analogues
to the `SFC` parameters. These determine the boundary layer depth for
near-shelf temperature, salinity and velocities, which are used for
calculation of melt parameterisation.
This now takes frac_shelf_h into account when computing depth_ml
used for calculating the surface state.
@angus-g
angus-g requested a review from dougiesquire October 26, 2026 07:30

@dougiesquire dougiesquire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @angus-g. A few questions, comments and suggestions.

Also I think these changes need to be included: 9a6fa99, e7ecd85?

Comment thread src/core/MOM.F90
Comment on lines 4122 to +4228
@@ -4147,6 +4186,14 @@ subroutine extract_surface_state(CS, sfc_state_in)
sfc_state%v(i,J) = 0.0
enddo
do k=1,nz ; do i=is,ie
if (use_iceshelves) then
frac_shelf_v = 0.0
if (G%areaT(i,j) + G%areaT(i,j+1) > 0.0) &
frac_shelf_v = ( CS%frac_shelf_h(i,j) * G%areaT(i,j) &
+ CS%frac_shelf_h(i,j+1) * G%areaT(i,j+1))&
/ (G%areaT(i,j) + G%areaT(i,j+1))
depth_ml = frac_shelf_v * CS%Hmix_UV_shelf + (1. - frac_shelf_v) * CS%Hmix_UV
endif
hv = 0.5 * (h(i,j,k) + h(i,j+1,k)) * H_rescale
if (depth(i) + hv < depth_ml) then
dh = hv
@@ -4171,6 +4218,14 @@ subroutine extract_surface_state(CS, sfc_state_in)
sfc_state%u(I,j) = 0.0
enddo
do k=1,nz ; do I=is-1,ie
if (use_iceshelves) then
frac_shelf_u = 0.0
if (G%areaT(i,j) + G%areaT(i+1,j) > 0.0) &
frac_shelf_u = ( CS%frac_shelf_h(i,j) * G%areaT(i,j) &
+ CS%frac_shelf_h(i+1,j) * G%areaT(i+1,j))&
/ (G%areaT(i+1,j) + G%areaT(i+1,j))
depth_ml = frac_shelf_u * CS%Hmix_UV_shelf + (1. - frac_shelf_u) * CS%Hmix_UV
endif

@dougiesquire dougiesquire Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the loops' OpenMP directives needs updating for the new variables.

Comment thread src/core/MOM.F90
if (G%areaT(i,j) + G%areaT(i+1,j) > 0.0) &
frac_shelf_u = ( CS%frac_shelf_h(i,j) * G%areaT(i,j) &
+ CS%frac_shelf_h(i+1,j) * G%areaT(i+1,j))&
/ (G%areaT(i+1,j) + G%areaT(i+1,j))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/ (G%areaT(i+1,j) + G%areaT(i+1,j))
/ (G%areaT(i,j) + G%areaT(i+1,j))

Comment thread src/core/MOM.F90
Comment on lines +4189 to +4196
if (use_iceshelves) then
frac_shelf_v = 0.0
if (G%areaT(i,j) + G%areaT(i,j+1) > 0.0) &
frac_shelf_v = ( CS%frac_shelf_h(i,j) * G%areaT(i,j) &
+ CS%frac_shelf_h(i,j+1) * G%areaT(i,j+1))&
/ (G%areaT(i,j) + G%areaT(i,j+1))
depth_ml = frac_shelf_v * CS%Hmix_UV_shelf + (1. - frac_shelf_v) * CS%Hmix_UV
endif

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused here. Say we have HMIX_UV_SHELF_PROP = 0 and we're at a point fully under the shelf (ie frac_shelf_v = 1). That would give depth_ml = 0, so dh=0, so sfc_state%v stays 0. So doesn't the default HMIX_UV_SHELF_PROP = 0 actually set the surface velocity to zero, rather than doing no averaging.

Do we need to widen the if (CS%Hmix_UV>0.) then guard around this loop?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually just widening the guard probably wouldn't be enough, but you get the idea

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, because this sits inside the if (CS%Hmix_UV>0.) then, HMIX_UV_SHELF_PROP does nothing unless HMIX_UV_SFC_PROP > 0. So it's not possible to average velocities under ice-shelves but not in the open ocean.

Comment thread src/core/MOM.F90
frac_shelf_u = ( CS%frac_shelf_h(i,j) * G%areaT(i,j) &
+ CS%frac_shelf_h(i+1,j) * G%areaT(i+1,j))&
/ (G%areaT(i+1,j) + G%areaT(i+1,j))
depth_ml = frac_shelf_u * CS%Hmix_UV_shelf + (1. - frac_shelf_u) * CS%Hmix_UV

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would writing like this be better for preserving answers when HMIX_UV_SHELF_PROP == HMIX_UV_SFC_PROP:

Suggested change
depth_ml = frac_shelf_u * CS%Hmix_UV_shelf + (1. - frac_shelf_u) * CS%Hmix_UV
depth_ml = CS%Hmix_UV + frac_shelf_u * (CS%Hmix_UV_shelf - CS%Hmix_UV)

Comment thread src/core/MOM.F90
frac_shelf_v = ( CS%frac_shelf_h(i,j) * G%areaT(i,j) &
+ CS%frac_shelf_h(i,j+1) * G%areaT(i,j+1))&
/ (G%areaT(i,j) + G%areaT(i,j+1))
depth_ml = frac_shelf_v * CS%Hmix_UV_shelf + (1. - frac_shelf_v) * CS%Hmix_UV

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would writing like this be better for preserving answers when HMIX_UV_SHELF_PROP == HMIX_UV_SFC_PROP:

Suggested change
depth_ml = frac_shelf_v * CS%Hmix_UV_shelf + (1. - frac_shelf_v) * CS%Hmix_UV
depth_ml = CS%Hmix_UV + frac_shelf_v * (CS%Hmix_UV_shelf - CS%Hmix_UV)

type(diabatic_CS), pointer :: CS !< module control structure
type(stochastic_CS), pointer :: stoch_CS !< stochastic control structure
type(Wave_parameters_CS), pointer :: Waves !< Surface gravity waves
real, dimension(:,:), optional, intent(in) :: frac_shelf_h !< Fractional ice shelf coverage [nondim]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
real, dimension(:,:), optional, intent(in) :: frac_shelf_h !< Fractional ice shelf coverage [nondim]
real, dimension(SZI_(G),SZJ_(G)), optional, intent(in) :: frac_shelf_h !< Fractional ice shelf coverage [nondim]

type(oda_incupd_CS), pointer :: oda_incupd_CSp !< pointer to the ocean data assimilation incremental
!! update module control structure
type(int_tide_CS), pointer :: int_tide_CSp !< pointer to the internal tide structure
real, dimension(:,:), optional, intent(in) :: frac_shelf_h !< Fractional ice shelf coverage [nondim]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
real, dimension(:,:), optional, intent(in) :: frac_shelf_h !< Fractional ice shelf coverage [nondim]
real, dimension(SZI_(G),SZJ_(G)), optional, intent(in) :: frac_shelf_h !< Fractional ice shelf coverage [nondim]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, could we pass a logical here instead of the full array (Or just read ICE_SHELF directly from param_file)?

optional, pointer :: MLD_h !< Mixed layer thickness for brine plumes [H ~> m or kg m-2]
real, dimension(SZI_(G),SZJ_(G)), &
optional, intent(in) :: frac_shelf_h !< Fractional ice shelf coverage [nondim]
real, optional, intent(in) :: shelf_forcing_depth !< Flux depth for shelf regions

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs units:

Suggested change
real, optional, intent(in) :: shelf_forcing_depth !< Flux depth for shelf regions
real, optional, intent(in) :: shelf_forcing_depth !< Flux depth for shelf regions [H ~> m or kg m-2].

Comment thread src/core/MOM.F90
type(group_pass_type) :: tmp_pass_uv_T_S_h, pass_uv_T_S_h

real :: Hmix_z, Hmix_UV_z ! Temporary variables with averaging depths [Z ~> m]
real :: Hmix_shelf_z, Hmix_UV_shelf_z

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
real :: Hmix_shelf_z, Hmix_UV_shelf_z
real :: Hmix_shelf_z, Hmix_UV_shelf_z ! Temporary variables with ice-shelf averaging depths [Z ~> m]

Comment thread src/core/MOM.F90
logical :: use_iceshelves
character(240) :: msg
integer :: turns ! Number of quarter turns
real :: frac_shelf_u, frac_shelf_v

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
real :: frac_shelf_u, frac_shelf_v
real :: frac_shelf_u, frac_shelf_v ! Ice shelf area fraction at u and v points [nondim]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants