Skip to content

Commit 990593a

Browse files
committed
revamp ConservationChecker
add to driver add to driver conserves clean up
1 parent 102ad86 commit 990593a

File tree

9 files changed

+387
-496
lines changed

9 files changed

+387
-496
lines changed

config/model_configs/interactive_debug.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ rad: "gray"
44
energy_check: true
55
mode_name: "slabplanet"
66
t_end: "10days"
7-
dt_save_to_sol: "3600secs"
8-
dt_cpl: 200
9-
dt: "200secs"
7+
dt_save_to_sol: "2days"
8+
dt_cpl: 400
9+
dt: "400secs"
1010
mono_surface: true
1111
turb_flux_partition: "CombinedStateFluxes"
1212
h_elem: 4

experiments/AMIP/modular/components/atmosphere/climaatmos_init.jl

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,14 @@ end
7171
# extensions required by the Interfacer
7272
get_field(sim::ClimaAtmosSimulation, ::Val{:radiative_energy_flux}) =
7373
Fields.level(sim.integrator.p.ᶠradiation_flux, half)
74-
get_field(sim::ClimaAtmosSimulation, ::Val{:liquid_precipitation}) =
75-
sim.integrator.p.col_integrated_rain .+ sim.integrator.p.col_integrated_snow # all fallen snow melts for now
76-
get_field(sim::ClimaAtmosSimulation, ::Val{:snow_precipitation}) = sim.integrator.p.col_integrated_snow .* FT(0)
74+
function get_field(sim::ClimaAtmosSimulation, ::Val{:liquid_precipitation})
75+
ρ_liq = CAP.ρ_cloud_liq(sim.integrator.p.params)
76+
sim.integrator.p.col_integrated_rain .* ρ_liq #.+ sim.integrator.p.col_integrated_snow .* ρ_liq # kg/m^2/s ; all fallen snow melts for now
77+
end
78+
function get_field(sim::ClimaAtmosSimulation, ::Val{:snow_precipitation}) # kg/m^2/s
79+
ρ_liq = CAP.ρ_cloud_liq(sim.integrator.p.params)
80+
sim.integrator.p.col_integrated_snow .* ρ_liq #.* FT(0)
81+
end
7782

7883
get_field(sim::ClimaAtmosSimulation, ::Val{:turbulent_energy_flux}) =
7984
Geometry.WVector.(sim.integrator.p.sfc_conditions.ρ_flux_h_tot)
@@ -252,3 +257,40 @@ Extension of Checkpointer.get_model_state_vector to get the model state.
252257
function get_model_state_vector(sim::ClimaAtmosSimulation)
253258
return sim.integrator.u
254259
end
260+
261+
function get_field(atmos_sim::ClimaAtmosSimulation, ::Val{:F_radiative_TOA})
262+
radiation = atmos_sim.integrator.p.radiation_model
263+
FT = eltype(atmos_sim.integrator.u)
264+
# save radiation source
265+
if radiation != nothing
266+
face_space = axes(atmos_sim.integrator.u.f)
267+
z = parent(Fields.coordinate_field(face_space).z)
268+
Δz_top = round(FT(0.5) * (z[end, 1, 1, 1, 1] - z[end - 1, 1, 1, 1, 1]))
269+
n_faces = length(z[:, 1, 1, 1, 1])
270+
271+
LWd_TOA = Fields.level(
272+
RRTMGPI.array2field(FT.(atmos_sim.integrator.p.radiation_model.face_lw_flux_dn), face_space),
273+
n_faces - half,
274+
)
275+
LWu_TOA = Fields.level(
276+
RRTMGPI.array2field(FT.(atmos_sim.integrator.p.radiation_model.face_lw_flux_up), face_space),
277+
n_faces - half,
278+
)
279+
SWd_TOA = Fields.level(
280+
RRTMGPI.array2field(FT.(atmos_sim.integrator.p.radiation_model.face_sw_flux_dn), face_space),
281+
n_faces - half,
282+
)
283+
SWu_TOA = Fields.level(
284+
RRTMGPI.array2field(FT.(atmos_sim.integrator.p.radiation_model.face_sw_flux_up), face_space),
285+
n_faces - half,
286+
)
287+
288+
return @. -(LWd_TOA + SWd_TOA - LWu_TOA - SWu_TOA) # [W/m^2]
289+
else
290+
return FT(0)
291+
end
292+
end
293+
294+
get_field(atmos_sim::ClimaAtmosSimulation, ::Val{:energy}) = atmos_sim.integrator.u.c.ρe_tot
295+
296+
get_field(atmos_sim::ClimaAtmosSimulation, ::Val{:water}) = atmos_sim.integrator.u.c.ρq_tot

experiments/AMIP/modular/components/land/bucket_utils.jl

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11

