Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/APIs/common_grids_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ CommonGrids.ColumnGrid
CommonGrids.Box3DGrid
CommonGrids.SliceXZGrid
CommonGrids.RectangleXYGrid
CommonGrids.PointColumnEnsembleGrid
```
1 change: 1 addition & 0 deletions docs/src/APIs/common_spaces_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ CommonSpaces.ColumnSpace
CommonSpaces.Box3DSpace
CommonSpaces.SliceXZSpace
CommonSpaces.RectangleXYSpace
CommonSpaces.PointColumnEnsembleSpace
```
8 changes: 8 additions & 0 deletions ext/cuda/adapt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Adapt.adapt_structure(
grid::Grids.ExtrudedFiniteDifferenceGrid,
) = Grids.DeviceExtrudedFiniteDifferenceGrid(
Adapt.adapt(to, Grids.vertical_topology(grid)),
grid.horizontal_grid isa Grids.PointCloudGrid ? nothing :
Adapt.adapt(to, grid.horizontal_grid.quadrature_style),
Adapt.adapt(to, grid.global_geometry),
Adapt.adapt(to, grid.center_local_geometry),
Expand Down Expand Up @@ -39,6 +40,13 @@ Adapt.adapt_structure(to::CUDA.KernelAdaptor, space::Spaces.PointSpace) =
Adapt.adapt(to, Spaces.local_geometry_data(space)),
)

Adapt.adapt_structure(to::CUDA.KernelAdaptor, space::Spaces.PointCloudSpace) =
Spaces.PointCloudSpace(
ClimaCore.DeviceSideContext(),
Adapt.adapt(to, space.full_grid),
Adapt.adapt(to, Spaces.local_geometry_data(space)),
)

