Skip to content

Commit 3ebb64e

Browse files
Speeding up Dynamics and removing internal heat flux when h < hc (#89)
* this should speed up tremendously my computation * maybe this works? * go * ok this should work? * try it out * should work * this works! * let's go * no need to fill the halos here * fix the periodic BC * fix the periodic BC * go like this * converted args * typo * remove this * try computing stresses * go ahead * this should work? * correct * try it out * fix * send it * bump patch release * Apply suggestions from code review * Update README.md * Update Project.toml * RheologyAuxiliaries * using Adapt * tidy up * more tidying up * rename to auxiliaries * extend * Update elasto_visco_plastic_rheology.jl * removed required auxiliaires * change --------- Co-authored-by: Navid C. Constantinou <navidcy@users.noreply.github.com>
1 parent 0751923 commit 3ebb64e

File tree

10 files changed

+141
-107
lines changed

10 files changed

+141
-107
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ClimaSeaIce"
22
uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4"
33
authors = ["Climate Modeling Alliance and contributors"]
4-
version = "0.3.5"
4+
version = "0.3.7"
55

66
[deps]
77
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
@@ -14,7 +14,7 @@ SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40"
1414
[compat]
1515
Adapt = "3, 4"
1616
KernelAbstractions = "0.9"
17-
Oceananigans = "0.97.6"
17+
Oceananigans = "0.98.0"
1818
Roots = "2"
1919
RootSolvers = "0.3, 0.4"
2020
SeawaterPolynomials = "0.3.4"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@ When things have progressed, we'll put an outline here.
3636
If you use ClimaSeaIcea for your research, teaching, or fun 🤩, everyone in our community will be grateful
3737
if you give credit by citing the corresponding Zenodo record, e.g.,
3838

39-
> Silvestri, S. et al. (2025). CliMA/ClimaSeaIce.jl: v0.3.3 (v0.3.3). Zenodo. https://doi.org/10.5281/zenodo.16143708
39+
> Silvestri, S. et al. (2025). CliMA/ClimaSeaIce.jl: v0.3.6 (v0.3.6). Zenodo. https://doi.org/10.5281/zenodo.16143708

examples/ice_advected_by_anticyclone.jl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ set!(Vₐ, (x, y) -> va_time(x, y, 0))
7676

7777
fill_halo_regions!((Uₐ, Vₐ))
7878

79-
τₐu = - Uₐ * sqrt(Uₐ^2 + Vₐ^2) * 1.3 * 1.2e-3
80-
τₐv = - Vₐ * sqrt(Uₐ^2 + Vₐ^2) * 1.3 * 1.2e-3
79+
τₐu = Field(- Uₐ * sqrt(Uₐ^2 + Vₐ^2) * 1.3 * 1.2e-3)
80+
τₐv = Field(- Vₐ * sqrt(Uₐ^2 + Vₐ^2) * 1.3 * 1.2e-3)
8181

8282
#####
8383
##### Numerical details
@@ -124,6 +124,9 @@ function compute_wind_stress(sim)
124124

125125
fill_halo_regions!((Uₐ, Vₐ))
126126

127+
compute!(τₐu)
128+
compute!(τₐv)
129+
127130
return nothing
128131
end
129132

@@ -177,10 +180,10 @@ vtimeseries = FieldTimeSeries("sea_ice_advected_by_anticyclone.jld2", "v")
177180
Nt = length(htimeseries)
178181
iter = Observable(1)
179182

180-
hi = @lift(htimeseries[$iter])
181-
ℵi = @lift(ℵtimeseries[$iter])
182-
ui = @lift(utimeseries[$iter])
183-
vi = @lift(vtimeseries[$iter])
183+
hi = @lift(interior(htimeseries[$iter], :, :, 1))
184+
ℵi = @lift(interior(ℵtimeseries[$iter], :, :, 1))
185+
ui = @lift(interior(utimeseries[$iter], :, :, 1))
186+
vi = @lift(interior(vtimeseries[$iter], :, :, 1))
184187

185188
fig = Figure()
186189
ax = Axis(fig[1, 1], title = "sea ice thickness")

src/Rheologies/Rheologies.jl

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,35 @@
11
module Rheologies
22

33
export ViscousRheology, ElastoViscoPlasticRheology
4-
export ∂ⱼ_σ₁ⱼ, ∂ⱼ_σ₂ⱼ, required_auxiliary_fields
4+
export ∂ⱼ_σ₁ⱼ, ∂ⱼ_σ₂ⱼ, Auxiliaries
55

66
using Oceananigans
77
using Oceananigans.Operators
8+
using Oceananigans.Grids: AbstractGrid
89
using ClimaSeaIce: ice_mass
10+
using Adapt
11+
12+
struct Auxiliaries{F, K}
13+
fields :: F
14+
kernels :: K
15+
end
16+
17+
# When adapted, only the fields need to be passed to the GPU.
18+
# kernels operate only on the CPU.
19+
Adapt.adapt_structure(to, a::Auxiliaries) =
20+
Auxiliaries(Adapt.adapt(to, a.fields), nothing)
21+
22+
"""
23+
Auxiliaries(rheology, grid)
24+
25+
A struct holding any auxiliary fields and kernels needed for the computation of
26+
sea ice stresses.
27+
"""
28+
Auxiliaries(rheology, grid::AbstractGrid) = Auxiliaries(NamedTuple(), nothing)
929

1030
# Nothing rheology
11-
required_auxiliary_fields(rheology, grid) = NamedTuple()
1231
initialize_rheology!(model, rheology) = nothing
13-
compute_stresses!(model, dynamics, rheology, Δt) = nothing
32+
compute_stresses!(dynamics, fields, grid, rheology, Δt) = nothing
1433

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

src/Rheologies/elasto_visco_plastic_rheology.jl

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,15 @@ function ElastoViscoPlasticRheology(FT::DataType = Float64;
105105
pressure_formulation)
106106
end
107107

108-
function required_auxiliary_fields(r::ElastoViscoPlasticRheology, grid)
109-
108+
# Extend Auxiliaries to hold auxiliaries for the ElastoViscoPlasticRheology
109+
function Auxiliaries(r::ElastoViscoPlasticRheology, grid::AbstractGrid)
110+
111+
arch = architecture(grid)
112+
Nx, Ny, _ = size(grid)
113+
Hx, Hy, _ = halo_size(grid)
114+
115+
parameters = KernelParameters(-Hx+2:Nx+Hx-1, -Hy+2:Ny+Hy-1)
116+
110117
# TODO: What about boundary conditions?
111118
σ₁₁ = Field{Center, Center, Nothing}(grid)
112119
σ₂₂ = Field{Center, Center, Nothing}(grid)
@@ -122,7 +129,16 @@ function required_auxiliary_fields(r::ElastoViscoPlasticRheology, grid)
122129
# An initial (safe) educated guess
123130
fill!(α, r.max_relaxation_parameter)
124131

125-
return (; σ₁₁, σ₂₂, σ₁₂, ζ, Δ, α, uⁿ, vⁿ, P)
132+
_viscosity_kernel! = configure_kernel(arch, grid, parameters, _compute_evp_viscosities!)[1]
133+
_stresses_kernel! = configure_kernel(arch, grid, parameters, _compute_evp_stresses!)[1]
134+
135+
parameters = KernelParameters(size(P.data)[1:2], P.data.offsets[1:2])
136+
_initialize_rhology! = configure_kernel(arch, grid, parameters, _initialize_evp_rhology!)[1]
137+
138+
fields = (; σ₁₁, σ₂₂, σ₁₂, ζ, Δ, α, uⁿ, vⁿ, P)
139+
kernels = (; _viscosity_kernel!, _stresses_kernel!, _initialize_rhology!)
140+
141+
return Auxiliaries(fields, kernels)
126142
end
127143

128144
# Extend the `adapt_structure` function for the ElastoViscoPlasticRheology
@@ -149,13 +165,11 @@ function initialize_rheology!(model, rheology::ElastoViscoPlasticRheology)
149165
P★ = rheology.ice_compressive_strength
150166
C = rheology.ice_compaction_hardening
151167

152-
u, v = model.velocities
153-
fields = model.dynamics.auxiliary_fields
168+
u, v = model.velocities
169+
fields = model.dynamics.auxiliaries.fields
170+
kernels = model.dynamics.auxiliaries.kernels
171+
kernels._initialize_rhology!(fields, model.grid, P★, C, h, ℵ, u, v)
154172

155-
# compute on the whole grid including halos
156-
parameters = KernelParameters(size(fields.P.data)[1:2], fields.P.data.offsets[1:2])
157-
launch!(architecture(model.grid), model.grid, parameters, _initialize_evp_rhology!, fields, model.grid, P★, C, h, ℵ, u, v)
158-
159173
return nothing
160174
end
161175

@@ -170,25 +184,16 @@ end
170184
@inline ice_strength(i, j, k, grid, P★, C, h, ℵ) = @inbounds P★ * h[i, j, k] * exp(- C * (1 - ℵ[i, j, k]))
171185

172186
# Specific compute stresses for the EVP rheology
173-
function compute_stresses!(model, dynamics, rheology::ElastoViscoPlasticRheology, Δt)
174-
175-
grid = model.grid
176-
arch = architecture(grid)
177-
178-
h = model.ice_thickness
179-
ρᵢ = model.ice_density
180-
= model.ice_concentration
181-
182-
fields = dynamics.auxiliary_fields
183-
u, v = model.velocities
184-
185-
Nx, Ny, _ = size(grid)
186-
Hx, Hy, _ = halo_size(grid)
187-
188-
parameters = KernelParameters(-Hx+2:Nx+Hx-1, -Hy+2:Ny+Hy-1)
189-
190-
launch!(arch, grid, parameters, _compute_evp_viscosities!, fields, grid, rheology, u, v)
191-
launch!(arch, grid, parameters, _compute_evp_stresses!, fields, grid, rheology, u, v, h, ℵ, ρᵢ, Δt)
187+
function compute_stresses!(dynamics, fields, grid, rheology::ElastoViscoPlasticRheology, Δt)
188+
189+
h = fields.h
190+
ρᵢ = fields.ρ
191+
= fields.
192+
u = fields.u
193+
v = fields.v
194+
195+
dynamics.auxiliaries.kernels._viscosity_kernel!(fields, grid, rheology, u, v)
196+
dynamics.auxiliaries.kernels._stresses_kernel!(fields, grid, rheology, u, v, h, ℵ, ρᵢ, Δt)
192197

193198
return nothing
194199
end

src/SeaIceDynamics/SeaIceDynamics.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ using ClimaSeaIce.Rheologies: ∂ⱼ_σ₁ⱼ,
1818
∂ⱼ_σ₂ⱼ,
1919
immersed_∂ⱼ_σ₁ⱼ,
2020
immersed_∂ⱼ_σ₂ⱼ,
21-
required_auxiliary_fields,
21+
Auxiliaries,
2222
compute_stresses!,
2323
initialize_rheology!,
2424
compute_substep_Δtᶠᶜᶜ,
2525
compute_substep_Δtᶜᶠᶜ,
2626
sum_of_forcing_u,
2727
sum_of_forcing_v
28-
28+
2929
import Oceananigans: fields
3030

3131
## A Framework to solve for the ice momentum equation, in the form:

src/SeaIceDynamics/explicit_momentum_equations.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function time_step_momentum!(model, ::ExplicitMomentumEquation, Δt)
1212

1313
dynamics = model.dynamics
1414

15-
model_fields = merge(dynamics.auxiliary_fields, model.velocities,
15+
model_fields = merge(dynamics.auxiliaries.fields, model.velocities,
1616
(; h = model.ice_thickness,
1717
= model.ice_concentration,
1818
ρ = model.ice_density))
@@ -77,7 +77,7 @@ function compute_momentum_tendencies!(model, ::ExplicitMomentumEquation, Δt)
7777
coriolis = dynamics.coriolis
7878
rheology = dynamics.rheology
7979

80-
model_fields = merge(dynamics.auxiliary_fields, model.velocities,
80+
model_fields = merge(dynamics.auxiliaries.fields, model.velocities,
8181
(; h = model.ice_thickness,
8282
= model.ice_concentration,
8383
ρ = model.ice_density))

src/SeaIceDynamics/sea_ice_momentum_equations.jl

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ using Adapt
44
struct SeaIceMomentumEquation{S, C, R, F, A, ES, FT}
55
coriolis :: C
66
rheology :: R
7-
auxiliary_fields :: A
7+
auxiliaries :: A
88
solver :: S
99
free_drift :: F
1010
external_momentum_stresses :: ES
@@ -19,7 +19,6 @@ struct ExplicitSolver end
1919
SeaIceMomentumEquation(grid;
2020
coriolis = nothing,
2121
rheology = ElastoViscoPlasticRheology(eltype(grid)),
22-
auxiliary_fields = NamedTuple(),
2322
top_momentum_stress = nothing,
2423
bottom_momentum_stress = nothing,
2524
free_drift = nothing,
@@ -48,7 +47,6 @@ Keyword Arguments
4847
4948
- `coriolis`: Parameters for the background rotation rate of the model.
5049
- `rheology`: The sea ice rheology model, default is `ElastoViscoPlasticRheology(eltype(grid))`.
51-
- `auxiliary_fields`: A named tuple of auxiliary fields, default is an empty `NamedTuple()`.
5250
- `free_drift`: The free drift velocities used to limit sea ice momentum when the mass or the concentration are
5351
below a certain threshold. Default is `nothing` (indicating that the free drift velocities are zero).
5452
- `solver`: The momentum solver to be used.
@@ -58,28 +56,27 @@ Keyword Arguments
5856
function SeaIceMomentumEquation(grid;
5957
coriolis = nothing,
6058
rheology = ElastoViscoPlasticRheology(eltype(grid)),
61-
auxiliary_fields = NamedTuple(),
6259
top_momentum_stress = nothing,
6360
bottom_momentum_stress = nothing,
6461
free_drift = nothing,
6562
solver = SplitExplicitSolver(150),
6663
minimum_concentration = 1e-3,
6764
minimum_mass = 1.0)
6865

69-
auxiliary_fields = merge(auxiliary_fields, required_auxiliary_fields(rheology, grid))
66+
auxiliaries = Auxiliaries(rheology, grid)
7067
external_momentum_stresses = (top = top_momentum_stress,
7168
bottom = bottom_momentum_stress)
7269

7370
FT = eltype(grid)
7471

7572
return SeaIceMomentumEquation(coriolis,
7673
rheology,
77-
auxiliary_fields,
74+
auxiliaries,
7875
solver,
7976
free_drift,
8077
external_momentum_stresses,
8178
convert(FT, minimum_concentration),
8279
convert(FT, minimum_mass))
8380
end
8481

85-
fields(mom::SeaIceMomentumEquation) = mom.auxiliary_fields
82+
fields(mom::SeaIceMomentumEquation) = mom.auxiliaries.fields

0 commit comments

Comments
 (0)