-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR goal is to build a global calibration pipeline (minimal working example - MWE) to calibrate a land model globally. In this commit, we calibrate a bucket model (the framework for full land model would be the same). Two different approaches are added to this commit: the same calibration is done with just EnsembleKalmanProcesses.jl - EKP, or with ClimaCalibrate.jl (ClimaCalibrate.jl uses EKP, but has different backend, optimised for different HPCs). In our MWE, we use ERA5 latent heat - LH and sensible heat - SH flux as target observations for the calibration. We stack monthly observation at n (e.g., 50) locations on land.
- Loading branch information
1 parent
7156d7d
commit 027b32c
Showing
14 changed files
with
1,707 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# Use the .buildkite environment | ||
# bucket_turbulent_fluxes(params) returns lhf and shf as a function of 6 parameters | ||
include("calibrate_bucket_function.jl") | ||
|
||
using Random | ||
|
||
#= Target (perfect model) | ||
params = (; | ||
κ_soil = FT(1.5), | ||
ρc_soil = FT(2e6), | ||
f_bucket = FT(0.75), | ||
W_f = FT(0.2), | ||
p = FT(1), | ||
z_0m = FT(1e-2), | ||
) | ||
target = bucket_turbulent_fluxes(params)[1] | ||
=# | ||
|
||
target = full_obs_era5 | ||
|
||
# Parameters prior | ||
prior_κ_soil = EKP.constrained_gaussian("κ_soil", 2, 1, 0, Inf); | ||
prior_ρc_soil = EKP.constrained_gaussian("ρc_soil", 4e6, 2e6, 0, Inf); | ||
prior_f_bucket = EKP.constrained_gaussian("f_bucket", 0.5, 0.3, 0, 1); | ||
prior_W_f = EKP.constrained_gaussian("W_f", 0.4, 0.4, 0, Inf); | ||
prior_p = EKP.constrained_gaussian("p", 2, 1, 1, Inf); | ||
prior_z_0m = EKP.constrained_gaussian("z_0m", 0.01, 0.1, 0, Inf); | ||
prior = EKP.combine_distributions([ | ||
prior_κ_soil, | ||
prior_ρc_soil, | ||
prior_f_bucket, | ||
prior_W_f, | ||
prior_p, | ||
prior_z_0m, | ||
]); | ||
|
||
rng_seed = 2 | ||
rng = Random.MersenneTwister(rng_seed) | ||
|
||
N_ensemble = 10 | ||
N_iterations = 5 | ||
|
||
initial_ensemble = EKP.construct_initial_ensemble(rng, prior, N_ensemble); | ||
ensemble_kalman_process = EKP.EnsembleKalmanProcess( | ||
initial_ensemble, | ||
target, | ||
EKP.Inversion(); | ||
rng = rng, | ||
); | ||
|
||
for i in 1:N_iterations | ||
params_i = EKP.get_ϕ_final(prior, ensemble_kalman_process) | ||
|
||
G_ens = hcat( | ||
[ | ||
bucket_turbulent_fluxes((; | ||
κ_soil = params_i[1, j], | ||
ρc_soil = params_i[2, j], | ||
f_bucket = params_i[3, j], | ||
W_f = params_i[4, j], | ||
p = params_i[5, j], | ||
z_0m = params_i[6, j], | ||
))[2] for j in 1:N_ensemble | ||
]..., | ||
) | ||
|
||
EKP.update_ensemble!(ensemble_kalman_process, G_ens) | ||
end | ||
|
||
final_ensemble = EKP.get_ϕ_final(prior, ensemble_kalman_process) | ||
println(final_ensemble) |
Oops, something went wrong.