From b107e129ccb99b26ee493131d45d175af294a753 Mon Sep 17 00:00:00 2001 From: Herman Sletmoen Date: Sun, 2 Feb 2025 11:56:16 +0100 Subject: [PATCH] Add @description to @mtkmodel --- docs/src/basics/MTKLanguage.md | 8 ++++++++ docs/src/tutorials/acausal_components.md | 2 ++ src/systems/model_parsing.jl | 16 ++++++++++++++-- test/model_parsing.jl | 3 ++- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/docs/src/basics/MTKLanguage.md b/docs/src/basics/MTKLanguage.md index 06250f90b4..2bcec99b6a 100644 --- a/docs/src/basics/MTKLanguage.md +++ b/docs/src/basics/MTKLanguage.md @@ -23,6 +23,7 @@ equations. `@mtkmodel` definition contains begin blocks of + - `@description`: for describing the whole system with a human-readable string - `@components`: for listing sub-components of the system - `@constants`: for declaring constants - `@defaults`: for passing `defaults` to ODESystem @@ -42,6 +43,7 @@ using ModelingToolkit using ModelingToolkit: t @mtkmodel ModelA begin + @description "A component with parameters `k` and `k_array`." @parameters begin k k_array[1:2] @@ -49,6 +51,7 @@ using ModelingToolkit: t end @mtkmodel ModelB begin + @description "A component with parameters `p1` and `p2`." @parameters begin p1 = 1.0, [description = "Parameter of ModelB"] p2 = 1.0, [description = "Parameter of ModelB"] @@ -56,6 +59,7 @@ end end @mtkmodel ModelC begin + @description "A bigger system that contains many more things." @icon "https://github.com/SciML/SciMLDocs/blob/main/docs/src/assets/logo.png" @constants begin c::Int = 1, [description = "Example constant."] @@ -91,6 +95,10 @@ end end ``` +#### `@description` + +A documenting `String` that summarizes and explains what the model is. + #### `@icon` An icon can be embedded in 3 ways: diff --git a/docs/src/tutorials/acausal_components.md b/docs/src/tutorials/acausal_components.md index 096b576d29..b97500a3e9 100644 --- a/docs/src/tutorials/acausal_components.md +++ b/docs/src/tutorials/acausal_components.md @@ -84,6 +84,7 @@ end end @mtkmodel RCModel begin + @description "A circuit with a constant voltage source, resistor and capacitor connected in series." @components begin resistor = Resistor(R = 1.0) capacitor = Capacitor(C = 1.0) @@ -251,6 +252,7 @@ make all of our parameter values 1.0. As `resistor`, `capacitor`, `source` lists ```@example acausal @mtkmodel RCModel begin + @description "A circuit with a constant voltage source, resistor and capacitor connected in series." @components begin resistor = Resistor(R = 1.0) capacitor = Capacitor(C = 1.0) diff --git a/src/systems/model_parsing.jl b/src/systems/model_parsing.jl index 52e46597bf..1976e89aa2 100644 --- a/src/systems/model_parsing.jl +++ b/src/systems/model_parsing.jl @@ -109,11 +109,13 @@ function _model_macro(mod, name, expr, isconnector) gui_metadata = isassigned(icon) > 0 ? GUIMetadata(GlobalRef(mod, name), icon[]) : GUIMetadata(GlobalRef(mod, name)) + description = get(dict, :description, "") + @inline pop_structure_dict!.( Ref(dict), [:constants, :defaults, :kwargs, :structural_parameters]) sys = :($ODESystem($(flatten_equations)(equations), $iv, variables, parameters; - name, systems, gui_metadata = $gui_metadata, defaults)) + name, description = $description, systems, gui_metadata = $gui_metadata, defaults)) if length(ext) == 0 push!(exprs.args, :(var"#___sys___" = $sys)) @@ -598,7 +600,9 @@ function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, sps, c_evts, d_evts, dict, mod, arg, kwargs, where_types) mname = arg.args[1] body = arg.args[end] - if mname == Symbol("@components") + if mname == Symbol("@description") + parse_description!(body, dict) + elseif mname == Symbol("@components") parse_components!(exprs, comps, dict, body, kwargs) elseif mname == Symbol("@extend") parse_extend!(exprs, ext, dict, mod, body, kwargs) @@ -1156,6 +1160,14 @@ function parse_icon!(body::Symbol, dict, icon, mod) parse_icon!(getfield(mod, body), dict, icon, mod) end +function parse_description!(body, dict) + if body isa String + dict[:description] = body + else + error("Invalid description string $body") + end +end + ### Parsing Components: function component_args!(a, b, varexpr, kwargs; index_name = nothing) diff --git a/test/model_parsing.jl b/test/model_parsing.jl index baaa4651bf..559992d7c5 100644 --- a/test/model_parsing.jl +++ b/test/model_parsing.jl @@ -127,6 +127,7 @@ end end @mtkmodel RC begin + @description "An RC circuit." @structural_parameters begin R_val = 10u"Ω" C_val = 10u"F" @@ -139,7 +140,6 @@ end constant = Constant(; k = k_val) ground = MyMockModule.Ground() end - @equations begin connect(constant.output, source.V) connect(source.p, resistor.p) @@ -157,6 +157,7 @@ sol = solve(prob) defs = ModelingToolkit.defaults(rc) @test sol[rc.capacitor.v, end] ≈ defs[rc.constant.k] resistor = getproperty(rc, :resistor; namespace = false) +@test ModelingToolkit.description(rc) == "An RC circuit." @test getname(rc.resistor) === getname(resistor) @test getname(rc.resistor.R) === getname(resistor.R) @test getname(rc.resistor.v) === getname(resistor.v)