Skip to content

B grid dynamics #55

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 121 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
4471c04
try it out
simone-silvestri Feb 25, 2025
dcf8162
almost done
simone-silvestri Feb 25, 2025
0e428a7
better
simone-silvestri Feb 25, 2025
acbfb10
complete Bgrid rheology
simone-silvestri Feb 25, 2025
f855c8b
kind of works?
simone-silvestri Feb 25, 2025
3cd0dc6
adapt
simone-silvestri Feb 25, 2025
05147ad
add
simone-silvestri Feb 26, 2025
30cd58b
will this work?
simone-silvestri Mar 3, 2025
31751e4
remove the show
simone-silvestri Mar 3, 2025
94c3aa2
bump to 0.2.1
simone-silvestri Mar 3, 2025
f840534
add this
simone-silvestri Mar 3, 2025
5bbb1ac
Merge branch 'ss/new-thermodynamic-timestep' of github.com:CliMA/Clim…
simone-silvestri Mar 3, 2025
f8739e5
make sure we do not mask point 1 but the top
simone-silvestri Mar 4, 2025
b27d6b8
bugfix
simone-silvestri Mar 4, 2025
b0843b0
update
simone-silvestri Mar 4, 2025
5643b95
start separating the two
simone-silvestri Mar 4, 2025
35af721
will this work?
simone-silvestri Mar 4, 2025
57fd25d
comment
simone-silvestri Mar 4, 2025
e3031d4
completely melt the ice
simone-silvestri Mar 4, 2025
74b07c0
adjust the thermodynamic step
simone-silvestri Mar 4, 2025
4cc60e6
will this work?
simone-silvestri Mar 4, 2025
2cd8cc2
some bugfixes
simone-silvestri Mar 4, 2025
70746a1
add freezing bucket
simone-silvestri Mar 4, 2025
5807494
remove the show
simone-silvestri Mar 4, 2025
5317586
adapt freezing bucket
simone-silvestri Mar 4, 2025
a9040d1
comment
simone-silvestri Mar 4, 2025
23c1576
add a comment for tomorrow
simone-silvestri Mar 4, 2025
4f3b3c9
this should work
simone-silvestri Mar 5, 2025
e928864
this works!
simone-silvestri Mar 5, 2025
b9b8836
Merge branch 'main' into ss/new-thermodynamic-timestep
simone-silvestri Mar 5, 2025
c9859ba
remove the show methods
simone-silvestri Mar 5, 2025
a518b5d
Merge branch 'ss/new-thermodynamic-timestep' of github.com:CliMA/Clim…
simone-silvestri Mar 5, 2025
af21933
fix examples
simone-silvestri Mar 5, 2025
0db4a5f
add freezing in winter
simone-silvestri Mar 5, 2025
f4ab9e7
new example
simone-silvestri Mar 5, 2025
632bd81
better
simone-silvestri Mar 5, 2025
e70f38a
only 10 days
simone-silvestri Mar 5, 2025
d6113ba
make
simone-silvestri Mar 5, 2025
d633392
keep a "thermodynamic_tendency"
simone-silvestri Mar 5, 2025
522656f
maybe a bit smaller font
simone-silvestri Mar 5, 2025
81c672b
fix examples
simone-silvestri Mar 5, 2025
331f198
correct examples
simone-silvestri Mar 5, 2025
8fc86f5
Merge remote-tracking branch 'origin/main' into ss/b-grid-dynamics
simone-silvestri Mar 6, 2025
37816a7
Merge remote-tracking branch 'origin/ss/new-thermodynamic-timestep' i…
simone-silvestri Mar 6, 2025
2869815
add this
simone-silvestri Mar 6, 2025
796459e
add it
simone-silvestri Mar 6, 2025
f02692c
add it
simone-silvestri Mar 6, 2025
274b8d9
improve
simone-silvestri Mar 6, 2025
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
9357d19
Merge remote-tracking branch 'origin/main' into ss/b-grid-dynamics
simone-silvestri Mar 26, 2025
946fca4
remove ice salinity from there
simone-silvestri Mar 26, 2025
13a69d0
fix the examples
simone-silvestri Mar 26, 2025
b41e338
improve
simone-silvestri Mar 26, 2025
bff5717
Merge remote-tracking branch 'origin/ss/fix-examples' into ss/b-grid-…
simone-silvestri Mar 26, 2025
a0bc65f
change name
simone-silvestri Mar 26, 2025
855b721
try it out
simone-silvestri Mar 26, 2025
aeab0f4
fixes
simone-silvestri Mar 26, 2025
fac6c5e
step tracers
simone-silvestri Mar 26, 2025
589bdef
adding ice_salinity
simone-silvestri Mar 26, 2025
7ae099f
take off the salinity from here
simone-silvestri Mar 26, 2025
7ada6a4
this should work
simone-silvestri Mar 26, 2025
7bd550f
merge here
simone-silvestri Mar 26, 2025
b4a4933
remove IS
simone-silvestri Mar 26, 2025
1908e9a
just remove it for now
simone-silvestri Mar 26, 2025
99279ba
full tau
simone-silvestri Mar 26, 2025
981d0f0
change name
simone-silvestri Mar 26, 2025
11a963a
bugfix
simone-silvestri Mar 27, 2025
9b49ed6
Merge remote-tracking branch 'origin/main' into ss/b-grid-dynamics
simone-silvestri May 1, 2025
87382c3
Merge remote-tracking branch 'origin/main' into ss/b-grid-dynamics
simone-silvestri May 1, 2025
c56616a
space
simone-silvestri May 1, 2025
73e0f46
more changes
simone-silvestri May 1, 2025
4b9d9ca
we can remove all this
simone-silvestri May 1, 2025
6f8237d
no more immersed stresses
simone-silvestri May 1, 2025
77712d6
better
simone-silvestri May 1, 2025
d524160
add ice salinity
simone-silvestri May 1, 2025
a9731ab
bugfix
simone-silvestri May 1, 2025
a3c8db5
adding
simone-silvestri May 5, 2025
90a0499
ice_thermodynamics
simone-silvestri May 5, 2025
64e37f5
do not use max(d, dm)
simone-silvestri May 5, 2025
d4aec31
remove BBM for the moment
simone-silvestri May 5, 2025
7c2c06f
actually need this regularization
simone-silvestri May 5, 2025
f558138
som fixes
simone-silvestri May 6, 2025
1fce552
not here for the moment
simone-silvestri May 6, 2025
8796748
fix tests
simone-silvestri May 6, 2025
fe39196
no need for these
simone-silvestri May 6, 2025
17837a5
some more fixes
simone-silvestri May 6, 2025
28e91a7
fixes for viscous rheology
simone-silvestri May 6, 2025
e97332d
bugfix
simone-silvestri May 6, 2025
0ba55eb
some corrections
simone-silvestri May 6, 2025
dddf06d
fix the symmetric advection
simone-silvestri May 6, 2025
89f7297
fix docs
simone-silvestri May 6, 2025
459be18
fix the momentum tendencies
simone-silvestri May 6, 2025
eb8a3f9
remove bbm for now
simone-silvestri May 6, 2025
92639cf
correct the tendencies
simone-silvestri May 14, 2025
9c6c6a0
Merge branch 'main' into ss/b-grid-dynamics
simone-silvestri May 21, 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/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ example_scripts = [
"melting_in_spring.jl",
"freezing_of_a_lake.jl",
"ice_advected_by_anticyclone.jl",
# "ice_advected_on_coastline.jl",
"ice_advected_on_coastline.jl",
"arctic_basin_seasonal_cycle.jl"
]

