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

Commit 1b7dc2f

Browse files
committed
Added a {dim} version of all BC constructors,
Fleshed out PartiallyComposedBCs
1 parent 7674c3d commit 1b7dc2f

File tree

2 files changed

+80
-32
lines changed

2 files changed

+80
-32
lines changed

src/derivative_operators/BC_operators.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Creates a periodic boundary condition, where the lower index end of some u is ex
1818
It is not reccomended to concretize this BC type in to a BandedMatrix, since the vast majority of bands will be all 0s. SpatseMatrix concretization is reccomended.
1919
"""
2020
struct PeriodicBC{T} <: AtomicBC{T}
21+
PeriodicBC(T::Type) = new{T}()
2122
end
2223

2324
"""

src/derivative_operators/multi_dim_bc_operators.jl

Lines changed: 79 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -54,42 +54,60 @@ struct ComposedMultiDimBC{T, B<:AtomicBC{T}, N,M} <: MultiDimensionalBC{T, N}
5454
BCs::Vector{Array{B, M}}
5555
end
5656

57-
struct PartiallyComposedMultiDimBC{T,B<:MultiDimDirectionalBC,N,L} <:MultiDimensionalBC{T,N}
57+
struct PartiallyComposedMultiDimBC{T,B<:Union{MultiDimDirectionalBC, Nothing},N, is_extended} <:MultiDimensionalBC{T,N}
5858
BCs::Vector{B}
5959
end
6060

61-
function Base.:+(Q1::MultiDimDirectionalBC{T,B1,D1,N,M}, Q2::MultiDimDirectionalBC{T,B2,D2,N,M}) where {T,B1, B2,D1,D2,N,M}
62-
@assert D1 != D2 "BCs should all extend along a unique axis"
63-
return PartiallyComposedMultiDimBC{T,Union{typeof(Q1),typeof(Q2)}, N,2}(Array[Q1,Q2])
64-
end
61+
numextended
6562

66-
function Base.:+(Q1::MultiDimDirectionalBC{T,B1,D1,2,1}, Q2:: MultiDimDirectionalBC{T,B2,D2,2,1}) where {T,B1,B2,D1,D2}
67-
return compose(Q1,Q2)
68-
end
6963

