Skip to content

Commit bd63ee7

Browse files
Merge branch 'master' into myb/unit
2 parents 1a8b723 + df4b7e5 commit bd63ee7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1654
-283
lines changed

.github/dependabot.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@ updates:
55
directory: "/" # Location of package manifests
66
schedule:
77
interval: "weekly"
8+
ignore:
9+
- dependency-name: "crate-ci/typos"
10+
update-types: ["version-update:semver-patch"]

.github/workflows/SpellCheck.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: Spell Check
2+
3+
on: [pull_request]
4+
5+
jobs:
6+
typos-check:
7+
name: Spell Check with Typos
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Checkout Actions Repository
11+
uses: actions/checkout@v4
12+
- name: Check spelling
13+
uses: crate-ci/typos@v1.16.25

.github/workflows/ci.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@ jobs:
2121
test:
2222
runs-on: ubuntu-latest
2323
strategy:
24+
fail-fast: false
2425
matrix:
2526
group:
26-
- All
27+
- InterfaceI
28+
- InterfaceII
29+
- Extensions
2730
version:
2831
- '1'
2932
steps:
@@ -43,6 +46,8 @@ jobs:
4346
${{ runner.os }}-
4447
- uses: julia-actions/julia-buildpkg@v1
4548
- uses: julia-actions/julia-runtest@v1
49+
env:
50+
GROUP: ${{ matrix.group }}
4651
- uses: julia-actions/julia-processcoverage@v1
4752
- uses: codecov/codecov-action@v3
4853
with:

.typos.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[default.extend-words]
2+
nin = "nin"
3+
nd = "nd"
4+
Strat = "Strat"
5+
eles = "eles"
6+
ser = "ser"

Project.toml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ModelingToolkit"
22
uuid = "961ee093-0014-501f-94e3-6117800e7a78"
33
authors = ["Yingbo Ma <mayingbo5@gmail.com>", "Chris Rackauckas <accounts@chrisrackauckas.com> and contributors"]
4-
version = "8.72.2"
4+
version = "8.75.0"
55

66
[deps]
77
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
@@ -69,6 +69,7 @@ DataStructures = "0.17, 0.18"
6969
DiffEqBase = "6.103.0"
7070
DiffEqCallbacks = "2.16"
7171
DiffRules = "0.1, 1.0"
72+
Distributed = "1"
7273
Distributions = "0.23, 0.24, 0.25"
7374
DocStringExtensions = "0.7, 0.8, 0.9"
7475
DomainSets = "0.6"
@@ -77,26 +78,31 @@ ForwardDiff = "0.10.3"
7778
FunctionWrappersWrappers = "0.1"
7879
Graphs = "1.5.2"
7980
IfElse = "0.1"
81+
InteractiveUtils = "1"
8082
JuliaFormatter = "1"
8183
JumpProcesses = "9.1"
8284
LabelledArrays = "1.3"
8385
Latexify = "0.11, 0.12, 0.13, 0.14, 0.15, 0.16"
86+
Libdl = "1"
87+
LinearAlgebra = "1"
8488
MLStyle = "0.4.17"
8589
MacroTools = "0.5"
8690
NaNMath = "0.3, 1"
8791
OrdinaryDiffEq = "6"
8892
PrecompileTools = "1"
89-
RecursiveArrayTools = "2.3"
93+
RecursiveArrayTools = "2.3, 3"
9094
Reexport = "0.2, 1"
9195
RuntimeGeneratedFunctions = "0.5.9"
9296
SciMLBase = "2.0.1"
97+
Serialization = "1"
9398
Setfield = "0.7, 0.8, 1"
94-
SimpleNonlinearSolve = "0.1.0"
99+
SimpleNonlinearSolve = "0.1.0, 1"
100+
SparseArrays = "1"
95101
SpecialFunctions = "0.7, 0.8, 0.9, 0.10, 1.0, 2"
96102
StaticArrays = "0.10, 0.11, 0.12, 1.0"
97-
SymbolicIndexingInterface = "0.1, 0.2"
103+
SymbolicIndexingInterface = "0.3.1"
98104
SymbolicUtils = "1.0"
99-
Symbolics = "5.0"
105+
Symbolics = "5.7"
100106
URIs = "1"
101107
UnPack = "0.1, 1.0"
102108
Unitful = "1.1"
@@ -105,7 +111,6 @@ julia = "1.9"
105111
[extras]
106112
AmplNLWriter = "7c4d4715-977e-5154-bfe0-e096adeac482"
107113
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
108-
BifurcationKit = "0f109fa4-8a5d-4b75-95aa-f515264e7665"
109114
ControlSystemsMTK = "687d7614-c7e5-45fc-bfc3-9ee385575c88"
110115
DeepDiffs = "ab62b9b5-e342-54a8-a765-a90f495de1a6"
111116
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
@@ -116,6 +121,7 @@ NonlinearSolve = "8913a72c-1f9b-4ce2-8d82-65094dcecaec"
116121
Optimization = "7f7a1694-90dd-40f0-9382-eb1efda571ba"
117122
OptimizationMOI = "fd9f6733-72f4-499f-8506-86b2bdd0dea1"
118123
OptimizationOptimJL = "36348300-93cb-4f02-beb5-3c3902f8871e"
124+
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
119125
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
120126
ReferenceTests = "324d217c-45ce-50fc-942e-d289b448e8cf"
121127
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
@@ -128,4 +134,4 @@ Sundials = "c3572dad-4567-51f8-b174-8c6c989267f4"
128134
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
129135