Expand All @@ -31,7 +31,7 @@ example_pages = [
"Melting in Spring" => "literated/melting_in_spring.md",
"Freezing of a Lake" => "literated/freezing_of_a_lake.md",
"Ice advected by anticyclone" => "literated/ice_advected_by_anticyclone.md",
# "Ice advected on coastline" => "literated/ice_advected_on_coastline.md",
"Ice advected on coastline" => "literated/ice_advected_on_coastline.md",
"Arctic basin seasonal cycle" => "literated/arctic_basin_seasonal_cycle.md"
]

Expand Down
6 changes: 3 additions & 3 deletions examples/freezing_bucket.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ top_heat_boundary_condition = PrescribedTemperature(-10)
# slab sea ice representation of ice_thermodynamics

ice_thermodynamics = SlabSeaIceThermodynamics(grid;
internal_heat_flux,
phase_transitions,
top_heat_boundary_condition)
internal_heat_flux,
phase_transitions,
top_heat_boundary_condition)

# We also prescribe a frazil ice heat flux that stops when the ice has reached a concentration of 1.
# This heat flux represents the initial ice formation from a liquid bucket.
Expand Down
22 changes: 13 additions & 9 deletions examples/ice_advected_by_anticyclone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ L = 512kilometers

# 2 km domain
grid = RectilinearGrid(arch;
size = (128, 128),
size = (256, 256),
x = (0, L),
y = (0, L),
halo = (7, 7),
Expand All @@ -35,19 +35,23 @@ grid = RectilinearGrid(arch;
##### Value boundary conditions for velocities
#####

u_bcs = FieldBoundaryConditions(north=ValueBoundaryCondition(0),
south=ValueBoundaryCondition(0))
u_bcs = FieldBoundaryConditions(north=OpenBoundaryCondition(0),
south=OpenBoundaryCondition(0),
west=OpenBoundaryCondition(0),
east=OpenBoundaryCondition(0))

v_bcs = FieldBoundaryConditions(west=ValueBoundaryCondition(0),
east=ValueBoundaryCondition(0))
v_bcs = FieldBoundaryConditions(north=OpenBoundaryCondition(0),
south=OpenBoundaryCondition(0),
west=OpenBoundaryCondition(0),
east=OpenBoundaryCondition(0))

#####
##### Ocean sea-ice stress
#####

# Constant ocean velocities corresponding to a cyclonic eddy
Uₒ = XFaceField(grid)
Vₒ = YFaceField(grid)
Uₒ = Field{Face, Face, Nothing}(grid)
Vₒ = Field{Face, Face, Nothing}(grid)

set!(Uₒ, (x, y) -> 𝓋ₒ * (2y - L) / L)
set!(Vₒ, (x, y) -> 𝓋ₒ * (L - 2x) / L)
Expand All @@ -59,8 +63,8 @@ fill_halo_regions!((Uₒ, Vₒ))
#### Atmosphere - sea ice stress
####

Uₐ = XFaceField(grid)
Vₐ = YFaceField(grid)
Uₐ = Field{Face, Face, Nothing}(grid)
Vₐ = Field{Face, Face, Nothing}(grid)

# Atmospheric velocities corresponding to an anticyclonic eddy moving north-east
@inline center(t) = 256kilometers + 51.2kilometers * t / 86400
Expand Down
5 changes: 0 additions & 5 deletions examples/ice_advected_on_coastline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,10 @@ dynamics = SeaIceMomentumEquation(grid;
rheology = ElastoViscoPlasticRheology(),
solver = SplitExplicitSolver(substeps=150))

u_bcs = FieldBoundaryConditions(top = nothing, bottom = nothing,
north = ValueBoundaryCondition(0),
south = ValueBoundaryCondition(0))

#Define the model!
model = SeaIceModel(grid;
advection = WENO(order=7),
dynamics = dynamics,
boundary_conditions = (; u=u_bcs),
ice_thermodynamics = nothing)

# We start with a concentration of ℵ = 1 everywhere
Expand Down
14 changes: 9 additions & 5 deletions src/Rheologies/Rheologies.jl
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
module Rheologies

export ViscousRheology, ElastoViscoPlasticRheology
export ∂ⱼ_σ₁ⱼ, ∂ⱼ_σ₂ⱼ, required_auxiliary_fields
export ∂ⱼ_σ₁ⱼ, ∂ⱼ_σ₂ⱼ, rheology_auxiliary_fields

using Oceananigans
using Oceananigans.Operators
using ClimaSeaIce: ice_mass

# Nothing rheology
required_auxiliary_fields(rheology, grid) = NamedTuple()
initialize_rheology!(model, rheology) = nothing
compute_stresses!(model, dynamics, rheology, Δt) = nothing
compute_stresses!(model, dynamics, rheology, Δt, Ns) = nothing

# Nothing rheology or viscous rheology
@inline compute_substep_Δtᶠᶜᶜ(i, j, grid, Δt, rheology, substeps, fields) = Δt / substeps
@inline compute_substep_Δtᶜᶠᶜ(i, j, grid, Δt, rheology, substeps, fields) = Δt / substeps
@inline compute_substep_Δtᶠᶠᶜ(i, j, grid, Δt, rheology, substeps, fields) = Δt / substeps

# Fallback
@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)

# No needed extra tracers
rheology_prognostic_tracers(rheology) = ()

# No needed auxiliary fields
rheology_auxiliary_fields(rheology, grid) = NamedTuple()

include("ice_stress_divergence.jl")
include("viscous_rheology.jl")
include("elasto_visco_plastic_rheology.jl")
Expand Down
131 changes: 54 additions & 77 deletions src/Rheologies/elasto_visco_plastic_rheology.jl
Original file line number Diff line number Diff line change
Expand Up @@ -105,19 +105,20 @@
pressure_formulation)
end

