API

Utilities

ClimaCore.Utilities.PlusHalfType
PlusHalf(i)

Represents i + 1/2, but stored as internally as an integer value. Used for indexing into staggered finite difference meshes: the convention "half" values are indexed at cell faces, whereas centers are indexed at cell centers.

Supports +, - and inequalities.

See also half.

source
ClimaCore.Utilities.UnrolledFunctionsModule
UnrolledFunctions

A collection of generated functions that get unrolled during compilation, which make it possible to iterate over nonuniform collections without sacrificing type-stability.

The functions exported by this module are

  • unrolled_map(f, values, [values2]): alternative to map
  • unrolled_any(f, values): alternative to any
  • unrolled_all(f, values): alternative to all
  • unrolled_filter(f, values): alternative to filter
  • unrolled_foreach(f, values): alternative to foreach
  • unrolled_in(value, values): alternative to in
  • unrolled_unique(values): alternative to unique
  • unrolled_flatten(values): alternative to Iterators.flatten
  • unrolled_flatmap(f, values): alternative to Iterators.flatmap
  • unrolled_product(values1, values2): alternative to Iterators.product
  • unrolled_findonly(f, values): checks that only one value satisfies f, and then returns that value
  • unrolled_split(f, values): returns a tuple that contains the result of calling unrolled_filter with f and the result of calling it with !f
  • unrolled_take(values, ::Val{N}): alternative to Iterators.take, but with an Int wrapped in a Val as the second argument instead of a regular Int; this usually compiles more quickly than values[1:N]
  • unrolled_drop(values, ::Val{N}): alternative to Iterators.drop, but with an Int wrapped in a Val as the second argument instead of a regular Int; this usually compiles more quickly than values[(end - N + 1):end]
source

Utilities.Cache

ClimaCore.Utilities.CacheModule

Utilities.Cache

ClimaCore maintains an internal cache of topology and grid objects: this ensures that if the constructor with the same arguments is invoked again (e.g. by reading from a file), the cached object will be returned (also known as memoization). This has two main advantages:

  1. topology and metric information can be reused, reducing memory usage.

  2. it is easy to check if two fields live on the same grid: we can just check if the underlying grid objects are the same (===), rather than checking all the fields are equal (via ==).

However this means that objects in the cache will not be removed from the garbage collector, so we provide an interface to remove these.

source
ClimaCore.Utilities.Cache.clean_cache!Function
Utilities.Cache.clean_cache!(object)

Remove object from the cache of created objects.

In most cases, this function should not need to be called, unless you are constructing many grid objects, for example when doing a sweep over grid paramaters.

source
Utilities.Cache.clean_cache!()

Remove all objects from the cache of created objects.

In most cases, this function should not need to be called, unless you are constructing many grid objects, for example when doing a sweep over grid paramaters.

source

DataLayouts

ClimaCore.DataLayoutsModule
ClimaCore.DataLayouts

Defines the following DataLayouts (see individual docs for more info):

TODO: Add links to these datalayouts

  • IJKFVH
  • IJFH
  • IJHF
  • IFH
  • IHF
  • DataF
  • IJF
  • IF
  • VF
  • VIJFH
  • VIJHF
  • VIFH
  • VIHF
  • IH1JH2
  • IV1JH2

Notation:

  • i,j are horizontal node indices within an element
  • k is the vertical node index within an element
  • f is the field index (1 if field is scalar, >1 if it is a vector field)
  • v is the vertical element index in a stack
  • h is the element stack index

Data layout is specified by the order in which they appear, e.g. IJKFVH indexes the underlying array as [i,j,k,f,v,h]

Datalayouts that end with the field index

One of the fundamental features of datalayouts is to be able to store multiple variables in the same array, and then access those variables by name. As such, we occasionally must index into multiple variables when performing operations with a datalayout.

We can efficiently support linear indexing with datalayouts whose field index (f) is first or last. This is for the same reason as https://docs.julialang.org/en/v1/devdocs/subarrays/#Linear-indexing:

Linear indexing can be implemented efficiently when the entire array
has a single stride that separates successive elements, starting from
some offset.

Therefore, we provide special handling for these datalayouts where possible to leverage efficient linear indexing.

Here are some references containing relevant discussions and efforts to leverage efficient linear indexing:

  • https://github.com/CliMA/ClimaCore.jl/issues/1889
  • https://github.com/JuliaLang/julia/issues/28126
  • https://github.com/JuliaLang/julia/issues/32051
  • https://github.com/maleadt/StaticCartesian.jl
  • https://github.com/JuliaGPU/GPUArrays.jl/pull/454#issuecomment-1431575721
  • https://github.com/JuliaGPU/GPUArrays.jl/pull/520
  • https://github.com/JuliaGPU/GPUArrays.jl/pull/464
source
ClimaCore.DataLayouts.DataFType
DataF{S, A} <: Data0D{S}

Backing DataLayout for 0D point data.

DataF{S}(ArrayType[, ones | zeros | rand])

The ArrayType constructor returns a DataF given the ArrayType and (optionally) an initialization method (one of Base.ones, Base.zeros, Random.rand).

source
ClimaCore.DataLayouts.IFType
IF{S, Ni, A} <: DataSlab1D{S, Ni}

Backing DataLayout for 1D spectral element slab data.

Nodal element data (I) are contiguous for each S datatype struct field (F) for a single element slab.

A DataSlab1D view can be returned from other Data1D objects by calling slab(data, idx...).

IF{S}(ArrayType[, ones | zeros | rand]; Ni)

The keyword constructor returns a IF given the ArrayType and (optionally) an initialization method (one of Base.ones, Base.zeros, Random.rand) and the keywords:

  • Ni quadrature degrees of freedom in the horizontal direction
Note

Objects made with the keyword constructor 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.

source
ClimaCore.DataLayouts.IJFType
IJF{S, Nij, A} <: DataSlab2D{S, Nij}

Backing DataLayout for 2D spectral element slab data.

Nodal element data (I,J) are contiguous for each S datatype struct field (F) for a single element slab.

A DataSlab2D view can be returned from other Data2D objects by calling slab(data, idx...).

IJF{S}(ArrayType[, ones | zeros | rand]; Nij)

The keyword constructor returns a IJF given the ArrayType and (optionally) an initialization method (one of Base.ones, Base.zeros, Random.rand) and the keywords:

  • Nij quadrature degrees of freedom per horizontal direction
Note

Objects made with the keyword constructor 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.

source
ClimaCore.DataLayouts.VFType
VF{S, A} <: DataColumn{S, Nv}

Backing DataLayout for 1D FV column data.

Column level data (V) are contiguous for each S datatype struct field (F).

A DataColumn view can be returned from other Data1DX, Data2DX objects by calling column(data, idx...).

VF{S}(ArrayType[, ones | zeros | rand]; Nv)

The keyword constructor returns a VF given the ArrayType and (optionally) an initialization method (one of Base.ones, Base.zeros, Random.rand) and the keywords:

  • Nv number of vertical degrees of freedom
Note

Objects made with the keyword constructor 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.

source
ClimaCore.DataLayouts.IFHType
IFH{S,Ni,Nh,A} <: Data1D{S, Ni}
IFH{S,Ni,Nh}(ArrayType)

Backing DataLayout for 1D spectral element slabs.

Element nodal point (I) data is contiguous for each datatype S struct field (F), for each 1D mesh element (H).

The ArrayType-constructor makes a IFH 1D Spectral DataLayout given the backing ArrayType, quadrature degrees of freedom Ni, and the number of mesh elements Nh.

IFH{S}(ArrayType[, ones | zeros | rand]; Ni, Nh)

The keyword constructor returns a IFH given the ArrayType and (optionally) an initialization method (one of Base.ones, Base.zeros, Random.rand) and the keywords:

  • Ni quadrature degrees of freedom in the horizontal direction
  • Nh number of mesh elements
Note

Objects made with the keyword constructor 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.

source
ClimaCore.DataLayouts.IJFHType
IJFH{S, Nij, A} <: Data2D{S, Nij}
IJFH{S,Nij}(ArrayType, nelements)

Backing DataLayout for 2D spectral element slabs.

Element nodal point (I,J) data is contiguous for each datatype S struct field (F), for each 2D mesh element slab (H).

The ArrayType-constructor constructs a IJFH 2D Spectral DataLayout given the backing ArrayType, quadrature degrees of freedom Nij × Nij, and the number of mesh elements nelements.

IJFH{S}(ArrayType[, Base.ones | zeros | rand]; Nij, Nh)

The keyword constructor returns a IJFH given the ArrayType and (optionally) an initialization method (one of Base.ones, Base.zeros, Random.rand) and the keywords:

  • Nij quadrature degrees of freedom per horizontal direction
  • Nh number of mesh elements
Note

Objects made with the keyword constructor 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.

source
ClimaCore.DataLayouts.VIFHType
VIFH{S, Nv, Ni, A} <: Data1DX{S, Nv, Ni}

Backing DataLayout for 1D spectral element slab + extruded 1D FV column data.

Column levels (V) are contiguous for every element nodal point (I) for each datatype S struct field (F), for each 1D mesh element slab (H).

VIFH{S}(ArrayType[, ones | zeros | rand]; Nv, Ni, Nh)

The keyword constructor returns a VIFH given the ArrayType and (optionally) an initialization method (one of Base.ones, Base.zeros, Random.rand) and the keywords:

  • Nv number of vertical degrees of freedom
  • Ni quadrature degrees of freedom in the horizontal direction
  • Nh number of horizontal elements
Note

Objects made with the keyword constructor 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.

source
ClimaCore.DataLayouts.VIJFHType
VIJFH{S, Nij, A} <: Data2DX{S, Nij}

Backing DataLayout for 2D spectral element slab + extruded 1D FV column data.

Column levels (V) are contiguous for every element nodal point (I, J) for each S datatype struct field (F), for each 2D mesh element slab (H).

VIJFH{S}(ArrayType[, ones | zeros | rand]; Nv, Nij, Nh)

The keyword constructor returns a VIJFH given the ArrayType and (optionally) an initialization method (one of Base.ones, Base.zeros, Random.rand) and the keywords:

  • Nv number of vertical degrees of freedom
  • Nij quadrature degrees of freedom per horizontal direction
  • Nh number of horizontal elements
Note

Objects made with the keyword constructor 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.

source
ClimaCore.DataLayouts.IHFType
IHF{S,Ni,Nh,A} <: Data1D{S, Ni}
IHF{S,Ni,Nh}(ArrayType)

Backing DataLayout for 1D spectral element slabs.

Element nodal point (I) data is contiguous for each datatype S struct field (F), for each 1D mesh element (H).

The ArrayType-constructor makes a IHF 1D Spectral DataLayout given the backing ArrayType, quadrature degrees of freedom Ni, and the number of mesh elements Nh.

IHF{S}(ArrayType[, ones | zeros | rand]; Ni, Nh)

