Skip to content

Commit 80091f1

Browse files
authored
Merge branch 'SciML:master' into iss3707
2 parents f9f5257 + 96602e3 commit 80091f1

Some content is hidden

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

60 files changed

+2425
-1435
lines changed

.github/workflows/Downstream.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66
pull_request:
77
paths-ignore:
88
- 'docs/**'
9+
- 'benchmark/**'
910

1011
concurrency:
1112
# Skip intermediate builds: always, but for the master branch and tags.
@@ -26,6 +27,7 @@ jobs:
2627
os: [ubuntu-latest]
2728
package:
2829
- {user: SciML, repo: SciMLBase.jl, group: Downstream}
30+
- {user: SciML, repo: SciMLBase.jl, group: SymbolicIndexingInterface}
2931
- {user: SciML, repo: Catalyst.jl, group: All}
3032
- {user: SciML, repo: CellMLToolkit.jl, group: Core}
3133
- {user: SciML, repo: SBMLToolkit.jl, group: All}

.github/workflows/ReleaseTest.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66
pull_request:
77
paths-ignore:
88
- 'docs/**'
9+
- 'benchmark/**'
910

1011
concurrency:
1112
# Skip intermediate builds: always, but for the master branch and tags.

.github/workflows/Tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ on:
1313
- master
1414
paths-ignore:
1515
- 'docs/**'
16+
- 'benchmark/**'
1617

1718
concurrency:
1819
# Skip intermediate builds: always, but for the master branch.

.github/workflows/benchmark.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@ jobs:
2222
- uses: MilesCranmer/AirspeedVelocity.jl@action-v1
2323
with:
2424
julia-version: "${{ matrix.version }}"
25+
script: "benchmark/benchmarks.jl"
26+
extra-pkgs: "ModelingToolkitStandardLibrary,OrdinaryDiffEqDefault"

Project.toml

Lines changed: 6 additions & 4 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 <[email protected]>", "Chris Rackauckas <[email protected]> and contributors"]
4-
version = "10.2.0"
4+
version = "10.5.0"
55

66
[deps]
77
ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"
@@ -98,7 +98,7 @@ Combinatorics = "1"
9898
CommonSolve = "0.2.4"
9999
Compat = "3.42, 4"
100100
ConstructionBase = "1"
101-
DataInterpolations = "6.4"
101+
DataInterpolations = "7, 8"
102102
DataStructures = "0.17, 0.18"
103103
DeepDiffs = "1"
104104
DelayDiffEq = "5.50"
@@ -129,6 +129,7 @@ LabelledArrays = "1.3"
129129
Latexify = "0.11, 0.12, 0.13, 0.14, 0.15, 0.16"
130130
Libdl = "1"
131131
LinearAlgebra = "1"
132+
LinearSolve = "3"
132133
Logging = "1"
133134
MLStyle = "0.4.17"
134135
ModelingToolkitStandardLibrary = "2.20"
@@ -148,7 +149,7 @@ RecursiveArrayTools = "3.26"
148149
Reexport = "0.2, 1"
149150
RuntimeGeneratedFunctions = "0.5.9"
150151
SCCNonlinearSolve = "1.0.0"
151-
SciMLBase = "2.91.1"
152+
SciMLBase = "2.100.0"
152153
SciMLPublic = "1.0.0"
153154
SciMLStructures = "1.7"
154155
Serialization = "1"
@@ -180,6 +181,7 @@ ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
180181
Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9"
181182
Ipopt_jll = "9cc047cb-c261-5740-88fc-0cf96f7bdcc7"
182183
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
184+
LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae"
183185
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
184186
ModelingToolkitStandardLibrary = "16a59e39-deab-5bd0-87e4-056b12336739"
185187
NonlinearSolve = "8913a72c-1f9b-4ce2-8d82-65094dcecaec"
@@ -205,4 +207,4 @@ Sundials = "c3572dad-4567-51f8-b174-8c6c989267f4"
205207
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
206208

