Skip to content

Stress balance free drift model #72

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 84 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
82e3a7c
add this
simone-silvestri Mar 7, 2025
e2d7bea
Update freezing_of_a_lake.jl
simone-silvestri Mar 7, 2025
b935dff
formatting
simone-silvestri Mar 8, 2025
a2477ce
some fixes
simone-silvestri Mar 10, 2025
d543278
hmm, not sure heat capacity is consistent here
simone-silvestri Mar 10, 2025
6aa378c
add to examples?
simone-silvestri Mar 13, 2025
e169eca
the seasonal cycle is not that well predicted I guess
simone-silvestri Mar 13, 2025
bf42993
Merge branch 'main' into ss/fix-examples
simone-silvestri Mar 13, 2025
499e4ff
add this
simone-silvestri Mar 13, 2025
75a3f25
Merge branch 'ss/fix-examples' of github.com:CliMA/ClimaSeaIce.jl int…
simone-silvestri Mar 13, 2025
fd8e294
the fluxes have wrong signs
simone-silvestri Mar 13, 2025
876c2f4
missing a minus and a conversion factor
simone-silvestri Mar 13, 2025
b56dca3
some error in the table
simone-silvestri Mar 13, 2025
c033058
muuuch better
simone-silvestri Mar 13, 2025
b857445
much better
simone-silvestri Mar 13, 2025
1b05402
fix examples
simone-silvestri Mar 13, 2025
fdeab12
add ice salinity
simone-silvestri Mar 13, 2025
a209c01
ok this works
simone-silvestri Mar 13, 2025
bc16771
small fix
simone-silvestri Mar 13, 2025
6cb53a5
cairomakie
simone-silvestri Mar 20, 2025
6414056
fix examples
simone-silvestri Mar 20, 2025
07656ab
energy budget
simone-silvestri Mar 20, 2025
e95488b
add an energy budgets
simone-silvestri Mar 20, 2025
cf5a04b
Update src/SeaIceThermodynamics/slab_thermodynamics_tendencies.jl
simone-silvestri Mar 24, 2025
bde6e04
this should work
simone-silvestri Mar 25, 2025
e522985
Merge branch 'ss/fix-examples' of github.com:CliMA/ClimaSeaIce.jl int…
simone-silvestri Mar 25, 2025
2d3b1c7
add a change to conc
simone-silvestri Mar 25, 2025
e46b00b
Merge branch 'main' into ss/fix-examples
simone-silvestri Apr 30, 2025
ec32728
ifelse
simone-silvestri Apr 30, 2025
05819b9
drop heavy examples
simone-silvestri Apr 30, 2025
e131d54
drop heavy examples
simone-silvestri Apr 30, 2025
bb01c62
Merge branch 'main' into ss/fix-examples
navidcy Apr 30, 2025
699035e
show figs
simone-silvestri Apr 30, 2025
76f2553
just one dynamical case
simone-silvestri Apr 30, 2025
e423fb2
heat budget
simone-silvestri Apr 30, 2025
8505222
better naming
simone-silvestri Apr 30, 2025
72a2b72
correct
simone-silvestri Apr 30, 2025
845dc13
fix the example
simone-silvestri May 1, 2025
b1e471a
back to 20 days
simone-silvestri May 1, 2025
e7c3fba
add
simone-silvestri May 1, 2025
1448378
Merge remote-tracking branch 'origin/main' into ss/free-drift
simone-silvestri May 22, 2025
64fa5d4
flux balance
simone-silvestri May 22, 2025
bc9aab3
no need for C
simone-silvestri May 22, 2025
1b325c9
add a way to timestep only with free drift
simone-silvestri May 22, 2025
edc83f1
add it
simone-silvestri May 22, 2025
d8c3577
comment
simone-silvestri May 22, 2025
c204d21
add it
simone-silvestri May 22, 2025
a8645bb
fallbacks
simone-silvestri May 22, 2025
5a91887
comment
simone-silvestri May 22, 2025
d80931b
no need to do this
simone-silvestri May 22, 2025
7e906e6
inbounds
simone-silvestri May 22, 2025
8e3c1d8
last fix
simone-silvestri May 22, 2025
3aa3d39
SeaIcedynamics
simone-silvestri May 22, 2025
3a9aac7
name changes
simone-silvestri May 22, 2025
d45ba46
fix example
simone-silvestri May 22, 2025
81e3eb2
introducing an adapt
simone-silvestri May 22, 2025
8e826fe
another bugfix
simone-silvestri May 22, 2025
148ae8a
an example
simone-silvestri May 22, 2025
5a6b3fb
better defaults
simone-silvestri May 22, 2025
cae2b40
Merge branch 'main' into ss/free-drift
simone-silvestri May 22, 2025
a1d867b
bugfix
simone-silvestri May 22, 2025
67270fa
Merge branch 'ss/free-drift' of github.com:CliMA/ClimaSeaIce.jl into …
simone-silvestri May 22, 2025
1be457b
Update stress_balance_free_drift.jl
simone-silvestri May 22, 2025
0669e43
Update src/SeaIceDynamics/sea_ice_momentum_equations.jl
simone-silvestri May 22, 2025
8f91768
Merge branch 'main' into ss/free-drift
simone-silvestri May 23, 2025
735b386
Merge remote-tracking branch 'origin/main' into ss/free-drift
simone-silvestri May 23, 2025
0f13b14
Merge branch 'ss/free-drift' of github.com:CliMA/ClimaSeaIce.jl into …
simone-silvestri May 23, 2025
ef20d9b
add a quadratic formulation
simone-silvestri May 23, 2025
b9c22b4
add an explanation
simone-silvestri May 23, 2025
c260232
remove one coefficient
simone-silvestri May 23, 2025
93daca2
make sure we don't nan
simone-silvestri May 23, 2025
d2bea13
better comment
simone-silvestri May 23, 2025
2257f8d
fix another comment
simone-silvestri May 23, 2025
d38f428
remove model
simone-silvestri May 23, 2025
8a2efbb
comment
simone-silvestri May 23, 2025
debe548
comment
simone-silvestri May 23, 2025
040f0a2
add this simplified formula
simone-silvestri May 23, 2025
290cfb9
bugfix
simone-silvestri May 23, 2025
a0ae17a
leave this case for later?
simone-silvestri May 23, 2025
d048336
add a fallback
simone-silvestri May 23, 2025
2d7b08c
just pass any
simone-silvestri May 23, 2025
41a996d
correct locations
simone-silvestri May 23, 2025
bec0a3e
correct default
simone-silvestri May 23, 2025
51e4d8d
adapt bugfix
simone-silvestri May 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/src/library/public.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ Modules = [ClimaSeaIce.Rheologies]
Private = false
```

## ClimaSeaIce.SeaIceMomentumEquations
## ClimaSeaIce.SeaIceDynamics

```@autodocs
Modules = [ClimaSeaIce.SeaIceMomentumEquations]
Modules = [ClimaSeaIce.SeaIceDynamics]
Private = false
```
17 changes: 6 additions & 11 deletions examples/ice_advected_by_anticyclone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#
#
using ClimaSeaIce
using ClimaSeaIce.SeaIceMomentumEquations
using ClimaSeaIce.SeaIceDynamics
using ClimaSeaIce.Rheologies
using Oceananigans
using Oceananigans.Units
Expand Down Expand Up @@ -86,18 +86,13 @@ fill_halo_regions!((Uₐ, Vₐ))
# We use an elasto-visco-plastic rheology and WENO seventh order
# for advection of h and ℵ

momentum_equations = SeaIceMomentumEquation(grid;
top_momentum_stress = (u=τₐu, v=τₐv),
bottom_momentum_stress = τₒ,
coriolis = FPlane(f=1e-4),
ocean_velocities = (u = Uₒ, v = Vₒ),
rheology = ElastoViscoPlasticRheology(),
solver = SplitExplicitSolver(substeps=150))

# Define the model!
dynamics = SeaIceMomentumEquation(grid;
top_momentum_stress = (u=τₐu, v=τₐv),
bottom_momentum_stress = τₒ,
coriolis = FPlane(f=1e-4))

model = SeaIceModel(grid;
dynamics = momentum_equations,
dynamics,
ice_thermodynamics = nothing, # No ice_thermodynamics here
advection = WENO(order=7),
boundary_conditions = (u=u_bcs, v=v_bcs))
Expand Down
2 changes: 1 addition & 1 deletion examples/ice_advected_on_coastline.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using ClimaSeaIce
using ClimaSeaIce.SeaIceMomentumEquations
using ClimaSeaIce.SeaIceDynamics
using ClimaSeaIce.Rheologies
using Oceananigans
using Oceananigans.Units
Expand Down
4 changes: 2 additions & 2 deletions src/ClimaSeaIce.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ include("forward_euler_timestepper.jl")

include("SeaIceThermodynamics/SeaIceThermodynamics.jl")
include("Rheologies/Rheologies.jl")
include("SeaIceMomentumEquations/SeaIceMomentumEquations.jl")
include("SeaIceDynamics/SeaIceDynamics.jl")
include("sea_ice_model.jl")
include("sea_ice_advection.jl")
include("tracer_tendency_kernel_functions.jl")
include("sea_ice_time_stepping.jl")
include("EnthalpyMethodSeaIceModel.jl")

using .SeaIceThermodynamics
using .SeaIceMomentumEquations
using .SeaIceDynamics
using .Rheologies

# Advection timescale for a `SeaIceModel`. Sea ice dynamics are two-dimensional so
Expand Down
5 changes: 5 additions & 0 deletions src/Rheologies/Rheologies.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ compute_stresses!(model, dynamics, rheology, Δt) = nothing
@inline sum_of_forcing_u(i, j, k, grid, rheology, u_forcing, fields, Δt) = u_forcing(i, j, k, grid, fields)
@inline sum_of_forcing_v(i, j, k, grid, rheology, v_forcing, fields, Δt) = v_forcing(i, j, k, grid, fields)

@inline ice_stress_ux(i, j, k, grid, ::Nothing, args...) = zero(grid)
@inline ice_stress_uy(i, j, k, grid, ::Nothing, args...) = zero(grid)
@inline ice_stress_vx(i, j, k, grid, ::Nothing, args...) = zero(grid)
@inline ice_stress_vy(i, j, k, grid, ::Nothing, args...) = zero(grid)

include("ice_stress_divergence.jl")
include("viscous_rheology.jl")
include("elasto_visco_plastic_rheology.jl")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module SeaIceMomentumEquations
module SeaIceDynamics

# The only functions provided by the module
export compute_momentum_tendencies!, time_step_momentum!
export SeaIceMomentumEquation, ExplicitSolver, SplitExplicitSolver, SemiImplicitStress
export SeaIceMomentumEquation, ExplicitSolver, SplitExplicitSolver, SemiImplicitStress, StressBalanceFreeDrift

using ClimaSeaIce

Expand Down Expand Up @@ -46,8 +46,9 @@ import Oceananigans: fields
time_step_momentum!(model, dynamics, Δt) = nothing
compute_momentum_tendencies!(model, dynamics, Δt) = nothing

include("sea_ice_momentum_equations.jl")
include("sea_ice_external_stress.jl")
include("stress_balance_free_drift.jl")
include("sea_ice_momentum_equations.jl")
include("momentum_tendencies_kernel_functions.jl")
include("explicit_momentum_equations.jl")
include("split_explicit_momentum_equations.jl")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function time_step_momentum!(model, ::ExplicitMomentumEquation, Δt)
ρ = model.ice_density))


ocean_velocities = dynamics.ocean_velocities
free_drift = dynamics.free_drift
clock = model.clock
minimum_mass = dynamics.minimum_mass
minimum_concentration = dynamics.minimum_concentration
Expand All @@ -27,15 +27,15 @@ function time_step_momentum!(model, ::ExplicitMomentumEquation, Δt)
bottom_stress = dynamics.external_momentum_stresses.bottom

launch!(arch, grid, :xy, _step_velocities!, u, v, grid, Gⁿ, Δt,
top_stress, bottom_stress, ocean_velocities,
top_stress, bottom_stress, free_drift,
minimum_mass, minimum_concentration, clock, model_fields)

return nothing
end

@kernel function _step_velocities!(u, v, grid, Gⁿ, Δt,
top_stress, bottom_stress,
ocean_velocities, minimum_mass, minimum_concentration, clock, fields)
free_drift, minimum_mass, minimum_concentration, clock, fields)

i, j = @index(Global, NTuple)
kᴺ = size(grid, 3)
Expand All @@ -56,8 +56,8 @@ end
uᴰ = (u[i, j, 1] + Δt * Gⁿ.u[i, j, 1]) / (1 + Δt * τuᵢ)
vᴰ = (v[i, j, 1] + Δt * Gⁿ.v[i, j, 1]) / (1 + Δt * τvᵢ)

uᶠ = free_drift_u(i, j, kᴺ, grid, ocean_velocities)
vᶠ = free_drift_v(i, j, kᴺ, grid, ocean_velocities)
uᶠ = free_drift_u(i, j, kᴺ, grid, free_drift, clock, fields)
vᶠ = free_drift_v(i, j, kᴺ, grid, free_drift, clock, fields)

sea_ice = (mᶠᶜ ≥ minimum_mass) & (ℵᶠᶜ ≥ minimum_concentration)
u[i, j, 1] = ifelse(sea_ice, uᴰ, uᶠ)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using ClimaSeaIce.Rheologies
using Adapt

struct SeaIceMomentumEquation{S, C, R, V, A, ES, FT}
struct SeaIceMomentumEquation{S, C, R, F, A, ES, FT}
coriolis :: C
rheology :: R
auxiliary_fields :: A
solver :: S
ocean_velocities :: V
free_drift :: F
external_momentum_stresses :: ES
minimum_concentration :: FT
minimum_mass :: FT
Expand All @@ -17,16 +17,19 @@ struct ExplicitSolver end

"""
SeaIceMomentumEquation(grid;
coriolis=nothing,
rheology=ElastoViscoPlasticRheology(eltype(grid)),
auxiliary_fields=NamedTuple(),
ocean_velocities=nothing,
solver=ExplicitSolver(),
minimum_concentration=1e-3,
minimum_mass=1.0)
coriolis = nothing,
rheology = ElastoViscoPlasticRheology(eltype(grid)),
auxiliary_fields = NamedTuple(),
top_momentum_stress = (u=nothing, v=nothing),
bottom_momentum_stress = (u=nothing, v=nothing),
free_drift = StressBalanceFreeDrift(top_momentum_stress, bottom_momentum_stress),
solver = SplitExplicitSolver(150),
minimum_concentration = 1e-3,
minimum_mass = 1.0)

Constructs a `SeaIceMomentumEquation` object that controls the dynamical evolution of sea-ice momentum.
The sea-ice momentum obey the following evolution equation:

```math
∂u τₒ τₐ
-- + f x u = ∇ ⋅ σ + -- + --
Expand All @@ -46,8 +49,8 @@ Keyword Arguments
- `coriolis`: Parameters for the background rotation rate of the model.
- `rheology`: The sea ice rheology model, default is `ElastoViscoPlasticRheology(eltype(grid))`.
- `auxiliary_fields`: A named tuple of auxiliary fields, default is an empty `NamedTuple()`.
- `ocean_velocities`: The ocean surface velocities used to limit the sea ice momentum when the mass or the concentration are
below a certain threshold. default is `nothing` (indicating that the free drift velocities are zero).
- `free_drift`: The free drift velocities used to limit sea ice momentum when the mass or the concentration are
below a certain threshold. default is `nothing` (indicating that the free drift velocities are zero).
- `solver`: The momentum solver to be used.
- `minimum_concentration`: The minimum sea ice concentration above which the sea ice velocity is dynamically calculated, default is `1e-3`.
- `minimum_mass`: The minimum sea ice mass per area above which the sea ice velocity is dynamically calculated, default is `1.0 kg/m²`.
Expand All @@ -56,10 +59,10 @@ function SeaIceMomentumEquation(grid;
coriolis = nothing,
rheology = ElastoViscoPlasticRheology(eltype(grid)),
auxiliary_fields = NamedTuple(),
ocean_velocities = nothing,
top_momentum_stress = (u = nothing, v = nothing),
bottom_momentum_stress = (u = nothing, v = nothing),
solver = ExplicitSolver(),
top_momentum_stress = nothing,
bottom_momentum_stress = nothing,
free_drift = StressBalanceFreeDrift(top_momentum_stress, bottom_momentum_stress),
solver = SplitExplicitSolver(150),
minimum_concentration = 1e-3,
minimum_mass = 1.0)

