|
| 1 | +# Changelog |
| 2 | + |
| 3 | +## v0.14.0 |
| 4 | + |
| 5 | +Changes in this section are based on the git history since [`v0.13.2`](https://github.com/VirtualPlantLab/PlantSimEngine.jl/releases/tag/v0.13.2), corresponding to the GitHub compare view for [`v0.14.0`](https://github.com/VirtualPlantLab/PlantSimEngine.jl/compare/v0.13.2...v0.14.0). |
| 6 | + |
| 7 | +### Summary |
| 8 | + |
| 9 | +This release introduces first-class multi-rate execution for MTG simulations. |
| 10 | +The main addition is a new configuration layer around `ModelMapping` and |
| 11 | +`ModelSpec`, making it possible to run models at different cadences in the same |
| 12 | +simulation, define how inputs and weather are resampled across rates, and export |
| 13 | +derived time series at requested clocks. |
| 14 | + |
| 15 | +The release also consolidates mapping APIs, improves validation and |
| 16 | +introspection, updates the package to the newer MultiScaleTreeGraph release, |
| 17 | +and substantially expands the documentation. |
| 18 | + |
| 19 | +### Breaking changes |
| 20 | + |
| 21 | +The main user-facing breaking change in this release is the move toward |
| 22 | +`Symbol`-based scale names in mappings and multi-scale configuration. Code that |
| 23 | +still uses string scales such as `"Leaf"` or `"Plant"` should be updated to use |
| 24 | +symbols such as `:Leaf` and `:Plant`, especially in `ModelMapping(...)`, |
| 25 | +`MultiScaleModel(...)`, and explicit multi-rate bindings. `ModelList` is also on |
| 26 | +the deprecation path in favor of `ModelMapping`, so this release is a good time |
| 27 | +to migrate mapping code to the newer API. |
| 28 | + |
| 29 | +### Added |
| 30 | + |
| 31 | +- First-class multi-rate MTG execution support, including runtime clocks, |
| 32 | + temporal input resolution, weather sampling, stream publishing, scoping, and |
| 33 | + requested-output export. |
| 34 | +- New multi-rate configuration building blocks: |
| 35 | + `ModelMapping`, `ModelSpec`, `ClockSpec`, `TimeStepModel`, |
| 36 | + `InputBindings`, `MeteoBindings`, `MeteoWindow`, `OutputRouting`, and |
| 37 | + `ScopeModel`. |
| 38 | +- New model traits for multi-rate inference and defaults: |
| 39 | + `output_policy`, `timestep_hint`, and `meteo_hint`. |
| 40 | +- New export API for resampled output streams with `OutputRequest(...)` and |
| 41 | + `collect_outputs(...)`. |
| 42 | +- New debugging/introspection helpers: |
| 43 | + `resolved_model_specs(mapping)` and `explain_model_specs(mapping_or_sim)`. |
| 44 | +- Support for calendar-aligned weather windows through PlantMeteo windows such |
| 45 | + as `CalendarWindow(:day, ...)`. |
| 46 | +- Support for `Dates` periods in model timesteps |
| 47 | + (`Dates.Minute`, `Dates.Hour`, `Dates.Day`, ...), in addition to numeric steps |
| 48 | + and `ClockSpec`. |
| 49 | +- `Interpolate()` as a policy for slow-to-fast couplings, alongside clarified |
| 50 | + `Integrate()` and `Aggregate()` behavior. |
| 51 | +- A dedicated benchmark suite for the multi-rate implementation. |
| 52 | +- A new multi-rate documentation track: |
| 53 | + [introduction](/Users/rvezy/Documents/dev/PlantSimEngine/docs/src/multirate/introduction.md), |
| 54 | + [step-by-step tutorial](/Users/rvezy/Documents/dev/PlantSimEngine/docs/src/multirate/multirate_tutorial.md), |
| 55 | + and [advanced configuration](/Users/rvezy/Documents/dev/PlantSimEngine/docs/src/multirate/advanced_configuration.md). |
| 56 | + |
| 57 | +### Changed |
| 58 | + |
| 59 | +- `ModelMapping` is now the canonical mapping type for both single-scale and |
| 60 | + multiscale usage. It replaces the old "plain `Dict` for multiscale, |
| 61 | + `ModelList` for single-scale" split. |
| 62 | +- Multi-rate execution is now inferred from the mapping/runtime configuration. |
| 63 | + The old explicit `multirate=true` flag has been removed. |
| 64 | +- Runtime timestep resolution is now explicit and consistent: |
| 65 | + `ModelSpec.timestep` > non-default `timespec(model)` > meteo base timestep. |
| 66 | +- Input-source inference is more capable and more predictable: |
| 67 | + same-scale unique producers are preferred, mapped variables participate in |
| 68 | + inference, and the runtime gives better errors when ambiguity remains. |
| 69 | +- Multi-rate weather aggregation now relies on PlantMeteo’s sampling APIs and |
| 70 | + default transforms for common `Atmosphere` variables. |
| 71 | +- Same-rate hard dependencies no longer require the explicit multi-rate |
| 72 | + machinery that slower/faster couplings need. |
| 73 | +- Scale names are moving toward `Symbol` consistently across the API and docs. |
| 74 | +- Package compatibility was updated to newer core dependencies: |
| 75 | + Julia `1.10`, `MultiScaleTreeGraph = 0.15.1`, `PlantMeteo = 0.8.2`, |
| 76 | + `Term = 2`. |
| 77 | + |
| 78 | +### Deprecated |
| 79 | + |
| 80 | +- `run!(::ModelList, ...)` is deprecated. Use `run!(ModelMapping(...), ...)` |
| 81 | + instead. |
| 82 | +- `run!` with collections of `ModelList` is deprecated. Use collections of |
| 83 | + `ModelMapping` instead. |
| 84 | +- `run!(mtg, mapping::AbstractDict, ...)` is deprecated. Construct a |
| 85 | + `ModelMapping(...)` first, or call `run!(mtg, ModelMapping(mapping), ...)`. |
| 86 | +- String scale names are deprecated in multi-scale mapping APIs. Use `Symbol` |
| 87 | + scales such as `:Leaf` instead of `"Leaf"`. |
| 88 | +- `ModelList` remains available for now but is being phased out in favor of |
| 89 | + `ModelMapping`. |
| 90 | + |
| 91 | +### Migration guide |
| 92 | + |
| 93 | +#### 1. Replace ad hoc mappings with `ModelMapping` |
| 94 | + |
| 95 | +If you previously used `ModelList(...)` directly for single-scale runs, or a |
| 96 | +plain `Dict` for MTG runs, migrate to `ModelMapping(...)`. |
| 97 | + |
| 98 | +Before: |
| 99 | + |
| 100 | +```julia |
| 101 | +leaf = ModelList( |
| 102 | + process1 = Process1Model(), |
| 103 | + process2 = Process2Model(), |
| 104 | + status = (x = 1.0,), |
| 105 | +) |
| 106 | + |
| 107 | +mapping = Dict( |
| 108 | + :Leaf => (ToyAssimModel(),), |
| 109 | + :Plant => (ToyGrowthModel(),), |
| 110 | +) |
| 111 | +``` |
| 112 | + |
| 113 | +After: |
| 114 | + |
| 115 | +```julia |
| 116 | +leaf = ModelMapping( |
| 117 | + process1 = Process1Model(), |
| 118 | + process2 = Process2Model(), |
| 119 | + status = (x = 1.0,), |
| 120 | +) |
| 121 | + |
| 122 | +mapping = ModelMapping( |
| 123 | + :Leaf => (ToyAssimModel(),), |
| 124 | + :Plant => (ToyGrowthModel(),), |
| 125 | +) |
| 126 | +``` |
| 127 | + |
| 128 | +#### 2. Use rate-specific behavior in `ModelSpec(...)` |
| 129 | + |
| 130 | +When a model should run at a cadence different from the meteo, wrap it in |
| 131 | +`ModelSpec(...)` and add the relevant transforms. |
| 132 | + |
| 133 | +Typical pattern: |
| 134 | + |
| 135 | +```julia |
| 136 | +mapping = ModelMapping( |
| 137 | + :Leaf => ( |
| 138 | + ModelSpec(HourlyLeafModel()) |> TimeStepModel(1.0), |
| 139 | + ), |
| 140 | + :Plant => ( |
| 141 | + ModelSpec(DailyPlantModel()) |> |
| 142 | + TimeStepModel(Dates.Day(1)) |> |
| 143 | + InputBindings(; A=(process=:hourlyleaf, var=:A, scale=:Leaf, policy=Integrate())) |> |
| 144 | + MeteoBindings(; T=MeanWeighted()), |
| 145 | + ), |
| 146 | +) |
| 147 | +``` |
| 148 | + |
| 149 | +You do not always need explicit `InputBindings(...)` or `MeteoBindings(...)`: |
| 150 | +the runtime can infer simple cases, and PlantMeteo already defines defaults for |
| 151 | +common weather variables. But this is now the place where explicit multi-rate |
| 152 | +behavior belongs. |
| 153 | + |
| 154 | +#### 3. Ensure weather rows define `duration` |
| 155 | + |
| 156 | +When meteo is provided, `duration` is now mandatory on every weather row. |
| 157 | +Without it, PlantSimEngine cannot determine the meteo base timestep or perform |
| 158 | +correct aggregation over coarser model clocks. |
| 159 | + |
| 160 | +Before: |
| 161 | + |
| 162 | +```julia |
| 163 | +Weather([ |
| 164 | + Atmosphere(T=20.0, Wind=1.0, Rh=0.65), |
| 165 | +]) |
| 166 | +``` |
| 167 | + |
| 168 | +After: |
| 169 | + |
| 170 | +```julia |
| 171 | +Weather([ |
| 172 | + Atmosphere(duration=Dates.Hour(1), T=20.0, Wind=1.0, Rh=0.65), |
| 173 | +]) |
| 174 | +``` |
| 175 | + |
| 176 | +#### 4. Use `Symbol` scale names |
| 177 | + |
| 178 | +If your mappings still use string scales, migrate them to symbols. |
| 179 | + |
| 180 | +Before: |
| 181 | + |
| 182 | +```julia |
| 183 | +mapping = ModelMapping( |
| 184 | + "Leaf" => (ToyAssimModel(),), |
| 185 | +) |
| 186 | + |
| 187 | +ModelSpec(DailyPlantModel()) |> |
| 188 | +MultiScaleModel([:A => "Leaf"]) |
| 189 | +``` |
| 190 | + |
| 191 | +After: |
| 192 | + |
| 193 | +```julia |
| 194 | +mapping = ModelMapping( |
| 195 | + :Leaf => (ToyAssimModel(),), |
| 196 | +) |
| 197 | + |
| 198 | +ModelSpec(DailyPlantModel()) |> |
| 199 | +MultiScaleModel([:A => :Leaf]) |
| 200 | +``` |
| 201 | + |
| 202 | +#### 5. Prefer `OutputRequest(...)` for explicit exported clocks |
| 203 | + |
| 204 | +If you want clean hourly/daily/weekly exports from a multi-rate simulation, use |
| 205 | +`OutputRequest(...)` in `tracked_outputs` and optionally return them directly |
| 206 | +from `run!`. |
| 207 | + |
| 208 | +```julia |
| 209 | +req = OutputRequest(:Plant, :plant_assim_d; |
| 210 | + name=:plant_assim_daily, |
| 211 | + clock=ClockSpec(24.0, 0.0), |
| 212 | +) |
| 213 | + |
| 214 | +out_status, exported = run!( |
| 215 | + mtg, |
| 216 | + mapping, |
| 217 | + meteo; |
| 218 | + tracked_outputs=[req], |
| 219 | + return_requested_outputs=true, |
| 220 | +) |
| 221 | +``` |
| 222 | + |
| 223 | +This is the recommended way to export resampled streams instead of manually |
| 224 | +rebuilding them from mixed-rate internal outputs. |
| 225 | + |
| 226 | +#### 6. Add trait defaults where they improve clarity |
| 227 | + |
| 228 | +For reusable models, it is now often worth defining: |
| 229 | + |
| 230 | +- `output_policy(::Type{<:MyModel})` to describe the natural aggregation rule |
| 231 | + for a produced variable, |
| 232 | +- `timestep_hint(::Type{<:MyModel})` to declare valid/preferred cadences, |
| 233 | +- `meteo_hint(::Type{<:MyModel})` to declare default weather aggregation rules. |
| 234 | + |
| 235 | +This is optional, but it makes inference more useful and error messages more |
| 236 | +actionable. |
| 237 | + |
| 238 | +### Documentation |
| 239 | + |
| 240 | +The documentation was significantly reorganized and expanded around this |
| 241 | +release: |
| 242 | + |
| 243 | +- multi-rate now has dedicated introduction, tutorial, and advanced pages; |
| 244 | +- the model execution and API pages describe the new scheduling and inference |
| 245 | + rules; |
| 246 | +- outdated draft pages were removed from the published docs; |
| 247 | +- multiscale docs were refreshed to match the newer mapping APIs. |
| 248 | + |
| 249 | +### Internal and maintenance notes |
| 250 | + |
| 251 | +- CI and benchmark workflows were refreshed around the new multi-rate runtime. |
| 252 | +- Downstream/benchmark setup was cleaned up as part of the release prep. |
| 253 | +- Several doc and benchmark follow-up commits after the core implementation were |
| 254 | + included in this release range. |
| 255 | + |
| 256 | +### Included pull requests |
| 257 | + |
| 258 | +- Downstream testing CI changes by @Samuel-amap in [#154](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/154) |
| 259 | +- AirSpeedVelocity.jl benchmarks by @Samuel-amap in [#155](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/155) |
| 260 | +- Fix #144 and add to tests by @Samuel-amap in [#156](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/156) |
| 261 | +- Remove windows and mac from the .yml by @Samuel-amap in [#157](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/157) |
| 262 | +- Filter out empty status vectors by @Samuel-amap in [#160](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/160) |
| 263 | +- Streamline graphsim initialisation by @Samuel-amap in [#169](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/169) |
| 264 | +- Small addendum to the list of PlantSimEngine Julia errors, also used by @Samuel-amap in [#172](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/172) |
| 265 | +- Bump actions/checkout from 4 to 6 by @dependabot[bot] in [#167](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/167) |
| 266 | +- Use dependabot action and remove compathelper by @VEZY in [#175](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/175) |
| 267 | +- Unified interface for model mapping by @VEZY in [#177](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/177) |
| 268 | +- `ModelMapping` validations at construction by @VEZY in [#178](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/178) |
| 269 | +- Add `PlantSimEngine.output_policy` trait by @VEZY in [#179](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/179) |
| 270 | +- Upgrade to MultiScaleTreeGraph v0.15.0 by @VEZY in [#180](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/180) |
| 271 | +- Fix world age issues by @VEZY in [#184](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/184) |
| 272 | +- Implement multirate simulations - take 3 by @VEZY in [#174](https://github.com/VirtualPlantLab/PlantSimEngine.jl/pull/174) |
0 commit comments