Fields

ClimaCore.Fields.FieldType
Field(values::DataLayout, space::AbstractSpace)
Field(T::Type, space::AbstractSpace)

Field of values defined at each point of space. The second form allocates an uninitialized field with element type T on space.

Fields

  • values: The DataLayout holding the field values.
  • space: The AbstractSpace on which the field is defined; returned by axes.
source
ClimaCore.Fields.FieldVectorType
FieldVector{T, M} <: BlockArrays.AbstractBlockVector{T}

Wrapper around one or more Fields that acts like a vector of the underlying arrays. Unlike a plain concatenation of the underlying arrays, its components can be referred to by name.

Constructor

FieldVector(; name1 = field1, name2 = field2, ...)

Construct a FieldVector wrapping field1, field2, ... under the names name1, name2, .... Real components are wrapped in a ScalarWrapper and NamedTuple components become nested FieldVectors (see Fields.wrap). The element type T is the promotion of the component element types.

source
ClimaCore.Fields.coordinate_fieldFunction
coordinate_field(space::AbstractSpace)
coordinate_field(field::Field)

Return the coordinates of space (or of the space of field) as a Field. The result shares the coordinate data of the space; no copy is made.

source
ClimaCore.Fields.local_geometry_fieldFunction
local_geometry_field(space::AbstractSpace)
local_geometry_field(field::Field)

Return the LocalGeometry of space (or of the space of field) as a Field. The result shares the local geometry data of the space; no copy is made.

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)

Compute the mean of v or f.(v) over the domain, weighted by area. As for 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)

Compute the approximate $L^p$ norm of v, where $L^p$ is 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). As for 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), 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, the norm is the maximum of the absolute values,

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

so that the norm has the same units for all $p$, namely those of norm of a single value.

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

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

Populate field with the values of f, which is called as f(::LocalGeometry, args...) at every point. Returns nothing.

Examples

using ClimaCore.Fields
using ClimaCore.CommonSpaces
ᶜspace = ExtrudedCubedSphereSpace(Float64;
    z_elem = 10,
    z_min = 0,
    z_max = 1,
    radius = 10,
    h_elem = 10,
    n_quad_points = 4,
    staggering = CellCenter(),
)
x = Fields.Field(Float64, ᶜspace)
Fields.set!(x) do lg
    sin(lg.coordinates.z)
end
source
ClimaCore.Fields.bycolumnFunction
Fields.bycolumn(fn, space)

Call fn(colidx) for every ColumnIndex colidx of space. This can be used to apply multiple column-wise operations in a single pass, using multiple threads on a CPUMultiThreaded device. Returns nothing.

Note

On GPUs this evaluates fn once with colidx = :, without iterating over columns. This may change in future.

Examples

∇ = 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)

Return a Field on space (or on the space of field) containing the vertical extent Δz of each cell [m]. The result shares the geometry data of the space.

source
Base.zerosMethod
zeros(space::AbstractSpace)
zeros(FT::Type, space::AbstractSpace)

Create a new field on space that is zero everywhere, with element type FT (default: the float type of space). Unlike fill, this also zeroes data at masked-out points, so that the field contains no uninitialized values.

source
Base.onesMethod
ones(space::AbstractSpace)
ones(FT::Type, space::AbstractSpace)

Create a new field on space that is one everywhere, with element type FT (default: the float type of space). Masked-out points are set as well.

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

Compute the approximate integral 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 the sum 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

Accessing the data

ClimaCore.Fields.field_valuesFunction
Fields.field_values(field::Field)

The DataLayouts.DataLayout holding the values of field, without the space. For a broadcasted expression over fields, return the corresponding broadcasted expression over their DataLayouts.

source
ClimaCore.Fields.field_vector_valuesFunction
Fields.field_vector_values(fv::FieldVector)

Return the NamedTuple of the top-level values of fv, keyed by the names passed to the constructor. Fields and nested FieldVectors are returned as stored; scalar components are returned as their ScalarWrapper (use getproperty to unwrap them).

source
ClimaCore.Fields.componentFunction
Fields.component(field::Field, i::Integer)

Return the ith scalar component of field, whose element type must be a Geometry.Tensor (a vector or higher-order tensor), as a Fields.Field on the same space that shares memory with field. Components are numbered in the column-major order of the tensor components, so for a vector i is the index of the basis vector, and for a 2-tensor i runs down the columns of the matrix. Equivalent to the property chain field.components.data.:(i).

Example

u₁ = Fields.component(uₕ, 1)  # first covariant component of a Covariant12Vector field
source

Slicing

level, slab, and column are defined at the top level of ClimaCore and apply to fields, spaces, and data layouts alike. Columns may also be addressed by a Grids.ColumnIndex instead of the standard (i, j, h) tuple.

