Mercurial > repos > public > sbplib_julia
comparison src/SbpOperators/volumeops/derivatives/second_derivative_variable.jl @ 1367:71e89507dd9a feature/variable_derivatives
Remove size field from SecondDerivativeVariable since it duplicates info from the coefficient field
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Fri, 26 May 2023 14:53:19 +0200 |
parents | 4684c7f1c4cb |
children | 26ad90b42efd |
comparison
equal
deleted
inserted
replaced
1365:4684c7f1c4cb | 1367:71e89507dd9a |
---|---|
7 A second derivative operator in direction `Dir` with a variable coefficient. | 7 A second derivative operator in direction `Dir` with a variable coefficient. |
8 """ | 8 """ |
9 struct SecondDerivativeVariable{Dir,T,D,M,IStencil<:NestedStencil{T},CStencil<:NestedStencil{T},TArray<:AbstractArray} <: LazyTensor{T,D,D} | 9 struct SecondDerivativeVariable{Dir,T,D,M,IStencil<:NestedStencil{T},CStencil<:NestedStencil{T},TArray<:AbstractArray} <: LazyTensor{T,D,D} |
10 inner_stencil::IStencil | 10 inner_stencil::IStencil |
11 closure_stencils::NTuple{M,CStencil} | 11 closure_stencils::NTuple{M,CStencil} |
12 size::NTuple{D,Int} | |
13 coefficient::TArray | 12 coefficient::TArray |
14 | 13 |
15 function SecondDerivativeVariable{Dir, D}(inner_stencil::NestedStencil{T}, closure_stencils::NTuple{M,NestedStencil{T}}, size::NTuple{D,Int}, coefficient::AbstractArray) where {Dir,T,D,M} | 14 function SecondDerivativeVariable{Dir, D}(inner_stencil::NestedStencil{T}, closure_stencils::NTuple{M,NestedStencil{T}}, coefficient::AbstractArray) where {Dir,T,D,M} |
16 IStencil = typeof(inner_stencil) | 15 IStencil = typeof(inner_stencil) |
17 CStencil = eltype(closure_stencils) | 16 CStencil = eltype(closure_stencils) |
18 TArray = typeof(coefficient) | 17 TArray = typeof(coefficient) |
19 return new{Dir,T,D,M,IStencil,CStencil,TArray}(inner_stencil,closure_stencils,size, coefficient) | 18 return new{Dir,T,D,M,IStencil,CStencil,TArray}(inner_stencil, closure_stencils, coefficient) |
20 end | 19 end |
21 end | 20 end |
22 | 21 |
23 function SecondDerivativeVariable(g::TensorGrid, coeff::AbstractArray, inner_stencil::NestedStencil, closure_stencils, dir) | 22 function SecondDerivativeVariable(g::TensorGrid, coeff::AbstractArray, inner_stencil::NestedStencil, closure_stencils, dir) |
24 check_coefficient(g, coeff) | 23 check_coefficient(g, coeff) |
25 | 24 |
26 Δxᵢ = spacing(g.grids[dir]) | 25 Δxᵢ = spacing(g.grids[dir]) |
27 scaled_inner_stencil = scale(inner_stencil, 1/Δxᵢ^2) | 26 scaled_inner_stencil = scale(inner_stencil, 1/Δxᵢ^2) |
28 scaled_closure_stencils = scale.(Tuple(closure_stencils), 1/Δxᵢ^2) | 27 scaled_closure_stencils = scale.(Tuple(closure_stencils), 1/Δxᵢ^2) |
29 return SecondDerivativeVariable{dir, ndims(g)}(scaled_inner_stencil, scaled_closure_stencils, size(g), coeff) | 28 return SecondDerivativeVariable{dir, ndims(g)}(scaled_inner_stencil, scaled_closure_stencils, coeff) |
30 end | 29 end |
31 | 30 |
32 function SecondDerivativeVariable(g::EquidistantGrid, coeff::AbstractVector, inner_stencil::NestedStencil, closure_stencils) | 31 function SecondDerivativeVariable(g::EquidistantGrid, coeff::AbstractVector, inner_stencil::NestedStencil, closure_stencils) |
33 return SecondDerivativeVariable(TensorGrid(g), coeff, inner_stencil, closure_stencils, 1) | 32 return SecondDerivativeVariable(TensorGrid(g), coeff, inner_stencil, closure_stencils, 1) |
34 end | 33 end |
76 | 75 |
77 derivative_direction(::SecondDerivativeVariable{Dir}) where {Dir} = Dir | 76 derivative_direction(::SecondDerivativeVariable{Dir}) where {Dir} = Dir |
78 | 77 |
79 closure_size(op::SecondDerivativeVariable) = length(op.closure_stencils) | 78 closure_size(op::SecondDerivativeVariable) = length(op.closure_stencils) |
80 | 79 |
81 LazyTensors.range_size(op::SecondDerivativeVariable) = op.size | 80 LazyTensors.range_size(op::SecondDerivativeVariable) = size(op.coefficient) |
82 LazyTensors.domain_size(op::SecondDerivativeVariable) = op.size | 81 LazyTensors.domain_size(op::SecondDerivativeVariable) = size(op.coefficient) |
83 | 82 |
84 | 83 |
85 function derivative_view(op, a, I) | 84 function derivative_view(op, a, I) |
86 d = derivative_direction(op) | 85 d = derivative_direction(op) |
87 | 86 |
108 function apply_upper(op::SecondDerivativeVariable, v, I...) | 107 function apply_upper(op::SecondDerivativeVariable, v, I...) |
109 ṽ = derivative_view(op, v, I) | 108 ṽ = derivative_view(op, v, I) |
110 c̃ = derivative_view(op, op.coefficient, I) | 109 c̃ = derivative_view(op, op.coefficient, I) |
111 | 110 |
112 i = I[derivative_direction(op)] | 111 i = I[derivative_direction(op)] |
113 stencil = op.closure_stencils[op.size[derivative_direction(op)]-i+1] | 112 sz = domain_size(op)[derivative_direction(op)] |
113 stencil = op.closure_stencils[sz-i+1] | |
114 return @inbounds apply_stencil_backwards(stencil, c̃, ṽ, i) | 114 return @inbounds apply_stencil_backwards(stencil, c̃, ṽ, i) |
115 end | 115 end |
116 | 116 |
117 function LazyTensors.apply(op::SecondDerivativeVariable, v::AbstractArray, I::Vararg{Index}) | 117 function LazyTensors.apply(op::SecondDerivativeVariable, v::AbstractArray, I::Vararg{Index}) |
118 if I[derivative_direction(op)] isa Index{Lower} | 118 if I[derivative_direction(op)] isa Index{Lower} |
126 end | 126 end |
127 end | 127 end |
128 | 128 |
129 function LazyTensors.apply(op::SecondDerivativeVariable, v::AbstractArray, I...) | 129 function LazyTensors.apply(op::SecondDerivativeVariable, v::AbstractArray, I...) |
130 dir = derivative_direction(op) | 130 dir = derivative_direction(op) |
131 sz = domain_size(op)[dir] | |
131 | 132 |
132 i = I[dir] | 133 i = I[dir] |
133 | 134 |
134 I = map(i->Index(i, Interior), I) | 135 I = map(i->Index(i, Interior), I) |
135 if 0 < i <= closure_size(op) | 136 if 0 < i <= closure_size(op) |
136 I = Base.setindex(I, Index(i, Lower), dir) | 137 I = Base.setindex(I, Index(i, Lower), dir) |
137 return LazyTensors.apply(op, v, I...) | 138 return LazyTensors.apply(op, v, I...) |
138 elseif closure_size(op) < i <= op.size[dir]-closure_size(op) | 139 elseif closure_size(op) < i <= sz-closure_size(op) |
139 I = Base.setindex(I, Index(i, Interior), dir) | 140 I = Base.setindex(I, Index(i, Interior), dir) |
140 return LazyTensors.apply(op, v, I...) | 141 return LazyTensors.apply(op, v, I...) |
141 elseif op.size[dir]-closure_size(op) < i <= op.size[dir] | 142 elseif sz-closure_size(op) < i <= sz |
142 I = Base.setindex(I, Index(i, Upper), dir) | 143 I = Base.setindex(I, Index(i, Upper), dir) |
143 return LazyTensors.apply(op, v, I...) | 144 return LazyTensors.apply(op, v, I...) |
144 else | 145 else |
145 error("Bounds error") # TODO: Make this more standard | 146 error("Bounds error") # TODO: Make this more standard |
146 end | 147 end |
168 | 169 |
169 function apply_upper(op::SecondDerivativeVariable{1}, v, i, j) | 170 function apply_upper(op::SecondDerivativeVariable{1}, v, i, j) |
170 ṽ = @view v[:,j] | 171 ṽ = @view v[:,j] |
171 c̃ = @view op.coefficient[:,j] | 172 c̃ = @view op.coefficient[:,j] |
172 | 173 |
173 stencil = op.closure_stencils[op.size[derivative_direction(op)]-i+1] | 174 sz = domain_size(op)[derivative_direction(op)] |
175 stencil = op.closure_stencils[sz-i+1] | |
174 return @inbounds apply_stencil_backwards(stencil, c̃, ṽ, i) | 176 return @inbounds apply_stencil_backwards(stencil, c̃, ṽ, i) |
175 end | 177 end |
176 | 178 |
177 | 179 |
178 ## y-direction | 180 ## y-direction |
192 | 194 |
193 function apply_upper(op::SecondDerivativeVariable{2}, v, i, j) | 195 function apply_upper(op::SecondDerivativeVariable{2}, v, i, j) |
194 ṽ = @view v[i,:] | 196 ṽ = @view v[i,:] |
195 c̃ = @view op.coefficient[i,:] | 197 c̃ = @view op.coefficient[i,:] |
196 | 198 |
197 stencil = op.closure_stencils[op.size[derivative_direction(op)]-j+1] | 199 sz = domain_size(op)[derivative_direction(op)] |
200 stencil = op.closure_stencils[sz-j+1] | |
198 return @inbounds apply_stencil_backwards(stencil, c̃, ṽ, j) | 201 return @inbounds apply_stencil_backwards(stencil, c̃, ṽ, j) |
199 end | 202 end |