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

(WIP) Safer handling of DerivativeOperator.coefficients #244

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
2 changes: 1 addition & 1 deletion src/DiffEqOperators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ include("derivative_operators/multi_dim_bc_operators.jl")

### Derivative Operators
include("derivative_operators/fornberg.jl")
include("derivative_operators/coefficients.jl")
include("derivative_operators/derivative_operator.jl")
include("derivative_operators/abstract_operator_functions.jl")
include("derivative_operators/convolutions.jl")
include("derivative_operators/ghost_derivative_operator.jl")
include("derivative_operators/derivative_operator_functions.jl")
include("derivative_operators/coefficient_functions.jl")

### Composite Operators
include("composite_operators.jl")
Expand Down
67 changes: 0 additions & 67 deletions src/derivative_operators/coefficient_functions.jl

This file was deleted.

32 changes: 32 additions & 0 deletions src/derivative_operators/coefficients.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""
```
init_coefficients(coeff_func, len::Int)
```

Return the initial value of an operator's `coefficients` field based on the type
of `coeff_func`.
"""
init_coefficients(coeff_func::Nothing, len::Int) = nothing

init_coefficients(coeff_func::Number, len::Int) = coeff_func * ones(typeof(coeff_func), len)

function init_coefficients(coeff_func::AbstractVector{T}, len::Int) where T <: Number
coeff_func
end

init_coefficients(coeff_func::Function, len::Int) = ones(Float64, len)



"""
```
get_coefficient(coefficients, index)
```
"""
get_coefficient(coefficients::AbstractVector, index::Int) = coefficients[index]

# FIXME: I don't think this case is used anymore
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case was covered by a subset of convolution functions, but I don't know what the use-case is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's for a constant coefficient, like D*A so a constant diffusion. If the coefficient is a number, then the whole setup is actually a bitstype so it'll compile to the GPU and distribute much better, and this is a common case so it's worth supporting. I think that one function is really all that's necessary to support it.

get_coefficient(coefficients::Number, index::Int) = coefficients

# FIXME: Why use "true" here for the value 1?
get_coefficient(coefficients::Nothing, index::Int) = true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true is a hard 1 in Julia. true will convert to any type, so it's the recommended value if you want it to promote in further operations.

44 changes: 22 additions & 22 deletions src/derivative_operators/concretization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ function Base.copyto!(L::AbstractMatrix{T}, A::DerivativeOperator{T}, N::Int) wh
bstl = A.boundary_stencil_length

coeff = A.coefficients
get_coeff = if coeff isa AbstractVector
i -> coeff[i]
get_coeff(i) = if coeff isa AbstractVector
get_coefficient(coeff, i)
elseif coeff isa Number
i -> coeff
coeff
else
i -> true
true
end

for i in 1:bl
Expand Down Expand Up @@ -451,7 +451,7 @@ function LinearAlgebra.Array(A::DerivativeOperator{T,N,true}, len::Int=A.len) wh
stencils = A.stencil_coefs

for i in 1:bpc
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
if cur_coeff >= 0
cur_stencil = stencils
L[i,i+1:i+stl] = cur_coeff*cur_stencil
Expand All @@ -462,7 +462,7 @@ function LinearAlgebra.Array(A::DerivativeOperator{T,N,true}, len::Int=A.len) wh
end

for i in bpc+1:len-bpc
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
cur_stencil = stencils
cur_stencil = cur_coeff >= 0 ? cur_stencil : ((-1)^A.derivative_order)*reverse(cur_stencil)
if cur_coeff >= 0
Expand All @@ -473,7 +473,7 @@ function LinearAlgebra.Array(A::DerivativeOperator{T,N,true}, len::Int=A.len) wh
end

for i in len-bpc+1:len
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very clean. Beautiful.

if cur_coeff < 0
cur_stencil = stencils
cur_stencil = ((-1)^A.derivative_order)*reverse(cur_stencil)
Expand All @@ -495,7 +495,7 @@ function LinearAlgebra.Array(A::DerivativeOperator{T,N,true,M}, len::Int=A.len)
coeff = A.coefficients

for i in 1:bpc
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
if cur_coeff >= 0
L[i,i+1:i+stl] = cur_coeff * A.low_boundary_coefs[1,i]
else
Expand All @@ -504,7 +504,7 @@ function LinearAlgebra.Array(A::DerivativeOperator{T,N,true,M}, len::Int=A.len)
end

for i in bpc+1:len-bpc
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
if cur_coeff >= 0
L[i,i+1:i+stl] = cur_coeff * A.stencil_coefs[1,i-bpc]
else
Expand All @@ -513,7 +513,7 @@ function LinearAlgebra.Array(A::DerivativeOperator{T,N,true,M}, len::Int=A.len)
end

for i in len-bpc+1:len
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
if cur_coeff < 0
L[i,i-stl+2:i+1] = cur_coeff * A.high_boundary_coefs[2,i-len+bpc]
else
Expand All @@ -540,7 +540,7 @@ function SparseArrays.SparseMatrixCSC(A::DerivativeOperator{T,N,true}, len::Int=
stencils = A.stencil_coefs

for i in 1:bpc
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
if cur_coeff >= 0
cur_stencil = stencils
L[i,i+1:i+stl] = cur_coeff*cur_stencil
Expand All @@ -551,7 +551,7 @@ function SparseArrays.SparseMatrixCSC(A::DerivativeOperator{T,N,true}, len::Int=
end

for i in bpc+1:len-bpc
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
cur_stencil = stencils
cur_stencil = cur_coeff >= 0 ? cur_stencil : ((-1)^A.derivative_order)*reverse(cur_stencil)
if cur_coeff >= 0
Expand All @@ -562,7 +562,7 @@ function SparseArrays.SparseMatrixCSC(A::DerivativeOperator{T,N,true}, len::Int=
end

for i in len-bpc+1:len
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
if cur_coeff < 0
cur_stencil = stencils
cur_stencil = ((-1)^A.derivative_order)*reverse(cur_stencil)
Expand All @@ -584,7 +584,7 @@ function SparseArrays.SparseMatrixCSC(A::DerivativeOperator{T,N,true,M}, len::In
coeff = A.coefficients

for i in 1:bpc
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
if cur_coeff >= 0
L[i,i+1:i+stl] = cur_coeff * A.low_boundary_coefs[1,i]
else
Expand All @@ -593,7 +593,7 @@ function SparseArrays.SparseMatrixCSC(A::DerivativeOperator{T,N,true,M}, len::In
end

for i in bpc+1:len-bpc
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
if cur_coeff >= 0
L[i,i+1:i+stl] = cur_coeff * A.stencil_coefs[1,i-bpc]
else
Expand All @@ -602,7 +602,7 @@ function SparseArrays.SparseMatrixCSC(A::DerivativeOperator{T,N,true,M}, len::In
end

for i in len-bpc+1:len
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
if cur_coeff < 0
L[i,i-stl+2:i+1] = cur_coeff * A.high_boundary_coefs[2,i-len+bpc]
else
Expand All @@ -629,7 +629,7 @@ function BandedMatrices.BandedMatrix(A::DerivativeOperator{T,N,true}, len::Int=A
stencils = A.stencil_coefs

for i in 1:bpc
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
if cur_coeff >= 0
cur_stencil = stencils
L[i,i+1:i+stl] = cur_coeff*cur_stencil
Expand All @@ -640,7 +640,7 @@ function BandedMatrices.BandedMatrix(A::DerivativeOperator{T,N,true}, len::Int=A
end

for i in bpc+1:len-bpc
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
cur_stencil = stencils
cur_stencil = cur_coeff >= 0 ? cur_stencil : ((-1)^A.derivative_order)*reverse(cur_stencil)
if cur_coeff >= 0
Expand All @@ -651,7 +651,7 @@ function BandedMatrices.BandedMatrix(A::DerivativeOperator{T,N,true}, len::Int=A
end

for i in len-bpc+1:len
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
if cur_coeff < 0
cur_stencil = stencils
cur_stencil = ((-1)^A.derivative_order)*reverse(cur_stencil)
Expand All @@ -674,7 +674,7 @@ function BandedMatrices.BandedMatrix(A::DerivativeOperator{T,N,true,M}, len::Int
L = BandedMatrix{T}(Zeros(len, len+2), (stl-2, stl))

for i in 1:bpc
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
if cur_coeff >= 0
L[i,i+1:i+stl] = cur_coeff * A.low_boundary_coefs[1,i]
else
Expand All @@ -683,7 +683,7 @@ function BandedMatrices.BandedMatrix(A::DerivativeOperator{T,N,true,M}, len::Int
end

for i in bpc+1:len-bpc
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
if cur_coeff >= 0
L[i,i+1:i+stl] = cur_coeff * A.stencil_coefs[1,i-bpc]
else
Expand All @@ -692,7 +692,7 @@ function BandedMatrices.BandedMatrix(A::DerivativeOperator{T,N,true,M}, len::Int
end

for i in len-bpc+1:len
cur_coeff = coeff[i]
cur_coeff = get_coefficient(coeff, i)
if cur_coeff < 0
L[i,i-stl+2:i+1] = cur_coeff * A.high_boundary_coefs[2,i-len+bpc]
else
Expand Down
Loading