Skip to content
This repository was 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
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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