130136
[targets]
131-
test = ["AmplNLWriter", "BenchmarkTools", "BifurcationKit", "ControlSystemsMTK", "NonlinearSolve", "ForwardDiff", "Ipopt", "Ipopt_jll", "ModelingToolkitStandardLibrary", "Optimization", "OptimizationOptimJL", "OptimizationMOI", "Random", "ReferenceTests", "SafeTestsets", "StableRNGs", "Statistics", "SteadyStateDiffEq", "Test", "StochasticDiffEq", "Sundials", "StochasticDelayDiffEq"]
137+
test = ["AmplNLWriter", "BenchmarkTools", "ControlSystemsMTK", "NonlinearSolve", "ForwardDiff", "Ipopt", "Ipopt_jll", "ModelingToolkitStandardLibrary", "Optimization", "OptimizationOptimJL", "OptimizationMOI", "Random", "ReferenceTests", "SafeTestsets", "StableRNGs", "Statistics", "SteadyStateDiffEq", "Test", "StochasticDiffEq", "Sundials", "StochasticDelayDiffEq", "Pkg"]

docs/Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ Distributions = "0.25"
2727
Documenter = "1"
2828
ModelingToolkit = "8.33"
2929
ModelingToolkitDesigner = "1"
30-
NonlinearSolve = "0.3, 1, 2"
30+
NonlinearSolve = "0.3, 1, 2, 3"
3131
Optim = "1.7"
3232
Optimization = "3.9"
3333
OptimizationOptimJL = "0.1"
3434
OrdinaryDiffEq = "6.31"
3535
Plots = "1.36"
3636
StochasticDiffEq = "6"
37-
StructuralIdentifiability = "0.4"
37+
StructuralIdentifiability = "0.4, 0.5"
3838
SymbolicUtils = "1"
3939
Symbolics = "5"
4040
Unitful = "1.12"

docs/src/basics/AbstractSystem.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ patterns via an abstract interpretation without requiring differentiation.
121121

122122
At the end, the system types have `DEProblem` constructors, like `ODEProblem`,
123123
which allow for directly generating the problem types required for numerical
124-
methods. The first argument is always the `AbstractSystem`, and the proceding
124+
methods. The first argument is always the `AbstractSystem`, and the next
125125
arguments match the argument order of their original constructors. Whenever an
126126
array would normally be provided, such as `u0` the initial condition of an
127127
`ODEProblem`, it is instead replaced with a variable map, i.e., an array of

docs/src/basics/Linearization.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ If linearization is to be performed around multiple operating points, the simpli
5151

5252
## Symbolic linearization
5353

54-
The function [`ModelingToolkit.linearize_symbolic`](@ref) works simiar to [`ModelingToolkit.linearize`](@ref) but returns symbolic rather than numeric Jacobians. Symbolic linearization have several limitations and no all systems that can be linearized numerically can be linearized symbolically.
54+
The function [`ModelingToolkit.linearize_symbolic`](@ref) works similar to [`ModelingToolkit.linearize`](@ref) but returns symbolic rather than numeric Jacobians. Symbolic linearization have several limitations and no all systems that can be linearized numerically can be linearized symbolically.
5555

