comparison src/SbpOperators/volumeops/laplace/laplace.jl @ 866:1784b1c0af3e feature/laplace_opset

Merge with default
author Vidar Stiernström <vidar.stiernstrom@it.uu.se>
date Wed, 19 Jan 2022 14:44:24 +0100
parents 1970ebceabe4 b4acd25943f4
children 4bd35ba8f34a
comparison
equal deleted inserted replaced
865:545a6c1a0a0e 866:1784b1c0af3e
1 """ 1 """
2 Laplace{T, Dim, TMdiffop} <: TensorMapping{T,Dim,Dim} 2 Laplace{T, Dim, TMdiffop} <: TensorMapping{T,Dim,Dim}
3 Laplace(grid::AbstractGrid, fn; order) 3 Laplace(grid, filename; order)
4 4
5 Implements the Laplace operator, approximating ∑d²/xᵢ² , i = 1,...,`Dim` as a 5 Implements the Laplace operator, approximating ∑d²/xᵢ² , i = 1,...,`Dim` as a
6 `TensorMapping`. Additionally, `Laplace` stores the inner product and boundary 6 `TensorMapping`. Additionally, `Laplace` stores the inner product and boundary
7 operators relevant for constructing a SBP finite difference scheme as `TensorMapping`s. 7 operators relevant for constructing a SBP finite difference scheme as a `TensorMapping`.
8 8
9 Laplace(grid, fn; order) creates the Laplace operator defined on `grid`, 9 `Laplace(grid, filename; order)` creates the Laplace operator defined on `grid`,
10 where the operators are read from TOML. The differential operator is created 10 where the operators are read from TOML. The differential operator is created
11 using `laplace(grid::AbstractGrid,...)`. 11 using `laplace(grid,...)`.
12 12
13 Note that all properties of Laplace, excluding the Differential operator `D`, are 13 Note that all properties of Laplace, excluding the differential operator `Laplace.D`, are
14 abstract types. For performance reasons, they should therefore be 14 abstract types. For performance reasons, they should therefore be
15 accessed via the provided getter functions (e.g `inner_product(::Laplace)`). 15 accessed via the provided getter functions (e.g `inner_product(::Laplace)`).
16 16
17 """ 17 """
18 struct Laplace{T, Dim, TMdiffop<:TensorMapping{T,Dim,Dim}} <: TensorMapping{T,Dim,Dim} 18 struct Laplace{T, Dim, TMdiffop<:TensorMapping{T,Dim,Dim}} <: TensorMapping{T,Dim,Dim}
19 D::TMdiffop # Differential operator 19 D::TMdiffop # Differential operator
20 H::TensorMapping # Inner product operator 20 H::TensorMapping # Inner product operator
21 H_inv::TensorMapping # Inverse inner product operator 21 H_inv::TensorMapping # Inverse inner product operator
22 e::StaticDict{<:BoundaryIdentifier,<:TensorMapping} # Boundary restriction operators. 22 e::StaticDict{<:BoundaryIdentifier,<:TensorMapping} # Boundary restriction operators.
23 d::StaticDict{<:BoundaryIdentifier,<:TensorMapping} # Normal derivative operators 23 d::StaticDict{<:BoundaryIdentifier,<:TensorMapping} # Normal derivative operators
24 H_boundary::StaticDict{<:BoundaryIdentifier,<:TensorMapping} # Boundary quadrature operators # TODO: Boundary inner product? 24 H_boundary::StaticDict{<:BoundaryIdentifier,<:TensorMapping} # Boundary quadrature operators
25 end 25 end
26 export Laplace 26 export Laplace
27 27
28 function Laplace(grid::AbstractGrid, fn; order) 28 function Laplace(grid, filename; order)
29
30 # Read stencils
31 stencil_set = read_stencil_set(filename; order)
29 # TODO: Removed once we can construct the volume and 32 # TODO: Removed once we can construct the volume and
30 # boundary operators by op(grid, fn; order,...). 33 # boundary operators by op(grid, read_stencil_set(fn; order,...)).
31 # Read stencils 34 D_inner_stecil = parse_stencil(stencil_set["D2"]["inner_stencil"])
32 op = read_D2_operator(fn; order) 35 D_closure_stencils = parse_stencil.(stencil_set["D2"]["closure_stencils"])
33 D_inner_stecil = op.innerStencil 36 H_inner_stencils = parse_scalar(stencil_set["H"]["inner"])
34 D_closure_stencils = op.closureStencils 37 H_closure_stencils = parse_tuple(stencil_set["H"]["closure"])
35 H_closure_stencils = op.quadratureClosure 38 e_closure_stencil = parse_stencil(stencil_set["e"]["closure"])
36 e_closure_stencil = op.eClosure 39 d_closure_stencil = parse_stencil(stencil_set["d1"]["closure"])
37 d_closure_stencil = op.dClosure
38 40
39 # Volume operators 41 # Volume operators
40 Δ = laplace(grid, D_inner_stecil, D_closure_stencils) 42 Δ = laplace(grid, D_inner_stecil, D_closure_stencils)
41 H = inner_product(grid, H_closure_stencils) 43 H = inner_product(grid, H_inner_stencils, H_closure_stencils)
42 H⁻¹ = inverse_inner_product(grid, H_closure_stencils) 44 H⁻¹ = inverse_inner_product(grid, H_inner_stencils, H_closure_stencils)
43 45
44 # Boundary operator - id pairs 46 # Boundary operator - id pairs
45 ids = boundary_identifiers(grid) 47 ids = boundary_identifiers(grid)
46 n_ids = length(ids) 48 n_ids = length(ids)
47 e_pairs = ntuple(i -> ids[i] => boundary_restriction(grid,e_closure_stencil,ids[i]),n_ids) 49 e_pairs = ntuple(i -> ids[i] => boundary_restriction(grid, e_closure_stencil, ids[i]), n_ids)
48 d_pairs = ntuple(i -> ids[i] => normal_derivative(grid,d_closure_stencil,ids[i]),n_ids) 50 d_pairs = ntuple(i -> ids[i] => normal_derivative(grid, d_closure_stencil, ids[i]), n_ids)
49 Hᵧ_pairs = ntuple(i -> ids[i] => inner_product(boundary_grid(grid,ids[i]),H_closure_stencils),n_ids) 51 Hᵧ_pairs = ntuple(i -> ids[i] => inner_product(boundary_grid(grid, ids[i]), H_inner_stencils, H_closure_stencils), n_ids)
50 52
51 return Laplace(Δ, H, H⁻¹, StaticDict(e_pairs), StaticDict(d_pairs), StaticDict(Hᵧ_pairs)) 53 return Laplace(Δ, H, H⁻¹, StaticDict(e_pairs), StaticDict(d_pairs), StaticDict(Hᵧ_pairs))
52 end 54 end
53 55
54 # TODO: Consider pretty printing of the following form 56 # TODO: Consider pretty printing of the following form
58 LazyTensors.domain_size(L::Laplace) = LazyTensors.domain_size(L.D) 60 LazyTensors.domain_size(L::Laplace) = LazyTensors.domain_size(L.D)
59 LazyTensors.apply(L::Laplace, v::AbstractArray, I...) = LazyTensors.apply(L.D,v,I...) 61 LazyTensors.apply(L::Laplace, v::AbstractArray, I...) = LazyTensors.apply(L.D,v,I...)
60 62
61 63
62 """ 64 """
63 inner_product(L::Lapalace) 65 inner_product(L::Laplace)
64 66
65 Returns the inner product operator associated with `L` 67 Returns the inner product operator associated with `L`
66 68
67 """ 69 """
68 inner_product(L::Laplace) = L.H 70 inner_product(L::Laplace) = L.H
69 export inner_product 71 export inner_product
70 72
71 73
72 """ 74 """
73 inverse_inner_product(L::Lapalace) 75 inverse_inner_product(L::Laplace)
74 76
75 Returns the inverse of the inner product operator associated with `L` 77 Returns the inverse of the inner product operator associated with `L`
76 78
77 """ 79 """
78 inverse_inner_product(L::Laplace) = L.H_inv 80 inverse_inner_product(L::Laplace) = L.H_inv
79 export inverse_inner_product 81 export inverse_inner_product
80 82
81 83
82 """ 84 """
83 boundary_restriction(L::Lapalace,id::BoundaryIdentifier) 85 boundary_restriction(L::Laplace, id::BoundaryIdentifier)
84 boundary_restriction(L::Lapalace,ids::NTuple{N,BoundaryIdentifier}) 86 boundary_restriction(L::Laplace, ids::NTuple{N,BoundaryIdentifier})
85 boundary_restriction(L::Lapalace,ids...) 87 boundary_restriction(L::Laplace, ids...)
86 88
87 Returns boundary restriction operator(s) associated with `L` for the boundary(s) 89 Returns boundary restriction operator(s) associated with `L` for the boundary(s)
88 identified by id(s). 90 identified by id(s).
89 91
90 """ 92 """
91 boundary_restriction(L::Laplace,id::BoundaryIdentifier) = L.e[id] 93 boundary_restriction(L::Laplace, id::BoundaryIdentifier) = L.e[id]
92 boundary_restriction(L::Laplace,ids::NTuple{N,BoundaryIdentifier}) where N = ntuple(i->L.e[ids[i]],N) 94 boundary_restriction(L::Laplace, ids::NTuple{N,BoundaryIdentifier}) where N = ntuple(i->L.e[ids[i]],N)
93 boundary_restriction(L::Laplace,ids::Vararg{BoundaryIdentifier,N}) where N = ntuple(i->L.e[ids[i]],N) 95 boundary_restriction(L::Laplace, ids::Vararg{BoundaryIdentifier,N}) where N = ntuple(i->L.e[ids[i]],N)
94 export boundary_restriction 96 export boundary_restriction
95 97
96 98
97 """ 99 """
98 normal_derivative(L::Lapalace,id::BoundaryIdentifier) 100 normal_derivative(L::Laplace, id::BoundaryIdentifier)
99 normal_derivative(L::Lapalace,ids::NTuple{N,BoundaryIdentifier}) 101 normal_derivative(L::Laplace, ids::NTuple{N,BoundaryIdentifier})
100 normal_derivative(L::Lapalace,ids...) 102 normal_derivative(L::Laplace, ids...)
101 103
102 Returns normal derivative operator(s) associated with `L` for the boundary(s) 104 Returns normal derivative operator(s) associated with `L` for the boundary(s)
103 identified by id(s). 105 identified by id(s).
104 106
105 """ 107 """
106 normal_derivative(L::Laplace,id::BoundaryIdentifier) = L.d[id] 108 normal_derivative(L::Laplace, id::BoundaryIdentifier) = L.d[id]
107 normal_derivative(L::Laplace,ids::NTuple{N,BoundaryIdentifier}) where N = ntuple(i->L.d[ids[i]],N) 109 normal_derivative(L::Laplace, ids::NTuple{N,BoundaryIdentifier}) where N = ntuple(i->L.d[ids[i]],N)
108 normal_derivative(L::Laplace,ids::Vararg{BoundaryIdentifier,N}) where N = ntuple(i->L.d[ids[i]],N) 110 normal_derivative(L::Laplace, ids::Vararg{BoundaryIdentifier,N}) where N = ntuple(i->L.d[ids[i]],N)
109 export normal_derivative 111 export normal_derivative
110 112
111 113
112 # TODO: boundary_inner_product?
113 """ 114 """
114 boundary_quadrature(L::Lapalace,id::BoundaryIdentifier) 115 boundary_quadrature(L::Laplace, id::BoundaryIdentifier)
115 boundary_quadrature(L::Lapalace,ids::NTuple{N,BoundaryIdentifier}) 116 boundary_quadrature(L::Laplace, ids::NTuple{N,BoundaryIdentifier})
116 boundary_quadrature(L::Lapalace,ids...) 117 boundary_quadrature(L::Laplace, ids...)
117 118
118 Returns boundary quadrature operator(s) associated with `L` for the boundary(s) 119 Returns boundary quadrature operator(s) associated with `L` for the boundary(s)
119 identified by id(s). 120 identified by id(s).
120 121
121 """ 122 """
122 boundary_quadrature(L::Laplace,id::BoundaryIdentifier) = L.H_boundary[id] 123 boundary_quadrature(L::Laplace, id::BoundaryIdentifier) = L.H_boundary[id]
123 boundary_quadrature(L::Laplace,ids::NTuple{N,BoundaryIdentifier}) where N = ntuple(i->L.H_boundary[ids[i]],N) 124 boundary_quadrature(L::Laplace, ids::NTuple{N,BoundaryIdentifier}) where N = ntuple(i->L.H_boundary[ids[i]],N)
124 boundary_quadrature(L::Laplace,ids::Vararg{BoundaryIdentifier,N}) where N = ntuple(i->L.H_boundary[ids[i]],N) 125 boundary_quadrature(L::Laplace, ids::Vararg{BoundaryIdentifier,N}) where N = ntuple(i->L.H_boundary[ids[i]],N)
125 export boundary_quadrature 126 export boundary_quadrature
126 127
127 128
128 """ 129 """
129 laplace(grid, inner_stencil, closure_stencils) 130 laplace(grid::EquidistantGrid{Dim}, inner_stencil, closure_stencils)
130 131
131 Creates the Laplace operator operator `Δ` as a `TensorMapping` 132 Creates the Laplace operator operator `Δ` as a `TensorMapping`
132 133
133 `Δ` approximates the Laplace operator ∑d²/xᵢ² , i = 1,...,N on the N-dimensional 134 `Δ` approximates the Laplace operator ∑d²/xᵢ² , i = 1,...,`Dim` on `grid`, using
134 `grid`, using the stencil `inner_stencil` in the interior and a set of stencils 135 the stencil `inner_stencil` in the interior and a set of stencils `closure_stencils`
135 `closure_stencils` for the points in the closure regions. 136 for the points in the closure regions.
136 137
137 On a one-dimensional `grid`, `Δ` is equivalent to `second_derivative`. On a 138 On a one-dimensional `grid`, `Δ` is equivalent to `second_derivative`. On a
138 multi-dimensional `grid`, `Δ` is the sum of multi-dimensional `second_derivative`s 139 multi-dimensional `grid`, `Δ` is the sum of multi-dimensional `second_derivative`s
139 where the sum is carried out lazily. 140 where the sum is carried out lazily.
140 """ 141 """
141 function laplace(grid::AbstractGrid, inner_stencil, closure_stencils) 142 function laplace(grid::EquidistantGrid, inner_stencil, closure_stencils)
142 Δ = second_derivative(grid, inner_stencil, closure_stencils, 1) 143 Δ = second_derivative(grid, inner_stencil, closure_stencils, 1)
143 for d = 2:dimension(grid) 144 for d = 2:dimension(grid)
144 Δ += second_derivative(grid, inner_stencil, closure_stencils, d) 145 Δ += second_derivative(grid, inner_stencil, closure_stencils, d)
145 end 146 end
146 return Δ 147 return Δ