Skip to content

Lorenz-96

Lorenz-96 on a ring of sites around a latitude circle.

  • Class: Lorenz96System
  • Import: from skcomplex.systems.physics.climate import Lorenz96System
  • Field: physics/climate
  • Topics: chaos, ode, atmosphere, spatiotemporal chaos, data assimilation
  • References: Lorenz 1996; Datseris and Parlitz 2022

Use this system

from skcomplex.core.engine.runtime import simulate
from skcomplex.systems.physics.climate import Lorenz96System

trajectory = simulate(Lorenz96System())

Parameters

Parameter Default
n_sites 20
F 8.0
perturbation 0.01

Tags

Tag Values
Time continuous
Space continuous
Laws rate
Randomness deterministic
Domains vector
Structure fixed

Class

class Lorenz96System(BaseSystem):
    """Lorenz-96 on a ring of sites around a latitude circle.

    Every site follows `dx_i/dt = (x_{i+1} - x_{i-2}) x_{i-1} - x_i + F`.

    The sites start at the steady state `F`, and the first one is displaced by `perturbation`. For `F = 8` the steady
    state is unstable and the ring is chaotic. The system has the values `ring.x` of all sites.

    Args:
        n_sites:
            The number of sites, at least 4, the dimension of the state `x`.

        F:
            The constant forcing.

        perturbation:
            The displacement of the first site from the steady state.

        label:
            The label of the system, which names it when it is nested in another one.

    Examples:
        >>> from skcomplex.systems.physics.climate import Lorenz96System
        >>> Lorenz96System(6).prepare().system_.space.n_dim
        6
    """

    field = 'physics/climate'
    topics = ('chaos', 'ode', 'atmosphere', 'spatiotemporal chaos', 'data assimilation')
    references = ('Lorenz 1996', 'Datseris and Parlitz 2022')
    until = 20.0
    dt = 0.05

    def __init__(
        self,
        n_sites: int = 20,
        *,
        F: float = 8.0,
        perturbation: float = 0.01,
        label: str = 'system',
    ) -> None:
        super().__init__(label)
        self.n_sites = n_sites
        self.F = F
        self.perturbation = perturbation

    def _build_system(self) -> System:
        """Return the parts of the system, built from its model parameters."""
        values = np.full(self.n_sites, float(self.F))
        values[0] += self.perturbation
        return System(
            self.label,
            elements=[Lorenz96Element('ring', x=values, F=self.F)],
            space=ContinuousSpace(n_dim=self.n_sites),
        )

Components

Elements:

  • Lorenz96Element, from Element
class Lorenz96Element(Element):
    """Ring of Lorenz-96 sites around a latitude circle.

    The sites are advected by their neighbours, damped, and forced.

    Every site follows `dx_i/dt = (x_{i+1} - x_{i-2}) x_{i-1} - x_i + F`, with the indices taken around the ring.

    Args:
        label:
            The label of the ring.

        visual:
            How the element is drawn, or `None` for `default_visual_`.

        x:
            The initial values of all sites.

        F:
            The constant forcing.

    Examples:
        >>> from skcomplex.systems.physics.climate import Lorenz96Element
        >>> Lorenz96Element('ring').F
        8.0
    """

    law_classes = (RateLaw,)

    def __init__(
        self,
        label: str,
        visual: VisualSpec | None = None,
        *,
        x: Annotated[npt.ArrayLike, StateSpec(vector=True)] = 8.0,
        F: Annotated[float, ParameterSpec()] = 8.0,
    ) -> None:
        super().__init__(label, visual=visual)
        self.x = x
        self.F = F

    def _get_laws(self, s: SimpleNamespace) -> list[BaseLaw]:
        """Return the advection, damping, and forcing of every site of the ring.

        Args:
            s:
                The namespace of the symbols the laws can use.

        Returns:
            laws:
                The rate law of the values of all sites.
        """
        x = s.x
        n_sites = len(x)
        rates = [(x[(i + 1) % n_sites] - x[i - 2]) * x[i - 1] - x[i] + s.F for i in range(n_sites)]
        return [RateLaw(s.x, vector(SR, rates))]