5656
## Input derivatives
5757

docs/src/basics/MTKModel_Connector.md

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ equations.
2929
- `@icon` : for embedding the model icon
3030
- `@parameters`: for specifying the symbolic parameters
3131
- `@structural_parameters`: for specifying non-symbolic parameters
32-
- `@variables`: for specifing the states
32+
- `@variables`: for specifying the states
3333

3434
Let's explore these in more detail with the following example:
3535

@@ -104,7 +104,7 @@ end
104104

105105
#### `@structural_parameters` begin block
106106

107-
- This block is for non symbolic input arguements. These are for inputs that usually are not meant to be part of components; but influence how they are defined. One can list inputs like boolean flags, functions etc... here.
107+
- This block is for non symbolic input arguments. These are for inputs that usually are not meant to be part of components; but influence how they are defined. One can list inputs like boolean flags, functions etc... here.
108108
- Whenever default values are specified, unlike parameters/variables, they are reflected in the keyword argument list.
109109

110110
#### `@parameters` and `@variables` begin block
@@ -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+
```

docs/src/basics/Variable_metadata.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,19 @@ hasbounds(u)
8383
getbounds(u)
8484
```
8585

86+
## Guess
87+
88+
Specify an initial guess for custom initial conditions of an `ODESystem`.
89+
90+
```@example metadata
91+
@variables u [guess = 1]
92+
hasguess(u)
93+
```
94+
95+
```@example metadata
96+
getguess(u)
97+
```
98+
8699
## Mark input as a disturbance
87100

88101
Indicate that an input is not available for control, i.e., it's a disturbance input.

docs/src/tutorials/bifurcation_diagram_computation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# [Bifurcation Diagrams](@id bifurcation_diagrams)
22

3-
Bifurcation diagrams describes how, for a dynamic system, the quantity and quality of its steady states changes with a parameter's value. These can be computed through the [BifurcationKit.jl](https://github.com/bifurcationkit/BifurcationKit.jl) package. ModelingToolkit provides a simple interface for creating BifurcationKit compatible `BifurcationProblem`s from `NonlinearSystem`s and `ODESystem`s. All teh features provided by BifurcationKit can then be applied to these systems. This tutorial provides a brief introduction for these features, with BifurcationKit.jl providing [a more extensive documentation](https://bifurcationkit.github.io/BifurcationKitDocs.jl/stable/).
3+
Bifurcation diagrams describes how, for a dynamic system, the quantity and quality of its steady states changes with a parameter's value. These can be computed through the [BifurcationKit.jl](https://github.com/bifurcationkit/BifurcationKit.jl) package. ModelingToolkit provides a simple interface for creating BifurcationKit compatible `BifurcationProblem`s from `NonlinearSystem`s and `ODESystem`s. All the features provided by BifurcationKit can then be applied to these systems. This tutorial provides a brief introduction for these features, with BifurcationKit.jl providing [a more extensive documentation](https://bifurcationkit.github.io/BifurcationKitDocs.jl/stable/).
44

55
### Creating a `BifurcationProblem`
66

docs/src/tutorials/domain_connections.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ nothing #hide
205205

