Skip to content
This repository was archived by the owner on Jul 19, 2023. It is now read-only.

Commit aaa0645

Browse files
committed
Fixed ccd and chalfcd
1 parent d1a2fce commit aaa0645

1 file changed

Lines changed: 19 additions & 55 deletions

File tree

src/derivative_operators/derivative_operator.jl

Lines changed: 19 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ function CenteredDifference{N}(derivative_order::Int,
133133
low_boundary_x = [zero(T); cumsum(dx[1:boundary_stencil_length-1])]
134134
high_boundary_x = cumsum(dx[end-boundary_stencil_length+1:end])
135135
# Because it's a N x (N+2) operator, the last stencil on the sides are the [b,0,x,x,x,x] stencils, not the [0,x,x,x,x,x] stencils, since we're never solving for the derivative at the boundary point.
136-
deriv_spots = (-div(stencil_length,2)+1) : -1
136+
deriv_spots = (-div(stencil_length,2)+1) : -1>
137137

138138
stencil_coefs = [convert(SVector{stencil_length, T}, calculate_weights(derivative_order, zero(T), generate_coordinates(i, stencil_x, dummy_x, dx))) for i in interior_x]
139139
_low_boundary_coefs = SVector{boundary_stencil_length, T}[convert(SVector{boundary_stencil_length, T},
@@ -181,8 +181,8 @@ function CompleteCenteredDifference{N}(derivative_order::Int,
181181
boundary_point_count = div(stencil_length,2) # -1 due to the ghost point
182182
# Because it's a N x (N+2) operator, the last stencil on the sides are the [b,0,x,x,x,x] stencils, not the [0,x,x,x,x,x] stencils, since we're never solving for the derivative at the boundary point.
183183
#deriv_spots = (-div(stencil_length,2)+1) : -1 # unused
184-
L_boundary_deriv_spots = left_boundary_x[0:div(stencil_length,2)]
185-
R_boundary_deriv_spots = right_boundary_x[0:div(stencil_length,2)]
184+
L_boundary_deriv_spots = left_boundary_x[1:div(stencil_length,2)]
185+
R_boundary_deriv_spots = right_boundary_x[1:div(stencil_length,2)]
186186

187187
stencil_coefs = convert(SVector{stencil_length, T}, (1/dx^derivative_order) * calculate_weights(derivative_order, zero(T), dummy_x))
188188
_low_boundary_coefs = SVector{boundary_stencil_length, T}[convert(SVector{boundary_stencil_length, T}, (1/dx^derivative_order) * calculate_weights(derivative_order, oneunit(T)*x0, left_boundary_x)) for x0 in L_boundary_deriv_spots]
@@ -208,69 +208,33 @@ function CompleteCenteredDifference{N}(derivative_order::Int,
208208
)
209209
end
210210

211-
struct CompleteCenteredDifference{N} end
212211

213212
"""
214-
A helper function to compute the coefficients of a derivative operator including the boundary coefficients in the centered scheme.
213+
A helper function to compute the coefficients of a derivative operator including the boundary coefficients in the half centered scheme. See table 2 in https://web.njit.edu/~jiang/math712/fornberg.pdf
215214
"""
216-
function FoorwardHalfDifference(derivative_order::Int,
215+
function CompleteHalfCenteredDifference(derivative_order::Int,
217216
approximation_order::Int, dx::T,
218-
len::Int, coeff_func=1) where {T<:Real,N}
217+
len::Int, isforward=false) where {T<:Real,N}
219218
@assert approximation_order>1 "approximation_order must be greater than 1."
220-
stencil_length = derivative_order + approximation_order - 1 + (derivative_order+approximation_order)%2
219+
stencil_length = approximation_order + 2*floor(derivative_order/2) + 2*(approximation_order%2)
221220
boundary_stencil_length = derivative_order + approximation_order
222-
dummy_x = -div(stencil_length,2) : div(stencil_length,2)
223-
left_boundary_x = 0:(boundary_stencil_length-1)
224-
right_boundary_x = reverse(-boundary_stencil_length+1:0)
221+
endpoint = (stencil_length-1)/2
222+
dummy_x = -endpoint : endpoint
223+
left_boundary_x = -1:(boundary_stencil_length-1)
224+
right_boundary_x = reverse(-boundary_stencil_length+1:1)
225225

226-
boundary_point_count = div(stencil_length,2)# -1 due to the ghost point
227-
# Because it's a N x (N+2) operator, the last stencil on the sides are the [b,0,x,x,x,x] stencils, not the [0,x,x,x,x,x] stencils, since we're never solving for the derivative at the boundary point.
228-
#deriv_spots = (-div(stencil_length,2)+1) : -1 # unused
229-
L_boundary_deriv_spots = left_boundary_x[0:div(stencil_length,2)]
230-
R_boundary_deriv_spots = right_boundary_x[0:div(stencil_length,2)]
226+
# ? Is fornberg valid when taking an x0 outside of the stencil i.e at the boundary?
227+
xoffset = isforward ? convert(T, 0.5) : convert(T, -0.5)
231228

232-
stencil_coefs = convert(SVector{stencil_length, T}, (1/dx^derivative_order) * calculate_weights(derivative_order, convert(T, 0.5), dummy_x))
233-
_low_boundary_coefs = SVector{boundary_stencil_length, T}[convert(SVector{boundary_stencil_length, T}, (1/dx^derivative_order) * calculate_weights(derivative_order, oneunit(T)*x0 + convert(T, 0.5), left_boundary_x)) for x0 in L_boundary_deriv_spots]
234-
low_boundary_coefs = convert(SVector{boundary_point_count},vcat(_low_boundary_coefs))
235229

236-
# _high_boundary_coefs = SVector{boundary_stencil_length, T}[convert(SVector{boundary_stencil_length, T}, (1/dx^derivative_order) * calculate_weights(derivative_order, oneunit(T)*x0, reverse(right_boundary_x))) for x0 in R_boundary_deriv_spots]
237-
high_boundary_coefs = convert(SVector{boundary_point_count},reverse(map(reverse, _low_boundary_coefs*(-1)^derivative_order)))
238-
239-
offside = 0
240-
241-
coefficients = fill!(Vector{T}(undef,len),0)
242-
243-
244-
DerivativeOperator{T,1,false,T,typeof(stencil_coefs),
245-
typeof(low_boundary_coefs),typeof(high_boundary_coefs),typeof(coefficients),
246-
typeof(coeff_func)}(
247-
derivative_order, approximation_order, dx, len, stencil_length,
248-
stencil_coefs,
249-
boundary_stencil_length,
250-
boundary_point_count,
251-
low_boundary_coefs,
252-
high_boundary_coefs,offside,coefficients,coeff_func
253-
)
254-
end
255-
256-
function ReverseHalfDifference(derivative_order::Int,
257-
approximation_order::Int, dx::T,
258-
len::Int, coeff_func=1) where {T<:Real,N}
259-
@assert approximation_order>1 "approximation_order must be greater than 1."
260-
stencil_length = derivative_order + approximation_order - 1 + (derivative_order+approximation_order)%2
261-
boundary_stencil_length = derivative_order + approximation_order
262-
dummy_x = -div(stencil_length,2) : div(stencil_length,2)
263-
left_boundary_x = 0:(boundary_stencil_length-1)
264-
right_boundary_x = reverse(-boundary_stencil_length+1:0)
265-
266-
boundary_point_count = div(stencil_length,2)# -1 due to the ghost point
230+
boundary_point_count = div(stencil_length,2) # -1 due to the ghost point
267231
# Because it's a N x (N+2) operator, the last stencil on the sides are the [b,0,x,x,x,x] stencils, not the [0,x,x,x,x,x] stencils, since we're never solving for the derivative at the boundary point.
268232
#deriv_spots = (-div(stencil_length,2)+1) : -1 # unused
269-
L_boundary_deriv_spots = left_boundary_x[0:div(stencil_length,2)]
270-
R_boundary_deriv_spots = right_boundary_x[0:div(stencil_length,2)]
233+
L_boundary_deriv_spots = left_boundary_x[1:div(stencil_length,2)]
234+
R_boundary_deriv_spots = right_boundary_x[1:div(stencil_length,2)]
271235

272-
stencil_coefs = convert(SVector{stencil_length, T}, (1/dx^derivative_order) * calculate_weights(derivative_order, convert(T, -0.5), dummy_x))
273-
_low_boundary_coefs = SVector{boundary_stencil_length, T}[convert(SVector{boundary_stencil_length, T}, (1/dx^derivative_order) * calculate_weights(derivative_order, oneunit(T)*x0 + convert(T, -0.5), left_boundary_x)) for x0 in L_boundary_deriv_spots]
236+
stencil_coefs = convert(SVector{stencil_length, T}, (1/dx^derivative_order) * calculate_weights(derivative_order, zero(T), dummy_x))
237+
_low_boundary_coefs = SVector{boundary_stencil_length, T}[convert(SVector{boundary_stencil_length, T}, (1/dx^derivative_order) * calculate_weights(derivative_order, oneunit(T)*x0+xoffset, left_boundary_x)) for x0 in L_boundary_deriv_spots]
274238
low_boundary_coefs = convert(SVector{boundary_point_count},vcat(_low_boundary_coefs))
275239

276240
# _high_boundary_coefs = SVector{boundary_stencil_length, T}[convert(SVector{boundary_stencil_length, T}, (1/dx^derivative_order) * calculate_weights(derivative_order, oneunit(T)*x0, reverse(right_boundary_x))) for x0 in R_boundary_deriv_spots]
@@ -281,7 +245,7 @@ function ReverseHalfDifference(derivative_order::Int,
281245
coefficients = fill!(Vector{T}(undef,len),0)
282246

283247

284-
DerivativeOperator{T,1,false,T,typeof(stencil_coefs),
248+
DerivativeOperator{T,N,false,T,typeof(stencil_coefs),
285249
typeof(low_boundary_coefs),typeof(high_boundary_coefs),typeof(coefficients),
286250
typeof(coeff_func)}(
287251
derivative_order, approximation_order, dx, len, stencil_length,

0 commit comments

Comments
 (0)