ClimaCore.levelFunction
level(data, v)

Return a horizontal view of data at level v, spanning all elements in that level.

source
ClimaCore.slabFunction
slab(data, v, h)
slab(data, h)

Return a horizontal view of data at level v and horizontal element h. If v is omitted, it is assumed to be 1.

source
ClimaCore.columnFunction
column(data, i, j, h)
column(data, i, h)

Return a vertical view of data at nodal point index (i, j) of horizontal element h. If j is omitted, it is assumed to be 1.

source

Iterating over a FieldVector

ClimaCore.Fields.field_iteratorFunction
field_iterator(::Union{Field, FieldVector})

Return an iterator over the scalar fields of f, found by recursively calling getproperty for all propertynames. Each item is a Tuple of

  • the individual scalar field, with Covariant12Vector and Covariant3Vector fields converted to UVVector and WVector fields, and
  • the property chain used to reach it.
source
ClimaCore.Fields.property_chainsFunction
property_chains(f::Union{Field, FieldVector})

Return an array of the "property chains" of f: the tuples of property names that getproperty follows recursively until a single scalar field is reached.

A property chain may be, for example, (:model, :submodel, :temperature), where model.submodel.temperature is a scalar field.

source
ClimaCore.Fields.single_fieldFunction
Fields.single_field(f::Union{Field, FieldVector}, prop_chain, transform = transform_field)

Return the field reached from f by following the property chain prop_chain (a tuple of symbols or integers, e.g. (:c, :uₕ, :components, :data, 1)), applying transform at each step. The default transform_field converts covariant vector fields to UVVector/WVector fields for output and leaves other fields unchanged; pass identity to skip the conversion.

source
ClimaCore.Fields.rcompareFunction
rcompare(x::T, y::T; strict = true) where {T <: Union{FieldVector, NamedTuple}}

Recursively compare x and y via ==; return true if all components are equal.

With strict = true, the types must match as well, and FieldVectors or NamedTuples of different types compare unequal. With strict = false, rcompare returns true for FieldVectors and NamedTuples with the same properties in permuted order. For example:

  • rcompare((; a = 1, b = 2), (; b = 2, a = 1); strict = true) returns false.
  • rcompare((; a = 1, b = 2), (; b = 2, a = 1); strict = false) returns true.
source
ClimaCore.Fields.@rprint_diffMacro
@rprint_diff x y

Recursively print the differences between x and y, which are FieldVectors or NamedTuples of the same type, to stdout.

source

Field types

Type aliases naming the field that corresponds to each space, for dispatch.

Conversion to arrays

ClimaCore.Fields.field2arrayFunction
field2array(field)

Return a view of the underlying array of field. Used to get and set values of external models that store their state in plain arrays, e.g. an RRTMGPModel:

center_temperature .= field2array(center_temperature_field)
field2array(face_flux_field) .= face_flux

The dimensions of the resulting array are (number of vertical nodes, number of horizontal nodes), with the first dimension dropped for fields on horizontal spaces. Only fields of scalars are supported: the element type of field must be the element type of its parent array.

source
ClimaCore.Fields.array2fieldFunction
array2field(array, space)

Wrap array in a Field defined over space, without copying. The element type of the resulting Field is the element type of array. Used to get and set values of external models that store their state in plain arrays, e.g. an RRTMGPModel:

array2field(center_temperature, center_space) .= center_temperature_field
face_flux_field .= array2field(model.face_flux, face_space)
source
ClimaCore.Fields.fieldvector2array!Function
fieldvector2array!(array, fv)

Copy the entries of the FieldVector fv into the flat AbstractVector array of the same length, without allocating or scalar indexing: each component block is copied with a single array-level copyto!, so FieldVectors backed by GPU arrays are supported (including mixed cases, where array and some components live on different devices). Entries are ordered as in the FieldVector's own linear indexing: component blocks in order, each in the linear order of its backing array.

Scalar (ScalarWrapper) components are written to array with a fill! on a one-element view, which is GPU-safe.

Intended for interfacing with libraries that operate on flat vectors, such as the Krylov.jl workspace vectors given by Krylov.ktypeof(::FieldVector) (see KrylovExt). See array2fieldvector! for the inverse copy and fieldvector2array for an allocating version.

source
ClimaCore.Fields.array2fieldvector!Function
array2fieldvector!(fv, array)

Copy the entries of the flat AbstractVector array into the FieldVector fv of the same length — the inverse of fieldvector2array!, with the same entry ordering, allocation-free block-wise copies, and GPU support.

Copying a scalar (ScalarWrapper) component out of array requires a scalar read, so scalar components are only supported when array is a CPU array (a GPU-backed array throws a scalar-indexing error rather than performing a hidden synchronizing transfer).

See array2fieldvector for an allocating version.

source