Skip to content

Commit

Permalink
Add convenience constructors for grids
Browse files Browse the repository at this point in the history
  • Loading branch information
charleskawczynski committed Oct 29, 2024
1 parent a802b34 commit 1a96990
Show file tree
Hide file tree
Showing 4 changed files with 450 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/Grids/Grids.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ include("spectralelement.jl")
include("extruded.jl")
include("column.jl")
include("level.jl")
include("convenience_constructors.jl")



Expand Down
372 changes: 372 additions & 0 deletions src/Grids/convenience_constructors.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,372 @@
#=
These convenience constructors accept integer
keyword inputs, so they are dynamically created. You may
want to use a different constructor if you're making the
object in a performance-critical section, and if you know
the type parameters at compile time.
If no convenience constructor exists to make the
grid you need, then you may need to use our lower
level compose-able API.
=#
check_device_context(context, device) =
@assert ClimaComms.device(context) == device "The given device and context device do not match."

"""
ExtrudedCubedSphereGrid(
::Type{<:AbstractFloat}; # defaults to Float64
z_elem::Integer,
z_min::Real,
z_max::Real,
radius::Real,
h_elem::Integer,
n_quad_points::Integer,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
context::ClimaComms.AbstractCommsContext = ClimaComms.context(device),
stretch::Meshes.StretchingRule = Meshes.Uniform(),
hypsography::HypsographyAdaption = Flat(),
global_geometry::Geometry.AbstractGlobalGeometry = Geometry.ShallowSphericalGlobalGeometry(radius),
quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
h_mesh = Meshes.EquiangularCubedSphere(Domains.SphereDomain(radius), h_elem),
)
A convenience constructor, which builds a
`ExtrudedFiniteDifferenceGrid`.
"""
ExtrudedCubedSphereGrid(; kwargs...) =
ExtrudedCubedSphereGrid(Float64; kwargs...)

function ExtrudedCubedSphereGrid(
::Type{FT};
z_elem::Integer,
z_min::Real,
z_max::Real,
radius::Real,
h_elem::Integer,
n_quad_points::Integer,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
context::ClimaComms.AbstractCommsContext = ClimaComms.context(device),
stretch::Meshes.StretchingRule = Meshes.Uniform(),
hypsography::HypsographyAdaption = Flat(),
global_geometry::Geometry.AbstractGlobalGeometry = Geometry.ShallowSphericalGlobalGeometry(
radius,
),
quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
h_mesh = Meshes.EquiangularCubedSphere(
Domains.SphereDomain{FT}(radius),
h_elem,
),
) where {FT}
check_device_context(context, device)

z_boundary_names = (:bottom, :top)
h_topology = Topologies.Topology2D(context, h_mesh)
h_grid = Grids.SpectralElementGrid2D(h_topology, quad)
z_domain = Domains.IntervalDomain(
Geometry.ZPoint{FT}(z_min),
Geometry.ZPoint{FT}(z_max);
boundary_names = z_boundary_names,
)
z_mesh = Meshes.IntervalMesh(z_domain, stretch; nelems = z_elem)
z_topology = Topologies.IntervalTopology(context, z_mesh)
vertical_grid = FiniteDifferenceGrid(z_topology)
return ExtrudedFiniteDifferenceGrid(
h_grid,
vertical_grid,
hypsography,
global_geometry,
)
end

"""
CubedSphereGrid(
::Type{<:AbstractFloat}; # defaults to Float64
radius::Real,
n_quad_points::Integer,
h_elem::Integer,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
context::ClimaComms.AbstractCommsContext = ClimaComms.context(device),
quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
h_mesh = Meshes.EquiangularCubedSphere(Domains.SphereDomain(radius), h_elem),
)
A convenience constructor, which builds a
`SpectralElementGrid2D`.
"""
CubedSphereGrid(; kwargs...) = CubedSphereGrid(Float64; kwargs...)
function CubedSphereGrid(
::Type{FT};
radius::Real,
n_quad_points::Integer,
h_elem::Integer,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
context::ClimaComms.AbstractCommsContext = ClimaComms.context(device),
quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
h_mesh = Meshes.EquiangularCubedSphere(
Domains.SphereDomain{FT}(radius),
h_elem,
),
) where {FT}
check_device_context(context, device)
h_topology = Topologies.Topology2D(context, h_mesh)
return Grids.SpectralElementGrid2D(h_topology, quad)
end

