Solver API#
- pyCRO.solver.CRO_simulate(par, IC=[0, 0], N=2400, NE=100, NM='EH', dt=0.1, saveat=1.0, savemethod='sampling', freq='MS', use_cftime=False, start=None, EF=None, noise_custom=None, verbose=False)#
Run CRO ensemble simulation (same as RO_solver) and return results as an xarray Dataset.
This function wraps the low-level RO solver (RO_solver) and converts the output into a structured xarray.Dataset, including time and ensemble dimensions.
The CRO model simulates coupled SST (T) and thermocline (h) dynamics under stochastic forcing and optional external forcing.
- Parameters:
par (dict) –
CRO parameter dictionary (output of par_load), containing:
Linear and nonlinear deterministic parameters (R, F1, F2, epsilon, etc.)
Noise parameters (sigma_T, sigma_h, B)
Noise configuration (n_T, n_h, n_g, m_T, m_h)
IC (array-like of shape (2,), optional) –
Initial conditions:
IC[0] : initial SST anomaly (T0)
IC[1] : initial thermocline anomaly (h0)
Default is [0, 0].
N (float, optional) –
Total simulation length in months.
Default = 12 * 200 (200 years).
NE (int, optional) –
Number of ensemble members.
Default = 100.
NM ({"EM", "EH"}, optional) –
Numerical integration scheme:
”EM” : Euler–Maruyama method
”EH” : Euler–Heun method (default)
dt (float, optional) – Time step (months). Default = 0.1.
saveat (float, optional) –
Output saving interval (months). Must be a multiple of dt.
Default = 1.0.
savemethod ({"sampling", "mean"}, optional) –
Method for temporal aggregation:
”sampling” : subsample at saveat interval (default)
”mean” : block-average over each interval
freq (str, optional) – Time step frequency. Default is “MS” (month start).
use_cftime (bool, optional) – If True, return time axis as CFTime objects; otherwise use standard datetime objects. Default is False.
EF (dict, optional) –
External forcing dictionary with keys:
”E_T” : SST forcing time series
”E_h” : thermocline forcing time series
If None, zero forcing is used.
noise_custom (None, int, or ndarray, optional) –
Custom stochastic forcing:
None : internally generated Gaussian noise
int : random seed for reproducibility
ndarray : pre-generated noise with shape (NT-1, 4, NE)
verbose (bool, optional) – If True, prints simulation configuration and progress.
- Returns:
CRO simulation output with:
Nino34 : SST anomaly (T) [time × member]
WWV : thermocline depth anomaly (h) [time × member]
Coordinates: - time : monthly time index starting from year 0001 - member : ensemble member index
- Return type:
xarray.Dataset
Notes
Time axis is generated using xarray.date_range(…, freq=”MS”) and uses CF-compatible time format.
Ensemble dimension corresponds to independent stochastic realizations.
Output is already aligned with climate-model-style diagnostics.
Examples
>>> par = pyCRO.par_load("ORAS5", "Linear-White-Additive") >>> ds = pyCRO.CRO_simulate(par, NE=10, N=120) >>> ds
Access variables:
>>> ds["T"] >>> ds["h"]
- pyCRO.solver.RO_analytic_solver(par, IC, N, NE, dt=0.1, saveat=1.0, savemethod='sampling', noise_custom=None)#
Analytical solution of the Recharge Oscillator (RO) model with deterministic and stochastic forcing. ONLY for linear RO model with white noise (annual mean parameters only)
- Parameters:
par (dict) –
Dictionary of model parameters, each as at least a one-element array:
'R'floatDamping parameter.
'F1'floatFeedback parameter relating thermocline depth to SST.
'epsilon'floatThermocline damping parameter.
'F2'floatFeedback parameter relating SST to thermocline.
'sigma_T'floatNoise amplitude for SST.
'sigma_h'floatNoise amplitude for thermocline depth.
IC (tuple of float) –
Initial condition
(To, ho):To: initial SST anomaly.ho: initial thermocline depth anomaly.
N (float) – Total simulation length (time units).
NE (int) – Number of ensemble members.
dt (float, optional) – Numerical integration time step. Default is
0.1.saveat (float, optional) – Output saving interval. Must be divisible by
dt. Default is1.0.savemethod ({'sampling', 'mean'}, optional) –
Method for saving results:
'sampling': take samples everysaveat.'mean': average values over eachsaveatinterval.
noise_custom ({None, int, ndarray}, optional) –
Specification of stochastic noise:
None(default): new Gaussian noise is generated for each ensemble.int: seed for reproducible noise (same across ensembles).ndarrayof shape(NT-1, 4): user-provided noise, repeated across ensembles.ndarrayof shape(NT-1, 4, NE): user-provided noise for each ensemble.
- Returns:
T_anal_out (ndarray of shape (N_out, NE)) – SST anomalies including deterministic and stochastic forcing, after applying the saving scheme. The final row is NaN-padded for dimensional consistency.
h_anal_out (ndarray of shape (N_out, NE)) – Thermocline anomalies including deterministic and stochastic forcing, after applying the saving scheme. The final row is NaN-padded.
noise_array (ndarray of shape (NT-1, 4, NE)) – Realizations of Gaussian noise used in the simulation.
Notes
The analytical solution consists of:
Deterministic part: exponential-sinusoidal functions of time.
Stochastic part: weighted sums (discrete convolutions) of noise with exponential and sinusoidal kernels.
Ensemble members are evaluated simultaneously using vectorized NumPy broadcasting, avoiding explicit Python loops.
Examples
>>> par = {'R':[0.5], 'F1':[1.2], 'epsilon':[0.3], 'F2':[0.8], ... 'sigma_T':[0.2], 'sigma_h':[0.1]} >>> IC = (0.1, -0.2) >>> T, h, noise = RO_solver_analytic(par, IC, N=50, NE=10, dt=0.1, saveat=1.0) >>> T.shape, h.shape ((51, 10), (51, 10))
- pyCRO.solver.RO_solver(par, IC, N, NE, NM='EH', dt=0.1, saveat=1.0, savemethod='sampling', EF=None, noise_custom=None, verbose=True)#
Numerical solution of the Recharge Oscillator (RO) model with stochastic forcing.
This function integrates the Recharge Oscillator (RO) system numerically using either the Euler–Maruyama (EM) or Euler–Heun (EH) scheme. It includes deterministic dynamics, stochastic noise (white or red), and optional external forcing. Ensemble simulations are supported, with results returned at user-specified output intervals.
- Parameters:
par (dict) –
Dictionary of model parameters with the following keys (as 1-element arrays):
'R'floatDamping parameter.
'F1'floatFeedback parameter relating thermocline depth to SST.
'epsilon'floatThermocline damping parameter.
'F2'floatFeedback parameter relating SST to thermocline.
'sigma_T'floatNoise amplitude for SST.
'sigma_h'floatNoise amplitude for thermocline depth.
'B'floatMultiplicative noise coefficient (used when
n_g= 0 or 1).
'n_T'intNoise type in SST equation (
1= white noise,0= red noise).
'm_T'ndarrayMemory kernel for red noise in SST equation (ignored if
n_T=1).
'n_h'intNoise type in thermocline equation (
1= white noise,0= red noise).
'm_h'ndarrayMemory kernel for red noise in thermocline equation (ignored if
n_h=1).
'n_g'intNoise structure in SST equation:
0= multiplicative,1= multiplicative + Heaviside,2= additive.
IC (tuple of float) –
Initial condition
(T0, h0):T0: initial SST anomaly.h0: initial thermocline depth anomaly.
N (float) – Total simulation length (time units).
NE (int) – Number of ensemble members.
NM ({'EM', 'EH'}, optional) – Numerical integration method. Default is
'EH'(Euler–Heun).dt (float, optional) – Numerical integration time step. Default is
0.1.saveat (float, optional) – Output saving interval. Must be divisible by
dt. Default is1.0.savemethod ({'sampling', 'mean'}, optional) –
Method for saving results:
'sampling': store values everysaveatsteps (default).'mean': average values within eachsaveatinterval.
EF (dict, optional) –
External forcing with the following keys (as 1D arrays of length 5):
'E_T': SST forcing coefficients.'E_h': Thermocline forcing coefficients.
If
None(default), no external forcing is applied.noise_custom ({None, int, ndarray}, optional) –
Specification of stochastic noise:
None(default): generate new Gaussian noise for each ensemble.int: random seed for reproducible noise (same across ensembles).ndarrayof shape (NT-1, 4, NE) : user-provided noise realizations.
verbose (bool, optional) – If
True(default), print detailed setup and progress messages.
- Returns:
T_out (ndarray of shape (N_out, NE)) – SST anomalies from the numerical integration, after applying the saving scheme.
h_out (ndarray of shape (N_out, NE)) – Thermocline anomalies from the numerical integration, after applying the saving scheme.
noise_out (ndarray of shape (NT-1, 4, NE)) – Realizations of Gaussian noise used in the simulation.
Notes
White noise forcing corresponds to
n_T = 1orn_h = 1.Red noise forcing (
n_T = 0orn_h = 0) requires a nonzero memory kernelm_Torm_h.For the Euler–Maruyama method (
NM = 'EM') with multiplicative noise, an Ito-to-Stratonovich correction is applied automatically.
Examples
>>> par = { ... 'R':[0.5], 'F1':[1.2], 'epsilon':[0.3], 'F2':[0.8], ... 'sigma_T':[0.2], 'sigma_h':[0.1], 'B':[0.05], ... 'n_T':[1], 'm_T':[0], 'n_h':[1], 'm_h':[0], 'n_g':[0] ... } >>> IC = (0.1, -0.2) >>> T, h, noise = RO_solver(par, IC, N=50, NE=5, dt=0.1, saveat=1.0) >>> T.shape, h.shape ((51, 5), (51, 5))