Expand All @@ -73,18 +76,10 @@ function SeaIceMomentumEquation(grid;
rheology,
auxiliary_fields,
solver,
ocean_velocities,
free_drift,
external_momentum_stresses,
convert(FT, minimum_concentration),
convert(FT, minimum_mass))
end

fields(mom::SeaIceMomentumEquation) = mom.auxiliary_fields

# Just passing ocean velocities without mitigation
@inline free_drift_u(i, j, k, grid, f) = @inbounds f.u[i, j, k]
@inline free_drift_v(i, j, k, grid, f) = @inbounds f.v[i, j, k]

# Passing no velocities
@inline free_drift_u(i, j, k, grid, ::Nothing) = zero(grid)
@inline free_drift_v(i, j, k, grid, ::Nothing) = zero(grid)
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function time_step_momentum!(model, dynamics::SplitExplicitMomentumEquation, Δt

u, v = model.velocities

ocean_velocities = dynamics.ocean_velocities
free_drift = dynamics.free_drift
clock = model.clock
coriolis = dynamics.coriolis

Expand All @@ -55,8 +55,10 @@ function time_step_momentum!(model, dynamics::SplitExplicitMomentumEquation, Δt
ℵ = model.ice_concentration,
ρ = model.ice_density))

u_velocity_kernel!, _ = configure_kernel(arch, grid, :xy, _u_velocity_step!)
v_velocity_kernel!, _ = configure_kernel(arch, grid, :xy, _v_velocity_step!)
active_cells_map = Oceananigans.Grids.get_active_column_map(grid)

