Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for field_to_array and array_to_field #1765

Closed
charleskawczynski opened this issue May 31, 2024 · 1 comment
Closed

Add support for field_to_array and array_to_field #1765

charleskawczynski opened this issue May 31, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@charleskawczynski
Copy link
Member

From ClimaAtmos:

"""
    field2array(field)

Extracts a view of a `ClimaCore` `Field`'s underlying array. Can be used to
simplify the process of getting and setting values in an `RRTMGPModel`; e.g.
model.center_temperature .= field2array(center_temperature_field)
field2array(face_flux_field) .= model.face_flux

The dimensions of the resulting array are `([number of vertical nodes], number
of horizontal nodes)`. Also, `field` must be a `Field` of scalars, so that the
element type of the array is the same as the struct type of `field`.
"""
function field2array(field::Fields.Field)
    if sizeof(eltype(field)) != sizeof(eltype(parent(field)))
        f_axis_size = sizeof(eltype(parent(field))) ÷ sizeof(eltype(field))
        error("unable to use field2array because each Field element is \
               represented by $f_axis_size array elements (must be 1)")
    end
    return data2array(Fields.field_values(field))
end
data2array(data::Union{DataLayouts.IF, DataLayouts.IFH}) =
    reshape(parent(data), :)
data2array(data::Union{DataLayouts.IJF, DataLayouts.IJFH}) =
    reshape(parent(data), :)
data2array(data::Union{DataLayouts.VF, DataLayouts.VIFH, DataLayouts.VIJFH}) =
    reshape(parent(data), size(parent(data), 1), :)

"""
    array2field(array, space)

Wraps `array` in a `ClimaCore` `Field` that is defined over `space`. Can be used
to simplify the process of getting and setting values in an `RRTMGPModel`; e.g.
array2field(model.center_temperature, center_space) .=
    center_temperature_field
face_flux_field .= array2field(model.face_flux, face_space)

The dimensions of `array` are assumed to be `([number of vertical nodes], number
of horizontal nodes)`. Also, `array` must represent a `Field` of scalars, so
that the struct type of the resulting `Field` is the same as the element type of
`array`. If this restriction were removed, one would also need to pass the
desired `Field` struct type as an argument to `array2field`, which would then
need to permute the dimensions of `array` to match the target `DataLayout`.
"""
array2field(array, space) =
    Fields.Field(array2data(array, Spaces.local_geometry_data(space)), space)
array2data(
    array::AbstractArray{T, 1},
    ::DataLayouts.IF{<:Any, Ni},
) where {T, Ni} = DataLayouts.IF{T, Ni}(reshape(array, Ni, 1))
array2data(
    array::AbstractArray{T, 1},
    ::DataLayouts.IFH{<:Any, Ni},
) where {T, Ni} = DataLayouts.IFH{T, Ni}(reshape(array, Ni, 1, :))
array2data(
    array::AbstractArray{T, 1},
    ::DataLayouts.IJF{<:Any, Nij},
) where {T, Nij} = DataLayouts.IJF{T, Nij}(reshape(array, Nij, Nij, 1))
array2data(
    array::AbstractArray{T, 1},
    ::DataLayouts.IJFH{<:Any, Nij},
) where {T, Nij} = DataLayouts.IJFH{T, Nij}(reshape(array, Nij, Nij, 1, :))
array2data(
    array::AbstractArray{T, 2},
    ::DataLayouts.VF{<:Any, Nv},
) where {T, Nv} = DataLayouts.VF{T, Nv}(reshape(array, size(array, 1), 1))
array2data(
    array::AbstractArray{T, 2},
    ::DataLayouts.VIFH{<:Any, Nv, Ni},
) where {T, Nv, Ni} =
    DataLayouts.VIFH{T, Nv, Ni}(reshape(array, size(array, 1), Ni, 1, :))
array2data(
    array::AbstractArray{T, 2},
    ::DataLayouts.VIJFH{<:Any, Nv, Nij},
) where {T, Nv, Nij} = DataLayouts.VIJFH{T, Nv, Nij}(
    reshape(array, size(array, 1), Nij, Nij, 1, :),
)
@charleskawczynski charleskawczynski added the enhancement New feature or request label May 31, 2024
@Sbozzolo
Copy link
Member

Sbozzolo commented Jun 1, 2024

Closed by #1768 #1770

@Sbozzolo Sbozzolo closed this as completed Jun 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants