Repository navigation
Tags: VirtualPlantLab/PlantSimEngine.jl
Tags
[Diff since v0.14.1](v0.14.1...v0.15.0) Largest API change since the beginning. Sorry for people using PlantSimEngine, but this was needed to move forward with both different cadences for models and different plants/species in a simulation (that did require a sense of parents/children/subtrees). I think this API is quite stable now, as I have tested it extensively with XPalm, PlantBiophysics, ArchimedLight.jl, AMAPSim.jl, PlantGeom, etc... And it is agent-friendly, so now we can more easily use AI to build and modify models. Enjoy! PlantSimEngine 0.15 is a breaking release that replaces the historical `ModelMapping`/`MultiScaleModel` execution stack with one compiled `CompositeModel`/`Object` runtime. The same scenario representation now covers single objects, multiscale plants, several plants or species, shared resources, dynamic topology, multirate models, global or spatial environments, and retained output streams. The redesign makes coupling and execution explicit. Model applications declare where they run, which values they read, which models they call, where they write, their cadence, and their environment through one `ModelSpec` grammar. The compiler validates and resolves those declarations before execution, while the `Diagnostics` and `Authoring` namespaces expose structured explanations for users, graphical tools, tests, and coding agents. Scientific equations can usually remain unchanged, but model packages must adopt `PlantSimEngine.run!(model, status, environment, constants, context)`, read parameters from `model`, and update input declarations as well as scenario assembly and coupling. - The historical scenario and execution APIs were removed without a compatibility layer: `ModelList`, `ModelMapping`, `GraphSimulation`, `MultiScaleModel`, their direct and batch `run!` methods, and the separate mapping dependency/runtime stack. Scenarios must use `CompositeModel`, `Object`, and named `ModelSpec` applications. - Mapping-era configuration wrappers were removed, including `SameScale`, `TimeStepModel`, `InputBindings`, `MeteoBindings`, `MeteoWindow`, and `ScopeModel`, and `OutputRouting`. Their replacements are selectors and the `on`, `inputs`, `every`, `environment`, and `output_routing` fields of `ModelSpec`. - Model kernels now read their parameters from `model` and receive a `RunContext` through `PlantSimEngine.run!(model, status, environment, constants, context)`. Direct recursive dependency execution and the former mapping-runtime kernel signatures are no longer supported. - `inputs_(model)` must distinguish required inputs from genuine fallbacks with `Required(T)` and `Default(value)`. Plain input literals are rejected because they do not state whether a value is required or optional. Use `init_variables(model)` to obtain only real input defaults and initial output values. - `Self()` now selects only the object where the consumer runs. Use `Subtree()` for that object and its descendants, `SelfPlant()` for the nearest containing `scale=:Plant` object and its subtree, or an explicit `SceneScope()`, `Ancestor(...)`, `Scope(...)`, or `Relation(...)` selector for other topology scopes. - Repeated applications must be named explicitly. Scenario inputs, calls, output requests, overrides, and ordered updates use canonical application identity rather than assuming that a process identifies one unique application. - Singular scenario `process=...` references, output-request `process=...`, and process-only overrides were removed. Use `application=...`; `Many(process=...)` remains available as an explicit multi-application discovery query. - Legacy string-keyed mapping scales were removed. Composite-model labels are stored canonically as symbols; use `:Leaf` and `:Plant` in new code. - `run!(model; ...)` always starts a fresh timeline and returns a `Simulation`. Use `continue!(simulation)` or `step!(simulation)` to preserve the timeline, temporal histories, environment position, and multirate phase. - The `tracked_outputs` keyword was removed. Output retention is explicit with `outputs=:none`, `outputs=:all`, or one or more `OutputRequest`s; the safe default is `outputs=:none`. - MTG-backed runtime `Status` objects are owned by the `CompositeModel` registry instead of being stored as live status columns in MTG node attributes. - Compiler representations and cache controls moved to `PlantSimEngine.Advanced`. Model discovery, supported diagnostics, graph editing, environment extensions, and evaluation APIs live in the qualified `Authoring`, `Diagnostics`, `GraphEditor`, `EnvironmentAPI`, and `Evaluation` namespaces. - PlantMeteo reducers are no longer re-exported. Use qualified names such as `PlantMeteo.MeanReducer` and `PlantMeteo.RadiationEnergy`. - Graph visualization and editing moved to the qualified `GraphEditor` namespace. In particular, use `GraphEditor.model_graph_view`, `GraphEditor.write_model_graph_view`, and `GraphEditor.current_model` instead of `graph_view`, `write_graph_view`, and `current_mapping`. - Object and instance overrides now require the complete compiled model interface to match: full status/environment schemas, variable contracts, model-authored dependencies, cadence, output policy, timestep hint, and environment hint. Alternatives of the same process that differ in any of these declarations must use a reconfigured `ModelSpec` instead. - Environment backends now compile an opaque per-target handle with `EnvironmentAPI.bind_environment`. Accepted state is committed explicitly with `commit_environment!`, while provider-aware trial state is passed with `run_call!(context, name; environment=state)`. The former support/scatter, scoped override, and context-level meteorology APIs were removed. - Hard dependencies now execute through `run_call!(context::RunContext, name::Symbol; ...)`, which executes every selector-resolved target and always returns a vector-like `CallTargets` collection. Calls default to `publish=false` for trial states; accepted iterative states must be published explicitly with `publish=true`. Applications used exclusively as manual-call targets are skipped by the root scheduler. - String-name hard-call methods were removed. `call_model(context, :name)` is the singular convenience for retrieving the concrete model behind a call that resolves exactly one target; use `call_targets(context, :name)` for target status, selective execution, or plural calls. - Declare outputs written to selected objects inside `outputs_` with `Distributed(Default(value))` or `Distributed(Required(T))`. These variables are now visible when inspecting a model before building a scenario. - `outputs_to` now takes an anonymous tuple of `OutputTo` entries. One entry can omit `vars` to bind all distributed outputs; multiple entries must explicitly partition variable names. Defaults and types belong to the model. - Request destination columns with `output_targets(context, (:x, :y))`. Missing, duplicate, and incompatible destination declarations fail before initialization. Named output groups and schemas in `OutputTo.vars` were removed. - A unified runtime object registry with stable `ObjectId` identities and an architecture-neutral `Object` hierarchy. `CompositeModelTemplate`, `ObjectInstance`, and `Override` reuse one configuration across several plants or species while allowing compatible object-specific alternatives. - One application grammar: `ModelSpec(model; name=..., on=..., inputs=..., calls=..., outputs_to=..., every=..., environment=..., output_routing=..., updates=...)`. Unique same-object inputs are inferred; cross-object couplings remain explicit and are compiled to scalar references, homogeneous reference vectors, heterogeneous object-reference vectors, or typed temporal streams. - Model-author dependency defaults through `dep(model)` using `Input(...)`, `Call(...)`, and `Initializer(...)`. Scenario-level `ModelSpec` declarations through `inputs=...` and `calls=...` can replace those defaults. - Uniform selectors with `One`, `OptionalOne`, and `Many` multiplicity; `SceneScope`, `Self`, `Subtree`, `SelfPlant`, `Ancestor`, `Scope`, and `Relation` scope; and `kind`, `species`, `scale`, and `name` label criteria. - Identity-aware many-input access through `bound_input`, `BoundMany`, and `object_ids`, preserving the alignment between values and source objects. - Distributed output assignment with `OutputTo`, `OutputTargets`, `output_targets`, and `assign_outputs!`. Applications can own an output while storing its values on explicitly selected destination objects, with exact identity and writer validation. - `Updates(:variable; after=:application)` for intentional writer order and `output_routing=(variable=:stream_only,)` for retaining a publisher's stream without giving it canonical status ownership. - `VariableContract` metadata for validating unit, spatial or object basis, temporal basis, aggregation meaning, and intensive/extensive semantics at compiled producer-consumer boundaries without wrapping runtime values. - Integrated multirate execution through `ModelSpec(...; every=Dates.Period)` and the `HoldLast`, `Interpolate`, `Integrate`, and `Aggregate` temporal policies. `PreviousTimeStep` expresses an explicit lag and breaks same-timestep dependency cycles. - Global and spatial environment backends with compiled per-target handles, source remapping through `Environment`, model-authored environment defaults, and targeted rebinding after geometry changes. - MTG adaptation with `objects_from_mtg` and `CompositeModel(mtg; ...)`, plus a complete dynamic lifecycle API for registering, adding, removing, reparenting, moving, and updating the geometry of objects. Affected targets, input carriers, call targets, schedules, writer checks, execution batches, and environment bindings are refreshed automatically. - `Initializer` and `run_initializer!` for running an already scheduled application once on a newly registered object during its creation event. - `add_organ!(...; use_status_adapter=false)` for MTG-backed models whose new node attributes already form the authoritative initialization payload. The default remains `true`; opting out skips only the stored adapter status initializer while preserving node attributes, explicit initial-value precedence, node identity, object registration, and binding invalidation. - `Simulation`, `continue!`, `step!`, `current_step`, `final_state`, `outputs`, `OutputRequest`, and `collect_outputs` for explicit timeline continuation and typed output inspection. Streams are keyed by application, object, and variable so repeated processes cannot overwrite one another. - Bounded retention of internal streams required by temporal dependencies, plus `Diagnostics.explain_output_retention` for explaining why each stream is retained. - `PlantSimEngine.Authoring`, a versioned, serializable API for process/model discovery, exact instance descriptions, optional parameter metadata, interface comparison, and structured model/scenario validation. - `Authoring.scenario_source` for reconstructing an editable `CompositeModel`, plus `Authoring.compiled_model_source` and `Authoring.write_compiled_model_source` for reviewing an executable, readable view of the resolved application plan. - A package-owned PlantSimEngine agent skill organized as a short router with focused authoring, coupling, lifecycle, diagnostics, and repository references. Its canonical examples are executed by the package test suite. - `CallTargets`, a cached `AbstractVector` view over compiled hard-call targets that is allocation-free to retrieve. - `run_call!(context, name)` for the common execute-all operation while retaining `run_call!(target::CallTarget)` for selective, per-target, and iterative control. - Structured diagnostics for objects, instances, scopes, applications, value bindings, calls, distributed outputs, environment bindings, schedules, writers, initialization, execution plans, retained outputs, and collected streams. - Model applications are compiled into dependency-ordered, homogeneous execution batches with cached value carriers, hard-call targets, schedules, and environment handles. Dynamic dispatch occurs at concrete batch boundaries instead of once per object. - Structural lifecycle changes use targeted indexes to refresh only affected selectors and carriers when possible. Geometry-only changes can refresh environment bindings without rebuilding structural bindings. - Compilation now rejects missing required inputs, invalid selectors, cardinality mismatches, incompatible declared `VariableContract`s, ambiguous or unordered writers, unsupported override interfaces, and same-timestep dependency cycles before the simulation starts. - Output streams preserve their concrete value type through publication, interpolation, integration, and collection without coercing stream values to `Float64`. - Status conversion is configured on `CompositeModel(...; type_promotion=..., status_transform=...)` and applied when status storage is materialized for initial objects, model defaults, and objects registered later. - The GraphEditor now edits and visualizes `CompositeModel` scenarios. - Compatibility was updated to MultiScaleTreeGraph 0.16 and PlantMeteo 0.9. - Retained outputs and temporal dependency streams snapshot mutable values, so later in-place model updates do not overwrite historical samples. This also covers the initial values of output requests, including selector reentry. - Temporal history buffers grow when newly added consumers need longer windows. `PreviousTimeStep` retains the preceding publication even when fractional clocks or manual calls leave gaps between publications. - `Many` inputs respect application and process filters for local producers. Positional `Relation(...)` selectors keep separate bindings for each consumer after objects are added. - Newborn initializers can read fully initialized sources registered in the same lifecycle event. Unrelated distributed outputs no longer hide newborn sources from `Many` inputs. - Mixed-type object IDs with the same text remain distinct during sorting and identity-based lookup. - Temporal inputs and `final_state` snapshots no longer alias nested mutable producer values. Explicitly declared environment durations also survive forcing-source remapping without duplicate fields or replacement. - Fixed-period cadences now support subsecond durations. A cadence that is not an integer multiple of the simulation base step is rejected with an explicit error instead of silently running less often than requested. - Model validation checks the five-argument kernel signature, including variadic implementations. Model comparison treats reordered named output policies consistently with runtime override compatibility. - Type-only model discovery no longer executes guessed placeholder constructors and reports field-level provenance when an exact instance is unavailable. - Removed ambiguities in distributed-output runtime dispatch when temporal streams are absent and output retention is either absent or compiled. - Construct dynamic `Status` values directly from the final ordered payload, preserving precedence and independent `Ref` storage without the generic iterable-to-`NamedTuple` merge path. This release intentionally does not retain aliases or fallback methods for the removed mapping runtime. The [`CompositeModel`/`Object` migration guide](docs/src/migration_composite_model.md) provides executable translations for scenario structure, multiscale inputs, hard calls, multiple plants, multirate coupling, environments, dynamic organs, and output collection. The principal replacements are: | Historical configuration | v0.15 replacement | | --- | --- | | `ModelMapping` scale assembly | `CompositeModel` objects and model applications | | `MultiScaleModel(...)` | consumer-side `ModelSpec(...; inputs=...)` | | `TimeStepModel(...)` | `ModelSpec(...; every=...)` | | `InputBindings(...)` | selector, policy, and window in `ModelSpec(...; inputs=...)` | | `MeteoBindings(...)` / `MeteoWindow(...)` | automatic binding, `environment_hint`, and `Environment(...)` | | `ScopeModel(...)` | `ModelSpec(...; on=...)` and selector scopes | | `SameScale()` | `One(within=Self(), var=:source)` | | `OutputRouting(...)` | `ModelSpec(...; output_routing=(...))` | | mapping status conversion | `CompositeModel(...; type_promotion=..., status_transform=...)` | | mapping output indexing | `outputs(sim)`, `OutputRequest`, and `collect_outputs` | * Bump actions/setup-node from 4 to 7 by @dependabot[bot] in #201 * Bump actions/checkout from 6 to 7 by @dependabot[bot] in #200 * Bump codecov/codecov-action from 6 to 7 by @dependabot[bot] in #199 * Bump actions/upload-artifact from 4 to 7 by @dependabot[bot] in #196 * Update HTTP requirement from 1 to 1, 2.0 in the all-julia-packages group by @dependabot[bot] in #198 * Restore incremental lifecycle performance with distributed outputs by @VEZY in #211 * Improve model setup and share results with plant parts by @VEZY in #209 * [codex] Optimize dynamic organ lifecycle refresh by @VEZY in #212 * Multi-plants by @VEZY in #186 * docs: build a Bonito website and simplify modeling guides by @VEZY in #214 * build(deps): bump actions/upload-artifact from 4 to 7 by @dependabot[bot] in #217 * build(deps): bump actions/checkout from 6 to 7 by @dependabot[bot] in #218 * [codex] Avoid rebuilding unchanged statuses during compilation by @VEZY in #215 * Declare distributed outputs and clarify scenario authoring by @VEZY in #216 * [codex] Fix selector, initializer, and output-history regressions by @VEZY in #220 **Full Changelog**: v0.14.1...v0.15.0 **Merged pull requests:** - Multi-plants (#186) (@VEZY) - Bump actions/upload-artifact from 4 to 7 (#196) (@dependabot[bot]) - Update HTTP requirement from 1 to 1, 2.0 in the all-julia-packages group (#198) (@dependabot[bot]) - Bump codecov/codecov-action from 6 to 7 (#199) (@dependabot[bot]) - Bump actions/checkout from 6 to 7 (#200) (@dependabot[bot]) - Bump actions/setup-node from 4 to 7 (#201) (@dependabot[bot]) - Improve model setup and share results with plant parts (#209) (@VEZY) - Restore incremental lifecycle performance with distributed outputs (#211) (@VEZY) - [codex] Optimize dynamic organ lifecycle refresh (#212) (@VEZY) - docs: build a Bonito website and simplify modeling guides (#214) (@VEZY) - [codex] Avoid rebuilding unchanged statuses during compilation (#215) (@VEZY) - Declare distributed outputs and clarify scenario authoring (#216) (@VEZY) - build(deps): bump actions/upload-artifact from 4 to 7 (#217) (@dependabot[bot]) - build(deps): bump actions/checkout from 6 to 7 (#218) (@dependabot[bot]) - [codex] Fix selector, initializer, and output-history regressions (#220) (@VEZY)
[Diff since v0.14.0](v0.14.0...v0.14.1) Changes in this section are based on the git history since [`v0.14.0`](https://github.com/VirtualPlantLab/PlantSimEngine.jl/releases/tag/v0.14.0), corresponding to the GitHub compare view for [`v0.14.1`](v0.14.0...v0.14.1). This release adds a dependency graph visualizer and an interactive graph editor. The new tooling makes it possible to inspect a `ModelMapping`, see which models produce and consume each variable, diagnose missing initialization values, and interactively build or revise a mapping from a browser UI. The static graph viewer is available directly from `PlantSimEngine` through `write_graph_view`, `graph_view`, and `graph_view_json`. The live editor is provided by the `PlantSimEngineGraphEditorExt` package extension and is loaded when `HTTP.jl` is available in the session. The release also includes benchmark and CI maintenance, updated developer guidance, and a new agent skill for working with PlantSimEngine internals. - New dependency graph visualization API: `graph_view`, `graph_view_json`, `compile_graph_view`, and `write_graph_view`. - A standalone HTML graph viewer with model nodes, variable ports, hard-call edges, variable dependency edges, scale filters, relationship filters, search, overview/detail modes, and an inspector. - An interactive browser-based graph editor through `edit_graph`, backed by a local `HTTP.jl` server and WebSocket session. - The live graph editor runs as a package extension that depends on `HTTP.jl`; static graph visualization is available without loading `HTTP`. - Editing support for adding, updating, removing, and reconnecting models in a `ModelMapping`. - Support for starting the editor from a blank mapping with `edit_graph()`. - Mapping-code generation from the editor, including `using PackageName` statements for loaded model packages and a top-level `mapping` variable. - Save, autosave, recent-file reopening, undo, and redo support in live graph editing sessions. - Model discovery helpers: `available_processes`, `available_models`, `model_descriptor`, and `model_constructor_descriptor`. - Editor suggestions for adding producer models from input variables and consumer models from output variables. - Cycle diagnostics in the graph UI, including highlighted cycle edges and an interactive way to wrap selected inputs in `PreviousTimeStep`. - Visualization of required initialization values and graph diagnostics even when a mapping is incomplete or cyclic. - A new documentation page for graph visualization and editing: [`docs/src/step_by_step/graph_visualization_editor.md`](docs/src/step_by_step/graph_visualization_editor.md). - Playwright end-to-end tests for the browser editor and new Julia tests for the static graph viewer and editor extension. - A local `plantsimengine` Codex skill describing the package architecture and contributor workflow. - Fixed type promotion behavior with `ModelMapping`. - Fixed benchmark and documentation issues that were blocking CI. **Merged pull requests:** - Fix benchmarks (#187) (@VEZY) - Bump codecov/codecov-action from 5 to 6 (#188) (@dependabot[bot]) - Bump julia-actions/setup-julia from 2 to 3 (#189) (@dependabot[bot]) - Add dependency graph visualizer and editor (#192) (@VEZY) - Add skill (#193) (@VEZY) - Adds graph editing (#194) (@VEZY) - Update skill (#195) (@VEZY) **Closed issues:** - Dependency graph visualization (#108) - API for supercharging models with more informations about time steps, multiscale mapping... (#121) - Variable timestep considerations (#124) - Simplified development workflow for modelers (#139)
[Diff since v0.13.2](v0.13.2...v0.14.0) This release introduces first-class multi-rate execution for MTG simulations. The main addition is a new configuration layer around `ModelMapping` and `ModelSpec`, making it possible to run models at different cadences in the same simulation, define how inputs and weather are resampled across rates, and export derived time series at requested clocks. The release also consolidates mapping APIs, improves validation and introspection, updates the package to the newer MultiScaleTreeGraph release, and substantially expands the documentation. 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`](v0.13.2...v0.14.0). The main user-facing breaking change in this release is the move toward `Symbol`-based scale names in mappings and multi-scale configuration. Code that still uses string scales such as `"Leaf"` or `"Plant"` should be updated to use symbols such as `:Leaf` and `:Plant`, especially in `ModelMapping(...)`, `MultiScaleModel(...)`, and explicit multi-rate bindings. `ModelList` is also on the deprecation path in favor of `ModelMapping`, so this release is a good time to migrate mapping code to the newer API. - First-class multi-rate MTG execution support, including runtime clocks, temporal input resolution, weather sampling, stream publishing, scoping, and requested-output export. - New multi-rate configuration building blocks: `ModelMapping`, `ModelSpec`, `ClockSpec`, `TimeStepModel`, `InputBindings`, `MeteoBindings`, `MeteoWindow`, `OutputRouting`, and `ScopeModel`. - New model traits for multi-rate inference and defaults: `output_policy`, `timestep_hint`, and `meteo_hint`. - New export API for resampled output streams with `OutputRequest(...)` and `collect_outputs(...)`. - New debugging/introspection helpers: `resolved_model_specs(mapping)` and `explain_model_specs(mapping_or_sim)`. - Support for calendar-aligned weather windows through PlantMeteo windows such as `CalendarWindow(:day, ...)`. - Support for `Dates` periods in model timesteps (`Dates.Minute`, `Dates.Hour`, `Dates.Day`, ...), in addition to numeric steps and `ClockSpec`. - `Interpolate()` as a policy for slow-to-fast couplings, alongside clarified `Integrate()` and `Aggregate()` behavior. - A dedicated benchmark suite for the multi-rate implementation. - A new multi-rate documentation track: [introduction](/Users/rvezy/Documents/dev/PlantSimEngine/docs/src/multirate/introduction.md), [step-by-step tutorial](/Users/rvezy/Documents/dev/PlantSimEngine/docs/src/multirate/multirate_tutorial.md), and [advanced configuration](/Users/rvezy/Documents/dev/PlantSimEngine/docs/src/multirate/advanced_configuration.md). - `ModelMapping` is now the canonical mapping type for both single-scale and multiscale usage. It replaces the old "plain `Dict` for multiscale, `ModelList` for single-scale" split. - Multi-rate execution is now inferred from the mapping/runtime configuration. The old explicit `multirate=true` flag has been removed. - Runtime timestep resolution is now explicit and consistent: `ModelSpec.timestep` > non-default `timespec(model)` > meteo base timestep. - Input-source inference is more capable and more predictable: same-scale unique producers are preferred, mapped variables participate in inference, and the runtime gives better errors when ambiguity remains. - Multi-rate weather aggregation now relies on PlantMeteo’s sampling APIs and default transforms for common `Atmosphere` variables. - Same-rate hard dependencies no longer require the explicit multi-rate machinery that slower/faster couplings need. - Scale names are moving toward `Symbol` consistently across the API and docs. - Package compatibility was updated to newer core dependencies: Julia `1.10`, `MultiScaleTreeGraph = 0.15.1`, `PlantMeteo = 0.8.2`, `Term = 2`. - `run!(::ModelList, ...)` is deprecated. Use `run!(ModelMapping(...), ...)` instead. - `run!` with collections of `ModelList` is deprecated. Use collections of `ModelMapping` instead. - `run!(mtg, mapping::AbstractDict, ...)` is deprecated. Construct a `ModelMapping(...)` first, or call `run!(mtg, ModelMapping(mapping), ...)`. - String scale names are deprecated in multi-scale mapping APIs. Use `Symbol` scales such as `:Leaf` instead of `"Leaf"`. - `ModelList` remains available for now but is being phased out in favor of `ModelMapping`. If you previously used `ModelList(...)` directly for single-scale runs, or a plain `Dict` for MTG runs, migrate to `ModelMapping(...)`. Before: ```julia leaf = ModelList( process1 = Process1Model(), process2 = Process2Model(), status = (x = 1.0,), ) mapping = Dict( :Leaf => (ToyAssimModel(),), :Plant => (ToyGrowthModel(),), ) ``` After: ```julia leaf = ModelMapping( process1 = Process1Model(), process2 = Process2Model(), status = (x = 1.0,), ) mapping = ModelMapping( :Leaf => (ToyAssimModel(),), :Plant => (ToyGrowthModel(),), ) ``` When a model should run at a cadence different from the meteo, wrap it in `ModelSpec(...)` and add the relevant transforms. Typical pattern: ```julia mapping = ModelMapping( :Leaf => ( ModelSpec(HourlyLeafModel()) |> TimeStepModel(1.0), ), :Plant => ( ModelSpec(DailyPlantModel()) |> TimeStepModel(Dates.Day(1)) |> InputBindings(; A=(process=:hourlyleaf, var=:A, scale=:Leaf, policy=Integrate())) |> MeteoBindings(; T=MeanWeighted()), ), ) ``` You do not always need explicit `InputBindings(...)` or `MeteoBindings(...)`: the runtime can infer simple cases, and PlantMeteo already defines defaults for common weather variables. But this is now the place where explicit multi-rate behavior belongs. When meteo is provided, `duration` is now mandatory on every weather row. Without it, PlantSimEngine cannot determine the meteo base timestep or perform correct aggregation over coarser model clocks. Before: ```julia Weather([ Atmosphere(T=20.0, Wind=1.0, Rh=0.65), ]) ``` After: ```julia Weather([ Atmosphere(duration=Dates.Hour(1), T=20.0, Wind=1.0, Rh=0.65), ]) ``` If your mappings still use string scales, migrate them to symbols. Before: ```julia mapping = ModelMapping( "Leaf" => (ToyAssimModel(),), ) ModelSpec(DailyPlantModel()) |> MultiScaleModel([:A => "Leaf"]) ``` After: ```julia mapping = ModelMapping( :Leaf => (ToyAssimModel(),), ) ModelSpec(DailyPlantModel()) |> MultiScaleModel([:A => :Leaf]) ``` If you want clean hourly/daily/weekly exports from a multi-rate simulation, use `OutputRequest(...)` in `tracked_outputs` and optionally return them directly from `run!`. ```julia req = OutputRequest(:Plant, :plant_assim_d; name=:plant_assim_daily, clock=ClockSpec(24.0, 0.0), ) out_status, exported = run!( mtg, mapping, meteo; tracked_outputs=[req], return_requested_outputs=true, ) ``` This is the recommended way to export resampled streams instead of manually rebuilding them from mixed-rate internal outputs. For reusable models, it is now often worth defining: - `output_policy(::Type{<:MyModel})` to describe the natural aggregation rule for a produced variable, - `timestep_hint(::Type{<:MyModel})` to declare valid/preferred cadences, - `meteo_hint(::Type{<:MyModel})` to declare default weather aggregation rules. This is optional, but it makes inference more useful and error messages more actionable. The documentation was significantly reorganized and expanded around this release: - multi-rate now has dedicated introduction, tutorial, and advanced pages; - the model execution and API pages describe the new scheduling and inference rules; - outdated draft pages were removed from the published docs; - multiscale docs were refreshed to match the newer mapping APIs. - CI and benchmark workflows were refreshed around the new multi-rate runtime. - Downstream/benchmark setup was cleaned up as part of the release prep. - Several doc and benchmark follow-up commits after the core implementation were included in this release range. - Downstream testing CI changes by @Samuel-amap in [#154](#154) - AirSpeedVelocity.jl benchmarks by @Samuel-amap in [#155](#155) - Fix #144 and add to tests by @Samuel-amap in [#156](#156) - Remove windows and mac from the .yml by @Samuel-amap in [#157](#157) - Filter out empty status vectors by @Samuel-amap in [#160](#160) - Streamline graphsim initialisation by @Samuel-amap in [#169](#169) - Small addendum to the list of PlantSimEngine Julia errors, also used by @Samuel-amap in [#172](#172) - Bump actions/checkout from 4 to 6 by @dependabot[bot] in [#167](#167) - Use dependabot action and remove compathelper by @VEZY in [#175](#175) - Unified interface for model mapping by @VEZY in [#177](#177) - `ModelMapping` validations at construction by @VEZY in [#178](#178) - Add `PlantSimEngine.output_policy` trait by @VEZY in [#179](#179) - Upgrade to MultiScaleTreeGraph v0.15.0 by @VEZY in [#180](#180) - Fix world age issues by @VEZY in [#184](#184) - Implement multirate simulations - take 3 by @VEZY in [#174](#174) **Merged pull requests:** - Downstream testing CI changes (#154) (@Samuel-amap) - AirSpeedVelocity.jl benchmarks (#155) (@Samuel-amap) - Fix #144 and add to tests (#156) (@Samuel-amap) - Remove windows and mac from the .yml (#157) (@Samuel-amap) - Filter out empty status vectors (#160) (@Samuel-amap) - Bump actions/checkout from 4 to 6 (#167) (@dependabot[bot]) - Streamline graphsim initialisation (#169) (@Samuel-amap) - Small addendum to the list of PlantSimEngine Julia errors, also used … (#172) (@Samuel-amap) - Implement multirate simulations - take 3 (#174) (@VEZY) - Use dependabot action and remove compathelper (#175) (@VEZY) - Unified interface for model mapping (#177) (@VEZY) - `ModelMapping` validations at construction (#178) (@VEZY) - Add `PlantSimEngine.output_policy` trait (#179) (@VEZY) - Upgrade to MultiScaleTreeGraph v0.15.0 (#180) (@VEZY) - Bump julia-actions/cache from 2 to 3 (#183) (@dependabot[bot]) - Fix world age issues (#184) (@VEZY) **Closed issues:** - Parrallel computations (#21) - Add parallel computations for time-steps in MTG (not just over nodes) (#25) - Run independent models in parallel first, even if other models are not independent (#40) - Test FloatTracker.jl (#48) - Improve model call to help the compiler (#54) - Document variable naming (#65) - Remove type instabilities and unnecessary GC allocations (#73) - Explicit updating of a variable (variable as input _and_ output) (#80) - Automating IsObjectIndependent (#97) - Handle models that update variables (variable in both inputs and outputs) (#107) - Non-steady-state models (#114) - Dependency graph traversal (#118) - Fix issue when no organ is created for a scale (#138) - Use AirSpeedVelocity for Benchmarks (#142) - Improve the dependency testing system: avoid relying on a dev branch in the repositories. (#143) - Error with TimeStepTable of one (#144) - World-age changes in 1.12 (#158) - Fix world age issue when generating models (#163)
[Diff since v0.13.0](v0.13.0...v0.13.1) Fixing performance regressions: * Add dependency graph into model list by @VEZY in #149 * Fixing #146: performance regression by @VEZY in #147 **Full Changelog**: v0.13.0...v0.14.0 **Merged pull requests:** - Fixing #146: performance regression (#147) (@VEZY) - Add dependency graph into model list (#149) (@VEZY) **Closed issues:** - Add dependency tree in the ModelList (#29) - Change default output structure (#123) - Improve performance of inputs pre-allocation step in `run!` (#146) - Improve performance of dependency graph creation (#148)
[Diff since v0.12.0](v0.12.0...v0.13.0) PRs: * Multiscale outputs struct rework by @Samuel-amap in #134 * Dev by @Samuel-amap in #137 Summary: The outputs are now stored differently during the simulation for better performance. You now need to call `convert_outputs` on the outputs of the simulation, *e.g.* if the simulation outputs are stored `outputs_sim`: ```julia df_dict = convert_outputs(outputs_sim, DataFrame) ``` `df_dict` will be a dictionary of dataframes, with the scale as the key and the results for this scale as the value. **Full Changelog**: v0.12.0...v0.13.0 **Merged pull requests:** - Multiscale outputs struct rework (#134) (@Samuel-amap) - Dev (#137) (@Samuel-amap) **Closed issues:** - ModelList -> better manage models that takes values from the previous time-step (#85) - BoundsError with a single model and several Weather timesteps (#86) - XPalm Github action for testing (#90) - Non-obvious Julia errors (#92) - Documentation improvements (#93) - Collapse similar codepaths, and create a mapping for single-scale simulations (#101) - No outputs when simulating a mapping with one meteo timestep (#105) - Multiscale : outputs not saved when dependency graph only has one depth level (#111)
[Diff since v0.11.2](v0.11.2...v0.11.3) **Merged pull requests:** - Incomplete working version of a modellist to mapping conversion function (#122) (@Samuel-amap) **Closed issues:** - API : enable passing in a vector providing values per timestep in multi-scale modelling (#117)
PreviousNext