function required_auxiliary_fields(r::ElastoViscoPlasticRheology, grid)
function rheology_auxiliary_fields(r::ElastoViscoPlasticRheology, grid)

# TODO: What about boundary conditions?
σ₁₁ = Field{Center, Center, Nothing}(grid)
σ₂₂ = Field{Center, Center, Nothing}(grid)
σ₁₂ = Field{Face, Face, Nothing}(grid)
σ₁₂ = Field{Center, Center, Nothing}(grid)

uⁿ = Field{Face, Center, Nothing}(grid)
vⁿ = Field{Center, Face, Nothing}(grid)
P = Field{Center, Center, Nothing}(grid)
α = Field{Center, Center, Nothing}(grid) # Dynamic substeps a la Kimmritz et al (2016)
ζ = Field{Center, Center, Nothing}(grid)
Δ = Field{Center, Center, Nothing}(grid)
α = Field{Center, Center, Nothing}(grid) # Dynamic substeps a la Kimmritz et al (2016)

uⁿ = Field{Face, Face, Nothing}(grid)
vⁿ = Field{Face, Face, Nothing}(grid)

# An initial (safe) educated guess
fill!(α, r.max_relaxation_parameter)
Expand Down Expand Up @@ -170,7 +171,7 @@
@inline ice_strength(i, j, k, grid, P★, C, h, ℵ) = @inbounds P★ * h[i, j, k] * exp(- C * (1 - ℵ[i, j, k]))