"""
ColumnGrid(
::Type{<:AbstractFloat}; # defaults to Float64
z_elem::Integer,
z_min::Real,
z_max::Real,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
context::ClimaComms.AbstractCommsContext = ClimaComms.context(device),
stretch::Meshes.StretchingRule = Meshes.Uniform(),
)
A convenience constructor, which builds a
`FiniteDifferenceGrid` given.
"""
ColumnGrid(; kwargs...) = ColumnGrid(Float64; kwargs...)
function ColumnGrid(
::Type{FT};
z_elem::Integer,
z_min::Real,
z_max::Real,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
context::ClimaComms.AbstractCommsContext = ClimaComms.context(device),
stretch::Meshes.StretchingRule = Meshes.Uniform(),
) where {FT}
check_device_context(context, device)
z_boundary_names = (:bottom, :top)
z_domain = Domains.IntervalDomain(
Geometry.ZPoint{FT}(z_min),
Geometry.ZPoint{FT}(z_max);
boundary_names = z_boundary_names,
)
z_mesh = Meshes.IntervalMesh(z_domain, stretch; nelems = z_elem)
z_topology = Topologies.IntervalTopology(context, z_mesh)
return FiniteDifferenceGrid(z_topology)
end

"""
Box3DGrid(
::Type{<:AbstractFloat}; # defaults to Float64
z_elem::Integer,
x_min::Real,
x_max::Real,
y_min::Real,
y_max::Real,
z_min::Real,
z_max::Real,
periodic_x::Bool,
periodic_y::Bool,
n_quad_points::Integer,
x_elem::Integer,
y_elem::Integer,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
context::ClimaComms.AbstractCommsContext = ClimaComms.context(device),
stretch::Meshes.StretchingRule = Meshes.Uniform(),
hypsography::HypsographyAdaption = Flat(),
global_geometry::Geometry.AbstractGlobalGeometry = Geometry.CartesianGlobalGeometry(),
quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
)
A convenience constructor, which builds a
`ExtrudedFiniteDifferenceGrid` with a
`FiniteDifferenceGrid` vertical grid and a
`SpectralElementGrid2D` horizontal grid.
"""
Box3DGrid(; kwargs...) = Box3DGrid(Float64; kwargs...)
function Box3DGrid(
::Type{FT};
z_elem::Integer,
x_min::Real,
x_max::Real,
y_min::Real,
y_max::Real,
z_min::Real,
z_max::Real,
periodic_x::Bool,
periodic_y::Bool,
n_quad_points::Integer,
x_elem::Integer,
y_elem::Integer,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
context::ClimaComms.AbstractCommsContext = ClimaComms.context(device),
stretch::Meshes.StretchingRule = Meshes.Uniform(),
hypsography::HypsographyAdaption = Flat(),
global_geometry::Geometry.AbstractGlobalGeometry = Geometry.CartesianGlobalGeometry(),
quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
) where {FT}
check_device_context(context, device)
x1boundary = (:east, :west)
x2boundary = (:south, :north)
z_boundary_names = (:bottom, :top)
domain = Domains.RectangleDomain(
Domains.IntervalDomain(
Geometry.XPoint{FT}(x_min),
Geometry.XPoint{FT}(x_max);
periodic = periodic_x,
boundary_names = x1boundary,
),
Domains.IntervalDomain(
Geometry.YPoint{FT}(y_min),
Geometry.YPoint{FT}(y_max);
periodic = periodic_y,
boundary_names = x2boundary,
),
)
h_mesh = Meshes.RectilinearMesh(domain, x_elem, y_elem)
h_topology = Topologies.Topology2D(context, h_mesh)
h_grid = Grids.SpectralElementGrid2D(h_topology, quad)
z_domain = Domains.IntervalDomain(
Geometry.ZPoint{FT}(z_min),
Geometry.ZPoint{FT}(z_max);
boundary_names = z_boundary_names,
)
z_mesh = Meshes.IntervalMesh(z_domain, stretch; nelems = z_elem)
z_topology = Topologies.IntervalTopology(context, z_mesh)
vertical_grid = FiniteDifferenceGrid(z_topology)
return ExtrudedFiniteDifferenceGrid(
h_grid,
vertical_grid,
hypsography,
global_geometry,
)
end

