Skip to content

Commit

Permalink
Merge #1336
Browse files Browse the repository at this point in the history
1336: Better printing of objects r=simonbyrne a=simonbyrne

Improves printing, of domains, meshes, topologies and spaces. 

Example
```
SpectralElementSpace2D:
  context: ClimaComms.SingletonCommsContext{ClimaComms.CPUDevice}(ClimaComms.CPUDevice())
  mesh: 4×8-element RectilinearMesh of RectangleDomain: x ∈ [-3.0,5.0] (:east, :west) × y ∈ [-2.0,8.0] (:south, :north)
  quadrature: 4-point Gauss-Legendre-Lobatto quadrature
```

- [x] Code follows the [style guidelines](https://clima.github.io/ClimateMachine.jl/latest/DevDocs/CodeStyle/) OR N/A.
- [x] Unit tests are included OR N/A.
- [x] Code is exercised in an integration test OR N/A.
- [x] Documentation has been added/updated OR N/A.


Co-authored-by: Simon Byrne <[email protected]>
  • Loading branch information
bors[bot] and simonbyrne authored Aug 10, 2023
2 parents fc34a0a + a44343c commit 277ff28
Show file tree
Hide file tree
Showing 12 changed files with 152 additions and 43 deletions.
34 changes: 23 additions & 11 deletions src/Domains/Domains.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ A domain represents a region of space.
"""
abstract type AbstractDomain end

function Base.summary(io::IO, domain::AbstractDomain)
print(io, nameof(typeof(domain)))
end

const BCTagType = Union{Nothing, Tuple{Symbol, Symbol}}

float_type(domain::AbstractDomain) = float_type(coordinate_type(domain))
Expand Down Expand Up @@ -65,18 +69,26 @@ IntervalDomain(coords::ClosedInterval; kwargs...) =
coordinate_type(::IntervalDomain{CT}) where {CT} = CT
Base.eltype(domain::IntervalDomain) = coordinate_type(domain)

function Base.show(io::IO, domain::IntervalDomain)
function print_interval(io::IO, domain::IntervalDomain{CT}) where {CT}
print(
io,
nameof(typeof(domain)),
"($(domain.coord_min), $(domain.coord_max); ",
fieldname(CT, 1),
" ∈ [",
Geometry.component(domain.coord_min, 1),
",",
Geometry.component(domain.coord_max, 1),
"] ",
)
if isperiodic(domain)
print(io, "periodic=true)")
print(io, "(periodic)")
else
print(io, "boundary_names = $(domain.boundary_names))")
print(io, domain.boundary_names)
end
end
function Base.show(io::IO, domain::IntervalDomain)
print(io, nameof(typeof(domain)), ": ")
print_interval(io, domain)
end

struct RectangleDomain{I1 <: IntervalDomain, I2 <: IntervalDomain} <:
AbstractDomain
Expand Down Expand Up @@ -119,12 +131,12 @@ end


function Base.show(io::IO, domain::RectangleDomain)
indent = get(io, :indent, 0)
println(io, nameof(typeof(domain)), "(")
println(io, " "^(indent + 2), domain.interval1)
println(io, " "^(indent + 2), domain.interval2)
print(io, " "^indent, ")")
print(io, nameof(typeof(domain)), ": ")
print_interval(io, domain.interval1)
print(io, " × ")
print_interval(io, domain.interval2)
end

coordinate_type(domain::RectangleDomain) = typeof(
Geometry.product_coordinates(
domain.interval1.coord_min,
Expand All @@ -141,7 +153,7 @@ struct SphereDomain{FT} <: AbstractDomain where {FT <: AbstractFloat}
radius::FT
end
Base.show(io::IO, domain::SphereDomain) =
print(io, nameof(typeof(domain)), "($(domain.radius))")
print(io, nameof(typeof(domain)), ": radius = ", domain.radius)

boundary_names(::SphereDomain) = ()
coordinate_type(::SphereDomain{FT}) where {FT} = Geometry.Cartesian123Point{FT}
Expand Down
21 changes: 9 additions & 12 deletions src/Meshes/cubedsphere.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,15 @@ sphere.
struct NormalizedBilinearMap <: LocalElementMap end


Base.show(io::IO, mesh::AbstractCubedSphere) = print(
io,
mesh.ne,
"×",
mesh.ne,
"×",
6,
"-element ",
nameof(typeof(mesh)),
" of ",
mesh.domain,
)
function Base.summary(io::IO, mesh::AbstractCubedSphere)
ne = mesh.ne
print(io, ne, "×", ne, "×", 6, "-element ", nameof(typeof(mesh)))
end
function Base.show(io::IO, mesh::AbstractCubedSphere)
summary(io, mesh)
print(io, " of ", mesh.domain)
end


domain(mesh::AbstractCubedSphere) = mesh.domain
elements(mesh::AbstractCubedSphere) = CartesianIndices((mesh.ne, mesh.ne, 6))
Expand Down
6 changes: 5 additions & 1 deletion src/Meshes/interval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ domain(mesh::IntervalMesh) = mesh.domain
nelements(mesh::IntervalMesh) = length(mesh.faces) - 1
elements(mesh::IntervalMesh) = Base.OneTo(nelements(mesh))

function Base.summary(io::IO, mesh::IntervalMesh)
print(io, nelements(mesh), "-element IntervalMesh")
end
function Base.show(io::IO, mesh::IntervalMesh)
print(io, nelements(mesh), "-element IntervalMesh of ")
summary(io, mesh)
print(io, " of ")
print(io, mesh.domain)
end

Expand Down
10 changes: 8 additions & 2 deletions src/Meshes/rectangle.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,17 @@ RectilinearMesh(domain::RectangleDomain, n1::Int, n2::Int) = RectilinearMesh(
IntervalMesh(domain.interval2; nelems = n2),
)

function Base.show(io::IO, mesh::RectilinearMesh)
function Base.summary(io::IO, mesh::RectilinearMesh)
n1 = nelements(mesh.intervalmesh1)
n2 = nelements(mesh.intervalmesh2)
print(io, n1, "×", n2, "-element RectilinearMesh of ", domain(mesh))
print(io, n1, "×", n2, "-element RectilinearMesh")
end
function Base.show(io::IO, mesh::RectilinearMesh)
summary(io, mesh)
print(io, " of ", domain(mesh))
end


domain(mesh::RectilinearMesh) =
RectangleDomain(domain(mesh.intervalmesh1), domain(mesh.intervalmesh2))
nelements(mesh::RectilinearMesh) =
Expand Down
20 changes: 18 additions & 2 deletions src/Spaces/extruded.jl
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,24 @@ function Base.show(io::IO, space::ExtrudedFiniteDifferenceSpace)
"FaceExtrudedFiniteDifferenceSpace",
":",
)
println(iio, " "^(indent + 2), space.horizontal_space)
print(iio, " "^(indent + 2), space.vertical_topology)
print(iio, " "^(indent + 2), "context: ")
Topologies.print_context(iio, space.horizontal_space.topology.context)
println(iio)
println(iio, " "^(indent + 2), "horizontal:")
println(
iio,
" "^(indent + 4),
"mesh: ",
space.horizontal_space.topology.mesh,
)
println(
iio,
" "^(indent + 4),
"quadrature: ",
space.horizontal_space.quadrature_style,
)
println(iio, " "^(indent + 2), "vertical:")
print(iio, " "^(indent + 4), "mesh: ", space.vertical_topology.mesh)
end
local_geometry_data(space::CenterExtrudedFiniteDifferenceSpace) =
space.center_local_geometry
Expand Down
5 changes: 4 additions & 1 deletion src/Spaces/finitedifference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ function Base.show(io::IO, space::FiniteDifferenceSpace)
"FaceFiniteDifferenceSpace",
":",
)
print(iio, " "^(indent + 2), Spaces.topology(space))
print(iio, " "^(indent + 2), "context: ")
Topologies.print_context(iio, space.topology.context)
println(iio)
print(iio, " "^(indent + 2), "mesh: ", space.topology.mesh)
end

function FiniteDifferenceSpace{S}(
Expand Down
5 changes: 5 additions & 0 deletions src/Spaces/quadrature.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ Gauss-Legendre-Lobatto quadrature using `Nq` quadrature points.
"""
struct GLL{Nq} <: QuadratureStyle end

Base.show(io::IO, ::GLL{Nq}) where {Nq} =
print(io, Nq, "-point Gauss-Legendre-Lobatto quadrature")

@inline polynomial_degree(::GLL{Nq}) where {Nq} = Int(Nq - 1)
@inline degrees_of_freedom(::GLL{Nq}) where {Nq} = Int(Nq)

Expand All @@ -62,6 +65,8 @@ end
Gauss-Legendre quadrature using `Nq` quadrature points.
"""
struct GL{Nq} <: QuadratureStyle end
Base.show(io::IO, ::GL{Nq}) where {Nq} =
print(io, Nq, "-point Gauss-Legendre quadrature")

@inline polynomial_degree(::GL{Nq}) where {Nq} = Int(Nq - 1)
@inline degrees_of_freedom(::GL{Nq}) where {Nq} = Int(Nq)
Expand Down
7 changes: 5 additions & 2 deletions src/Spaces/spectralelement.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ function Base.show(io::IO, space::AbstractSpectralElementSpace)
println(io, nameof(typeof(space)), ":")
if hasfield(typeof(space), :topology)
# some reduced spaces (like slab space) do not have topology
println(iio, " "^(indent + 2), space.topology)
print(iio, " "^(indent + 2), "context: ")
Topologies.print_context(iio, space.topology.context)
println(iio)
println(iio, " "^(indent + 2), "mesh: ", space.topology.mesh)
end
print(iio, " "^(indent + 2), space.quadrature_style)
print(iio, " "^(indent + 2), "quadrature: ", space.quadrature_style)
end

ClimaComms.device(space::AbstractSpectralElementSpace) =
Expand Down
31 changes: 31 additions & 0 deletions src/Topologies/Topologies.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,37 @@ mesh in the horizontal domain.
"""
abstract type AbstractTopology end

function Base.summary(io::IO, topology::AbstractTopology)
print(io, nameof(typeof(topology)))
end

# TODO: move this to ClimaComms
function print_device(io::IO, device::ClimaComms.AbstractDevice)
print(io, nameof(typeof(device)))
end

function print_context(io::IO, context::ClimaComms.SingletonCommsContext)
print(io, "SingletonCommsContext using ")
print_device(io, context.device)
end

function print_context(io::IO, context::ClimaComms.MPICommsContext)
if ClimaComms.MPI.Initialized()
print(
io,
"MPICommsContext with ",
ClimaComms.nprocs(context),
" processes",
)
else
print(io, "MPICommsContext (uninitialized)")
end
print(io, " using ")
print_device(io, context.device)
end


abstract type AbstractDistributedTopology <: AbstractTopology end

coordinate_type(topology::AbstractTopology) = coordinate_type(domain(topology))
Expand Down
8 changes: 6 additions & 2 deletions src/Topologies/interval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,12 @@ IntervalTopology(mesh::Meshes.IntervalMesh) = IntervalTopology(

isperiodic(topology::AbstractIntervalTopology) = isempty(topology.boundaries)

function Base.show(io::IO, topology::AbstractIntervalTopology)
print(io, "IntervalTopology on ", Topologies.mesh(topology))
function Base.show(io::IO, topology::IntervalTopology)
println(io, nameof(typeof(topology)))
print(io, " context: ")
print_context(io, topology.context)
println(io)
print(io, " mesh: ", topology.mesh)
end

function mesh(topology::AbstractIntervalTopology)
Expand Down
15 changes: 15 additions & 0 deletions src/Topologies/topology2d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,21 @@ ClimaComms.device(topology::Topology2D) = topology.context.device
ClimaComms.array_type(topology::Topology2D) =
ClimaComms.array_type(topology.context.device)

function Base.show(io::IO, topology::Topology2D)
indent = get(io, :indent, 0)
println(io, nameof(typeof(topology)))
print(io, " "^(indent + 2), "context: ")
print_context(io, topology.context)
println(io)
println(io, " "^(indent + 2), "mesh: ", topology.mesh)
print(io, " "^(indent + 2), "elemorder: ")
if topology.elemorder isa CartesianIndices
print(io, topology.elemorder)
else
summary(io, topology.elemorder)
end
end

"""
spacefillingcurve(mesh::Meshes.AbstractCubedSphere)
Expand Down
33 changes: 23 additions & 10 deletions test/Spaces/spaces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ import ClimaCore.DataLayouts: IJFH, VF

space = Spaces.SpectralElementSpace1D(topology, quad)

@test repr(space) === """
SpectralElementSpace1D:
context: SingletonCommsContext using CPUSingleThreaded
mesh: 1-element IntervalMesh of IntervalDomain: x ∈ [-3.0,5.0] (periodic)
quadrature: 4-point Gauss-Legendre-Lobatto quadrature"""

coord_data = Spaces.coordinates_data(space)
@test eltype(coord_data) == Geometry.XPoint{Float64}

Expand Down Expand Up @@ -99,17 +105,19 @@ end
boundary_names = (:bottom, :top),
)
mesh = Meshes.IntervalMesh(domain; nelems = 1)
topology = Topologies.IntervalTopology(mesh)
topology = Topologies.IntervalTopology(context, mesh)

for Space in
[Spaces.CenterFiniteDifferenceSpace, Spaces.FaceFiniteDifferenceSpace]
space = Spaces.CenterFiniteDifferenceSpace(topology)
coord_data = Spaces.coordinates_data(space)
point_space = Spaces.level(space, 1)
@test point_space isa Spaces.PointSpace
@test Spaces.coordinates_data(point_space)[] ==
Spaces.level(coord_data, 1)[]
end
space = Spaces.CenterFiniteDifferenceSpace(topology)
@test repr(space) == """
CenterFiniteDifferenceSpace:
context: SingletonCommsContext using CPUSingleThreaded
mesh: 1-element IntervalMesh of IntervalDomain: z ∈ [0.0,5.0] (:bottom, :top)"""

coord_data = Spaces.coordinates_data(space)
point_space = Spaces.level(space, 1)
@test point_space isa Spaces.PointSpace
@test Spaces.coordinates_data(point_space)[] ==
Spaces.level(coord_data, 1)[]

x_max = FT(0)
y_max = FT(1)
Expand Down Expand Up @@ -155,6 +163,11 @@ end
points, weights = Spaces.Quadratures.quadrature_points(FT, quad)

space = Spaces.SpectralElementSpace2D(grid_topology, quad)
@test repr(space) == """
SpectralElementSpace2D:
context: SingletonCommsContext using CPUSingleThreaded
mesh: 1×1-element RectilinearMesh of RectangleDomain: x ∈ [-3.0,5.0] (periodic) × y ∈ [-2.0,8.0] (:south, :north)
quadrature: 4-point Gauss-Legendre-Lobatto quadrature"""

coord_data = Spaces.coordinates_data(space)
array = parent(coord_data)
Expand Down

0 comments on commit 277ff28

Please sign in to comment.