Skip to content

Commit 73e0fb2

Browse files
Akshay SridharAkshay Sridhar
Akshay Sridhar
authored and
Akshay Sridhar
committed
Merge remote-tracking branch 'origin/as/calibrate_expt' into as/calibrate_expt
2 parents ef6d85f + 1368b90 commit 73e0fb2

File tree

7 files changed

+891
-3
lines changed

7 files changed

+891
-3
lines changed

calibration/coupler_component_init.jl

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
2+
# get the paths to the necessary data files: land-sea mask, sst map, sea ice concentration
3+
include(joinpath(pkgdir(ClimaCoupler), "artifacts", "artifact_funcs.jl"))
4+
sst_data = joinpath(sst_dataset_path(), "sst.nc")
5+
sic_data = joinpath(sic_dataset_path(), "sic.nc")
6+
co2_data = joinpath(co2_dataset_path(), "mauna_loa_co2.nc")
7+
land_mask_data = joinpath(mask_dataset_path(), "seamask.nc")
8+
9+
atmos_sim = atmos_init(FT, config_dict_atmos);
10+
thermo_params = get_thermo_params(atmos_sim) # TODO: this should be shared by all models
11+
12+
#=
13+
We use a common `Space` for all global surfaces. This enables the MPI processes to operate on the same columns in both
14+
the atmospheric and surface components, so exchanges are parallelized. Note this is only possible when the
15+
atmosphere and surface are of the same horizontal resolution.
16+
=#
17+
## init a 2D boundary space at the surface
18+
boundary_space = Spaces.horizontal_space(atmos_sim.domain.face_space)
19+
20+
# init land-sea fraction
21+
land_fraction =
22+
FT.(
23+
Regridder.land_fraction(
24+
FT,
25+
REGRID_DIR,
26+
comms_ctx,
27+
land_mask_data,
28+
"LSMASK",
29+
boundary_space,
30+
mono = mono_surface,
31+
)
32+
)
33+
34+
@info mode_name
35+
if mode_name == "amip"
36+
@info "AMIP boundary conditions - do not expect energy conservation"
37+
38+
## land
39+
land_sim = bucket_init(
40+
FT,
41+
tspan,
42+
config_dict["land_domain_type"],
43+
config_dict["land_albedo_type"],
44+
config_dict["land_temperature_anomaly"],
45+
comms_ctx,
46+
REGRID_DIR;
47+
dt = Δt_cpl,
48+
space = boundary_space,
49+
saveat = saveat,
50+
area_fraction = land_fraction,
51+
date_ref = date0,
52+
t_start = t_start,
53+
)
54+
55+
## ocean
56+
SST_info = bcfile_info_init(
57+
FT,
58+
REGRID_DIR,
59+
sst_data,
60+
"SST",
61+
boundary_space,
62+
comms_ctx,
63+
interpolate_daily = true,
64+
scaling_function = clean_sst, ## convert to Kelvin
65+
land_fraction = land_fraction,
66+
date0 = date0,
67+
mono = mono_surface,
68+
)
69+
70+
update_midmonth_data!(date0, SST_info)
71+
SST_init = interpolate_midmonth_to_daily(date0, SST_info)
72+
ocean_sim = SurfaceStub((;
73+
T_sfc = SST_init,
74+
ρ_sfc = ClimaCore.Fields.zeros(boundary_space),
75+
z0m = FT(1e-3),
76+
z0b = FT(1e-3),
77+
beta = FT(1),
78+
α = FT(0.06),
79+
area_fraction = (FT(1) .- land_fraction),
80+
phase = TD.Liquid(),
81+
thermo_params = thermo_params,
82+
))
83+
84+
## sea ice
85+
SIC_info = bcfile_info_init(
86+
FT,
87+
REGRID_DIR,
88+
sic_data,
89+
"SEAICE",
90+
boundary_space,
91+
comms_ctx,
92+
interpolate_daily = true,
93+
scaling_function = clean_sic, ## convert to fraction
94+
land_fraction = land_fraction,
95+
date0 = date0,
96+
mono = mono_surface,
97+
)
98+
update_midmonth_data!(date0, SIC_info)
99+
SIC_init = interpolate_midmonth_to_daily(date0, SIC_info)
100+
ice_fraction = get_ice_fraction.(SIC_init, mono_surface)
101+
ice_sim = ice_init(
102+
FT;
103+
tspan = tspan,
104+
dt = Δt_cpl,
105+
space = boundary_space,
106+
saveat = saveat,
107+
area_fraction = ice_fraction,
108+
thermo_params = thermo_params,
109+
)
110+
111+
## CO2 concentration
112+
CO2_info = bcfile_info_init(
113+
FT,
114+
REGRID_DIR,
115+
co2_data,
116+
"co2",
117+
boundary_space,
118+
comms_ctx,
119+
interpolate_daily = true,
120+
land_fraction = ones(boundary_space),
121+
date0 = date0,
122+
mono = mono_surface,
123+
)
124+
125+
update_midmonth_data!(date0, CO2_info)
126+
CO2_init = interpolate_midmonth_to_daily(date0, CO2_info)
127+
update_field!(atmos_sim, Val(:co2_gm), CO2_init)
128+
129+
mode_specifics = (; name = mode_name, SST_info = SST_info, SIC_info = SIC_info, CO2_info = CO2_info)
130+
131+
elseif mode_name in ("slabplanet", "slabplanet_aqua", "slabplanet_terra")
132+
133+
land_fraction = mode_name == "slabplanet_aqua" ? land_fraction .* 0 : land_fraction
134+
land_fraction = mode_name == "slabplanet_terra" ? land_fraction .* 0 .+ 1 : land_fraction
135+
136+
## land
137+
land_sim = bucket_init(
138+
FT,
139+
tspan,
140+
config_dict["land_domain_type"],
141+
config_dict["land_albedo_type"],
142+
config_dict["land_temperature_anomaly"],
143+
comms_ctx,
144+
REGRID_DIR;
145+
dt = Δt_cpl,
146+
space = boundary_space,
147+
saveat = saveat,
148+
area_fraction = land_fraction,
149+
date_ref = date0,
150+
t_start = t_start,
151+
)
152+
153+
## ocean
154+
ocean_sim = ocean_init(
155+
FT;
156+
tspan = tspan,
157+
dt = Δt_cpl,
158+
space = boundary_space,
159+
saveat = saveat,
160+
area_fraction = (FT(1) .- land_fraction), ## NB: this ocean fraction includes areas covered by sea ice (unlike the one contained in the cs)
161+
thermo_params = thermo_params,
162+
evolving = evolving_ocean,
163+
)
164+
165+
## sea ice (here set to zero area coverage)
166+
ice_sim = SurfaceStub((;
167+
T_sfc = ClimaCore.Fields.ones(boundary_space),
168+
ρ_sfc = ClimaCore.Fields.zeros(boundary_space),
169+
z0m = FT(0),
170+
z0b = FT(0),
171+
beta = FT(1),
172+
α = FT(1),
173+
area_fraction = ClimaCore.Fields.zeros(boundary_space),
174+
phase = TD.Ice(),
175+
thermo_params = thermo_params,
176+
))
177+
178+
mode_specifics = (; name = mode_name, SST_info = nothing, SIC_info = nothing)
179+
end
180+
181+
#=
182+
## Coupler Initialization
183+
The coupler needs to contain exchange information, manage the calendar and be able to access all component models. It can also optionally
184+
save online diagnostics. These are all initialized here and saved in a global `CouplerSimulation` struct, `cs`.
185+
=#
186+
187+
## coupler exchange fields
188+
coupler_field_names = (
189+
:T_S,
190+
:z0m_S,
191+
:z0b_S,
192+
:ρ_sfc,
193+
:q_sfc,
194+
:albedo,
195+
:beta,
196+
:F_turb_energy,
197+
:F_turb_moisture,
198+
:F_turb_ρτxz,
199+
:F_turb_ρτyz,
200+
:F_radiative,
201+
:P_liq,
202+
:P_snow,
203+
:F_radiative_TOA,
204+
:P_net,
205+
)
206+
coupler_fields =
207+
NamedTuple{coupler_field_names}(ntuple(i -> ClimaCore.Fields.zeros(boundary_space), length(coupler_field_names)))
208+
209+
## model simulations
210+
model_sims = (atmos_sim = atmos_sim, ice_sim = ice_sim, land_sim = land_sim, ocean_sim = ocean_sim);
211+
212+
## dates
213+
dates = (; date = [date], date0 = [date0], date1 = [Dates.firstdayofmonth(date0)], new_month = [false])
214+
215+
#=
216+
### Online Diagnostics
217+
User can write custom diagnostics in the `user_diagnostics.jl`.
218+
=#
219+
monthly_3d_diags = init_diagnostics(
220+
(:T, :u, :q_tot, :q_liq_ice),
221+
atmos_sim.domain.center_space;
222+
save = Monthly(),
223+
operations = (; accumulate = TimeMean([Int(0)])),
224+
output_dir = COUPLER_OUTPUT_DIR,
225+
name_tag = "monthly_mean_3d_",
226+
)
227+
228+
monthly_2d_diags = init_diagnostics(
229+
(:precipitation_rate, :toa_fluxes, :T_sfc, :tubulent_energy_fluxes),
230+
boundary_space;
231+
save = Monthly(),
232+
operations = (; accumulate = TimeMean([Int(0)])),
233+
output_dir = COUPLER_OUTPUT_DIR,
234+
name_tag = "monthly_mean_2d_",
235+
)
236+
237+
diagnostics = (monthly_3d_diags, monthly_2d_diags)
238+
239+
#=
240+
## Initialize Conservation Checks
241+
=#
242+
## init conservation info collector
243+
conservation_checks = nothing
244+
if energy_check
245+
@assert(
246+
mode_name[1:10] == "slabplanet" && !CA.is_distributed(ClimaComms.context(boundary_space)),
247+
"Only non-distributed slabplanet allowable for energy_check"
248+
)
249+
conservation_checks = (; energy = EnergyConservationCheck(model_sims), water = WaterConservationCheck(model_sims))
250+
end
251+
252+
dir_paths = (; output = COUPLER_OUTPUT_DIR, artifacts = COUPLER_ARTIFACTS_DIR)
253+
checkpoint_cb =
254+
HourlyCallback(dt = FT(480), func = checkpoint_sims, ref_date = [dates.date[1]], active = hourly_checkpoint) # 20 days
255+
update_firstdayofmonth!_cb =
256+
MonthlyCallback(dt = FT(1), func = update_firstdayofmonth!, ref_date = [dates.date1[1]], active = true) # for BCReader
257+
callbacks = (; checkpoint = checkpoint_cb, update_firstdayofmonth! = update_firstdayofmonth!_cb)
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
surface_thermo_state_type: "GCMSurfaceThermoState"
2+
topo_smoothing: false
3+
warn_allocations_diagnostics: false
4+
hyperdiff: "ClimaHyperdiffusion"
5+
dt: "150secs"
6+
output_dir: "experiments/amip_coupled/truth_simulation"
7+
prognostic_tke: false
8+
override_τ_precip: true
9+
use_newton_rtol: false
10+
netcdf_output_at_levels: false
11+
device: "auto"
12+
t_end: "150secs"
13+
dz_top: 3000.0
14+
y_elem: 6
15+
z_stretch: false
16+
bubble: true
17+
ode_algo: "ARS343"
18+
max_newton_iters_ode: 1
19+
start_date: "19790101"
20+
check_precipitation: false
21+
forcing: ~
22+
edmfx_nh_pressure: false
23+
scalar_hyperdiffusion_coefficient: 1.5
24+
prognostic_surface: "false"
25+
test_dycore_consistency: false
26+
moist: "equil"
27+
perf_mode: "PerfStandard"
28+
edmf_coriolis: ~
29+
rad: "gray"
30+
rayleigh_sponge: true
31+
initial_condition: "DecayingProfile"
32+
cloud_model: "quadrature"
33+
krylov_rtol: 0.1
34+
divergence_damping_factor: 1.0
35+
edmfx_entr_model: ~
36+
eisenstat_walker_forcing_alpha: 2.0
37+
dt_cloud_fraction: "3hours"
38+
smoothing_order: 3
39+
idealized_h2o: false
40+
surface_setup: "PrescribedSurface"
41+
perturb_initstate: true
42+
jvp_step_adjustment: 1.0
43+
discrete_hydrostatic_balance: false
44+
netcdf_interpolate_z_over_msl: false
45+
log_progress: true
46+
dz_bottom: 30.0
47+
h_elem: 16
48+
dt_save_state_to_disk: "Inf"
49+
netcdf_interpolation_num_points: ~
50+
advection_test: false
51+
z_max: 30000.0
52+
apply_limiter: false
53+
topography: "NoWarp"
54+
reference_job_id: ~
55+
precip_model: "0M"
56+
perf_summary: false
57+
vorticity_hyperdiffusion_coefficient: 1.5
58+
viscous_sponge: false
59+
surface_temperature: "ZonallySymmetric"
60+
diagnostics:
61+
- short_name:
62+
- "pfull"
63+
- "wa"
64+
- "va"
65+
- "rv"
66+
period: "150secs"
67+
reduction: "average"
68+
job_id: "target_amip_n1_shortrun"
69+
orographic_gravity_wave: ~
70+
dt_rad: "1hours"
71+
approximate_linear_solve_iters: 1
72+
edmfx_upwinding: "none"
73+
tracer_upwinding: "none"
74+
nh_poly: 3
75+
edmfx_sgs_diffusive_flux: false
76+
y_max: 300000.0
77+
non_orographic_gravity_wave: false
78+
use_reference_state: true
79+
config: "sphere"
80+
energy_upwinding: "none"
81+
FLOAT_TYPE: "Float64"
82+
updraft_number: 1
83+
split_ode: true
84+
regression_test: false
85+
check_conservation: false
86+
ls_adv: ~
87+
output_default_diagnostics: true
88+
implicit_diffusion: false
89+
x_max: 300000.0
90+
edmfx_sgs_mass_flux: false
91+
z_elem: 50
92+
newton_rtol: 1.0e-5
93+
fps: 5
94+
edmfx_sgsflux_upwinding: "none"
95+
turbconv: ~
96+
x_elem: 6
97+
idealized_clouds: false
98+
vert_diff: "true"
99+
use_krylov_method: false
100+
subsidence: ~
101+
use_dynamic_krylov_rtol: false
102+
idealized_insolation: true
103+
toml:
104+
- "/Users/akshaysridhar/.julia/packages/ClimaCoupler/utcpx/toml/default_coarse.toml"
105+
edmfx_detr_model: ~
106+
dt_save_to_sol: "1days"

0 commit comments

Comments
 (0)