Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions climatecritters/core/forcing.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
f = seq.compile() # → Forcing

# Register with a model
model.register_forcing('S', f, attachment_style='additive', timing='pre')
cc.Model.register_forcing('S', f, attachment_style='additive', timing='pre')

# Superpose two indefinite signals
combined = cc.Forcing(orbital_func) + cc.Forcing(noise_func)
model.register_forcing('S0', combined)
cc.Model.register_forcing('S0', combined)
"""

from __future__ import annotations
Expand Down
6 changes: 3 additions & 3 deletions climatecritters/core/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def _format_value(v):
class Model:
"""The overarching model structure for ClimateCritters.

CCModel serves as the archetype/parent class for models within the
Model serves as the archetype/parent class for models within the
``model_critters`` directory. It is not meant to be instantiated directly.

Parameter handling
Expand Down Expand Up @@ -580,7 +580,7 @@ def sde_noise(self, t, y):

def integrate(self, t_span=None, y0=None, method='RK45', dt=None,
output_time=None, run_name=None, kwargs=None):
"""Integrate the model over a time span and return a :class:`CCOutput`.
"""Integrate the model over a time span and return an `Output`.

Parameters
----------
Expand Down Expand Up @@ -608,7 +608,7 @@ def integrate(self, t_span=None, y0=None, method='RK45', dt=None,
Fixed timestep for ``euler``, ``euler_maruyama``, ``heun_maruyama``,
``milstein``, and ``rk4``. Required for those methods.
output_time : array-like, optional
If provided, the returned ``CCOutput`` is immediately reframed onto
If provided, the returned ``Output`` is immediately reframed onto
this time axis (e.g. to exclude a spin-up period).
``output.model_time`` always retains the raw solver grid.
run_name : str, optional
Expand Down
6 changes: 3 additions & 3 deletions climatecritters/core/output.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""CCOutput — container for a single CCModel integration run.
"""Output — container for a single Model integration run.

Separating run output from model configuration lets the same model instance
be re-run with different parameters or initial conditions while keeping each
Expand All @@ -13,9 +13,9 @@


class Output:
"""Container for the results of one call to ``CCModel.integrate()``.
"""Container for the results of one call to ``Model.integrate()``.

``CCOutput`` carries the full trajectory produced by the solver and
``Output`` carries the full trajectory produced by the solver and
exposes output-focused operations (noise addition, pyleoclim export,
time resampling). Keeping these on the output rather than on the model
means a single model instance can produce multiple independent outputs
Expand Down
24 changes: 12 additions & 12 deletions climatecritters/model_critters/box_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

"""Generic box-model utilities for ClimateCritters.

This module provides a small declarative layer on top of :class:`CCModel` for
This module provides a small declarative layer on top of `Model` for
building simple ODE box models without writing a full bespoke subclass each
time.

Two styles are supported:

1. Explicit callable tendencies via :class:`BoxModelSpec.register_tendency`
1. Explicit callable tendencies via `BoxModelSpec.register_tendency`
2. Automatic box-network assembly via reciprocal exchange and directed
transport relations

Expand Down Expand Up @@ -87,7 +87,7 @@ class BoxModelContext:
The context exposes a compact, box-model-friendly API:

- ``ctx["A"]`` for direct state lookup
- ``ctx.param("k")`` for parameters resolved through ``CCModel.get_param``
- ``ctx.param("k")`` for parameters resolved through ``Model.get_param``
- ``ctx.input("R")`` for external prescribed inputs
- ``ctx.volume("SP")`` and ``ctx.concentration("SP")`` for box-network
models
Expand Down Expand Up @@ -128,7 +128,7 @@ class BoxModelSpec:
inputs, diagnostics, and either:

- explicit callable tendencies registered via
:meth:`register_tendency` / :meth:`register_relations`, or
`BoxModelSpec.register_tendency` / `BoxModelSpec.register_relations`, or
- an automatic box network assembled from volumes, reciprocal exchange,
and directed transport terms

Expand All @@ -140,13 +140,13 @@ class BoxModelSpec:

Notes
-----
Call :meth:`validate` (or :meth:`make_boxmodel`) before integrating.
Call `BoxModelSpec.validate` (or `make_boxmodel`) before integrating.
Validation checks that every state variable has a tendency relation
(explicit mode) or a registered volume (automatic mode).

See also
--------
GenericBoxModel : The ``CCModel`` subclass produced by :meth:`make_boxmodel`.
GenericBoxModel : The ``Model`` subclass produced by `make_boxmodel`.
BoxModelContext : Evaluation context passed to callable tendencies.

Examples
Expand Down Expand Up @@ -218,7 +218,7 @@ def register_parameters(self, **parameters):
"""Register default parameter values.

Values may be constants, callables, or ``Forcing``-like objects
compatible with ``CCModel.get_param``.
compatible with ``Model.get_param``.
"""
self.parameter_defaults.update(parameters)
return self
Expand Down Expand Up @@ -280,7 +280,7 @@ def register_input(self, name, fallback_param=None):
def register_tendency(self, state_variable, relation):
"""Register a callable tendency for one state variable.

``relation`` must accept a :class:`BoxModelContext` and return the
``relation`` must accept a `BoxModelContext` and return the
tendency for ``state_variable``.
"""
self.tendency_relations[str(state_variable)] = relation
Expand Down Expand Up @@ -376,7 +376,7 @@ def validate(self):
raise ValueError(f"Missing tendency relations for state variables: {missing}")

def make_model(self, var_name=None, **parameter_overrides):
"""Instantiate a :class:`GenericBoxModel` from this spec."""
"""Instantiate a `GenericBoxModel` from this spec."""
self.validate()
return GenericBoxModel(
self,
Expand All @@ -389,9 +389,9 @@ def make_boxmodel(self, var_name=None, **parameter_overrides):


class GenericBoxModel(Model):
"""``CCModel`` subclass produced by :class:`BoxModelSpec`.
"""``Model`` subclass produced by `BoxModelSpec`.

Users construct this via :meth:`BoxModelSpec.make_boxmodel` rather than
Users construct this via `make_boxmodel` rather than
instantiating it directly. The resulting model integrates with
``model.integrate(...)``, exports to Pyleoclim via ``output.to_pyleo()``,
and computes diagnostics from solved history via
Expand Down Expand Up @@ -427,7 +427,7 @@ def __init__(self, spec, var_name=None, *args, **kwargs):
setattr(self, name, value)

def uses_post_history(self):
"""Route diagnostics through CCModel's post-history hooks."""
"""Route diagnostics through Model's post-history hooks."""
return True

def resolve_input(self, name, t, state):
Expand Down
2 changes: 1 addition & 1 deletion climatecritters/model_critters/damped_spring.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def __init__(
self.params = ()

# ------------------------------------------------------------------
# CCModel interface
# Model interface
# ------------------------------------------------------------------

def uses_post_history(self):
Expand Down
18 changes: 9 additions & 9 deletions climatecritters/model_critters/ebm.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

# ---------------------------------------------------------------------------
# Module-level physics helpers
# All callables comply with the CCModel contract: (t), (t, state), or
# All callables comply with the Model contract: (t), (t, state), or
# (t, state, model) with the first positional arg named 't' or 'time'.
# ---------------------------------------------------------------------------

Expand Down Expand Up @@ -49,7 +49,7 @@ def OLR_func(pRad=650, ps=1000):
Returns
-------
func : callable
A ``(t, state)`` callable compliant with the CCModel parameter
A ``(t, state)`` callable compliant with the Model parameter
contract (see ``contracts/signal_model_contract.md``). Returns OLR
in W m⁻².
"""
Expand Down Expand Up @@ -93,7 +93,7 @@ def albedo_func1D(t, state, model, *, a2=0.25, alpha_ice=0.6, alpha_0=0.1, T1=26
"""P2-corrected latitudinal albedo using a Legendre polynomial parameterization.

Uses the global-mean temperature to set the base albedo via the same
quadratic ice-line transition as :func:`albedo_func`, then adds a
quadratic ice-line transition as `albedo_func`, then adds a
second-order Legendre polynomial correction to capture the equator-to-pole
gradient. Requires the model to expose a ``phi`` attribute (degrees).

Expand Down Expand Up @@ -150,7 +150,7 @@ class EBMBase(Model):

See also
--------
climatecritters.core.CCModel : Base class for all ClimateCritters models.
climatecritters.core.Model : Base class for all ClimateCritters models.
EBM0D : Zero-dimensional EBM subclass.
EBM1DLat : Latitudinally-resolved diffusive EBM subclass.
"""
Expand Down Expand Up @@ -477,7 +477,7 @@ def __init__(self, var_name='ebm1d_lat', grid_n=50, C=10.0, D=0.55,
def validate_initial_state(self, y0):
"""Validate and normalize the initial temperature profile.

Overrides :meth:`CCModel.validate_initial_state` to accept a scalar
Overrides `Model.validate_initial_state` to accept a scalar
initial condition and broadcast it uniformly across the latitude grid.

Parameters
Expand All @@ -503,7 +503,7 @@ def validate_initial_state(self, y0):
def calc_albedo(self, T, t):
"""Compute the latitudinal ice-albedo with a linear transition zone.

Overrides :meth:`EBMBase.calc_albedo`. Each grid point is assigned
Overrides `EBMBase.calc_albedo`. Each grid point is assigned
an albedo based on local temperature: 0.6 below -10 °C, 0.3 above
0 °C, and a linear blend in between.

Expand Down Expand Up @@ -533,7 +533,7 @@ def calc_albedo(self, T, t):
def calc_OLR(self, T, t):
"""Compute the Budyko linear OLR: ``(A - CO2_forcing) + B * T``.

Overrides :meth:`EBMBase.calc_OLR`. Parameters ``A``, ``B``, and
Overrides `EBMBase.calc_OLR`. Parameters ``A``, ``B``, and
``CO2_forcing`` are resolved through ``get_param_value``, so they can
be time-varying or Forcing objects.

Expand Down Expand Up @@ -699,7 +699,7 @@ def dydt(self, t, state):

This method has **no side effects**: because ``uses_post_history = True``,
all output is derived from the full solved trajectory in
:meth:`populate_diagnostics_from_history` rather than accumulated here.
`EBM1DLat.populate_diagnostics_from_history` rather than accumulated here.

Parameters
----------
Expand All @@ -725,7 +725,7 @@ def dydt(self, t, state):
def populate_diagnostics_from_history(self, time, history):
"""Compute diagnostic variables from the full solved trajectory.

Called automatically by :meth:`CCModel.post_integrate` after the
Called automatically by `Model.post_integrate` after the
solver completes. Populates ``self.diagnostic_variables`` with the
global-mean temperature and ice-line latitude at every timestep.

Expand Down
6 changes: 3 additions & 3 deletions climatecritters/model_critters/enso_recharge.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def seasonal_forcing(A=0.5, period=6.0):
"""Return a sinusoidal seasonal forcing callable for the ENSO recharge oscillator.

The returned function computes ``A * sin(2π t / period)`` and can be
wrapped in a :class:`~climatecritters.core.Forcing` or passed directly to
:meth:`~climatecritters.core.CCModel.register_forcing`::
wrapped in a `Forcing` or passed directly to
`Model.register_forcing`::

import climatecritters as cc
from climatecritters.model_critters.enso_recharge import (
Expand Down Expand Up @@ -64,7 +64,7 @@ class ENSORechargeOscillator(Model):
where ``b = b0*mu`` and ``R = gamma*b - c``.

Seasonal or any other external forcing is added through the standard
:meth:`~climatecritters.core.CCModel.register_forcing` interface::
`Model.register_forcing` interface::

from climatecritters.utils.forcing import create_sinusoid_forcing

Expand Down
2 changes: 1 addition & 1 deletion climatecritters/model_critters/g24.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class Model3(Model):
model.register_forcing('insolation', cc.Forcing(calc_f))

The internal derivative of forcing ``dfdt`` is computed via
:func:`calc_df` by default; supply a custom callable or
`calc_df` by default; supply a custom callable or
``cc.Forcing`` to override.

Parameter defaults are taken from Ganopolski (2024). Time-varying
Expand Down
4 changes: 2 additions & 2 deletions climatecritters/model_critters/melcher25.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class Melcher25(Model):

See also
--------
cc.core.CCModel : Base class.
cc.core.Model : Base class.
classify_bistable_states : Reclassify a Δb signal post-hoc without
re-running the SDE.

Expand Down Expand Up @@ -267,7 +267,7 @@ def sde_noise(self, t, y):
def populate_diagnostics_from_history(self, time, history):
"""Classify states and compute thresholds from the full solved trajectory.

Called automatically by ``CCModel.post_integrate`` after every
Called automatically by ``Model.post_integrate`` after every
``integrate()`` call. Populates ``diagnostic_variables['states']``
with the hysteresis classification and sets
``self.stadial_threshold`` / ``self.interstadial_threshold``.
Expand Down
6 changes: 3 additions & 3 deletions climatecritters/model_critters/pendulum.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ def cartesian_positions(self):

@dataclass
class PendulumRodBeta:
"""Properties of one rod in a :class:`MultiPendulumBeta` chain.
"""Properties of one rod in a `MultiPendulumBeta` chain.

Parameters
----------
Expand All @@ -504,7 +504,7 @@ class PendulumRodBeta:
Notes
-----
``forcing`` is resolved at runtime using the same contract as
:class:`CCModel` parameters, so constants, ``lambda t: ...`` callables,
`Model` parameters, so constants, ``lambda t: ...`` callables,
``lambda t, state: ...`` callables, and forcing objects are all accepted.
"""

Expand Down Expand Up @@ -545,7 +545,7 @@ class MultiPendulumBeta(Model):
Parameters
----------
rods:
Sequence of :class:`PendulumRodBeta` in pivot-to-tip order. Must
Sequence of `PendulumRodBeta` in pivot-to-tip order. Must
contain at least two rods.
g:
Gravitational acceleration in m/s^2. Must be > 0.
Expand Down
Loading
Loading