# Specific compute stresses for the EVP rheology
function compute_stresses!(model, dynamics, rheology::ElastoViscoPlasticRheology, Δt)
function compute_stresses!(model, dynamics, rheology::ElastoViscoPlasticRheology, Δt, Ns)

grid = model.grid
arch = architecture(grid)
Expand All @@ -187,17 +188,25 @@

parameters = KernelParameters(-Hx+2:Nx+Hx-1, -Hy+2:Ny+Hy-1)

launch!(arch, grid, parameters, _compute_evp_viscosities!, fields, grid, rheology, u, v)
launch!(arch, grid, parameters, _compute_evp_stresses!, fields, grid, rheology, u, v, h, ℵ, ρᵢ, Δt)
launch!(arch, grid, parameters, _compute_evp_viscosities!, fields, grid, rheology, u, v, h, ℵ, ρᵢ, Δt)

return nothing
end

@inline strain_rate_xx(i, j, k, grid, u, v) = δxᶜᵃᵃ(i, j, k, grid, Δy_qᶠᶜᶜ, u) / Azᶜᶜᶜ(i, j, k, grid)
@inline strain_rate_yy(i, j, k, grid, u, v) = δyᵃᶜᵃ(i, j, k, grid, Δx_qᶜᶠᶜ, v) / Azᶜᶜᶜ(i, j, k, grid)
@inline strain_rate_xy(i, j, k, grid, u, v) = (δxᶠᵃᵃ(i, j, k, grid, Δy_qᶜᶠᶜ, v) + δyᵃᶠᵃ(i, j, k, grid, Δx_qᶠᶜᶜ, u)) / Azᶠᶠᶜ(i, j, k, grid) / 2
@inline strain_rate_xx(i, j, k, grid, u, v) = ℑyᵃᶜᵃ(i, j, k, grid, δxᶜᵃᵃ, Δy_qᶠᶠᶜ, u) * Az⁻¹ᶜᶜᶜ(i, j, k, grid)
@inline strain_rate_yy(i, j, k, grid, u, v) = ℑxᶜᵃᵃ(i, j, k, grid, δyᵃᶜᵃ, Δx_qᶠᶠᶜ, v) * Az⁻¹ᶜᶜᶜ(i, j, k, grid)
@inline strain_rate_xy(i, j, k, grid, u, v) = (δxᶜᵃᵃ(i, j, k, grid, ℑyᵃᶜᵃ, Δy_qᶠᶠᶜ, v) + δyᵃᶜᵃ(i, j, k, grid, ℑxᶜᵃᵃ, Δx_qᶠᶠᶜ, u)) * Az⁻¹ᶜᶜᶜ(i, j, k, grid) / 2

