Mercurial > repos > public > sbplib_julia
comparison src/SbpOperators/volumeops/derivatives/second_derivative_variable.jl @ 889:069e58fb3829 feature/variable_derivatives
Refactor as multidimensional operator
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Mon, 07 Feb 2022 20:38:07 +0100 |
parents | d228d1b26729 |
children | f72cc96a58c6 |
comparison
equal
deleted
inserted
replaced
888:e6d8fd5e8268 | 889:069e58fb3829 |
---|---|
28 """ | 28 """ |
29 SecondDerivativeVariable{T,N,M,K} <: TensorOperator{T,1} | 29 SecondDerivativeVariable{T,N,M,K} <: TensorOperator{T,1} |
30 | 30 |
31 Implements the one-dimensional second derivative with variable coefficients. | 31 Implements the one-dimensional second derivative with variable coefficients. |
32 """ | 32 """ |
33 struct SecondDerivativeVariable{T,N,M,K,TArray<:AbstractVector} <: TensorMapping{T,1,1} | 33 struct SecondDerivativeVariable{Dir,T,D,N,M,K,TArray<:AbstractArray} <: TensorMapping{T,D,D} |
34 inner_stencil::NestedStencil{T,N} | 34 inner_stencil::NestedStencil{T,N} |
35 closure_stencils::NTuple{M,NestedStencil{T,K}} | 35 closure_stencils::NTuple{M,NestedStencil{T,K}} |
36 size::NTuple{1,Int} | 36 size::NTuple{D,Int} |
37 coefficient::TArray | 37 coefficient::TArray |
38 | |
39 function SecondDerivativeVariable{Dir, D}(inner_stencil::NestedStencil{T,N}, closure_stencils::NTuple{M,NestedStencil{T,K}}, size::NTuple{D,Int}, coefficient::TArray) where {Dir,T,D,N,M,K,TArray<:AbstractArray} | |
40 return new{Dir,T,D,N,M,K,TArray}(inner_stencil,closure_stencils,size, coefficient) | |
41 end | |
42 end | |
43 | |
44 function SecondDerivativeVariable(grid::EquidistantGrid, coeff::AbstractArray, inner_stencil, closure_stencils, dir) | |
45 return SecondDerivativeVariable{dir, dimension(grid)}(inner_stencil, Tuple(closure_stencils), size(grid), coeff) | |
38 end | 46 end |
39 | 47 |
40 function SecondDerivativeVariable(grid::EquidistantGrid{1}, coeff::AbstractVector, inner_stencil, closure_stencils) | 48 function SecondDerivativeVariable(grid::EquidistantGrid{1}, coeff::AbstractVector, inner_stencil, closure_stencils) |
41 return SecondDerivativeVariable(inner_stencil, Tuple(closure_stencils), size(grid), coeff) | 49 return SecondDerivativeVariable(grid, coeff, inner_stencil, closure_stencils, 1) |
42 end | 50 end |
51 | |
52 derivative_direction(::SecondDerivativeVariable{Dir}) where {Dir} = Dir | |
43 | 53 |
44 closure_size(::SecondDerivativeVariable{T,N,M}) where {T,N,M} = M | 54 closure_size(::SecondDerivativeVariable{T,N,M}) where {T,N,M} = M |
45 | 55 |
46 LazyTensors.range_size(op::SecondDerivativeVariable) = op.size | 56 LazyTensors.range_size(op::SecondDerivativeVariable) = op.size |
47 LazyTensors.domain_size(op::SecondDerivativeVariable) = op.size | 57 LazyTensors.domain_size(op::SecondDerivativeVariable) = op.size |
48 | 58 |
49 function LazyTensors.apply(op::SecondDerivativeVariable{T}, v::AbstractVector{T}, i::Index{Lower}) where T | 59 |
50 return @inbounds apply_stencil(op.closure_stencils[Int(i)], op.coefficient, v, Int(i)) | 60 function derivative_view(op, a, I) |
61 d = derivative_direction(op) | |
62 | |
63 Iview = Base.setindex(I,:,d) | |
64 return @view a[Iview...] | |
65 | |
66 # D = domain_dim(op) | |
67 # Iₗ, _, Iᵣ = split_tuple(I, Val(d-1), Val(1), Val(D-d)) | |
68 # return @view a[Iₗ..., :, Iᵣ...] | |
51 end | 69 end |
52 | 70 |
53 function LazyTensors.apply(op::SecondDerivativeVariable{T}, v::AbstractVector{T}, i::Index{Interior}) where T | 71 function apply_lower(op::SecondDerivativeVariable, v, I...) |
54 return apply_stencil(op.inner_stencil, op.coefficient, v, Int(i)) | 72 ṽ = derivative_view(op, v, I) |
73 c̃ = derivative_view(op, op.coefficient, I) | |
74 | |
75 i = I[derivative_direction(op)] | |
76 return @inbounds apply_stencil(op.closure_stencils[i], c̃, ṽ, i) | |
55 end | 77 end |
56 | 78 |
57 function LazyTensors.apply(op::SecondDerivativeVariable{T}, v::AbstractVector{T}, i::Index{Upper}) where T | 79 function apply_interior(op::SecondDerivativeVariable, v, I...) |
58 return @inbounds apply_stencil_backwards(op.closure_stencils[op.size[1]-Int(i)+1], op.coefficient, v, Int(i)) | 80 ṽ = derivative_view(op, v, I) |
81 c̃ = derivative_view(op, op.coefficient, I) | |
82 | |
83 i = I[derivative_direction(op)] | |
84 return apply_stencil(op.inner_stencil, c̃, ṽ, i) | |
59 end | 85 end |
60 | 86 |
61 function LazyTensors.apply(op::SecondDerivativeVariable{T}, v::AbstractVector{T}, i) where T | 87 function apply_upper(op::SecondDerivativeVariable, v, I...) |
88 ṽ = derivative_view(op, v, I) | |
89 c̃ = derivative_view(op, op.coefficient, I) | |
90 | |
91 i = I[derivative_direction(op)] | |
92 return @inbounds apply_stencil_backwards(op.closure_stencils[op.size[1]-i+1], c̃, ṽ, i) | |
93 end | |
94 | |
95 function LazyTensors.apply(op::SecondDerivativeVariable, v::AbstractVector, I::Vararg{Index}) | |
96 if I[derivative_direction(op)] isa Index{Lower} | |
97 return apply_lower(op, v, Int.(I)...) | |
98 elseif I[derivative_direction(op)] isa Index{Upper} | |
99 return apply_upper(op, v, Int.(I)...) | |
100 else | |
101 return apply_interior(op, v, Int.(I)...) | |
102 end | |
103 end | |
104 | |
105 function LazyTensors.apply(op::SecondDerivativeVariable, v::AbstractVector, I...) | |
106 i = I[derivative_direction(op)] | |
62 r = getregion(i, closure_size(op), op.size[1]) | 107 r = getregion(i, closure_size(op), op.size[1]) |
63 return LazyTensors.apply(op, v, Index(i, r)) | 108 return LazyTensors.apply(op, v, Index(i, r)) |
64 end | 109 end |
65 | 110 |
66 # TODO: Rename SecondDerivativeVariable -> VariableSecondDerivative | 111 # TODO: Rename SecondDerivativeVariable -> VariableSecondDerivative |