Mercurial > repos > public > sbplib_julia
diff src/SbpOperators/volumeops/derivatives/dissipation.jl @ 1221:b3b4d29b46c3 refactor/grids
Merge default
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Fri, 10 Feb 2023 08:36:56 +0100 |
parents | d60a10ad6579 |
children | 356ec6a72974 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/SbpOperators/volumeops/derivatives/dissipation.jl Fri Feb 10 08:36:56 2023 +0100 @@ -0,0 +1,107 @@ +""" + undivided_skewed04(g::EquidistantGrid, p, direction) + +Create undivided difference operators approximating the `p`th derivative. The +operators do not satisfy any SBP-property and are meant to be used for +building artificial dissipation terms. + +The operators and how they are used to create accurate artifical dissipation +is described in "K. Mattsson, M. Svärd, and J. Nordström, “Stable and Accurate +Artificial Dissipation,” Journal of Scientific Computing, vol. 21, no. 1, pp. +57–79, Aug. 2004" +""" +function undivided_skewed04(g::EquidistantGrid, p, direction) + T = eltype(g) + interior_weights = T.(dissipation_interior_weights(p)) + + D = stencil_operator_distinct_closures( + g, + dissipation_interior_stencil(interior_weights), + dissipation_lower_closure_stencils(interior_weights), + dissipation_upper_closure_stencils(interior_weights), + direction, + ) + Dᵀ = stencil_operator_distinct_closures( + g, + dissipation_transpose_interior_stencil(interior_weights), + dissipation_transpose_lower_closure_stencils(interior_weights), + dissipation_transpose_upper_closure_stencils(interior_weights), + direction, + ) + + return D, Dᵀ +end + +undivided_skewed04(g::EquidistantGrid{1}, p) = undivided_skewed04(g, p, 1) + +function dissipation_interior_weights(p) + if p == 0 + return (1,) + end + + return (0, dissipation_interior_weights(p-1)...) .- (dissipation_interior_weights(p-1)..., 0) +end + +midpoint(weights) = length(weights)÷2 + 1 +midpoint_transpose(weights) = length(weights)+1 - midpoint(weights) + +function dissipation_interior_stencil(weights) + return Stencil(weights..., center=midpoint(weights)) +end +function dissipation_transpose_interior_stencil(weights) + if iseven(length(weights)) + weights = map(-, weights) + end + + return Stencil(weights..., center=midpoint_transpose(weights)) +end + +dissipation_lower_closure_size(weights) = midpoint(weights) - 1 +dissipation_upper_closure_size(weights) = length(weights) - midpoint(weights) + +function dissipation_lower_closure_stencils(interior_weights) + stencil(i) = Stencil(interior_weights..., center=i) + return ntuple(i->stencil(i), dissipation_lower_closure_size(interior_weights)) +end + +function dissipation_upper_closure_stencils(interior_weights) + center(i) = length(interior_weights) - dissipation_upper_closure_size(interior_weights) + i + stencil(i) = Stencil(interior_weights..., center=center(i)) + return ntuple(i->stencil(i), dissipation_upper_closure_size(interior_weights)) +end + +function dissipation_transpose_lower_closure_stencils(interior_weights) + closure = ntuple(i->dissipation_transpose_lower_closure_stencil(interior_weights, i), length(interior_weights)) + + N = maximum(s->length(s.weights), closure) + return right_pad.(closure, N) +end + +function dissipation_transpose_upper_closure_stencils(interior_weights) + closure = reverse(ntuple(i->dissipation_transpose_upper_closure_stencil(interior_weights, i), length(interior_weights))) + + N = maximum(s->length(s.weights), closure) + return left_pad.(closure, N) +end + + +function dissipation_transpose_lower_closure_stencil(interior_weights, i) + w = ntuple(k->interior_weights[i], dissipation_lower_closure_size(interior_weights)) + + for k ∈ i:-1:1 + w = (w..., interior_weights[k]) + end + + return Stencil(w..., center = i) +end + +function dissipation_transpose_upper_closure_stencil(interior_weights, i) + j = length(interior_weights)+1-i + w = ntuple(k->interior_weights[j], dissipation_upper_closure_size(interior_weights)) + + for k ∈ j:1:length(interior_weights) + w = (interior_weights[k], w...) + end + + return Stencil(w..., center = length(interior_weights)-midpoint(interior_weights)+1) +end