The keyword constructor returns a IHF given the ArrayType and (optionally) an initialization method (one of Base.ones, Base.zeros, Random.rand) and the keywords:

  • Ni quadrature degrees of freedom in the horizontal direction
  • Nh number of mesh elements
Note

Objects made with the keyword constructor 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.

source
ClimaCore.DataLayouts.IJHFType
IJHF{S, Nij, A} <: Data2D{S, Nij}
IJHF{S,Nij}(ArrayType, nelements)

Backing DataLayout for 2D spectral element slabs.

Element nodal point (I,J) data is contiguous for each datatype S struct field (F), for each 2D mesh element slab (H).

The ArrayType-constructor constructs a IJHF 2D Spectral DataLayout given the backing ArrayType, quadrature degrees of freedom Nij × Nij, and the number of mesh elements nelements.

IJHF{S}(ArrayType[, Base.ones | zeros | rand]; Nij, Nh)

The keyword constructor returns a IJHF given the ArrayType and (optionally) an initialization method (one of Base.ones, Base.zeros, Random.rand) and the keywords:

  • Nij quadrature degrees of freedom per horizontal direction
  • Nh number of mesh elements
Note

Objects made with the keyword constructor 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.

source
ClimaCore.DataLayouts.VIHFType
VIHF{S, Nv, Ni, A} <: Data1DX{S, Nv, Ni}

Backing DataLayout for 1D spectral element slab + extruded 1D FV column data.

Column levels (V) are contiguous for every element nodal point (I) for each datatype S struct field (F), for each 1D mesh element slab (H).

VIHF{S}(ArrayType[, ones | zeros | rand]; Nv, Ni, Nh)

The keyword constructor returns a VIHF given the ArrayType and (optionally) an initialization method (one of Base.ones, Base.zeros, Random.rand) and the keywords:

  • Nv number of vertical degrees of freedom
  • Ni quadrature degrees of freedom in the horizontal direction
  • Nh number of horizontal elements
Note

Objects made with the keyword constructor 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.

source
ClimaCore.DataLayouts.VIJHFType
VIJHF{S, Nij, A} <: Data2DX{S, Nij}

Backing DataLayout for 2D spectral element slab + extruded 1D FV column data.

Column levels (V) are contiguous for every element nodal point (I, J) for each S datatype struct field (F), for each 2D mesh element slab (H).

VIJHF{S}(ArrayType[, ones | zeros | rand]; Nv, Nij, Nh)

The keyword constructor returns a VIJHF given the ArrayType and (optionally) an initialization method (one of Base.ones, Base.zeros, Random.rand) and the keywords:

  • Nv number of vertical degrees of freedom
  • Nij quadrature degrees of freedom per horizontal direction
  • Nh number of horizontal elements
Note

Objects made with the keyword constructor 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.

source

Geometry

Global Geometry

ClimaCore.Geometry.CartesianGlobalGeometryType
CartesianGlobalGeometry()

Specifies that the local coordinates align with the Cartesian coordinates, e.g. XYZPoint aligns with Cartesian123Point, and UVWVector aligns with Cartesian123Vector.

source

Coordinates

ClimaCore.Geometry.AbstractPointType
AbstractPoint

Represents a point in space.

The following types are supported:

  • XPoint(x)
  • YPoint(y)
  • ZPoint(z)
  • XYPoint(x, y)
  • XZPoint(x, z)
  • XYZPoint(x, y, z)
  • LatPoint(lat)
  • LongPoint(long)
  • LatLongPoint(lat, long)
  • LatLongZPoint(lat, long, z)
  • Cartesian1Point(x1)
  • Cartesian2Point(x2)
  • Cartesian3Point(x3)
  • Cartesian12Point(x1, x2)
  • Cartesian13Point(x1, x3)
  • Cartesian123Point(x1, x2, x3)
source

Points represent locations in space, specified by coordinates in a given coordinate system (Cartesian, spherical, etc), whereas vectors, on the other hand, represent displacements in space.

An analogy with time works well: times (also called instants or datetimes) are locations in time, while, durations are displacements in time.

Note 1: Latitude and longitude are specified via angles (and, therefore, trigonometric functions: cosd, sind, acosd, asind, tand,...) in degrees, not in radians. Moreover, lat (usually denoted by $\theta$) $\in [-90.0, 90.0]$, and long (usually denoted by $\lambda$) $\in [-180.0, 180.0]$.

Note 2:: In a Geometry.LatLongZPoint(lat, long, z), z represents the elevation above the surface of the sphere with radius R (implicitly accounted for in the geoemtry).

Note 3: There are also a set of specific Cartesian points (Cartesian1Point(x1), Cartesian2Point(x2), etc). These are occasionally useful for converting everything to a full Cartesian domain (e.g. for visualization purposes). These are distinct from XYZPoint as ZPoint can mean different things in different domains.

Domains

Types

ClimaCore.Domains.IntervalDomainType
IntervalDomain(coord⁻, coord⁺; periodic=true)
IntervalDomain(coord⁻, coord⁺; boundary_names::Tuple{Symbol,Symbol})

Construct a IntervalDomain, the closed interval is given by coord⁻, coord⁺ coordinate arguments.

Either a periodic or boundary_names keyword argument is required.

source
ClimaCore.Domains.RectangleDomainType
RectangleDomain(x1::ClosedInterval, x2::ClosedInterval;
    x1boundary::Tuple{Symbol,Symbol},
    x2boundary::Tuple{Symbol,Symbol},
    x1periodic = false,
    x2periodic = false,
)

Construct a RectangularDomain in the horizontal. If a given x1 or x2 boundary is not periodic, then x1boundary or x2boundary boundary name keyword arguments must be supplied.

source

Interfaces

Meshes

A Mesh is a division of a domain into elements.

Mesh types

ClimaCore.Meshes.AbstractMeshType
AbstractMesh{dim}

A Mesh is an object which represents how we discretize a domain into elements.

It should be lightweight (i.e. exists on all MPI ranks), e.g for meshes stored in a file, it would contain the filename.

Face and vertex numbering

In 1D, faces and vertices are the same, and both are numbered [1,2].

In 2D, a face is a line segment between to vertices, and both are numbered [1,2,3,4], in a counter-clockwise direction.

 v4        f3        v3
   o-----------------o
   |                 |	    face    vertices
   |                 |	      f1 =>  v1 v2
f4 |                 | f2     f2 =>  v2 v3
   |                 |	      f3 =>  v3 v4
   |                 |        f4 =>  v4 v1
   |                 |
   o-----------------o
  v1       f1        v2

Interface

A subtype of AbstractMesh should define the following methods:

The following types/methods are provided by AbstractMesh:

source
ClimaCore.Meshes.IntervalMeshType
IntervalMesh <: AbstractMesh

A 1D mesh on an IntervalDomain.

Constuctors

IntervalMesh(domain::IntervalDomain, faces::AbstractVector)

Construct a 1D mesh with face locations at faces.

IntervalMesh(domain::IntervalDomain[, stretching=Uniform()]; nelems=)

Constuct a 1D mesh on domain with nelems elements, using stretching. Possible values of stretching are:

source
ClimaCore.Meshes.RectilinearMeshType
RectilinearMesh <: AbstractMesh2D

Constructors

RectilinearMesh(domain::RectangleDomain, n1, n2)

Construct a RectilinearMesh of equally-spaced n1 by n2 elements on domain.

RectilinearMesh(intervalmesh1::IntervalMesh1, intervalmesh2::IntervalMesh2)

Construct the product mesh of intervalmesh1 and intervalmesh2.

source
ClimaCore.Meshes.AbstractCubedSphereType
AbstractCubedSphere <: AbstractMesh2D

This is an abstract type of cubed-sphere meshes on SphereDomains. A cubed-sphere mesh has 6 panels, laid out as follows:

                                          :   Panel 1   :
                            +-------------+-------------+
                            |     +x1     |     +x1     |
                            |             |             |
                            |    Panel    |    Panel    |
                            |+x3   5   -x3|-x2   6   +x2|
                            |     -x2     |     -x3     |
                            |             |             |
                            |     -x1     |     -x1     |
              +-------------+-------------+-------------+
              |     -x2     |     -x2     |
              |             |             |
              |    Panel    |    Panel    |
              |+x1   3   -x1|+x3   4   -x3|
              |     +x3     |     -x1     |
              |             |             |
              |     +x2     |     +x2     |
+-------------+-------------+-------------+
|     +x3     |     +x3     |
|             |             |
|    Panel    |    Panel    |
|-x2   1   +x2|+x1   2   -x1|
|     +x1     |     +x2     |
|             |             |
|     -x3     |     -x3     |
+-------------+-------------+
:   Panel 6   :

This is the same panel ordering used by the S2 Geometry library (though we use 1-based instead of 0-based numering).

Elements are indexed by a CartesianIndex{3} object, where the components are:

  • horizontal element index (left to right) within each panel.
  • vertical element index (bottom to top) within each panel.
  • panel number

Subtypes should have the following fields:

  • domain: a SphereDomain
  • ne: number of elements across each panel

External links

source
ClimaCore.Meshes.EquiangularCubedSphereType
EquiangularCubedSphere <: AbstractCubedSphere

An equiangular gnomonic mesh proposed by [7]. Uses the element indexing convention of AbstractCubedSphere.

Constructors

EquiangularCubedSphere(
    domain::Domains.SphereDomain,
    ne::Integer,
    localelementmap=NormalizedBilinearMap()
    )

Constuct an EquiangularCubedSphere on domain with ne elements across each panel.

source
ClimaCore.Meshes.EquidistantCubedSphereType
EquidistantCubedSphere <: AbstractCubedSphere

An equidistant gnomonic mesh outlined in [8] and [9]. Uses the element indexing convention of AbstractCubedSphere.

Constructors

EquidistantCubedSphere(domain::Domains.SphereDomain, ne::Integer)

Constuct an EquidistantCubedSphere on domain with ne elements across each panel.

source
ClimaCore.Meshes.ConformalCubedSphereType
ConformalCubedSphere <: AbstractCubedSphere

A conformal mesh outlined in [8]. Uses the element indexing convention of AbstractCubedSphere.

Constructors

ConformalCubedSphere(domain::Domains.SphereDomain, ne::Integer)

Constuct a ConformalCubedSphere on domain with ne elements across each panel.

source

Local element map

Mesh stretching

ClimaCore.Meshes.ExponentialStretchingType
ExponentialStretching(H::FT)

Apply exponential stretching to the domain when constructing elements. H is the scale height (a typical atmospheric scale height H ≈ 7.5km).

For an interval $[z_0,z_1]$, this makes the elements uniformally spaced in $\zeta$, where

\[\zeta = \frac{1 - e^{-\eta/h}}{1-e^{-1/h}},\]

