Mercurial > repos > public > sbplib_julia
comparison DiffOps/src/laplace.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 | |
| children | a5fdc00d5070 |
comparison
equal
deleted
inserted
replaced
| 225:3ab0c61f1367 | 228:5acef2d5db2e |
|---|---|
| 1 struct NormalDerivative{N,M,K} | |
| 2 op::D2{Float64,N,M,K} | |
| 3 grid::EquidistantGrid | |
| 4 bId::CartesianBoundary | |
| 5 end | |
| 6 | |
| 7 function apply_transpose(d::NormalDerivative, v::AbstractArray, I::Integer) | |
| 8 u = selectdim(v,3-dim(d.bId),I) | |
| 9 return apply_d(d.op, d.grid.inverse_spacing[dim(d.bId)], u, region(d.bId)) | |
| 10 end | |
| 11 | |
| 12 # Not correct abstraction level | |
| 13 # TODO: Not type stable D:< | |
| 14 function apply(d::NormalDerivative, v::AbstractArray, I::Tuple{Integer,Integer}) | |
| 15 i = I[dim(d.bId)] | |
| 16 j = I[3-dim(d.bId)] | |
| 17 N_i = d.grid.size[dim(d.bId)] | |
| 18 | |
| 19 r = getregion(i, closureSize(d.op), N_i) | |
| 20 | |
| 21 if r != region(d.bId) | |
| 22 return 0 | |
| 23 end | |
| 24 | |
| 25 if r == Lower | |
| 26 # Note, closures are indexed by offset. Fix this D:< | |
| 27 return d.grid.inverse_spacing[dim(d.bId)]*d.op.dClosure[i-1]*v[j] | |
| 28 elseif r == Upper | |
| 29 return d.grid.inverse_spacing[dim(d.bId)]*d.op.dClosure[N_i-j]*v[j] | |
| 30 end | |
| 31 end | |
| 32 | |
| 33 struct BoundaryValue{N,M,K} | |
| 34 op::D2{Float64,N,M,K} | |
| 35 grid::EquidistantGrid | |
| 36 bId::CartesianBoundary | |
| 37 end | |
| 38 | |
| 39 function apply(e::BoundaryValue, v::AbstractArray, I::Tuple{Integer,Integer}) | |
| 40 i = I[dim(e.bId)] | |
| 41 j = I[3-dim(e.bId)] | |
| 42 N_i = e.grid.size[dim(e.bId)] | |
| 43 | |
| 44 r = getregion(i, closureSize(e.op), N_i) | |
| 45 | |
| 46 if r != region(e.bId) | |
| 47 return 0 | |
| 48 end | |
| 49 | |
| 50 if r == Lower | |
| 51 # Note, closures are indexed by offset. Fix this D:< | |
| 52 return e.op.eClosure[i-1]*v[j] | |
| 53 elseif r == Upper | |
| 54 return e.op.eClosure[N_i-j]*v[j] | |
| 55 end | |
| 56 end | |
| 57 | |
| 58 function apply_transpose(e::BoundaryValue, v::AbstractArray, I::Integer) | |
| 59 u = selectdim(v,3-dim(e.bId),I) | |
| 60 return apply_e(e.op, u, region(e.bId)) | |
| 61 end | |
| 62 | |
| 63 struct Laplace{Dim,T<:Real,N,M,K} <: DiffOpCartesian{Dim} | |
| 64 grid::EquidistantGrid{Dim,T} | |
| 65 a::T | |
| 66 op::D2{Float64,N,M,K} | |
| 67 # e::BoundaryValue | |
| 68 # d::NormalDerivative | |
| 69 end | |
| 70 | |
| 71 function apply(L::Laplace{Dim}, v::AbstractArray{T,Dim} where T, I::CartesianIndex{Dim}) where Dim | |
| 72 error("not implemented") | |
| 73 end | |
| 74 | |
| 75 # u = L*v | |
| 76 function apply(L::Laplace{1}, v::AbstractVector, i::Int) | |
| 77 uᵢ = L.a * SbpOperators.apply(L.op, L.grid.spacing[1], v, i) | |
| 78 return uᵢ | |
| 79 end | |
| 80 | |
| 81 @inline function apply(L::Laplace{2}, v::AbstractArray{T,2} where T, I::Tuple{Index{R1}, Index{R2}}) where {R1, R2} | |
| 82 # 2nd x-derivative | |
| 83 @inbounds vx = view(v, :, Int(I[2])) | |
| 84 @inbounds uᵢ = L.a*SbpOperators.apply(L.op, L.grid.inverse_spacing[1], vx , I[1]) | |
| 85 # 2nd y-derivative | |
| 86 @inbounds vy = view(v, Int(I[1]), :) | |
| 87 @inbounds uᵢ += L.a*SbpOperators.apply(L.op, L.grid.inverse_spacing[2], vy, I[2]) | |
| 88 # NOTE: the package qualifier 'SbpOperators' can problably be removed once all "applying" objects use LazyTensors | |
| 89 return uᵢ | |
| 90 end | |
| 91 | |
| 92 # Slow but maybe convenient? | |
| 93 function apply(L::Laplace{2}, v::AbstractArray{T,2} where T, i::CartesianIndex{2}) | |
| 94 I = Index{Unknown}.(Tuple(i)) | |
| 95 apply(L, v, I) | |
| 96 end | |
| 97 | |
| 98 | |
| 99 struct Neumann{Bid<:BoundaryIdentifier} <: BoundaryCondition end | |
| 100 | |
| 101 function sat(L::Laplace{2,T}, bc::Neumann{Bid}, v::AbstractArray{T,2}, g::AbstractVector{T}, I::CartesianIndex{2}) where {T,Bid} | |
| 102 e = BoundaryValue(L.op, L.grid, Bid()) | |
| 103 d = NormalDerivative(L.op, L.grid, Bid()) | |
| 104 Hᵧ = BoundaryQuadrature(L.op, L.grid, Bid()) | |
| 105 # TODO: Implement BoundaryQuadrature method | |
| 106 | |
| 107 return -L.Hi*e*Hᵧ*(d'*v - g) | |
| 108 # Need to handle d'*v - g so that it is an AbstractArray that TensorMappings can act on | |
| 109 end | |
| 110 | |
| 111 struct Dirichlet{Bid<:BoundaryIdentifier} <: BoundaryCondition | |
| 112 tau::Float64 | |
| 113 end | |
| 114 | |
| 115 function sat(L::Laplace{2,T}, bc::Dirichlet{Bid}, v::AbstractArray{T,2}, g::AbstractVector{T}, i::CartesianIndex{2}) where {T,Bid} | |
| 116 e = BoundaryValue(L.op, L.grid, Bid()) | |
| 117 d = NormalDerivative(L.op, L.grid, Bid()) | |
| 118 Hᵧ = BoundaryQuadrature(L.op, L.grid, Bid()) | |
| 119 # TODO: Implement BoundaryQuadrature method | |
| 120 | |
| 121 return -L.Hi*(tau/h*e + d)*Hᵧ*(e'*v - g) | |
| 122 # Need to handle scalar multiplication and addition of TensorMapping | |
| 123 end | |
| 124 | |
| 125 # function apply(s::MyWaveEq{D}, v::AbstractArray{T,D}, i::CartesianIndex{D}) where D | |
| 126 # return apply(s.L, v, i) + | |
| 127 # sat(s.L, Dirichlet{CartesianBoundary{1,Lower}}(s.tau), v, s.g_w, i) + | |
| 128 # sat(s.L, Dirichlet{CartesianBoundary{1,Upper}}(s.tau), v, s.g_e, i) + | |
| 129 # sat(s.L, Dirichlet{CartesianBoundary{2,Lower}}(s.tau), v, s.g_s, i) + | |
| 130 # sat(s.L, Dirichlet{CartesianBoundary{2,Upper}}(s.tau), v, s.g_n, i) | |
| 131 # end |