Adapt.adapt_structure(
to::CUDA.KernelAdaptor,
topology::Topologies.IntervalTopology,
Expand Down
75 changes: 74 additions & 1 deletion src/CommonGrids/CommonGrids.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,12 @@ grid = ExtrudedCubedSphereGrid(;
module CommonGrids

export ExtrudedCubedSphereGrid,
CubedSphereGrid, ColumnGrid, Box3DGrid, SliceXZGrid, RectangleXYGrid
CubedSphereGrid,
ColumnGrid,
Box3DGrid,
SliceXZGrid,
RectangleXYGrid,
PointColumnEnsembleGrid

import ClimaComms
import ..DataLayouts,
Expand Down Expand Up @@ -706,4 +711,72 @@ function RectangleXYGrid(
)
end

"""
PointColumnEnsembleGrid(
::Type{<:AbstractFloat}; # defaults to Float64
points::AbstractVector{Geometry.LatLongPoint{FT}},
z_elem::Integer,
z_min::Real,
z_max::Real,
radius::Real,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
stretch::Meshes.StretchingRule = Meshes.Uniform(),
z_mesh::Meshes.IntervalMesh = DefaultZMesh(FT; z_min, z_max, z_elem, stretch),
)

A convenience constructor that builds an
[`Grids.ExtrudedFiniteDifferenceGrid`](@ref) for N independent columns at
arbitrary (lat, lon) locations on a sphere, given:

- `FT` the floating-point type (defaults to `Float64`) [`Float32`, `Float64`],
- `points` a vector of `Geometry.LatLongPoint` specifying each column
location,
- `z_elem` the number of z-points,
- `z_min` the domain minimum along the z-direction,
- `z_max` the domain maximum along the z-direction,
- `radius` the radius of the sphere,
- `device` the `ClimaComms.device`,
- `stretch` the mesh `Meshes.StretchingRule` (defaults to
[`Meshes.Uniform`](@ref)),
- `z_mesh` the vertical mesh, defaults to an `Meshes.IntervalMesh` along `z`
with given `stretch`.

There is no horizontal connectivity between columns. Horizontal operators are
not supported. Use [`ClimaCore.Fields.bycolumn`](@ref) to iterate over columns.

# Example usage

```julia
using ClimaCore.CommonGrids, ClimaCore.Geometry
points = [LatLongPoint(0.0, 0.0), LatLongPoint(10.0, 20.0), LatLongPoint(-5.0, 90.0)]
grid = PointColumnEnsembleGrid(;
points = points,
z_elem = 10,
z_min = 0,
z_max = 10_000,
radius = 6.371229e6,
)
```
"""
PointColumnEnsembleGrid(; kwargs...) = PointColumnEnsembleGrid(Float64; kwargs...)
function PointColumnEnsembleGrid(
::Type{FT};
points::AbstractVector{Geometry.LatLongPoint{FT}},
z_elem::Integer,
z_min::Real,
z_max::Real,
radius::Real = 6.371229e6,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
stretch::Meshes.StretchingRule = Meshes.Uniform(),
z_mesh::Meshes.IntervalMesh = DefaultZMesh(FT; z_min, z_max, z_elem, stretch),
) where {FT}
h_grid = Grids.PointCloudGrid(points; radius, device)
z_topology = Topologies.IntervalTopology(
ClimaComms.SingletonCommsContext(device),
z_mesh,
)
z_grid = Grids.FiniteDifferenceGrid(z_topology)
return Grids.ExtrudedFiniteDifferenceGrid(h_grid, z_grid)
end

end # module
56 changes: 55 additions & 1 deletion src/CommonSpaces/CommonSpaces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export ExtrudedCubedSphereSpace,
Box3DSpace,
SliceXZSpace,
RectangleXYSpace,
PointColumnEnsembleSpace,
CellCenter,
CellFace,
face_space,
Expand All @@ -32,7 +33,8 @@ import ..CommonGrids:
ColumnGrid,
Box3DGrid,
SliceXZGrid,
RectangleXYGrid
RectangleXYGrid,
PointColumnEnsembleGrid
import ..Spaces: face_space, center_space


Expand Down Expand Up @@ -426,4 +428,56 @@ RectangleXYSpace(; kwargs...) = RectangleXYSpace(Float64; kwargs...)
RectangleXYSpace(::Type{FT}; kwargs...) where {FT} =
Spaces.SpectralElementSpace2D(RectangleXYGrid(FT; kwargs...))

"""
PointColumnEnsembleSpace(
::Type{<:AbstractFloat}; # defaults to Float64
points::AbstractVector{Geometry.LatLongPoint{FT}},
z_elem::Integer,
z_min::Real,
z_max::Real,
device::ClimaComms.AbstractDevice = ClimaComms.device(),
stretch::Meshes.StretchingRule = Meshes.Uniform(),
z_mesh::Meshes.IntervalMesh = DefaultZMesh(FT; z_min, z_max, z_elem, stretch),
staggering::Staggering,
)

Construct a [`Spaces.ExtrudedFiniteDifferenceSpace`](@ref) (aliased as
`Spaces.MultiColumnFiniteDifferenceSpace`) for N independent columns at arbitrary (lat, lon)
locations on a sphere, given:

- `FT` the floating-point type (defaults to `Float64`) [`Float32`, `Float64`]
- `points` a vector of `Geometry.LatLongPoint` specifying each column location
- `z_elem` the number of z-points
- `z_min` the domain minimum along the z-direction
- `z_max` the domain maximum along the z-direction
- `device` the `ClimaComms.device`
- `stretch` the mesh `Meshes.StretchingRule` (defaults to [`Meshes.Uniform`](@ref))
- `z_mesh` the vertical mesh, defaults to an `Meshes.IntervalMesh` along `z` with given `stretch`
- `staggering` vertical staggering, can be one of [[`Grids.CellFace`](@ref), [`Grids.CellCenter`](@ref)]

Note that these arguments are all the same as [`CommonGrids.PointColumnEnsembleGrid`](@ref),
except for `staggering`.

# Example usage

```julia
using ClimaCore.CommonSpaces, ClimaCore.Geometry
points = [LatLongPoint(0.0, 0.0), LatLongPoint(10.0, 20.0), LatLongPoint(-5.0, 90.0)]
space = PointColumnEnsembleSpace(;
points = points,
z_elem = 10,
z_min = 0,
z_max = 10_000,
staggering = CellCenter()
)
```
"""
function PointColumnEnsembleSpace end
PointColumnEnsembleSpace(; kwargs...) = PointColumnEnsembleSpace(Float64; kwargs...)
PointColumnEnsembleSpace(::Type{FT}; staggering::Staggering, kwargs...) where {FT} =
Spaces.MultiColumnFiniteDifferenceSpace(
PointColumnEnsembleGrid(FT; kwargs...),
staggering,
)

end # module
23 changes: 22 additions & 1 deletion src/Fields/Fields.jl
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,22 @@ const CenterExtrudedFiniteDifferenceField{V, S} = Field{
S,
} where {V <: AbstractData, S <: Spaces.CenterExtrudedFiniteDifferenceSpace}

const MultiColumnFiniteDifferenceField{V, S} = Field{
V,
S,
} where {V <: AbstractData, S <: Spaces.MultiColumnFiniteDifferenceSpace}
const FaceMultiColumnFiniteDifferenceField{V, S} = Field{
V,
S,
} where {V <: AbstractData, S <: Spaces.FaceMultiColumnFiniteDifferenceSpace}
const CenterMultiColumnFiniteDifferenceField{V, S} = Field{
V,
S,
} where {
V <: AbstractData,
S <: Spaces.CenterMultiColumnFiniteDifferenceSpace,
}

#
const SpectralElementField1D{V, S} =
Field{V, S} where {V <: AbstractData, S <: Spaces.SpectralElementSpace1D}
Expand Down Expand Up @@ -497,6 +513,7 @@ Base.@propagate_inbounds function level(
field::Union{
CenterFiniteDifferenceField,
CenterExtrudedFiniteDifferenceField,
CenterMultiColumnFiniteDifferenceField,
},
v::Int,
)
Expand All @@ -505,7 +522,11 @@ Base.@propagate_inbounds function level(
Field(data, hspace)
end
Base.@propagate_inbounds function level(
field::Union{FaceFiniteDifferenceField, FaceExtrudedFiniteDifferenceField},
field::Union{
FaceFiniteDifferenceField,
FaceExtrudedFiniteDifferenceField,
FaceMultiColumnFiniteDifferenceField,
},
v::PlusHalf,
)
hspace = level(axes(field), v)
Expand Down
22 changes: 22 additions & 0 deletions src/Fields/indices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,28 @@ bycolumn(
device::ClimaComms.AbstractCPUDevice,
) = bycolumn(fn, Spaces.horizontal_space(space), device)

function bycolumn(
fn,
space::Spaces.MultiColumnFiniteDifferenceSpace,
::ClimaComms.CPUSingleThreaded,
)
N = Spaces.ncolumns(space)
@inbounds for h in 1:N
fn(ColumnIndex((1,), h))
end
return nothing
end
function bycolumn(
fn,
space::Spaces.MultiColumnFiniteDifferenceSpace,
::ClimaComms.CPUMultiThreaded,
)
N = Spaces.ncolumns(space)
@inbounds Threads.@threads for h in 1:N
fn(ColumnIndex((1,), h))
end
return nothing
end


"""
Expand Down
3 changes: 3 additions & 0 deletions src/Grids/Grids.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Meshes.domain(grid::AbstractGrid) = Meshes.domain(topology(grid))

include("finitedifference.jl")
include("spectralelement.jl")
include("pointcloud.jl")
include("extruded.jl")
include("column.jl")
include("level.jl")
Expand Down Expand Up @@ -106,6 +107,7 @@ has_horizontal(::ExtrudedFiniteDifferenceGrid) = true
has_horizontal(::DeviceSpectralElementGrid2D) = true
has_horizontal(::SpectralElementGrid2D) = true
has_horizontal(::SpectralElementGrid1D) = true
has_horizontal(::PointCloudGrid) = true

"""
has_vertical(::AbstractGrid)
Expand All @@ -124,6 +126,7 @@ Retrieve the mask for the grid (defaults to DataLayouts.NoMask).
"""
get_mask(::AbstractGrid) = DataLayouts.NoMask()
get_mask(grid::ExtrudedFiniteDifferenceGrid) = grid.horizontal_grid.mask
get_mask(::ExtrudedFiniteDifferenceGrid{<:PointCloudGrid}) = DataLayouts.NoMask()

"""
set_mask!(fn::Function, grid)
Expand Down
11 changes: 8 additions & 3 deletions src/Grids/extruded.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ local_geometry_type(
) where {H, V, A, GG, CLG, FLG} = eltype(CLG) # calls eltype from DataLayouts

function ExtrudedFiniteDifferenceGrid(
horizontal_grid::Union{SpectralElementGrid1D, SpectralElementGrid2D},
horizontal_grid::AbstractSpectralElementGrid,
vertical_grid::FiniteDifferenceGrid,
hypsography::HypsographyAdaption = Flat();
deep = false,
Expand All @@ -70,7 +70,7 @@ end

# memoized constructor
function ExtrudedFiniteDifferenceGrid(
horizontal_grid::Union{SpectralElementGrid1D, SpectralElementGrid2D},
horizontal_grid::AbstractSpectralElementGrid,
vertical_grid::FiniteDifferenceGrid,
hypsography::HypsographyAdaption,
global_geometry::Geometry.AbstractGlobalGeometry,
Expand All @@ -96,7 +96,7 @@ end

# Non-memoized constructor. Should not generally be called, but can be defined for other Hypsography types
function _ExtrudedFiniteDifferenceGrid(
horizontal_grid::Union{SpectralElementGrid1D, SpectralElementGrid2D},
horizontal_grid::AbstractSpectralElementGrid,
vertical_grid::FiniteDifferenceGrid,
hypsography::Flat,
global_geometry::Geometry.AbstractGlobalGeometry,
Expand Down Expand Up @@ -126,6 +126,11 @@ end

topology(grid::ExtrudedFiniteDifferenceGrid) = topology(grid.horizontal_grid)

ClimaComms.context(grid::ExtrudedFiniteDifferenceGrid) =
ClimaComms.context(grid.horizontal_grid)
ClimaComms.device(grid::ExtrudedFiniteDifferenceGrid) =
ClimaComms.device(grid.horizontal_grid)

vertical_topology(grid::ExtrudedFiniteDifferenceGrid) =
topology(grid.vertical_grid)

Expand Down
3 changes: 3 additions & 0 deletions src/Grids/level.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ level(

topology(levelgrid::LevelGrid) = topology(levelgrid.full_grid)

ClimaComms.context(levelgrid::LevelGrid) = ClimaComms.context(levelgrid.full_grid)
ClimaComms.device(levelgrid::LevelGrid) = ClimaComms.device(levelgrid.full_grid)

# The DSS weights for extruded spaces are currently the same as the weights for
# horizontal spaces. If we ever need to use extruded weights, this method will
# need to extract the weights at a particular level.
Expand Down
Loading
Loading