This repository was archived by the owner on Jul 19, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 70
Expand file tree
/
Copy pathghost_derivative_operator.jl
More file actions
69 lines (57 loc) · 2.46 KB
/
ghost_derivative_operator.jl
File metadata and controls
69 lines (57 loc) · 2.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
struct GhostDerivativeOperator{T, E <: AbstractDiffEqLinearOperator{T}, F <: AbstractBC{T}
} <: AbstractDiffEqLinearOperator{T}
L::E
Q::F
end
function *(L::AbstractDiffEqLinearOperator{T}, Q::AbstractBC{T}) where {T}
return GhostDerivativeOperator{T, typeof(L), typeof(Q)}(L, Q)
end
function *(L::SciMLBase.AbstractDiffEqCompositeOperator{T}, Q::AbstractBC{T}) where {T}
return sum(map(op -> op * Q, L.ops))
end
function LinearAlgebra.mul!(out::AbstractArray, A::GhostDerivativeOperator,
u::AbstractArray)
padded = A.Q * u # assume: creates boundary padded array w/o realloc
LinearAlgebra.mul!(out, A.L, padded)
end
function *(A::GhostDerivativeOperator{T1}, u::AbstractArray{T2}) where {T1, T2}
#TODO Implement a function domaincheck(L::AbstractDiffEqLinearOperator, u) to see if components of L along each dimension match the size of u
x = zeros(promote_type(T1, T2), unpadded_size(u))
LinearAlgebra.mul!(x, A, u)
return x
end
function \(A::GhostDerivativeOperator, u::AbstractArray) # FIXME should have T1,T2 and promote result
#TODO implement check that A has compatible size with u
s = size(u)
(A_l, A_b) = sparse(A, s)
x = A_l \ Vector(reshape(u, length(u)) .- A_b) #Has to be converted to vector to work, A_b being sparse was causing a conversion to sparse.
return reshape(x, s)
end
function \(A::GhostDerivativeOperator, u::AbstractVector) # FIXME as above, should promote_type(T1,T2)
# TODO: is this specialization to u::AbstractVector really any faster?
@assert length(u) == size(A.L, 1)
(A_l, A_b) = sparse(A, length(u))
A_l \ Vector(u .- A_b)
end
# update coefficients
function DiffEqBase.update_coefficients!(A::GhostDerivativeOperator, u, p, t)
DiffEqBase.update_coefficients!(A.L, u, p, t)
end
# Implement multiplication for coefficients
function *(c::Number, A::GhostDerivativeOperator)
(c * A.L) * A.Q
end
function *(c::Vector{<:Number}, A::GhostDerivativeOperator)
(c * A.L) * A.Q
end
function *(coeff_func::Function, A::GhostDerivativeOperator)
(coeff_func * A.L) * A.Q
end
# length and sizes
Base.ndims(A::GhostDerivativeOperator) = 2
Base.size(A::GhostDerivativeOperator) = (A.L.len, A.L.len)
Base.size(A::GhostDerivativeOperator, i::Integer) = size(A)[i]
Base.length(A::GhostDerivativeOperator) = reduce(*, size(A))
@inline function ==(A1::GhostDerivativeOperator, A2::GhostDerivativeOperator)
A1.L == A2.L && A1.Q == A2.Q
end