Skip to content

Commit ef93c33

Browse files
committed
add coupler fields based on sim types
1 parent e6ba001 commit ef93c33

File tree

15 files changed

+167
-64
lines changed

15 files changed

+167
-64
lines changed

NEWS.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ ClimaCoupler.jl Release Notes
66

77
### ClimaCoupler features
88

9+
#### Add coupler fields based on simulation type PR[#1207](https://github.com/CliMA/ClimaCoupler.jl/pull/1207)
10+
Previously, the coupler fields were hardcoded to be the same for all
11+
simulations, independent of what components were included. Now, each
12+
component model specifies the coupler fields it requires for coupling,
13+
and these are used to construct the set of coupler fields.
14+
TOA radiation and net precipitation are added only if conservation is enabled.
15+
The coupler fields are also now stored as a ClimaCore Field of NamedTuples,
16+
rather than as a NamedTuple of ClimaCore Fields.
17+
918
#### Remove extra `get_field` functions PR[#1203](https://github.com/CliMA/ClimaCoupler.jl/pull/1203)
1019
Removes the `get_field` functions for `air_density` for all models, which
1120
were unused except for the `BucketSimulation` method, which is replaced by a

docs/src/interfacer.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ of SciMLBase.jl.
5151
- `get_model_prog_state(::ComponentModelSimulation)`: A function that
5252
returns the state vector of the simulation at its current state. This
5353
is used for checkpointing the simulation.
54+
- `add_coupler_fields!(coupler_field_names::Set, ::ComponentModelSimulation)`:
55+
A function that adds names of quantities the coupler must exchange
56+
to support this component model. These will be added for each model
57+
in addition to the existing defaults: `z0m_sfc`, `z0b_sfc`, `beta`,
58+
`F_turb_energy`, `F_turb_moisture`, `F_turb_ρτxz`, `F_turb_ρτyz`,
59+
`temp1`, and `temp2`.
5460

5561
### ComponentModelSimulation - optional functions
5662
- `update_sim!(::ComponentModelSimulation, csf, turbulent_fluxes)`: A

experiments/ClimaEarth/components/atmosphere/climaatmos.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,21 @@ end
258258

259259
Interfacer.reinit!(sim::ClimaAtmosSimulation) = Interfacer.reinit!(sim.integrator)
260260

261+
"""
262+
Extend Interfacer.add_coupler_fields! to add the fields required for ClimaAtmosSimulation.
263+
264+
The fields added are:
265+
- `:surface_direct_albedo` (for radiation)
266+
- `:surface_diffuse_albedo` (for radiation)
267+
- `:ϵ_sfc` (for radiation)
268+
- `:T_sfc` (for radiation)
269+
- `:q_sfc` (for moisture)
270+
"""
271+
function Interfacer.add_coupler_fields!(coupler_field_names, ::ClimaAtmosSimulation)
272+
atmos_coupler_fields = [:surface_direct_albedo, :surface_diffuse_albedo, :ϵ_sfc, :T_sfc, :q_sfc]
273+
push!(coupler_field_names, atmos_coupler_fields...)
274+
end
275+
261276
function FieldExchanger.update_sim!(atmos_sim::ClimaAtmosSimulation, csf, turbulent_fluxes)
262277

263278
u = atmos_sim.integrator.u

experiments/ClimaEarth/components/land/climaland_bucket.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,20 @@ end
300300
Interfacer.step!(sim::BucketSimulation, t) = Interfacer.step!(sim.integrator, t - sim.integrator.t, true)
301301
Interfacer.reinit!(sim::BucketSimulation) = Interfacer.reinit!(sim.integrator)
302302

303+
"""
304+
Extend Interfacer.add_coupler_fields! to add the fields required for BucketSimulation.
305+
306+
The fields added are:
307+
- `:ρ_sfc`
308+
- `:F_radiative` (for radiation input)
309+
- `:P_liq` (for precipitation input)
310+
- `:P_snow` (for precipitation input)
311+
"""
312+
function Interfacer.add_coupler_fields!(coupler_field_names, ::BucketSimulation)
313+
bucket_coupler_fields = [:ρ_sfc, :F_radiative, :P_liq, :P_snow]
314+
push!(coupler_field_names, bucket_coupler_fields...)
315+
end
316+
303317
# extensions required by FluxCalculator (partitioned fluxes)
304318
function FluxCalculator.update_turbulent_fluxes!(sim::BucketSimulation, fields::NamedTuple)
305319
(; F_turb_energy, F_turb_moisture) = fields

