|
8 | 8 | ################################################ |
9 | 9 |
|
10 | 10 | # Against a standard vector, assume already padded and just apply the stencil |
11 | | -function convolve_interior!(x_temp::AbstractVector{T}, x::AbstractVector{T}, A::DerivativeOperator; overwrite = true) where {T<:Real} |
| 11 | +function convolve_interior!(x_temp::AbstractVector{T}, x::AbstractVector{T}, A::DerivativeOperator; overwrite = true) where {T<:Real, N} |
12 | 12 | @assert length(x_temp)+2 == length(x) |
13 | 13 | stencil = A.stencil_coefs |
14 | 14 | coeff = A.coefficients |
15 | | - |
16 | | - # Upwind operators have a non-centred stencil |
17 | | - if use_winding(A) |
18 | | - mid = 1 + A.stencil_length%2 |
19 | | - else |
20 | | - mid = div(A.stencil_length,2) |
21 | | - end |
22 | | - |
| 15 | + mid = div(A.stencil_length,2) |
23 | 16 | for i in (1+A.boundary_point_count) : (length(x_temp)-A.boundary_point_count) |
24 | 17 | xtempi = zero(T) |
25 | 18 | cur_stencil = eltype(stencil) <: AbstractVector ? stencil[i-A.boundary_point_count] : stencil |
26 | 19 | cur_coeff = typeof(coeff) <: AbstractVector ? coeff[i] : coeff isa Number ? coeff : true |
27 | 20 | cur_stencil = use_winding(A) && cur_coeff < 0 ? reverse(cur_stencil) : cur_stencil |
28 | 21 | for idx in 1:A.stencil_length |
29 | | - x_idx = use_winding(A) && cur_coeff < 0 ? x[i + mid - idx] : x[i - mid + idx] |
30 | | - xtempi += cur_coeff * cur_stencil[idx] * x_idx |
| 22 | + xtempi += cur_coeff * cur_stencil[idx] * x[i - mid + idx] |
31 | 23 | end |
32 | 24 | x_temp[i] = xtempi + !overwrite*x_temp[i] |
33 | 25 | end |
34 | 26 | end |
35 | 27 |
|
36 | | -function convolve_BC_left!(x_temp::AbstractVector{T}, x::AbstractVector{T}, A::DerivativeOperator; overwrite = true) where {T<:Real} |
| 28 | +function convolve_BC_left!(x_temp::AbstractVector{T}, x::AbstractVector{T}, A::DerivativeOperator; overwrite = true) where {T<:Real, N} |
37 | 29 | stencil = A.low_boundary_coefs |
38 | 30 | coeff = A.coefficients |
39 | | - |
40 | | - _bpc = A.boundary_point_count |
41 | | - use_interior_stencil = false |
42 | | - if isempty(stencil) |
43 | | - _bpc = A.boundary_point_count + 1 |
44 | | - use_interior_stencil = true |
45 | | - end |
46 | | - |
47 | | - for i in 1 : _bpc |
48 | | - if use_interior_stencil == true |
49 | | - cur_stencil = A.stencil_coefs |
50 | | - slen = length(A.stencil_coefs) |
51 | | - else |
52 | | - cur_stencil = stencil[i] |
53 | | - slen = length(cur_stencil) |
54 | | - end |
55 | | - |
| 31 | + for i in 1 : A.boundary_point_count |
| 32 | + cur_stencil = stencil[i] |
56 | 33 | cur_coeff = typeof(coeff) <: AbstractVector ? coeff[i] : coeff isa Number ? coeff : true |
57 | 34 | cur_stencil = use_winding(A) && cur_coeff < 0 ? reverse(cur_stencil) : cur_stencil |
58 | | - xtempi = cur_coeff*cur_stencil[1]*x[1] |
59 | | - for idx in 2:slen |
| 35 | + xtempi = cur_coeff*stencil[i][1]*x[1] |
| 36 | + for idx in 2:A.boundary_stencil_length |
60 | 37 | xtempi += cur_coeff * cur_stencil[idx] * x[idx] |
61 | 38 | end |
62 | 39 | x_temp[i] = xtempi + !overwrite*x_temp[i] |
63 | 40 | end |
64 | 41 | end |
65 | 42 |
|
66 | | -function convolve_BC_right!(x_temp::AbstractVector{T}, x::AbstractVector{T}, A::DerivativeOperator; overwrite = true) where {T<:Real} |
| 43 | +function convolve_BC_right!(x_temp::AbstractVector{T}, x::AbstractVector{T}, A::DerivativeOperator; overwrite = true) where {T<:Real, N} |
67 | 44 | stencil = A.high_boundary_coefs |
68 | 45 | coeff = A.coefficients |
69 | | - N = length(x) |
70 | | - L = A.boundary_stencil_length |
71 | | - |
72 | | - _bpc = A.boundary_point_count |
73 | | - use_interior_stencil = false |
74 | | - |
75 | | - if isempty(stencil) |
76 | | - _bpc = 1 |
77 | | - use_interior_stencil = true |
78 | | - end |
79 | | - |
80 | | - for i in 1 : _bpc |
81 | | - if use_interior_stencil == true |
82 | | - cur_stencil = A.stencil_coefs |
83 | | - slen = length(A.stencil_coefs) |
84 | | - L = A.stencil_length |
85 | | - else |
86 | | - cur_stencil = stencil[i] |
87 | | - slen = length(cur_stencil) |
88 | | - end |
89 | | - |
| 46 | + for i in 1 : A.boundary_point_count |
| 47 | + cur_stencil = stencil[i] |
90 | 48 | cur_coeff = typeof(coeff) <: AbstractVector ? coeff[i] : coeff isa Number ? coeff : true |
91 | 49 | cur_stencil = use_winding(A) && cur_coeff < 0 ? reverse(cur_stencil) : cur_stencil |
92 | | - xtempi = zero(T) |
93 | | - for idx in 1:slen |
94 | | - xtempi += cur_coeff * cur_stencil[idx] * x[N-L+idx] |
| 50 | + xtempi = cur_coeff*stencil[i][end]*x[end] |
| 51 | + for idx in (A.boundary_stencil_length-1):-1:1 |
| 52 | + xtempi += cur_coeff * cur_stencil[end-idx] * x[end-idx] |
95 | 53 | end |
96 | | - x_temp[end-_bpc+i] = xtempi + !overwrite*x_temp[end-_bpc+i] |
| 54 | + x_temp[end-A.boundary_point_count+i] = xtempi + !overwrite*x_temp[end-A.boundary_point_count+i] |
97 | 55 | end |
98 | 56 | end |
99 | 57 |
|
100 | 58 | ########################################### |
101 | 59 |
|
102 | 60 | # Against A BC-padded vector, specialize the computation to explicitly use the left, right, and middle parts |
103 | | -function convolve_interior!(x_temp::AbstractVector{T}, _x::BoundaryPaddedVector, A::DerivativeOperator{T,N,true}; overwrite = true) where {T<:Real,N} |
104 | | - @assert length(x_temp) == length(_x.u) |
| 61 | +function convolve_interior!(x_temp::AbstractVector{T}, _x::BoundaryPaddedVector, A::DerivativeOperator{T,N,false}; overwrite = true) where {T<:Real, N} |
105 | 62 | stencil = A.stencil_coefs |
106 | 63 | coeff = A.coefficients |
107 | | - x_len = length(x_temp) + 2 |
108 | | - # Upwind operators have a non-centred stencil |
109 | | - mid = 1 + A.stencil_length%2 |
110 | 64 | x = _x.u |
| 65 | + mid = div(A.stencil_length,2) + 1 |
111 | 66 | # Just do the middle parts |
112 | | - for i in (1+A.boundary_point_count) : (length(x_temp)-A.boundary_point_count) |
| 67 | + for i in (2+A.boundary_point_count) : (length(x_temp)-A.boundary_point_count)-1 |
113 | 68 | xtempi = zero(T) |
114 | 69 | cur_stencil = eltype(stencil) <: AbstractVector ? stencil[i-A.boundary_point_count] : stencil |
115 | 70 | cur_coeff = typeof(coeff) <: AbstractVector ? coeff[i-A.boundary_point_count] : coeff isa Number ? coeff : true |
116 | 71 | cur_stencil = use_winding(A) && cur_coeff < 0 ? reverse(cur_stencil) : cur_stencil |
117 | 72 | @inbounds for idx in 1:A.stencil_length |
118 | | - if i-mid+idx == 1 |
119 | | - x_idx = _x.l |
120 | | - elseif i-mid+idx == x_len |
121 | | - x_idx = _x.r |
122 | | - else |
123 | | - x_idx = use_winding(A) && cur_coeff < 0 ? x[i + mid - idx - 1] : x[i - mid + idx - 1] |
124 | | - end |
125 | | - xtempi += cur_coeff * cur_stencil[idx] * x_idx |
| 73 | + xtempi += cur_coeff * cur_stencil[idx] * x[(i-1) - (mid-idx) + 1] |
126 | 74 | end |
127 | 75 | x_temp[i] = xtempi + !overwrite*x_temp[i] |
128 | 76 | end |
129 | 77 | end |
130 | 78 |
|
131 | | -function convolve_interior!(x_temp::AbstractVector{T}, _x::BoundaryPaddedVector, A::DerivativeOperator{T,N,false}; overwrite = true) where {T<:Real,N} |
132 | | - @assert length(x_temp) == length(_x.u) |
133 | | - stencil = A.stencil_coefs |
134 | | - coeff = A.coefficients |
135 | | - x_len = length(x_temp) + 2 |
136 | | - |
137 | | - mid = div(A.stencil_length,2) |
138 | | - x = _x.u |
139 | | - |
140 | | - # Just do the middle parts |
141 | | - for i in (2+A.boundary_point_count) : (length(x_temp)-A.boundary_point_count-1) |
142 | | - xtempi = zero(T) |
143 | | - cur_stencil = eltype(stencil) <: AbstractVector ? stencil[i-A.boundary_point_count] : stencil |
144 | | - cur_coeff = typeof(coeff) <: AbstractVector ? coeff[i-A.boundary_point_count] : coeff isa Number ? coeff : true |
145 | | - cur_stencil = use_winding(A) && cur_coeff < 0 ? reverse(cur_stencil) : cur_stencil |
146 | | - @inbounds for idx in 1:A.stencil_length |
147 | | - x_idx = use_winding(A) && cur_coeff < 0 ? x[i + mid - idx - 1] : x[i - mid + idx - 1] |
148 | | - xtempi += cur_coeff * cur_stencil[idx] * x_idx |
149 | | - end |
150 | | - x_temp[i] = xtempi |
151 | | - end |
152 | | -end |
153 | | - |
154 | | - |
155 | | -function convolve_BC_left!(x_temp::AbstractVector{T}, _x::BoundaryPaddedVector, A::DerivativeOperator{T,N,false}; overwrite = true) where {T<:Real,N} |
| 79 | +function convolve_BC_left!(x_temp::AbstractVector{T}, _x::BoundaryPaddedVector, A::DerivativeOperator{T,N,false}; overwrite = true) where {T<:Real, N} |
156 | 80 | stencil = A.low_boundary_coefs |
157 | 81 | coeff = A.coefficients |
158 | | - |
159 | | - _bpc = A.boundary_point_count |
160 | | - |
161 | | - for i in 1 : _bpc |
| 82 | + for i in 1 : A.boundary_point_count |
162 | 83 | cur_stencil = stencil[i] |
163 | | - slen = length(cur_stencil) |
164 | | - |
165 | 84 | cur_coeff = typeof(coeff) <: AbstractVector ? coeff[i] : coeff isa Number ? coeff : true |
166 | | - cur_stencil = use_winding(A) && cur_coeff < 0 ? reverse(cur_stencil) : cur_stencil |
167 | | - |
168 | | - # need to account for x.l in first interior |
169 | 85 | xtempi = cur_coeff*cur_stencil[1]*_x.l |
170 | | - @inbounds for idx in 2:slen |
| 86 | + cur_stencil = use_winding(A) && cur_coeff < 0 ? reverse(cur_stencil) : cur_stencil |
| 87 | + @inbounds for idx in 2:A.boundary_stencil_length |
171 | 88 | xtempi += cur_coeff * cur_stencil[idx] * _x.u[idx-1] |
172 | 89 | end |
173 | | - x_temp[i] = xtempi |
| 90 | + x_temp[i] = xtempi + !overwrite*x_temp[i] |
174 | 91 | end |
175 | | - |
176 | | - # explicitely handling the last point which involves the ghost point in its calculations |
177 | | - i = _bpc+1 |
178 | | - cur_coeff = typeof(coeff) <: AbstractVector ? coeff[i] : coeff isa Number ? coeff : true |
179 | | - cur_stencil = A.stencil_coefs |
180 | | - slen = length(cur_stencil) |
| 92 | + # need to account for x.l in first interior |
| 93 | + mid = div(A.stencil_length,2) + 1 |
| 94 | + x = _x.u |
| 95 | + i = 1 + A.boundary_point_count |
| 96 | + xtempi = zero(T) |
| 97 | + cur_stencil = eltype(A.stencil_coefs) <: AbstractVector ? A.stencil_coefs[i-A.boundary_point_count] : A.stencil_coefs |
| 98 | + cur_coeff = typeof(coeff) <: AbstractVector ? coeff[i-A.boundary_point_count] : coeff isa Number ? coeff : true |
181 | 99 | cur_stencil = use_winding(A) && cur_coeff < 0 ? reverse(cur_stencil) : cur_stencil |
182 | 100 | xtempi = cur_coeff*cur_stencil[1]*_x.l |
183 | | - @inbounds for idx in 2:slen |
184 | | - xtempi += cur_coeff * cur_stencil[idx] * _x.u[idx-1] |
| 101 | + @inbounds for idx in 2:A.stencil_length |
| 102 | + xtempi += cur_coeff * cur_stencil[idx] * x[(i-1) - (mid-idx) + 1] |
185 | 103 | end |
186 | | - x_temp[i] = xtempi |
| 104 | + x_temp[i] = xtempi + !overwrite*x_temp[i] |
187 | 105 | end |
188 | 106 |
|
189 | | - |
190 | | -function convolve_BC_right!(x_temp::AbstractVector{T}, _x::BoundaryPaddedVector, A::DerivativeOperator{T,N,false}; overwrite = true) where {T<:Real,N} |
| 107 | +function convolve_BC_right!(x_temp::AbstractVector{T}, _x::BoundaryPaddedVector, A::DerivativeOperator{T,N,false}; overwrite = true) where {T<:Real, N} |
191 | 108 | stencil = A.high_boundary_coefs |
192 | 109 | coeff = A.coefficients |
193 | | - u_len = length(_x.u) |
194 | | - bpc = A.boundary_point_count |
195 | | - |
| 110 | + bc_start = length(_x.u) - A.boundary_point_count |
196 | 111 | # need to account for _x.r in last interior convolution |
| 112 | + mid = div(A.stencil_length,2) + 1 |
197 | 113 | x = _x.u |
198 | | - L = A.boundary_stencil_length |
199 | | - _bpc = A.boundary_point_count |
200 | | - |
201 | | - # explicitely handling the first point which involves the ghost point in its calculations |
202 | | - i = u_len-_bpc |
203 | | - cur_coeff = typeof(coeff) <: AbstractVector ? coeff[i] : coeff isa Number ? coeff : true |
204 | | - |
205 | | - cur_stencil = A.stencil_coefs |
| 114 | + i = length(x_temp)-A.boundary_point_count |
| 115 | + xtempi = zero(T) |
| 116 | + cur_stencil = eltype(A.stencil_coefs) <: AbstractVector ? A.stencil_coefs[i-A.boundary_point_count] : A.stencil_coefs |
| 117 | + cur_coeff = typeof(coeff) <: AbstractVector ? coeff[i-A.boundary_point_count] : coeff isa Number ? coeff : true |
206 | 118 | cur_stencil = use_winding(A) && cur_coeff < 0 ? reverse(cur_stencil) : cur_stencil |
207 | 119 | xtempi = cur_coeff*cur_stencil[end]*_x.r |
208 | | - slen = length(cur_stencil) |
209 | | - |
210 | | - @inbounds for idx in slen-1:-1:1 |
211 | | - xtempi += cur_coeff * cur_stencil[end-idx] * _x.u[end-idx+1] |
| 120 | + @inbounds for idx in 1:A.stencil_length-1 |
| 121 | + xtempi += cur_coeff * cur_stencil[idx] * x[(i-1) - (mid-idx) + 1] |
212 | 122 | end |
213 | 123 | x_temp[i] = xtempi + !overwrite*x_temp[i] |
214 | | - |
215 | | - for i in u_len-_bpc+1 : u_len |
216 | | - cur_stencil = stencil[i+_bpc-u_len] |
217 | | - slen = length(cur_stencil) |
218 | | - |
219 | | - cur_coeff = typeof(coeff) <: AbstractVector ? coeff[i] : coeff isa Number ? coeff : true |
| 124 | + for i in 1 : A.boundary_point_count |
| 125 | + cur_stencil = stencil[i] |
| 126 | + cur_coeff = typeof(coeff) <: AbstractVector ? coeff[bc_start + i] : coeff isa Number ? coeff : true |
220 | 127 | xtempi = cur_coeff*cur_stencil[end]*_x.r |
221 | 128 | cur_stencil = use_winding(A) && cur_coeff < 0 ? reverse(cur_stencil) : cur_stencil |
222 | | - |
223 | | - @inbounds for idx in slen-1:-1:1 |
| 129 | + @inbounds for idx in A.stencil_length:-1:1 |
224 | 130 | xtempi += cur_coeff * cur_stencil[end-idx] * _x.u[end-idx+1] |
225 | 131 | end |
226 | | - x_temp[i] = xtempi + !overwrite*x_temp[i] |
| 132 | + x_temp[bc_start + i] = xtempi + !overwrite*x_temp[bc_start + i] |
| 133 | + end |
| 134 | +end |
| 135 | + |
| 136 | + |
| 137 | +# Against A BC-padded vector, specialize the computation to explicitly use the left, right, and middle parts |
| 138 | +function convolve_interior!(x_temp::AbstractVector{T}, _x::BoundaryPaddedVector, A::DerivativeOperator{T,N,true}; overwrite = true) where {T<:Real,N} |
| 139 | + @assert length(x_temp) == length(_x.u) |
| 140 | + stencil = A.stencil_coefs |
| 141 | + coeff = A.coefficients |
| 142 | + x_len = length(x_temp) + 2 |
| 143 | + # Upwind operators have a non-centred stencil |
| 144 | + mid = 1 + A.stencil_length%2 |
| 145 | + x = _x.u |
| 146 | + # Just do the middle parts |
| 147 | + for i in (1+A.boundary_point_count) : (length(x_temp)-A.boundary_point_count) |
| 148 | + xtempi = zero(T) |
| 149 | + cur_stencil = eltype(stencil) <: AbstractVector ? stencil[i-A.boundary_point_count] : stencil |
| 150 | + cur_coeff = typeof(coeff) <: AbstractVector ? coeff[i-A.boundary_point_count] : coeff isa Number ? coeff : true |
| 151 | + cur_stencil = use_winding(A) && cur_coeff < 0 ? reverse(cur_stencil) : cur_stencil |
| 152 | + @inbounds for idx in 1:A.stencil_length |
| 153 | + if i-mid+idx == 1 |
| 154 | + x_idx = _x.l |
| 155 | + elseif i-mid+idx == x_len |
| 156 | + x_idx = _x.r |
| 157 | + else |
| 158 | + x_idx = use_winding(A) && cur_coeff < 0 ? x[i + mid - idx - 1] : x[i - mid + idx - 1] |
| 159 | + end |
| 160 | + xtempi += cur_coeff * cur_stencil[idx] * x_idx |
| 161 | + end |
| 162 | + x_temp[i] = xtempi |
227 | 163 | end |
228 | 164 | end |
229 | 165 |
|
230 | 166 |
|
231 | | -function convolve_BC_left!(x_temp::AbstractVector{T}, _x::BoundaryPaddedVector, A::DerivativeOperator{T,N,true}; overwrite = true) where {T<:Real,N} |
| 167 | +function convolve_BC_left!(x_temp::AbstractVector{T}, _x::BoundaryPaddedVector, A::DerivativeOperator{T,N,true}) where {T<:Real,N} |
232 | 168 | stencil = A.low_boundary_coefs |
233 | 169 | coeff = A.coefficients |
234 | 170 |
|
|
304 | 240 |
|
305 | 241 | ################################################################################# |
306 | 242 |
|
307 | | -function convolve_interior_add_range!(x_temp::AbstractVector{T}, x::AbstractVector{T}, A::DerivativeOperator, offset::Int) where {T<:Real} |
| 243 | +function convolve_interior_add_range!(x_temp::AbstractVector{T}, x::AbstractVector{T}, A::DerivativeOperator, offset::Int) where {T<:Real, N} |
308 | 244 | @assert length(x_temp)+2 == length(x) |
309 | 245 | stencil = A.stencil_coefs |
310 | 246 | coeff = A.coefficients |
|
0 commit comments