ScalarField#

class fridom.framework.scalar_field.ScalarField(mset: fr.ModelSettingsBase, mdata: fr.FieldMetadata | None = None, arr: ndarray | None = None, **kwargs: any)[source]#

Bases: FieldBase

A scalar mapping from grid space to real / complex numbers.

Description#

A scalar field is the most basic field in FRIDOM. It is a mapping from the grid space to real or complex numbers. It is used to represent scalar quantities like pressure, temperature, etc. Essentially, a scalar field is wrapper around a numpy-like array with additional metadata and methods.

Parameters#

msetfr.ModelSettingsBase

The model settings object.

mdatafr.FieldMetadata, optional

The metadata object for the field. If not provided, a new one is created.

arrndarray, optional

The underlying array of the field. If not provided, a new array is created.

__init__(mset: fr.ModelSettingsBase, mdata: fr.FieldMetadata | None = None, arr: ndarray | None = None, **kwargs: any) None[source]#

Methods

__init__(mset[, mdata, arr])

abs()

Map the field by taking the absolute value (\(|f|\)).

apply_water_mask()

Apply a water mask to the field.

conj()

Compute the complex conjugate.

cumulative_integral(axis[, direction])

Compute the cumulative integral along an axis.

diff(axis[, order])

Compute the partial derivative along an axis.

div([axes])

Compute the divergence.

dot(other)

Compute the dot product with another field.

extend(topo)

Extend the field in the specified directions.

fft([padding])

Perform a Fast Fourier Transform (FFT) on the field.

from_netcdf(mset, path)

Create a field from a NetCDF file.

from_xarray(mset, ds)

Create a field from an xarray object.

get_mesh()

Get the meshgrid of the ScalarField.

grad([axes])

Compute the gradient.

has_nan()

Check if the field contains NaN values.

ifft([padding])

Perform an Inverse Fast Fourier Transform (IFFT) on the field.

integrate([axes])

Global integral of the Field in specified axes.

interpolate(destination)

Interpolate the field to the destination position.

laplacian([axes])

Compute the Laplacian.

max([axes])

Maximum value of the Field over the whole domain.

mean([axes])

Global mean of the Field in specified axes.

min([axes])

Minimum value of the Field over the whole domain.

norm_l2()

Calculate the L2 norm of the field.

set_random([seed])

Set the field to random values.

sum([axes])

Sum of the Field over the whole domain in the specified axes.

sync()

Synchronize the field across all MPI ranks and apply boundary conditions.

to_netcdf(path)

Save the field to a NetCDF file.

unpad()

Remove padding from the Scalar Field.

Attributes

arr

The underlying array.

bc_types

The boundary condition types for the ScalarField.

flags

Dictionary with flag options for the ScalarField.

grid

The grid object.

info

Dictionary with information about the field.

is_constant

Flag indicating whether the field is constant.

is_spectral

True if the ScalarField is in spectral space.

long_name

The long name of the ScalarField.

mdata

The metadata of the ScalarField.

mset

The model settings.

name

The name of the ScalarField.

nc_attrs

Dictionary with additional attributes for the NetCDF file or xarray.

position

The position of the ScalarField on the staggered grid.

topo

Topology of the ScalarField.

units

The unit of the ScalarField.

value

The value of the constant ScalarField.

xr

The xarray representation of the field.

xrs

Convert a slice of the field to an xarray object.

fft(padding: FFTPadding = FFTPadding.NOPADDING) ScalarField[source]#

Perform a Fast Fourier Transform (FFT) on the field.

Description#

Computes the Fast Fourier Transform (FFT) of the field. The padding parameter can be used to specify the zero-padding strategy.

Parameters#

paddingfr.grid.FFTPadding

The padding strategy.

Returns#

FieldBase

The FFT of the field.

ifft(padding: FFTPadding = FFTPadding.NOPADDING) ScalarField[source]#

Perform an Inverse Fast Fourier Transform (IFFT) on the field.

Description#

Computes the Inverse Fast Fourier Transform (IFFT) of the field. The padding parameter can be used to specify the zero-padding strategy.

Parameters#

paddingfr.grid.FFTPadding

The padding strategy.

Returns#

FieldBase

The IFFT of the field.

sync() ScalarField[source]#

Synchronize the field across all MPI ranks and apply boundary conditions.

Description#

This method synchronizes the field across all MPI ranks and applies the boundary conditions. This is necessary to ensure that the ghost cells are up-to-date. This method changes the field in-place, but also returns the synchronized field.

Returns#

FieldBase

The synchronized field.

apply_water_mask() ScalarField[source]#

Apply a water mask to the field.

Description#

A water mask is a binary field that indicates which cells are water (active) and which are land (inactive). This method applies the water mask to the field. The field is changed in-place.

Returns#

FieldBase

The field with the water mask applied.

has_nan() bool[source]#

Check if the field contains NaN values.

Returns#

bool

Flag indicating whether the field contains NaN values.

set_random(seed: int = 1234) ScalarField[source]#

Set the field to random values.

Description#

This method sets the field to random values. If the field is in spectral space, the random values are complex.