"""
SliceXZGrid(
::Type{<:AbstractFloat}; # defaults to Float64
z_elem::Integer,
x_min::Real,
x_max::Real,
z_min::Real,
z_max::Real,
periodic_x::Bool,
n_quad_points::Integer,
x_elem::Integer,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
context::ClimaComms.AbstractCommsContext = ClimaComms.context(device),
stretch::Meshes.StretchingRule = Meshes.Uniform(),
hypsography::HypsographyAdaption = Flat(),
global_geometry::Geometry.AbstractGlobalGeometry = Geometry.CartesianGlobalGeometry(),
quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
)
A convenience constructor, which builds a
`ExtrudedFiniteDifferenceGrid` with a
`FiniteDifferenceGrid` vertical grid and a
`SpectralElementGrid1D` horizontal grid.
- ``
"""
SliceXZGrid(; kwargs...) = SliceXZGrid(Float64; kwargs...)
function SliceXZGrid(
::Type{FT};
z_elem::Integer,
x_min::Real,
x_max::Real,
z_min::Real,
z_max::Real,
periodic_x::Bool,
n_quad_points::Integer,
x_elem::Integer,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
context::ClimaComms.AbstractCommsContext = ClimaComms.context(device),
stretch::Meshes.StretchingRule = Meshes.Uniform(),
hypsography::HypsographyAdaption = Flat(),
global_geometry::Geometry.AbstractGlobalGeometry = Geometry.CartesianGlobalGeometry(),
quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
) where {FT}
check_device_context(context, device)

x1boundary = (:east, :west)
z_boundary_names = (:bottom, :top)
h_domain = Domains.IntervalDomain(
Geometry.XPoint{FT}(x_min),
Geometry.XPoint{FT}(x_max);
periodic = periodic_x,
boundary_names = x1boundary,
)
h_mesh = Meshes.IntervalMesh(h_domain; nelems = x_elem)
h_topology = Topologies.IntervalTopology(context, h_mesh)
h_grid = Grids.SpectralElementGrid1D(h_topology, quad)
z_domain = Domains.IntervalDomain(
Geometry.ZPoint{FT}(z_min),
Geometry.ZPoint{FT}(z_max);
boundary_names = z_boundary_names,
)
z_mesh = Meshes.IntervalMesh(z_domain, stretch; nelems = z_elem)
z_topology = Topologies.IntervalTopology(context, z_mesh)
vertical_grid = FiniteDifferenceGrid(z_topology)
return ExtrudedFiniteDifferenceGrid(
h_grid,
vertical_grid,
hypsography,
global_geometry,
)
end

"""
RectangleXYGrid(
::Type{<:AbstractFloat}; # defaults to Float64
x_min::Real,
x_max::Real,
y_min::Real,
y_max::Real,
periodic_x::Bool,
periodic_y::Bool,
n_quad_points::Integer,
x_elem::Integer, # number of horizontal elements
y_elem::Integer, # number of horizontal elements
device::ClimaComms.AbstractDevice = ClimaComms.device(),
context::ClimaComms.AbstractCommsContext = ClimaComms.context(device),
hypsography::HypsographyAdaption = Flat(),
global_geometry::Geometry.AbstractGlobalGeometry = Geometry.CartesianGlobalGeometry(),
quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
)
A convenience constructor, which builds a
`SpectralElementGrid2D` with a horizontal
`RectilinearMesh` mesh.
"""
RectangleXYGrid(; kwargs...) = RectangleXYGrid(Float64; kwargs...)
function RectangleXYGrid(
::Type{FT};
x_min::Real,
x_max::Real,
y_min::Real,
y_max::Real,
periodic_x::Bool,
periodic_y::Bool,
n_quad_points::Integer,
x_elem::Integer, # number of horizontal elements
y_elem::Integer, # number of horizontal elements
device::ClimaComms.AbstractDevice = ClimaComms.device(),
context::ClimaComms.AbstractCommsContext = ClimaComms.context(device),
hypsography::HypsographyAdaption = Flat(),
global_geometry::Geometry.AbstractGlobalGeometry = Geometry.CartesianGlobalGeometry(),
quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
) where {FT}
check_device_context(context, device)

x1boundary = (:east, :west)
x2boundary = (:south, :north)
domain = Domains.RectangleDomain(
Domains.IntervalDomain(
Geometry.XPoint{FT}(x_min),
Geometry.XPoint{FT}(x_max);
periodic = periodic_x,
boundary_names = x1boundary,
),
Domains.IntervalDomain(
Geometry.YPoint{FT}(y_min),
Geometry.YPoint{FT}(y_max);
periodic = periodic_y,
boundary_names = x2boundary,
),
)
h_mesh = Meshes.RectilinearMesh(domain, x_elem, y_elem)
h_topology = Topologies.Topology2D(context, h_mesh)
return Grids.SpectralElementGrid2D(h_topology, quad)
end
Loading

0 comments on commit 1a96990

Please sign in to comment.