Mercurial > repos > public > sbplib_julia
comparison DiffOps/src/DiffOps.jl @ 228:5acef2d5db2e boundary_conditions
Move Laplace operator and related structs/functions to separate file.
author | Vidar Stiernström <vidar.stiernstrom@it.uu.se> |
---|---|
date | Wed, 26 Jun 2019 14:38:01 +0200 |
parents | b3506cfbb9d8 |
children | cd60382f392b |
comparison
equal
deleted
inserted
replaced
225:3ab0c61f1367 | 228:5acef2d5db2e |
---|---|
1 module DiffOps | 1 module DiffOps |
2 | 2 |
3 using RegionIndices | 3 using RegionIndices |
4 using SbpOperators | 4 using SbpOperators |
5 using Grids | 5 using Grids |
6 | |
7 export Laplace | |
8 | 6 |
9 abstract type DiffOp end | 7 abstract type DiffOp end |
10 | 8 |
11 # TBD: The "error("not implemented")" thing seems to be hiding good error information. How to fix that? Different way of saying that these should be implemented? | 9 # TBD: The "error("not implemented")" thing seems to be hiding good error information. How to fix that? Different way of saying that these should be implemented? |
12 function apply(D::DiffOp, v::AbstractVector, i::Int) | 10 function apply(D::DiffOp, v::AbstractVector, i::Int) |
89 return u | 87 return u |
90 end | 88 end |
91 | 89 |
92 export apply | 90 export apply |
93 | 91 |
94 struct NormalDerivative{N,M,K} | |
95 op::D2{Float64,N,M,K} | |
96 grid::EquidistantGrid | |
97 bId::CartesianBoundary | |
98 end | |
99 | |
100 function apply_transpose(d::NormalDerivative, v::AbstractArray, I::Integer) | |
101 u = selectdim(v,3-dim(d.bId),I) | |
102 return apply_d(d.op, d.grid.inverse_spacing[dim(d.bId)], u, region(d.bId)) | |
103 end | |
104 | |
105 # Not correct abstraction level | |
106 # TODO: Not type stable D:< | |
107 function apply(d::NormalDerivative, v::AbstractArray, I::Tuple{Integer,Integer}) | |
108 i = I[dim(d.bId)] | |
109 j = I[3-dim(d.bId)] | |
110 N_i = d.grid.size[dim(d.bId)] | |
111 | |
112 r = getregion(i, closureSize(d.op), N_i) | |
113 | |
114 if r != region(d.bId) | |
115 return 0 | |
116 end | |
117 | |
118 if r == Lower | |
119 # Note, closures are indexed by offset. Fix this D:< | |
120 return d.grid.inverse_spacing[dim(d.bId)]*d.op.dClosure[i-1]*v[j] | |
121 elseif r == Upper | |
122 return d.grid.inverse_spacing[dim(d.bId)]*d.op.dClosure[N_i-j]*v[j] | |
123 end | |
124 end | |
125 | |
126 struct BoundaryValue{N,M,K} | |
127 op::D2{Float64,N,M,K} | |
128 grid::EquidistantGrid | |
129 bId::CartesianBoundary | |
130 end | |
131 | |
132 function apply(e::BoundaryValue, v::AbstractArray, I::Tuple{Integer,Integer}) | |
133 i = I[dim(e.bId)] | |
134 j = I[3-dim(e.bId)] | |
135 N_i = e.grid.size[dim(e.bId)] | |
136 | |
137 r = getregion(i, closureSize(e.op), N_i) | |
138 | |
139 if r != region(e.bId) | |
140 return 0 | |
141 end | |
142 | |
143 if r == Lower | |
144 # Note, closures are indexed by offset. Fix this D:< | |
145 return e.op.eClosure[i-1]*v[j] | |
146 elseif r == Upper | |
147 return e.op.eClosure[N_i-j]*v[j] | |
148 end | |
149 end | |
150 | |
151 function apply_transpose(e::BoundaryValue, v::AbstractArray, I::Integer) | |
152 u = selectdim(v,3-dim(e.bId),I) | |
153 return apply_e(e.op, u, region(e.bId)) | |
154 end | |
155 | |
156 struct Laplace{Dim,T<:Real,N,M,K} <: DiffOpCartesian{Dim} | |
157 grid::EquidistantGrid{Dim,T} | |
158 a::T | |
159 op::D2{Float64,N,M,K} | |
160 # e::BoundaryValue | |
161 # d::NormalDerivative | |
162 end | |
163 | |
164 function apply(L::Laplace{Dim}, v::AbstractArray{T,Dim} where T, I::CartesianIndex{Dim}) where Dim | |
165 error("not implemented") | |
166 end | |
167 | |
168 # u = L*v | |
169 function apply(L::Laplace{1}, v::AbstractVector, i::Int) | |
170 uᵢ = L.a * SbpOperators.apply(L.op, L.grid.spacing[1], v, i) | |
171 return uᵢ | |
172 end | |
173 | |
174 @inline function apply(L::Laplace{2}, v::AbstractArray{T,2} where T, I::Tuple{Index{R1}, Index{R2}}) where {R1, R2} | |
175 # 2nd x-derivative | |
176 @inbounds vx = view(v, :, Int(I[2])) | |
177 @inbounds uᵢ = L.a*SbpOperators.apply(L.op, L.grid.inverse_spacing[1], vx , I[1]) | |
178 # 2nd y-derivative | |
179 @inbounds vy = view(v, Int(I[1]), :) | |
180 @inbounds uᵢ += L.a*SbpOperators.apply(L.op, L.grid.inverse_spacing[2], vy, I[2]) | |
181 # NOTE: the package qualifier 'SbpOperators' can problably be removed once all "applying" objects use LazyTensors | |
182 return uᵢ | |
183 end | |
184 | |
185 # Slow but maybe convenient? | |
186 function apply(L::Laplace{2}, v::AbstractArray{T,2} where T, i::CartesianIndex{2}) | |
187 I = Index{Unknown}.(Tuple(i)) | |
188 apply(L, v, I) | |
189 end | |
190 | |
191 struct BoundaryOperator | |
192 | |
193 end | |
194 | |
195 | |
196 """ | 92 """ |
197 A BoundaryCondition should implement the method | 93 A BoundaryCondition should implement the method |
198 sat(::DiffOp, v::AbstractArray, data::AbstractArray, ...) | 94 sat(::DiffOp, v::AbstractArray, data::AbstractArray, ...) |
199 """ | 95 """ |
200 abstract type BoundaryCondition end | 96 abstract type BoundaryCondition end |
201 | 97 |
202 struct Neumann{Bid<:BoundaryIdentifier} <: BoundaryCondition end | |
203 | 98 |
204 function sat(L::Laplace{2,T}, bc::Neumann{Bid}, v::AbstractArray{T,2}, g::AbstractVector{T}, I::CartesianIndex{2}) where {T,Bid} | 99 include("laplace.jl") |
205 e = BoundaryValue(L.op, L.grid, Bid()) | 100 export Laplace |
206 d = NormalDerivative(L.op, L.grid, Bid()) | |
207 Hᵧ = BoundaryQuadrature(L.op, L.grid, Bid()) | |
208 # TODO: Implement BoundaryQuadrature method | |
209 | 101 |
210 return -L.Hi*e*Hᵧ*(d'*v - g) | |
211 # Need to handle d'*v - g so that it is an AbstractArray that TensorMappings can act on | |
212 end | |
213 | |
214 struct Dirichlet{Bid<:BoundaryIdentifier} <: BoundaryCondition | |
215 tau::Float64 | |
216 end | |
217 | |
218 function sat(L::Laplace{2,T}, bc::Dirichlet{Bid}, v::AbstractArray{T,2}, g::AbstractVector{T}, i::CartesianIndex{2}) where {T,Bid} | |
219 e = BoundaryValue(L.op, L.grid, Bid()) | |
220 d = NormalDerivative(L.op, L.grid, Bid()) | |
221 Hᵧ = BoundaryQuadrature(L.op, L.grid, Bid()) | |
222 # TODO: Implement BoundaryQuadrature method | |
223 | |
224 return -L.Hi*(tau/h*e + d)*Hᵧ*(e'*v - g) | |
225 # Need to handle scalar multiplication and addition of TensorMapping | |
226 end | |
227 | |
228 # function apply(s::MyWaveEq{D}, v::AbstractArray{T,D}, i::CartesianIndex{D}) where D | |
229 # return apply(s.L, v, i) + | |
230 # sat(s.L, Dirichlet{CartesianBoundary{1,Lower}}(s.tau), v, s.g_w, i) + | |
231 # sat(s.L, Dirichlet{CartesianBoundary{1,Upper}}(s.tau), v, s.g_e, i) + | |
232 # sat(s.L, Dirichlet{CartesianBoundary{2,Lower}}(s.tau), v, s.g_s, i) + | |
233 # sat(s.L, Dirichlet{CartesianBoundary{2,Upper}}(s.tau), v, s.g_n, i) | |
234 # end | |
235 | 102 |
236 end # module | 103 end # module |