Parameters#

seedint

The seed for the random number generator.

Returns#

FieldBase

The field with random values.

unpad() ndarray[source]#

Remove padding from the Scalar Field.

Returns#

ndarray

The unpadded array.

get_mesh() tuple[ndarray][source]#

Get the meshgrid of the ScalarField.

Description#

This method returns the meshgrid of the ScalarField. It returns a tuple of ndarrays, where each ndarray represents the meshgrid in one direction. For example, a 3D field that is extended in x, z but not in y would return a tuple of 2 ndarrays (x, z).

Returns#

tuple[ndarray]

The meshgrid of the ScalarField for each direction that is extended.

interpolate(destination: Position) ScalarField[source]#

Interpolate the field to the destination position.

Parameters#

destinationfr.grid.Position

The position to interpolate to.

Returns#

ScalarField

The interpolated field.

diff(axis: int, order: int = 1) ScalarField[source]#

Compute the partial derivative along an axis.

\[\partial_i^n f\]

with axis \(i\) and order \(n\).

Parameters#

axisint

The axis along which to differentiate.

orderint

The order of the derivative. Default is 1.

Returns#

fr.ScalarField | fr.VectorField | fr.TensorField

The derivative of the field along the specified axis.

grad(axes: list[int] | None = None) VectorField[source]#

Compute the gradient.

\[\begin{split}\nabla f = \begin{pmatrix} \partial_1 f \\ \dots \\ \partial_n f \end{pmatrix}\end{split}\]

Parameters#

axeslist[int] | None (default is None)

The axes along which to compute the gradient. If None, the gradient is computed along all axes.

Returns#

fr.VectorField | fr.TensorField

The gradient of the field along the specified axes. The list contains the gradient components along each axis. Axis which are not included in axes will have a value of None. E.g. for a 3D grid, diff.grad(f, axes=[0, 2]) will return [df/dx, None, df/dz].

laplacian(axes: tuple[int] | None = None) ScalarField[source]#

Compute the Laplacian.

\[\nabla^2 f = \sum_{i=1}^n \partial_i^2 f\]

Parameters#

axestuple[int] | None (default is None)

The axes along which to compute the Laplacian. If None, the Laplacian is computed along all axes.

Returns#

fr.ScalarField | fr.VectorField | fr.TensorField

The Laplacian of the field.

div(axes: list[int] | None = None) None[source]#

Compute the divergence.

\[\nabla \cdot f = \sum_{i=1}^n \partial_i f\]

Returns#

fr.ScalarField | fr.VectorField

The divergence of the field.

cumulative_integral(axis: int, direction: Literal['forward', 'backward'] = 'forward') ScalarField[source]#

Compute the cumulative integral along an axis.

Description#

The cumulative integral computes the integral starting at one end of the domain and accumulates the integral along the specified axis. The integral is computed in either the forward or backward direction.

Forward integral:

\[\int_{x_0}^{x} f(x') dx'\]

with axis \(x\) and \(x_0\) the lower bound of the domain.

Backward integral:

\[\int_{x}^{x_1} f(x') dx'\]

with axis \(x\) and \(x_1\) the upper bound of the domain.

Parameters#

axisint

The axis along which to integrate.

directionstr (default is “forward”)

The direction of the integration. Can be “forward” or “backward”.

Returns#

fr.ScalarField | fr.VectorField | fr.TensorField

The cumulative integral of the field along the specified axis.

property xr: xr.DataArray#

The xarray representation of the field.

Returns#

xr.DataArray | xr.Dataset

The xarray representation of the field.

property xrs: fr.utils.SliceableAttribute[xr.DataArray]#

Convert a slice of the field to an xarray object.

Description#

This method returns a sliceable attribute that allows to convert a slice of the field to an xarray object. This is useful when dealing with large fields and only a subset of the data is needed. For example, the top region of the field.

classmethod from_xarray(mset: fr.ModelSettingsBase, ds: xr.DataArray) ScalarField[source]#

Create a field from an xarray object.

Description#

This method creates a field from an xarray object. The model settings are required to create the field.

Parameters#

msetfr.ModelSettingsBase

The model settings.

dsxr.DataArray | xr.Dataset

The xarray object.

Returns#

FieldBase

The field.

classmethod from_netcdf(mset: ModelSettingsBase, path: str) ScalarField[source]#

Create a field from a NetCDF file.

Parameters#

msetfr.ModelSettingsBase

The model settings.

pathstr

The path to the NetCDF file.

Returns#

FieldBase

The field.

property value: complex | float#

The value of the constant ScalarField.

Description#

This property returns the value of a constant ScalarField. Constant means that the ScalarField has no extension in any direction. If the ScalarField is not constant, a ValueError is raised.

Returns#

complex | float

The value of the constant ScalarField.

Raises#

ValueError

If the ScalarField is not constant.

property info: dict#

Dictionary with information about the field.

property arr: ndarray#

The underlying array.

property mdata: FieldMetadata#

The metadata of the ScalarField.

property name: str#

The name of the ScalarField.

property long_name: str#

The long name of the ScalarField.

property units: str#

The unit of the ScalarField.

property nc_attrs: dict#

Dictionary with additional attributes for the NetCDF file or xarray.

property is_spectral: bool#

True if the ScalarField is in spectral space.

property topo: tuple[bool]#

Topology of the ScalarField.

Description#

Scalar fields do not have to be extended in all directions. For example, one might want to create a 2D forcing field for a 3D simulation, that only depends on x and y. In this case, the topo of the ScalarField would be (True, True, False).

property is_constant: bool#

Flag indicating whether the field is constant.

property position: Position#

The position of the ScalarField on the staggered grid.

property bc_types: tuple[BCType] | None#

The boundary condition types for the ScalarField.

property flags: dict#

Dictionary with flag options for the ScalarField.

extend(topo: tuple[bool]) ScalarField[source]#

Extend the field in the specified directions.

Description#

This method extends the field in the specified directions. The field can be extended in any direction, but it cannot be shrunk. This means that if the field is extended in a direction, it has to be extended in all directions. Values in the extended directions are copied from the original field, such that:

\[f_{\text{new}}(x, y, z) = f_{\text{old}}(x, y)\]

where \(f_{\text{new}}\) is the new field extended in (x, y, z), and \(f_{\text{old}}\) is the old field, extended in (x, y).

Parameters#

topotuple[bool]

The new topology of the field.

Returns#

FieldBase

The extended field.

Raises#

ValueError

If the field is shrunk in any direction.

sum(axes: tuple[int] | None = None) ScalarField[source]#

Sum of the Field over the whole domain in the specified axes.

Description#

This method computes the sum of the Field over the whole domain (across all processes) in the specified axes. If no axes are specified, the sum is computed over all axes.

Note

We recommend using the f.integrate() method to integrate the field in certain directions. The integrate() method takes the grid spacing into account while the sum() method does not.

Parameters#

axestuple[int] | None

The axes to sum over. If None, sum over all axes.

Returns#

FieldBase

The sum of the field. The returned field has no extend in the specified axes.

max(axes: tuple[int] | None = None) ScalarField[source]#

Maximum value of the Field over the whole domain.

Description#

This method computes the maximum value of the Field over the whole domain (across all processes) in the specified axes. If no axes are specified, the maximum is computed over all axes.

Parameters#

axestuple[int] | None

The axes to compute the maximum over. If None, compute the maximum over all axes.

Returns#

FieldBase

The maximum value of the Field over the specified axes. The returned field has no extend in the specified axes.

min(axes: tuple[int] | None = None) ScalarField[source]#

Minimum value of the Field over the whole domain.

Description#

This method computes the minimum value of the Field over the whole domain (across all processes) in the specified axes. If no axes are specified, the minimum is computed over all axes.

Parameters#

axestuple[int] | None

The axes to compute the minimum over. If None, compute the minimum over all axes.

Returns#

FieldBase

The minimum value of the Field over the specified axes. The returned field has no extend in the specified axes.

integrate(axes: tuple[int] | None = None) ScalarField[source]#

Global integral of the Field in specified axes.

Description#

Computes the global integral of the Field in the specified axes:

\[\sum_{i} \int_{x_i} f(\boldsymbol{x}) dx_i\]

If no axes are specified, the integral is computed over all axes.

Parameters#

axestuple[int] | None

The axes to integrate over. If None, integrate over all axes.

Returns#

FieldBase

The integral of the Field over the specified axes.

mean(axes: tuple[int] | None = None) ScalarField[source]#

Global mean of the Field in specified axes.

Description#

Computes the global mean of the Field in the specified axes:

\[\frac{\sum_{i} \int_{x_i} f(\boldsymbol{x}) dx_i} {\sum_{i} \int_{x_i} dx_i}\]

If no axes are specified, the mean is computed over all axes.

Parameters#

axestuple[int] | None

The axes to compute the mean over. If None, compute the mean over all axes.

Returns#

FieldBase

The mean of the Field over the specified axes.

abs() ScalarField[source]#

Map the field by taking the absolute value (\(|f|\)).

Returns#

FieldBase

The absolute value of the field.

dot(other: ScalarField | VectorField | TensorField) ScalarField | VectorField | TensorField[source]#

Compute the dot product with another field.

Parameters#

otherFieldBase

The other field.

Returns#

FieldBase

The dot product.

Description#

Computes the dot product with another field. The dot product is defined as

\[f \cdot g^*\]

where \(f\) and \(g\) are the fields and \(^*\) denotes the complex conjugate.

The return value depends on the type of the fields. The following table shows the possible return values:

Field Type

Field Type

Return Type

ScalarField

ScalarField

ScalarField

ScalarField

VectorField

VectorField

ScalarField

TensorField

TensorField

VectorField

ScalarField

VectorField

VectorField

VectorField

ScalarField

VectorField

TensorField

Error

TensorField

ScalarField

TensorField

TensorField

VectorField

VectorField

TensorField

TensorField

TensorField

conj() ScalarField[source]#

Compute the complex conjugate.

Returns#

FieldBase

The complex conjugate. If the field is real, the field itself is returned.