2-
"""
3-
get_bucket_energy(bucket_sim)
4-
5-
Returns the volumetric internal energy of the bucket land model.
6-
"""
7-
function get_land_energy(bucket_sim::BucketSimulation, e_per_area)
2+
function get_field(bucket_sim::BucketSimulation, ::Val{:energy})
83
# required by ConservationChecker
9-
e_per_area .= zeros(axes(bucket_sim.integrator.u.bucket.W))
10-
soil_depth = FT = eltype(bucket_sim.integrator.u.bucket.W)
4+
e_per_area = zeros(axes(bucket_sim.integrator.u.bucket.W))
115
ClimaCore.Fields.bycolumn(axes(bucket_sim.integrator.u.bucket.T)) do colidx
126
e_per_area[colidx] .=
137
bucket_sim.model.parameters.ρc_soil .* mean(bucket_sim.integrator.u.bucket.T[colidx]) .*
@@ -20,6 +14,13 @@ function get_land_energy(bucket_sim::BucketSimulation, e_per_area)
2014
return e_per_area
2115
end
2216

17+
function get_field(bucket_sim::BucketSimulation, ::Val{:water})
18+
ρ_cloud_liq = ClimaLSM.LSMP.ρ_cloud_liq(bucket_sim.model.parameters.earth_param_set)
19+
return
20+
@. (bucket_sim.integrator.u.bucket.σS + bucket_sim.integrator.u.bucket.W + bucket_sim.integrator.u.bucket.Ws) *
21+
ρ_cloud_liq # kg water / m2
22+
end
23+
2324
"""
2425
get_land_temp_from_state(land_sim, u)
2526
Returns the surface temperature of the earth, computed
@@ -105,10 +106,12 @@ function update_field!(sim::BucketSimulation, ::Val{:radiative_energy_flux}, fie
105106
parent(sim.integrator.p.bucket.R_n) .= parent(field)
106107
end
107108
function update_field!(sim::BucketSimulation, ::Val{:liquid_precipitation}, field)
108-
parent(sim.integrator.p.bucket.P_liq) .= parent(field)
109+
ρ_liq = (LSMP.ρ_cloud_liq(sim.model.parameters.earth_param_set))
110+
parent(sim.integrator.p.bucket.P_liq) .= parent(field ./ ρ_liq)
109111
end
110112
function update_field!(sim::BucketSimulation, ::Val{:snow_precipitation}, field)
111-
parent(sim.integrator.p.bucket.P_snow) .= parent(field)
113+
ρ_liq = (LSMP.ρ_cloud_liq(sim.model.parameters.earth_param_set))
114+
parent(sim.integrator.p.bucket.P_snow) .= parent(field ./ ρ_liq)
112115
end
113116

114117
function update_field!(sim::BucketSimulation, ::Val{:air_density}, field)

experiments/AMIP/modular/components/ocean/slab_ocean_init.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,8 @@ Extension of Checkpointer.get_model_state_vector to get the model state.
157157
function get_model_state_vector(sim::SlabOceanSimulation)
158158
return sim.integrator.u
159159
end
160+
161+
get_field(sim::SlabOceanSimulation, ::Val{:energy}) =
162+
sim.integrator.p.params.ρ .* sim.integrator.p.params.c .* sim.integrator.u.T_sfc .* sim.integrator.p.params.h
163+
164+
get_field(sim::SlabOceanSimulation, ::Val{:water}) = nothing

experiments/AMIP/modular/components/ocean/slab_seaice_init.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,8 @@ Extension of Checkpointer.get_model_state_vector to get the model state.
167167
function get_model_state_vector(sim::PrescribedIceSimulation)
168168
return sim.integrator.u
169169
end
170+
171+
get_field(sim::PrescribedIceSimulation, ::Val{:energy}) =
172+
sim.integrator.p.params.ρ .* sim.integrator.p.params.c .* sim.integrator.u.T_sfc .* sim.integrator.p.params.h
173+
174+
get_field(sim::PrescribedIceSimulation, ::Val{:water}) = nothing

experiments/AMIP/modular/coupler_driver_modular.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,7 @@ if energy_check
387387
mode_name == "slabplanet" && !CA.is_distributed(ClimaComms.context(boundary_space)),
388388
"Only non-distributed slabplanet allowable for energy_check"
389389
)
390-
conservation_checks =
391-
(; energy = EnergyConservationCheck([], [], [], [], [], []), water = WaterConservationCheck([], [], [], []))
390+
conservation_checks = (; energy = EnergyConservationCheck(model_sims), water = WaterConservationCheck(model_sims))
392391
end
393392

394393
## coupler simulation
@@ -516,7 +515,7 @@ function solve_coupler!(cs)
516515
end
517516

518517
## compute global energy
519-
!isnothing(cs.conservation_checks) ? check_conservation!(cs, get_slab_energy, get_land_energy) : nothing
518+
!isnothing(cs.conservation_checks) ? check_conservation!(cs) : nothing
520519

521520
## run component models sequentially for one coupling timestep (Δt_cpl)
522521
ClimaComms.barrier(comms_ctx)

0 commit comments

Comments
 (0)