@@ -4,6 +4,7 @@ import DomainSets
44# Method of lines discretization scheme
55
66@enum GridAlign center_align edge_align
7+
78struct MOLFiniteDifference{T,T2} <: DiffEqBase.AbstractDiscretization
89 dxs:: T
910 time:: T2
@@ -45,10 +46,13 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
4546 pdeeqs = pdesys. eqs isa Vector ? pdesys. eqs : [pdesys. eqs]
4647 t = discretization. time
4748 # Get tspan
48- tdomain = pdesys. domain[findfirst (d-> isequal (t. val, d. variables),pdesys. domain)]
49- @assert tdomain. domain isa DomainSets. Interval
50- tspan = (tdomain. domain. lower,tdomain. domain. upper)
51-
49+ tspan = nothing
50+ if t != nothing
51+ tdomain = pdesys. domain[findfirst (d-> isequal (t. val, d. variables),pdesys. domain)]
52+ @assert tdomain. domain isa DomainSets. Interval
53+ tspan = (DomainSets. infimum (tdomain. domain), DomainSets. supremum (tdomain. domain))
54+ end
55+
5256 depvar_ops = map (x-> operation (x. val),pdesys. depvars)
5357
5458 u0 = []
@@ -66,7 +70,7 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
6670 # Read the independent variables,
6771 # ignore if the only argument is [t]
6872 allindvars = Set (filter (xs-> ! isequal (xs,[t]),map (arguments,depvars)))
69- allnottime = Set (filter (! isempty,map (u-> filter (x-> ! isequal (x,t. val),arguments (u)),depvars)))
73+ allnottime = Set (filter (! isempty,map (u-> filter (x-> t == nothing || ! isequal (x,t. val),arguments (u)),depvars)))
7074 if isempty (allnottime)
7175 push! (alleqs,eq)
7276 push! (alldepvarsdisc,depvars)
@@ -87,7 +91,7 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
8791 space = map (nottime) do x
8892 xdomain = pdesys. domain[findfirst (d-> isequal (x, d. variables),pdesys. domain)]
8993 dx = discretization. dxs[findfirst (dxs-> isequal (x, dxs[1 ]. val),discretization. dxs)][2 ]
90- dx isa Number ? (xdomain. domain. lower : dx: xdomain. domain. upper ) : dx
94+ dx isa Number ? (DomainSets . infimum ( xdomain. domain) : dx: DomainSets . supremum ( xdomain. domain) ) : dx
9195 end
9296 dxs = map (nottime) do x
9397 dx = discretization. dxs[findfirst (dxs-> isequal (x, dxs[1 ]. val),discretization. dxs)][2 ]
@@ -112,7 +116,9 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
112116 space_indices = CartesianIndices (((axes (s)[1 ] for s in space). .. ,))
113117 grid_indices = CartesianIndices (((axes (g)[1 ] for g in grid). .. ,))
114118 depvarsdisc = map (depvars) do u
115- if isequal (arguments (u),[t])
119+ if t == nothing
120+ [Num (Variable {Real} (Base. nameof (operation (u)),II. I... )) for II in grid_indices]
121+ elseif isequal (arguments (u),[t])
116122 [u for II in grid_indices]
117123 else
118124 [Num (Variable {Symbolics.FnType{Tuple{Any}, Real}} (Base. nameof (operation (u)),II. I... ))(t) for II in grid_indices]
@@ -134,7 +140,10 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
134140
135141 bclocs = map (e-> substitute .(indvars,e),edgevals) # location of the boundary conditions e.g. (t,0.0,y)
136142 edgemaps = Dict (bclocs .=> [spacevals[e... ] for e in edges])
137- initmaps = substitute .(depvars,[t=> tspan[1 ]])
143+ initmaps = depvars
144+ if t != nothing
145+ initmaps = substitute .(depvars,[t=> tspan[1 ]])
146+ end
138147
139148 # Generate map from variable (e.g. u(t,0)) to discretized variable (e.g. u₁(t))
140149 subvar (depvar) = substitute .((depvar,),edgevals)
@@ -179,7 +188,7 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
179188 for bc in pdesys. bcs
180189 bcdepvar = first (get_depvars (bc. lhs, depvar_ops))
181190 if any (u-> isequal (operation (u),operation (bcdepvar)),depvars)
182- if operation (bc. lhs) isa Sym && ! any (x -> isequal (x, t. val), arguments (bc. lhs))
191+ if t != nothing && operation (bc. lhs) isa Sym && ! any (x -> isequal (x, t. val), arguments (bc. lhs))
183192 # initial condition
184193 # Assume in the form `u(...) ~ ...` for now
185194 i = findfirst (isequal (bc. lhs),initmaps)
@@ -334,7 +343,7 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
334343 push! (alldepvarsdisc,reduce (vcat,depvarsdisc))
335344 end
336345 end
337- u0 = reduce (vcat,u0)
346+ u0 = ! isempty (u0) ? reduce (vcat,u0) : u0
338347 bceqs = reduce (vcat,bceqs)
339348 alleqs = reduce (vcat,alleqs)
340349 alldepvarsdisc = unique (reduce (vcat,alldepvarsdisc))
@@ -343,12 +352,25 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
343352 defaults = pdesys. ps === nothing || pdesys. ps === SciMLBase. NullParameters () ? u0 : vcat (u0,pdesys. ps)
344353 ps = pdesys. ps === nothing || pdesys. ps === SciMLBase. NullParameters () ? Num[] : first .(pdesys. ps)
345354 # Combine PDE equations and BC equations
346- sys = ODESystem (vcat (alleqs,unique (bceqs)),t,vec (reduce (vcat,vec (alldepvarsdisc))),ps,defaults= Dict (defaults))
347- sys, tspan
355+ if t == nothing
356+ # At the time of writing, NonlinearProblems require that the system of equations be in this form:
357+ # 0 ~ ...
358+ # Thus, before creating a NonlinearSystem we normalize the equations s.t. the lhs is zero.
359+ eqs = map (eq -> 0 ~ eq. rhs - eq. lhs, vcat (alleqs,unique (bceqs)))
360+ sys = NonlinearSystem (eqs,vec (reduce (vcat,vec (alldepvarsdisc))),ps,defaults= Dict (defaults))
361+ return sys, nothing
362+ else
363+ sys = ODESystem (vcat (alleqs,unique (bceqs)),t,vec (reduce (vcat,vec (alldepvarsdisc))),ps,defaults= Dict (defaults))
364+ return sys, tspan
365+ end
348366end
349367
350368function SciMLBase. discretize (pdesys:: ModelingToolkit.PDESystem ,discretization:: DiffEqOperators.MOLFiniteDifference )
351369 sys, tspan = SciMLBase. symbolic_discretize (pdesys,discretization)
352- simpsys = structural_simplify (sys)
353- prob = ODEProblem (simpsys,Pair[],tspan)
370+ if tspan == nothing
371+ return prob = NonlinearProblem (sys, ones (length (sys. states)))
372+ else
373+ simpsys = structural_simplify (sys)
374+ return prob = ODEProblem (simpsys,Pair[],tspan)
375+ end
354376end
0 commit comments