where $\eta = \frac{z - z_0}{z_1-z_0}$, and $h = \frac{H}{z_1-z_0}$ is the non-dimensional scale height. If reverse_mode is true, the smallest element is at the top, and the largest at the bottom (this is typical for land model configurations).

Then, the user can define a stretched mesh via

ClimaCore.Meshes.IntervalMesh(interval_domain, ExponentialStretching(H); nelems::Int, reverse_mode = false)

faces contain reference z without any warping.

source
ClimaCore.Meshes.GeneralizedExponentialStretchingType
GeneralizedExponentialStretching(dz_bottom::FT, dz_top::FT)

Apply a generalized form of exponential stretching to the domain when constructing elements. dz_bottom and dz_top are target element grid spacings at the bottom and at the top of the vertical column domain (m). In typical atmosphere configurations, dz_bottom is the smallest grid spacing and dz_top the largest one. On the other hand, for typical land configurations, dz_bottom is the largest grid spacing and dz_top the smallest one.

For land configurations, use reverse_mode = true (default value false).

Then, the user can define a generalized stretched mesh via

ClimaCore.Meshes.IntervalMesh(interval_domain, GeneralizedExponentialStretching(dz_bottom, dz_top); nelems::Int, reverse_mode = false)

faces contain reference z without any warping.

source
ClimaCore.Meshes.HyperbolicTangentStretchingType
HyperbolicTangentStretching(dz_surface::FT)

Apply a hyperbolic tangent stretching to the domain when constructing elements. dz_surface is the target element grid spacing at the surface. In typical atmosphere configuration, it is the grid spacing at the bottom of the vertical column domain (m). On the other hand, for typical land configurations, it is the grid spacing at the top of the vertical column domain.

For an interval $[z_0,z_1]$, this makes the elements uniformally spaced in $\zeta$, where

\[\eta = 1 - \frac{tanh[\gamma(1-\zeta)]}{tanh(\gamma)},\]

where $\eta = \frac{z - z_0}{z_1-z_0}$. The stretching parameter $\gamma$ is chosen to achieve a given resolution dz_surface at the surface.

Then, the user can define a stretched mesh via

ClimaCore.Meshes.IntervalMesh(interval_domain, HyperbolicTangentStretching(dz_surface); nelems::Int, reverse_mode)

reverse_mode is default to false for atmosphere configurations. For land configurations, use reverse_mode = true.

faces contain reference z without any warping.

source

Mesh utilities

ClimaCore.Meshes.truncate_meshFunction
truncate_mesh(
    parent_mesh::AbstractMesh,
    trunc_domain::IntervalDomain{CT},
)

Constructs an IntervalMesh, truncating the given parent_mesh defined on a truncated trunc_domain. The truncation preserves the number of degrees of freedom covering the space from the trunc_domain's z_bottom to z_top, adjusting the stretching.

source

Interfaces

ClimaCore.Meshes.elementsFunction
Meshes.elements(mesh::AbstractMesh)

An iterator over the elements of a mesh. Elements of a mesh can be of any type.

source
ClimaCore.Meshes.boundary_face_nameFunction
Meshes.boundary_face_name(mesh::AbstractMesh, elem, face::Int)::Union{Symbol,Nothing}

The name of the boundary facing face of element elem, or nothing if it is not on the boundary.

source
ClimaCore.Meshes.opposing_faceFunction
opelem, opface, reversed = Meshes.opposing_face(mesh::AbstractMesh, elem, face::Int)

The element and face (opelem, opface) that oppose face face of element elem.

source
ClimaCore.Meshes.coordinatesFunction
Meshes.coordinates(mesh, elem, vert::Int)
Meshes.coordinates(mesh, elem, ξ::SVector)

Return the physical coordinates of a point in an element elem of mesh. The position of the point can either be a vertex number vert or the coordinates ξ in the reference element.

source
ClimaCore.Meshes.containing_elementFunction
elem = Meshes.containing_element(mesh::AbstractMesh, coord)

The element elem in mesh containing the coordinate coord. If the coordinate falls on the boundary between two or more elements, an arbitrary element is chosen.

source
ClimaCore.Meshes.reference_coordinatesFunction
ξ = Meshes.reference_coordinates(mesh::AbstractMesh, elem, coord)

An SVector of coordinates in the reference element such that

Meshes.coordinates(mesh, elem, ξ) == coord

This can be used for interpolation to a specific point.

source
ClimaCore.Meshes.face_connectivity_matrixFunction
M = Meshes.face_connectivity_matrix(mesh, elemorder = elements(mesh))

Construct a Bool-valued SparseCSCMatrix containing the face connections of mesh. Elements are indexed according to elemorder.

Note that M[i,i] == true only if two distinct faces of element i are connected.

source
ClimaCore.Meshes.vertex_connectivity_matrixFunction
M = Meshes.vertex_connectivity_matrix(mesh, elemorder = elements(mesh))

Construct a Bool-valued SparseCSCMatrix containing the vertex connections of mesh. Elements are indexed according to elemorder.

Note that M[i,i] == true only if two distinct vertices of element i are connected.

source
ClimaCore.Meshes.linearindicesFunction
Meshes.linearindices(elemorder)

Given a data structure elemorder[i] = elem that orders elements, construct the inverse map from orderindex = linearindices(elemorder) such that orderindex[elem] = i.

This will try to use the most efficient structure available.

source

Topologies

A Topology determines the ordering and connections between elements of a mesh. Space-filling curve element ordering for a cubed sphere mesh

Types

ClimaCore.Topologies.Topology2DType
Topology2D(mesh::AbstractMesh2D, elemorder=Mesh.elements(mesh))

This is a distributed topology for 2D meshes. elemorder is a vector or other linear ordering of the Mesh.elements(mesh). elempid is a sorted vector of the same length as elemorder, each element of which contains the pid of the owning process.

Internally, we can refer to elements in several different ways:

  • elem: an element of the mesh. Often a CartesianIndex object.
  • gidx: "global index": an enumeration of all elements:
    • elemorder[gidx] == elem
    • orderindex[elem] == gidx
  • lidx: "local index": an enumeration of local elements.
    • local_elem_gidx[lidx] == gidx
  • sidx: "send index": an index into the send buffer of a local element. A single local element may have multiple sidxs if it needs to be send to multiple processes.
    • send_elem_lidx[sidx] == lidx
  • ridx: "receive index": an index into the receive buffer of a ghost element.
    • recv_elem_gidx[ridx] == gidx
source
ClimaCore.Topologies.spacefillingcurveFunction
spacefillingcurve(mesh::Meshes.AbstractCubedSphere)

Generate element ordering, elemorder, based on a space filling curve for a CubedSphere mesh.

source
spacefillingcurve(mesh::Meshes.RectilinearMesh)

Generate element ordering, elemorder, based on a space filling curve for a Rectilinear mesh.

source
ClimaCore.Topologies.ghost_facesFunction
ghost_faces(topology::AbstractTopology)

An iterator over the ghost faces of topology. Each element of the iterator is a 5-tuple the form

(elem1, face1, elem2, face2, reversed)

where elemX, faceX are the element and face numbers, and reversed indicates whether they have opposing orientations.

source

Interfaces

ClimaCore.Topologies.opposing_faceFunction
(opelem, opface, reversed) = opposing_face(topology, elem, face)

The opposing face of face number face of element elem in topology.

  • opelem is the opposing element number, 0 for a boundary, negative for a ghost element
  • opface is the opposite face number, or boundary face number if a boundary
  • reversed indicates whether the opposing face has the opposite orientation.
source
ClimaCore.Topologies.interior_facesFunction
interior_faces(topology::AbstractTopology)

An iterator over the interior faces of topology. Each element of the iterator is a 5-tuple the form

(elem1, face1, elem2, face2, reversed)

where elemX, faceX are the element and face numbers, and reversed indicates whether they have opposing orientations.

source
ClimaCore.Topologies.boundary_tagsFunction
boundary_tags(topology)

A Tuple or NamedTuple of the boundary tags of the topology. A boundary tag is an integer that uniquely identifies a boundary.

source
ClimaCore.Topologies.boundary_tagFunction
boundary_tag(topology, name::Symbol)

The boundary tag of the topology for boundary name name. A boundary tag is an integer that uniquely identifies a boundary.

source
ClimaCore.Topologies.boundary_facesFunction
boundary_faces(topology, boundarytag)

An iterator over the faces of topology which face the boundary with tag boundarytag. Each element of the iterator is an (elem, face) pair.

source
ClimaCore.Topologies.local_neighboring_elementsFunction
local_neighboring_elements(topology::AbstractTopology, lidx::Integer)

An iterator of the local element indices (lidx) of the local elements which are neighbors of the local element lidx in topology (excluding lidx itself).

source

Grids

ClimaCore.Grids.ColumnGridType
ColumnGrid(
    full_grid :: ExtrudedFiniteDifferenceGrid, 
    colidx    :: ColumnIndex,
)

A view into a column of a ExtrudedFiniteDifferenceGrid. This can be used as an

source
ClimaCore.Grids.FiniteDifferenceGridType
FiniteDifferenceGrid(topology::Topologies.IntervalTopology)
FiniteDifferenceGrid(device::ClimaComms.AbstractDevice, mesh::Meshes.IntervalMesh)

Construct a FiniteDifferenceGrid from an IntervalTopology (or an IntervalMesh).

This is an object which contains all the necessary geometric information.

To avoid unnecessary duplication, we memoize the construction of the grid.

source
ClimaCore.Grids.ExtrudedFiniteDifferenceGridType
ExtrudedFiniteDifferenceGrid(
    horizontal_space::AbstractSpace,
    vertical_space::FiniteDifferenceSpace,
    hypsography::HypsographyAdaption = Flat(),
)

Construct an ExtrudedFiniteDifferenceGrid from the horizontal and vertical spaces.

source
ClimaCore.Grids.SpectralElementGrid1DType
SpectralElementGrid1D(mesh::Meshes.IntervalMesh, quadrature_style::Quadratures.QuadratureStyle)

A one-dimensional space: within each element the space is represented as a polynomial.

source

Hypsography

CommonGrids

ClimaCore.CommonGridsModule
CommonGrids

CommonGrids contains convenience constructors for common grids. Constructors in this module are sometimes 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, then you may need to create a custom grid using our low-level compose-able API.

Transitioning to using CommonGrids

You may have constructed a grid in the following way:

using ClimaComms
using ClimaCore: DataLayouts, Geometry, Topologies, Quadratures, Domains, Meshes, Grids
FT = Float64
z_elem = 63
z_min = FT(0)
z_max = FT(1)
radius = FT(6.371229e6)
h_elem = 15
n_quad_points = 4
device = ClimaComms.device()
context = ClimaComms.context(device)
hypsography = Grids.Flat()
global_geometry = Geometry.ShallowSphericalGlobalGeometry(radius)
quad = Quadratures.GLL{n_quad_points}()
h_mesh = Meshes.EquiangularCubedSphere(Domains.SphereDomain{FT}(radius), h_elem)
h_topology = Topologies.Topology2D(context, h_mesh)
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; nelems = z_elem)
h_grid = Grids.SpectralElementGrid2D(h_topology, quad)
z_topology = Topologies.IntervalTopology(context, z_mesh)
z_grid = Grids.FiniteDifferenceGrid(z_topology)
grid = Grids.ExtrudedFiniteDifferenceGrid(
    h_grid,
    z_grid,
    hypsography,
    global_geometry,
)