70-
function Base.:+(Q::PartiallyComposedMultiDimBC{T,B,N,L}, Q1::MultiDimDirectionalBC) where {T,B,N,M,L}
71-
new_BCs = vcat(Q.BCs,Q1)
72-
if L+1 == N
73-
return compose(new_BCs...)
74-
elseif !(getaxis(Q1) in getaxis.(Q.BCs))
75-
return PartiallyComposedMultiDimBC{T,eltype(new_BCs), N,L-1}(new_BCs)
76-
else
77-
throw("BCs should all extend along a unique axis")
64+
function Base._:+(BCs::MultiDimDirectionalBC{T}...) where T
65+
D = getaxis.(BCs)
66+
BCs = BCs[sortperm([D...])]
67+
B = typeof.(BCs)
68+
dimensionalities = ndims.(BCs)
69+
for n in dimensionalities[2:end]
70+
@assert dimensionalites[1] == n "There are "
71+
72+
for d in D
73+
@assert length(setdiff(D, d)) == (N-1) "There are multiple boundary conditions that extend along $d - make sure every dimension has a unique extension"
7874
end
75+
is_extended = falses(length(ndims(BCs[1]))
76+
is_extended[D] .= true
77+
A = Vector{Union{B..., Nothing}}(undef, ndims(BCs[1]))
78+
A[!is_extended] .= Nothing()
79+
for (i,BC) in enumerate(BCs)
80+
A[is_extended][i] = BC
81+
end
82+
return PartiallyComposedMultiDimBC{T, eltype(A), N, is_extended}(A)
83+
end
84+
85+
86+
function Base.:+(Q::PartiallyComposedMultiDimBC{T,B,N,L}, Q1::MultiDimDirectionalBC{T, B2, D, N, M}) where {T,D, B1, B2,N,M,L}
87+
new_BCs = Q.BCs
88+
new_BCs[D] = Q1
89+
is_extended = L
90+
is_extended[D] = true
91+
@assert !(getaxis(Q1) in getaxis.(Q.BCs)) "BCs should all extend along a unique axis"
92+
return PartiallyComposedMultiDimBC{T,eltype(new_BCs), N,is_extended}(new_BCs)
93+
7994
end
8095

8196
Base.:+(Q1::MultiDimDirectionalBC, Q::PartiallyComposedMultiDimBC) = +(Q,Q1)
8297

83-
function Base.:+(Q1::PartiallyComposedMultiDimBC{T,B1,N,L1} Q2::PartiallyComposedMultiDimBC{T,B2,N,L2) where {T,B1,B2,N,L1,L2}
84-
new_BCs = vcat(Q1.BCs, Q2.BCs)
85-
if L1 + L2 < N
86-
@assert length(setdiff(1:N, getaxis.(new_BCs))) == (N-L1-L2) "BCs should all extend along a unique axis"
87-
return PartiallyComposedMultiDimBC{T,Union{B1,B2}, N, L1+ L2}(new_BCs)
88-
elseif L1+L2 == N
89-
return compose(new_BCs...)
90-
else
91-
throw("Too many supplied BCs for the number of dimensions")
92-
end
98+
function Base.:+(Q1::PartiallyComposedMultiDimBC{T,B1,N,L1} Q2::PartiallyComposedMultiDimBC{T,B2,N,L2}) where {T,B1,B2,N,L1,L2}
99+
new_BCs = deepcopy(Q1.BCs)
100+
Lnew = L1 .| L2
101+
for (i,q) in enumerate(Q2.BCs)
102+
if q <: MultiDimensionalBC
103+
if new_BCs[i] <: Nothing
104+
new_BCs[i] = q
105+
else
106+
throw("BCs should all extend along a unique axis")
107+
end
108+
end
109+
end
110+
return PartiallyComposedMultiDimBC{T,Union{B1,B2}, N, Lnew}(new_BCs)
93111
end
94112

95113
"""
@@ -121,6 +139,11 @@ For Neumann0BC, please use
121139
where T is the element type of the domain to be extended
122140
"""
123141
struct MultiDimBC{N} end
142+
struct NeumannBC{N} end
143+
struct Neumann0BC{N} end
144+
struct DirichletBC{N} end
145+
struct Dirichlet0BC{N} end
146+
124147
MultiDimBC{dim}(BC::Array{B,N}) where {N, B<:AtomicBC, dim} = MultiDimDirectionalBC{gettype(BC[1]), B, dim, N+1, N}(BC)
125148
#s should be size of the domain
126149
MultiDimBC{dim}(BC::B, s) where {B<:AtomicBC, dim} = MultiDimDirectionalBC{gettype(BC), B, dim, length(s), length(s)-1}(fill(BC, s[setdiff(1:length(s), dim)]))
@@ -129,17 +152,26 @@ MultiDimBC{dim}(BC::B, s) where {B<:AtomicBC, dim} = MultiDimDirectionalBC{gett
129152
#Only valid in the uniform grid case!
130153
MultiDimBC(BC::B, s) where {B<:AtomicBC} = Tuple([MultiDimDirectionalBC{gettype(BC), B, dim, length(s), length(s)-1}(fill(BC, s[setdiff(1:length(s), dim)])) for dim in 1:length(s)])
131154

132-
# Additional constructors for cases when the BC is the same for all boundarties
133-
134-
PeriodicBC{T}(s) where T = MultiDimBC(PeriodicBC{T}(), s)
155+
# Additional constructors for cases when the BC is the same for all boundarties
156+
PeriodicBC{dim}(T,s) where T = MultiDimBC{dim}(PeriodicBC(T), s)
157+
PeriodicBC(T,s) where T = MultiDimBC(PeriodicBC(T), s)
135158

159+
NeumannBC{dim}::NTuple{2,T}, dx, order, s) where T = RobinBC{dim}((zero(T), one(T), α[1]), (zero(T), one(T), α[2]), dx, order, s)
136160
NeumannBC::NTuple{2,T}, dxyz, order, s) where T = RobinBC((zero(T), one(T), α[1]), (zero(T), one(T), α[2]), dxyz, order, s)
161+
162+
DirichletBC{dim}(αl::T, αr::T, s) where T = RobinBC{dim}((one(T), zero(T), αl), (one(T), zero(T), αr), [ones(T, si) for si in s], 2.0, s)
137163
DirichletBC(αl::T, αr::T, s) where T = RobinBC((one(T), zero(T), αl), (one(T), zero(T), αr), [ones(T, si) for si in s], 2.0, s)
138164

165+
Dirichlet0BC{dim}(T::Type, s) = DirichletBC{dim}(zero(T), zero(T), s)
139166
Dirichlet0BC(T::Type, s) = DirichletBC(zero(T), zero(T), s)
167+
168+
Neumann0BC{dim}(T::Type, dx, order, s) = NeumannBC{dim}((zero(T), zero(T)), dx, order, s)
140169
Neumann0BC(T::Type, dxyz, order, s) = NeumannBC((zero(T), zero(T)), dxyz, order, s)
141170

171+
RobinBC{dim}(l::NTuple{3,T}, r::NTuple{3,T}, dx, order, s) where {T} = MultiDimBC{dim}(RobinBC(l, r, dx, order), s)
142172
RobinBC(l::NTuple{3,T}, r::NTuple{3,T}, dxyz, order, s) where {T} = Tuple([MultiDimDirectionalBC{T, RobinBC{T}, dim, length(s), length(s)-1}(fill(RobinBC(l, r, dxyz[dim], order), perpindex(s,dim))) for dim in 1:length(s)])
173+
174+
GeneralBC{dim}(αl::AbstractVector{T}, αr::AbstractVector{T}, dx, order, s) where {T} = MultiDimBC{dim}(GeneralBC(αl, αr, dx, order), s)
143175
GeneralBC(αl::AbstractVector{T}, αr::AbstractVector{T}, dxyz, order, s) where {T} = Tuple([MultiDimDirectionalBC{T, GeneralBC{T}, dim, length(s), length(s)-1}(fill(GeneralBC(αl, αr, dxyz[dim], order),perpindex(s,dim))) for dim in 1:length(s)])
144176

145177

@@ -157,7 +189,7 @@ Creates a ComposedMultiDimBC operator, Q, that extends every boundary when appli
157189
158190
Qx Qy and Qz can be passed in any order, as long as there is exactly one BC operator that extends each dimension.
159191
"""
160-
function compose(BCs...)
192+
function compose(BCs::MultiDimDirectionalBC...)
161193
T = gettype(BCs[1])
162194
N = ndims(BCs[1])
163195
Ds = getaxis.(BCs)
@@ -170,6 +202,8 @@ function compose(BCs...)
170202
ComposedMultiDimBC{T, Union{eltype.(BC.BCs for BC in BCs)...}, N,N-1}([condition.BCs for condition in BCs])
171203
end
172204

205+
Base.:+(BCs::MultiDimDirectionalBC...) = compose(BCs...)
206+
173207
"""
174208
Qx, Qy,... = decompose(Q::ComposedMultiDimBC{T,N,M})
175209
@@ -198,5 +232,18 @@ function Base.:*(Q::ComposedMultiDimBC{T, B, N, K}, u::AbstractArray{T, N}) wher
198232
return ComposedBoundaryPaddedArray{T, N, K, typeof(u), typeof(out[1][1])}([A[1] for A in out], [A[2] for A in out], u)
199233
end
200234

201-
function Base.:*(Q::PartiallyComposedMultiDimBC, u::AbstractArray{T,N} where {T,N}
202-
return Tuple([MultiDimDirectionalBC
235+
236+
237+
function Base.:*(Q::PartiallyComposedMultiDimBC{T,B,N,is_extended}, u::AbstractArray{T,N} where {T,N}
238+
lower = Vector{Union{Array{T,N-1}, Nothing}}(undef, N)
239+
upper = Vector{Union{Array{T,N-1}, Nothing}}(undef, N)
240+
for (i,q) in Q.BCs
241+
if !(q <: Nothing)
242+
lower[i], upper[i] = slice_rmul(q, u)
243+
else
244+
lower[i] = Nothing()
245+
upper[i] = Nothing()
246+
end
247+
end
248+
return PartiallyComposedBoundaryPaddedArray{}(lower,upper,u)
249+
end

0 commit comments

Comments
 (0)