You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
functioncalculate_weights_cartesian(order::Int, x0::T, xs::AbstractVector, idxs::AbstractVector) where T<:Real
2
-
# Cartesian domain: use Fornberg
3
-
calculate_weights(order, x0, vec(xs[idxs]))
1
+
"""
2
+
`interpolate_discrete_param`
3
+
4
+
Interpolate gridpoints by taking the average of the values of the discrete points, or if the offset is outside the grid, extrapolate the value with dx.
# We can't activate this assertion for now because the rules try to create the spherical Laplacian
12
-
# before checking whether there is a spherical Laplacian
13
-
# this could be fixed by dispatching on domain type when we have different domain types
14
-
# but for now everything is an Interval
15
-
# @assert length(x) == 3
16
-
#TODO: nonlinear diffusion in a spherical domain
17
-
i = idxs[2]
18
-
dx1 = x[i] - x[i-1]
19
-
dx2 = x[i+1] - x[i]
20
-
i0 = i -1# indexing starts at 0 in the paper and starts at 1 in julia
21
-
1/ (i0 * dx1 * dx2) * [i0-1, -2i0, i0+1]
17
+
18
+
"""
19
+
`cartesian_nonlinear_laplacian`
20
+
21
+
Differential(x)(expr(x)*Differential(x)(u(x)))
22
+
23
+
Given an internal multiplying expression `expr`, return the correct finite difference equation for the nonlinear laplacian at the location in the grid given by `II`.
24
+
25
+
The inner derivative is discretized with the half offset centered scheme, giving the derivative at interpolated grid points offset by dx/2 from the regular grid.
26
+
27
+
The outer derivative is discretized with the centered scheme, giving the nonlinear laplacian at the grid point `II`.
where `finitediff(u, i)` is the finite difference at the interpolated point `i` in the grid.
42
+
43
+
And so on.
44
+
"""
45
+
functioncartesian_nonlinear_laplacian(expr, II, derivweights, s, x, u)
46
+
# Based on the paper https://web.mit.edu/braatzgroup/analysis_of_finite_difference_discretization_schemes_for_diffusion_in_spheres_with_variable_diffusivity.pdf
47
+
# See scheme 1, namely the term without the 1/r dependence. See also #354 and #371 in DiffEqOperators, the previous home of this package.
Given an internal multiplying expression `expr`, return the correct finite difference equation for the nonlinear laplacian at the location in the grid given by `II`.
84
+
85
+
The inner derivative is discretized with the half offset centered scheme, giving the derivative at interpolated grid points offset by dx/2 from the regular grid.
86
+
87
+
The outer derivative is discretized with the centered scheme, giving the nonlinear laplacian at the grid point `II`.
functionspherical_diffusion(innerexpr, II, derivweights, s, r, u)
106
+
# Based on the paper https://web.mit.edu/braatzgroup/analysis_of_finite_difference_discretization_schemes_for_diffusion_in_spheres_with_variable_diffusivity.pdf
107
+
D_1 = derivweights.map[Differential(r)]
108
+
D_2 = derivweights.map[Differential(r)^2]
41
109
42
-
# get a sorted list derivative order such that highest order is first. This is useful when substituting rules
# Full rules for substituting parameters in the inner expression
113
+
rsubs(I) =vcat([v => s.discvars[v][I] for v in s.vars], [_rsubs(x, I) for x inparams(s)])
114
+
# Discretization func for u
115
+
ufunc_u(v, I, x) = s.discvars[v][I]
45
116
117
+
# 2nd order finite difference in u
118
+
exprhere =substitute(innerexpr, rsubs(II))
119
+
# Catch the r ≈ 0 case
120
+
ifsubstitute(r, _rsubs(r, II)) ≈0
121
+
D_2_u =central_difference(D_2, II, s, (s.x2i(r), r), u, ufunc_u)
122
+
return3exprhere*D_2_u # See appendix B of the paper
123
+
124
+
D_1_u =central_difference(D_1, II, s, (s.x2i[r], r), u, ufunc_u)
125
+
# See scheme 1 in appendix A of the paper
126
+
127
+
return exprhere*(D_1_u/substitute(r, _rsubs(r, II)) +cartesian_nonlinear_laplacian(innerexpr, II, derivweights, s, r, u))
128
+
end
129
+
130
+
"""
131
+
`generate_finite_difference_rules`
132
+
133
+
Generate a vector of finite difference rules to dictate what to replace variables in the `pde` with at the gridpoint `II`.
134
+
135
+
Care is taken to make sure that the rules only use points that are actually in the discretized grid by progressively up/downwinding the stencils when the gridpoint `II` is close to the boundary.
136
+
137
+
There is a genral catch all ruleset that uses the cartesian centered difference scheme for derivatives, and simply the discretized variable at the given gridpoint for particular variables.
138
+
139
+
There are of course more specific schemes that are used to improve stability/speed/accuracy when particular forms are encountered in the PDE. These rules are applied first to override the general ruleset.
140
+
141
+
##Currently implemented special cases are as follows:
142
+
- Spherical derivatives
143
+
- Nonlinear laplacian uses a half offset centered scheme for the inner derivative to improve stability
144
+
- Spherical nonlinear laplacian.
145
+
146
+
##Planned special cases include:
147
+
- Up/Downwind schemes to be used for odd ordered derivatives multiplied by a coefficient, downwinding when the coefficient is positive, and upwinding when the coefficient is negative.
148
+
149
+
Please submit an issue if you know of any special cases that are not implemented, with links to papers and/or code that demonstrates the special case.
rs = [(Differential(x)^d)(u) =>central_difference(derivweights.map[Differential(x)^d], II, s, (j,x), u, central_ufunc) for d in derivweights.orders[x], u in s.vars]
57
162
58
-
valrules =vcat([s.vars[k] => s.discvars[k][II] for k in1:length(s.vars)],
59
-
[s.nottime[j] => s.grid[j][II[j]] for j in1:nparams(s)])
for (j, iv) inenumerate(s.nottime) for (k, dv) inenumerate(s.vars)]))
178
+
cartesian_deriv_rules = [@rule ($(Differential(x))(*(~~a, $(Differential(x))(u), ~~b))) =>cartesian_nonlinear_laplacian(*(a..., b...), II, derivweights, s, x, u) for x in s.nottime, u in s.vars]
[@rule ($(Differential(x))($(Differential(x))(u)/~a)) =>cartesian_nonlinear_laplacian(1/~a, II, derivweights, s, x, u) for x in s.nottime, u in s.vars]))
0 commit comments