Skip to content

Commit eb40f6d

Browse files
committed
add perturbed RH
1 parent 0a873e3 commit eb40f6d

File tree

6 files changed

+683
-252
lines changed

6 files changed

+683
-252
lines changed

.buildkite/longruns_gpu/pipeline.yml

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,14 @@ steps:
3939

4040
- group: "Global Land Models"
4141
if: build.env("LONGER_RUN") == null
42+
if: build.env("PERTURBED_RUN") == null
4243
steps:
4344

4445
- label: ":snow_capped_mountain: Snowy Land"
4546
command:
4647
- julia --color=yes --project=.buildkite experiments/long_runs/snowy_land.jl
4748
artifact_paths:
4849
- "snowy_land_longrun_gpu/*png"
49-
- "snowy_land_longrun_gpu/*pdf"
50-
agents:
51-
slurm_gpus: 1
52-
slurm_time: 3:00:00
53-
env:
54-
CLIMACOMMS_DEVICE: "CUDA"
55-
56-
- label: ":snow_capped_mountain: Low-Res Snowy Land"
57-
command:
58-
- julia --color=yes --project=.buildkite experiments/long_runs/low_res_snowy_land.jl
59-
artifact_paths:
60-
- "lowres_snowy_land_longrun_gpu/*png"
61-
- "lowres_snowy_land_longrun_gpu/*pdf"
6250
agents:
6351
slurm_gpus: 1
6452
slurm_time: 3:00:00
@@ -68,7 +56,7 @@ steps:
6856
- label: ":sunglasses: California regional simulation"
6957
command:
7058
- julia --color=yes --project=.buildkite experiments/long_runs/land_region.jl
71-
artifact_paths: "california_longrun_gpu/*pdf"
59+
artifact_paths: "california_longrun_gpu/*png"
7260
agents:
7361
slurm_gpus: 1
7462
slurm_time: 01:00:00
@@ -78,7 +66,7 @@ steps:
7866
- label: "Soil"
7967
command:
8068
- julia --color=yes --project=.buildkite experiments/long_runs/soil.jl
81-
artifact_paths: "soil_longrun_gpu/*pdf"
69+
artifact_paths: "soil_longrun_gpu/*png"
8270
agents:
8371
slurm_gpus: 1
8472
slurm_time: 3:00:00
@@ -88,13 +76,41 @@ steps:
8876
- label: "Global bucket simulation"
8977
command:
9078
- julia --color=yes --project=.buildkite experiments/long_runs/bucket.jl
91-
artifact_paths: "bucket_longrun_gpu/*pdf"
79+
artifact_paths: "bucket_longrun_gpu/*png"
9280
agents:
9381
slurm_gpus: 1
9482
slurm_time: 00:30:00
9583
env:
9684
CLIMACOMMS_DEVICE: "CUDA"
9785

86+
- group: "Perturbed Low-res Global Land Models"
87+
if: build.env("PERTURBED_RUN") != null
88+
steps:
89+
90+
- label: ":snow_capped_mountain: Low-Res Snowy Land Perturbed Temperature"
91+
command:
92+
- julia --color=yes --project=.buildkite experiments/long_runs/low_res_snowy_land_temp.jl
93+
artifact_paths:
94+
- "lowres_snowy_land_longrun_temp_gpu/*png"
95+
agents:
96+
slurm_gpus: 1
97+
slurm_time: 3:00:00
98+
env:
99+
CLIMACOMMS_DEVICE: "CUDA"
100+
PERTURBED_RUN: ""
101+
102+
- label: ":snow_capped_mountain: Low-Res Snowy Land Perturbed RH"
103+
command:
104+
- julia --color=yes --project=.buildkite experiments/long_runs/low_res_snowy_land_rh.jl
105+
artifact_paths:
106+
- "lowres_snowy_land_longrun_rh_gpu/*png"
107+
agents:
108+
slurm_gpus: 1
109+
slurm_time: 3:00:00
110+
env:
111+
CLIMACOMMS_DEVICE: "CUDA"
112+
PERTURBED_RUN: ""
113+
98114
- group: "Longer runs of Global Land Models"
99115
if: build.env("LONGER_RUN") != null
100116
steps:
@@ -103,7 +119,7 @@ steps:
103119
- julia --color=yes --project=.buildkite experiments/long_runs/snowy_land.jl
104120
artifact_paths:
105121
- "snowy_land_longrun_gpu/*png"
106-
- "snowy_land_longrun_gpu/*pdf"
122+
- "snowy_land_longrun_gpu/*png"
107123
agents:
108124
slurm_gpus: 1
109125
slurm_time: 15:00:00
@@ -114,7 +130,7 @@ steps:
114130
- label: "Soil, 20 years"
115131
command:
116132
- julia --color=yes --project=.buildkite experiments/long_runs/soil.jl
117-
artifact_paths: "soil_longrun_gpu/*pdf"
133+
artifact_paths: "soil_longrun_gpu/*png"
118134
agents:
119135
slurm_gpus: 1
120136
slurm_time: 15:00:00

