Source code for fields.mixins.base

"""
Core mixin classes for the central
field classes.
"""
from typing import TYPE_CHECKING, Any, Generic, Iterable, Optional, Type, TypeVar

from pymetric.fields.components import FieldComponent
from pymetric.fields.utils.utilities import validate_rank_signature

# =============================== #
# Configure Typing                #
# =============================== #
# This section of the module supports typing
# hints and protocols for static type checking.
if TYPE_CHECKING:
    # noinspection PyUnresolvedReferences
    from pymetric.fields.utils._typing import (
        ComponentDictionary,
        ComponentIndex,
        SignatureInput,
    )

    from ._typing import (
        _SupportsDFieldCore,
        _SupportsDTFieldCore,
        _SupportsFieldCore,
        _SupportsSFieldCore,
    )

_SupFieldCore = TypeVar("_SupFieldCore", bound="_SupportsFieldCore")
_SupSFieldCore = TypeVar("_SupSFieldCore", bound="_SupportsSFieldCore")
_SupDFieldCore = TypeVar("_SupDFieldCore", bound="_SupportsDFieldCore")
_SupDTFieldCore = TypeVar("_SupDTFieldCore", bound="_SupportsDTFieldCore")


# =============================== #
# Mixin Classes                   #
# =============================== #
[docs] class FieldCoreMixin(Generic[_SupFieldCore]): """ Core mixin methods for the :class:`~fields.base.Field` class. """ # --- Utility Methods --- # # These are simple utility methods for use # when performing various checks.
[docs] def validate_components(self, components: "ComponentDictionary") -> None: """ Validate all components in a dictionary for consistency with the field. Parameters ---------- components : dict A dictionary mapping component indices to FieldComponent instances. Raises ------ TypeError, ValueError If any component is invalid or inconsistent with the field’s grid. """ for index, component in components.items(): self.validate_component(index, component)
[docs] def validate_component( self: _SupFieldCore, index: "ComponentIndex", component: Any ) -> None: """ Validate a single field component and its index. Checks that: - the component is a FieldComponent, - the component’s grid matches the field’s grid, - the index is of the correct type (int or tuple of ints). Parameters ---------- index : int or tuple of int The index key for the component in the field. component : Any The component object to validate. Raises ------ TypeError If the component is not a FieldComponent or index is not valid. ValueError If the component uses a different grid or index format is incorrect. """ if not isinstance(component, FieldComponent): raise TypeError( f"Component {index!r} is not a FieldComponent (got {type(component).__name__})." ) if component.grid is not self.__grid__: raise ValueError( f"Component {index!r} uses a different grid (got {component.grid!r}, " f"expected {self.__grid__!r})." ) # Ensure the index is valid if isinstance(index, tuple): if not all(isinstance(i, int) for i in index): raise TypeError( f"Component index {index!r} must be a tuple of integers, " f"but got invalid entries: {index}." ) elif not isinstance(index, int): raise TypeError( f"Component index {index!r} must be an int or tuple of ints." )
[docs] class SFieldCoreMixin(Generic[_SupSFieldCore]): """ Core mixin methods for the :class:`~fields.base.SparseField` class. """ # ========================== # # Utility Methods: Access # # ========================== # # Simple methods to allow various access patterns # for elements in the SparseFields.
[docs] def items(self: _SupSFieldCore) -> Iterable: """ Return a view of (index, component) pairs in the field. This is equivalent to calling `.items()` on the underlying component dictionary. Returns ------- ItemsView A view over the field’s component index-value pairs. """ return self.__components__.items()
[docs] def keys(self: _SupSFieldCore) -> Iterable: """ Return a view of the component indices in the field. This is equivalent to calling `.keys()` on the underlying component dictionary. Returns ------- KeysView A view over the field’s component indices. """ return self.__components__.keys()
[docs] def values(self: _SupSFieldCore) -> Iterable: """ Return a view of the field components. This is equivalent to calling `.values()` on the underlying component dictionary. Returns ------- ValuesView A view over the field’s components. """ return self.__components__.values()
[docs] class DFieldCoreMixin(Generic[_SupDFieldCore]): """ Core mixin methods for the :class:`~fields.base.DenseField` class. """ # ============================= # # Data Access Methods # # ============================= # # These methods provide entry points for getting data from # FieldComponents.
[docs] def as_array(self: _SupDFieldCore): """ Return the underlying buffer as a NumPy array. This method extracts the field's raw data buffer and returns it as a standard NumPy array. This strips any associated units or metadata. Returns ------- np.ndarray The raw array representing the field's data. """ return self.__component__.buffer.as_array()
[docs] def as_unyt_array(self: _SupDFieldCore): """ Return the underlying buffer as a unyt array with units. This method extracts the field's data buffer and returns it as a `unyt.unyt_array`, preserving physical units and dimensionality. Returns ------- unyt.unyt_array The unit-aware array representing the field's data. """ return self.component.buffer.as_unyt_array()
# ============================= # # Generator Methods # # ============================= # # These methods provide entry points for creating # FieldComponents. @classmethod def _wrap_comp_from_op( cls: Type[_SupDFieldCore], operation: str, *args, **kwargs ) -> "_SupDFieldCore": """ Apply an operation from `FieldComponent` and wrap the result in the current class. This method takes the name of an operation (as a string) or a direct reference to a method defined in the `FieldComponent` class, applies it to the provided arguments, and wraps the resulting `FieldComponent` instance in a new instance of `cls`. Parameters ---------- operation : str or callable The name of a method defined in `FieldComponent` or a callable method itself. *args : tuple Positional arguments to pass to the operation. **kwargs : dict Keyword arguments to pass to the operation. Returns ------- cls A new instance of the calling class (`cls`), wrapping the result of the operation. Raises ------ ValueError If the operation is not a valid attribute of `FieldComponent`. Examples -------- >>> MyFieldClass._wrap_comp_from_op("some_operation", arg1, arg2, kwarg1=value) """ try: operation_fn = getattr(FieldComponent, operation) except AttributeError: raise ValueError( f"Operation {operation!r} is not a valid operation of FieldComponent" ) c = operation_fn(*args, **kwargs) return cls(c.grid, c) # noinspection PyIncorrectDocstring
[docs] @classmethod def from_function(cls: Type[_SupDFieldCore], *args, **kwargs) -> _SupDFieldCore: """ Construct a :class:`~fields.components.FieldComponent` by evaluating a function on the grid. This method evaluates a coordinate-dependent function `func` over a physical coordinate mesh generated from `grid` along the specified `axes`. It is useful for initializing field data from analytic expressions. Parameters ---------- func : callable A function that takes coordinate arrays (one per axis) and returns an array of values with shape `(*grid_shape, *result_shape)`, matching the evaluated field. grid : ~grids.base.GridBase The grid over which to evaluate the function. axes : list of str Coordinate axes along which the field is defined. *args : Additional arguments forwarded to the buffer constructor (e.g., dtype). result_shape : tuple of int, optional Shape of trailing element-wise structure (e.g., for vectors/tensors). Defaults to scalar `()`. buffer_class : str or ~fields.buffers.base.BufferBase, optional The buffer backend used to hold data. buffer_registry : ~fields.buffers.registry.BufferRegistry, optional Registry used to resolve buffer class strings. buffer_kwargs : dict, optional Extra keyword arguments passed to the buffer constructor (e.g., units). **kwargs : Additional keyword arguments forwarded to the function `func`. Returns ------- FieldComponent A new field component with data populated from `func`. Raises ------ ValueError If the output shape of `func` does not match the expected field shape. """ return cls._wrap_comp_from_op("from_function", *args, **kwargs)
# noinspection PyIncorrectDocstring
[docs] @classmethod def from_array(cls: Type[_SupDFieldCore], *args, **kwargs) -> _SupDFieldCore: """ Construct a :class:`~fields.components.FieldComponent` from an existing array-like object. This method creates a :class:`~fields.components.FieldComponent` by wrapping a NumPy array, unyt array, or similar backend-supported array in a compatible buffer. The shape of the input array must match the combined spatial and element-wise shape implied by `grid` and `axes`. Parameters ---------- array_like : array-like The array to wrap. This can be a :class:`numpy.ndarray`, :class:`unyt.unyt_array`, or other compatible type. grid : ~grids.base.GridBase The grid over which the field is defined. axes : list of str The spatial axes of the coordinate system over which the array is defined. The shape of the array must begin with the grid shape corresponding to these axes. buffer_class : str or ~fields.buffers.base.BufferBase, optional The buffer class to use for wrapping the data. This can be a class or string identifier. If not provided, defaults to `ArrayBuffer`. buffer_registry : ~fields.buffers.registry.BufferRegistry, optional Custom registry to use for resolving string buffer types. *args, **kwargs : Additional keyword arguments forwarded to the buffer constructor (e.g., `units` if supported). Returns ------- FieldComponent A new component wrapping the given array. Raises ------ ValueError If the input array shape is incompatible with the grid and axes. """ return cls._wrap_comp_from_op("from_array", *args, **kwargs)
# noinspection PyIncorrectDocstring
[docs] @classmethod def zeros(cls: Type[_SupDFieldCore], *args, **kwargs) -> _SupDFieldCore: """ Create a dense field filled with zeros. This is a convenience constructor that builds a zero-initialized :class:`~fields.components.FieldComponent` using the provided grid and axes, then wraps it in a :class:`~fields.base.DenseField`. Parameters ---------- grid : ~grids.base.GridBase The structured grid over which the field is defined. axes : list of str The spatial axes of the underlying coordinate system over which the field is defined. This must be some subset of the axes available in the coordinate system of `grid`. *args : Additional positional arguments forwarded to the buffer constructor. The specific available args will depend on ``buffer_class`` and ``buffer_registry``. element_shape : tuple of int, optional Shape of the element-wise data structure (e.g., vector or tensor dimensions). This does **not** include the spatial shape, which is fixed by the grid. The resulting buffer will have an overall shape of ``(*spatial_shape, *element_shape)``. buffer_class : str or ~fields.buffers.base.BufferBase, optional The buffer class to use for holding the data. This may be specified as a string, in which case the ``buffer_registry`` is queried for a matching class or it may be a specific buffer class. The relevant ``*args`` and ``**kwargs`` arguments will be passed underlying buffer class's ``.zeros()`` method. buffer_registry : ~fields.buffer.registry.BufferRegistry, optional Custom registry to use for resolving buffer class strings. By default, the standard registry is used. **kwargs : Additional keyword arguments forwarded to the buffer constructor (e.g., `dtype`, `units`). Returns ------- ~fields.base.DenseField A new field object filled with zeros and defined over the specified grid and axes. """ # Start with generation of the component so that # it can be wrapped. return cls._wrap_comp_from_op("zeros", *args, **kwargs)
# noinspection PyIncorrectDocstring
[docs] @classmethod def ones(cls: Type[_SupDFieldCore], *args, **kwargs) -> _SupDFieldCore: """ Create a dense field filled with ones. This is a convenience constructor that builds a ones-initialized :class:`~fields.components.FieldComponent` using the provided grid and axes, then wraps it in a :class:`~fields.base.DenseField`. Parameters ---------- grid : ~grids.base.GridBase The structured grid over which the field is defined. axes : list of str The spatial axes of the underlying coordinate system over which the field is defined. This must be some subset of the axes available in the coordinate system of `grid`. *args : Additional positional arguments forwarded to the buffer constructor. The specific available args will depend on ``buffer_class`` and ``buffer_registry``. element_shape : tuple of int, optional Shape of the element-wise data structure (e.g., vector or tensor dimensions). This does **not** include the spatial shape, which is fixed by the grid. The resulting buffer will have an overall shape of ``(*spatial_shape, *element_shape)``. buffer_class : str or ~fields.buffers.base.BufferBase, optional The buffer class to use for holding the data. This may be specified as a string, in which case the ``buffer_registry`` is queried for a matching class or it may be a specific buffer class. The relevant ``*args`` and ``**kwargs`` arguments will be passed underlying buffer class's ``.ones()`` method. buffer_registry : ~fields.buffer.registry.BufferRegistry, optional Custom registry to use for resolving buffer class strings. By default, the standard registry is used. **kwargs : Additional keyword arguments forwarded to the buffer constructor (e.g., `dtype`, `units`). Returns ------- ~fields.base.DenseField A new field object filled with ones and defined over the specified grid and axes. """ # Start with generation of the component so that # it can be wrapped. return cls._wrap_comp_from_op("ones", *args, **kwargs)
# noinspection PyIncorrectDocstring
[docs] @classmethod def full(cls: Type[_SupDFieldCore], *args, **kwargs) -> _SupDFieldCore: """ Create a dense field filled with a fill value. This is a convenience constructor that builds a :class:`~fields.components.FieldComponent` using the provided grid and axes, then wraps it in a :class:`~fields.base.DenseField`. Parameters ---------- grid : ~grids.base.GridBase The structured grid over which the field is defined. axes : list of str The spatial axes of the underlying coordinate system over which the field is defined. This must be some subset of the axes available in the coordinate system of `grid`. *args : Additional positional arguments forwarded to the buffer constructor. The specific available args will depend on ``buffer_class`` and ``buffer_registry``. element_shape : tuple of int, optional Shape of the element-wise data structure (e.g., vector or tensor dimensions). This does **not** include the spatial shape, which is fixed by the grid. The resulting buffer will have an overall shape of ``(*spatial_shape, *element_shape)``. buffer_class : str or ~fields.buffers.base.BufferBase, optional The buffer class to use for holding the data. This may be specified as a string, in which case the ``buffer_registry`` is queried for a matching class or it may be a specific buffer class. The relevant ``*args`` and ``**kwargs`` arguments will be passed underlying buffer class's ``.full()`` method. buffer_registry : ~fields.buffer.registry.BufferRegistry, optional Custom registry to use for resolving buffer class strings. By default, the standard registry is used. **kwargs : Additional keyword arguments forwarded to the buffer constructor (e.g., `dtype`, `units`). Returns ------- ~fields.base.DenseField A new field object filled with `fill_value` and defined over the specified grid and axes. """ # Start with generation of the component so that # it can be wrapped. return cls._wrap_comp_from_op("full", *args, **kwargs)
[docs] @classmethod def zeros_like( cls: Type[_SupDFieldCore], other: Type[_SupDFieldCore], *args, **kwargs ) -> _SupDFieldCore: """ Create a zero-filled component with the same grid, axes, and element shape as another. Parameters ---------- other : ~fields.base.DenseField The reference component whose layout is used. *args, **kwargs: Forwarded to the :meth:`zeros` constructor. Returns ------- ~fields.base.DenseField A new component with the same layout as `other` and zero-initialized data. """ # Extract the other's grid, axes, and shape. grid, axes, shape = other.grid, other.axes, other.element_shape return cls.zeros(grid, axes, *args, element_shape=shape, **kwargs)
[docs] @classmethod def ones_like( cls: Type[_SupDFieldCore], other: Type[_SupDFieldCore], *args, **kwargs ) -> _SupDFieldCore: """ Create a one-filled component with the same grid, axes, and element shape as another. Parameters ---------- other : ~fields.base.DenseField The reference component whose layout is used. *args, **kwargs: Forwarded to the :meth:`ones` constructor. Returns ------- ~fields.base.DenseField A new component with the same layout as `other` and one-initialized data. """ # Extract the other's grid, axes, and shape. grid, axes, shape = other.grid, other.axes, other.element_shape return cls.ones(grid, axes, *args, element_shape=shape, **kwargs)
[docs] @classmethod def full_like( cls: Type[_SupDFieldCore], other: Type[_SupDFieldCore], *args, **kwargs ) -> _SupDFieldCore: """ Create a full-valued component with the same grid, axes, and element shape as another. Parameters ---------- other : ~fields.base.DenseField The reference component whose layout is used. *args, **kwargs: Forwarded to the :meth:`full` constructor. Returns ------- ~fields.base.DenseField A new component with the same layout as `other` and filled with a constant value. """ # Extract the other's grid, axes, and shape. grid, axes, shape = other.grid, other.axes, other.element_shape return cls.full(grid, axes, *args, element_shape=shape, **kwargs)
[docs] class DTensorFieldCoreMixin(DFieldCoreMixin, Generic[_SupDTFieldCore]): """ Core mixin methods for the :class:`~fields.tensors.DenseTensorField` class. """ # ============================= # # Generator Methods # # ============================= # # These methods provide entry points for creating # DenseTensorFields. # noinspection PyIncorrectDocstring
[docs] @classmethod def from_function( cls: Type[_SupDTFieldCore], *args, signature: Optional["SignatureInput"] = None, **kwargs, ) -> _SupDTFieldCore: """ Construct a :class:`~fields.components.FieldComponent` by evaluating a function on the grid. This method evaluates a coordinate-dependent function `func` over a physical coordinate mesh generated from `grid` along the specified `axes`. It is useful for initializing field data from analytic expressions. Parameters ---------- func : callable A function that takes coordinate arrays (one per axis) and returns an array of values with shape `(*grid_shape, *result_shape)`, matching the evaluated field. grid : ~grids.base.GridBase The grid over which to evaluate the function. axes : list of str Coordinate axes along which the field is defined. *args : Additional arguments forwarded to the buffer constructor (e.g., dtype). signature : int or list of int, optional The signature of the tensor field being generated. This should be a sequence of `1` and `-1` with `1` marking a contravariant index and `-1` a covariant index. The length must match that of `rank`. If not specified, `signature` defaults to a fully contravariant form. result_shape : tuple of int, optional Shape of trailing element-wise structure (e.g., for vectors/tensors). Defaults to scalar `()`. buffer_class : str or ~fields.buffers.base.BufferBase, optional The buffer backend used to hold data. buffer_registry : ~fields.buffers.registry.BufferRegistry, optional Registry used to resolve buffer class strings. buffer_kwargs : dict, optional Extra keyword arguments passed to the buffer constructor (e.g., units). **kwargs : Additional keyword arguments forwarded to the function `func`. Returns ------- FieldComponent A new field component with data populated from `func`. Raises ------ ValueError If the output shape of `func` does not match the expected field shape. """ # create the component vis-a-vis the lower level c = FieldComponent.from_function(*args, **kwargs) return cls(c.grid, c, signature=signature)
# noinspection PyIncorrectDocstring
[docs] @classmethod def from_array( cls: Type[_SupDTFieldCore], *args, signature: Optional["SignatureInput"] = None, **kwargs, ) -> _SupDTFieldCore: """ Construct a :class:`~fields.components.FieldComponent` from an existing array-like object. This method creates a :class:`~fields.components.FieldComponent` by wrapping a NumPy array, unyt array, or similar backend-supported array in a compatible buffer. The shape of the input array must match the combined spatial and element-wise shape implied by `grid` and `axes`. Parameters ---------- array_like : array-like The array to wrap. This can be a :class:`numpy.ndarray`, :class:`unyt.unyt_array`, or other compatible type. grid : ~grids.base.GridBase The grid over which the field is defined. axes : list of str The spatial axes of the coordinate system over which the array is defined. The shape of the array must begin with the grid shape corresponding to these axes. signature : int or list of int, optional The signature of the tensor field being generated. This should be a sequence of `1` and `-1` with `1` marking a contravariant index and `-1` a covariant index. The length must match that of `rank`. If not specified, `signature` defaults to a fully contravariant form. buffer_class : str or ~fields.buffers.base.BufferBase, optional The buffer class to use for wrapping the data. This can be a class or string identifier. If not provided, defaults to `ArrayBuffer`. buffer_registry : ~fields.buffers.registry.BufferRegistry, optional Custom registry to use for resolving string buffer types. **kwargs : Additional keyword arguments forwarded to the buffer constructor (e.g., `units` if supported). Returns ------- FieldComponent A new component wrapping the given array. Raises ------ ValueError If the input array shape is incompatible with the grid and axes. """ # create the component vis-a-vis the lower level c = FieldComponent.from_array(*args, **kwargs) return cls(c.grid, c, signature=signature)
# noinspection PyIncorrectDocstring
[docs] @classmethod def zeros( cls: Type[_SupDTFieldCore], *args, signature: Optional["SignatureInput"] = None, **kwargs, ) -> _SupDTFieldCore: """ Create a dense field filled with zeros. This is a convenience constructor that builds a zero-initialized :class:`~fields.components.FieldComponent` using the provided grid and axes, then wraps it in a :class:`~fields.base.DenseField`. Parameters ---------- grid : ~grids.base.GridBase The structured grid over which the field is defined. axes : list of str The spatial axes of the underlying coordinate system over which the field is defined. This must be some subset of the axes available in the coordinate system of `grid`. rank: int, optional The rank of the tensor field being generated. This can be supplemented by specifying the `signature` below to determine the variance of each rank index. *args : Additional positional arguments forwarded to the buffer constructor. The specific available args will depend on ``buffer_class`` and ``buffer_registry``. signature : int or list of int, optional The signature of the tensor field being generated. This should be a sequence of `1` and `-1` with `1` marking a contravariant index and `-1` a covariant index. The length must match that of `rank`. If not specified, `signature` defaults to a fully contravariant form. buffer_class : str or ~fields.buffers.base.BufferBase, optional The buffer class to use for holding the data. This may be specified as a string, in which case the ``buffer_registry`` is queried for a matching class or it may be a specific buffer class. The relevant ``*args`` and ``**kwargs`` arguments will be passed underlying buffer class's ``.zeros()`` method. buffer_registry : ~fields.buffer.registry.BufferRegistry, optional Custom registry to use for resolving buffer class strings. By default, the standard registry is used. **kwargs : Additional keyword arguments forwarded to the buffer constructor (e.g., `dtype`, `units`). Returns ------- ~fields.base.DenseField A new field object filled with zeros and defined over the specified grid and axes. """ # Validate the rank and the signature. grid, axes, rank, *xargs = args args = (grid, axes, *xargs) signature = validate_rank_signature(rank, signature=signature) # Fix the element shape element_shape = (grid.ndim,) * rank kwargs["element_shape"] = element_shape # create the component vis-a-vis the lower level c = FieldComponent.zeros(*args, **kwargs) return cls(grid, c, signature=signature)
# noinspection PyIncorrectDocstring
[docs] @classmethod def ones( cls: Type[_SupDTFieldCore], *args, signature: Optional["SignatureInput"] = None, **kwargs, ) -> _SupDTFieldCore: """ Create a dense field filled with ones. This is a convenience constructor that builds a ones-initialized :class:`~fields.components.FieldComponent` using the provided grid and axes, then wraps it in a :class:`~fields.base.DenseField`. Parameters ---------- grid : ~grids.base.GridBase The structured grid over which the field is defined. axes : list of str The spatial axes of the underlying coordinate system over which the field is defined. This must be some subset of the axes available in the coordinate system of `grid`. rank: int, optional The rank of the tensor field being generated. This can be supplemented by specifying the `signature` below to determine the variance of each rank index. *args : Additional positional arguments forwarded to the buffer constructor. The specific available args will depend on ``buffer_class`` and ``buffer_registry``. signature : int or list of int, optional The signature of the tensor field being generated. This should be a sequence of `1` and `-1` with `1` marking a contravariant index and `-1` a covariant index. The length must match that of `rank`. If not specified, `signature` defaults to a fully contravariant form. buffer_class : str or ~fields.buffers.base.BufferBase, optional The buffer class to use for holding the data. This may be specified as a string, in which case the ``buffer_registry`` is queried for a matching class or it may be a specific buffer class. The relevant ``*args`` and ``**kwargs`` arguments will be passed underlying buffer class's ``.ones()`` method. buffer_registry : ~fields.buffer.registry.BufferRegistry, optional Custom registry to use for resolving buffer class strings. By default, the standard registry is used. **kwargs : Additional keyword arguments forwarded to the buffer constructor (e.g., `dtype`, `units`). Returns ------- ~fields.base.DenseField A new field object filled with ones and defined over the specified grid and axes. """ # Validate the rank and the signature. grid, axes, rank, *xargs = args args = (grid, axes, *xargs) signature = validate_rank_signature(rank, signature=signature) # Fix the element shape element_shape = (grid.ndim,) * rank kwargs["element_shape"] = element_shape # create the component vis-a-vis the lower level c = FieldComponent.ones(*args, **kwargs) return cls(grid, c, signature=signature)
# noinspection PyIncorrectDocstring
[docs] @classmethod def full( cls: Type[_SupDTFieldCore], *args, signature: Optional["SignatureInput"] = None, **kwargs, ) -> _SupDTFieldCore: """ Create a dense field filled with a fill value. This is a convenience constructor that builds a :class:`~fields.components.FieldComponent` using the provided grid and axes, then wraps it in a :class:`~fields.base.DenseField`. Parameters ---------- grid : ~grids.base.GridBase The structured grid over which the field is defined. axes : list of str The spatial axes of the underlying coordinate system over which the field is defined. This must be some subset of the axes available in the coordinate system of `grid`. rank: int, optional The rank of the tensor field being generated. This can be supplemented by specifying the `signature` below to determine the variance of each rank index. *args : Additional positional arguments forwarded to the buffer constructor. The specific available args will depend on ``buffer_class`` and ``buffer_registry``. signature : int or list of int, optional The signature of the tensor field being generated. This should be a sequence of `1` and `-1` with `1` marking a contravariant index and `-1` a covariant index. The length must match that of `rank`. If not specified, `signature` defaults to a fully contravariant form. buffer_class : str or ~fields.buffers.base.BufferBase, optional The buffer class to use for holding the data. This may be specified as a string, in which case the ``buffer_registry`` is queried for a matching class or it may be a specific buffer class. The relevant ``*args`` and ``**kwargs`` arguments will be passed underlying buffer class's ``.full()`` method. buffer_registry : ~fields.buffer.registry.BufferRegistry, optional Custom registry to use for resolving buffer class strings. By default, the standard registry is used. **kwargs : Additional keyword arguments forwarded to the buffer constructor (e.g., `dtype`, `units`). Returns ------- ~fields.base.DenseField A new field object filled with `fill_value` and defined over the specified grid and axes. """ # Validate the rank and the signature. grid, axes, rank, *xargs = args args = (grid, axes, *xargs) signature = validate_rank_signature(rank, signature=signature) # Fix the element shape element_shape = (grid.ndim,) * rank kwargs["element_shape"] = element_shape # create the component vis-a-vis the lower level c = FieldComponent.full(*args, **kwargs) return cls(grid, c, signature=signature)
[docs] @classmethod def zeros_like( cls: Type[_SupDTFieldCore], other: Type[_SupDTFieldCore], *args, **kwargs ) -> _SupDTFieldCore: """ Create a zero-filled component with the same grid, axes, and element shape as another. Parameters ---------- other : ~fields.base.DenseField The reference component whose layout is used. *args, **kwargs: Forwarded to the :meth:`zeros` constructor. Returns ------- ~fields.base.DenseField A new component with the same layout as `other` and zero-initialized data. """ # Extract the other's grid, axes, and shape. grid, axes, rank, signature = ( other.grid, other.axes, other.rank, other.signature, ) return cls.zeros(grid, axes, rank, *args, signature=signature, **kwargs)
[docs] @classmethod def ones_like( cls: Type[_SupDTFieldCore], other: Type[_SupDTFieldCore], *args, **kwargs ) -> _SupDTFieldCore: """ Create a one-filled component with the same grid, axes, and element shape as another. Parameters ---------- other : ~fields.base.DenseField The reference component whose layout is used. *args, **kwargs: Forwarded to the :meth:`ones` constructor. Returns ------- ~fields.base.DenseField A new component with the same layout as `other` and one-initialized data. """ # Extract the other's grid, axes, and shape. grid, axes, rank, signature = ( other.grid, other.axes, other.rank, other.signature, ) return cls.ones(grid, axes, rank, *args, signature=signature, **kwargs)
[docs] @classmethod def full_like( cls: Type[_SupDTFieldCore], other: Type[_SupDTFieldCore], *args, **kwargs ) -> _SupDTFieldCore: """ Create a full-valued component with the same grid, axes, and element shape as another. Parameters ---------- other : ~fields.base.DenseField The reference component whose layout is used. *args, **kwargs: Forwarded to the :meth:`full` constructor. Returns ------- ~fields.base.DenseField A new component with the same layout as `other` and filled with a constant value. """ # Extract the other's grid, axes, and shape. grid, axes, rank, signature = ( other.grid, other.axes, other.rank, other.signature, ) return cls.full(grid, axes, rank, *args, signature=signature, **kwargs)