Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/as/calibrate_expt' into as/calib…
Browse files Browse the repository at this point in the history
…rate_expt
  • Loading branch information
Akshay Sridhar authored and Akshay Sridhar committed Mar 13, 2024
2 parents ef6d85f + 1368b90 commit 73e0fb2
Show file tree
Hide file tree
Showing 7 changed files with 891 additions and 3 deletions.
257 changes: 257 additions & 0 deletions calibration/coupler_component_init.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@

# get the paths to the necessary data files: land-sea mask, sst map, sea ice concentration
include(joinpath(pkgdir(ClimaCoupler), "artifacts", "artifact_funcs.jl"))
sst_data = joinpath(sst_dataset_path(), "sst.nc")
sic_data = joinpath(sic_dataset_path(), "sic.nc")
co2_data = joinpath(co2_dataset_path(), "mauna_loa_co2.nc")
land_mask_data = joinpath(mask_dataset_path(), "seamask.nc")

atmos_sim = atmos_init(FT, config_dict_atmos);
thermo_params = get_thermo_params(atmos_sim) # TODO: this should be shared by all models

#=
We use a common `Space` for all global surfaces. This enables the MPI processes to operate on the same columns in both
the atmospheric and surface components, so exchanges are parallelized. Note this is only possible when the
atmosphere and surface are of the same horizontal resolution.
=#
## init a 2D boundary space at the surface
boundary_space = Spaces.horizontal_space(atmos_sim.domain.face_space)

# init land-sea fraction
land_fraction =
FT.(
Regridder.land_fraction(
FT,
REGRID_DIR,
comms_ctx,
land_mask_data,
"LSMASK",
boundary_space,
mono = mono_surface,
)
)

@info mode_name
if mode_name == "amip"
@info "AMIP boundary conditions - do not expect energy conservation"

## land
land_sim = bucket_init(
FT,
tspan,
config_dict["land_domain_type"],
config_dict["land_albedo_type"],
config_dict["land_temperature_anomaly"],
comms_ctx,
REGRID_DIR;
dt = Δt_cpl,
space = boundary_space,
saveat = saveat,
area_fraction = land_fraction,
date_ref = date0,
t_start = t_start,
)

## ocean
SST_info = bcfile_info_init(
FT,
REGRID_DIR,
sst_data,
"SST",
boundary_space,
comms_ctx,
interpolate_daily = true,
scaling_function = clean_sst, ## convert to Kelvin
land_fraction = land_fraction,
date0 = date0,
mono = mono_surface,
)

update_midmonth_data!(date0, SST_info)
SST_init = interpolate_midmonth_to_daily(date0, SST_info)
ocean_sim = SurfaceStub((;
T_sfc = SST_init,
ρ_sfc = ClimaCore.Fields.zeros(boundary_space),
z0m = FT(1e-3),
z0b = FT(1e-3),
beta = FT(1),
α = FT(0.06),
area_fraction = (FT(1) .- land_fraction),
phase = TD.Liquid(),
thermo_params = thermo_params,
))

## sea ice
SIC_info = bcfile_info_init(
FT,
REGRID_DIR,
sic_data,
"SEAICE",
boundary_space,
comms_ctx,
interpolate_daily = true,
scaling_function = clean_sic, ## convert to fraction
land_fraction = land_fraction,
date0 = date0,
mono = mono_surface,
)
update_midmonth_data!(date0, SIC_info)
SIC_init = interpolate_midmonth_to_daily(date0, SIC_info)
ice_fraction = get_ice_fraction.(SIC_init, mono_surface)
ice_sim = ice_init(
FT;
tspan = tspan,
dt = Δt_cpl,
space = boundary_space,
saveat = saveat,
area_fraction = ice_fraction,
thermo_params = thermo_params,
)

## CO2 concentration
CO2_info = bcfile_info_init(
FT,
REGRID_DIR,
co2_data,
"co2",
boundary_space,
comms_ctx,
interpolate_daily = true,
land_fraction = ones(boundary_space),
date0 = date0,
mono = mono_surface,
)

