Skip to content

Commit 9ff8d74

Browse files
authored
Merge pull request #2319 from ven-k/vkb/if-else-ladder
Support conditional statements in `@mtkmodel`
2 parents 32654d6 + 8b75e01 commit 9ff8d74

File tree

3 files changed

+745
-89
lines changed

3 files changed

+745
-89
lines changed

docs/src/basics/MTKModel_Connector.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,104 @@ Dict{Symbol, Any} with 7 entries:
251251
:extend => Any[[:p2, :p1], Symbol("#mtkmodel__anonymous__ModelB"), :ModelB]
252252
:equations => ["model_a.k ~ f(v)"]
253253
```
254+
255+
### Using conditional statements
256+
257+
#### Conditional elements of the system
258+
259+
Both `@mtkmodel` and `@connector` support conditionally defining parameters,
260+
variables, equations, and components.
261+
262+
The if-elseif-else statements can be used inside `@equations`, `@parameters`,
263+
`@variables`, `@components`.
264+
265+
```@example branches-in-components
266+
using ModelingToolkit
267+
268+
@mtkmodel C begin end
269+
270+
@mtkmodel BranchInsideTheBlock begin
271+
@structural_parameters begin
272+
flag = true
273+
end
274+
@parameters begin
275+
if flag
276+
a1
277+
else
278+
a2
279+
end
280+
end
281+
@components begin
282+
if flag
283+
sys1 = C()
284+
else
285+
sys2 = C()
286+
end
287+
end
288+
end
289+
```
290+
291+
Alternatively, the `@equations`, `@parameters`, `@variables`, `@components` can be
292+
used inside the if-elseif-else statements.
293+
294+
```@example branches-in-components
295+
@mtkmodel BranchOutsideTheBlock begin
296+
@structural_parameters begin
297+
flag = true
298+
end
299+
if flag
300+
@parameters begin
301+
a1
302+
end
303+
@components begin
304+
sys1 = C()
305+
end
306+
@equations begin
307+
a1 ~ 0
308+
end
309+
else
310+
@parameters begin
311+
a2
312+
end
313+
@equations begin
314+
a2 ~ 0
315+
end
316+
end
317+
end
318+
```
319+
320+
The conditional parts are reflected in the `structure`. For `BranchOutsideTheBlock`, the metadata is:
321+
322+
```julia
323+
julia> BranchOutsideTheBlock.structure
324+
Dict{Symbol, Any} with 5 entries:
325+
:components => Any[(:if, :flag, [[:sys1, :C]], Any[])]
326+
:kwargs => Dict{Symbol, Any}(:flag=>true)
327+
:independent_variable => t
328+
:parameters => Dict{Symbol, Dict{Symbol, Any}}(:a1=>Dict(:condition=>(:if, :flag, Dict{Symbol, Any}(:kwargs => Dict{Any, Any}(:a1 => nothing), :parameters => Any[Dict{Symbol, Dict{Symbol, Any}}(:a1 => Dict())]), Dict{Symbol, Any}(:kwargs => Dict{Any, Any}(:a2 => nothing), :parameters => Any[Dict{Symbol, Dict{Symbol, Any}}(:a2 => Dict())]))
329+
:equations => Any[(:if, :flag, ["a1 ~ 0"], ["a2 ~ 0"])]
330+
```
331+
332+
Conditional entries are entered in the format of `(branch, condition, [case when it is true], [case when it is false])`;
333+
where `branch` is either `:if` or `:elseif`.<br>
334+
The `[case when it is false]` is either an empty vector or `nothing` when only if branch is
335+
present; it is a vector or dictionary whenever else branch is present; it is a conditional tuple
336+
whenever elseif branches are present.
337+
338+
For the conditional components and equations these condition tuples are added
339+
directly, while for parameters and variables these are added as `:condition` metadata.
340+
341+
#### Conditional initial guess of symbolic variables
342+
343+
Using ternary operator or if-elseif-else statement, conditional initial guesses can be assigned to parameters and variables.
344+
345+
```@example branches-in-components
346+
@mtkmodel DefaultValues begin
347+
@structural_parameters begin
348+
flag = true
349+
end
350+
@parameters begin
351+
p = flag ? 1 : 2
352+
end
353+
end
354+
```

0 commit comments

Comments
 (0)