Skip to content

Commit 616e197

Browse files
Add convenience constructors for grids
1 parent a802b34 commit 616e197

File tree

4 files changed

+450
-0
lines changed

4 files changed

+450
-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

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

0 commit comments

Comments
 (0)