Landfast sea ice

This example shows sea ice grounding on a shallow shelf. Wind blows along a coast whose water deepens offshore, and where the ice keels are thick enough to reach the sea floor the bed arrests them: a stationary landfast belt forms against the coast while the pack streams freely offshore. Running the same configuration with and without LandfastBasalStress isolates the effect. This example demonstrates how to:

  • give a sea-ice model a bathymetry it can ground on,
  • switch on the Lemieux et al. (2015) basal stress,
  • visualize the landfast belt it produces.

Install dependencies

using Pkg
pkg"add Oceananigans, ClimaSeaIce, CairoMakie"
using ClimaSeaIce
using Oceananigans
using Oceananigans.Units
using Printf
using CairoMakie

The physical domain

The domain is a coastal strip, periodic along the coast and bounded across it. Unlike a pure sea-ice problem, the grid needs a vertical extent: the basal stress is driven by the water depth, so the model has to be told where the sea floor is.

Lx, Ly = 200kilometers, 100kilometers
Nx, Ny, Nz = 128, 64, 30

coastal_depth = 2      # m, at the coast
offshore_depth = 60    # m, at the open boundary
60

The vertical grid must resolve the shelf. With cells thicker than the coastal depth the whole top cell would be immersed and the column depth would collapse to zero.

underlying_grid = RectilinearGrid(size = (Nx, Ny, Nz),
                                     x = (0, Lx),
                                     y = (0, Ly),
                                     z = (-offshore_depth, 0),
                                  halo = (4, 4, 4),
                              topology = (Periodic, Bounded, Bounded))

@inline sea_floor(x, y) = - (coastal_depth + (offshore_depth - coastal_depth) * y / Ly)

grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(sea_floor))
128×64×30 ImmersedBoundaryGrid{Float64, Oceananigans.Grids.Periodic, Oceananigans.Grids.Bounded, Oceananigans.Grids.Bounded} on CPU with 4×4×4 halo:
├── immersed_boundary: GridFittedBottom(mean(z)=-31.0, min(z)=-60.0, max(z)=-2.0)
├── underlying_grid: 128×64×30 RectilinearGrid{Float64, Periodic, Bounded, Bounded} on CPU with 4×4×4 halo
├── Periodic x ∈ [0.0, 200000.0) regularly spaced with Δx=1562.5
├── Bounded  y ∈ [0.0, 100000.0] regularly spaced with Δy=1562.5
└── Bounded  z ∈ [-60.0, 0.0]    regularly spaced with Δz=2.0

Where the ice grounds

Keels ground where the ice is thicker than the critical thickness $hᶜ = H ℵ / k₁$. With $k₁ = 8$ and three metres of fully concentrated ice, that is everywhere shallower than 24 m:

ice_thickness = 3.0
critical_thickness_parameter = 8

grounding_depth = critical_thickness_parameter * ice_thickness
grounding_line = Ly * (grounding_depth - coastal_depth) / (offshore_depth - coastal_depth)