You may re-write this as:

using ClimaCore.CommonGrids: ExtrudedCubedSphereGrid
grid = ExtrudedCubedSphereGrid(;
    z_elem = 63,
    z_min = 0,
    z_max = 1,
    radius = 6.371229e6,
    h_elem = 15,
    n_quad_points = 4,
)
source
ClimaCore.CommonGrids.ExtrudedCubedSphereGridFunction
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_fun = (h_grid, z_grid) -> Grids.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),
    h_topology::Topologies.AbstractDistributedTopology = Topologies.Topology2D(context, h_mesh),
    horizontal_layout_type = DataLayouts.IJFH,
    z_mesh::Meshes.IntervalMesh = DefaultZMesh(FT; z_min, z_max, z_elem, stretch),
    enable_bubble::Bool = false
)

A convenience constructor, which builds an Grids.ExtrudedFiniteDifferenceGrid, given:

  • FT the floating-point type (defaults to Float64) [Float32, Float64]
  • 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 cubed sphere
  • h_elem the number of horizontal elements per side of every panel (6 panels in total)
  • n_quad_points the number of quadrature points per horizontal element
  • device the ClimaComms.device
  • context the ClimaComms.context
  • stretch the mesh Meshes.StretchingRule (defaults to Meshes.Uniform)
  • hypsography_fun a function or callable object (hypsography_fun(h_grid, z_grid) -> hypsography) for constructing the hypsography model.
  • global_geometry the global geometry (defaults to Geometry.CartesianGlobalGeometry)
  • quad the quadrature style (defaults to Quadratures.GLL{n_quad_points})
  • h_mesh the horizontal mesh (defaults to Meshes.EquiangularCubedSphere)
  • h_topology the horizontal topology (defaults to Topologies.Topology2D)
  • horizontal_layout_type the horizontal DataLayout type (defaults to DataLayouts.IJFH). This parameter describes how data is arranged in memory. See Grids.SpectralElementGrid2D for its use.
  • z_mesh the vertical mesh, defaults to an Meshes.IntervalMesh along z with given stretch
  • enable_bubble enables the "bubble correction" for more accurate element areas when computing the spectral element space. See Grids.SpectralElementGrid2D for more information.

Example usage

using ClimaCore.CommonGrids
grid = ExtrudedCubedSphereGrid(;
    z_elem = 10,
    z_min = 0,
    z_max = 1,
    radius = 10,
    h_elem = 10,
    n_quad_points = 4,
)
source
ClimaCore.CommonGrids.CubedSphereGridFunction
CubedSphereGrid(
    ::Type{<:AbstractFloat}; # defaults to Float64
    radius::Real,
    h_elem::Integer,
    n_quad_points::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),
    h_topology::Topologies.AbstractDistributedTopology = Topologies.Topology2D(context, h_mesh),
    horizontal_layout_type = DataLayouts.IJFH,
)

A convenience constructor, which builds a Grids.SpectralElementGrid2D given:

  • FT the floating-point type (defaults to Float64) [Float32, Float64]
  • radius the radius of the cubed sphere
  • h_elem the number of horizontal elements per side of every panel (6 panels in total)
  • n_quad_points the number of quadrature points per horizontal element
  • device the ClimaComms.device
  • context the ClimaComms.context
  • quad the quadrature style (defaults to Quadratures.GLL{n_quad_points})
  • h_mesh the horizontal mesh (defaults to Meshes.EquiangularCubedSphere)
  • h_topology the horizontal topology (defaults to Topologies.Topology2D)
  • horizontal_layout_type the horizontal DataLayout type (defaults to DataLayouts.IJFH). This parameter describes how data is arranged in memory. See Grids.SpectralElementGrid2D for its use.

Example usage

using ClimaCore.CommonGrids
grid = CubedSphereGrid(; radius = 10, n_quad_points = 4, h_elem = 10)
source
ClimaCore.CommonGrids.ColumnGridFunction
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(),
    z_mesh::Meshes.IntervalMesh = DefaultZMesh(FT; z_min, z_max, z_elem, stretch),
)

A convenience constructor, which builds a Grids.FiniteDifferenceGrid given:

  • FT the floating-point type (defaults to Float64) [Float32, Float64]
  • 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
  • context the ClimaComms.context
  • stretch the mesh Meshes.StretchingRule (defaults to Meshes.Uniform)
  • z_mesh the vertical mesh, defaults to an Meshes.IntervalMesh along z with given stretch

Example usage

using ClimaCore.CommonGrids
grid = ColumnGrid(; z_elem = 10, z_min = 0, z_max = 10)
source
ClimaCore.CommonGrids.Box3DGridFunction
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_fun = (h_grid, z_grid) -> Grids.Flat(),
    global_geometry::Geometry.AbstractGlobalGeometry = Geometry.CartesianGlobalGeometry(),
    quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
    horizontal_layout_type = DataLayouts.IJFH,
    [h_topology::Topologies.AbstractDistributedTopology], # optional
    [z_mesh::Meshes.IntervalMesh], # optional
    enable_bubble::Bool = false,
)

A convenience constructor, which builds a Grids.ExtrudedFiniteDifferenceGrid with a Grids.FiniteDifferenceGrid vertical grid and a Grids.SpectralElementGrid2D horizontal grid, given:

  • z_elem the number of z-points
  • x_min the domain minimum along the x-direction.
  • x_max the domain maximum along the x-direction.
  • y_min the domain minimum along the y-direction.
  • y_max the domain maximum along the y-direction.
  • z_min the domain minimum along the z-direction.
  • z_max the domain maximum along the z-direction.
  • periodic_x Bool indicating to use periodic domain along x-direction
  • periodic_y Bool indicating to use periodic domain along y-direction
  • n_quad_points the number of quadrature points per horizontal element
  • x_elem the number of x-points
  • y_elem the number of y-points
  • device the ClimaComms.device
  • context the ClimaComms.context
  • stretch the mesh Meshes.StretchingRule (defaults to Meshes.Uniform)
  • hypsography_fun a function or callable object (hypsography_fun(h_grid, z_grid) -> hypsography) for constructing the hypsography model.
  • global_geometry the global geometry (defaults to Geometry.CartesianGlobalGeometry)
  • quad the quadrature style (defaults to Quadratures.GLL{n_quad_points})
  • h_topology the horizontal topology (defaults to Topologies.Topology2D)
  • z_mesh the vertical mesh, defaults to an Meshes.IntervalMesh along z with given stretch
  • enable_bubble enables the "bubble correction" for more accurate element areas when computing the spectral element space. See Grids.SpectralElementGrid2D for more information.
  • horizontal_layout_type the horizontal DataLayout type (defaults to DataLayouts.IJFH). This parameter describes how data is arranged in memory. See Grids.SpectralElementGrid2D for its use.

Example usage

using ClimaCore.CommonGrids
grid = Box3DGrid(;
    z_elem = 10,
    x_min = 0,
    x_max = 1,
    y_min = 0,
    y_max = 1,
    z_min = 0,
    z_max = 10,
    periodic_x = false,
    periodic_y = false,
    n_quad_points = 4,
    x_elem = 3,
    y_elem = 4,
)
source
ClimaCore.CommonGrids.SliceXZGridFunction
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_fun = (h_grid, z_grid) -> Grids.Flat(),
    global_geometry::Geometry.AbstractGlobalGeometry = Geometry.CartesianGlobalGeometry(),
    quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
)

A convenience constructor, which builds a Grids.ExtrudedFiniteDifferenceGrid with a Grids.FiniteDifferenceGrid vertical grid and a Grids.SpectralElementGrid1D horizontal grid, given:

  • FT the floating-point type (defaults to Float64) [Float32, Float64]
  • z_elem the number of z-points
  • x_min the domain minimum along the x-direction.
  • x_max the domain maximum along the x-direction.
  • z_min the domain minimum along the z-direction.
  • z_max the domain maximum along the z-direction.
  • periodic_x Bool indicating to use periodic domain along x-direction
  • n_quad_points the number of quadrature points per horizontal element
  • x_elem the number of x-points
  • device the ClimaComms.device
  • context the ClimaComms.context
  • stretch the mesh Meshes.StretchingRule (defaults to Meshes.Uniform)
  • hypsography_fun a function or callable object (hypsography_fun(h_grid, z_grid) -> hypsography) for constructing the hypsography model.
  • global_geometry the global geometry (defaults to Geometry.CartesianGlobalGeometry)
  • quad the quadrature style (defaults to Quadratures.GLL{n_quad_points})

Example usage

using ClimaCore.CommonGrids
grid = SliceXZGrid(;
    z_elem = 10,
    x_min = 0,
    x_max = 1,
    z_min = 0,
    z_max = 1,
    periodic_x = false,
    n_quad_points = 4,
    x_elem = 4,
)
source
ClimaCore.CommonGrids.RectangleXYGridFunction
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::Grids.HypsographyAdaption = Grids.Flat(),
    global_geometry::Geometry.AbstractGlobalGeometry = Geometry.CartesianGlobalGeometry(),
    quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
)

A convenience constructor, which builds a Grids.SpectralElementGrid2D with a horizontal RectilinearMesh mesh, given:

  • x_min the domain minimum along the x-direction.
  • x_max the domain maximum along the x-direction.
  • y_min the domain minimum along the y-direction.
  • y_max the domain maximum along the y-direction.
  • periodic_x Bool indicating to use periodic domain along x-direction
  • periodic_y Bool indicating to use periodic domain along y-direction
  • n_quad_points the number of quadrature points per horizontal element
  • x_elem the number of x-points
  • y_elem the number of y-points
  • device the ClimaComms.device
  • context the ClimaComms.context
  • hypsography_fun a function or callable object (hypsography_fun(h_grid, z_grid) -> hypsography) for constructing the hypsography model.
  • global_geometry the global geometry (defaults to Geometry.CartesianGlobalGeometry)
  • quad the quadrature style (defaults to Quadratures.GLL{n_quad_points})

Example usage

using ClimaCore.CommonGrids
grid = RectangleXYGrid(;
    x_min = 0,
    x_max = 1,
    y_min = 0,
    y_max = 1,
    periodic_x = false,
    periodic_y = false,
    n_quad_points = 4,
    x_elem = 3,
    y_elem = 4,
)
source

Spaces

