Skip to content

Commit 83e97cc

Browse files
committed
documentation for fluxnet sites
1 parent 749503a commit 83e97cc

File tree

8 files changed

+252
-92
lines changed

8 files changed

+252
-92
lines changed

docs/list_tutorials.jl

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
tutorials = [
22
"Running Fluxnet simulations" => [
3-
"Canopy and soil" => "integrated/soil_canopy_tutorial.jl",
4-
"Canopy, soil, and snow" => "integrated/snowy_land_tutorial.jl",
3+
"Canopy and soil" => "integrated/soil_canopy_fluxnet_tutorial.jl",
4+
"Canopy, soil, and snow" => "integrated/snowy_land_fluxnet_tutorial.jl",
55
"Data processing" =>
66
"Fluxnet forcing and comparison data" => "integrated/fluxnet_data.jl",
7+
"Visualization" =>
8+
"Fluxnet simulation visualization" => "integrated/fluxnet_vis.jl",
79
],
810
"Running global simulations" => [
911
"Bucket land model" => [
1012
"standalone/Bucket/bucket_tutorial.jl",
1113
"standalone/Bucket/coupled_bucket.jl",
1214
],
13-
"Canopy, soil, and snow" => "integrated/snowy_land_global_tutorial.jl",
14-
"Forcing data" => "standalone/shared_utilities/era5_modis_tutorial.jl",
15-
"Handling interactions between model components" => [
16-
"Adjusting boundary conditions for the soil" => "integrated/handling_soil_fluxes.jl",
17-
"Adjusting boundary conditions for the snow" => "integrated/handling_snow_fluxes.jl",
18-
],
1915
],
2016
"Running standalone component simulations" => [
2117
"Soil" => [
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# # Fluxnet simulations with the full land model: snow, soil, canopy
2+
3+
# In the
4+
# [`previous tutorial`](@ref https://clima.github.io/ClimaLand.jl/dev/generated/soil_canopy_tutorial/),
5+
# we demonstrated how to run the an integrated model with a soil and
6+
# canopy component at the US-MOz fluxnet site.
7+
# Here we add in a snow component, and run the site at the Niwot Ridge site instead.
8+
# Again, the focus of this tutorial is to learn the steps towards setting up and
9+
# running an integrated simulation, and less on the parameterization choices.
10+
# As such, the default parameters are implicitly set. To experiment with
11+
# modularity in the parameters and parameterizations, please see tutorial X.
12+
13+
# # Preliminary Setup
14+
using Dates
15+
import ClimaParams as CP
16+
using ClimaDiagnostics
17+
using ClimaLand
18+
using ClimaLand.Domains: Column
19+
using ClimaLand.Simulations
20+
import ClimaLand.Parameters as LP
21+
using DelimitedFiles
22+
FluxnetSimulationsExt =
23+
Base.get_extension(ClimaLand, :FluxnetSimulationsExt).FluxnetSimulationsExt;
24+
using CairoMakie, ClimaAnalysis, GeoMakie, Poppler_jll, Printf, StatsBase
25+
LandSimulationVisualizationExt =
26+
Base.get_extension(
27+
ClimaLand,
28+
:LandSimulationVisualizationExt,
29+
).LandSimulationVisualizationExt;
30+
31+
# Define the floating point precision desired (64 or 32 bit), and get the
32+
# parameter set holding constants used across CliMA Models.
33+
34+
const FT = Float32;
35+
earth_param_set = LP.LandParameters(FT);
36+
37+
# We will use prescribed atmospheric and radiative drivers from the
38+
# US-NR1 tower, which we read in here. We also
39+
# read in the MODIS LAI and let that vary in time in a prescribed manner.
40+
site_ID = "US-NR1"
41+
time_offset = 7 # Timezone (offset from UTC in hrs)
42+
lat = FT(40.0329) # degree
43+
long = FT(-105.5464) # degree
44+
atmos_h = FT(21.5); # Height of the sensor at the site (m)
45+
(start_date, stop_date) =
46+
FluxnetSimulationsExt.get_data_dates(site_ID, time_offset) # in UTC
47+
Δt = 450.0; # seconds
48+
49+
# Forcing data for the site - this uses our interface for working with Fluxnet data
50+
forcing = FluxnetSimulationsExt.prescribed_forcing_fluxnet(
51+
site_ID,
52+
lat,
53+
long,
54+
time_offset,
55+
atmos_h,
56+
start_date,
57+
earth_param_set,
58+
FT,
59+
);
60+
# LAI for the site - this uses our interface for working with MODIS data.
61+
(LAI, maxLAI) =
62+
FluxnetSimulationsExt.prescribed_LAI_fluxnet(site_ID, start_date);# eventually just get LAI
63+
64+
# Setup the domain for the model:
65+
zmin = FT(-5) # in m
66+
zmax = FT(0) # in m
67+
domain = Column(; zlim = (zmin, zmax), nelements = 10, longlat = (long, lat))
68+
69+
# # Setup the integrated model
70+
71+
# We want to simulate the canopy-soil-snow system together, so the model type
72+
# [`LandModel`](https://clima.github.io/ClimaLand.jl/dev/APIs/ClimaLand/#LSM-Model-Types-and-methods)
73+
# is chosen. Here we use the highest level model constructor, which uses default parameters,
74+
# and parameterizations, for the soil, snow, and canopy models.
75+
# A different tutorial will show you how to change these parameters and parameterizations.
76+
land_model = LandModel{FT}(forcing, LAI, earth_param_set, domain, Δt);
77+
set_ic! = FluxnetSimulationsExt.make_set_fluxnet_initial_conditions(
78+
site_ID,
79+
start_date,
80+
time_offset,
81+
land_model,
82+
);
83+
output_vars = ["swu", "lwu", "shf", "lhf", "swe", "swc", "si"]
84+
diagnostics = ClimaLand.default_diagnostics(
85+
land_model,
86+
start_date;
87+
output_writer = ClimaDiagnostics.Writers.DictWriter(),
88+
output_vars,
89+
average_period = :hourly,
90+
);
91+
92+
simulation = Simulations.LandSimulation(
93+
FT,
94+
start_date,
95+
stop_date,
96+
Δt, # seconds
97+
land_model;
98+
set_ic!,
99+
user_callbacks = (),
100+
diagnostics,
101+
);
102+
@time solve!(simulation);
103+
104+
# # Plotting results
105+
LandSimulationVisualizationExt.make_diurnal_timeseries(
106+
simulation;
107+
short_names = ["shf", "lhf", "swu", "lwu"],
108+
spinup_date = start_date + Day(20),
109+
);
110+
# ![](diurnal_timeseries.png)
111+
LandSimulationVisualizationExt.make_timeseries(
112+
simulation;
113+
short_names = ["swc", "si", "swe"],
114+
spinup_date = start_date + Day(20),
115+
);

docs/src/tutorials/integrated/soil_canopy_tutorial.jl renamed to docs/src/tutorials/integrated/soil_canopy_fluxnet_tutorial.jl

Lines changed: 20 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# [`previous tutorial`](@ref https://clima.github.io/ClimaLand.jl/dev/generated/soil_plant_hydrology_tutorial/),
55
# we demonstrated how to run the canopy model in
66
# standalone mode using prescribed values for the inputs of soil moisture
7+
# and ground temperature
78
# into the canopy hydraulics model. However, ClimaLand can also
89
# integrate the canopy model with a soil model and timestep the two
910
# components together to simulate an interacting canopy-soil system. This tutorial
@@ -13,26 +14,16 @@
1314
# oak-hickory forest in Ozark, Missouri, USA.
1415
# The focus of this tutorial is to learn the steps towards setting up and
1516
# running an integrated simulation, and less on the parameterization choices.
16-
# As such, a number of default parameters are implicitly set.
17+
# As such, the default parameters are implicitly set. To experiment with
18+
# modularity in the parameters and parameterizations, please see tutorial X.
1719

1820
# # Preliminary Setup
19-
import SciMLBase
20-
using Plots
21-
using Statistics
2221
using Dates
23-
using Insolation
24-
using ClimaCore
2522
import ClimaParams as CP
26-
import ClimaTimeSteppers as CTS
2723
using ClimaDiagnostics
2824
using ClimaLand
29-
using ClimaLand.Domains: Column, obtain_surface_domain
30-
using ClimaLand.Soil
31-
using ClimaLand.Soil.Biogeochemistry
32-
using ClimaLand.Canopy
25+
using ClimaLand.Domains: Column
3326
using ClimaLand.Simulations
34-
using ClimaLand.Canopy.PlantHydraulics
35-
import ClimaLand
3627
import ClimaLand.Parameters as LP
3728
using DelimitedFiles
3829
FluxnetSimulationsExt =
@@ -44,13 +35,11 @@ LandSimulationVisualizationExt =
4435
:LandSimulationVisualizationExt,
4536
).LandSimulationVisualizationExt;
4637

47-
# Define the floating point precision desired (64 or 32 bit), get the
48-
# parameter set holding constants used across CliMA Models, and define
49-
# the components of the integrated model.
38+
# Define the floating point precision desired (64 or 32 bit), and get the
39+
# parameter set holding constants used across CliMA Models.
5040

5141
const FT = Float32;
5242
earth_param_set = LP.LandParameters(FT);
53-
prognostic_land_components = (:canopy, :soil, :soilco2);
5443

5544
# We will use prescribed atmospheric and radiative drivers from the
5645
# US-MOz tower, which we read in here. We also
@@ -61,12 +50,11 @@ lat = FT(38.7441) # degree
6150
long = FT(-92.2000) # degree
6251
atmos_h = FT(32); # Height of the sensor at the site (m)
6352

64-
start_date = DateTime(2010) + Hour(time_offset) + Day(150) # start mid year - in UTC
65-
stop_date = DateTime(2010) + Hour(time_offset) + Day(250) # end 100 days later - in UTC
66-
Δt = Float64(450); # seconds
67-
53+
start_date = DateTime("2010-05-01", "yyyy-mm-dd") # in UTC
54+
stop_date = DateTime("2010-09-01", "yyyy-mm-dd") # in UTC
55+
Δt = 450.0; # seconds
6856
# Forcing data for the site - this uses our interface for working with Fluxnet data
69-
(; atmos, radiation) = FluxnetSimulationsExt.prescribed_forcing_fluxnet(
57+
forcing = FluxnetSimulationsExt.prescribed_forcing_fluxnet(
7058
site_ID,
7159
lat,
7260
long,
@@ -80,72 +68,25 @@ stop_date = DateTime(2010) + Hour(time_offset) + Day(250) # end 100 days later -
8068
(LAI, maxLAI) =
8169
FluxnetSimulationsExt.prescribed_LAI_fluxnet(site_ID, start_date);# eventually just get LAI
8270

83-
# Setup the domain(s) for the model:
71+
# Setup the domain for the model:
8472
zmin = FT(-2) # in m
8573
zmax = FT(0) # in m
8674
domain = Column(; zlim = (zmin, zmax), nelements = 10, longlat = (long, lat))
87-
soil_domain = domain # vertically resolved
88-
canopy_domain = ClimaLand.Domains.obtain_surface_domain(domain); # only the surface
8975

90-
# # Setup the Coupled Canopy and Soil Physics Model
76+
# # Setup the integrated model
9177

9278
# We want to simulate the canopy-soil system together, so the model type
9379
# [`SoilCanopyModel`](https://clima.github.io/ClimaLand.jl/dev/APIs/ClimaLand/#LSM-Model-Types-and-methods)
94-
# is chosen.
95-
96-
# For our soil model, we use the
97-
# [`EnergyHydrology`](https://clima.github.io/ClimaLand.jl/dev/APIs/Soil/#Soil-Models-2)
98-
# model. Here we use default parameter choices corresponding to the values taken from global
99-
# maps at the latitude
100-
# and longitude of the site we are modeling. See the
101-
# [tutorial](https://clima.github.io/ClimaLand.jl/dev/generated/Soil/soil_energy_hydrology/)
102-
# on the model for a more detailed explanation of the soil model and how to vary parameter values
103-
# and parameterizations.
104-
soil_forcing = (; atmos, radiation)
105-
soil = Soil.EnergyHydrology{FT}(
106-
soil_domain,
107-
soil_forcing,
108-
earth_param_set;
109-
prognostic_land_components,
110-
additional_sources = (ClimaLand.RootExtraction{FT}(),), # in addition to phase changes
111-
runoff = ClimaLand.Soil.Runoff.SurfaceRunoff(),
112-
);
113-
# We next make the heterotrophic respiration model; again we use
114-
# default parameter values, see the
115-
# [documentation](https://clima.github.io/ClimaLand.jl/previews/PR214/dynamicdocs/pages/soil_biogeochemistry/microbial_respiration/)
116-
# for additional information.
117-
soil_organic_carbon =
118-
ClimaLand.PrescribedSoilOrganicCarbon{FT}(TimeVaryingInput((t) -> 5))# kg C/m^3; eventually this will be read from a file.
119-
co2_prognostic_soil = Soil.Biogeochemistry.PrognosticMet(soil.parameters)
120-
soil_co2_forcing = Soil.Biogeochemistry.SoilDrivers(
121-
co2_prognostic_soil,
122-
soil_organic_carbon,
123-
atmos,
124-
)
125-
soilco2 = Soil.Biogeochemistry.SoilCO2Model{FT}(soil_domain, soil_co2_forcing);
126-
127-
# Next we set up the [`CanopyModel`](https://clima.github.io/ClimaLand.jl/dev/APIs/canopy/Canopy/#Canopy-Model-Structs).
128-
# For more details on the specifics of this model and it's parameter options,
129-
# see the previous tutorial.
130-
canopy_forcing =
131-
(; atmos, radiation, ground = ClimaLand.PrognosticSoilConditions{FT}())
132-
canopy = Canopy.CanopyModel{FT}(
133-
canopy_domain,
134-
canopy_forcing,
135-
LAI,
136-
earth_param_set;
137-
prognostic_land_components,
138-
);
139-
140-
# # Setup and solve the simulation, including a function to set initial conditions, output diagnostics
141-
142-
land_model = SoilCanopyModel{FT}(soilco2, soil, canopy);
80+
# is chosen. Here we use the highest level model constructor, which uses default parameters,
81+
# and parameterizations, for the soil and canopy models.
82+
# A different tutorial will show you how to change these parameters and parameterizations.
83+
land_model = SoilCanopyModel{FT}(forcing, LAI, earth_param_set, domain);
14384
set_ic! = FluxnetSimulationsExt.make_set_fluxnet_initial_conditions(
14485
site_ID,
14586
start_date,
14687
time_offset,
14788
land_model,
148-
)
89+
);
14990
output_vars = ["gpp", "swu", "lwu", "shf", "lhf"]
15091
diagnostics = ClimaLand.default_diagnostics(
15192
land_model,
@@ -159,18 +100,18 @@ simulation = Simulations.LandSimulation(
159100
FT,
160101
start_date,
161102
stop_date,
162-
Δt,
103+
Δt, # seconds
163104
land_model;
164105
set_ic!,
165106
user_callbacks = (),
166107
diagnostics,
167-
)
108+
);
168109
solve!(simulation);
169110

170111
# # Plotting results
171112
LandSimulationVisualizationExt.make_diurnal_timeseries(
172113
simulation;
173114
short_names = ["gpp", "shf", "lhf", "swu", "lwu"],
174115
spinup_date = start_date + Day(20),
175-
)
116+
);
176117
# ![](diurnal_timeseries.png)

ext/LandSimulationVisualizationExt.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module LandSimulationVisualizationExt
22
import ClimaDiagnostics
3+
import ClimaUtilities.TimeManager: ITime
34
import ClimaAnalysis
45
import ClimaAnalysis.Visualize as viz
56
using CairoMakie

0 commit comments

Comments
 (0)