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_linear = true, stiff_quadratic = false, stiff_nonlinear = 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_linear`, `stiff_quadratic` and `stiff_nonlinear` can
210+ be used to control which parts are considered as stiff.
211+ """
212+
213+ const SEMILINEAR_A_B_C_KWARGS = """
214+ - `stiff_linear`: 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_quadratic`: 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_nonlinear`: 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_linear`, `stiff_quadratic`, `stiff_nonlinear` 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,12 +241,23 @@ 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]
206- @eval @doc problem_docstring ($ mod.$ prob, $ func, $ istd) $ mod.$ prob
252+ kwexpr = Expr (:parameters )
253+ for (k, v) in pairs (kws)
254+ push! (kwexpr. args, Expr (:kw , k, v))
255+ end
256+ @eval @doc problem_docstring ($ kwexpr, $ mod.$ prob, $ func, $ istd) $ mod.$ prob
207257end
208258
209- function function_docstring (func, istd, optionals)
259+ function function_docstring (
260+ func, istd, optionals; extra_body = " " , extra_kwargs = " " , extra_kwargs_desc = " " )
210261 return """
211262 $func (sys::System; kwargs...)
212263 $func {iip}(sys::System; kwargs...)
@@ -216,6 +267,8 @@ function function_docstring(func, istd, optionals)
216267 function should be in-place. `specialization` is a `SciMLBase.AbstractSpecalize`
217268 subtype indicating the level of specialization of the $func .
218269
270+ $(extra_body)
271+
219272 Beyond the arguments listed below, this constructor accepts all keyword arguments
220273 supported by the DifferentialEquations.jl `solve` function. For a complete list
221274 and detailed descriptions, see the [DifferentialEquations.jl solve documentation](https://docs.sciml.ai/DiffEqDocs/stable/basics/common_solver_opts/).
@@ -236,9 +289,11 @@ function function_docstring(func, istd, optionals)
236289 sparse matrices. Also controls whether the mass matrix is sparse, wherever applicable.
237290 $(prob_fun_common_kwargs (func, istd))
238291 $(process_optional_function_kwargs (optionals))
292+ $(extra_kwargs)
239293 - `kwargs...`: Additional keyword arguments passed to the solver
240294
241295 All other keyword arguments are forwarded to the `$func ` struct constructor.
296+ $(extra_kwargs_desc)
242297 """
243298end
244299
@@ -329,20 +384,30 @@ function process_optional_function_kwargs(choices::Vector{Symbol})
329384 join (map (Base. Fix1 (getindex, OPTIONAL_FN_KWARGS_DICT), choices), " \n " )
330385end
331386
332- for (mod, func, istd, optionals) in [
333- (SciMLBase, :ODEFunction , true , [:jac , :tgrad ]),
334- (SciMLBase, :ODEInputFunction , true , [:inputfn , :jac , :tgrad , :controljac ]),
335- (SciMLBase, :DAEFunction , true , [:jac , :tgrad ]),
336- (SciMLBase, :DDEFunction , true , Symbol[]),
337- (SciMLBase, :SDEFunction , true , [:jac , :tgrad ]),
338- (SciMLBase, :SDDEFunction , true , Symbol[]),
339- (SciMLBase, :DiscreteFunction , true , Symbol[]),
340- (SciMLBase, :ImplicitDiscreteFunction , true , Symbol[]),
341- (SciMLBase, :NonlinearFunction , false , [:resid_prototype , :jac ]),
342- (SciMLBase, :IntervalNonlinearFunction , false , Symbol[]),
343- (SciMLBase, :OptimizationFunction , false , [:jac , :grad , :hess , :cons_h , :cons_j ])
387+ for (mod, func, istd, optionals, kws) in [
388+ (SciMLBase, :ODEFunction , true , [:jac , :tgrad ], (;)),
389+ (SciMLBase, :ODEInputFunction , true , [:inputfn , :jac , :tgrad , :controljac ], (;)),
390+ (SciMLBase, :DAEFunction , true , [:jac , :tgrad ], (;)),
391+ (SciMLBase, :DDEFunction , true , Symbol[], (;)),
392+ (SciMLBase, :SDEFunction , true , [:jac , :tgrad ], (;)),
393+ (SciMLBase, :SDDEFunction , true , Symbol[], (;)),
394+ (SciMLBase, :DiscreteFunction , true , Symbol[], (;)),
395+ (SciMLBase, :ImplicitDiscreteFunction , true , Symbol[], (;)),
396+ (SciMLBase, :NonlinearFunction , false , [:resid_prototype , :jac ], (;)),
397+ (SciMLBase, :IntervalNonlinearFunction , false , Symbol[], (;)),
398+ (SciMLBase, :OptimizationFunction , false , [:jac , :grad , :hess , :cons_h , :cons_j ], (;)),
399+ (ModelingToolkit,
400+ :SemilinearODEFunction ,
401+ true ,
402+ [:jac ],
403+ (; extra_body = SEMILINEAR_EXTRA_BODY, extra_kwargs = SEMILINEAR_A_B_C_KWARGS,
404+ extra_kwargs_desc = SEMILINEAR_A_B_C_CONSTRAINT))
344405]
345- @eval @doc function_docstring ($ mod.$ func, $ istd, $ optionals) $ mod.$ func
406+ kwexpr = Expr (:parameters )
407+ for (k, v) in pairs (kws)
408+ push! (kwexpr. args, Expr (:kw , k, v))
409+ end
410+ @eval @doc function_docstring ($ kwexpr, $ mod.$ func, $ istd, $ optionals) $ mod.$ func
346411end
347412
348413@doc """
0 commit comments