Skip to content

Commit d2f211a

Browse files
authored
RegularGrid: Add more constructors (#1066)
* 'RegularGrid': Add more constructors * Update code * Update code * Update 'CartesianGrid' constructors * Update code * Update code order * Add tests
1 parent 404e397 commit d2f211a

File tree

3 files changed

+103
-52
lines changed

3 files changed

+103
-52
lines changed

src/domains/meshes/cartesiangrid.jl

Lines changed: 15 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -56,41 +56,19 @@ See also [`RegularGrid`](@ref).
5656
"""
5757
const CartesianGrid{M<:𝔼,C<:Cartesian} = RegularGrid{M,C}
5858

59-
function CartesianGrid(
60-
origin::Point{<:𝔼},
61-
spacing::NTuple{Dim,ℒ},
62-
offset::Dims{Dim},
63-
topology::GridTopology{Dim}
64-
) where {Dim,ℒ<:Len}
65-
orig = Point(convert(Cartesian, coords(origin)))
66-
RegularGrid(orig, spacing, offset, topology)
67-
end
68-
69-
CartesianGrid(
70-
origin::Point{<:𝔼},
71-
spacing::NTuple{Dim,Len},
72-
offset::Dims{Dim},
73-
topology::GridTopology{Dim}
74-
) where {Dim} = CartesianGrid(origin, promote(spacing...), offset, topology)
75-
7659
CartesianGrid(
77-
origin::Point{<:𝔼},
60+
origin::Point{𝔼{Dim}},
7861
spacing::NTuple{Dim,Number},
7962
offset::Dims{Dim},
8063
topology::GridTopology{Dim}
81-
) where {Dim} = CartesianGrid(origin, addunit.(spacing, u"m"), offset, topology)
64+
) where {Dim} = RegularGrid(_cartpoint(origin), spacing, offset, topology)
8265

83-
function CartesianGrid(
66+
CartesianGrid(
8467
dims::Dims{Dim},
85-
origin::Point,
68+
origin::Point{𝔼{Dim}},
8669
spacing::NTuple{Dim,Number},
8770
offset::Dims{Dim}=ntuple(i -> 1, Dim)
88-
) where {Dim}
89-
if !all(>(0), dims)
90-
throw(ArgumentError("dimensions must be positive"))
91-
end
92-
CartesianGrid(origin, spacing, offset, GridTopology(dims))
93-
end
71+
) where {Dim} = RegularGrid(dims, _cartpoint(origin), spacing, offset)
9472

9573
CartesianGrid(
9674
dims::Dims{Dim},
@@ -99,28 +77,14 @@ CartesianGrid(
9977
offset::Dims{Dim}=ntuple(i -> 1, Dim)
10078
) where {Dim} = CartesianGrid(dims, Point(origin), spacing, offset)
10179

102-
function CartesianGrid(start::Point, finish::Point, spacing::NTuple{Dim,ℒ}) where {Dim,ℒ<:Len}
103-
dims = Tuple(ceil.(Int, (finish - start) ./ spacing))
104-
origin = start
105-
offset = ntuple(i -> 1, Dim)
106-
CartesianGrid(dims, origin, spacing, offset)
107-
end
108-
109-
CartesianGrid(start::Point, finish::Point, spacing::NTuple{Dim,Len}) where {Dim} =
110-
CartesianGrid(start, finish, promote(spacing...))
111-
112-
CartesianGrid(start::Point, finish::Point, spacing::NTuple{Dim,Number}) where {Dim} =
113-
CartesianGrid(start, finish, addunit.(spacing, u"m"))
80+
CartesianGrid(start::Point{𝔼{Dim}}, finish::Point{𝔼{Dim}}, spacing::NTuple{Dim,Number}) where {Dim} =
81+
RegularGrid(_cartpoint(start), _cartpoint(finish), spacing)
11482

11583
CartesianGrid(start::NTuple{Dim,Number}, finish::NTuple{Dim,Number}, spacing::NTuple{Dim,Number}) where {Dim} =
11684
CartesianGrid(Point(start), Point(finish), spacing)
11785

118-
function CartesianGrid(start::Point, finish::Point; dims::Dims=ntuple(i -> 100, embeddim(start)))
119-
origin = start
120-
spacing = Tuple((finish - start) ./ dims)
121-
offset = ntuple(i -> 1, length(dims))
122-
CartesianGrid(dims, origin, spacing, offset)
123-
end
86+
CartesianGrid(start::Point{𝔼{Dim}}, finish::Point{𝔼{Dim}}; dims::Dims{Dim}=ntuple(i -> 100, Dim)) where {Dim} =
87+
RegularGrid(_cartpoint(start), _cartpoint(finish); dims)
12488

12589
CartesianGrid(
12690
start::NTuple{Dim,Number},
@@ -136,3 +100,9 @@ function CartesianGrid(dims::Dims{Dim}) where {Dim}
136100
end
137101

138102
CartesianGrid(dims::Int...) = CartesianGrid(dims)
103+
104+
# -----------------
105+
# HELPER FUNCTIONS
106+
# -----------------
107+
108+
_cartpoint(p) = Point(convert(Cartesian, coords(p)))

src/domains/meshes/regulargrid.jl

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ and cell spacing `spacing`. The three arguments must have the same length.
1313
A regular grid with dimensions `dims`, with lower left corner of element
1414
`offset` at `origin` and cell spacing `spacing`.
1515
16+
RegularGrid(start, finish, dims=dims)
17+
18+
Alternatively, construct a regular grid from a `start` point to a `finish`
19+
with dimensions `dims`.
20+
21+
RegularGrid(start, finish, spacing)
22+
23+
Alternatively, construct a regular grid from a `start` point to a `finish`
24+
point using a given `spacing`.
25+
1626
## Examples
1727
1828
```
@@ -44,13 +54,9 @@ function RegularGrid(
4454
offset::Dims{N},
4555
topology::GridTopology{N}
4656
) where {M<:Manifold,C<:CRS,N}
47-
if M <: 🌐 && !(C <: LatLon)
48-
throw(ArgumentError("regular spacing on `🌐` requires `LatLon` coordinates"))
49-
end
57+
_checkorigin(origin)
5058

51-
T = CoordRefSystems.mactype(C)
5259
nc = CoordRefSystems.ncoords(C)
53-
us = CoordRefSystems.units(C)
5460

5561
if N nc
5662
throw(ArgumentError("""
@@ -59,9 +65,9 @@ function RegularGrid(
5965
"""))
6066
end
6167

62-
sp = ntuple(i -> numconvert(T, withunit(spacing[i], us[i])), nc)
68+
spac = _spacing(origin, spacing)
6369

64-
RegularGrid{M,C,N,typeof(sp)}(origin, sp, offset, topology)
70+
RegularGrid{M,C,N,typeof(spac)}(origin, spac, offset, topology)
6571
end
6672

6773
function RegularGrid(
@@ -76,6 +82,21 @@ function RegularGrid(
7682
RegularGrid(origin, spacing, offset, GridTopology(dims))
7783
end
7884

85+
function RegularGrid(start::Point, finish::Point, spacing::NTuple{N,Number}) where {N}
86+
_checkorigin(start)
87+
svals, fvals = _startfinish(start, finish)
88+
spac = _spacing(start, spacing)
89+
dims = ceil.(Int, (fvals .- svals) ./ spac)
90+
RegularGrid(dims, start, spac)
91+
end
92+
93+
function RegularGrid(start::Point, finish::Point; dims::Dims=ntuple(i -> 100, CoordRefSystems.ncoords(crs(start))))
94+
_checkorigin(start)
95+
svals, fvals = _startfinish(start, finish)
96+
spacing = (fvals .- svals) ./ dims
97+
RegularGrid(dims, start, spacing)
98+
end
99+
79100
spacing(g::RegularGrid) = g.spacing
80101

81102
offset(g::RegularGrid) = g.offset
@@ -132,3 +153,38 @@ function Base.show(io::IO, ::MIME"text/plain", g::RegularGrid)
132153
println(io, "├─ maximum: ", maximum(g))
133154
print(io, "└─ spacing: ", spacing(g))
134155
end
156+
157+
# -----------------
158+
# HELPER FUNCTIONS
159+
# -----------------
160+
161+
function _checkorigin(origin)
162+
if manifold(origin) <: 🌐 && !(crs(origin) <: LatLon)
163+
throw(ArgumentError("regular spacing on `🌐` requires `LatLon` coordinates"))
164+
end
165+
end
166+
167+
function _spacing(origin, spacing)
168+
C = crs(origin)
169+
T = CoordRefSystems.mactype(C)
170+
nc = CoordRefSystems.ncoords(C)
171+
us = CoordRefSystems.units(C)
172+
ntuple(i -> numconvert(T, withunit(spacing[i], us[i])), nc)
173+
end
174+
175+
function _startfinish(start::Point{<:𝔼}, finish::Point{<:𝔼})
176+
scoords = coords(start)
177+
fcoords = convert(crs(start), coords(finish))
178+
svals = CoordRefSystems.values(scoords)
179+
fvals = CoordRefSystems.values(fcoords)
180+
svals, fvals
181+
end
182+
183+
function _startfinish(start::Point{<:🌐}, finish::Point{<:🌐})
184+
slatlon = convert(LatLon, coords(start))
185+
flatlon = convert(LatLon, coords(finish))
186+
slon = flatlon.lon < slatlon.lon ? slatlon.lon - 360u"°" : slatlon.lon
187+
svals = (slatlon.lat, slon)
188+
fvals = (flatlon.lat, flatlon.lon)
189+
svals, fvals
190+
end

test/meshes.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,31 @@
6767
@test grid[1, 1, 1] == grid[1]
6868
@test grid[10, 20, 30] == grid[6000]
6969

70+
# constructors with start and finish
71+
grid = RegularGrid(merc(0, 0), merc(10, 10), T.((0.1, 0.1)))
72+
@test size(grid) == (100, 100)
73+
@test minimum(grid) == merc(0, 0)
74+
@test maximum(grid) == merc(10, 10)
75+
@test spacing(grid) == (T(0.1) * u"m", T(0.1) * u"m")
76+
77+
grid = RegularGrid(latlon(-50, 150), latlon(50, 30), T.((10, 12)))
78+
@test size(grid) == (10, 20)
79+
@test minimum(grid) == latlon(-50, 150)
80+
@test maximum(grid) == latlon(50, 30)
81+
@test spacing(grid) == (T(10) * u"°", T(12) * u"°")
82+
83+
grid = RegularGrid(merc(0, 0), merc(10, 10), dims=(100, 100))
84+
@test size(grid) == (100, 100)
85+
@test minimum(grid) == merc(0, 0)
86+
@test maximum(grid) == merc(10, 10)
87+
@test spacing(grid) == (T(0.1) * u"m", T(0.1) * u"m")
88+
89+
grid = RegularGrid(latlon(-50, 150), latlon(50, 30), dims=(10, 20))
90+
@test size(grid) == (10, 20)
91+
@test minimum(grid) == latlon(-50, 150)
92+
@test maximum(grid) == latlon(50, 30)
93+
@test spacing(grid) == (T(10) * u"°", T(12) * u"°")
94+
7095
# spacing unit and numtype
7196
grid = RegularGrid((10, 20), Point(Polar(T(0) * u"cm", T(0) * u"rad")), (10.0 * u"mm", 1.0f0 * u"rad"))
7297
@test unit.(spacing(grid)) == (u"cm", u"rad")

0 commit comments

Comments
 (0)