A Space represents a discretized function space over some domain. Currently two main discretizations are supported: Spectral Element Discretization (both Continuous Galerkin and Discontinuous Galerkin types) and a staggered Finite Difference Discretization. Combination of these two in the horizontal/vertical directions, respectively, is what we call a hybrid space.

Sketch of a 2DX hybrid discretization:

3D hybrid discretization in a Cartesian domain

ClimaCore.SpacesModule
Meshes
  • domain
  • topology
  • coordinates
  • metric terms (inverse partial derivatives)
  • quadrature rules and weights

References / notes

source

Finite Difference Spaces

ClimaCore.jl supports staggered Finite Difference discretizations. Finite Differences discretize an interval domain by approximating the function by a value at either the center of each element (also referred to as cell) (CenterFiniteDifferenceSpace), or the interfaces (faces in 3D, edges in 2D or points in 1D) between elements (FaceFiniteDifferenceSpace).

Users should construct either the center or face space from the mesh, then construct the other space from the original one: this internally reuses the same data structures, and avoids allocating additional memory.

Internals

Spectral Element Spaces

ClimaCore.Spaces.SpectralElementSpace1DType
SpectralElementSpace1D(grid::SpectralElementGrid1D)
SpectralElementSpace1D(
    topology::Topologies.IntervalTopology,
    quadrature_style::Quadratures.QuadratureStyle;
    kwargs...
)
source

Extruded Finite Difference Spaces

ClimaCore.Spaces.ExtrudedFiniteDifferenceSpaceType
ExtrudedFiniteDifferenceSpace(grid, staggering)

ExtrudedFiniteDifferenceSpace(
    horizontal_space::AbstractSpace,
    vertical_space::FiniteDifferenceSpace,
    hypsography::Grids.HypsographyAdaption = Grids.Flat(),
)

An extruded finite-difference space, where the extruded direction is staggered, containing grid information at either

source

CommonSpaces

ClimaCore.CommonSpacesModule
CommonSpaces

CommonSpaces contains convenience constructors for common spaces, which builds off of CommonGrids and(when appropriate) requires an additional argument, staggering::Staggering to construct the desired space.

source
ClimaCore.CommonSpaces.ExtrudedCubedSphereSpaceFunction
ExtrudedCubedSphereSpace(
    ::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_fun = (h_grid, z_grid) -> Grids.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),
    h_topology::Topologies.AbstractDistributedTopology = Topologies.Topology2D(context, h_mesh),
    horizontal_layout_type = DataLayouts.IJFH,
    z_mesh::Meshes.IntervalMesh = DefaultZMesh(FT; z_min, z_max, z_elem, stretch),
    enable_bubble::Bool = false
    staggering::Staggering,
)

Construct an Spaces.ExtrudedFiniteDifferenceSpace for a cubed sphere configuration, given:

  • FT the floating-point type (defaults to Float64) [Float32, Float64]
  • 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 cubed sphere
  • h_elem the number of horizontal elements per side of every panel (6 panels in total)
  • n_quad_points the number of quadrature points per horizontal element
  • device the ClimaComms.device
  • context the ClimaComms.context
  • stretch the mesh Meshes.StretchingRule (defaults to Meshes.Uniform)
  • hypsography_fun a function or callable object (hypsography_fun(h_grid, z_grid) -> hypsography) for constructing the hypsography model.
  • global_geometry the global geometry (defaults to Geometry.CartesianGlobalGeometry)
  • quad the quadrature style (defaults to Quadratures.GLL{n_quad_points})
  • h_mesh the horizontal mesh (defaults to Meshes.EquiangularCubedSphere)
  • h_topology the horizontal topology (defaults to Topologies.Topology2D)
  • horizontal_layout_type the horizontal DataLayout type (defaults to DataLayouts.IJFH). This parameter describes how data is arranged in memory. See Grids.SpectralElementGrid2D for its use.
  • z_mesh the vertical mesh, defaults to an Meshes.IntervalMesh along z with given stretch
  • enable_bubble enables the "bubble correction" for more accurate element areas when computing the spectral element space. See Grids.SpectralElementGrid2D for more information.
  • staggering vertical staggering, can be one of [Grids.CellFace, Grids.CellCenter]

Note that these arguments are all the same as CommonGrids.ExtrudedCubedSphereGrid, except for staggering.

Example usage

using ClimaCore.CommonSpaces
space = ExtrudedCubedSphereSpace(;
    z_elem = 10,
    z_min = 0,
    z_max = 1,
    radius = 10,
    h_elem = 10,
    n_quad_points = 4,
    staggering = Grids.CellCenter()
)
source
ClimaCore.CommonSpaces.CubedSphereSpaceFunction
CubedSphereSpace(
    ::Type{<:AbstractFloat}; # defaults to Float64
    radius::Real,
    h_elem::Integer,
    n_quad_points::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),
    h_topology::Topologies.AbstractDistributedTopology = Topologies.Topology2D(context, h_mesh),
    horizontal_layout_type = DataLayouts.IJFH,
)

Construct a Spaces.SpectralElementSpace2D for a cubed sphere configuration, given:

  • FT the floating-point type (defaults to Float64) [Float32, Float64]
  • radius the radius of the cubed sphere
  • h_elem the number of horizontal elements per side of every panel (6 panels in total)
  • n_quad_points the number of quadrature points per horizontal element
  • device the ClimaComms.device
  • context the ClimaComms.context
  • quad the quadrature style (defaults to Quadratures.GLL{n_quad_points})
  • h_mesh the horizontal mesh (defaults to Meshes.EquiangularCubedSphere)
  • h_topology the horizontal topology (defaults to Topologies.Topology2D)
  • horizontal_layout_type the horizontal DataLayout type (defaults to DataLayouts.IJFH). This parameter describes how data is arranged in memory. See Grids.SpectralElementGrid2D for its use.

Note that these arguments are all the same as CommonGrids.CubedSphereGrid.

Example usage

using ClimaCore.CommonSpaces
space = CubedSphereSpace(;
    radius = 10,
    n_quad_points = 4,
    h_elem = 10,
)
source
ClimaCore.CommonSpaces.ColumnSpaceFunction
ColumnSpace(
    ::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(),
    z_mesh::Meshes.IntervalMesh = DefaultZMesh(FT; z_min, z_max, z_elem, stretch),
)

Construct a 1D Spaces.FiniteDifferenceSpace for a column configuration, given:

  • FT the floating-point type (defaults to Float64) [Float32, Float64]
  • 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
  • context the ClimaComms.context
  • stretch the mesh Meshes.StretchingRule (defaults to Meshes.Uniform)
  • z_mesh the vertical mesh, defaults to an Meshes.IntervalMesh along z with given stretch
  • staggering vertical staggering, can be one of [Grids.CellFace, Grids.CellCenter]

Note that these arguments are all the same as CommonGrids.ColumnGrid, except for staggering.

Example usage

using ClimaCore.CommonSpaces
space = ColumnSpace(;
    z_elem = 10,
    z_min = 0,
    z_max = 10,
    staggering = Grids.CellCenter()
)
source
ClimaCore.CommonSpaces.Box3DSpaceFunction
Box3DSpace(
    ::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_fun = (h_grid, z_grid) -> Grids.Flat(),
    global_geometry::Geometry.AbstractGlobalGeometry = Geometry.CartesianGlobalGeometry(),
    quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
    horizontal_layout_type = DataLayouts.IJFH,
    [h_topology::Topologies.AbstractDistributedTopology], # optional
    [z_mesh::Meshes.IntervalMesh], # optional
    enable_bubble::Bool = false,
    staggering::Staggering
)

Construct a Spaces.ExtrudedFiniteDifferenceSpace for a 3D box configuration, given:

  • z_elem the number of z-points
  • x_min the domain minimum along the x-direction.
  • x_max the domain maximum along the x-direction.
  • y_min the domain minimum along the y-direction.
  • y_max the domain maximum along the y-direction.
  • z_min the domain minimum along the z-direction.
  • z_max the domain maximum along the z-direction.
  • periodic_x Bool indicating to use periodic domain along x-direction
  • periodic_y Bool indicating to use periodic domain along y-direction
  • n_quad_points the number of quadrature points per horizontal element
  • x_elem the number of x-points
  • y_elem the number of y-points
  • device the ClimaComms.device
  • context the ClimaComms.context
  • stretch the mesh Meshes.StretchingRule (defaults to Meshes.Uniform)
  • hypsography_fun a function or callable object (hypsography_fun(h_grid, z_grid) -> hypsography) for constructing the hypsography model.
  • global_geometry the global geometry (defaults to Geometry.CartesianGlobalGeometry)
  • quad the quadrature style (defaults to Quadratures.GLL{n_quad_points})
  • h_topology the horizontal topology (defaults to Topologies.Topology2D)
  • z_mesh the vertical mesh, defaults to an Meshes.IntervalMesh along z with given stretch
  • enable_bubble enables the "bubble correction" for more accurate element areas when computing the spectral element space. See Grids.SpectralElementGrid2D for more information.
  • horizontal_layout_type the horizontal DataLayout type (defaults to DataLayouts.IJFH). This parameter describes how data is arranged in memory. See Grids.SpectralElementGrid2D for its use.
  • staggering vertical staggering, can be one of [Grids.CellFace, Grids.CellCenter]

Note that these arguments are all the same as CommonGrids.Box3DGrid, except for staggering.

Example usage

using ClimaCore.CommonSpaces
space = Box3DSpace(;
    z_elem = 10,
    x_min = 0,
    x_max = 1,
    y_min = 0,
    y_max = 1,
    z_min = 0,
    z_max = 10,
    periodic_x = false,
    periodic_y = false,
    n_quad_points = 4,
    x_elem = 3,
    y_elem = 4,
    staggering = Grids.CellCenter()
)
source
ClimaCore.CommonSpaces.SliceXZSpaceFunction
SliceXZSpace(
    ::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_fun = (h_grid, z_grid) -> Grids.Flat(),
    global_geometry::Geometry.AbstractGlobalGeometry = Geometry.CartesianGlobalGeometry(),
    quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
    staggering::Staggering
)

Construct a Spaces.ExtrudedFiniteDifferenceSpace for a 2D slice configuration, given:

  • FT the floating-point type (defaults to Float64) [Float32, Float64]
  • z_elem the number of z-points
  • x_min the domain minimum along the x-direction.
  • x_max the domain maximum along the x-direction.
  • z_min the domain minimum along the z-direction.
  • z_max the domain maximum along the z-direction.
  • periodic_x Bool indicating to use periodic domain along x-direction
  • n_quad_points the number of quadrature points per horizontal element
  • x_elem the number of x-points
  • device the ClimaComms.device
  • context the ClimaComms.context
  • stretch the mesh Meshes.StretchingRule (defaults to Meshes.Uniform)
  • hypsography_fun a function or callable object (hypsography_fun(h_grid, z_grid) -> hypsography) for constructing the hypsography model.
  • global_geometry the global geometry (defaults to Geometry.CartesianGlobalGeometry)
  • quad the quadrature style (defaults to Quadratures.GLL{n_quad_points})
  • staggering vertical staggering, can be one of [Grids.CellFace, Grids.CellCenter]

