Skip to content

Commit 85c0e16

Browse files
Updated primer
1 parent b02a5d1 commit 85c0e16

File tree

1 file changed

+48
-42
lines changed

1 file changed

+48
-42
lines changed

docs/src/primer.md

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
11
# Primer
22

3-
Streamfall is a stream network modelling framework with integrated systems analysis and modelling in mind. The aim is to simplify the construction of basin-scale hydrology models, itself a constituent of a larger system of systems. The overarching concepts are explained here.
3+
Streamfall is a stream network modelling framework with integrated systems analysis and
4+
modelling in mind. The aim is to simplify the construction of basin-scale hydrology models,
5+
itself a constituent of a larger system of systems. The overarching concepts are explained
6+
here.
7+
8+
The motivation for Streamfall is to enable flexible modelling of a hydrological system.\
9+
This includes:
10+
11+
- Representation of catchments with heterogenous combinations of rainfall-runoff models \
12+
(each sub-catchment may be represented by a different hydrological model)
13+
- Support interaction with other models which may represent groundwater interactions or \
14+
anthropogenic activity (e.g., water extractions)
15+
- High performance relative to available implementations in R and Python
416

517
Primary components of the Streamfall framework include:
618

7-
1. The graph network defining the stream and the model associated with each node in the network
8-
2. Data for the basin, including climate data and hydrologic interactions driven by other systems
19+
1. The graph representing a network of gauges and the associated model
20+
2. Data for the basin, including climate data and hydrologic interactions \
21+
driven by other systems
922
3. The functions which run the network as a whole and individual nodes
1023

1124
## Defining a network
@@ -22,12 +35,15 @@ The spec takes the following form:
2235
# The node type which defines which model is used for this node
2336
# In this case, it is the IHACRES with the bilinear formulation of the CMD module
2437
node_type: IHACRESBilinearNode
38+
area: 130.0 # subcatchment area in km^2 (from BoM)
2539

2640
# This spec defines a single node system
2741
# so it has no nodes upstream (inlets) or downstream (outlets)
2842
inlets:
2943
outlets:
30-
area: 130.0 # subcatchment area in km^2 (from BoM)
44+
45+
# Initial CMD state, CMD > 0 means there is a deficit
46+
initial_storage: 0.0
3147

3248
# Model parameters (in this case, for IHACRES)
3349
parameters:
@@ -39,17 +55,13 @@ The spec takes the following form:
3955
b: 0.1 # slowflow scaling factor
4056
storage_coef: 2.9 # groundwater interaction factor
4157
alpha: 0.95 # effective rainfall scaling factor
42-
initial_storage: 0.0 # initial CMD value, CMD > 0 means there is a deficit
4358
```
4459
45-
The spec is then loaded in Julia and passed into `create_network()`
60+
The spec is then loaded with `load_network()`
4661

4762
```julia
48-
# Load file
49-
network = YAML.load_file("network.yml")
50-
51-
# Create network from spec, with a human-readable name.
52-
sn = create_network("Gingera Catchment", network)
63+
# Load network from a spec file, with a human-readable name.
64+
sn = load_network("Gingera Catchment", "network.yml")
5365
```
5466

5567
Printing the network displays a summary of the nodes:
@@ -59,10 +71,9 @@ julia> sn
5971
6072
Network Name: Gingera Catchment
6173
Represented Area: 130.0
62-
-----------------
63-
64-
Node 1 :
6574
75+
Node 1
76+
--------
6677
Name: 410730 [BilinearNode]
6778
Area: 130.0
6879
┌──────────────┬───────┬─────────────┬─────────────┐
@@ -124,7 +135,6 @@ Data that may be optionally provided include:
124135
- `extractions` : additional extractions from the stream
125136
- `exchange` : additional forcing for groundwater interactions.
126137

127-
128138
These may be provided as a Dictionary of arrays with the node name as the key.
129139

130140
More details may be found in the [Input data format](@ref) page.
@@ -148,10 +158,11 @@ Date, 406214_rain, 406214_evap, 406219_rain, 406219_evap
148158

149159
```julia
150160
# Load data from CSV
151-
date_format = "YYYY-mm-dd"
152-
climate_data = CSV.File(joinpath(data_path, "climate/climate_historic.csv"),
153-
comment="#",
154-
dateformat=date_format) |> DataFrame
161+
climate_data = CSV.read(
162+
joinpath(data_path, "climate/climate_historic.csv"), DataFrame,
163+
comment="#",
164+
dateformat="YYYY-mm-dd"
165+
)
155166
156167
# Create a climate object, specifying which identifiers to use.
157168
climate = Climate(climate_data, "_rain", "_evap")
@@ -185,16 +196,13 @@ gw_flux = ... # forced groundwater interactions for each time step
185196
run_node!(node, climate; inflow=inflow, extraction=extractions, exchange=gw_flux)
186197
```
187198

188-
Another approach is to identify the outlets for a given network...
199+
Another, more direct approach, is to identify all outlets for a given network and call
200+
`run_node!()` for each outlet with relevant climate data for each timestep.
201+
All relevant upstream nodes will also be run.
189202

190203
```julia
191204
inlets, outlets = find_inlets_and_outlets(sn)
192-
```
193-
194-
... and call `run_node!` for each outlet (with relevant climate data), which will recurse through all relevant nodes upstream.
195205
196-
197-
```julia
198206
@info "Running example stream..."
199207
timesteps = sim_length(climate)
200208
for ts in (1:timesteps)
@@ -204,7 +212,8 @@ for ts in (1:timesteps)
204212
end
205213
```
206214

207-
When interactions with other socio-environmental systems are expected, it can become necessary to run each node individually as needed.
215+
When interactions with other socio-environmental systems are expected, it can become
216+
necessary to run each node individually as needed.
208217

209218
Interactions with these external systems are represented as influencing:
210219

@@ -216,24 +225,21 @@ The following pattern can be used in such a context:
216225

217226

218227
```julia
219-
# ... as an example, this is the 100th day in simulation...
220-
this_timestep = 100
221-
222-
# Inflow comes from upstream
223-
# This could be obtained by running all nodes upstream, for example
224-
# node_id, node = sn["406219"]
225-
# run_node!(sn, node_id, climate)
226-
inflow = run_node!(...)
227-
228-
# run external model that provides extraction, say 10ML
229-
# This does not have to be a model in Julia per se.
230-
extractions = some_other_model(...)
228+
@info "Running example stream..."
229+
timesteps = sim_length(climate)
230+
for ts in (1:timesteps)
231+
# Run external model that provides extraction **in the same units**
232+
# This does not have to be a model in Julia, but inter-language interoperability is
233+
# outside the scope of this example.
234+
extractions = some_water_extraction_model(...)
231235
232-
# Run a different model which provides groundwater interactions
233-
exchange = another_model(...)
236+
# Run a different model which provides groundwater interactions
237+
exchange = a_groundwater_model(...)
234238
235-
# Obtain outflow and level for this time step
236-
outflow, level = run_node!(target_node, climate, this_timestep; inflow=inflow, extraction=extractions, exchange=exchange)
239+
for outlet in outlets
240+
run_node!(outlet, climate, ts; extraction=extractions, exchange=exchange)
241+
end
242+
end
237243
```
238244

239245
Specific examples can be found in the Examples section.

0 commit comments

Comments
 (0)