|
14 | 14 | - [Unique Features](#unique-features) |
15 | 15 | - [Automatic Model Coupling](#automatic-model-coupling) |
16 | 16 | - [Flexibility with Precision Control](#flexibility-with-precision-control) |
| 17 | + - [Multi-rate Execution](#multi-rate-execution) |
17 | 18 | - [Batteries included](#batteries-included) |
18 | 19 | - [Ask Questions](#ask-questions) |
19 | 20 | - [Installation](#installation) |
20 | 21 | - [Example usage](#example-usage) |
21 | 22 | - [Simple example](#simple-example) |
22 | 23 | - [Model coupling](#model-coupling) |
23 | 24 | - [Multiscale modelling](#multiscale-modelling) |
| 25 | + - [Multi-rate modelling](#multi-rate-modelling) |
24 | 26 | - [Projects that use PlantSimEngine](#projects-that-use-plantsimengine) |
25 | 27 | - [Performance](#performance) |
26 | 28 | - [Make it yours](#make-it-yours) |
|
48 | 50 |
|
49 | 51 | **Effortless Model Switching:** Researchers can switch between different component models using a simple syntax without rewriting the underlying model code. This enables rapid comparison between different hypotheses and model versions, accelerating the scientific discovery process. |
50 | 52 |
|
| 53 | +### Multi-rate Execution |
| 54 | + |
| 55 | +**Mix model cadences in one simulation:** PlantSimEngine can run models at different timesteps within the same MTG simulation. This makes it possible to combine, for example, hourly leaf processes with daily plant balances and weekly reporting models without writing custom scheduling glue. |
| 56 | + |
| 57 | +**Explicit bindings between rates:** `TimeStepModel`, `InputBindings`, `MeteoBindings`, `ScopeModel`, and `OutputRequest` let you declare how model inputs, meteorology, and exported outputs should behave when rates differ. |
| 58 | + |
51 | 59 | ## Batteries included |
52 | 60 |
|
53 | 61 | - **Automated Management**: Seamlessly handle inputs, outputs, time-steps, objects, and dependency resolution. |
54 | 62 | - **Iterative Development**: Fast and interactive prototyping of models with built-in constraints to avoid errors and sensible defaults to streamline the model writing process. |
55 | 63 | - **Control Your Degrees of Freedom**: Fix variables to constant values or force to observations, use simpler models for specific processes to reduce complexity. |
| 64 | +- **Multi-Rate Scheduling**: Combine hourly, daily, and coarser models in the same simulation, with explicit policies for input aggregation and meteorological sampling. |
56 | 65 | - **High-Speed Computations**: Achieve impressive performance with benchmarks showing operations in the 100th of nanoseconds range for complex models (see this [benchmark script](https://github.com/VirtualPlantLab/PlantSimEngine.jl/blob/main/examples/benchmark.jl)). |
57 | 66 | - **Parallelize and Distribute Computing**: Out-of-the-box support for sequential, multi-threaded, or distributed computations over objects, time-steps, and independent processes, thanks to [Floops.jl](https://juliafolds.github.io/FLoops.jl/stable/). |
58 | 67 | - **Scale Effortlessly**: Methods for computing over objects, time-steps, and [Multi-Scale Tree Graphs](https://github.com/VEZY/MultiScaleTreeGraph.jl). |
@@ -92,7 +101,7 @@ using PlantSimEngine |
92 | 101 | using PlantSimEngine.Examples |
93 | 102 |
|
94 | 103 | # Define the model: |
95 | | -model = ModelList( |
| 104 | +model = ModelMapping( |
96 | 105 | ToyLAIModel(), |
97 | 106 | status=(TT_cu=1.0:2000.0,), # Pass the cumulated degree-days as input to the model |
98 | 107 | ) |
@@ -136,27 +145,27 @@ lines(model[:TT_cu], model[:LAI], color=:green, axis=(ylabel="LAI (m² m⁻²)", |
136 | 145 |
|
137 | 146 | ### Model coupling |
138 | 147 |
|
139 | | -Model coupling is done automatically by the package, and is based on the dependency graph between the models. To couple models, we just have to add them to the `ModelList`. For example, let's couple the `ToyLAIModel` with a model for light interception based on Beer's law: |
| 148 | +Model coupling is done automatically by the package, and is based on the dependency graph between the models. To couple models, we just have to add them to the `ModelMapping`. For example, let's couple the `ToyLAIModel` with a model for light interception based on Beer's law: |
140 | 149 |
|
141 | 150 | ```julia |
142 | | -# ] add PlantSimEngine, DataFrames, CSV |
143 | | -using PlantSimEngine, PlantMeteo, DataFrames, CSV |
| 151 | +# ] add PlantSimEngine, PlantMeteo, Dates |
| 152 | +using PlantSimEngine, PlantMeteo, Dates |
144 | 153 |
|
145 | 154 | # Include the model definition from the examples folder: |
146 | 155 | using PlantSimEngine.Examples |
147 | 156 |
|
148 | 157 | # Import the example meteorological data: |
149 | | -meteo_day = CSV.read(joinpath(pkgdir(PlantSimEngine), "examples/meteo_day.csv"), DataFrame, header=18) |
| 158 | +meteo_day = read_weather(joinpath(pkgdir(PlantSimEngine), "examples/meteo_day.csv"), duration=Dates.Day) |
150 | 159 |
|
151 | 160 | # Define the list of models for coupling: |
152 | | -model = ModelList( |
| 161 | +model = ModelMapping( |
153 | 162 | ToyLAIModel(), |
154 | 163 | Beer(0.6), |
155 | 164 | status=(TT_cu=cumsum(meteo_day[:, :TT]),), # Pass the cumulated degree-days as input to `ToyLAIModel`, this could also be done using another model |
156 | 165 | ) |
157 | 166 | ``` |
158 | 167 |
|
159 | | -The `ModelList` couples the models by automatically computing the dependency graph of the models. The resulting dependency graph is: |
| 168 | +The `ModelMapping` couples the models by automatically computing the dependency graph of the models. The resulting dependency graph is: |
160 | 169 |
|
161 | 170 | ``` |
162 | 171 | ╭──── Dependency graph ──────────────────────────────────────────╮ |
|
223 | 232 | The package is designed to be easily scalable, and can be used to simulate models at different scales. For example, you can simulate a model at the leaf scale, and then couple it with models at any other scale, *e.g.* internode, plant, soil, scene scales. Here's an example of a simple model that simulates plant growth using sub-models operating at different scales: |
224 | 233 |
|
225 | 234 | ```julia |
226 | | -mapping = Dict( |
| 235 | +mapping = ModelMapping( |
227 | 236 | "Scene" => ToyDegreeDaysCumulModel(), |
228 | 237 | "Plant" => ( |
229 | 238 | MultiScaleModel( |
@@ -295,7 +304,7 @@ meteo = Weather( |
295 | 304 | And run the simulation: |
296 | 305 |
|
297 | 306 | ```julia |
298 | | -out_vars = Dict( |
| 307 | +out_vars = ModelMapping( |
299 | 308 | "Scene" => (:TT_cu,), |
300 | 309 | "Plant" => (:carbon_allocation, :carbon_assimilation, :soil_water_content, :aPPFD, :TT_cu, :LAI), |
301 | 310 | "Leaf" => (:carbon_demand, :carbon_allocation), |
@@ -337,6 +346,17 @@ An example output of a multiscale simulation is shown in the documentation of Pl |
337 | 346 |
|
338 | 347 |  |
339 | 348 |
|
| 349 | +### Multi-rate modelling |
| 350 | + |
| 351 | +PlantSimEngine also supports multi-rate MTG simulations, where different models run at different cadences inside the same execution. A typical use case is to run leaf-scale processes hourly, aggregate them into daily plant-scale balances, and then export weekly summary series from the same simulation. |
| 352 | + |
| 353 | +The dedicated documentation now has three pages: a short introduction to the |
| 354 | +core ideas, a fuller step-by-step tutorial, and an advanced configuration page: |
| 355 | + |
| 356 | +- [Introduction to multi-rate execution](https://VirtualPlantLab.github.io/PlantSimEngine.jl/stable/multirate/introduction/) |
| 357 | +- [Step-by-step hourly, daily, weekly simulation](https://VirtualPlantLab.github.io/PlantSimEngine.jl/stable/multirate/multirate_tutorial/) |
| 358 | +- [Advanced multi-rate configuration](https://VirtualPlantLab.github.io/PlantSimEngine.jl/stable/multirate/advanced_configuration/) |
| 359 | + |
340 | 360 | ## Projects that use PlantSimEngine |
341 | 361 |
|
342 | 362 | Take a look at these projects that use PlantSimEngine: |
|
0 commit comments