comparison src/SbpOperators/volumeops/derivatives/second_derivative_variable.jl @ 1370:4ef8fb75d144 feature/variable_derivatives

Start splitting out a second_derivative_variable function
author Jonatan Werpers <jonatan@werpers.com>
date Fri, 26 May 2023 21:39:08 +0200
parents 26ad90b42efd
children d0e48c2e6aad
comparison
equal deleted inserted replaced
1369:ff64acfc1ec9 1370:4ef8fb75d144
1 """
2 second_derivative_variable(g, coeff ..., [direction])
3
4 The variable second derivative operator as a `LazyTensor` on the given grid.
5 `coeff` is a grid function of the variable coefficient.
6
7 Approximates the d/dξ c d/dξ on `g` along the coordinate dimension specified
8 by `direction`.
9 """
10 function second_derivative_variable end
11
12
13 function second_derivative_variable(g::TensorGrid, coeff::AbstractArray, inner_stencil::NestedStencil, closure_stencils, dir)
14 check_coefficient(g, coeff)
15
16 Δxᵢ = spacing(g.grids[dir])
17 scaled_inner_stencil = scale(inner_stencil, 1/Δxᵢ^2)
18 scaled_closure_stencils = scale.(Tuple(closure_stencils), 1/Δxᵢ^2)
19 return SecondDerivativeVariable{dir, ndims(g)}(scaled_inner_stencil, scaled_closure_stencils, coeff)
20 end
21
22 function second_derivative_variable(g::EquidistantGrid, coeff::AbstractVector, inner_stencil::NestedStencil, closure_stencils)
23 return second_derivative_variable(TensorGrid(g), coeff, inner_stencil, closure_stencils, 1)
24 end
25
26 function second_derivative_variable(g::TensorGrid, coeff::AbstractArray, stencil_set, dir::Int)
27 inner_stencil = parse_nested_stencil(eltype(coeff), stencil_set["D2variable"]["inner_stencil"])
28 closure_stencils = parse_nested_stencil.(eltype(coeff), stencil_set["D2variable"]["closure_stencils"])
29
30 return second_derivative_variable(g, coeff, inner_stencil, closure_stencils, dir)
31 end
32
33 function second_derivative_variable(g::EquidistantGrid, coeff::AbstractArray, stencil_set)
34 return second_derivative_variable(TensorGrid(g), coeff, stencil_set, 1)
35 end
36
37
38 function check_coefficient(g, coeff)
39 if ndims(g) != ndims(coeff)
40 throw(ArgumentError("The coefficient has dimension $(ndims(coeff)) while the grid is dimension $(ndims(g))"))
41 end
42
43 if size(g) != size(coeff)
44 throw(DimensionMismatch("the size $(size(coeff)) of the coefficient does not match the size $(size(g)) of the grid"))
45 end
46 end
47
48
1 # REVIEW: Fixa docs 49 # REVIEW: Fixa docs
2 """ 50 """
3 SecondDerivativeVariable{Dir,T,D,...} <: LazyTensor{T,D,D} 51 SecondDerivativeVariable{Dir,T,D,...} <: LazyTensor{T,D,D}
4 52
5 A second derivative operator in direction `Dir` with a variable coefficient. 53 A second derivative operator in direction `Dir` with a variable coefficient.
12 function SecondDerivativeVariable{Dir, D}(inner_stencil::NestedStencil{T}, closure_stencils::NTuple{M,NestedStencil{T}}, coefficient::AbstractArray) where {Dir,T,D,M} 60 function SecondDerivativeVariable{Dir, D}(inner_stencil::NestedStencil{T}, closure_stencils::NTuple{M,NestedStencil{T}}, coefficient::AbstractArray) where {Dir,T,D,M}
13 IStencil = typeof(inner_stencil) 61 IStencil = typeof(inner_stencil)
14 CStencil = eltype(closure_stencils) 62 CStencil = eltype(closure_stencils)
15 TArray = typeof(coefficient) 63 TArray = typeof(coefficient)
16 return new{Dir,T,D,M,IStencil,CStencil,TArray}(inner_stencil, closure_stencils, coefficient) 64 return new{Dir,T,D,M,IStencil,CStencil,TArray}(inner_stencil, closure_stencils, coefficient)
17 end
18 end
19
20 function SecondDerivativeVariable(g::TensorGrid, coeff::AbstractArray, inner_stencil::NestedStencil, closure_stencils, dir)
21 check_coefficient(g, coeff)
22
23 Δxᵢ = spacing(g.grids[dir])
24 scaled_inner_stencil = scale(inner_stencil, 1/Δxᵢ^2)
25 scaled_closure_stencils = scale.(Tuple(closure_stencils), 1/Δxᵢ^2)
26 return SecondDerivativeVariable{dir, ndims(g)}(scaled_inner_stencil, scaled_closure_stencils, coeff)
27 end
28
29 function SecondDerivativeVariable(g::EquidistantGrid, coeff::AbstractVector, inner_stencil::NestedStencil, closure_stencils)
30 return SecondDerivativeVariable(TensorGrid(g), coeff, inner_stencil, closure_stencils, 1)
31 end
32
33 @doc raw"""
34 SecondDerivativeVariable(g::EquidistantGrid, coeff::AbstractArray, stencil_set, dir)
35
36 Create a `LazyTensor` for the second derivative with a variable coefficient
37 `coeff` on `grid` from the stencils in `stencil_set`. The direction is
38 determined by `dir`.
39
40 `coeff` is a grid function on `grid`.
41
42 # Example
43 With
44 ```
45 D = SecondDerivativeVariable(g, c, stencil_set, 2)
46 ```
47 then `D*u` approximates
48 ```math
49 \frac{\partial}{\partial y} c(x,y) \frac{\partial u}{\partial y},
50 ```
51 on ``(0,1)⨯(0,1)`` represented by `g`.
52 """
53 function SecondDerivativeVariable(g::TensorGrid, coeff::AbstractArray, stencil_set, dir::Int)
54 inner_stencil = parse_nested_stencil(eltype(coeff), stencil_set["D2variable"]["inner_stencil"])
55 closure_stencils = parse_nested_stencil.(eltype(coeff), stencil_set["D2variable"]["closure_stencils"])
56
57 return SecondDerivativeVariable(g, coeff, inner_stencil, closure_stencils, dir)
58 end
59
60 function SecondDerivativeVariable(g::EquidistantGrid, coeff::AbstractArray, stencil_set)
61 return SecondDerivativeVariable(TensorGrid(g), coeff, stencil_set, 1)
62 end
63
64 function check_coefficient(g, coeff)
65 if ndims(g) != ndims(coeff)
66 throw(ArgumentError("The coefficient has dimension $(ndims(coeff)) while the grid is dimension $(ndims(g))"))
67 end
68
69 if size(g) != size(coeff)
70 throw(DimensionMismatch("the size $(size(coeff)) of the coefficient does not match the size $(size(g)) of the grid"))
71 end 65 end
72 end 66 end
73 67
74 derivative_direction(::SecondDerivativeVariable{Dir}) where {Dir} = Dir 68 derivative_direction(::SecondDerivativeVariable{Dir}) where {Dir} = Dir
75 69