Note that these arguments are all the same as CommonGrids.SliceXZGrid, except for staggering.

Example usage

using ClimaCore.CommonSpaces
space = SliceXZSpace(;
    z_elem = 10,
    x_min = 0,
    x_max = 1,
    z_min = 0,
    z_max = 1,
    periodic_x = false,
    n_quad_points = 4,
    x_elem = 4,
    staggering = Grids.CellCenter()
)
source
ClimaCore.CommonSpaces.RectangleXYSpaceFunction
RectangleXYSpace(
    ::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::Grids.HypsographyAdaption = Grids.Flat(),
    global_geometry::Geometry.AbstractGlobalGeometry = Geometry.CartesianGlobalGeometry(),
    quad::Quadratures.QuadratureStyle = Quadratures.GLL{n_quad_points}(),
)

Construct a Spaces.SpectralElementSpace2D space for a 2D rectangular configuration, given:

  • x_min the domain minimum along the x-direction.
  • x_max the domain maximum along the x-direction.
  • y_min the domain minimum along the y-direction.
  • y_max the domain maximum along the y-direction.
  • periodic_x Bool indicating to use periodic domain along x-direction
  • periodic_y Bool indicating to use periodic domain along y-direction
  • n_quad_points the number of quadrature points per horizontal element
  • x_elem the number of x-points
  • y_elem the number of y-points
  • device the ClimaComms.device
  • context the ClimaComms.context
  • hypsography_fun a function or callable object (hypsography_fun(h_grid, z_grid) -> hypsography) for constructing the hypsography model.
  • global_geometry the global geometry (defaults to Geometry.CartesianGlobalGeometry)
  • quad the quadrature style (defaults to Quadratures.GLL{n_quad_points})

Note that these arguments are all the same as CommonGrids.RectangleXYGrid, except for staggering.

Example usage

using ClimaCore.CommonSpaces
space = RectangleXYSpace(;
    x_min = 0,
    x_max = 1,
    y_min = 0,
    y_max = 1,
    periodic_x = false,
    periodic_y = false,
    n_quad_points = 4,
    x_elem = 3,
    y_elem = 4,
)
source

Quadratures

ClimaCore.Quadratures.barycentric_weightsFunction
barycentric_weights(x::SVector{Nq}) where {Nq}

The barycentric weights associated with the array of point locations x:

\[w_j = \frac{1}{\prod_{k \ne j} (x_i - x_j)}\]

See [11], equation 3.2.

source
ClimaCore.Quadratures.interpolation_matrixFunction
interpolation_matrix(x::SVector, r::SVector{Nq})

The matrix which interpolates the Lagrange polynomial of degree Nq-1 through the points r, to points x. The matrix coefficients are computed using the Barycentric formula of [11], section 4:

\[I_{ij} = \begin{cases} 1 & \text{if } x_i = r_j, \\ 0 & \text{if } x_i = r_k \text{ for } k \ne j, \\ \frac{\displaystyle \frac{w_j}{x_i - r_j}}{\displaystyle \sum_k \frac{w_k}{x_i - r_k}} & \text{otherwise,} \end{cases}\]

where $w_j$ are the barycentric weights, see barycentric_weights.

source
ClimaCore.Quadratures.differentiation_matrixFunction
differentiation_matrix(r::SVector{Nq, T}) where {Nq, T}

The spectral differentiation matrix for the Lagrange polynomial of degree Nq-1 interpolating at points r.

The matrix coefficients are computed using the [11], section 9.3:

\[D_{ij} = \begin{cases} \displaystyle \frac{w_j}{w_i (x_i - x_j)} &\text{ if } i \ne j \\ -\sum_{k \ne j} D_{kj} &\text{ if } i = j \end{cases}\]

where $w_j$ are the barycentric weights, see barycentric_weights.

source
differentiation_matrix(FT, quadstyle::QuadratureStyle)

The spectral differentiation matrix at the quadrature points of quadstyle, using floating point types FT.

source
ClimaCore.Quadratures.orthonormal_polyFunction
V = orthonormal_poly(points, quad)

V_{ij} contains the j-1th Legendre polynomial evaluated at points[i]. i.e. it is the mapping from the modal to the nodal representation.

source

Internals

ClimaCore.Topologies.dss_transformFunction
dss_transform(arg, local_geometry, weight, I)

Transfrom arg[I] to a basis for direct stiffness summation (DSS). Transformations only apply to vector quantities.

  • local_geometry[I] is the relevant LocalGeometry object. If it is nothing, then no transformation is performed
  • weight[I] is the relevant DSS weights. If weight is nothing, then the result is simply summation.

See ClimaCore.Spaces.weighted_dss!.

source
ClimaCore.Topologies.dss_transform!Function
dss_transform!(
    device::ClimaComms.AbstractDevice,
    dss_buffer::DSSBuffer,
    data::Union{DataLayouts.IJFH, DataLayouts.IJHF, DataLayouts.VIJFH, DataLayouts.VIJHF},
    local_geometry::Union{DataLayouts.IJFH, DataLayouts.IJHF, DataLayouts.VIJFH, DataLayouts.VIJHF},
    weight::Union{DataLayouts.IJFH, DataLayouts.IJHF},
    perimeter::Perimeter2D,
    localelems::AbstractVector{Int},
)

Transforms vectors from Covariant axes to physical (local axis), weights the data at perimeter nodes, and stores result in the perimeter_data array. This function calls the appropriate version of dss_transform! based on the data layout of the input arguments.

Arguments:

  • dss_buffer: DSSBuffer generated by create_dss_buffer function for field data
  • data: field data
  • local_geometry: local metric information defined at each node
  • weight: local dss weights for horizontal space
  • perimeter: perimeter iterator
  • localelems: list of local elements to perform transformation operations on

Part of ClimaCore.Spaces.weighted_dss!.

source
function dss_transform!(
    ::ClimaComms.AbstractCPUDevice,
    perimeter_data::Union{DataLayouts.VIFH, DataLayouts.VIHF},
    data::Union{DataLayouts.IJFH, DataLayouts.IJHF, DataLayouts.VIJFH, DataLayouts.VIJHF},
    perimeter::AbstractPerimeter,
    bc,
    localelems::Vector{Int},
)

Transforms vectors from Covariant axes to physical (local axis), weights the data at perimeter nodes, and stores result in the perimeter_data array.

Arguments:

  • perimeter_data: contains the perimeter field data, represented on the physical axis, corresponding to the full field data in data
  • data: field data
  • perimeter: perimeter iterator
  • bc: A broadcasted object representing the dss transform.
  • localelems: list of local elements to perform transformation operations on

Part of ClimaCore.Spaces.weighted_dss!.

source
ClimaCore.Topologies.dss_untransform!Function
dss_untransform!(
    device::ClimaComms.AbstractDevice,
    dss_buffer::DSSBuffer,
    data::Union{DataLayouts.IJFH, DataLayouts.IJHF, DataLayouts.VIJFH, DataLayouts.VIJHF},
    local_geometry::Union{DataLayouts.IJFH, DataLayouts.IJHF, DataLayouts.VIJFH, DataLayouts.VIJHF},
    perimeter::AbstractPerimeter,
)

Transforms the DSS'd local vectors back to Covariant12 vectors, and copies the DSS'd data from the perimeter_data to data. This function calls the appropriate version of dss_transform! function based on the data layout of the input arguments.

Arguments:

  • dss_buffer: DSSBuffer generated by create_dss_buffer function for field data
  • data: field data
  • local_geometry: local metric information defined at each node
  • perimeter: perimeter iterator
  • localelems: list of local elements to perform transformation operations on

Part of ClimaCore.Spaces.weighted_dss!.

source
ClimaCore.Topologies.dss_local_ghost!Function
function dss_local_ghost!(
    ::ClimaComms.AbstractCPUDevice,
    perimeter_data::DataLayouts.VIFH,
    perimeter::AbstractPerimeter,
    topology::AbstractTopology,
)

Computes the "local" part of ghost vertex dss. (i.e. it computes the summation of all the shared local vertices of a unique ghost vertex and stores the value in each of the local vertex locations in perimeter_data)

Part of ClimaCore.Spaces.weighted_dss!.

source
ClimaCore.Topologies.dss_ghost!Function
dss_ghost!(
    device::ClimaComms.AbstractCPUDevice,
    perimeter_data::DataLayouts.VIFH,
    perimeter::AbstractPerimeter,
    topology::AbstractTopology,
)

Sets the value for all local vertices of each unique ghost vertex, in perimeter_data, to that of the representative ghost vertex.

Part of ClimaCore.Spaces.weighted_dss!.

source
ClimaCore.Topologies.create_dss_bufferFunction
create_dss_buffer(
    data::Union{DataLayouts.IJFH, DataLayouts.VIJFH},
    hspace::AbstractSpectralElementSpace,
)

Creates a DSSBuffer for the field data corresponding to data

source
Spaces.create_dss_buffer(fv::FieldVector)

Create a NamedTuple of buffers for communicating neighbour information of each Field in fv. In this NamedTuple, the name of each field is mapped to the buffer.

source
Spaces.create_dss_buffer(field::Field)

Create a buffer for communicating neighbour information of field.

source
create_dss_buffer(
    data::Union{DataLayouts.IJFH{S}, DataLayouts.IJHF{S}, DataLayouts.VIJFH{S}, DataLayouts.VIJHF{S}},
    topology::Topology2D,
    local_geometry::Union{DataLayouts.IJFH, DataLayouts.IJHF, DataLayouts.VIJFH, DataLayouts.VIJHF, Nothing} = nothing,
    local_weights::Union{DataLayouts.IJFH, DataLayouts.IJHF, DataLayouts.VIJFH, DataLayouts.VIJHF, Nothing} = nothing,
) where {S}

Creates a DSSBuffer for the field data corresponding to data

source
ClimaCore.Topologies.DSSBufferType
DSSBuffer{G, D, A, B}

Fields

  • graph_context: ClimaComms graph context for communication
  • perimeter_data: Perimeter DataLayout object: typically a VIFH{TT,Nv,Np,Nh} or VIHF{TT,Nv,Np,Nh}, where TT is the transformed type, Nv is the number of vertical levels, and Np is the length of the perimeter
  • send_date: send buffer AbstractVector{FT}
  • recv_data: recv buffer AbstractVector{FT}
  • send_buf_idx: indexing array for loading send buffer from perimeter_data
  • recv_buf_idx: indexing array for loading (and summing) data from recv buffer to
  • internal_elems: internal local elements (lidx)
  • perimeter_elems: local elements (lidx) located on process boundary