@inline ice_pressure(i, j, k, grid, ::IceStrength, r, fields) = @inbounds fields.P[i, j, k]

Check warning on line 200 in src/Rheologies/elasto_visco_plastic_rheology.jl

View check run for this annotation

Codecov / codecov/patch

src/Rheologies/elasto_visco_plastic_rheology.jl#L200

Added line #L200 was not covered by tests

@kernel function _compute_evp_viscosities!(fields, grid, rheology, u, v)
@inline function ice_pressure(i, j, k, grid, ::ReplacementPressure, r, fields)
Pᶜᶜᶜ = @inbounds fields.P[i, j, k]
Δᶜᶜᶜ = @inbounds fields.Δ[i, j, k]
Δm = r.minimum_plastic_stress
return Pᶜᶜᶜ * Δᶜᶜᶜ / (Δᶜᶜᶜ + Δm)
end

@kernel function _compute_evp_viscosities!(fields, grid, rheology, u, v, h, ℵ, ρᵢ, Δt)

Check warning on line 209 in src/Rheologies/elasto_visco_plastic_rheology.jl

View check run for this annotation

Codecov / codecov/patch

src/Rheologies/elasto_visco_plastic_rheology.jl#L209

Added line #L209 was not covered by tests
i, j = @index(Global, NTuple)
kᴺ = size(grid, 3)

Expand All @@ -210,41 +219,24 @@
# Strain rates
ϵ̇₁₁ = strain_rate_xx(i, j, kᴺ, grid, u, v)
ϵ̇₂₂ = strain_rate_yy(i, j, kᴺ, grid, u, v)

# Center - Center variables:
ϵ̇₁₂ᶜᶜᶜ = ℑxyᶜᶜᵃ(i, j, kᴺ, grid, strain_rate_xy, u, v)
ϵ̇₁₂ = strain_rate_xy(i, j, kᴺ, grid, u, v)

# Ice divergence
δ = ϵ̇₁₁ + ϵ̇₂₂

