Skip to content

Commit 36d2045

Browse files
Add convenience constructors for grids
1 parent 13c6176 commit 36d2045

File tree

4 files changed

+418
-0
lines changed

4 files changed

+418
-0
lines changed

src/Grids/Grids.jl

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ include("spectralelement.jl")
7575
include("extruded.jl")
7676
include("column.jl")
7777
include("level.jl")
78+
include("convenience_constructors.jl")
7879

7980

8081

src/Grids/convenience_constructors.jl

+379
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,379 @@
1+
#=
2+
While we recommend users to use our composable
3+
methods, this file contains some convenience
4+
constructors, which are meant to improve
5+
developer experience.
6+
=#
7+
8+
"""
9+
ExtrudedCubedSphereGrid(
10+
::Type{<:AbstractFloat}; # defaults to Float64
11+
z_elem::Integer = 10,
12+
z_min::Real = FT(0),
13+
z_max::Real = FT(1),
14+
boundary_names = (:bottom, :top),
15+
device = ClimaComms.device(),
16+
context = ClimaComms.context(device),
17+
stretch = Meshes.Uniform(),
18+
hypsography = Flat(),
19+
radius::Real = FT(6.371229e6),
20+
global_geometry = Geometry.ShallowSphericalGlobalGeometry(radius),
21+
h_elem::Integer = 4,
22+
Nq::Integer = 4,
23+
quad::Quadratures.QuadratureStyle = Quadratures.GLL{Nq}(),
24+
h_domain = Domains.SphereDomain(radius),
25+
h_mesh = Meshes.EquiangularCubedSphere(h_domain, h_elem)
26+
)
27+
28+
A convenience constructor, which builds a
29+
`ExtrudedFiniteDifferenceGrid`.
30+
31+
All arguments are optional.
32+
"""
33+
ExtrudedCubedSphereGrid(; kwargs...) =
34+
ExtrudedCubedSphereGrid(Float64; kwargs...)
35+
36+
function ExtrudedCubedSphereGrid(
37+
::Type{FT};
38+
z_elem::Integer = 10,
39+
z_min::Real = FT(0),
40+
z_max::Real = FT(1),
41+
boundary_names = (:bottom, :top),
42+
device = ClimaComms.device(),
43+
context = ClimaComms.context(device),
44+
stretch = Meshes.Uniform(),
45+
hypsography = Flat(),
46+
radius::Real = FT(6.371229e6),
47+
global_geometry = Geometry.ShallowSphericalGlobalGeometry(radius),
48+
h_elem::Integer = 4,
49+
Nq::Integer = 4,
50+
quad::Quadratures.QuadratureStyle = Quadratures.GLL{Nq}(),
51+
h_domain = Domains.SphereDomain(radius),
52+
h_mesh = Meshes.EquiangularCubedSphere(h_domain, h_elem),
53+
) where {FT}
54+
55+
h_topology = Topologies.Topology2D(context, h_mesh)
56+
h_grid = Grids.SpectralElementGrid2D(h_topology, quad)
57+
z_domain = Domains.IntervalDomain(
58+
Geometry.ZPoint(z_min),
59+
Geometry.ZPoint(z_max);
60+
boundary_names,
61+
)
62+
z_mesh = Meshes.IntervalMesh(z_domain, stretch; nelems = z_elem)
63+
z_topology = Topologies.IntervalTopology(context, z_mesh)
64+
vertical_grid = FiniteDifferenceGrid(z_topology)
65+
return ExtrudedFiniteDifferenceGrid(
66+
h_grid,
67+
vertical_grid,
68+
hypsography,
69+
global_geometry,
70+
)
71+
end
72+
73+
"""
74+
CubedSphereGrid(
75+
::Type{<:AbstractFloat}; # defaults to Float64
76+
device = ClimaComms.device(),
77+
context = ClimaComms.context(device),
78+
radius::Real = FT(6.371229e6),
79+
Nq::Integer = 4,
80+
h_elem::Integer = 10,
81+
quad::Quadratures.QuadratureStyle = Quadratures.GLL{Nq}(),
82+
h_domain = Domains.SphereDomain(radius),
83+
h_mesh = Meshes.EquiangularCubedSphere(h_domain, h_elem)
84+
)
85+
86+
A convenience constructor, which builds a
87+
`SpectralElementGrid2D`.
88+
89+
All arguments are optional.
90+
"""
91+
CubedSphereGrid(; kwargs...) = CubedSphereGrid(Float64; kwargs...)
92+
function CubedSphereGrid(
93+
::Type{FT};
94+
device = ClimaComms.device(),
95+
context = ClimaComms.context(device),
96+
radius::Real = FT(6.371229e6),
97+
Nq::Integer = 4,
98+
h_elem::Integer = 10,
99+
quad::Quadratures.QuadratureStyle = Quadratures.GLL{Nq}(),
100+
h_domain = Domains.SphereDomain(radius),
101+
h_mesh = Meshes.EquiangularCubedSphere(h_domain, h_elem),
102+
) where {FT}
103+
h_topology = Topologies.Topology2D(context, h_mesh)
104+
return Grids.SpectralElementGrid2D(h_topology, quad)
105+
end
106+
107+
"""
108+
ColumnGrid(
109+
::Type{<:AbstractFloat}; # defaults to Float64
110+
z_elem::Integer = 10,
111+
z_min::Real = FT(0),
112+
z_max::Real = FT(1),
113+
boundary_names = (:bottom, :top),
114+
device = ClimaComms.device(),
115+
context = ClimaComms.context(device),
116+
stretch = Meshes.Uniform(),
117+
)
118+
119+
A convenience constructor, which builds a
120+
`FiniteDifferenceGrid` given.
121+
122+
All arguments are optional.
123+
"""
124+
ColumnGrid(; kwargs...) = ColumnGrid(Float64; kwargs...)
125+
function ColumnGrid(
126+
::Type{FT};
127+
z_elem::Integer = 10,
128+
z_min::Real = FT(0),
129+
z_max::Real = FT(1),
130+
boundary_names = (:bottom, :top),
131+
device = ClimaComms.device(),
132+
context = ClimaComms.context(device),
133+
stretch = Meshes.Uniform(),
134+
) where {FT}
135+
z_domain = Domains.IntervalDomain(
136+
Geometry.ZPoint(z_min),
137+
Geometry.ZPoint(z_max);
138+
boundary_names,
139+
)
140+
z_mesh = Meshes.IntervalMesh(z_domain, stretch; nelems = z_elem)
141+
z_topology = Topologies.IntervalTopology(context, z_mesh)
142+
return FiniteDifferenceGrid(z_topology)
143+
end
144+
145+
"""
146+
Box3DGrid(
147+
::Type{<:AbstractFloat}; # defaults to Float64
148+
z_elem::Integer = 10,
149+
x_min::Real = FT(0),
150+
x_max::Real = FT(1),
151+
y_min::Real = FT(0),
152+
y_max::Real = FT(1),
153+
z_min::Real = FT(0),
154+
z_max::Real = FT(1),
155+
boundary_names = (:bottom, :top),
156+
x1periodic = true,
157+
x2periodic = true,
158+
x1boundary = (:east, :west),
159+
x2boundary = (:south, :north),
160+
device = ClimaComms.device(),
161+
context = ClimaComms.context(device),
162+
stretch = Meshes.Uniform(),
163+
hypsography = Flat(),
164+
global_geometry = Geometry.CartesianGlobalGeometry(),
165+
Nq::Integer = 4,
166+
n1::Integer = 1, # number of horizontal elements
167+
n2::Integer = 1, # number of horizontal elements
168+
quad::Quadratures.QuadratureStyle = Quadratures.GLL{Nq}(),
169+
)
170+
171+
A convenience constructor, which builds a
172+
`ExtrudedFiniteDifferenceGrid` with a
173+
`FiniteDifferenceGrid` vertical grid and a
174+
`SpectralElementGrid2D` horizontal grid.
175+
176+
All arguments are optional.
177+
"""
178+
Box3DGrid(; kwargs...) = Box3DGrid(Float64; kwargs...)
179+
function Box3DGrid(
180+
::Type{FT};
181+
z_elem::Integer = 10,
182+
x_min::Real = FT(0),
183+
x_max::Real = FT(1),
184+
y_min::Real = FT(0),
185+
y_max::Real = FT(1),
186+
z_min::Real = FT(0),
187+
z_max::Real = FT(1),
188+
boundary_names = (:bottom, :top),
189+
x1periodic = true,
190+
x2periodic = true,
191+
x1boundary = (:east, :west),
192+
x2boundary = (:south, :north),
193+
device = ClimaComms.device(),
194+
context = ClimaComms.context(device),
195+
stretch = Meshes.Uniform(),
196+
hypsography = Flat(),
197+
global_geometry = Geometry.CartesianGlobalGeometry(),
198+
Nq::Integer = 4,
199+
n1::Integer = 1,
200+
n2::Integer = 1,
201+
quad::Quadratures.QuadratureStyle = Quadratures.GLL{Nq}(),
202+
) where {FT}
203+
204+
domain = Domains.RectangleDomain(
205+
Domains.IntervalDomain(
206+
Geometry.XPoint{FT}(x_min),
207+
Geometry.XPoint{FT}(x_max);
208+
periodic = x1periodic,
209+
boundary_names = x1boundary,
210+
),
211+
Domains.IntervalDomain(
212+
Geometry.YPoint{FT}(y_min),
213+
Geometry.YPoint{FT}(y_max);
214+
periodic = x2periodic,
215+
boundary_names = x2boundary,
216+
),
217+
)
218+
h_mesh = Meshes.RectilinearMesh(domain, n1, n2)
219+
h_topology = Topologies.Topology2D(context, h_mesh)
220+
h_grid = Grids.SpectralElementGrid2D(h_topology, quad)
221+
z_domain = Domains.IntervalDomain(
222+
Geometry.ZPoint(z_min),
223+
Geometry.ZPoint(z_max);
224+
boundary_names,
225+
)
226+
z_mesh = Meshes.IntervalMesh(z_domain, stretch; nelems = z_elem)
227+
z_topology = Topologies.IntervalTopology(context, z_mesh)
228+
vertical_grid = FiniteDifferenceGrid(z_topology)
229+
return ExtrudedFiniteDifferenceGrid(
230+
h_grid,
231+
vertical_grid,
232+
hypsography,
233+
global_geometry,
234+
)
235+
end
236+
237+
"""
238+
SliceXZGrid(
239+
::Type{<:AbstractFloat}; # defaults to Float64
240+
z_elem::Integer = 10,
241+
x_min::Real = FT(0),
242+
x_max::Real = FT(1),
243+
z_min::Real = FT(0),
244+
z_max::Real = FT(1),
245+
boundary_names = (:bottom, :top),
246+
x1periodic = true,
247+
x1boundary = (:east, :west),
248+
device = ClimaComms.device(),
249+
context = ClimaComms.context(device),
250+
stretch = Meshes.Uniform(),
251+
hypsography = Flat(),
252+
global_geometry = Geometry.CartesianGlobalGeometry(),
253+
Nq::Integer = 4,
254+
n1::Integer = 1, # number of horizontal elements
255+
quad::Quadratures.QuadratureStyle = Quadratures.GLL{Nq}(),
256+
)
257+
258+
A convenience constructor, which builds a
259+
`ExtrudedFiniteDifferenceGrid` with a
260+
`FiniteDifferenceGrid` vertical grid and a
261+
`SpectralElementGrid1D` horizontal grid.
262+
263+
All arguments are optional.
264+
- ``
265+
"""
266+
SliceXZGrid(; kwargs...) = SliceXZGrid(Float64; kwargs...)
267+
function SliceXZGrid(
268+
::Type{FT};
269+
z_elem::Integer = 10,
270+
x_min::Real = FT(0),
271+
x_max::Real = FT(1),
272+
z_min::Real = FT(0),
273+
z_max::Real = FT(1),
274+
boundary_names = (:bottom, :top),
275+
x1periodic = true,
276+
x1boundary = (:east, :west),
277+
device = ClimaComms.device(),
278+
context = ClimaComms.context(device),
279+
stretch = Meshes.Uniform(),
280+
hypsography = Flat(),
281+
global_geometry = Geometry.CartesianGlobalGeometry(),
282+
Nq::Integer = 4,
283+
n1::Integer = 1,
284+
quad::Quadratures.QuadratureStyle = Quadratures.GLL{Nq}(),
285+
) where {FT}
286+
287+
h_domain = Domains.IntervalDomain(
288+
Geometry.XPoint{FT}(x_min),
289+
Geometry.XPoint{FT}(x_max);
290+
periodic = x1periodic,
291+
boundary_names = x1boundary,
292+
)
293+
h_mesh = Meshes.IntervalMesh(h_domain; nelems = n1)
294+
h_topology = Topologies.IntervalTopology(context, h_mesh)
295+
h_grid = Grids.SpectralElementGrid1D(h_topology, quad)
296+
z_domain = Domains.IntervalDomain(
297+
Geometry.ZPoint(z_min),
298+
Geometry.ZPoint(z_max);
299+
boundary_names,
300+
)
301+
z_mesh = Meshes.IntervalMesh(z_domain, stretch; nelems = z_elem)
302+
z_topology = Topologies.IntervalTopology(context, z_mesh)
303+
vertical_grid = FiniteDifferenceGrid(z_topology)
304+
return ExtrudedFiniteDifferenceGrid(
305+
h_grid,
306+
vertical_grid,
307+
hypsography,
308+
global_geometry,
309+
)
310+
end
311+
312+
"""
313+
RectangleXYGrid(
314+
::Type{<:AbstractFloat}; # defaults to Float64
315+
x_min::Real = FT(0),
316+
x_max::Real = FT(1),
317+
y_min::Real = FT(0),
318+
y_max::Real = FT(1),
319+
boundary_names = (:bottom, :top),
320+
x1periodic = true,
321+
x2periodic = true,
322+
x1boundary = (:east, :west),
323+
x2boundary = (:south, :north),
324+
device = ClimaComms.device(),
325+
context = ClimaComms.context(device),
326+
hypsography = Flat(),
327+
global_geometry = Geometry.CartesianGlobalGeometry(),
328+
Nq::Integer = 4,
329+
n1::Integer = 1, # number of horizontal elements
330+
n2::Integer = 1, # number of horizontal elements
331+
quad::Quadratures.QuadratureStyle = Quadratures.GLL{Nq}(),
332+
)
333+
334+
A convenience constructor, which builds a
335+
`SpectralElementGrid2D` with a horizontal
336+
`RectilinearMesh` mesh.
337+
338+
All arguments are optional.
339+
"""
340+
RectangleXYGrid(; kwargs...) = RectangleXYGrid(Float64; kwargs...)
341+
function RectangleXYGrid(
342+
::Type{FT};
343+
x_min::Real = FT(0),
344+
x_max::Real = FT(1),
345+
y_min::Real = FT(0),
346+
y_max::Real = FT(1),
347+
boundary_names = (:bottom, :top),
348+
x1periodic = true,
349+
x2periodic = true,
350+
x1boundary = (:east, :west),
351+
x2boundary = (:south, :north),
352+
device = ClimaComms.device(),
353+
context = ClimaComms.context(device),
354+
hypsography = Flat(),
355+
global_geometry = Geometry.CartesianGlobalGeometry(),
356+
Nq::Integer = 4,
357+
n1::Integer = 1,
358+
n2::Integer = 1,
359+
quad::Quadratures.QuadratureStyle = Quadratures.GLL{Nq}(),
360+
) where {FT}
361+
362+
domain = Domains.RectangleDomain(
363+
Domains.IntervalDomain(
364+
Geometry.XPoint{FT}(x_min),
365+
Geometry.XPoint{FT}(x_max);
366+
periodic = x1periodic,
367+
boundary_names = x1boundary,
368+
),
369+
Domains.IntervalDomain(
370+
Geometry.YPoint{FT}(y_min),
371+
Geometry.YPoint{FT}(y_max);
372+
periodic = x2periodic,
373+
boundary_names = x2boundary,
374+
),
375+
)
376+
h_mesh = Meshes.RectilinearMesh(domain, n1, n2)
377+
h_topology = Topologies.Topology2D(context, h_mesh)
378+
return Grids.SpectralElementGrid2D(h_topology, quad)
379+
end

0 commit comments

Comments
 (0)