Skip to content

Commit e86d6d0

Browse files
Add convenience constructors for grids
1 parent 3e95814 commit e86d6d0

File tree

4 files changed

+465
-0
lines changed

4 files changed

+465
-0
lines changed

src/Grids/Grids.jl

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ include("spectralelement.jl")
7676
include("extruded.jl")
7777
include("column.jl")
7878
include("level.jl")
79+
include("convenience_constructors.jl")
7980

8081

8182

src/Grids/convenience_constructors.jl

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

0 commit comments

Comments
 (0)