Skip to content

Commit 490efc1

Browse files
committed
fixes; runs with correct (?) fluxes
1 parent 1cac563 commit 490efc1

File tree

3 files changed

+68
-11
lines changed

3 files changed

+68
-11
lines changed

experiments/ClimaEarth/components/ocean/clima_seaice.jl

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ previous step is provided to the coupler to be used in computing fluxes.
5050
Specific details about the default model configuration
5151
can be found in the documentation for `ClimaOcean.ocean_simulation`.
5252
"""
53-
function ClimaSeaIceSimulation(land_fraction, ocean; output_dir)
53+
function ClimaSeaIceSimulation(land_fraction, ocean; output_dir, start_date = nothing)
5454
# Initialize the sea ice with the same grid as the ocean
5555
grid = ocean.ocean.model.grid
5656
arch = OC.Architectures.architecture(grid)
@@ -59,6 +59,23 @@ function ClimaSeaIceSimulation(land_fraction, ocean; output_dir)
5959

6060
ice = CO.sea_ice_simulation(grid, ocean.ocean; advection, top_heat_boundary_condition)
6161

62+
# Initialize nonzero sea ice if start date provided
63+
if !isnothing(start_date)
64+
sic_metadata = CO.DataWrangling.Metadatum(
65+
:sea_ice_concentration,
66+
dataset = CO.DataWrangling.ECCO.ECCO4Monthly(),
67+
date = start_date,
68+
)
69+
h_metadata = CO.DataWrangling.Metadatum(
70+
:sea_ice_thickness,
71+
dataset = CO.DataWrangling.ECCO.ECCO4Monthly(),
72+
date = start_date,
73+
)
74+
75+
OC.set!(ice.model.ice_concentration, sic_metadata)
76+
OC.set!(ice.model.ice_thickness, h_metadata)
77+
end
78+
6279
melting_speed = 1e-4
6380

6481
# Since ocean and sea ice share the same grid, we can also share the remapping objects
@@ -168,6 +185,7 @@ function FluxCalculator.update_turbulent_fluxes!(sim::ClimaSeaIceSimulation, fie
168185

169186
(; F_lh, F_sh, F_turb_ρτxz, F_turb_ρτyz, F_turb_moisture) = fields
170187
grid = sim.ice.model.grid
188+
ice_concentration = sim.ice.model.ice_concentration
171189

172190
# Remap momentum fluxes onto reduced 2D Center, Center fields using scratch arrays and fields
173191
CC.Remapping.interpolate!(
@@ -208,8 +226,8 @@ function FluxCalculator.update_turbulent_fluxes!(sim::ClimaSeaIceSimulation, fie
208226

209227
# Update the sea ice only where the concentration is greater than zero.
210228
si_flux_heat = sim.ice.model.external_heat_fluxes.top
211-
OC.interior(si_flux_heat, :, :, 1) .=
212-
OC.interior(si_flux_heat, :, :, 1) .+ (remapped_F_lh .+ remapped_F_sh)
229+
OC.interior(si_flux_heat, :, :, 1) .+=
230+
(OC.interior(ice_concentration, :, :, 1) .> 0) .* (remapped_F_lh .+ remapped_F_sh)
213231

214232
return nothing
215233
end
@@ -220,7 +238,7 @@ function Interfacer.update_field!(sim::ClimaSeaIceSimulation, ::Val{:area_fracti
220238
end
221239

222240
"""
223-
FieldExchanger.update_sim!(sim::ClimaSeaIceSimulation, csf, area_fraction)
241+
FieldExchanger.update_sim!(sim::ClimaSeaIceSimulation, csf)
224242
225243
Update the sea ice simulation with the provided fields, which have been filled in
226244
by the coupler.
@@ -238,20 +256,47 @@ ClimaAtmos provides precipitation as a negative flux at the surface, and
238256
ClimaSeaIce represents precipitation as a positive salinity flux,
239257
so a sign change is needed when we convert from precipitation to salinity flux.
240258
"""
241-
function FieldExchanger.update_sim!(sim::ClimaSeaIceSimulation, csf, area_fraction)
259+
function FieldExchanger.update_sim!(sim::ClimaSeaIceSimulation, csf)
260+
ice_concentration = sim.ice.model.ice_concentration
261+
242262
# Remap radiative flux onto scratch array; rename for clarity
243263
CC.Remapping.interpolate!(
244264
sim.remapping.scratch_arr1,
245265
sim.remapping.remapper_cc,
246-
csf.F_radiative,
266+
csf.SW_d,
247267
)
248-
remapped_F_radiative = sim.remapping.scratch_arr1
268+
remapped_SW_d = sim.remapping.scratch_arr1
269+
270+
CC.Remapping.interpolate!(
271+
sim.remapping.scratch_arr2,
272+
sim.remapping.remapper_cc,
273+
csf.LW_d,
274+
)
275+
remapped_LW_d = sim.remapping.scratch_arr2
249276

250277
# Update only the part due to radiative fluxes. For the full update, the component due
251278
# to latent and sensible heat is missing and will be updated in update_turbulent_fluxes.
252279
si_flux_heat = sim.ice.model.external_heat_fluxes.top
253-
OC.interior(si_flux_heat, :, :, 1) .= remapped_F_radiative
280+
# TODO: get sigma from parameters
281+
σ = 5.67e-8
282+
α = Interfacer.get_field(sim, Val(:surface_direct_albedo)) # scalar
283+
ϵ = Interfacer.get_field(sim, Val(:emissivity)) # scalar
254284

285+
# Update only where ice concentration is greater than zero.
286+
OC.interior(si_flux_heat, :, :, 1) .=
287+
(OC.interior(ice_concentration, :, :, 1) .> 0) .* .-(1 .- α) .* remapped_SW_d .-
288+
ϵ .* (
289+
remapped_LW_d .-
290+
σ .*
291+
(
292+
273.15 .+ OC.interior(
293+
sim.ice.model.ice_thermodynamics.top_surface_temperature,
294+
:,
295+
:,
296+
1,
297+
)
298+
) .^ 4
299+
)
255300
return nothing
256301
end
257302

@@ -352,9 +397,9 @@ end
352397
i, j = @index(Global, NTuple)
353398

354399
# ℑxᶠᵃᵃ: interpolate faces to centers
355-
oc_flux_u +=
400+
oc_flux_u[i, j, 1] +=
356401
ρτxio[i, j, 1] * ρₒ⁻¹ * OC.Operators.ℑxᶠᵃᵃ(i, j, 1, grid, ice_concentration)
357-
oc_flux_v +=
402+
oc_flux_v[i, j, 1] +=
358403
ρτyio[i, j, 1] * ρₒ⁻¹ * OC.Operators.ℑyᵃᶠᵃ(i, j, 1, grid, ice_concentration)
359404
end
360405

experiments/ClimaEarth/setup_run.jl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ function CoupledSimulation(config_dict::AbstractDict)
308308
shared_surface_space = share_surface_space ? boundary_space : nothing
309309
if land_model == "bucket"
310310

311-
# TODO only for cmip
311+
# TODO move this into resolve_area_fractions and call after init, think about restarts
312312
polar_mask = CC.Fields.zeros(boundary_space)
313313
lat = CC.Fields.coordinate_field(boundary_space).lat
314314
polar_mask .= abs.(lat) .>= FT(80)
@@ -375,6 +375,7 @@ function CoupledSimulation(config_dict::AbstractDict)
375375
@assert sim_mode <: CMIPMode
376376

377377
# TODO how should we initialize ocean fraction when using ClimaSeaIce?
378+
# TODO init everything with AF=1, then resolve after getting sea ice
378379
sic_data = try
379380
joinpath(
380381
@clima_artifact("historical_sst_sic", comms_ctx),
@@ -423,6 +424,14 @@ function CoupledSimulation(config_dict::AbstractDict)
423424
ice_fraction,
424425
ocean_sim;
425426
output_dir = dir_paths.ice_output_dir,
427+
start_date,
428+
)
429+
# TODO don't need to initialize ocean fraction correctly if we do this
430+
# TODO can rename to `resolve_area_fractions!` and also make land_fraction cover poles here instead of in driver
431+
FieldExchanger.resolve_ocean_ice_fractions!(
432+
ocean_sim,
433+
ice_sim,
434+
land_fraction,
426435
)
427436
end
428437
else
@@ -600,6 +609,8 @@ function CoupledSimulation(config_dict::AbstractDict)
600609
# 3. Update any fields in the model caches that can only be filled after the initial exchange.
601610
FieldExchanger.set_caches!(cs)
602611

612+
# TODO think about calling exchange again here to provide correct rad fluxes to surfaces
613+
603614
# 4. Calculate and update turbulent fluxes for each surface model,
604615
# and save the weighted average in coupler fields
605616
FluxCalculator.turbulent_fluxes!(cs)

src/FieldExchanger.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ function update_sim!(sim::Interfacer.SurfaceModelSimulation, csf)
217217
# radiative fluxes
218218
Interfacer.update_field!(sim, Val(:SW_d), csf.SW_d)
219219
Interfacer.update_field!(sim, Val(:LW_d), csf.LW_d)
220+
# TODO need to compute SWU, LWU here too
220221

221222
# precipitation
222223
Interfacer.update_field!(sim, Val(:liquid_precipitation), csf.P_liq)

0 commit comments

Comments
 (0)