update_midmonth_data!(date0, CO2_info)
CO2_init = interpolate_midmonth_to_daily(date0, CO2_info)
update_field!(atmos_sim, Val(:co2_gm), CO2_init)

mode_specifics = (; name = mode_name, SST_info = SST_info, SIC_info = SIC_info, CO2_info = CO2_info)

elseif mode_name in ("slabplanet", "slabplanet_aqua", "slabplanet_terra")

land_fraction = mode_name == "slabplanet_aqua" ? land_fraction .* 0 : land_fraction
land_fraction = mode_name == "slabplanet_terra" ? land_fraction .* 0 .+ 1 : land_fraction

## land
land_sim = bucket_init(
FT,
tspan,
config_dict["land_domain_type"],
config_dict["land_albedo_type"],
config_dict["land_temperature_anomaly"],
comms_ctx,
REGRID_DIR;
dt = Δt_cpl,
space = boundary_space,
saveat = saveat,
area_fraction = land_fraction,
date_ref = date0,
t_start = t_start,
)

## ocean
ocean_sim = ocean_init(
FT;
tspan = tspan,
dt = Δt_cpl,
space = boundary_space,
saveat = saveat,
area_fraction = (FT(1) .- land_fraction), ## NB: this ocean fraction includes areas covered by sea ice (unlike the one contained in the cs)
thermo_params = thermo_params,
evolving = evolving_ocean,
)

## sea ice (here set to zero area coverage)
ice_sim = SurfaceStub((;
T_sfc = ClimaCore.Fields.ones(boundary_space),
ρ_sfc = ClimaCore.Fields.zeros(boundary_space),
z0m = FT(0),
z0b = FT(0),
beta = FT(1),
α = FT(1),
area_fraction = ClimaCore.Fields.zeros(boundary_space),
phase = TD.Ice(),
thermo_params = thermo_params,
))

mode_specifics = (; name = mode_name, SST_info = nothing, SIC_info = nothing)
end

#=
## Coupler Initialization
The coupler needs to contain exchange information, manage the calendar and be able to access all component models. It can also optionally
save online diagnostics. These are all initialized here and saved in a global `CouplerSimulation` struct, `cs`.
=#

## coupler exchange fields
coupler_field_names = (
:T_S,
:z0m_S,
:z0b_S,
:ρ_sfc,
:q_sfc,
:albedo,
:beta,
:F_turb_energy,
:F_turb_moisture,
:F_turb_ρτxz,
:F_turb_ρτyz,
:F_radiative,
:P_liq,
:P_snow,
:F_radiative_TOA,
:P_net,
)
coupler_fields =
NamedTuple{coupler_field_names}(ntuple(i -> ClimaCore.Fields.zeros(boundary_space), length(coupler_field_names)))

## model simulations
model_sims = (atmos_sim = atmos_sim, ice_sim = ice_sim, land_sim = land_sim, ocean_sim = ocean_sim);

## dates
dates = (; date = [date], date0 = [date0], date1 = [Dates.firstdayofmonth(date0)], new_month = [false])

#=
### Online Diagnostics
User can write custom diagnostics in the `user_diagnostics.jl`.
=#
monthly_3d_diags = init_diagnostics(
(:T, :u, :q_tot, :q_liq_ice),
atmos_sim.domain.center_space;
save = Monthly(),
operations = (; accumulate = TimeMean([Int(0)])),
output_dir = COUPLER_OUTPUT_DIR,
name_tag = "monthly_mean_3d_",
)

monthly_2d_diags = init_diagnostics(
(:precipitation_rate, :toa_fluxes, :T_sfc, :tubulent_energy_fluxes),
boundary_space;
save = Monthly(),
operations = (; accumulate = TimeMean([Int(0)])),
output_dir = COUPLER_OUTPUT_DIR,
name_tag = "monthly_mean_2d_",
)

diagnostics = (monthly_3d_diags, monthly_2d_diags)

#=
## Initialize Conservation Checks
=#
## init conservation info collector
conservation_checks = nothing
if energy_check
@assert(
mode_name[1:10] == "slabplanet" && !CA.is_distributed(ClimaComms.context(boundary_space)),
"Only non-distributed slabplanet allowable for energy_check"
)
conservation_checks = (; energy = EnergyConservationCheck(model_sims), water = WaterConservationCheck(model_sims))
end