206206
![actsys2](https://github.com/SciML/ModelingToolkit.jl/assets/40798837/8ed50035-f6ac-48cb-a585-1ef415154a02)
207207

208-
After running `structural_simplify()` on `actsys2`, the defaults will show that `act.port_a.ρ` points to `fluid_a₊ρ` and `act.port_b.ρ` points to `fluid_b₊ρ`. This is a special case, in most cases a hydraulic system will have only 1 fluid, however this simple system has 2 separate domain networks. Therefore, we can connect a single fluid to both networks. This does not interfer with the mathmatical equations of the system, since no states are connected.
208+
After running `structural_simplify()` on `actsys2`, the defaults will show that `act.port_a.ρ` points to `fluid_a₊ρ` and `act.port_b.ρ` points to `fluid_b₊ρ`. This is a special case, in most cases a hydraulic system will have only 1 fluid, however this simple system has 2 separate domain networks. Therefore, we can connect a single fluid to both networks. This does not interfere with the mathematical equations of the system, since no states are connected.
209209

210210
```@example domain
211211
@component function ActuatorSystem1(; name)
@@ -239,7 +239,7 @@ nothing #hide
239239

240240
## Special Connection Cases (`domain_connect()`)
241241

242-
In some cases a component will be defined with 2 connectors of the same domain, but they are not connected. For example the `Restrictor` defined here gives equations to define the behavior of how the 2 connectors `port_a` and `port_b` are physcially connected.
242+
In some cases a component will be defined with 2 connectors of the same domain, but they are not connected. For example the `Restrictor` defined here gives equations to define the behavior of how the 2 connectors `port_a` and `port_b` are physically connected.
243243

244244
```@example domain
245245
@component function Restrictor(; name, p_int)

docs/src/tutorials/ode_modeling.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ plot(solve(prob))
327327

328328
More on this topic may be found in [Composing Models and Building Reusable Components](@ref acausal).
329329

330-
## Inital Guess
330+
## Initial Guess
331331

332332
It is often a good idea to specify reasonable values for the initial state and the
333333
parameters of a model component. Then, these do not have to be explicitly specified when constructing the `ODEProblem`.
@@ -347,7 +347,7 @@ end
347347
```
348348

349349
While defining the model `UnitstepFOLFactory`, an initial guess of 0.0 is assigned to `x(t)` and 1.0 to `τ`.
350-
Additionaly, these initial guesses can be modified while creating instances of `UnitstepFOLFactory` by passing arguements.
350+
Additionally, these initial guesses can be modified while creating instances of `UnitstepFOLFactory` by passing arguments.
351351

352352
```@example ode2
353353
@named fol = UnitstepFOLFactory(; x = 0.1)

ext/MTKBifurcationKitExt.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ struct ObservableRecordFromSolution{S, T}
2020
param_end_idxs::Int64
2121
# The index (in subs_vals) that contain the bifurcation parameter.
2222
bif_par_idx::Int64
23-
# A Vector of pairs (Symbolic => value) with teh default values of all system variables and parameters.
23+
# A Vector of pairs (Symbolic => value) with the default values of all system variables and parameters.
2424
subs_vals::T
2525

2626
function ObservableRecordFromSolution(nsys::NonlinearSystem,
@@ -34,17 +34,17 @@ struct ObservableRecordFromSolution{S, T}
3434
param_end_idxs = state_end_idxs + length(parameters(nsys))
3535

3636
bif_par_idx = state_end_idxs + bif_idx
37-
# Gets the (base) substitution values for states.
37+
# Gets the (base) substitution values for states.
3838
subs_vals_states = Pair.(states(nsys), u0_vals)
39-
# Gets the (base) substitution values for parameters.
39+
# Gets the (base) substitution values for parameters.
4040
subs_vals_params = Pair.(parameters(nsys), p_vals)
41-
# Gets the (base) substitution values for observables.
41+
# Gets the (base) substitution values for observables.
4242
subs_vals_obs = [obs.lhs => substitute(obs.rhs,
4343
[subs_vals_states; subs_vals_params]) for obs in observed(nsys)]
44-
# Sometimes observables depend on other observables, hence we make a second upate to this vector.
44+
# Sometimes observables depend on other observables, hence we make a second update to this vector.
4545
subs_vals_obs = [obs.lhs => substitute(obs.rhs,
4646
[subs_vals_states; subs_vals_params; subs_vals_obs]) for obs in observed(nsys)]
47-
# During the bifurcation process, teh value of some states, parameters, and observables may vary (and are calculated in each step). Those that are not are stored in this vector
47+
# During the bifurcation process, the value of some states, parameters, and observables may vary (and are calculated in each step). Those that are not are stored in this vector
4848
subs_vals = [subs_vals_states; subs_vals_params; subs_vals_obs]
4949

5050
param_end_idxs = state_end_idxs + length(parameters(nsys))
@@ -136,7 +136,7 @@ function BifurcationKit.BifurcationProblem(osys::ODESystem, args...; kwargs...)
136136
nsys = NonlinearSystem([0 ~ eq.rhs for eq in equations(osys)],
137137
states(osys),
138138
parameters(osys);
139-
name = osys.name)
139+
name = nameof(osys))
140140
return BifurcationKit.BifurcationProblem(nsys, args...; kwargs...)
141141
end
142142

0 commit comments

Comments
 (0)