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 26, 2024
1 parent bf41449 commit 4b819b9
Show file tree
Hide file tree
Showing 4 changed files with 444 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
366 changes: 366 additions & 0 deletions src/Grids/convenience_constructors.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,366 @@
#=
While we recommend users to use our compose-able
methods, this file contains some convenience
constructors, which are meant to improve
developer experience.
=#
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,
Nq::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{Nq}(),
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,
Nq::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{Nq}(),
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,
Nq::Integer,
h_elem::Integer,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
context::ClimaComms.AbstractCommsContext = ClimaComms.context(device),
quad::Quadratures.QuadratureStyle = Quadratures.GLL{Nq}(),
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,
Nq::Integer,
h_elem::Integer,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
context::ClimaComms.AbstractCommsContext = ClimaComms.context(device),
quad::Quadratures.QuadratureStyle = Quadratures.GLL{Nq}(),
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,
Nq::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{Nq}(),
)
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,
Nq::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{Nq}(),
) 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,
Nq::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{Nq}(),
)
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,
Nq::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{Nq}(),
) 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,
Nq::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{Nq}(),
)
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,
Nq::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{Nq}(),
) 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 4b819b9

Please sign in to comment.