dir_paths = (; output = COUPLER_OUTPUT_DIR, artifacts = COUPLER_ARTIFACTS_DIR)
checkpoint_cb =
HourlyCallback(dt = FT(480), func = checkpoint_sims, ref_date = [dates.date[1]], active = hourly_checkpoint) # 20 days
update_firstdayofmonth!_cb =
MonthlyCallback(dt = FT(1), func = update_firstdayofmonth!, ref_date = [dates.date1[1]], active = true) # for BCReader
callbacks = (; checkpoint = checkpoint_cb, update_firstdayofmonth! = update_firstdayofmonth!_cb)
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
surface_thermo_state_type: "GCMSurfaceThermoState"
topo_smoothing: false
warn_allocations_diagnostics: false
hyperdiff: "ClimaHyperdiffusion"
dt: "150secs"
output_dir: "experiments/amip_coupled/truth_simulation"
prognostic_tke: false
override_τ_precip: true
use_newton_rtol: false
netcdf_output_at_levels: false
device: "auto"
t_end: "150secs"
dz_top: 3000.0
y_elem: 6
z_stretch: false
bubble: true
ode_algo: "ARS343"
max_newton_iters_ode: 1
start_date: "19790101"
check_precipitation: false
forcing: ~
edmfx_nh_pressure: false
scalar_hyperdiffusion_coefficient: 1.5
prognostic_surface: "false"
test_dycore_consistency: false
moist: "equil"
perf_mode: "PerfStandard"
edmf_coriolis: ~
rad: "gray"
rayleigh_sponge: true
initial_condition: "DecayingProfile"
cloud_model: "quadrature"
krylov_rtol: 0.1
divergence_damping_factor: 1.0
edmfx_entr_model: ~
eisenstat_walker_forcing_alpha: 2.0
dt_cloud_fraction: "3hours"
smoothing_order: 3
idealized_h2o: false
surface_setup: "PrescribedSurface"
perturb_initstate: true
jvp_step_adjustment: 1.0
discrete_hydrostatic_balance: false
netcdf_interpolate_z_over_msl: false
log_progress: true
dz_bottom: 30.0
h_elem: 16
dt_save_state_to_disk: "Inf"
netcdf_interpolation_num_points: ~
advection_test: false
z_max: 30000.0
apply_limiter: false
topography: "NoWarp"
reference_job_id: ~
precip_model: "0M"
perf_summary: false
vorticity_hyperdiffusion_coefficient: 1.5
viscous_sponge: false
surface_temperature: "ZonallySymmetric"
diagnostics:
- short_name:
- "pfull"
- "wa"
- "va"
- "rv"
period: "150secs"
reduction: "average"
job_id: "target_amip_n1_shortrun"
orographic_gravity_wave: ~
dt_rad: "1hours"
approximate_linear_solve_iters: 1
edmfx_upwinding: "none"
tracer_upwinding: "none"
nh_poly: 3
edmfx_sgs_diffusive_flux: false
y_max: 300000.0
non_orographic_gravity_wave: false
use_reference_state: true
config: "sphere"
energy_upwinding: "none"
FLOAT_TYPE: "Float64"
updraft_number: 1
split_ode: true
regression_test: false
check_conservation: false
ls_adv: ~
output_default_diagnostics: true
implicit_diffusion: false
x_max: 300000.0
edmfx_sgs_mass_flux: false
z_elem: 50
newton_rtol: 1.0e-5
fps: 5
edmfx_sgsflux_upwinding: "none"
turbconv: ~
x_elem: 6
idealized_clouds: false
vert_diff: "true"
use_krylov_method: false
subsidence: ~
use_dynamic_krylov_rtol: false
idealized_insolation: true
toml:
- "/Users/akshaysridhar/.julia/packages/ClimaCoupler/utcpx/toml/default_coarse.toml"
edmfx_detr_model: ~
dt_save_to_sol: "1days"
Loading

0 comments on commit 73e0fb2

Please sign in to comment.