207209
[targets]
208-
test = ["AmplNLWriter", "BenchmarkTools", "BoundaryValueDiffEqMIRK", "BoundaryValueDiffEqAscher", "ControlSystemsBase", "DataInterpolations", "DelayDiffEq", "NonlinearSolve", "ForwardDiff", "Ipopt", "Ipopt_jll", "ModelingToolkitStandardLibrary", "Optimization", "OptimizationOptimJL", "OptimizationMOI", "OrdinaryDiffEq", "OrdinaryDiffEqCore", "OrdinaryDiffEqDefault", "REPL", "Random", "ReferenceTests", "SafeTestsets", "StableRNGs", "Statistics", "SteadyStateDiffEq", "Test", "StochasticDiffEq", "Sundials", "StochasticDelayDiffEq", "Pkg", "JET", "OrdinaryDiffEqNonlinearSolve", "Logging", "OptimizationBase"]
210+
test = ["AmplNLWriter", "BenchmarkTools", "BoundaryValueDiffEqMIRK", "BoundaryValueDiffEqAscher", "ControlSystemsBase", "DataInterpolations", "DelayDiffEq", "NonlinearSolve", "ForwardDiff", "Ipopt", "Ipopt_jll", "ModelingToolkitStandardLibrary", "Optimization", "OptimizationOptimJL", "OptimizationMOI", "OrdinaryDiffEq", "OrdinaryDiffEqCore", "OrdinaryDiffEqDefault", "REPL", "Random", "ReferenceTests", "SafeTestsets", "StableRNGs", "Statistics", "SteadyStateDiffEq", "Test", "StochasticDiffEq", "Sundials", "StochasticDelayDiffEq", "Pkg", "JET", "OrdinaryDiffEqNonlinearSolve", "Logging", "OptimizationBase", "LinearSolve"]

benchmark/Project.toml

Lines changed: 0 additions & 3 deletions
This file was deleted.

benchmark/benchmarks.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using ModelingToolkit, BenchmarkTools
22
using ModelingToolkitStandardLibrary
3-
using ModelingToolkitStandardLibrary.Thermal
3+
using ModelingToolkitStandardLibrary.Electrical
4+
using ModelingToolkitStandardLibrary.Mechanical.Rotational
5+
using ModelingToolkitStandardLibrary.Blocks
46
using OrdinaryDiffEqDefault
57

68
const SUITE = BenchmarkGroup()
@@ -51,4 +53,4 @@ tspan = (0.0, 6.0)
5153
SUITE["ODEProblem"] = @benchmarkable ODEProblem($model, $u0, $tspan)
5254

5355
prob = ODEProblem(model, u0, tspan)
54-
SUITE["init"] = init($prob)
56+
SUITE["init"] = @benchmarkable init($prob)

docs/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
3535
Attractors = "1.24"
3636
BenchmarkTools = "1.3"
3737
BifurcationKit = "0.4"
38-
CairoMakie = "0.13"
38+
CairoMakie = "0.13, 0.15"
3939
CommonSolve = "0.2"
4040
DataInterpolations = "6.5, 8"
4141
DiffEqDevTools = "2"

docs/src/API/codegen.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ ModelingToolkit.generate_constraint_hessian
2121
ModelingToolkit.generate_control_jacobian
2222
ModelingToolkit.build_explicit_observed_function
2323
ModelingToolkit.generate_control_function
24+
ModelingToolkit.generate_update_A
25+
ModelingToolkit.generate_update_b
2426
```
2527

2628
For functions such as jacobian calculation which require symbolic computation, there
@@ -42,6 +44,7 @@ ModelingToolkit.cost_hessian_sparsity
4244
ModelingToolkit.calculate_constraint_jacobian
4345
ModelingToolkit.calculate_constraint_hessian
4446
ModelingToolkit.calculate_control_jacobian
47+
ModelingToolkit.calculate_A_b
4548
```
4649

4750
All code generation eventually calls `build_function_wrapper`.

docs/src/API/dynamic_opt.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
### Solvers
1+
# [Dynamic Optimization Solvers](@id dynamic_opt_api)
22

33
Currently 4 backends are exposed for solving dynamic optimization problems using collocation: JuMP, InfiniteOpt, CasADi, and Pyomo.
44

