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

Commit 7ce6675

Browse files
committed
expanded comment about GeneralBC, fixed some type instability
1 parent ab7391f commit 7ce6675

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

src/derivative_operators/BC_operators.jl

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
abstract type AbstractBC{T} end
22

3-
# robin, general, and in general neumann BCs are all affine. neumann0 is not however; is a specialization needed?
3+
# robin, general, and in general neumann BCs are all affine opeartors, meaning that they take the form Qx = Qax + Qb. neumann0 is not however; is a specialization needed?
44
abstract type AffineBC{T,V} <: AbstractBC{T} end
55

66
struct DirichletBC{T} <: AbstractBC{T}
@@ -36,16 +36,14 @@ end
3636
3737
the variables in correspond to al*u(0) + bl*u'(0) = cl
3838
39-
40-
Write vector b̄_1 as a vertical concatanation with b0 and the rest of the elements of b̄_1, denoted b̄`_1, the same with ū into u0 and ū`. b̄` = fill(β/Δx, length(stencil)-1)
39+
Write vector b̄₁ as a vertical concatanation with b0 and the rest of the elements of b̄ ₁, denoted b̄`₁, the same with ū into u0 and ū`. b̄`₁ = b̄`_2 = fill(β/Δx, length(stencil)-1)
4140
Pull out the product of u0 and b0 from the dot product. The stencil used to approximate u` is denoted s. b0 = α+(β/Δx)*s[1]
42-
Rearrange terms to find a general formula for u0:= -b̄`_1̇⋅ū`/b0 + γ/b0, which is dependent on ū` the robin coefficients and Δx.
43-
The non identity part of Qa is qa:= -b`_1/b0 = -β.*s[2:end]/(α+β*s[1]/Δx). The constant part is Qb = γ/(α+β*s[1]/Δx)
44-
do the same at the other boundary (amounts to a flip in s with the right boundary coeffs)
41+
Rearrange terms to find a general formula for u0:= -b̄`₁̇⋅ū`/b0 + γ/b0, which is dependent on ū` the robin coefficients and Δx.
42+
The non identity part of Qa is qa:= -b`/b0 = -β.*s[2:end]/(α+β*s[1]/Δx). The constant part is Qb = γ/(α+β*s[1]/Δx)
43+
do the same at the other boundary (amounts to a flip of s[2:end], with the other set of boundary coeffs)
4544
"""
4645

4746
# For condition, the variables correspond to al*u(0) + bl*u'(0) = cl
48-
# this should not break
4947
struct RobinBC{T, V<:AbstractVector{T}} <: AffineBC{T,V}
5048
a_l::V
5149
b_l::T
@@ -56,7 +54,7 @@ struct RobinBC{T, V<:AbstractVector{T}} <: AffineBC{T,V}
5654
cr, ar, br = r
5755
dx_l, dx_r = dx
5856

59-
s = calculate_weights(1, zero(T), zero(T):order) #generate derivative coefficients about the boundary of required approximation order
57+
s = calculate_weights(1, zero(T), zero(T):convert(T,order)) #generate derivative coefficients about the boundary of required approximation order
6058

6159
a_l = -bl.*s[2:end]./(al .+ bl*s[1]./dx_l)
6260
a_r = -br.*s[end:-1:2]./(ar .+ br*s[1]./dx_r)
@@ -71,7 +69,11 @@ end
7169
"""
7270
Implements a generalization of the Robin boundary condition, where α is a vector of coefficients.
7371
Represents a condition of the form α[1] + α[2]u[0] + α[3]u'[0] + α[4]u''[0]+... = 0
74-
Implemented in an analogous way to the RobinBC
72+
Implemented in a similar way to the RobinBC (see above).
73+
74+
This time there are multiple stencils for multiple derivative orders - these can be written as a matrix S.
75+
All components that multiply u(0) are factored out, turns out to only involve the first colum of S, s̄0. The rest of S is denoted S`. the coeff of u(0) is s̄0⋅ᾱ[3:end] + α[2].
76+
the remaining components turn out to be ᾱ[3:end]⋅(S`ū`) or equivalantly (transpose(ᾱ[3:end])*S`)⋅ū`. Rearranging, a stencil q_a to be dotted with ū` upon extension can readily be found, along with a constant component q_b
7577
"""
7678
#If you know a more correct name for this kind of BC, please post an issue/PR
7779
struct GeneralBC{T, V<:AbstractVector{T}} <:AffineBC{T,V}
@@ -87,19 +89,19 @@ struct GeneralBC{T, V<:AbstractVector{T}} <:AffineBC{T,V}
8789
S_r = zeros(T, (nr-2, order+nr-2))
8890

8991
for i in 1:(nl-2)
90-
S_l[i,:] = [transpose(calculate_weights(i, zero(T), zero(T):(order+i))) transpose(zeros(T, nl-2-i))] #am unsure if the length of the dummy_x is correct here
92+
S_l[i,:] = [transpose(calculate_weights(i, zero(T), zero(T):convert(T, (order+i))) transpose(zeros(T, nl-2-i))] #am unsure if the length of the dummy_x is correct here
9193
end
9294
for i in 1:(nr-2)
93-
S_r[i,:] = [transpose(calculate_weights(i, zero(T), zero(T):(order+i))) transpose(zeros(T, nr-2-i))]
95+
S_r[i,:] = [transpose(calculate_weights(i, zero(T), zero(T):convert(T, order+i))) transpose(zeros(T, nr-2-i))]
9496
end
9597
s0_l = S_l[:,1] ; Sl = S_l[2:end,:]
9698
s0_r = S_r[:,1] ; Sr = S_r[2:end,:]
9799

98100
denoml = αl[2] .+ αl[3:end] s0_l
99101
denomr = αr[2] .+ αr[3:end] s0_r
100102

101-
a_l = -transpose(αl) Sl ./denoml
102-
a_r = -transpose(αr) Sr ./denomr
103+
a_l = -transpose(αl) * Sl ./denoml
104+
a_r = -transpose(αr) * Sr ./denomr
103105

104106
b_l = -αl[1]/denoml
105107
b_r = -αr[1]/denomr
@@ -113,14 +115,14 @@ RobinBC(al::T, bl::T, cl::T, dx_l::T, ar::T, br::T, cr::T, dx_r::T, order::T) wh
113115

114116
NeumannBC(l::T, dx_l::T, r::T, dx_r::T) where T = NeumannBC(l, r, [dx_l,dx_r])
115117
NeumannBC(l::T, dx_l::T, r::T, dx_r::T, order::T) where T = NeumannBC(l, r, [dx_l,dx_r], order)
118+
116119
# this is 'boundary padded vector' as opposed to 'boundary padded array' to distinguish it from the n dimensional implementation that will eventually be neeeded
117120
struct BoundaryPaddedVector{T,T2 <: AbstractVector{T}}
118121
l::T
119122
r::T
120123
u::T2
121124
end
122125

123-
124126
Base.:*(Q::DirichletBC, u) = BoundaryPaddedVector(Q.l,Q.r,u)
125127
Base.:*(Q::PeriodicBC, u) = BoundaryPaddedVector(u[end], u[1], u)
126128
Base.:*(Q::AffineBC, u) = BoundaryPaddedVector(Q.a_l u[1:length(Q.a_l)] + Q.b_l, Q.a_r u[(end-length(Q.a_r)+1):end] + Q.b_r, u)
@@ -140,9 +142,9 @@ function Base.getindex(Q::BoundaryPaddedVector,i)
140142
end
141143
end
142144

143-
function LinearAlgebra.Array(Q::AffineBC, N::Int)
144-
Q_L = [transpose(Q.a_l) transpose(zeros(N-length(Q.a_l))); Diagonal(ones(N)); transpose(zeros(N-length(Q.a_r))) transpose(Q.a_r)]
145-
Q_b = [Q.b_l; zeros(N); Q.b_r]
145+
function LinearAlgebra.Array(Q::AffineBC{T,V}, N::Int) where {T,V}
146+
Q_L = [transpose(Q.a_l) transpose(zeros(T, N-length(Q.a_l))); Diagonal(ones(T,N)); transpose(zeros(T, N-length(Q.a_r))) transpose(Q.a_r)]
147+
Q_b = [Q.b_l; zeros(T,N); Q.b_r]
146148
return (Q_L, Q_b)
147149
end
148150

0 commit comments

Comments
 (0)