u_velocity_kernel!, _ = configure_kernel(arch, grid, :xy, _u_velocity_step!; active_cells_map)
v_velocity_kernel!, _ = configure_kernel(arch, grid, :xy, _v_velocity_step!; active_cells_map)

substeps = dynamics.solver.substeps

Expand All @@ -73,24 +75,24 @@ function time_step_momentum!(model, dynamics::SplitExplicitMomentumEquation, Δt
# In odd substeps we switch and calculate vⁿ⁺¹ = f(uⁿ) and uⁿ⁺¹ = f(vⁿ⁺¹).
if iseven(substep)
u_velocity_kernel!(u, grid, Δt, substeps, rheology, model_fields,
ocean_velocities, clock, coriolis,
free_drift, clock, coriolis,
minimum_mass, minimum_concentration,
u_immersed_bc, top_stress, bottom_stress, u_forcing)

v_velocity_kernel!(v, grid, Δt, substeps, rheology, model_fields,
ocean_velocities, clock, coriolis,
free_drift, clock, coriolis,
minimum_mass, minimum_concentration,
v_immersed_bc, top_stress, bottom_stress, v_forcing)

else
v_velocity_kernel!(v, grid, Δt, substeps, rheology, model_fields,
ocean_velocities, clock, coriolis,
free_drift, clock, coriolis,
minimum_mass, minimum_concentration,
v_immersed_bc, top_stress, bottom_stress, v_forcing)


u_velocity_kernel!(u, grid, Δt, substeps, rheology, model_fields,
ocean_velocities, clock, coriolis,
free_drift, clock, coriolis,
minimum_mass, minimum_concentration,
u_immersed_bc, top_stress, bottom_stress, u_forcing)
end
Expand All @@ -107,7 +109,7 @@ end

@kernel function _u_velocity_step!(u, grid, Δt,
substeps, rheology,
model_fields, ocean_velocities,
model_fields, free_drift,
clock, coriolis,
minimum_mass, minimum_concentration,
u_immersed_bc, u_top_stress, u_bottom_stress, u_forcing)
Expand All @@ -127,7 +129,7 @@ end

τuᵢ = ifelse(mᵢ ≤ 0, zero(grid), τuᵢ)
uᴰ = @inbounds (u[i, j, 1] + Δτ * Gu) / (1 + Δτ * τuᵢ) # dynamical velocity
uᶠ = free_drift_u(i, j, kᴺ, grid, ocean_velocities) # free drift velocity
uᶠ = free_drift_u(i, j, kᴺ, grid, free_drift, clock, model_fields) # free drift velocity

# If the ice mass or the ice concentration are below a certain threshold,
# the sea ice velocity is set to the free drift velocity
Expand All @@ -138,7 +140,7 @@ end

@kernel function _v_velocity_step!(v, grid, Δt,
substeps, rheology,
model_fields, ocean_velocities,
model_fields, free_drift,
clock, coriolis,
minimum_mass, minimum_concentration,
v_immersed_bc, v_top_stress, v_bottom_stress, v_forcing)
Expand All @@ -159,7 +161,7 @@ end
τvᵢ = ifelse(mᵢ ≤ 0, zero(grid), τvᵢ)

vᴰ = @inbounds (v[i, j, 1] + Δτ * Gv) / (1 + Δτ * τvᵢ)# dynamical velocity
vᶠ = free_drift_v(i, j, kᴺ, grid, ocean_velocities) # free drift velocity
vᶠ = free_drift_v(i, j, kᴺ, grid, free_drift, clock, model_fields) # free drift velocity

# If the ice mass or the ice concentration are below a certain threshold,
# the sea ice velocity is set to the free drift velocity
Expand Down
Loading
Loading