docs/src/API/problems.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ SciMLBase.DiscreteProblem
2929
SciMLBase.ImplicitDiscreteProblem
3030
```
3131

32-
## Nonlinear systems
32+
## Linear and Nonlinear systems
3333

3434
```@docs
3535
SciMLBase.NonlinearFunction
@@ -41,6 +41,7 @@ SciMLBase.IntervalNonlinearFunction
4141
SciMLBase.IntervalNonlinearProblem
4242
ModelingToolkit.HomotopyContinuationProblem
4343
SciMLBase.HomotopyNonlinearFunction
44+
SciMLBase.LinearProblem
4445
```
4546

4647
## Optimization and optimal control

docs/src/basics/FAQ.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ are similarly undocumented. Following is the list of behaviors that should be re
2727
parameter with the given index.
2828
- `setindex!(::MTKParameters, value, ::ParameterIndex)` can be used to set the value of a
2929
parameter with the given index.
30-
- `parameter_values(sys, sym)` will return a `ParameterIndex` object if `sys` has been
30+
- `parameter_index(sys, sym)` will return a `ParameterIndex` object if `sys` has been
3131
`complete`d (through `mtkcompile`, `complete` or `@mtkcompile`).
3232
- `copy(::MTKParameters)` is defined and duplicates the parameter object, including the
3333
memory used by the underlying buffers.

docs/src/examples/perturbation.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,13 @@ eqs_pert = taylor_coeff(eq_pert, ϵ, 0:2)
9393
We solve and plot it as in the previous example, and compare the solution with $ϵ=0.1$ to the exact solution $x(t, ϵ) = e^{-ϵ t} \sin(\sqrt{(1-ϵ^2)}\,t) / \sqrt{1-ϵ^2}$ of the unperturbed equation:
9494

9595
```@example perturbation
96-
u0 = Dict([unknowns(sys) .=> 0.0; D(y[0]) => 1.0]) # nonzero initial velocity
96+
u0 = [y[0] => 0.0, y[1] => 0.0, y[2] => 0.0, D(y[0]) => 1.0, D(y[1]) => 0.0, D(y[2]) => 0.0] # nonzero initial velocity
9797
prob = ODEProblem(sys, u0, (0.0, 50.0))
9898
sol = solve(prob)
9999
plot(sol, idxs = substitute(x_series, ϵ => 0.1); label = "Perturbative (ϵ=0.1)")
100100
101101
x_exact(t, ϵ) = exp(-ϵ * t) * sin(√(1 - ϵ^2) * t) / √(1 - ϵ^2)
102+
@assert isapprox(sol(π/2; idxs = substitute(x_series, ϵ => 0.1)), x_exact(π/2, 0.1); atol = 1e-2) # compare around 1st peak # hide
102103
plot!(sol.t, x_exact.(sol.t, 0.1); label = "Exact (ϵ=0.1)")
103104
```
104105

src/ModelingToolkit.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ include("systems/index_cache.jl")
161161
include("systems/parameter_buffer.jl")
162162
include("systems/abstractsystem.jl")
163163
include("systems/model_parsing.jl")
164+
include("systems/connectiongraph.jl")
164165
include("systems/connectors.jl")
165166
include("systems/state_machines.jl")
166167
include("systems/analysis_points.jl")
@@ -188,6 +189,7 @@ include("problems/jumpproblem.jl")
188189
include("problems/initializationproblem.jl")
189190
include("problems/sccnonlinearproblem.jl")
190191
include("problems/bvproblem.jl")
192+
include("problems/linearproblem.jl")
191193

192194
include("modelingtoolkitize/common.jl")
193195
include("modelingtoolkitize/odeproblem.jl")

src/deprecations.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,5 +175,5 @@ macro brownian(xs...)
175175
return quote
176176
Base.depwarn("`@brownian` is deprecated. Use `@brownians` instead", :brownian_macro)
177177
$(@__MODULE__).@brownians $(xs...)
178-
end
178+
end |> esc
179179
end

src/discretedomain.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
using Symbolics: Operator, Num, Term, value, recursive_hasoperator
22

3+
"""
4+
$(TYPEDSIGNATURES)
5+
6+
Trait to be implemented for operators which determines whether application of the operator
7+
generates a semantically different variable or not. For example, `Differential` and `Shift`
8+
are not transparent but `Sample` and `Hold` are. Defaults to `false` if not implemented.
9+
"""
10+
is_transparent_operator(x) = is_transparent_operator(typeof(x))
11+
is_transparent_operator(::Type) = false
12+
313
"""
414
function SampleTime()
515
@@ -128,6 +138,8 @@ struct Sample <: Operator
128138
Sample(clock::Union{TimeDomain, InferredTimeDomain} = InferredDiscrete()) = new(clock)
129139
end
130140

141+
is_transparent_operator(::Type{Sample}) = true
142+
131143
function Sample(arg::Real)
132144
arg = unwrap(arg)
133145
if symbolic_type(arg) == NotSymbolic()
@@ -179,6 +191,9 @@ cont_x = Hold()(disc_x)
179191
"""
180192
struct Hold <: Operator
181193
end
194+
195+
is_transparent_operator(::Type{Hold}) = true
196+
182197
(D::Hold)(x) = Term{symtype(x)}(D, Any[x])
183198
(D::Hold)(x::Num) = Num(D(value(x)))
184199
SymbolicUtils.promote_symtype(::Hold, x) = x

src/linearization.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ function linearization_function(sys::AbstractSystem, inputs,
4545
warn_initialize_determined = true,
4646
guesses = Dict(),
4747
warn_empty_op = true,
48+
t = 0.0,
4849
kwargs...)
4950
op = Dict(op)
5051
if isempty(op) && warn_empty_op
@@ -73,7 +74,7 @@ function linearization_function(sys::AbstractSystem, inputs,
7374
end
7475

7576
prob = ODEProblem{true, SciMLBase.FullSpecialize}(
76-
sys, merge(op, anydict(p)), (nothing, nothing); allow_incomplete = true,
77+
sys, merge(op, anydict(p)), (t, t); allow_incomplete = true,
7778
algebraic_only = true, guesses)
7879
u0 = state_values(prob)
7980

@@ -753,7 +754,7 @@ function linearize(sys, inputs, outputs; op = Dict(), t = 0.0,
753754
inputs,
754755
outputs;
755756
zero_dummy_der,
756-
op,
757+
op, t,
757758
kwargs...)
758759
mats, extras = linearize(ssys, lin_fun; op, t, allow_input_derivatives)
759760
mats, ssys, extras

src/modelingtoolkitize/common.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ end
4646
"""
4747
$(TYPEDSIGNATURES)
4848
49-
Return a symbolic state for the given proble `prob.`. `t` is the independent variable.
49+
Return a symbolic state for the given problem `prob.`. `t` is the independent variable.
5050
`u_names` optionally contains the names to use for the created symbolic variables.
5151
"""
5252
function construct_vars(prob, t, u_names = nothing)
@@ -287,7 +287,7 @@ end
287287
"""
288288
$(TYPEDSIGNATURES)
289289
290-
Return a symbolic parameter object for the given proble `prob.`. `t` is the independent
290+
Return a symbolic parameter object for the given problem `prob.`. `t` is the independent
291291
variable. `p_names` optionally contains the names to use for the created symbolic
292292
variables.
293293
"""
@@ -319,7 +319,7 @@ end
319319
$(TYPEDSIGNATURES)
320320
321321
Given the differential operator `D`, mass matrix `mm` and ordered list of unknowns `vars`,
322-
return the list of
322+
return the list of
323323
"""
324324
function lhs_from_mass_matrix(D, mm, vars)
325325
var_set = Set(vars)

src/problems/compatibility.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,12 @@ function check_no_equations(sys::System, T)
169169
"""))
170170
end
171171
end
172+
173+
function check_affine(sys::System, T)
174+
if !isaffine(sys)
175+
throw(SystemCompatibilityError("""
176+
A non-affine system cannot be used to construct a `$T`. Consider a
177+
`NonlinearProblem` instead.
178+
"""))
179+
end
180+
end

src/problems/daeproblem.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ end
7272
eval_module, check_compatibility, implicit_dae = true, expression, kwargs...)
7373

7474
kwargs = process_kwargs(sys; expression, callback, eval_expression, eval_module,
75-
kwargs...)
75+
op, kwargs...)
7676

7777
diffvars = collect_differential_variables(sys)
7878
sts = unknowns(sys)

src/problems/ddeproblem.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ end
6666
end
6767

6868
kwargs = process_kwargs(
69-
sys; expression, callback, eval_expression, eval_module, kwargs...)
69+
sys; expression, callback, eval_expression, eval_module, op, kwargs...)
7070
args = (; f, u0, h, tspan, p)
7171

7272
return maybe_codegen_scimlproblem(expression, DDEProblem{iip}, args; kwargs...)

src/problems/docs.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,3 +391,32 @@ $PROBLEM_INTERNALS_HEADER
391391
392392
$PROBLEM_INTERNAL_KWARGS
393393
""" SciMLBase.IntervalNonlinearProblem
394+
395+
@doc """
396+
SciMLBase.LinearProblem(sys::System, op; kwargs...)
397+
SciMLBase.LinearProblem{iip}(sys::System, op; kwargs...)
398+
399+
Build a `LinearProblem` given a system `sys` and operating point `op`. `iip` is a boolean
400+
indicating whether the problem should be in-place. The operating point should be an
401+
iterable collection of key-value pairs mapping variables/parameters in the system to the
402+
(initial) values they should take in `LinearProblem`. Any values not provided will
403+
fallback to the corresponding default (if present).
404+
405+
Note that since `u0` is optional for `LinearProblem`, values of unknowns do not need to be
406+
specified in `op` to create a `LinearProblem`. In such a case, `prob.u0` will be `nothing`
407+
and attempting to symbolically index the problem with an unknown, observable, or expression
408+
depending on unknowns/observables will error.
409+
410+
Updating the parameters automatically updates the `A` and `b` arrays.
411+
412+
# Keyword arguments
413+
414+
$PROBLEM_KWARGS
415+
$(prob_fun_common_kwargs(LinearProblem, false))
416+
417+
All other keyword arguments are forwarded to the $func constructor.
418+
419+
$PROBLEM_INTERNALS_HEADER
420+
421+
$PROBLEM_INTERNAL_KWARGS
422+
""" SciMLBase.LinearProblem

src/problems/jumpproblem.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@
8080
end
8181

8282
# handle events, making sure to reset aggregators in the generated affect functions
83-
cbs = process_events(sys; callback, eval_expression, eval_module, reset_jumps = true)
83+
cbs = process_events(
84+
sys; callback, eval_expression, eval_module, op, reset_jumps = true)
8485

8586
if rng !== nothing
8687
kwargs = (; kwargs..., rng)

0 commit comments

Comments
 (0)