# Ice shear (at Centers)
s = sqrt((ϵ̇₁₁ - ϵ̇₂₂)^2 + 4ϵ̇₁₂ᶜᶜᶜ^2)
s = sqrt((ϵ̇₁₁ - ϵ̇₂₂)^2 + 4ϵ̇₁₂^2)

# Visco - Plastic parameter
# if Δ is very small we assume a linear viscous response
# adding a minimum Δ_min (at Centers)
Δᶜᶜᶜ = max(sqrt(δ^2 + s^2 * e⁻²), Δm)
Pᶜᶜᶜ = @inbounds P[i, j, 1]
Δ = max(sqrt(δ^2 + s^2 * e⁻²), Δm)
P = @inbounds P[i, j, kᴺ]
ζ = P / 2Δ

@inbounds fields.ζ[i, j, 1] = Pᶜᶜᶜ / 2Δᶜᶜᶜ
@inbounds fields.Δ[i, j, 1] = Δᶜᶜᶜ
end

@inline ice_pressure(i, j, k, grid, ::IceStrength, r, fields) = @inbounds fields.P[i, j, k]

@inline function ice_pressure(i, j, k, grid, ::ReplacementPressure, r, fields)
Pᶜᶜᶜ = @inbounds fields.P[i, j, k]
Δᶜᶜᶜ = @inbounds fields.Δ[i, j, k]
Δm = r.minimum_plastic_stress
return Pᶜᶜᶜ * Δᶜᶜᶜ / (Δᶜᶜᶜ + Δm)
end

# Compute the visco-plastic stresses for a slab sea ice model.
# The function updates the internal stress variables `σ₁₁`, `σ₂₂`, and `σ₁₂` in the `rheology` object
# following the αEVP formulation of Kimmritz et al (2016).
@kernel function _compute_evp_stresses!(fields, grid, rheology, u, v, h, ℵ, ρᵢ, Δt)
i, j = @index(Global, NTuple)
kᴺ = size(grid, 3)
# Store viscosity and the deformation for analysis purposes
@inbounds fields.ζ[i, j, kᴺ] = ζ
@inbounds fields.Δ[i, j, kᴺ] = Δ

e⁻² = rheology.yield_curve_eccentricity^(-2)
α⁺ = rheology.max_relaxation_parameter
Expand All @@ -257,50 +249,36 @@
σ₁₂ = fields.σ₁₂
α = fields.α

# Strain rates
ϵ̇₁₁ = strain_rate_xx(i, j, kᴺ, grid, u, v)
ϵ̇₂₂ = strain_rate_yy(i, j, kᴺ, grid, u, v)
ϵ̇₁₂ = strain_rate_xy(i, j, kᴺ, grid, u, v)

ζᶜᶜᶜ = @inbounds fields.ζ[i, j, 1]
ζᶠᶠᶜ = ℑxyᶠᶠᵃ(i, j, 1, grid, fields.ζ)

# replacement pressure?
Pᵣ = ice_pressure(i, j, 1, grid, ip, rheology, fields)

ηᶜᶜᶜ = ζᶜᶜᶜ * e⁻²
ηᶠᶠᶜ = ζᶠᶠᶜ * e⁻²
η = ζ * e⁻²

# σ(uᵖ): the tangential stress depends only shear viscosity
# while the compressive stresses depend on the bulk viscosity and the ice strength
σ₁₁ᵖ⁺¹ = 2 * ηᶜᶜᶜ * ϵ̇₁₁ + ((ζᶜᶜᶜ - ηᶜᶜᶜ) * (ϵ̇₁₁ + ϵ̇₂₂) - Pᵣ / 2)
σ₂₂ᵖ⁺¹ = 2 * ηᶜᶜᶜ * ϵ̇₂₂ + ((ζᶜᶜᶜ - ηᶜᶜᶜ) * (ϵ̇₁₁ + ϵ̇₂₂) - Pᵣ / 2)
σ₁₂ᵖ⁺¹ = 2 * ηᶠᶠᶜ * ϵ̇₁₂