source
ClimaCore.Topologies.load_from_recv_buffer!Function
load_from_recv_buffer!(::ClimaComms.AbstractCPUDevice, dss_buffer::DSSBuffer)

Adds data from the recv buffer to the corresponding location in perimeter_data. For ghost vertices, this data is added only to the representative vertices. The values are then scattered to other local vertices corresponding to each unique ghost vertex in dss_local_ghost.

Part of ClimaCore.Spaces.weighted_dss!.

source
ClimaCore.Spaces.weighted_dss_start!Function
weighted_dss_start!(
    data::Union{
        DataLayouts.IFH,
        DataLayouts.IHF,
        DataLayouts.VIFH,
        DataLayouts.VIHF,
        DataLayouts.IJFH,
        DataLayouts.IJHF,
        DataLayouts.VIJFH,
        DataLayouts.VIJHF,
    },
    space::Union{
        AbstractSpectralElementSpace,
        ExtrudedFiniteDifferenceSpace,
    },
    dss_buffer::Union{DSSBuffer, Nothing},
)

It comprises of the following steps:

1). Apply Spaces.dss_transform! on perimeter elements. This weights and tranforms vector fields to physical basis if needed. Scalar fields are weighted. The transformed and/or weighted perimeter data is stored in perimeter_data.

2). Apply Spaces.dss_local_ghost! This computes partial weighted DSS on ghost vertices, using only the information from local vertices.

3). Spaces.fill_send_buffer! Loads the send buffer from perimeter_data. For unique ghost vertices, only data from the representative ghost vertices which store result of "ghost local" DSS are loaded.

4). Start DSS communication with neighboring processes

source
ClimaCore.Spaces.weighted_dss_internal!Function
weighted_dss_internal!(
    data::Union{
        DataLayouts.IFH,
        DataLayouts.IHF,
        DataLayouts.VIFH,
        DataLayouts.VIHF,
        DataLayouts.IJFH,
        DataLayouts.IJHF,
        DataLayouts.VIJFH,
        DataLayouts.VIJHF,
    },
    space::Union{
        AbstractSpectralElementSpace,
        ExtrudedFiniteDifferenceSpace,
    },
    dss_buffer::DSSBuffer,
)

1). Apply Spaces.dss_transform! on interior elements. Local elements are split into interior and perimeter elements to facilitate overlapping of communication with computation.

2). Probe communication

3). Spaces.dss_local! computes the weighted DSS on local vertices and faces.

source
ClimaCore.Spaces.weighted_dss_ghost!Function
weighted_dss_ghost!(
    data::Union{
        DataLayouts.IFH,
        DataLayouts.IHF,
        DataLayouts.VIFH,
        DataLayouts.VIHF,
        DataLayouts.IJFH,
        DataLayouts.IJHF,
        DataLayouts.VIJFH,
        DataLayouts.VIJHF,
    },
    space::Union{
        AbstractSpectralElementSpace,
        ExtrudedFiniteDifferenceSpace,
    },
    dss_buffer::Union{DSSBuffer, Nothing},
)

1). Finish communications.

2). Call Spaces.load_from_recv_buffer! After the communication is complete, this adds data from the recv buffer to the corresponding location in perimeter_data. For ghost vertices, this data is added only to the representative vertices. The values are then scattered to other local vertices corresponding to each unique ghost vertex in dss_local_ghost.

3). Call Spaces.dss_untransform! on all local elements. This transforms the DSS'd local vectors back to Covariant12 vectors, and copies the DSS'd data from the perimeter_data to data.

source
ClimaCore.Spaces.weighted_dss!Function
function weighted_dss!(
    data::Union{
        DataLayouts.IFH,
        DataLayouts.IHF,
        DataLayouts.VIFH,
        DataLayouts.VIHF,
        DataLayouts.IJFH,
        DataLayouts.IJHF,
        DataLayouts.VIJFH,
        DataLayouts.VIJHF,
    },
    space::Union{
        AbstractSpectralElementSpace,
        ExtrudedFiniteDifferenceSpace,
    },
    dss_buffer::Union{DSSBuffer, Nothing},
)

Computes weighted dss of data.

It comprises of the following steps:

1). Spaces.weighted_dss_start!

2). Spaces.weighted_dss_internal!

3). Spaces.weighted_dss_ghost!

source
Spaces.weighted_dss!(fv::FieldVector, dss_buffer = Spaces.create_dss_buffer(fv))

Apply weighted direct stiffness summation (DSS) to each field in fv. If a dss_buffer object is not provided, a buffer will be created for each field in fv. Note that using the Pair interface here parallelizes the weighted_dss! calls.

source
Spaces.weighted_dss!(f::Field, dss_buffer = Spaces.create_dss_buffer(field))

Apply weighted direct stiffness summation (DSS) to f. This operates in-place (i.e. it modifies the f). ghost_buffer contains the necessary information for communication in a distributed setting, see Spaces.create_dss_buffer.

This is a projection operation from the piecewise polynomial space $\mathcal{V}_0$ to the continuous space $\mathcal{V}_1 = \mathcal{V}_0 \cap \mathcal{C}_0$, defined as the field $\theta \in \mathcal{V}_1$ such that for all $\phi \in \mathcal{V}_1$

\[\int_\Omega \phi \theta \,d\Omega = \int_\Omega \phi f \,d\Omega\]

In matrix form, we define $\bar \theta$ to be the unique global node representation, and $Q$ to be the "scatter" operator which maps to the redundant node representation $\theta$

\[\theta = Q \bar \theta\]

Then the problem can be written as

\[(Q \bar\phi)^\top W J Q \bar\theta = (Q \bar\phi)^\top W J f\]

which reduces to

\[\theta = Q \bar\theta = Q (Q^\top W J Q)^{-1} Q^\top W J f\]

source
Spaces.weighted_dss!(field1 => ghost_buffer1, field2 => ghost_buffer2, ...)

Call Spaces.weighted_dss! on multiple fields at once, overlapping communication as much as possible.

source
ClimaCore.Spaces.unique_nodesFunction
unique_nodes(space::SpectralElementSpace2D)

An iterator over the unique nodes of space. Each node is represented by the first ((i,j), e) triple.

This function is experimental, and may change in future.

source

Utilities

ClimaCore.Spaces.areaFunction
Spaces.area(space::Spaces.AbstractSpace)

The length/area/volume of space. This is computed as the sum of the quadrature weights $W_i$ multiplied by the Jacobian determinants $J_i$:

\[\sum_i W_i J_i \approx \int_\Omega \, d \Omega\]

If space is distributed, this uses a ClimaComms.allreduce operation.

source

RecursiveApply

ClimaCore.RecursiveApplyModule
RecursiveApply

This module contains operators to recurse over nested Tuples or NamedTuples.

To extend to another type T, define RecursiveApply.rmap(fn, args::T...)

source

Fields

Base.zerosMethod
zeros(space::AbstractSpace)

Construct a field on space that is zero everywhere.

source
Base.onesMethod
ones(space::AbstractSpace)

Construct a field on space that is one everywhere.

source
Base.sumMethod
sum([f=identity,] v::Field)

Approximate integration of v or f.(v) over the domain. In an AbstractSpectralElementSpace, an integral over the entire space is computed by summation over the elements of the integrand multiplied by the Jacobian determinants and the quadrature weights at each node within an element. Hence, sum is computed by summation of the field values multiplied by the Jacobian determinants and quadrature weights:

\[\sum_i f(v_i) W_i J_i \approx \int_\Omega f(v) \, d \Omega\]

where $v_i$ is the value at each node, and $f$ is the identity function if not specified.

If v is a distributed field, this uses a ClimaComms.allreduce operation.

source
ClimaCore.Fields.local_sumFunction
Fields.local_sum(v::Field)

Compute the approximate integral of v over the domain local to the current context.

See sum for the integral over the full domain.

source
Statistics.meanMethod
mean([f=identity, ]v::Field)

The mean value of field or f.(field) over the domain, weighted by area. Similar to sum, in an AbstractSpectralElementSpace, this is computed by summation of the field values multiplied by the Jacobian determinants and quadrature weights:

\[\frac{\sum_i f(v_i) W_i J_i}{\sum_i W_i J_i} \approx \frac{\int_\Omega f(v) \, d \Omega}{\int_\Omega \, d \Omega}\]

where $v_i$ is the Field value at each node, and $f$ is the identity function if not specified.

If v is a distributed field, this uses a ClimaComms.allreduce operation.

source
LinearAlgebra.normMethod
norm(v::Field, p=2; normalize=true)

The approximate $L^p$ norm of v, where $L^p$ represents the space of measurable functions for which the p-th power of the absolute value is Lebesgue integrable, that is:

\[\| v \|_p = \left( \int_\Omega |v|^p d \Omega \right)^{1/p}\]

where $|v|$ is defined to be the absolute value if $v$ is a scalar-valued Field, or the 2-norm if it is a vector-valued Field or composite Field (see LinearAlgebra.norm). Similar to sum and mean, in an AbstractSpectralElementSpace, this is computed by summation of the field values multiplied by the Jacobian determinants and quadrature weights. If normalize=true (the default), then internally the discrete norm is divided by the sum of the Jacobian determinants and quadrature weights:

\[\left(\frac{\sum_i |v_i|^p W_i J_i}{\sum_i W_i J_i}\right)^{1/p} \approx \left(\frac{\int_\Omega |v|^p \, d \Omega}{\int_\Omega \, d \Omega}\right)^{1/p}\]

If p=Inf, then the norm is the maximum of the absolute values

\[\max_i |v_i| \approx \sup_{\Omega} |v|\]

Consequently all norms should have the same units for all $p$ (being the same as calling norm on a single value).

If normalize=false, then the denominator term is omitted, and so the result will be the norm as described above multiplied by the length/area/volume of $\Omega$ to the power of $1/p$.

source
ClimaCore.Fields.set!Function
set!(f::Function, field::Field, args = ())

Apply function f to populate values in field field. f must have a function signature with signature f(::LocalGeometry[, args...]). Additional arguments may be passed to f with args.

source
ClimaCore.Grids.ColumnIndexType
ColumnIndex(ij,h)

An index into a column of a field. This can be used as an argument to getindex of a Field, to return a field on that column.

Example

colidx = ColumnIndex((1,1),1)
field[colidx]
source
ClimaCore.Fields.bycolumnFunction
Fields.bycolumn(fn, space)

Call fn(colidx) to every ColumnIndex colidx of space. This can be used to apply multiple column-wise operations in a single pass, making use of multiple threads.

Note

