1+ struct SemilinearODEFunction{iip, spec} end
2+ struct SemilinearODEProblem{iip, spec} end
3+
14const U0_P_DOCS = """
25The 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
9396end
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+
95107function 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 """
104116end
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+
189229for (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
211257end
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 """
242293end
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 " )
329380end
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
345406end
346407
347408@doc """
0 commit comments