11# Method of lines discretization scheme
22
3- function interface_errors (depvars, indvars, discretization)
3+ function PDEBase. interface_errors (pdesys:: PDESystem , v:: PDEBase.VariableMap , discretization:: MOLFiniteDifference )
4+ depvars = v. ū
5+ indvars = v. x̄
46 for x in indvars
57 @assert haskey (discretization. dxs, Num (x)) || haskey (discretization. dxs, x) " Variable $x has no step size"
68 end
@@ -12,7 +14,7 @@ function interface_errors(depvars, indvars, discretization)
1214 end
1315end
1416
15- function check_boundarymap (boundarymap, discretization)
17+ function PDEBase . check_boundarymap (boundarymap, discretization:: MOLFiniteDifference )
1618 bs = filter_interfaces (flatten_vardict (boundarymap))
1719 for b in bs
1820 dx1 = discretization. dxs[Num (b. x)]
@@ -23,44 +25,29 @@ function check_boundarymap(boundarymap, discretization)
2325 end
2426end
2527
26- function SciMLBase. symbolic_discretize (pdesys:: PDESystem , discretization:: MethodOfLines.MOLFiniteDifference{G} ) where {G}
27- t = discretization. time
28- disc_strategy = discretization. disc_strategy
29- cardinalize_eqs! (pdesys)
28+ function get_discrete (pdesys, discretization)
29+ t = get_time (discretization)
30+ PDEBase. cardinalize_eqs! (pdesys)
3031
3132 # ###########################
3233 # System Parsing and Transformation
3334 # ###########################
3435 # Parse the variables in to the right form and store useful information about the system
35- v = VariableMap (pdesys, t )
36+ v = VariableMap (pdesys, discretization )
3637 # Check for basic interface errors
37- interface_errors (v . ū , v. x̄ , discretization)
38+ PDEBase . interface_errors (pdesys , v, discretization)
3839 # Extract tspan
3940 tspan = t != = nothing ? v. intervals[t] : nothing
4041 # Find the derivative orders in the bcs
4142 bcorders = Dict (map (x -> x => d_orders (x, pdesys. bcs), all_ivs (v)))
4243 # Create a map of each variable to their boundary conditions including initial conditions
43- boundarymap = parse_bcs (pdesys. bcs, v, bcorders)
44-
45- check_boundarymap (boundarymap, discretization)
44+ boundarymap = PDEBase . parse_bcs (pdesys. bcs, v, bcorders)
45+ # Check that the boundary map is valid
46+ PDEBase . check_boundarymap (boundarymap, discretization)
4647
4748 # Transform system so that it is compatible with the discretization
48- if discretization. should_transform
49- if has_interfaces (boundarymap)
50- @warn " The system contains interface boundaries, which are not compatible with system transformation. The system will not be transformed. Please post an issue if you need this feature."
51- else
52- pdesys = transform_pde_system! (v, boundarymap, pdesys)
53- end
54- end
55-
56- # Check if the boundaries warrant using ODAEProblem, as long as this is allowed in the interface
57- use_ODAE = discretization. use_ODAE
58- if use_ODAE
59- bcivmap = reduce ((d1, d2) -> mergewith (vcat, d1, d2), collect (values (boundarymap)))
60- allbcs = mapreduce (x -> bcivmap[x], vcat, v. x̄)
61- if all (bc -> bc. order > 0 , allbcs)
62- use_ODAE = false
63- end
49+ if should_transform (pdesys, discretization)
50+ pdesys = PDEBase. transform_pde_system! (v, boundarymap, pdesys, discretization)
6451 end
6552
6653 pdeeqs = pdesys. eqs
@@ -69,123 +56,10 @@ function SciMLBase.symbolic_discretize(pdesys::PDESystem, discretization::Method
6956 # ###########################
7057 # Discretization of system
7158 # ###########################
72- alleqs = []
73- bceqs = []
59+ disc_state = PDEBase. construct_disc_state (discretization)
7460
7561 # Create discretized space and variables, this is called `s` throughout
76- s = DiscreteSpace (v, discretization)
77- # Get the interior and variable to solve for each equation
78- # TODO : do the interiormap before and independent of the discretization i.e. `s`
79- interiormap = InteriorMap (pdeeqs, boundarymap, s, discretization)
80- # Get the derivative orders appearing in each equation
81- pdeorders = Dict (map (x -> x => d_orders (x, pdeeqs), v. x̄))
82- bcorders = Dict (map (x -> x => d_orders (x, bcs), v. x̄))
83- orders = Dict (map (x -> x => collect (union (pdeorders[x], bcorders[x])), v. x̄))
84-
85- # Generate finite difference weights
86- derivweights = DifferentialDiscretizer (pdesys, s, discretization, orders)
87-
88- # Seperate bcs and ics
89- ics = t === nothing ? [] : mapreduce (u -> boundarymap[u][t], vcat, operation .(s. ū))
90-
91- bcmap = Dict (map (collect (keys (boundarymap))) do u
92- u => Dict (map (s. x̄) do x
93- x => boundarymap[u][x]
94- end )
95- end )
96-
97- # ###
98- # Loop over equations, Discretizing them and their dependent variables' boundary conditions
99- # ###
100- for pde in pdeeqs
101- # Read the dependent variables on both sides of the equation
102- depvars_lhs = get_depvars (pde. lhs, v. depvar_ops)
103- depvars_rhs = get_depvars (pde. rhs, v. depvar_ops)
104- depvars = collect (depvars_lhs ∪ depvars_rhs)
105- depvars = filter (u -> ! any (map (x -> x isa Number, arguments (u))), depvars)
106-
107- eqvar = interiormap. var[pde]
108-
109- # * Assumes that all variables in the equation have same dimensionality except edgevals
110- args = ivs (eqvar, s)
111- indexmap = Dict ([args[i] => i for i in 1 : length (args)])
112- if disc_strategy isa ScalarizedDiscretization
113- # Generate the equations for the interior points
114- discretize_equation! (alleqs, bceqs, pde, interiormap, eqvar, bcmap,
115- depvars, s, derivweights, indexmap)
116- else
117- throw (ArgumentError (" Only ScalarizedDiscretization is currently supported" ))
118- end
119- end
120-
121- u0 = generate_ic_defaults (ics, s, disc_strategy)
122-
123- defaults = Dict (pdesys. ps === nothing || pdesys. ps === SciMLBase. NullParameters () ? u0 : vcat (u0, pdesys. ps))
124- ps = pdesys. ps === nothing || pdesys. ps === SciMLBase. NullParameters () ? Num[] : first .(pdesys. ps)
125- # Combine PDE equations and BC equations
126- metadata = MOLMetadata (s, discretization, pdesys, use_ODAE)
127-
128- return generate_system (alleqs, bceqs, ics, s. discvars, defaults, ps, tspan, metadata)
129- end
130-
131- function SciMLBase. discretize (pdesys:: PDESystem ,discretization:: MethodOfLines.MOLFiniteDifference ; analytic = nothing , kwargs... )
132- sys, tspan = SciMLBase. symbolic_discretize (pdesys, discretization)
133- try
134- simpsys = structural_simplify (sys)
135- if tspan === nothing
136- add_metadata! (get_metadata (sys), sys)
137- return prob = NonlinearProblem (simpsys, ones (length (simpsys. states)); discretization. kwargs... , kwargs... )
138- else
139- # Use ODAE if nessesary
140- if getfield (sys, :metadata ) isa MOLMetadata && getfield (sys, :metadata ). use_ODAE
141- add_metadata! (get_metadata (simpsys), DAEProblem (simpsys; discretization. kwargs... , kwargs... ))
142- return prob = ODAEProblem (simpsys, Pair[], tspan; discretization. kwargs... , kwargs... )
143- else
144- add_metadata! (get_metadata (simpsys), sys)
145- prob = ODEProblem (simpsys, Pair[], tspan; discretization. kwargs... , kwargs... )
146- if analytic === nothing
147- return prob
148- else
149- f = ODEFunction (pdesys, discretization, analytic= analytic, discretization. kwargs... , kwargs... )
150-
151- return ODEProblem (f, prob. u0, prob. tspan, prob. p; discretization. kwargs... , kwargs... )
152- end
153- end
154- end
155- catch e
156- error_analysis (sys, e)
157- end
158- end
159-
160- function get_discrete (pdesys, discretization)
161- t = discretization. time
162- disc_strategy = discretization. disc_strategy
163- cardinalize_eqs! (pdesys)
164-
165- # ###########################
166- # System Parsing and Transformation
167- # ###########################
168- # Parse the variables in to the right form and store useful information about the system
169- v = VariableMap (pdesys, t)
170- # Check for basic interface errors
171- interface_errors (v. ū, v. x̄, discretization)
172- # Extract tspan
173- tspan = t != = nothing ? v. intervals[t] : nothing
174- # Find the derivative orders in the bcs
175- bcorders = Dict (map (x -> x => d_orders (x, pdesys. bcs), all_ivs (v)))
176- # Create a map of each variable to their boundary conditions including initial conditions
177- boundarymap = parse_bcs (pdesys. bcs, v, bcorders)
178-
179- # Transform system so that it is compatible with the discretization
180- if discretization. should_transform
181- if has_interfaces (boundarymap)
182- @warn " The system contains interface boundaries, which are not compatible with system transformation. The system will not be transformed. Please post an issue if you need this feature."
183- else
184- pdesys = transform_pde_system! (v, boundarymap, pdesys)
185- end
186- end
187-
188- s = DiscreteSpace (v, discretization)
62+ s = PDEBase. construct_discrete_space (v, discretization)
18963
19064 return Dict (vcat ([Num (x) => s. grid[x] for x in s. x̄], [Num (u) => s. discvars[u] for u in s. ū]))
19165end
0 commit comments