@info @sprintf("Ice grounds in water shallower than %.0f m, i.e. within %.0f km of the coast", grounding_depth, grounding_line / 1e3)
[ Info: Ice grounds in water shallower than 24 m, i.e. within 38 km of the coast

Atmospheric and oceanic forcing

The wind blows along the coast with a component pushing the ice onshore, so the pack is driven against the shelf:

uₐ = 15.0    # m s⁻¹
Cᴰ = 1.2e-3  # atmosphere-sea ice drag coefficient
ρₐ = 1.3     # kg m⁻³

τₐ = ρₐ * Cᴰ * uₐ^2

τᵤ = XFaceField(grid)
τᵥ = YFaceField(grid)
set!(τᵤ, - τₐ)          # along the coast
set!(τᵥ, - 0.3 * τₐ)    # and towards it
Oceananigans.BoundaryConditions.fill_halo_regions!(τᵤ)
Oceananigans.BoundaryConditions.fill_halo_regions!(τᵥ)

The ocean is at rest, so its stress opposes any ice motion:

τₒ = SemiImplicitStress()
SemiImplicitStress
├── uₑ: ZeroField{Float64}
├── vₑ: ZeroField{Float64}
├── ρₑ: 1026.0
└── Cᴰ: 0.0055

Running the two configurations

The only difference between the runs is whether the sea floor is allowed to grip the ice.

function run_landfast_simulation(basal_stress; stop_time = 2days, Δt = 10minutes)
    dynamics = SeaIceMomentumEquation(grid;
                                      top_momentum_stress = (u=τᵤ, v=τᵥ),
                                      bottom_momentum_stress = τₒ,
                                      rheology = ElastoViscoPlasticRheology(),
                                      basal_stress,
                                      solver = SplitExplicitSolver(grid; substeps=150))

    model = SeaIceModel(grid; dynamics,
                        advection = WENO(order=7),
                        ice_thermodynamics = nothing)

    set!(model, h = ice_thickness)
    set!(model, ℵ = 1)

    simulation = Simulation(model; Δt, stop_time)

    speed = []
    thickness = []

    s = Field(sqrt(model.velocities.u^2 + model.velocities.v^2))

    function accumulate!(sim)
        compute!(s)
        push!(speed, deepcopy(Array(interior(s))[:, :, 1]))
        push!(thickness, deepcopy(Array(interior(sim.model.ice_thickness))[:, :, 1]))
    end

    simulation.callbacks[:save] = Callback(accumulate!, IterationInterval(6))

    run!(simulation)

    return speed, thickness
end

drifting_speed, drifting_thickness = run_landfast_simulation(nothing)
landfast_speed, landfast_thickness = run_landfast_simulation(LandfastBasalStress())
(Any[[0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [4.6701093739035287e-7 4.817552999878544e-7 … 0.033024341940640495 0.03213785386038166; 4.6701093739035287e-7 4.817552999878544e-7 … 0.033024341940640495 0.03213785386038166; … ; 4.6701093739035287e-7 4.817552999878544e-7 … 0.033024341940640495 0.03213785386038166; 4.6701093739035287e-7 4.817552999878544e-7 … 0.033024341940640495 0.03213785386038166], [4.669953291049679e-7 4.817545671846727e-7 … 0.046084305898033875 0.04670352566861; 4.669953291049679e-7 4.817545671846727e-7 … 0.046084305898033875 0.04670352566861; … ; 4.669953291049679e-7 4.817545671846727e-7 … 0.046084305898033875 0.04670352566861; 4.669953291049679e-7 4.817545671846727e-7 … 0.046084305898033875 0.04670352566861], [4.669578949477547e-7 4.817022086945673e-7 … 0.058074156867438054 0.05739915917011309; 4.669578949477547e-7 4.817022086945673e-7 … 0.058074156867438054 0.05739915917011309; … ; 4.669578949477547e-7 4.817022086945673e-7 … 0.058074156867438054 0.05739915917011309; 4.669578949477547e-7 4.817022086945673e-7 … 0.058074156867438054 0.05739915917011309], [4.669367515785603e-7 4.816743950384003e-7 … 0.07032544126561768 0.07081885756084816; 4.669367515785603e-7 4.816743950384003e-7 … 0.07032544126561768 0.07081885756084816; … ; 4.669367515785603e-7 4.816743950384003e-7 … 0.07032544126561768 0.07081885756084816; 4.669367515785603e-7 4.816743950384003e-7 … 0.07032544126561768 0.07081885756084816], [4.66918170713133e-7 4.816316808792719e-7 … 0.07670391703027306 0.07704656200988529; 4.66918170713133e-7 4.816316808792719e-7 … 0.07670391703027306 0.07704656200988529; … ; 4.66918170713133e-7 4.816316808792719e-7 … 0.07670391703027306 0.07704656200988529; 4.66918170713133e-7 4.816316808792719e-7 … 0.07670391703027306 0.07704656200988529], [4.668857543370661e-7 4.8155674547463e-7 … 0.08474284562017859 0.0845568156670565; 4.668857543370661e-7 4.8155674547463e-7 … 0.08474284562017859 0.0845568156670565; … ; 4.668857543370661e-7 4.8155674547463e-7 … 0.08474284562017859 0.0845568156670565; 4.668857543370661e-7 4.8155674547463e-7 … 0.08474284562017859 0.0845568156670565], [4.6685595623046404e-7 4.814894944270803e-7 … 0.09015540698245632 0.08976885650870482; 4.6685595623046404e-7 4.814894944270803e-7 … 0.09015540698245632 0.08976885650870482; … ; 4.6685595623046404e-7 4.814894944270803e-7 … 0.09015540698245632 0.08976885650870482; 4.6685595623046404e-7 4.814894944270803e-7 … 0.09015540698245632 0.08976885650870482], [4.668708224970068e-7 4.814955574874265e-7 … 0.09253383297339053 0.09237350187967995; 4.668708224970068e-7 4.814955574874265e-7 … 0.09253383297339053 0.09237350187967995; … ; 4.668708224970068e-7 4.814955574874265e-7 … 0.09253383297339053 0.09237350187967995; 4.668708224970068e-7 4.814955574874265e-7 … 0.09253383297339053 0.09237350187967995], [4.668736871289319e-7 4.814926274312406e-7 … 0.09690733105236621 0.09686061163742542; 4.668736871289319e-7 4.814926274312406e-7 … 0.09690733105236621 0.09686061163742542; … ; 4.668736871289319e-7 4.814926274312406e-7 … 0.09690733105236621 0.09686061163742542; 4.668736871289319e-7 4.814926274312406e-7 … 0.09690733105236621 0.09686061163742542]  …  [4.66784009164887e-7 4.812946613024919e-7 … 0.10858130321140132 0.10900972427814307; 4.66784009164887e-7 4.812946613024919e-7 … 0.10858130321140132 0.10900972427814307; … ; 4.66784009164887e-7 4.812946613024919e-7 … 0.10858130321140132 0.10900972427814307; 4.66784009164887e-7 4.812946613024919e-7 … 0.10858130321140132 0.10900972427814307], [4.667861877806773e-7 4.812967829708095e-7 … 0.10931509903836555 0.10979619437373657; 4.667861877806773e-7 4.812967829708095e-7 … 0.10931509903836555 0.10979619437373657; … ; 4.667861877806773e-7 4.812967829708095e-7 … 0.10931509903836555 0.10979619437373657; 4.667861877806773e-7 4.812967829708095e-7 … 0.10931509903836555 0.10979619437373657], [4.6678351486722684e-7 4.812880565247475e-7 … 0.11041938274761576 0.10947433304443677; 4.6678351486722684e-7 4.812880565247475e-7 … 0.11041938274761576 0.10947433304443677; … ; 4.6678351486722684e-7 4.812880565247475e-7 … 0.11041938274761576 0.10947433304443677; 4.6678351486722684e-7 4.812880565247475e-7 … 0.11041938274761576 0.10947433304443677], [4.6678546016732687e-7 4.812937677055512e-7 … 0.10949960942638853 0.10929959957764217; 4.6678546016732687e-7 4.812937677055512e-7 … 0.10949960942638853 0.10929959957764217; … ; 4.6678546016732687e-7 4.812937677055512e-7 … 0.10949960942638853 0.10929959957764217; 4.6678546016732687e-7 4.812937677055512e-7 … 0.10949960942638853 0.10929959957764217], [4.6676976507912387e-7 4.812751477636772e-7 … 0.1101098870591658 0.11003592190538328; 4.6676976507912387e-7 4.812751477636772e-7 … 0.1101098870591658 0.11003592190538328; … ; 4.6676976507912387e-7 4.812751477636772e-7 … 0.1101098870591658 0.11003592190538328; 4.6676976507912387e-7 4.812751477636772e-7 … 0.1101098870591658 0.11003592190538328], [4.667809477853444e-7 4.812909134009797e-7 … 0.10858141214327631 0.10843754795446797; 4.667809477853444e-7 4.812909134009797e-7 … 0.10858141214327631 0.10843754795446797; … ; 4.667809477853444e-7 4.812909134009797e-7 … 0.10858141214327631 0.10843754795446797; 4.667809477853444e-7 4.812909134009797e-7 … 0.10858141214327631 0.10843754795446797], [4.667803793501522e-7 4.812848547406699e-7 … 0.1085489599010602 0.10866580356963161; 4.667803793501522e-7 4.812848547406699e-7 … 0.1085489599010602 0.10866580356963161; … ; 4.667803793501522e-7 4.812848547406699e-7 … 0.1085489599010602 0.10866580356963161; 4.667803793501522e-7 4.812848547406699e-7 … 0.1085489599010602 0.10866580356963161], [4.6679573161647894e-7 4.813096839082656e-7 … 0.10940225739667002 0.10880857207051305; 4.6679573161647894e-7 4.813096839082656e-7 … 0.10940225739667002 0.10880857207051305; … ; 4.6679573161647894e-7 4.813096839082656e-7 … 0.10940225739667002 0.10880857207051305; 4.6679573161647894e-7 4.813096839082656e-7 … 0.10940225739667002 0.10880857207051305], [4.6678002385966536e-7 4.812865175440708e-7 … 0.10972656824716241 0.10945932336085137; 4.6678002385966536e-7 4.812865175440708e-7 … 0.10972656824716241 0.10945932336085137; … ; 4.6678002385966536e-7 4.812865175440708e-7 … 0.10972656824716241 0.10945932336085137; 4.6678002385966536e-7 4.812865175440708e-7 … 0.10972656824716241 0.10945932336085137], [4.6677171971870653e-7 4.812699602061995e-7 … 0.10967583683968916 0.10963209236769736; 4.6677171971870653e-7 4.812699602061995e-7 … 0.10967583683968916 0.10963209236769736; … ; 4.6677171971870653e-7 4.812699602061995e-7 … 0.10967583683968916 0.10963209236769736; 4.6677171971870653e-7 4.812699602061995e-7 … 0.10967583683968916 0.10963209236769736]], Any[[3.0 3.0 … 3.0 3.0; 3.0 3.0 … 3.0 3.0; … ; 3.0 3.0 … 3.0 3.0; 3.0 3.0 … 3.0 3.0], [2.999999956821519 3.0000000502013893 … 3.0002934852221146 3.0003750378761764; 2.999999956821519 3.0000000502013893 … 3.0002934852221146 3.0003750378761764; … ; 2.999999956821519 3.0000000502013893 … 3.0002934852221146 3.0003750378761764; 2.999999956821519 3.0000000502013893 … 3.0002934852221146 3.0003750378761764], [2.999999989578114 3.0000002581998304 … 3.0009833942194444 3.0004054986024085; 2.999999989578114 3.0000002581998304 … 3.0009833942194444 3.0004054986024085; … ; 2.999999989578114 3.0000002581998304 … 3.0009833942194444 3.0004054986024085; 2.999999989578114 3.0000002581998304 … 3.0009833942194444 3.0004054986024085], [3.000000051990344 3.0000004739843367 … 3.003088320406456 3.000250915945971; 3.000000051990344 3.0000004739843367 … 3.003088320406456 3.000250915945971; … ; 3.000000051990344 3.0000004739843367 … 3.003088320406456 3.000250915945971; 3.000000051990344 3.0000004739843367 … 3.003088320406456 3.000250915945971], [3.000000125505073 3.000000690492175 … 3.0033052967549714 3.0000922951339963; 3.000000125505073 3.000000690492175 … 3.0033052967549714 3.0000922951339963; … ; 3.000000125505073 3.000000690492175 … 3.0033052967549714 3.0000922951339963; 3.000000125505073 3.000000690492175 … 3.0033052967549714 3.0000922951339963], [3.000000194933534 3.0000009025845698 … 3.0029702542282353 3.000999467711347; 3.000000194933534 3.0000009025845698 … 3.0029702542282353 3.000999467711347; … ; 3.000000194933534 3.0000009025845698 … 3.0029702542282353 3.000999467711347; 3.000000194933534 3.0000009025845698 … 3.0029702542282353 3.000999467711347], [3.000000255707054 3.000001105387126 … 3.0041344506270975 3.0014795619455232; 3.000000255707054 3.000001105387126 … 3.0041344506270975 3.0014795619455232; … ; 3.000000255707054 3.000001105387126 … 3.0041344506270975 3.0014795619455232; 3.000000255707054 3.000001105387126 … 3.0041344506270975 3.0014795619455232], [3.0000003075372548 3.000001298602689 … 3.0044629046782787 3.0013934098002557; 3.0000003075372548 3.000001298602689 … 3.0044629046782787 3.0013934098002557; … ; 3.0000003075372548 3.000001298602689 … 3.0044629046782787 3.0013934098002557; 3.0000003075372548 3.000001298602689 … 3.0044629046782787 3.0013934098002557], [3.0000003514677154 3.0000014833935476 … 3.005373439229455 3.0008974090167615; 3.0000003514677154 3.0000014833935476 … 3.005373439229455 3.0008974090167615; … ; 3.0000003514677154 3.0000014833935476 … 3.005373439229455 3.0008974090167615; 3.0000003514677154 3.0000014833935476 … 3.005373439229455 3.0008974090167615], [3.0000003916108406 3.000001664152535 … 3.0069377202353325 3.001030727432884; 3.0000003916108406 3.000001664152535 … 3.0069377202353325 3.001030727432884; … ; 3.0000003916108406 3.000001664152535 … 3.0069377202353325 3.001030727432884; 3.0000003916108406 3.000001664152535 … 3.0069377202353325 3.001030727432884]  …  [3.000000749491847 3.000006178106097 … 3.011928834867804 3.006672779416718; 3.000000749491847 3.000006178106097 … 3.011928834867804 3.006672779416718; … ; 3.000000749491847 3.000006178106097 … 3.011928834867804 3.006672779416718; 3.000000749491847 3.000006178106097 … 3.011928834867804 3.006672779416718], [3.0000007504173785 3.000006316698868 … 3.012092691761517 3.0066301949673058; 3.0000007504173785 3.000006316698868 … 3.012092691761517 3.0066301949673058; … ; 3.0000007504173785 3.000006316698868 … 3.012092691761517 3.0066301949673058; 3.0000007504173785 3.000006316698868 … 3.012092691761517 3.0066301949673058], [3.000000750540366 3.000006454294585 … 3.013179778155918 3.007052013328368; 3.000000750540366 3.000006454294585 … 3.013179778155918 3.007052013328368; … ; 3.000000750540366 3.000006454294585 … 3.013179778155918 3.007052013328368; 3.000000750540366 3.000006454294585 … 3.013179778155918 3.007052013328368], [3.0000007504766613 3.000006591875747 … 3.013800322179144 3.007323080661366; 3.0000007504766613 3.000006591875747 … 3.013800322179144 3.007323080661366; … ; 3.0000007504766613 3.000006591875747 … 3.013800322179144 3.007323080661366; 3.0000007504766613 3.000006591875747 … 3.013800322179144 3.007323080661366], [3.000000751341308 3.000006730738288 … 3.0140885821427283 3.0082336806122076; 3.000000751341308 3.000006730738288 … 3.0140885821427283 3.0082336806122076; … ; 3.000000751341308 3.000006730738288 … 3.0140885821427283 3.0082336806122076; 3.000000751341308 3.000006730738288 … 3.0140885821427283 3.0082336806122076], [3.0000007518833125 3.0000068688083124 … 3.0156704098912415 3.0077976052827524; 3.0000007518833125 3.0000068688083124 … 3.0156704098912415 3.0077976052827524; … ; 3.0000007518833125 3.0000068688083124 … 3.0156704098912415 3.0077976052827524; 3.0000007518833125 3.0000068688083124 … 3.0156704098912415 3.0077976052827524], [3.0000007520396506 3.000007006769762 … 3.016022364176317 3.007787072396331; 3.0000007520396506 3.000007006769762 … 3.016022364176317 3.007787072396331; … ; 3.0000007520396506 3.000007006769762 … 3.016022364176317 3.007787072396331; 3.0000007520396506 3.000007006769762 … 3.016022364176317 3.007787072396331], [3.0000007519060343 3.0000071441290928 … 3.0165089945029724 3.007885105585649; 3.0000007519060343 3.0000071441290928 … 3.0165089945029724 3.007885105585649; … ; 3.0000007519060343 3.0000071441290928 … 3.0165089945029724 3.007885105585649; 3.0000007519060343 3.0000071441290928 … 3.0165089945029724 3.007885105585649], [3.0000007515785754 3.0000072811154808 … 3.0165808492839505 3.0083107691455604; 3.0000007515785754 3.0000072811154808 … 3.0165808492839505 3.0083107691455604; … ; 3.0000007515785754 3.0000072811154808 … 3.0165808492839505 3.0083107691455604; 3.0000007515785754 3.0000072811154808 … 3.0165808492839505 3.0083107691455604], [3.0000007498186507 3.000007415003503 … 3.01622526894819 3.0085675580113542; 3.0000007498186507 3.000007415003503 … 3.01622526894819 3.0085675580113542; … ; 3.0000007498186507 3.000007415003503 … 3.01622526894819 3.0085675580113542; 3.0000007498186507 3.000007415003503 … 3.01622526894819 3.0085675580113542]])

Visualizing the landfast belt

x = xnodes(grid, Center()) ./ 1e3
y = ynodes(grid, Center()) ./ 1e3

Nt = length(landfast_speed)
iter = Observable(Nt)

sᵈ = @lift(100 .* drifting_speed[$iter])
sˡ = @lift(100 .* landfast_speed[$iter])
hˡ = @lift(landfast_thickness[$iter])

fig = Figure(size = (1100, 640))

ax = Axis(fig[1, 1], title = "Ice speed without basal stress (cm/s)",
          xlabel = "x (km)", ylabel = "y (km)")
heatmap!(ax, x, y, sᵈ, colormap = :speed, colorrange = (0, 30))
hlines!(ax, grounding_line / 1e3, color = :white, linestyle = :dash, linewidth = 2)

ax = Axis(fig[1, 2], title = "Ice speed with basal stress (cm/s)",
          xlabel = "x (km)", ylabel = "y (km)")
hm = heatmap!(ax, x, y, sˡ, colormap = :speed, colorrange = (0, 30))
hlines!(ax, grounding_line / 1e3, color = :white, linestyle = :dash, linewidth = 2)
Colorbar(fig[1, 3], hm)
Makie.Colorbar()

The cross-shore profile makes the arrest unambiguous: the belt inshore of the grounding line stops while the pack offshore of it keeps drifting.

ax = Axis(fig[2, 1:3], title = "Cross-shore profile of ice speed",
          xlabel = "Distance from the coast (km)", ylabel = "Speed (cm/s)")
lines!(ax, y, @lift(vec(sum($sᵈ, dims=1)) ./ Nx), linewidth = 3, label = "no basal stress")
lines!(ax, y, @lift(vec(sum($sˡ, dims=1)) ./ Nx), linewidth = 3, label = "basal stress")
vlines!(ax, grounding_line / 1e3, color = :black, linestyle = :dash, label = "grounding line")
axislegend(ax, position = :rb)
ylims!(ax, 0, 30)

CairoMakie.record(fig, "landfast_sea_ice.mp4", 1:Nt, framerate = 8) do i
    iter[] = i
end

Without the basal stress the whole pack drifts at a uniform 25 cm/s, and the coast is simply a wall the ice piles against. With it, the ice inshore of the grounding line is held by its keels and stops dead. The step in the cross-shore profile is the landfast edge, and it falls where the bathymetry crosses $H = k₁ h / ℵ$ — a line fixed by the parameters, not fitted to the result.

The pack offshore of the belt is not merely left alone: it slows from 25 to about 11 cm/s. Sea ice is a continuum, so the grounded belt buttresses the ice beyond it through the internal stress. That indirect effect reaches much further than the grounding line itself, which is why a landfast parameterization changes an ice pack well outside the shallow water it acts in.


This page was generated using Literate.jl.