mᵢᶜᶜᶜ = ice_mass(i, j, 1, grid, h, ℵ, ρᵢ)
mᵢᶠᶠᶜ = ℑxyᶠᶠᵃ(i, j, 1, grid, ice_mass, h, ℵ, ρᵢ)
σ₁₁ᵖ⁺¹ = 2 * η * ϵ̇₁₁ + ((ζ - η) * (ϵ̇₁₁ + ϵ̇₂₂) - Pᵣ / 2)
σ₂₂ᵖ⁺¹ = 2 * η * ϵ̇₂₂ + ((ζ - η) * (ϵ̇₁₁ + ϵ̇₂₂) - Pᵣ / 2)
σ₁₂ᵖ⁺¹ = 2 * η * ϵ̇₁₂

mᵢ = ice_mass(i, j, kᴺ, grid, h, ℵ, ρᵢ)

# Update coefficients for substepping using dynamic substepping
# with spatially varying coefficients as in Kimmritz et al (2016)
γ²ᶜᶜᶜ = ζᶜᶜᶜ * cα * Δt / mᵢᶜᶜᶜ / Azᶜᶜᶜ(i, j, 1, grid)
γ²ᶜᶜᶜ = ifelse(isnan(γ²ᶜᶜᶜ), α⁺^2, γ²ᶜᶜᶜ) # In case both ζᶜᶜᶜ and mᵢᶜᶜᶜ are zero
γᶜᶜᶜ = clamp(sqrt(γ²ᶜᶜᶜ), α⁻, α⁺)

γ²ᶠᶠᶜ = ζᶠᶠᶜ * cα * Δt / mᵢᶠᶠᶜ / Azᶠᶠᶜ(i, j, 1, grid)
γ²ᶠᶠᶜ = ifelse(isnan(γ²ᶠᶠᶜ), α⁺^2, γ²ᶠᶠᶜ) # In case both ζᶠᶠᶜ and mᵢᶠᶠᶜ are zero
γᶠᶠᶜ = clamp(sqrt(γ²ᶠᶠᶜ), α⁻, α⁺)
γ = ζ * cα * Δt / mᵢ * Az⁻¹ᶜᶜᶜ(i, j, kᴺ, grid)
α = clamp(sqrt(γ), α⁻, α⁺)
α = ifelse(isnan(α), α⁺, α)

@inbounds begin
# Compute the new stresses and store the value of the
# dynamic substepping coefficient α
σ₁₁★ = (σ₁₁ᵖ⁺¹ - σ₁₁[i, j, 1]) / γᶜᶜᶜ
σ₂₂★ = (σ₂₂ᵖ⁺¹ - σ₂₂[i, j, 1]) / γᶜᶜᶜ
σ₁₂★ = (σ₁₂ᵖ⁺¹ - σ₁₂[i, j, 1]) / γᶠᶠᶜ

σ₁₁[i, j, 1] += ifelse(mᵢᶜᶜᶜ > 0, σ₁₁★, zero(grid))
σ₂₂[i, j, 1] += ifelse(mᵢᶜᶜᶜ > 0, σ₂₂★, zero(grid))
σ₁₂[i, j, 1] += ifelse(mᵢᶠᶠᶜ > 0, σ₁₂★, zero(grid))
α[i, j, 1] = γᶜᶜᶜ
σ₁₁★ = (σ₁₁ᵖ⁺¹ - σ₁₁[i, j, kᴺ]) / α
σ₂₂★ = (σ₂₂ᵖ⁺¹ - σ₂₂[i, j, kᴺ]) / α
σ₁₂★ = (σ₁₂ᵖ⁺¹ - σ₁₂[i, j, kᴺ]) / α

