Mercurial > repos > public > sbplib_julia
comparison DiffOps/src/laplace.jl @ 247:ed29ee13e92e boundary_conditions
Restructure laplace.jl
| author | Vidar Stiernström <vidar.stiernstrom@it.uu.se> |
|---|---|
| date | Thu, 27 Jun 2019 09:43:44 +0200 |
| parents | a827568fc251 |
| children | 05e7bbe0af97 |
comparison
equal
deleted
inserted
replaced
| 244:a827568fc251 | 247:ed29ee13e92e |
|---|---|
| 1 """ | 1 struct Laplace{Dim,T<:Real,N,M,K} <: DiffOpCartesian{Dim} |
| 2 NormalDerivative{T,N,M,K} <: TensorMapping{T,2,1} | 2 grid::EquidistantGrid{Dim,T} |
| 3 | 3 a::T |
| 4 Implements the boundary operator `d` as a TensorMapping | 4 op::D2{Float64,N,M,K} |
| 5 """ | 5 # e::BoundaryValue |
| 6 struct NormalDerivative{T,N,M,K} <: TensorMapping{T,2,1} | 6 # d::NormalDerivative |
| 7 op::D2{T,N,M,K} | |
| 8 grid::EquidistantGrid | |
| 9 bId::CartesianBoundary | |
| 10 end | |
| 11 export NormalDerivative | |
| 12 | |
| 13 # TODO: This is obviouly strange. Is domain_size just discarded? Is there a way to avoid storing grid in BoundaryValue? | |
| 14 # Can we give special treatment to TensorMappings that go to a higher dim? | |
| 15 LazyTensors.range_size(e::NormalDerivative{T}, domain_size::NTuple{1,Integer}) where T = size(e.grid) | |
| 16 LazyTensors.domain_size(e::NormalDerivative{T}, range_size::NTuple{2,Integer}) where T = (range_size[3-dim(e.bId)],) | |
| 17 | |
| 18 # Not correct abstraction level | |
| 19 # TODO: Not type stable D:< | |
| 20 function LazyTensors.apply(d::NormalDerivative, v::AbstractArray, I::NTuple{2,Int}) | |
| 21 i = I[dim(d.bId)] | |
| 22 j = I[3-dim(d.bId)] | |
| 23 N_i = size(d.grid)[dim(d.bId)] | |
| 24 | |
| 25 if region(d.bId) == 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 region(d.bId) == Upper | |
| 29 return -d.grid.inverse_spacing[dim(d.bId)]*d.op.dClosure[N_i-i]*v[j] | |
| 30 end | |
| 31 end | 7 end |
| 32 | 8 |
| 33 function LazyTensors.apply_transpose(d::NormalDerivative, v::AbstractArray, I::NTuple{1,Int}) | 9 function apply(L::Laplace{Dim}, v::AbstractArray{T,Dim} where T, I::CartesianIndex{Dim}) where Dim |
| 34 u = selectdim(v,3-dim(d.bId),I[1]) | 10 error("not implemented") |
| 35 return apply_d(d.op, d.grid.inverse_spacing[dim(d.bId)], u, region(d.bId)) | |
| 36 end | 11 end |
| 12 | |
| 13 # u = L*v | |
| 14 function apply(L::Laplace{1}, v::AbstractVector, i::Int) | |
| 15 uᵢ = L.a * SbpOperators.apply(L.op, L.grid.spacing[1], v, i) | |
| 16 return uᵢ | |
| 17 end | |
| 18 | |
| 19 @inline function apply(L::Laplace{2}, v::AbstractArray{T,2} where T, I::Tuple{Index{R1}, Index{R2}}) where {R1, R2} | |
| 20 # 2nd x-derivative | |
| 21 @inbounds vx = view(v, :, Int(I[2])) | |
| 22 @inbounds uᵢ = L.a*SbpOperators.apply(L.op, L.grid.inverse_spacing[1], vx , I[1]) | |
| 23 # 2nd y-derivative | |
| 24 @inbounds vy = view(v, Int(I[1]), :) | |
| 25 @inbounds uᵢ += L.a*SbpOperators.apply(L.op, L.grid.inverse_spacing[2], vy, I[2]) | |
| 26 # NOTE: the package qualifier 'SbpOperators' can problably be removed once all "applying" objects use LazyTensors | |
| 27 return uᵢ | |
| 28 end | |
| 29 | |
| 30 # Slow but maybe convenient? | |
| 31 function apply(L::Laplace{2}, v::AbstractArray{T,2} where T, i::CartesianIndex{2}) | |
| 32 I = Index{Unknown}.(Tuple(i)) | |
| 33 apply(L, v, I) | |
| 34 end | |
| 35 | |
| 37 | 36 |
| 38 | 37 |
| 39 """ | 38 """ |
| 40 BoundaryValue{T,N,M,K} <: TensorMapping{T,2,1} | 39 BoundaryValue{T,N,M,K} <: TensorMapping{T,2,1} |
| 41 | 40 |
| 71 return apply_e(e.op, u, region(e.bId)) | 70 return apply_e(e.op, u, region(e.bId)) |
| 72 end | 71 end |
| 73 | 72 |
| 74 | 73 |
| 75 | 74 |
| 76 struct Laplace{Dim,T<:Real,N,M,K} <: DiffOpCartesian{Dim} | 75 """ |
| 77 grid::EquidistantGrid{Dim,T} | 76 NormalDerivative{T,N,M,K} <: TensorMapping{T,2,1} |
| 78 a::T | 77 |
| 79 op::D2{Float64,N,M,K} | 78 Implements the boundary operator `d` as a TensorMapping |
| 80 # e::BoundaryValue | 79 """ |
| 81 # d::NormalDerivative | 80 struct NormalDerivative{T,N,M,K} <: TensorMapping{T,2,1} |
| 81 op::D2{T,N,M,K} | |
| 82 grid::EquidistantGrid | |
| 83 bId::CartesianBoundary | |
| 84 end | |
| 85 export NormalDerivative | |
| 86 | |
| 87 # TODO: This is obviouly strange. Is domain_size just discarded? Is there a way to avoid storing grid in BoundaryValue? | |
| 88 # Can we give special treatment to TensorMappings that go to a higher dim? | |
| 89 LazyTensors.range_size(e::NormalDerivative{T}, domain_size::NTuple{1,Integer}) where T = size(e.grid) | |
| 90 LazyTensors.domain_size(e::NormalDerivative{T}, range_size::NTuple{2,Integer}) where T = (range_size[3-dim(e.bId)],) | |
| 91 | |
| 92 # Not correct abstraction level | |
| 93 # TODO: Not type stable D:< | |
| 94 function LazyTensors.apply(d::NormalDerivative, v::AbstractArray, I::NTuple{2,Int}) | |
| 95 i = I[dim(d.bId)] | |
| 96 j = I[3-dim(d.bId)] | |
| 97 N_i = size(d.grid)[dim(d.bId)] | |
| 98 | |
| 99 if region(d.bId) == Lower | |
| 100 # Note, closures are indexed by offset. Fix this D:< | |
| 101 return d.grid.inverse_spacing[dim(d.bId)]*d.op.dClosure[i-1]*v[j] | |
| 102 elseif region(d.bId) == Upper | |
| 103 return -d.grid.inverse_spacing[dim(d.bId)]*d.op.dClosure[N_i-i]*v[j] | |
| 104 end | |
| 82 end | 105 end |
| 83 | 106 |
| 84 function apply(L::Laplace{Dim}, v::AbstractArray{T,Dim} where T, I::CartesianIndex{Dim}) where Dim | 107 function LazyTensors.apply_transpose(d::NormalDerivative, v::AbstractArray, I::NTuple{1,Int}) |
| 85 error("not implemented") | 108 u = selectdim(v,3-dim(d.bId),I[1]) |
| 109 return apply_d(d.op, d.grid.inverse_spacing[dim(d.bId)], u, region(d.bId)) | |
| 86 end | 110 end |
| 87 | 111 |
| 88 # u = L*v | |
| 89 function apply(L::Laplace{1}, v::AbstractVector, i::Int) | |
| 90 uᵢ = L.a * SbpOperators.apply(L.op, L.grid.spacing[1], v, i) | |
| 91 return uᵢ | |
| 92 end | |
| 93 | |
| 94 @inline function apply(L::Laplace{2}, v::AbstractArray{T,2} where T, I::Tuple{Index{R1}, Index{R2}}) where {R1, R2} | |
| 95 # 2nd x-derivative | |
| 96 @inbounds vx = view(v, :, Int(I[2])) | |
| 97 @inbounds uᵢ = L.a*SbpOperators.apply(L.op, L.grid.inverse_spacing[1], vx , I[1]) | |
| 98 # 2nd y-derivative | |
| 99 @inbounds vy = view(v, Int(I[1]), :) | |
| 100 @inbounds uᵢ += L.a*SbpOperators.apply(L.op, L.grid.inverse_spacing[2], vy, I[2]) | |
| 101 # NOTE: the package qualifier 'SbpOperators' can problably be removed once all "applying" objects use LazyTensors | |
| 102 return uᵢ | |
| 103 end | |
| 104 | |
| 105 # Slow but maybe convenient? | |
| 106 function apply(L::Laplace{2}, v::AbstractArray{T,2} where T, i::CartesianIndex{2}) | |
| 107 I = Index{Unknown}.(Tuple(i)) | |
| 108 apply(L, v, I) | |
| 109 end | |
| 110 | 112 |
| 111 | 113 |
| 112 struct Neumann{Bid<:BoundaryIdentifier} <: BoundaryCondition end | 114 struct Neumann{Bid<:BoundaryIdentifier} <: BoundaryCondition end |
| 113 | 115 |
| 114 function sat(L::Laplace{2,T}, bc::Neumann{Bid}, v::AbstractArray{T,2}, g::AbstractVector{T}, I::CartesianIndex{2}) where {T,Bid} | 116 function sat(L::Laplace{2,T}, bc::Neumann{Bid}, v::AbstractArray{T,2}, g::AbstractVector{T}, I::CartesianIndex{2}) where {T,Bid} |
