@@ -33,13 +33,13 @@ function calculate_weights_spherical(order::Int, x0::T, x::AbstractVector, idxs:
33
33
# but for now everything is an Interval
34
34
# @assert length(x) == 3
35
35
# TODO : nonlinear diffusion in a spherical domain
36
- i = idxs[2 ]
36
+ i = idxs[2 ]
37
37
dx1 = x[i] - x[i- 1 ]
38
38
dx2 = x[i+ 1 ] - x[i]
39
39
i0 = i - 1 # indexing starts at 0 in the paper and starts at 1 in julia
40
40
1 / (i0 * dx1 * dx2) * [i0- 1 , - 2 i0, i0+ 1 ]
41
41
end
42
-
42
+
43
43
44
44
function SciMLBase. symbolic_discretize (pdesys:: ModelingToolkit.PDESystem ,discretization:: DiffEqOperators.MOLFiniteDifference )
45
45
grid_align = discretization. grid_align
@@ -54,7 +54,7 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
54
54
end
55
55
56
56
depvar_ops = map (x-> operation (x. val),pdesys. depvars)
57
-
57
+
58
58
u0 = []
59
59
bceqs = []
60
60
alleqs = []
@@ -93,7 +93,7 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
93
93
dx = discretization. dxs[findfirst (dxs-> isequal (x, dxs[1 ]. val),discretization. dxs)][2 ]
94
94
dx isa Number ? (DomainSets. infimum (xdomain. domain): dx: DomainSets. supremum (xdomain. domain)) : dx
95
95
end
96
- dxs = map (nottime) do x
96
+ dxs = map (nottime) do x
97
97
dx = discretization. dxs[findfirst (dxs-> isequal (x, dxs[1 ]. val),discretization. dxs)][2 ]
98
98
end
99
99
@@ -117,11 +117,13 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
117
117
grid_indices = CartesianIndices (((axes (g)[1 ] for g in grid). .. ,))
118
118
depvarsdisc = map (depvars) do u
119
119
if t == nothing
120
- [Num (Variable {Real} (Base. nameof (operation (u)),II. I... )) for II in grid_indices]
120
+ sym = nameof (operation (u))
121
+ collect (first (@variables $ sym[collect (axes (g)[1 ] for g in grid)... ]))
121
122
elseif isequal (arguments (u),[t])
122
123
[u for II in grid_indices]
123
124
else
124
- [Num (Variable {Symbolics.FnType{Tuple{Any}, Real}} (Base. nameof (operation (u)),II. I... ))(t) for II in grid_indices]
125
+ sym = nameof (operation (u))
126
+ collect (first (@variables $ sym[collect (axes (g)[1 ] for g in grid)... ](t)))
125
127
end
126
128
end
127
129
spacevals = map (y-> [Pair (nottime[i],space[i][y. I[i]]) for i in 1 : nspace],space_indices)
@@ -174,15 +176,15 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
174
176
push! (depvarderivbcmaps, r)
175
177
end
176
178
end
177
-
179
+
178
180
if grid_align == edge_align
179
- # Constructs symbolic spatially discretized terms of the form e.g. (u₁ + u₂) / 2
181
+ # Constructs symbolic spatially discretized terms of the form e.g. (u₁ + u₂) / 2
180
182
bcvars = [[dot (ones (2 )/ 2 ,depvar[left_idxs (1 )]), dot (ones (2 )/ 2 ,depvar[right_idxs (1 ,1 )])]
181
183
for depvar in depvarsdisc]
182
184
# replace u(t,0) with (u₁ + u₂) / 2, etc
183
185
depvarbcmaps = reduce (vcat,[subvar (depvar) .=> bcvars[i]
184
186
for (i, depvar) in enumerate (depvars) for s in nottime])
185
-
187
+
186
188
end
187
189
else
188
190
# Higher dimension
@@ -191,7 +193,7 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
191
193
end
192
194
# All unique order of derivates in BCs
193
195
bc_der_orders = filter (! iszero,sort (unique ([count_differentials (bc. lhs, nottime[1 ]) for bc in pdesys. bcs])))
194
- # no. of different orders in BCs
196
+ # no. of different orders in BCs
195
197
n = length (bc_der_orders)
196
198
# Generate initial conditions and bc equations
197
199
for bc in pdesys. bcs
@@ -276,21 +278,21 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
276
278
eqs = vec (map (interior) do II
277
279
# Use max and min to apply buffers
278
280
central_neighbor_idxs (II,j,order) = stencil (j,order) .+ max (Imin (order),min (II,Imax (order)))
279
- central_weights_cartesian (d_order,II,j) = calculate_weights_cartesian (d_order, grid[j][II[j]], grid[j], vec (map (i-> i[j],
281
+ central_weights_cartesian (d_order,II,j) = calculate_weights_cartesian (d_order, grid[j][II[j]], grid[j], vec (map (i-> i[j],
280
282
central_neighbor_idxs (II,j,approx_order))))
281
283
central_deriv (d_order, II,j,k) = dot (central_weights (d_order, II,j),depvarsdisc[k][central_neighbor_idxs (II,j,approx_order)])
282
284
283
285
central_deriv_cartesian (d_order,II,j,k) = dot (central_weights_cartesian (d_order,II,j),depvarsdisc[k][central_neighbor_idxs (II,j,approx_order)])
284
-
286
+
285
287
# spherical Laplacian has a hardcoded order of 2 (only 2nd order is implemented)
286
288
# both for derivative order and discretization order
287
289
central_weights_spherical (II,j) = calculate_weights_spherical (2 , grid[j][II[j]], grid[j], vec (map (i-> i[j], central_neighbor_idxs (II,j,2 ))))
288
290
central_deriv_spherical (II,j,k) = dot (central_weights_spherical (II,j),depvarsdisc[k][central_neighbor_idxs (II,j,2 )])
289
-
291
+
290
292
# get a sorted list derivative order such that highest order is first. This is useful when substituting rules
291
293
# starting from highest to lowest order.
292
294
d_orders (s) = reverse (sort (collect (union (differential_order (eq. rhs, s), differential_order (eq. lhs, s)))))
293
-
295
+
294
296
# central_deriv_rules = [(Differential(s)^2)(u) => central_deriv(2,II,j,k) for (j,s) in enumerate(nottime), (k,u) in enumerate(depvars)]
295
297
central_deriv_rules_cartesian = Array {Pair{Num,Num},1} ()
296
298
for (j,s) in enumerate (nottime)
@@ -300,12 +302,12 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
300
302
end
301
303
end
302
304
303
- central_deriv_rules_spherical = [Differential (s)(s^ 2 * Differential (s)(u))/ s^ 2 => central_deriv_spherical (II,j,k)
305
+ central_deriv_rules_spherical = [Differential (s)(s^ 2 * Differential (s)(u))/ s^ 2 => central_deriv_spherical (II,j,k)
304
306
for (j,s) in enumerate (nottime), (k,u) in enumerate (depvars)]
305
-
307
+
306
308
valrules = vcat ([depvars[k] => depvarsdisc[k][II] for k in 1 : length (depvars)],
307
309
[nottime[j] => grid[j][II[j]] for j in 1 : nspace])
308
-
310
+
309
311
# TODO : upwind rules needs interpolation into `@rule`
310
312
forward_weights (II,j) = DiffEqOperators. calculate_weights (discretization. upwind_order, 0.0 , grid[j][[II[j],II[j]+ 1 ]])
311
313
reverse_weights (II,j) = DiffEqOperators. calculate_weights (discretization. upwind_order, 0.0 , grid[j][[II[j]- 1 ,II[j]]])
@@ -314,14 +316,14 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
314
316
# *(~~a..., ~~b..., dot(forward_weights(II,j),depvars[k][central_neighbor_idxs(II,j)[2:3]]))))
315
317
# for j in 1:nspace, k in 1:length(pdesys.depvars)]
316
318
317
- # # Discretization of non-linear laplacian.
319
+ # # Discretization of non-linear laplacian.
318
320
# d/dx( a du/dx ) ~ (a(x+1/2) * (u[i+1] - u[i]) - a(x-1/2) * (u[i] - u[i-1]) / dx^2
319
321
b1 (II, j, k) = dot (reverse_weights (II, j), depvarsdisc[k][central_neighbor_idxs (II, j, approx_order)[1 : 2 ]]) / dxs[j]
320
322
b2 (II, j, k) = dot (forward_weights (II, j), depvarsdisc[k][central_neighbor_idxs (II, j, approx_order)[2 : 3 ]]) / dxs[j]
321
323
# TODO : improve interpolation of g(x) = u(x) for calculating u(x+-dx/2)
322
324
g (II, j, k, l) = sum ([depvarsdisc[k][central_neighbor_idxs (II, j, approx_order)][s] for s in (l == 1 ? [2 ,3 ] : [1 ,2 ])]) / 2.
323
325
# iv_mid returns middle space values. E.g. x(i-1/2) or y(i+1/2).
324
- iv_mid (II, j, l) = (grid[j][II[j]] + grid[j][II[j]+ l]) / 2.0
326
+ iv_mid (II, j, l) = (grid[j][II[j]] + grid[j][II[j]+ l]) / 2.0
325
327
# Dependent variable rules
326
328
r_mid_dep (II, j, k, l) = [depvars[k] => g (II, j, k, l) for k in 1 : length (depvars)]
327
329
# Independent variable rules
@@ -377,10 +379,10 @@ function SciMLBase.symbolic_discretize(pdesys::ModelingToolkit.PDESystem,discret
377
379
# 0 ~ ...
378
380
# Thus, before creating a NonlinearSystem we normalize the equations s.t. the lhs is zero.
379
381
eqs = map (eq -> 0 ~ eq. rhs - eq. lhs, vcat (alleqs,unique (bceqs)))
380
- sys = NonlinearSystem (eqs,vec (reduce (vcat,vec (alldepvarsdisc))),ps,defaults= Dict (defaults))
382
+ sys = NonlinearSystem (eqs,vec (reduce (vcat,vec (alldepvarsdisc))),ps,defaults= Dict (defaults),name = pdesys . name )
381
383
return sys, nothing
382
384
else
383
- sys = ODESystem (vcat (alleqs,unique (bceqs)),t,vec (reduce (vcat,vec (alldepvarsdisc))),ps,defaults= Dict (defaults))
385
+ sys = ODESystem (vcat (alleqs,unique (bceqs)),t,vec (reduce (vcat,vec (alldepvarsdisc))),ps,defaults= Dict (defaults),name = pdesys . name )
384
386
return sys, tspan
385
387
end
386
388
end
0 commit comments