σ₁₁[i, j, kᴺ] += ifelse(mᵢ > 0, σ₁₁★, zero(grid))
σ₂₂[i, j, kᴺ] += ifelse(mᵢ > 0, σ₂₂★, zero(grid))
σ₁₂[i, j, kᴺ] += ifelse(mᵢ > 0, σ₁₂★, zero(grid))

fields.α[i, j, kᴺ] = α
end
end

Expand All @@ -309,27 +287,26 @@
#####

# Here we extend all the functions that a rheology model needs to support:
@inline ice_stress_ux(i, j, k, grid, ::ElastoViscoPlasticRheology, clock, fields) = @inbounds fields.σ₁₁[i, j, k]
@inline ice_stress_vx(i, j, k, grid, ::ElastoViscoPlasticRheology, clock, fields) = @inbounds fields.σ₁₂[i, j, k]
@inline ice_stress_uy(i, j, k, grid, ::ElastoViscoPlasticRheology, clock, fields) = @inbounds fields.σ₁₂[i, j, k]
@inline ice_stress_vy(i, j, k, grid, ::ElastoViscoPlasticRheology, clock, fields) = @inbounds fields.σ₂₂[i, j, k]
@inline ice_stress_ux(i, j, k, grid, ::ElastoViscoPlasticRheology, clock, fields) = ℑyᵃᶠᵃ(i, j, k, grid, fields.σ₁₁)
@inline ice_stress_uy(i, j, k, grid, ::ElastoViscoPlasticRheology, clock, fields) = ℑxᶠᵃᵃ(i, j, k, grid, fields.σ₁₂)
@inline ice_stress_vx(i, j, k, grid, ::ElastoViscoPlasticRheology, clock, fields) = ℑyᵃᶠᵃ(i, j, k, grid, fields.σ₁₂)
@inline ice_stress_vy(i, j, k, grid, ::ElastoViscoPlasticRheology, clock, fields) = ℑxᶠᵃᵃ(i, j, k, grid, fields.σ₂₂)

# To help convergence to the right velocities
@inline compute_substep_Δtᶠᶜᶜ(i, j, grid, Δt, ::ElastoViscoPlasticRheology, substeps, fields) = Δt / ℑxᶠᵃᵃ(i, j, 1, grid, fields.α)
@inline compute_substep_Δtᶜᶠᶜ(i, j, grid, Δt, ::ElastoViscoPlasticRheology, substeps, fields) = Δt / ℑyᵃᶠᵃ(i, j, 1, grid, fields.α)
@inline compute_substep_Δtᶠᶠᶜ(i, j, grid, Δt, ::ElastoViscoPlasticRheology, substeps, fields) = @inbounds Δt / ℑxyᶠᶠᵃ(i, j, 1, grid, fields.α)

#####
##### Numerical forcing to help convergence
#####

@inline function sum_of_forcing_u(i, j, k, grid, ::ElastoViscoPlasticRheology, u_forcing, fields, Δt)
user_forcing = u_forcing(i, j, k, grid, fields)
rheology_forcing = @inbounds (fields.uⁿ[i, j, k] - fields.u[i, j, k]) / Δt / ℑxᶠᵃᵃ(i, j, k, grid, fields.α)
rheology_forcing = @inbounds (fields.uⁿ[i, j, k] - fields.u[i, j, k]) / Δt / ℑxyᶠᶠᵃ(i, j, k, grid, fields.α)
return user_forcing + rheology_forcing
end

@inline function sum_of_forcing_v(i, j, k, grid, ::ElastoViscoPlasticRheology, v_forcing, fields, Δt)
user_forcing = v_forcing(i, j, k, grid, fields)
rheology_forcing = @inbounds (fields.vⁿ[i, j, k] - fields.v[i, j, k]) / Δt / ℑyᵃᶠᵃ(i, j, k, grid, fields.α)
rheology_forcing = @inbounds (fields.vⁿ[i, j, k] - fields.v[i, j, k]) / Δt / ℑxyᶠᶠᵃ(i, j, k, grid, fields.α)
return user_forcing + rheology_forcing
end
Loading
Loading