Skip to content

Commit d3a5b70

Browse files
docs: document SemilinearODEProblem and SemilinearODEFunction
1 parent 83aaff9 commit d3a5b70

File tree

3 files changed

+83
-17
lines changed

3 files changed

+83
-17
lines changed

docs/src/API/codegen.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ ModelingToolkit.build_explicit_observed_function
2323
ModelingToolkit.generate_control_function
2424
ModelingToolkit.generate_update_A
2525
ModelingToolkit.generate_update_b
26+
ModelingToolkit.generate_semiquadratic_functions
27+
ModelingToolkit.generate_semiquadratic_jacobian
28+
ModelingToolkit.get_semiquadratic_W_sparsity
2629
```
2730

2831
For functions such as jacobian calculation which require symbolic computation, there

docs/src/API/problems.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ SciMLBase.ODEFunction
1717
SciMLBase.ODEProblem
1818
SciMLBase.DAEFunction
1919
SciMLBase.DAEProblem
20+
ModelingToolkit.SemilinearODEFunction
21+
ModelingToolkit.SemilinearODEProblem
2022
SciMLBase.SDEFunction
2123
SciMLBase.SDEProblem
2224
SciMLBase.DDEFunction

src/problems/docs.jl

Lines changed: 78 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
struct SemilinearODEFunction{iip, spec} end
2+
struct SemilinearODEProblem{iip, spec} end
3+
14
const U0_P_DOCS = """
25
The order of unknowns is determined by `unknowns(sys)`. If the system is split
36
[`is_split`](@ref) create an [`MTKParameters`](@ref) object. Otherwise, a parameter vector.
@@ -92,6 +95,15 @@ function problem_ctors(prob, istd)
9295
end
9396
end
9497

98+
function problem_ctors(prob::Type{<:SemilinearODEProblem}, istd)
99+
@assert istd
100+
"""
101+
SciMLBase.$prob(sys::System, op, tspan::NTuple{2}; kwargs...)
102+
SciMLBase.$prob{iip}(sys::System, op, tspan::NTuple{2}; kwargs...)
103+
SciMLBase.$prob{iip, specialize}(sys::System, op, tspan::NTuple{2}; stiff_A = true, stiff_B = false, stiff_C = false, kwargs...)
104+
"""
105+
end
106+
95107
function prob_fun_common_kwargs(T, istd)
96108
return """
97109
- `check_compatibility`: Whether to check if the given system `sys` contains all the
@@ -103,7 +115,8 @@ function prob_fun_common_kwargs(T, istd)
103115
"""
104116
end
105117

106-
function problem_docstring(prob, func, istd; init = true, extra_body = "")
118+
function problem_docstring(prob, func, istd; init = true, extra_body = "",
119+
extra_kwargs = "", extra_kwargs_desc = "")
107120
if func isa DataType
108121
func = "`$func`"
109122
end
@@ -127,8 +140,9 @@ function problem_docstring(prob, func, istd; init = true, extra_body = "")
127140
$PROBLEM_KWARGS
128141
$(istd ? TIME_DEPENDENT_PROBLEM_KWARGS : "")
129142
$(prob_fun_common_kwargs(prob, istd))
130-
143+
$(extra_kwargs)
131144
All other keyword arguments are forwarded to the $func constructor.
145+
$(extra_kwargs_desc)
132146
133147
$PROBLEM_INTERNALS_HEADER
134148
@@ -186,6 +200,32 @@ If the `System` has algebraic equations, like `x(t)^2 + y(t)^2`, the resulting
186200
`BVProblem` must be solved using BVDAE solvers, such as Ascher.
187201
"""
188202

203+
const SEMILINEAR_EXTRA_BODY = """
204+
This is a special form of an ODE which uses a `SplitFunction` internally. The equations are
205+
separated into linear, quadratic and general terms and phrased as matrix operations. See
206+
[`calculate_semiquadratic_form`](@ref) for information on how the equations are split. This
207+
formulation allows leveraging split ODE solvers such as `KenCarp4` and is useful for systems
208+
where the stiff and non-stiff terms can be separated out in such a manner. Typically the linear
209+
part of the equations is the stiff part, but the keywords `stiff_A`, `stiff_B` and `stiff_C` can
210+
be used to control which parts are considered as stiff.
211+
"""
212+
213+
const SEMILINEAR_A_B_C_KWARGS = """
214+
- `stiff_A`: Whether the linear part of the equations should be part of the stiff function
215+
in the split form. Has no effect if the equations have no linear part.
216+
- `stiff_B`: Whether the quadratic part of the equations should be part of the stiff
217+
function in the split form. Has no effect if the equations have no quadratic part.
218+
- `stiff_C`: Whether the non-linear non-quadratic part of the equations should be part of
219+
the stiff function in the split form. Has no effect if the equations have no such
220+
non-linear non-quadratic part.
221+
"""
222+
223+
const SEMILINEAR_A_B_C_CONSTRAINT = """
224+
Note that all three of `stiff_A`, `stiff_B`, `stiff_C` cannot be identical, and at least
225+
two of `A`, `B`, `C` returned from [`calculate_semiquadratic_form`](@ref) must be
226+
non-`nothing`. In other words, both of the functions in the split form must be non-empty.
227+
"""
228+
189229
for (mod, prob, func, istd, kws) in [
190230
(SciMLBase, :ODEProblem, ODEFunction, true, (;)),
191231
(SciMLBase, :SteadyStateProblem, ODEFunction, false, (;)),
@@ -201,7 +241,13 @@ for (mod, prob, func, istd, kws) in [
201241
(SciMLBase, :NonlinearProblem, NonlinearFunction, false, (;)),
202242
(SciMLBase, :NonlinearLeastSquaresProblem, NonlinearFunction, false, (;)),
203243
(SciMLBase, :SCCNonlinearProblem, NonlinearFunction, false, (; init = false)),
204-
(SciMLBase, :OptimizationProblem, OptimizationFunction, false, (; init = false))
244+
(SciMLBase, :OptimizationProblem, OptimizationFunction, false, (; init = false)),
245+
(ModelingToolkit,
246+
:SemilinearODEProblem,
247+
:SemilinearODEFunction,
248+
true,
249+
(; extra_body = SEMILINEAR_EXTRA_BODY, extra_kwargs = SEMILINEAR_A_B_C_KWARGS,
250+
extra_kwargs_desc = SEMILINEAR_A_B_C_CONSTRAINT))
205251
]
206252
kwexpr = Expr(:parameters)
207253
for (k, v) in pairs(kws)
@@ -210,7 +256,8 @@ for (mod, prob, func, istd, kws) in [
210256
@eval @doc problem_docstring($kwexpr, $mod.$prob, $func, $istd) $mod.$prob
211257
end
212258

213-
function function_docstring(func, istd, optionals)
259+
function function_docstring(
260+
func, istd, optionals; extra_body = "", extra_kwargs = "", extra_kwargs_desc = "")
214261
return """
215262
$func(sys::System; kwargs...)
216263
$func{iip}(sys::System; kwargs...)
@@ -220,6 +267,8 @@ function function_docstring(func, istd, optionals)
220267
function should be in-place. `specialization` is a `SciMLBase.AbstractSpecalize`
221268
subtype indicating the level of specialization of the $func.
222269
270+
$(extra_body)
271+
223272
# Keyword arguments
224273
225274
- `u0`: The `u0` vector for the corresponding problem, if available. Can be obtained
@@ -236,8 +285,10 @@ function function_docstring(func, istd, optionals)
236285
sparse matrices. Also controls whether the mass matrix is sparse, wherever applicable.
237286
$(prob_fun_common_kwargs(func, istd))
238287
$(process_optional_function_kwargs(optionals))
288+
$(extra_kwargs)
239289
240290
All other keyword arguments are forwarded to the `$func` struct constructor.
291+
$(extra_kwargs_desc)
241292
"""
242293
end
243294

@@ -328,20 +379,30 @@ function process_optional_function_kwargs(choices::Vector{Symbol})
328379
join(map(Base.Fix1(getindex, OPTIONAL_FN_KWARGS_DICT), choices), "\n")
329380
end
330381

331-
for (mod, func, istd, optionals) in [
332-
(SciMLBase, :ODEFunction, true, [:jac, :tgrad]),
333-
(SciMLBase, :ODEInputFunction, true, [:inputfn, :jac, :tgrad, :controljac]),
334-
(SciMLBase, :DAEFunction, true, [:jac, :tgrad]),
335-
(SciMLBase, :DDEFunction, true, Symbol[]),
336-
(SciMLBase, :SDEFunction, true, [:jac, :tgrad]),
337-
(SciMLBase, :SDDEFunction, true, Symbol[]),
338-
(SciMLBase, :DiscreteFunction, true, Symbol[]),
339-
(SciMLBase, :ImplicitDiscreteFunction, true, Symbol[]),
340-
(SciMLBase, :NonlinearFunction, false, [:resid_prototype, :jac]),
341-
(SciMLBase, :IntervalNonlinearFunction, false, Symbol[]),
342-
(SciMLBase, :OptimizationFunction, false, [:jac, :grad, :hess, :cons_h, :cons_j])
382+
for (mod, func, istd, optionals, kws) in [
383+
(SciMLBase, :ODEFunction, true, [:jac, :tgrad], (;)),
384+
(SciMLBase, :ODEInputFunction, true, [:inputfn, :jac, :tgrad, :controljac], (;)),
385+
(SciMLBase, :DAEFunction, true, [:jac, :tgrad], (;)),
386+
(SciMLBase, :DDEFunction, true, Symbol[], (;)),
387+
(SciMLBase, :SDEFunction, true, [:jac, :tgrad], (;)),
388+
(SciMLBase, :SDDEFunction, true, Symbol[], (;)),
389+
(SciMLBase, :DiscreteFunction, true, Symbol[], (;)),
390+
(SciMLBase, :ImplicitDiscreteFunction, true, Symbol[], (;)),
391+
(SciMLBase, :NonlinearFunction, false, [:resid_prototype, :jac], (;)),
392+
(SciMLBase, :IntervalNonlinearFunction, false, Symbol[], (;)),
393+
(SciMLBase, :OptimizationFunction, false, [:jac, :grad, :hess, :cons_h, :cons_j], (;)),
394+
(ModelingToolkit,
395+
:SemilinearODEFunction,
396+
true,
397+
[:jac],
398+
(; extra_body = SEMILINEAR_EXTRA_BODY, extra_kwargs = SEMILINEAR_A_B_C_KWARGS,
399+
extra_kwargs_desc = SEMILINEAR_A_B_C_CONSTRAINT))
343400
]
344-
@eval @doc function_docstring($mod.$func, $istd, $optionals) $mod.$func
401+
kwexpr = Expr(:parameters)
402+
for (k, v) in pairs(kws)
403+
push!(kwexpr.args, Expr(:kw, k, v))
404+
end
405+
@eval @doc function_docstring($kwexpr, $mod.$func, $istd, $optionals) $mod.$func
345406
end
346407

347408
@doc """

0 commit comments

Comments
 (0)