On GPUs this will simply evaluate f once with colidx=: (i.e. it doesn't perform evaluation by columns). This may change in future.

Example

∇ = GradientF2C()
div = DivergenceC2F()

bycolumn(axes(f)) do colidx
    @. ∇f[colidx] = ∇(f[colidx])
    @. df[colidx] = div(∇f[colidx])
end
source
ClimaCore.Fields.Δz_fieldFunction
Δz_field(field::Field)
Δz_field(space::AbstractSpace)

A Field containing the Δz values on the same space as the given field.

source

Hypsography

ClimaCore.Hypsography.SLEVEAdaptionType
SLEVEAdaption(surface::Field, ηₕ::FT, s::FT)

Locate vertical levels using an exponential function between the surface field and the top of the domain, using the method of [13]. This method is modified such no warping is applied above some user defined parameter 0 ≤ ηₕ < 1.0, where the lower and upper bounds represent the domain bottom and top respectively. s governs the decay rate. If the decay-scale is poorly specified (i.e., s * zₜ is lower than the maximum surface elevation), a warning is thrown and s is adjusted such that it szₜ > maximum(z_surface).

source
ClimaCore.Hypsography.diffuse_surface_elevation!Function
diffuse_surface_elevation!(f::Field; κ::T, iter::Int, dt::T)

Option for 2nd order diffusive smoothing of generated terrain. Mutate (smooth) a given elevation profile f before assigning the surface elevation to the HypsographyAdaption type. A spectral second-order diffusion operator is applied with forward-Euler updates to generate profiles for each new iteration. Steps to generate smoothed terrain ( represented as a ClimaCore Field) are as follows:

  • Compute discrete elevation profile f
  • Compute diffusesurfaceelevation!(f, κ, iter). f is mutated.
  • Define Hypsography.LinearAdaption(f)
  • Define ExtrudedFiniteDifferenceSpace with new surface elevation.

Default diffusion parameters are appropriate for spherical arrangements. For zmax-zsfc == 𝒪(10^4), κ == 𝒪(10^8), dt == 𝒪(10⁻¹).

source
ClimaCore.Hypsography.ref_z_to_physical_zFunction
ref_z_to_physical_z(adaption::HypsographyAdaption, z_ref::ZPoint, z_surface::ZPoint, z_top::ZPoint) :: ZPoint

Convert reference zs to physical zs as prescribed by the given adaption.

This function has to be the inverse of physical_z_to_ref_z.

source

Limiters

The limiters supertype is

This class of flux-limiters is applied only in the horizontal direction (on spectral advection operators).

Interfaces

ClimaCore.Limiters.QuasiMonotoneLimiterType
QuasiMonotoneLimiter

This limiter is inspired by the one presented in Guba et al [14]. In the reference paper, it is denoted by OP1, and is outlined in eqs. (37)-(40). Quasimonotone here is meant to be monotone with respect to the spectral element nodal values. This limiter involves solving a constrained optimization problem (a weighted least square problem up to a fixed tolerance) that is completely local to each element.

As in HOMME, the implementation idea here is the following: we need to find a grid field which is closest to the initial field (in terms of weighted sum), but satisfies the min/max constraints. So, first we find values that do not satisfy constraints and bring these values to a closest constraint. This way we introduce some change in the tracer mass, which we then redistribute so that the l2 error is smallest. This redistribution might violate constraints; thus, we do a few iterations (until abs(Δtracer_mass) <= rtol * tracer_mass).

  • ρq: tracer density Field, where q denotes tracer concentration per unit mass. This can be a scalar field, or a struct-valued field.
  • ρ: fluid density Field (scalar).

Constructor

limiter = QuasiMonotoneLimiter(ρq::Field; rtol = eps(eltype(parent(ρq))))

Creates a limiter instance for the field ρq with relative tolerance rtol.

Usage

Call compute_bounds! on the input fields:

compute_bounds!(limiter, ρq, ρ)

Then call apply_limiter! on the output fields:

apply_limiter!(ρq, ρ, limiter)
source
ClimaCore.Limiters.apply_limiter!Function
apply_limiter!(ρq, ρ, limiter::QuasiMonotoneLimiter)

Apply the limiter on the tracer density ρq, using the computed desired bounds on the concentration q and density ρ as an optimal weight. This iterates over each element, calling apply_limit_slab!. If the limiter fails to converge for any element, a warning is issued.

source

Internals

ClimaCore.Limiters.apply_limit_slab!Function
apply_limit_slab!(slab_ρq, slab_ρ, slab_WJ, slab_q_bounds, rtol)

Apply the computed bounds of the tracer concentration (slab_q_bounds) in the limiter to slab_ρq, given the total mass slab_ρ, metric terms slab_WJ, and relative tolerance rtol. Return whether the tolerance condition could be satisfied.

source

InputOutput

Writers

ClimaCore.InputOutput.HDF5WriterType
HDF5Writer(filename::AbstractString[, context::ClimaComms.AbstractCommsContext];
           overwrite::Bool = true)

An AbstractWriter for writing to HDF5-formatted files using the ClimaCore storage conventions. An internal cache is used to avoid writing duplicate domains, meshes, topologies and spaces to the file. Use HDF5Reader to load the data from the file.

The optional context can be used for writing distributed fields: in this case, the MPICommsContext used passed as an argument: this must match the context used for distributing the Field.

The writer overwrites or appends to existing files depending on the value of the overwrite keyword argument. When overwrite is false, the writer appends to filename if the file already exists, otherwise it creates a new one.

Note

The default Julia HDF5 binaries are not built with MPI support. To use the distributed functionality, you will need to configure HDF5.jl with an MPI-enabled HDF5 library, see the HDF5.jl documentation.

Interface

write!

Usage

writer = InputOutput.HDF5Writer(filename)
InputOutput.write!(writer, Y, "Y")
close(writer)
source
ClimaCore.InputOutput.write!Function
write!(writer::AbstractWriter, obj[, preferredname])

Write the object obj using writer. An optional preferredname can be provided, otherwise defaultname will be used to generate a name. The name of the object will be returned.

A cache of domains, meshes, topologies and spaces is kept: if one of these objects has already been written, then the file will not be modified: instead the name under which the object was first written will be returned. Note that Fields and FieldVectors are not cached, and so can be written multiple times.

source
write!(writer::HDF5Writer, name => value...)

Write one or more name => value pairs to writer.

source
write!(filename::AbstractString, name => value...)

Write one or more name => value pairs to the HDF5 file filename.

source

Readers

ClimaCore.InputOutput.HDF5ReaderType
HDF5Reader(filename::AbstractString[, context::ClimaComms.AbstractCommsContext])

An AbstractReader for reading from HDF5 files created by HDF5Writer. The reader object contains an internal cache of domains, meshes, topologies and spaces that are read so that duplicate objects are not created.

The optional context can be used for reading distributed fields: in this case, the MPICommsContext used passed as an argument: resulting Fields will be distributed using this context. As with HDF5Writer, this requires a HDF5 library with MPI support.

Interface

Usage

reader = InputOutput.HDF5Reader(filename)
Y = read_field(reader, "Y")
Y.c |> propertynames
Y.f |> propertynames
ρ_field = read_field(reader, "Y.c.ρ")
w_field = read_field(reader, "Y.f.w")
close(reader)

To explore the contents of the reader, use either

julia> reader |> propertynames

e.g, to explore the components of the space,

julia> reader.space_cache
Dict{Any, Any} with 3 entries:
  "center_extruded_finite_difference_space" => CenterExtrudedFiniteDifferenceSpace:…
  "horizontal_space"                        => SpectralElementSpace2D:…
  "face_extruded_finite_difference_space"   => FaceExtrudedFiniteDifferenceSpace:…

Once "unpacked" as shown above, ClimaCorePlots or ClimaCoreMakie can be used to visualise fields. ClimaCoreTempestRemap supports interpolation onto user-specified grids if necessary.

source
ClimaCore.InputOutput.read_domainFunction
read_domain(reader::AbstractReader, name)

Reads a domain named name from reader. Domain objects are cached in the reader to avoid creating duplicate objects.

source
ClimaCore.InputOutput.read_fieldFunction
read_field(reader, name)

Reads a Field or FieldVector named name from reader. Fields are not cached, so that reading the same field multiple times will create multiple distinct objects.

source

Remapping

ClimaCore.Remapping.interpolate_arrayFunction
interpolate_array(field, xpts, ypts)
interpolate_array(field, xpts, ypts, zpts)

Interpolate a field to a regular array using pointwise interpolation.

This is primarily used for plotting and diagnostics.

Examples

longpts = range(Geometry.LongPoint(-180.0), Geometry.LongPoint(180.0), length = 21)
latpts = range(Geometry.LatPoint(-80.0), Geometry.LatPoint(80.0), length = 21)
zpts = range(Geometry.ZPoint(0.0), Geometry.ZPoint(1000.0), length = 21)

interpolate_array(field, longpts, latpts, zpts)
Note

Hypsography is not currently handled correctly.

source
ClimaCore.Remapping.interpolateFunction

interpolate(remapper::Remapper, fields) interpolate!(dest, remapper::Remapper, fields)

Interpolate the given field(s) as prescribed by remapper.

The optimal number of fields passed is the buffer_length of the remapper. If more fields are passed, the remapper will batch work with size up to its buffer_length.

This call mutates the internal (private) state of the remapper.

Horizontally, interpolation is performed with the barycentric formula in [11], equation (3.2). Vertical interpolation is linear except in the boundary elements where it is 0th order.

interpolate! writes the output to the given destiniation. dest is expected to be defined on the root process and to be nothing for the other processes.

Note: interpolate allocates new arrays and has some internal type-instability, interpolate! is non-allocating and type-stable.

When using interpolate!, the destination has to be the same array type as the device in use (e.g., CuArray for CUDA runs).

Example

Given field1,field2, two Field defined on a cubed sphere.

longpts = range(-180.0, 180.0, 21)
latpts = range(-80.0, 80.0, 21)
zpts = range(0.0, 1000.0, 21)

hcoords = [Geometry.LatLongPoint(lat, long) for long in longpts, lat in latpts]
zcoords = [Geometry.ZPoint(z) for z in zpts]

space = axes(field1)

remapper = Remapper(space, hcoords, zcoords)

int1 = interpolate(remapper, field1)
int2 = interpolate(remapper, field2)

# Or
int12 = interpolate(remapper, [field1, field2])
# With int1 = int12[1, :, :, :]
source
   interpolate(field::ClimaCore.Fields, target_hcoords, target_zcoords)

Interpolate the given fields on the Cartesian product of target_hcoords with target_zcoords (if not empty).

Coordinates have to be ClimaCore.Geometry.Points.

Note: do not use this method when performance is important. Instead, define a Remapper and call interpolate(remapper, fields). Different Fields defined on the same Space can share a Remapper, so that interpolation can be optimized.

Example

Given field, a Field defined on a cubed sphere.

longpts = range(-180.0, 180.0, 21)
latpts = range(-80.0, 80.0, 21)
zpts = range(0.0, 1000.0, 21)

hcoords = [Geometry.LatLongPoint(lat, long) for long in longpts, lat in latpts]
zcoords = [Geometry.ZPoint(z) for z in zpts]

interpolate(field, hcoords, zcoords)
source