experiments/ClimaEarth/components/ocean/eisenman_seaice.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,18 @@ end
159159
Interfacer.step!(sim::EisenmanIceSimulation, t) = Interfacer.step!(sim.integrator, t - sim.integrator.t, true)
160160
Interfacer.reinit!(sim::EisenmanIceSimulation) = Interfacer.reinit!(sim.integrator)
161161

162+
"""
163+
Extend Interfacer.add_coupler_fields! to add the fields required for EisenmanIceSimulation.
164+
165+
The fields added are:
166+
- `:ρ_sfc` (for humidity calculation)
167+
- `:F_radiative` (for radiation input)
168+
"""
169+
function Interfacer.add_coupler_fields!(coupler_field_names, ::EisenmanIceSimulation)
170+
eisenman_coupler_fields = [:ρ_sfc, :F_radiative]
171+
push!(coupler_field_names, eisenman_coupler_fields...)
172+
end
173+
162174
# extensions required by FluxCalculator (partitioned fluxes)
163175
function FluxCalculator.update_turbulent_fluxes!(sim::EisenmanIceSimulation, fields::NamedTuple)
164176
(; F_turb_energy) = fields

experiments/ClimaEarth/components/ocean/prescr_seaice.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,18 @@ Interfacer.update_field!(sim::PrescribedIceSimulation, ::Val{:turbulent_moisture
191191
Interfacer.step!(sim::PrescribedIceSimulation, t) = Interfacer.step!(sim.integrator, t - sim.integrator.t, true)
192192
Interfacer.reinit!(sim::PrescribedIceSimulation) = Interfacer.reinit!(sim.integrator)
193193

194+
"""
195+
Extend Interfacer.add_coupler_fields! to add the fields required for PrescribedIceSimulation.
196+
197+
The fields added are:
198+
- `:ρ_sfc` (for humidity calculation)
199+
- `:F_radiative` (for radiation input)
200+
"""
201+
function Interfacer.add_coupler_fields!(coupler_field_names, ::PrescribedIceSimulation)
202+
ice_coupler_fields = [:ρ_sfc, :F_radiative]
203+
push!(coupler_field_names, ice_coupler_fields...)
204+
end
205+
194206
# extensions required by FluxCalculator (partitioned fluxes)
195207
function FluxCalculator.update_turbulent_fluxes!(sim::PrescribedIceSimulation, fields::NamedTuple)
196208
(; F_turb_energy) = fields

experiments/ClimaEarth/components/ocean/slab_ocean.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,18 @@ end
149149
Interfacer.step!(sim::SlabOceanSimulation, t) = Interfacer.step!(sim.integrator, t - sim.integrator.t, true)
150150
Interfacer.reinit!(sim::SlabOceanSimulation) = Interfacer.reinit!(sim.integrator)
151151

152+
"""
153+
Extend Interfacer.add_coupler_fields! to add the fields required for SlabOceanSimulation.
154+
155+
The fields added are:
156+
- `:ρ_sfc` (for humidity calculation)
157+
- `:F_radiative` (for radiation input)
158+
"""
159+
function Interfacer.add_coupler_fields!(coupler_field_names, ::SlabOceanSimulation)
160+
ocean_coupler_fields = [:ρ_sfc, :F_radiative]
161+
push!(coupler_field_names, ocean_coupler_fields...)
162+
end
163+
152164
# extensions required by FluxCalculator (partitioned fluxes)
153165
function FluxCalculator.update_turbulent_fluxes!(sim::SlabOceanSimulation, fields::NamedTuple)
154166
(; F_turb_energy) = fields

experiments/ClimaEarth/setup_run.jl

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -459,34 +459,20 @@ function setup_and_run(config_dict::AbstractDict)
459459
global `CoupledSimulation` struct, `cs`, below.
460460
=#
461461

462-
## coupler exchange fields
463-
coupler_field_names = (
464-
:T_sfc,
465-
:z0m_sfc,
466-
:z0b_sfc,
467-
:ρ_sfc,
468-
:q_sfc,
469-
:surface_direct_albedo,
470-
:surface_diffuse_albedo,
471-
:beta,
472-
:F_turb_energy,
473-
:F_turb_moisture,
474-
:F_turb_ρτxz,
475-
:F_turb_ρτyz,
476-
:F_radiative,
477-
:P_liq,
478-
:P_snow,
479-
:radiative_energy_flux_toa,
480-
:P_net,
481-
:temp1,
482-
:temp2,
483-
)
484-
coupler_fields = NamedTuple{coupler_field_names}(ntuple(i -> zeros(boundary_space), length(coupler_field_names)))
485-
Utilities.show_memory_usage()
486-
487462
## model simulations
488463
model_sims = (atmos_sim = atmos_sim, ice_sim = ice_sim, land_sim = land_sim, ocean_sim = ocean_sim)
489464

465+
## coupler exchange fields
466+
coupler_field_names = Interfacer.default_coupler_fields()
467+
for sim in model_sims
468+
Interfacer.add_coupler_fields!(coupler_field_names, sim)
469+
end
470+
# add coupler fields required to track conservation, if specified
471+
energy_check && push!(coupler_field_names, :radiative_energy_flux_toa, :P_net)
472+
473+
# allocate space for the coupler fields
474+
coupler_fields = Interfacer.init_coupler_fields(FT, coupler_field_names, boundary_space)
475+
490476
## dates
491477
dates = (; date = [date], date0 = [date0])
492478

experiments/ClimaEarth/test/debug_plots_tests.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ plot_field_names(sim::Interfacer.SurfaceStub) = (:stub_field,)
3535
@testset "import_atmos_fields!" begin
3636

3737
boundary_space = TestHelper.create_space(FT)
38-
coupler_names = (
38+
coupler_names = [
3939
:surface_direct_albedo,
4040
:surface_diffuse_albedo,
4141
:F_radiative,
@@ -52,15 +52,15 @@ plot_field_names(sim::Interfacer.SurfaceStub) = (:stub_field,)
5252
:z0b_sfc,
5353
:z0m_sfc,
5454
:radiative_energy_flux_toa,
55-
)
55+
]
5656
atmos_names = (:atmos_field,)
5757
surface_names = (:surface_field,)
5858
stub_names = (:stub_field,)
5959

6060
atmos_fields = NamedTuple{atmos_names}(ntuple(i -> CC.Fields.zeros(boundary_space), length(atmos_names)))
6161
surface_fields = NamedTuple{surface_names}(ntuple(i -> CC.Fields.zeros(boundary_space), length(surface_names)))
6262
stub_fields = NamedTuple{stub_names}(ntuple(i -> CC.Fields.zeros(boundary_space), length(stub_names)))
63-
coupler_fields = NamedTuple{coupler_names}(ntuple(i -> CC.Fields.zeros(boundary_space), length(coupler_names)))
63+
coupler_fields = Interfacer.init_coupler_fields(FT, coupler_names, boundary_space)
6464

6565
model_sims = (;
6666
atmos_sim = ClimaAtmosSimulation(atmos_fields),

experiments/ClimaEarth/user_io/debug_plots.jl

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -95,32 +95,15 @@ function debug(cs::Interfacer.CoupledSimulation, dir = "debug", cs_fields_ref =
9595
end
9696

9797
"""
98-
debug(cs_fields::NamedTuple, dir, cs_fields_ref = nothing)
98+
debug(cs_fields::CC.Fields.Field, dir, cs_fields_ref = nothing)
9999
100100
Plot useful coupler fields (in `field_names`) and save plots to a directory.
101101
102102
If `cs_fields_ref` is provided (e.g., using a copy of cs.fields from the initialization),
103103
plot the anomalies of the fields with respect to `cs_fields_ref`.
104104
"""
105-
function debug(cs_fields::NamedTuple, dir, cs_fields_ref = nothing)
106-
field_names = (
107-
:surface_direct_albedo,
108-
:surface_diffuse_albedo,
109-
:F_radiative,
110-
:F_turb_energy,
111-
:F_turb_moisture,
112-
:F_turb_ρτxz,
113-
:F_turb_ρτyz,
114-
:P_liq,
115-
:P_snow,
116-
:T_sfc,
117-
:ρ_sfc,
118-
:q_sfc,
119-
:beta,
120-
:z0b_sfc,
121-
:z0m_sfc,
122-
:radiative_energy_flux_toa,
123-
)
105+
function debug(cs_fields::CC.Fields.Field, dir, cs_fields_ref = nothing)
106+
field_names = propertynames(cs_fields)
124107
fig = Makie.Figure(size = (1500, 800))
125108
min_square_len = ceil(Int, sqrt(length(field_names)))
126109
for i in 1:min_square_len, j in 1:min_square_len

0 commit comments

Comments
 (0)