experiments/long_runs/low_res_snowy_land.jl renamed to experiments/long_runs/low_res_snowy_land_rh.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ context = ClimaComms.context()
4545
ClimaComms.init(context)
4646
device = ClimaComms.device()
4747
device_suffix = device isa ClimaComms.CPUSingleThreaded ? "cpu" : "gpu"
48-
root_path = "lowres_snowy_land_longrun_$(device_suffix)"
48+
root_path = "lowres_snowy_land_longrun_rh_$(device_suffix)"
4949
diagnostics_outdir = joinpath(root_path, "global_diagnostics")
5050
outdir =
5151
ClimaUtilities.OutputPathGenerator.generate_output_path(diagnostics_outdir)
@@ -58,12 +58,12 @@ function setup_model(FT, start_date, stop_date, Δt, domain, earth_param_set)
5858
context,
5959
lowres = true,
6060
)
61-
atmos, radiation = ClimaLand.prescribed_perturbed_forcing_era5(
61+
atmos, radiation = ClimaLand.prescribed_perturbed_rh_era5(
6262
era5_ncdata_path,
6363
surface_space,
6464
start_date,
6565
earth_param_set,
66-
5.0,
66+
-0.2,
6767
FT;
6868
max_wind_speed = 25.0,
6969
time_interpolation_method = LinearInterpolation(PeriodicCalendar()),
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# # Global run of land model at low resolution
2+
3+
# The code sets up and runs ClimaLand v1, which
4+
# includes soil, canopy, and snow, on a spherical domain,
5+
# using low resolution ERA5 data as forcing.
6+
7+
# Simulation Setup
8+
# Number of spatial elements: 30 in horizontal, 15 in vertical
9+
# Soil depth: 50 m
10+
# Simulation duration: 730 d
11+
# Timestep: 450 s
12+
# Timestepper: ARS111
13+
# Fixed number of iterations: 3
14+
# Jacobian update: every new Newton iteration
15+
# Atmos forcing update: every 3 hours
16+
17+
import ClimaComms
18+
ClimaComms.@import_required_backends
19+
using ClimaUtilities.ClimaArtifacts
20+
import ClimaUtilities.TimeManager: ITime, date
21+
22+
import ClimaDiagnostics
23+
import ClimaUtilities
24+
25+
import ClimaUtilities.TimeVaryingInputs:
26+
TimeVaryingInput, LinearInterpolation, PeriodicCalendar
27+
import ClimaUtilities.ClimaArtifacts: @clima_artifact
28+
import ClimaParams as CP
29+
using ClimaCore
30+
using ClimaLand
31+
using ClimaLand.Snow
32+
using ClimaLand.Soil
33+
using ClimaLand.Canopy
34+
import ClimaLand
35+
import ClimaLand.Parameters as LP
36+
import ClimaLand.Simulations: LandSimulation, solve!
37+
38+
using Dates
39+
40+
using CairoMakie, GeoMakie, Poppler_jll, ClimaAnalysis
41+
import ClimaLand.LandSimVis as LandSimVis
42+
43+
const FT = Float64;
44+
context = ClimaComms.context()
45+
ClimaComms.init(context)
46+
device = ClimaComms.device()
47+
device_suffix = device isa ClimaComms.CPUSingleThreaded ? "cpu" : "gpu"
48+
root_path = "lowres_snowy_land_longrun_temp_$(device_suffix)"
49+
diagnostics_outdir = joinpath(root_path, "global_diagnostics")
50+
outdir =
51+
ClimaUtilities.OutputPathGenerator.generate_output_path(diagnostics_outdir)
52+
53+
function setup_model(FT, start_date, stop_date, Δt, domain, earth_param_set)
54+
surface_domain = ClimaLand.Domains.obtain_surface_domain(domain)
55+
surface_space = domain.space.surface
56+
# Forcing data
57+
era5_ncdata_path = ClimaLand.Artifacts.era5_land_forcing_data2008_path(;
58+
context,
59+
lowres = true,
60+
)
61+
atmos, radiation = ClimaLand.prescribed_perturbed_temperature_era5(
62+
era5_ncdata_path,
63+
surface_space,
64+
start_date,
65+
earth_param_set,
66+
10.0,
67+
FT;
68+
max_wind_speed = 25.0,
69+
time_interpolation_method = LinearInterpolation(PeriodicCalendar()),
70+
)
71+
forcing = (; atmos, radiation)
72+
73+
# Read in LAI from MODIS data
74+
modis_lai_ncdata_path = ClimaLand.Artifacts.modis_lai_multiyear_paths(;
75+
context = nothing,
76+
start_date,
77+
end_date = stop_date,
78+
)
79+
LAI = ClimaLand.prescribed_lai_modis(
80+
modis_lai_ncdata_path,
81+
surface_space,
82+
start_date;
83+
time_interpolation_method = LinearInterpolation(),
84+
)
85+
86+
# Overwrite some defaults for the canopy model
87+
# Energy model
88+
ac_canopy = FT(2.5e3)
89+
energy = Canopy.BigLeafEnergyModel{FT}(; ac_canopy)
90+
91+
# Plant hydraulics
92+
a = FT(0.2 * 0.0098) # 1/m
93+
retention_model = Canopy.PlantHydraulics.LinearRetentionCurve{FT}(a)
94+
hydraulics =
95+
Canopy.PlantHydraulicsModel{FT}(surface_domain, LAI; retention_model)
96+
97+
# Roughness lengths
98+
h_canopy = hydraulics.compartment_surfaces[end]
99+
z0_m = FT(0.13) * h_canopy
100+
z0_b = FT(0.1) * z0_m
101+
102+
ground = ClimaLand.PrognosticGroundConditions{FT}()
103+
canopy_forcing = (; atmos, radiation, ground)
104+
105+
canopy = ClimaLand.Canopy.CanopyModel{FT}(
106+
surface_domain,
107+
canopy_forcing,
108+
LAI,
109+
earth_param_set;
110+
prognostic_land_components = (:canopy, :snow, :soil, :soilco2),
111+
energy,
112+
hydraulics,
113+
z_0m = z0_m,
114+
z_0b = z0_b,
115+
)
116+
117+
# Snow model setup
118+
# Set β = 0 in order to regain model without density dependence
119+
α_snow = Snow.ZenithAngleAlbedoModel(
120+
FT(0.64),
121+
FT(0.06),
122+
FT(2);
123+
β = FT(0.4),
124+
x0 = FT(0.2),
125+
)
126+
horz_degree_res =
127+
sum(ClimaLand.Domains.average_horizontal_resolution_degrees(domain)) / 2 # mean of resolution in latitude and longitude, in degrees
128+
scf = Snow.WuWuSnowCoverFractionModel(
129+
FT(0.08),
130+
FT(1.77),
131+
FT(1.0),
132+
horz_degree_res,
133+
)
134+
snow = Snow.SnowModel(
135+
FT,
136+
surface_domain,
137+
forcing,
138+
earth_param_set,
139+
Δt;
140+
prognostic_land_components = (:canopy, :snow, :soil, :soilco2),
141+
α_snow,
142+
scf,
143+
)
144+
145+
# Construct the land model with all default components except for snow
146+
land =
147+
LandModel{FT}(forcing, LAI, earth_param_set, domain, Δt; snow, canopy)
148+
return land
149+
end
150+
# Note that since the Northern hemisphere's winter season is defined as DJF,
151+
# we simulate from and until the beginning of
152+
# March so that a full season is included in seasonal metrics.
153+
start_date = DateTime("2008-03-01")
154+
stop_date = DateTime("2010-03-02")
155+
Δt = 450.0
156+
nelements = (30, 15)
157+
domain = ClimaLand.Domains.global_domain(
158+
FT;
159+
context,
160+
nelements,
161+
mask_threshold = FT(0.99),
162+
)
163+
params = LP.LandParameters(FT)
164+
model = setup_model(FT, start_date, stop_date, Δt, domain, params)
165+
user_callbacks = (
166+
ClimaLand.NaNCheckCallback(
167+
Dates.Month(6),
168+
start_date,
169+
ITime(Δt, epoch = start_date),
170+
mask = ClimaLand.Domains.landsea_mask(ClimaLand.get_domain(model)),
171+
),
172+
ClimaLand.ReportCallback(10000),
173+
)
174+
simulation =
175+
LandSimulation(FT, start_date, stop_date, Δt, model; user_callbacks, outdir)
176+
@info "Run: Global Soil-Canopy-Snow Model"
177+
@info "Resolution: $nelements"
178+
@info "Timestep: $Δt s"
179+
@info "Start Date: $start_date"
180+
@info "Stop Date: $stop_date"
181+
ClimaLand.Simulations.solve!(simulation)
182+
183+
LandSimVis.make_annual_timeseries(simulation; savedir = root_path)
184+
LandSimVis.make_heatmaps(simulation; savedir = root_path, date = stop_date)
185+
LandSimVis.make_leaderboard_plots(simulation; savedir = root_path)

src/ClimaLand.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ include("shared_utilities/checkpoints.jl")
2424
include("shared_utilities/utils.jl")
2525
include("shared_utilities/models.jl")
2626
include("shared_utilities/drivers.jl")
27+
include("shared_utilities/perturbed_drivers.jl")
2728
include("shared_utilities/boundary_conditions.jl")
2829
include("shared_utilities/sources.jl")
2930
include("shared_utilities/implicit_timestepping.jl")

0 commit comments

Comments
 (0)