Mercurial > repos > public > sbplib_julia
comparison src/Grids/EquidistantGrid.jl @ 911:a378ab959b6f
Merge feature/equidistant_grid/refine
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Tue, 15 Feb 2022 15:14:28 +0100 |
parents | b900fea1c057 |
children | 9b40aeac4269 5b3d4a8ec3ab |
comparison
equal
deleted
inserted
replaced
864:9a2776352c2a | 911:a378ab959b6f |
---|---|
1 export EquidistantGrid | |
2 export spacing | |
3 export inverse_spacing | |
4 export restrict | |
5 export boundary_identifiers | |
6 export boundary_grid | |
7 export refine | |
8 export coarsen | |
9 | |
1 """ | 10 """ |
2 EquidistantGrid(size::NTuple{Dim, Int}, limit_lower::NTuple{Dim, T}, limit_upper::NTuple{Dim, T}) | 11 EquidistantGrid{Dim,T<:Real} <: AbstractGrid |
3 EquidistantGrid{T}() | |
4 | 12 |
5 `EquidistantGrid` is a grid with equidistant grid spacing per coordinat direction. | 13 `Dim`-dimensional equidistant grid with coordinates of type `T`. |
6 | |
7 `EquidistantGrid(size, limit_lower, limit_upper)` construct the grid with the | |
8 domain defined by the two points P1, and P2 given by `limit_lower` and | |
9 `limit_upper`. The length of the domain sides are given by the components of | |
10 (P2-P1). E.g for a 2D grid with P1=(-1,0) and P2=(1,2) the domain is defined | |
11 as (-1,1)x(0,2). The side lengths of the grid are not allowed to be negative. | |
12 The number of equidistantly spaced points in each coordinate direction are given | |
13 by `size`. | |
14 | |
15 `EquidistantGrid{T}()` constructs a 0-dimensional grid. | |
16 | |
17 """ | 14 """ |
18 struct EquidistantGrid{Dim,T<:Real} <: AbstractGrid | 15 struct EquidistantGrid{Dim,T<:Real} <: AbstractGrid |
19 size::NTuple{Dim, Int} | 16 size::NTuple{Dim, Int} |
20 limit_lower::NTuple{Dim, T} | 17 limit_lower::NTuple{Dim, T} |
21 limit_upper::NTuple{Dim, T} | 18 limit_upper::NTuple{Dim, T} |
22 | 19 |
23 # General constructor | 20 function EquidistantGrid{Dim,T}(size::NTuple{Dim, Int}, limit_lower::NTuple{Dim, T}, limit_upper::NTuple{Dim, T}) where {Dim,T} |
24 function EquidistantGrid(size::NTuple{Dim, Int}, limit_lower::NTuple{Dim, T}, limit_upper::NTuple{Dim, T}) where Dim where T | |
25 if any(size .<= 0) | 21 if any(size .<= 0) |
26 throw(DomainError("all components of size must be postive")) | 22 throw(DomainError("all components of size must be postive")) |
27 end | 23 end |
28 if any(limit_upper.-limit_lower .<= 0) | 24 if any(limit_upper.-limit_lower .<= 0) |
29 throw(DomainError("all side lengths must be postive")) | 25 throw(DomainError("all side lengths must be postive")) |
30 end | 26 end |
31 return new{Dim,T}(size, limit_lower, limit_upper) | 27 return new{Dim,T}(size, limit_lower, limit_upper) |
32 end | 28 end |
29 end | |
33 | 30 |
34 # Specialized constructor for 0-dimensional grid | 31 """ |
35 EquidistantGrid{T}() where T = new{0,T}((),(),()) | 32 EquidistantGrid(size, limit_lower, limit_upper) |
33 | |
34 Construct an equidistant grid with corners at the coordinates `limit_lower` and | |
35 `limit_upper`. | |
36 | |
37 The length of the domain sides are given by the components of | |
38 `limit_upper-limit_lower`. E.g for a 2D grid with `limit_lower=(-1,0)` and `limit_upper=(1,2)` the domain is defined | |
39 as `(-1,1)x(0,2)`. The side lengths of the grid are not allowed to be negative. | |
40 | |
41 The number of equidistantly spaced points in each coordinate direction are given | |
42 by the tuple `size`. | |
43 """ | |
44 function EquidistantGrid(size, limit_lower, limit_upper) | |
45 return EquidistantGrid{length(size), eltype(limit_lower)}(size, limit_lower, limit_upper) | |
36 end | 46 end |
37 export EquidistantGrid | |
38 | 47 |
48 """ | |
49 EquidistantGrid{T}() | |
50 | |
51 Constructs a 0-dimensional grid. | |
52 """ | |
53 EquidistantGrid{T}() where T = EquidistantGrid{0,T}((),(),()) # Convenience constructor for 0-dim grid | |
39 | 54 |
40 """ | 55 """ |
41 EquidistantGrid(size::Int, limit_lower::T, limit_upper::T) | 56 EquidistantGrid(size::Int, limit_lower::T, limit_upper::T) |
42 | 57 |
43 Convenience constructor for 1D grids. | 58 Convenience constructor for 1D grids. |
60 dimension(grid::EquidistantGrid{Dim}) where Dim = Dim | 75 dimension(grid::EquidistantGrid{Dim}) where Dim = Dim |
61 | 76 |
62 """ | 77 """ |
63 spacing(grid::EquidistantGrid) | 78 spacing(grid::EquidistantGrid) |
64 | 79 |
65 The spacing between the grid points of the grid. | 80 The spacing between grid points. |
66 """ | 81 """ |
67 spacing(grid::EquidistantGrid) = (grid.limit_upper.-grid.limit_lower)./(grid.size.-1) | 82 spacing(grid::EquidistantGrid) = (grid.limit_upper.-grid.limit_lower)./(grid.size.-1) |
68 export spacing | |
69 | 83 |
70 """ | 84 """ |
71 inverse_spacing(grid::EquidistantGrid) | 85 inverse_spacing(grid::EquidistantGrid) |
72 | 86 |
73 The reciprocal of the spacing between the grid points of the grid. | 87 The reciprocal of the spacing between grid points. |
74 """ | 88 """ |
75 inverse_spacing(grid::EquidistantGrid) = 1 ./ spacing(grid) | 89 inverse_spacing(grid::EquidistantGrid) = 1 ./ spacing(grid) |
76 export inverse_spacing | |
77 | 90 |
78 """ | 91 """ |
79 points(grid::EquidistantGrid) | 92 points(grid::EquidistantGrid) |
80 | 93 |
81 The point of the grid as an array of tuples with the same dimension as the grid. | 94 The point of the grid as an array of tuples with the same dimension as the grid. |
91 end | 104 end |
92 | 105 |
93 """ | 106 """ |
94 restrict(::EquidistantGrid, dim) | 107 restrict(::EquidistantGrid, dim) |
95 | 108 |
96 Pick out given dimensions from the grid and return a grid for them | 109 Pick out given dimensions from the grid and return a grid for them. |
97 """ | 110 """ |
98 function restrict(grid::EquidistantGrid, dim) | 111 function restrict(grid::EquidistantGrid, dim) |
99 size = grid.size[dim] | 112 size = grid.size[dim] |
100 limit_lower = grid.limit_lower[dim] | 113 limit_lower = grid.limit_lower[dim] |
101 limit_upper = grid.limit_upper[dim] | 114 limit_upper = grid.limit_upper[dim] |
102 | 115 |
103 return EquidistantGrid(size, limit_lower, limit_upper) | 116 return EquidistantGrid(size, limit_lower, limit_upper) |
104 end | 117 end |
105 export restrict | |
106 | 118 |
107 """ | 119 """ |
108 boundary_identifiers(::EquidistantGrid) | 120 boundary_identifiers(::EquidistantGrid) |
109 | 121 |
110 Returns a tuple containing the boundary identifiers for the grid, stored as | 122 Returns a tuple containing the boundary identifiers for the grid, stored as |
112 CartesianBoundary(1,Upper), | 124 CartesianBoundary(1,Upper), |
113 CartesianBoundary(2,Lower), | 125 CartesianBoundary(2,Lower), |
114 ...) | 126 ...) |
115 """ | 127 """ |
116 boundary_identifiers(g::EquidistantGrid) = (((ntuple(i->(CartesianBoundary{i,Lower}(),CartesianBoundary{i,Upper}()),dimension(g)))...)...,) | 128 boundary_identifiers(g::EquidistantGrid) = (((ntuple(i->(CartesianBoundary{i,Lower}(),CartesianBoundary{i,Upper}()),dimension(g)))...)...,) |
117 export boundary_identifiers | |
118 | 129 |
119 | 130 |
120 """ | 131 """ |
121 boundary_grid(grid::EquidistantGrid,id::CartesianBoundary) | 132 boundary_grid(grid::EquidistantGrid,id::CartesianBoundary) |
122 boundary_grid(::EquidistantGrid{1},::CartesianBoundary{1}) | 133 boundary_grid(::EquidistantGrid{1},::CartesianBoundary{1}) |
131 if orth_dims == dims | 142 if orth_dims == dims |
132 throw(DomainError("boundary identifier not matching grid")) | 143 throw(DomainError("boundary identifier not matching grid")) |
133 end | 144 end |
134 return restrict(grid,orth_dims) | 145 return restrict(grid,orth_dims) |
135 end | 146 end |
136 export boundary_grid | |
137 boundary_grid(::EquidistantGrid{1,T},::CartesianBoundary{1}) where T = EquidistantGrid{T}() | 147 boundary_grid(::EquidistantGrid{1,T},::CartesianBoundary{1}) where T = EquidistantGrid{T}() |
148 | |
149 | |
150 """ | |
151 refine(grid::EquidistantGrid, r::Int) | |
152 | |
153 Refines `grid` by a factor `r`. The factor is applied to the number of | |
154 intervals which is 1 less than the size of the grid. | |
155 | |
156 See also: [`coarsen`](@ref) | |
157 """ | |
158 function refine(grid::EquidistantGrid, r::Int) | |
159 sz = size(grid) | |
160 new_sz = (sz .- 1).*r .+ 1 | |
161 return EquidistantGrid{dimension(grid), eltype(grid)}(new_sz, grid.limit_lower, grid.limit_upper) | |
162 end | |
163 | |
164 """ | |
165 coarsen(grid::EquidistantGrid, r::Int) | |
166 | |
167 Coarsens `grid` by a factor `r`. The factor is applied to the number of | |
168 intervals which is 1 less than the size of the grid. If the number of | |
169 intervals are not divisible by `r` an error is raised. | |
170 | |
171 See also: [`refine`](@ref) | |
172 """ | |
173 function coarsen(grid::EquidistantGrid, r::Int) | |
174 sz = size(grid) | |
175 | |
176 if !all(n -> (n % r == 0), sz.-1) | |
177 throw(DomainError(r, "Size minus 1 must be divisible by the ratio.")) | |
178 end | |
179 | |
180 new_sz = (sz .- 1).÷r .+ 1 | |
181 | |
182 return EquidistantGrid{dimension(grid), eltype(grid)}(new_sz, grid.limit_lower, grid.limit_upper) | |
183 end |