Skip to content

Commit 17278aa

Browse files
committed
clarify naming
1 parent d6e34ab commit 17278aa

File tree

3 files changed

+59
-62
lines changed

3 files changed

+59
-62
lines changed

experiments/ClimaEarth/components/ocean/clima_seaice.jl

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,18 @@ This type is used by the coupler to indicate that this simulation
1717
is an surface/ocean simulation for dispatch.
1818
1919
It contains the following objects:
20-
- `sea_ice::SIM`: The ClimaSeaIce simulation object.
20+
- `ice::SIM`: The ClimaSeaIce simulation object.
2121
- `area_fraction::A`: A ClimaCore Field representing the surface area fraction of this component model on the exchange grid.
2222
- `melting_speed::MS`: An constant characteristic speed for melting/freezing.
2323
- `remapping::REMAP`: Objects needed to remap from the exchange (spectral) grid to Oceananigans spaces.
24-
- `ocean_sea_ice_fluxes::NT`: A NamedTuple of fluxes between the ocean and sea ice, computed at each coupling step.
24+
- `ocean_ice_fluxes::NT`: A NamedTuple of fluxes between the ocean and sea ice, computed at each coupling step.
2525
"""
2626
struct ClimaSeaIceSimulation{SIM, A, MS, REMAP, NT} <: Interfacer.SeaIceModelSimulation
27-
sea_ice::SIM
27+
ice::SIM
2828
area_fraction::A
2929
melting_speed::MS
3030
remapping::REMAP
31-
ocean_sea_ice_fluxes::NT
31+
ocean_ice_fluxes::NT
3232
end
3333

3434
"""
@@ -51,14 +51,13 @@ can be found in the documentation for `ClimaOcean.ocean_simulation`.
5151
"""
5252
function ClimaSeaIceSimulation(land_fraction, ocean; output_dir)
5353
# Initialize the sea ice with the same grid as the ocean
54-
grid = ocean.ocean.model.grid
54+
grid = ocean.ocean.model.grid # TODO can't use lat/lon grid at poles for ice
5555
arch = grid.architecture
5656
advection = ocean.ocean.model.advection.T
5757
top_heat_boundary_condition = CO.MeltingConstrainedFluxBalance()
5858

5959
# TODO use branch ss-js/top-heat-bc for this constructor
60-
sea_ice =
61-
CO.sea_ice_simulation(grid, ocean.ocean; advection, top_heat_boundary_condition)
60+
ice = CO.sea_ice_simulation(grid, ocean.ocean; advection, top_heat_boundary_condition)
6261

6362
melting_speed = 1e-4
6463

@@ -68,24 +67,24 @@ function ClimaSeaIceSimulation(land_fraction, ocean; output_dir)
6867
# Before version 0.96.22, the NetCDFWriter was broken on GPU
6968
if arch isa OC.CPU || pkgversion(OC) >= v"0.96.22"
7069
# Save all tracers and velocities to a NetCDF file at daily frequency
71-
outputs = OC.prognostic_fields(sea_ice.model)
70+
outputs = OC.prognostic_fields(ice.model)
7271
jld_writer = OC.JLDWriter(
73-
sea_ice.model,
72+
ice.model,
7473
outputs;
7574
schedule = OC.TimeInterval(86400), # Daily output
7675
filename = joinpath(output_dir, "seaice_diagnostics.jld2"),
7776
overwrite_existing = true,
7877
array_type = Array{Float32},
7978
)
80-
sea_ice.output_writers[:diagnostics] = jld_writer
79+
ice.output_writers[:diagnostics] = jld_writer
8180
end
8281

8382
# Allocate space for the sea ice-ocean (io) fluxes
84-
ocean_sea_ice_fluxes = ocean.ocean_sea_ice_fluxes
83+
ocean_ice_fluxes = ocean.ocean_ice_fluxes
8584

8685
# TODO clean this up
87-
# Get the area fraction from the fractional sea ice concentration
88-
area_fraction = sea_ice.model.ice_concentration
86+
# Get the initial area fraction from the fractional ice concentration
87+
area_fraction = ice.model.ice_concentration
8988

9089
# Overwrite ice fraction with the static land area fraction anywhere we have nonzero land area
9190
# max needed to avoid Float32 errors (see issue #271; Heisenbug on HPC)
@@ -97,16 +96,16 @@ function ClimaSeaIceSimulation(land_fraction, ocean; output_dir)
9796
max(min(area_fraction_boundary_space, FT(1) - land_fraction), FT(0))
9897

9998
sim = ClimaSeaIceSimulation(
100-
sea_ice,
99+
ice,
101100
area_fraction_boundary_space,
102101
melting_speed,
103102
remapping,
104-
ocean_sea_ice_fluxes,
103+
ocean_ice_fluxes,
105104
)
106105
return sim
107106
end
108107

109-
function update_sic!(area_fraction, sea_ice)
108+
function update_sic!(area_fraction, ice)
110109
# TODO
111110
end
112111

@@ -116,11 +115,11 @@ end
116115

117116
# Timestep the simulation forward to time `t`
118117
Interfacer.step!(sim::ClimaSeaIceSimulation, t) =
119-
OC.time_step!(sim.sea_ice, float(t) - sim.sea_ice.model.clock.time)
118+
OC.time_step!(sim.ice, float(t) - sim.ice.model.clock.time)
120119

121120
Interfacer.get_field(sim::ClimaSeaIceSimulation, ::Val{:area_fraction}) = sim.area_fraction
122-
Interfacer.get_field(sim::ClimaSeaIceSimulation, Val(:sea_ice_concentration)) =
123-
sim.sea_ice.model.ice_concentration
121+
Interfacer.get_field(sim::ClimaSeaIceSimulation, ::Val(:ice_concentration)) =
122+
sim.ice.model.ice_concentration
124123

125124
# At the moment, we return always Float32. This is because we always want to run
126125
# Oceananingans with Float64, so we have no way to know the float type here. Sticking with
@@ -139,8 +138,7 @@ Interfacer.get_field(sim::ClimaSeaIceSimulation, ::Val{:surface_diffuse_albedo})
139138
# Approximate the sea ice surface temperature as the temperature computed from the
140139
# fluxes at the previous timestep.
141140
Interfacer.get_field(sim::ClimaSeaIceSimulation, ::Val{:surface_temperature}) =
142-
273.15 .+
143-
OC.interior(sim.sea_ice.model.ice_thermodynamics.top_surface_temperature, :, :, 1)
141+
273.15 .+ OC.interior(sim.ice.model.ice_thermodynamics.top_surface_temperature, :, :, 1)
144142

145143
"""
146144
FluxCalculator.update_turbulent_fluxes!(sim::ClimaSeaIceSimulation, fields)
@@ -162,7 +160,7 @@ function FluxCalculator.update_turbulent_fluxes!(sim::ClimaSeaIceSimulation, fie
162160
# Only LatitudeLongitudeGrid are supported because otherwise we have to rotate the vectors
163161

164162
(; F_lh, F_sh, F_turb_ρτxz, F_turb_ρτyz, F_turb_moisture) = fields
165-
grid = sim.sea_ice.model.grid
163+
grid = sim.ice.model.grid
166164

167165
# Remap momentum fluxes onto reduced 2D Center, Center fields using scratch arrays and fields
168166
CC.Remapping.interpolate!(
@@ -184,8 +182,8 @@ function FluxCalculator.update_turbulent_fluxes!(sim::ClimaSeaIceSimulation, fie
184182

185183
# Set the momentum flux BCs at the correct locations using the remapped scratch fields
186184
# Note that this requires the sea ice model to always be run with dynamics turned on
187-
si_flux_u = sim.sea_ice.model.dynamics.external_stresses.top.u
188-
si_flux_v = sim.sea_ice.model.dynamics.external_stresses.top.v
185+
si_flux_u = sim.ice.model.dynamics.external_stresses.top.u
186+
si_flux_v = sim.ice.model.dynamics.external_stresses.top.v
189187
set_from_extrinsic_vectors!(
190188
(; u = si_flux_u, v = si_flux_v),
191189
grid,
@@ -202,10 +200,10 @@ function FluxCalculator.update_turbulent_fluxes!(sim::ClimaSeaIceSimulation, fie
202200
remapped_F_sh = sim.remapping.scratch_arr2
203201

204202
# Update the sea ice only where the concentration is greater than zero.
205-
si_flux_heat = ice_sim.sea_ice.model.external_heat_fluxes.top
203+
si_flux_heat = ice_sim.ice.model.external_heat_fluxes.top
206204
OC.interior(si_flux_heat, :, :, 1) .=
207205
OC.interior(si_flux_heat, :, :, 1) .+ (
208-
(OC.interior(sim.sea_ice.model.ice_concentration, :, :, 1) .> 0) .*
206+
(OC.interior(sim.ice.model.ice_concentration, :, :, 1) .> 0) .*
209207
(remapped_F_lh .+ remapped_F_sh)
210208
)
211209

@@ -248,52 +246,50 @@ function FieldExchanger.update_sim!(sim::ClimaSeaIceSimulation, csf, area_fracti
248246
# Update only the part due to radiative fluxes. For the full update, the component due
249247
# to latent and sensible heat is missing and will be updated in update_turbulent_fluxes.
250248
# Update the sea ice only where the concentration is greater than zero.
251-
si_flux_heat = sim.sea_ice.model.external_heat_fluxes.top
249+
si_flux_heat = sim.ice.model.external_heat_fluxes.top
252250
OC.interior(si_flux_heat, :, :, 1) .=
253-
(OC.interior(sim.sea_ice.model.ice_concentration, :, :, 1) .> 0) .*
254-
remapped_F_radiative
251+
(OC.interior(sim.ice.model.ice_concentration, :, :, 1) .> 0) .* remapped_F_radiative
255252

256253
return nothing
257254
end
258255

259256
"""
260257
ocean_seaice_fluxes!(ocean_sim, ice_sim)
261258
262-
Compute the fluxes between the ocean and sea ice, storing them in the `ocean_sea_ice_fluxes`
259+
Compute the fluxes between the ocean and sea ice, storing them in the `ocean_ice_fluxes`
263260
fields of the ocean and sea ice simulations.
264261
"""
265262
function FluxCalculator.ocean_seaice_fluxes!(
266263
ocean_sim::OceananigansSimulation,
267264
ice_sim::ClimaSeaIceSimulation,
268265
)
269-
# TODO unify sea_ice vs ice naming convention in this file
270266
melting_speed = ice_sim.melting_speed
271267
ocean_properties = ocean_sim.ocean_properties
272268

273269
# Compute the fluxes and store them in the both simulations
274270
CO.compute_sea_ice_ocean_fluxes!(
275-
ice_sim.ocean_sea_ice_fluxes,
271+
ice_sim.ocean_ice_fluxes,
276272
ocean_sim.ocean,
277-
ice_sim.sea_ice,
273+
ice_sim.ice,
278274
melting_speed,
279275
ocean_properties,
280276
)
281-
ocean_sim.ocean_sea_ice_fluxes = ice_sim.ocean_sea_ice_fluxes
277+
ocean_sim.ocean_ice_fluxes = ice_sim.ocean_ice_fluxes
282278

283279
## Update the internals of the sea ice model
284280
# Set the bottom heat flux to the sum of the frazil and interface heat fluxes
285-
bottom_heat_flux = ice_sim.sea_ice.model.external_heat_fluxes.bottom
281+
bottom_heat_flux = ice_sim.ice.model.external_heat_fluxes.bottom
286282

287-
Qf = sea_ice_ocean_fluxes.frazil_heat # frazil heat flux
288-
Qi = sea_ice_ocean_fluxes.interface_heat # interfacial heat flux
283+
Qf = ice_sim.ocean_ice_fluxes.frazil_heat # frazil heat flux
284+
Qi = ice_sim.ocean_ice_fluxes.interface_heat # interfacial heat flux
289285
bottom_heat_flux .= Qf .+ Qi
290286

291287
## Update the internals of the ocean model
292288
ρₒ⁻¹ = 1 / ocean_sim.ocean_properties.reference_density
293289
cₒ = ocean_sim.ocean_properties.heat_capacity
294290

295291
Jᵀio = Qio * ρₒ⁻¹ / cₒ
296-
Jˢio = sea_ice_ocean_fluxes.salt[i, j, 1] * ℵᵢ
292+
Jˢio = ice_sim.ocean_ice_fluxes.salt[i, j, 1] * ℵᵢ
297293

298294
# ℑxᶠᵃᵃ: interpolate faces to centers
299295
τxio = ρτxio[i, j, 1] * ρₒ⁻¹ * ℑxᶠᵃᵃ(i, j, 1, grid, ℵ)

experiments/ClimaEarth/components/ocean/oceananigans.jl

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ It contains the following objects:
2121
- `area_fraction::A`: A ClimaCore Field representing the surface area fraction of this component model on the exchange grid.
2222
- `ocean_properties::OPROP`: A NamedTuple of ocean properties and parameters
2323
- `remapping::REMAP`: Objects needed to remap from the exchange (spectral) grid to Oceananigans spaces.
24-
- `ocean_sea_ice_fluxes::NT`: A NamedTuple of fluxes between the ocean and sea ice, computed at each coupling step.
25-
- `sea_ice_concentration::SIC`: A ClimaCore Field representing the sea ice concentration on the ocean/sea ice grid.
24+
- `ocean_ice_fluxes::NT`: A NamedTuple of fluxes between the ocean and sea ice, computed at each coupling step.
25+
- `ice_concentration::SIC`: A ClimaCore Field representing the sea ice concentration on the ocean/sea ice grid.
2626
"""
2727
struct OceananigansSimulation{SIM, A, OPROP, REMAP, NT, SIC} <:
2828
Interfacer.OceanModelSimulation
2929
ocean::SIM
3030
area_fraction::A
3131
ocean_properties::OPROP
3232
remapping::REMAP
33-
ocean_sea_ice_fluxes::NT
34-
sea_ice_concentration::SIC
33+
ocean_ice_fluxes::NT
34+
ice_concentration::SIC
3535
end
3636

3737
"""
@@ -199,7 +199,7 @@ function OceananigansSimulation(
199199
x_momentum = OC.Field{OC.Face, OC.Center, Nothing}(grid)
200200
y_momentum = OC.Field{OC.Center, OC.Face, Nothing}(grid)
201201

202-
ocean_sea_ice_fluxes = (
202+
ocean_ice_fluxes = (
203203
interface_heat = io_bottom_heat_flux,
204204
frazil_heat = io_frazil_heat_flux,
205205
salt = io_salt_flux,
@@ -212,7 +212,7 @@ function OceananigansSimulation(
212212
area_fraction,
213213
ocean_properties,
214214
remapping,
215-
ocean_sea_ice_fluxes,
215+
ocean_ice_fluxes,
216216
)
217217
return sim
218218
end
@@ -326,8 +326,11 @@ function FluxCalculator.update_turbulent_fluxes!(sim::OceananigansSimulation, fi
326326
F_turb_ρτxz_cc,
327327
F_turb_ρτyz_cc,
328328
)
329-
oc_flux_u .= (1 .- sea_ice_concentration) .* oc_flux_u
330-
oc_flux_v .= (1 .- sea_ice_concentration) .* oc_flux_v
329+
330+
# Weight the ocean fluxes by (1 - ice concentration)
331+
ice_concentration = OC.interior(sim.ice_concentration, :, :, 1)
332+
oc_flux_u .= (1 .- ice_concentration) .* oc_flux_u
333+
oc_flux_v .= (1 .- ice_concentration) .* oc_flux_v
331334

332335
(; ocean_reference_density, ocean_heat_capacity, ocean_fresh_water_density) =
333336
sim.ocean_properties
@@ -346,7 +349,7 @@ function FluxCalculator.update_turbulent_fluxes!(sim::OceananigansSimulation, fi
346349
oc_flux_T = surface_flux(sim.ocean.model.tracers.T)
347350
OC.interior(oc_flux_T, :, :, 1) .=
348351
OC.interior(oc_flux_T, :, :, 1) .+
349-
(1 .- sea_ice_concentration) .* (
352+
(1 .- ice_concentration) .* (
350353
(remapped_F_lh .+ remapped_F_sh) ./
351354
(ocean_reference_density * ocean_heat_capacity)
352355
)
@@ -363,22 +366,22 @@ function FluxCalculator.update_turbulent_fluxes!(sim::OceananigansSimulation, fi
363366
surface_salinity = OC.interior(sim.ocean.model.tracers.S, :, :, 1)
364367
OC.interior(oc_flux_S, :, :, 1) .=
365368
OC.interior(oc_flux_S, :, :, 1) .-
366-
(1 .- sea_ice_concentration) .* (surface_salinity .* moisture_fresh_water_flux)
369+
(1 .- ice_concentration) .* (surface_salinity .* moisture_fresh_water_flux)
367370
return nothing
368371
end
369372

370373
function Interfacer.update_field!(sim::OceananigansSimulation, ::Val{:area_fraction}, field)
371374
sim.area_fraction .= field
372375
return nothing
373376
end
374-
# Note, sea_ice_concentration is on the ocean/sea ice grid. This assumes the ocean and
377+
# Note, ice_concentration is on the ocean/sea ice grid. This assumes the ocean and
375378
# sea ice are using the same grid.
376379
function Interfacer.update_field!(
377380
sim::OceananigansSimulation,
378-
::Val{:sea_ice_concentration},
381+
::Val{:ice_concentration},
379382
field,
380383
)
381-
sim.sea_ice_concentration .= field
384+
sim.ice_concentration .= field
382385
return nothing
383386
end
384387

@@ -401,7 +404,7 @@ so a sign change is needed when we convert from precipitation to salinity flux.
401404
function FieldExchanger.update_sim!(sim::OceananigansSimulation, csf, area_fraction)
402405
(; ocean_reference_density, ocean_heat_capacity, ocean_fresh_water_density) =
403406
sim.ocean_properties
404-
sea_ice_concentration = OC.interior(sim.sea_ice_concentration, :, :, 1)
407+
ice_concentration = OC.interior(sim.ice_concentration, :, :, 1)
405408

406409
# Remap radiative flux onto scratch array; rename for clarity
407410
CC.Remapping.interpolate!(
@@ -417,7 +420,7 @@ function FieldExchanger.update_sim!(sim::OceananigansSimulation, csf, area_fract
417420
# TODO document ordering of flux updates somewhere
418421
OC.interior(oc_flux_T, :, :, 1) .=
419422
OC.interior(oc_flux_T, :, :, 1) .+
420-
(1 .- sea_ice_concentration) .*
423+
(1 .- ice_concentration) .*
421424
(remapped_F_radiative ./ (ocean_reference_density * ocean_heat_capacity))
422425

423426
# Remap precipitation fields onto scratch arrays; rename for clarity
@@ -442,7 +445,7 @@ function FieldExchanger.update_sim!(sim::OceananigansSimulation, csf, area_fract
442445
OC.interior(sim.ocean.model.tracers.S, :, :, 1) .* precipitating_fresh_water_flux
443446
OC.interior(oc_flux_S, :, :, 1) .=
444447
OC.interior(oc_flux_S, :, :, 1) .+
445-
(1 .- sea_ice_concentration) .* .-surface_salinity_flux
448+
(1 .- ice_concentration) .* .-surface_salinity_flux
446449
return nothing
447450
end
448451

src/FieldExchanger.jl

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,15 @@ function update_surface_fractions!(cs::Interfacer.CoupledSimulation)
3939
# ice and ocean fractions are dynamic
4040
if haskey(cs.model_sims, :ice_sim)
4141
ice_sim = cs.model_sims.ice_sim
42-
Interfacer.get_field!(cs.fields.temp1, ice_sim, Val(:sea_ice_concentration)) # TODO extend for non-ClimaSeaIce, add to Interfacer
43-
sea_ice_concentration = cs.fields.temp1
42+
Interfacer.get_field!(cs.fields.temp1, ice_sim, Val(:ice_concentration)) # TODO extend for non-ClimaSeaIce, add to Interfacer
43+
44+
# TODO ice concentration needs to be binary
45+
ice_concentration = cs.fields.temp1
4446
# max needed to avoid Float32 errors (see issue #271; Heisenbug on HPC)
4547
Interfacer.update_field!(
4648
ice_sim,
4749
Val(:area_fraction),
48-
max.(min.(sea_ice_concentration, FT(1) .- land_fraction), FT(0)),
50+
max.(min.(ice_concentration, FT(1) .- land_fraction), FT(0)),
4951
)
5052
ice_fraction = Interfacer.get_field(ice_sim, Val(:area_fraction))
5153
else
@@ -73,11 +75,7 @@ function update_surface_fractions!(cs::Interfacer.CoupledSimulation)
7375

7476
if haskey(cs.model_sims, :ocean_sim) && haskey(cs.model_sims, :ice_sim)
7577
# TODO add this update_field to interfacer
76-
Interfacer.update_field!(
77-
ocean_sim,
78-
Val(:sea_ice_concentration),
79-
sea_ice_concentration,
80-
)
78+
Interfacer.update_field!(ocean_sim, Val(:ice_concentration), ice_concentration)
8179
end
8280

8381
# check that the sum of area fractions is 1

0 commit comments

Comments
 (0)