-
Notifications
You must be signed in to change notification settings - Fork 32
Stability and precision
hi_class checks every model for ghost and gradient instabilities, sets consistent initial conditions for the scalar field perturbations, and can evolve them quasi-statically when they oscillate much faster than the Hubble rate. This page documents those mechanisms and the precision parameters that control them (sections 3–7 of hi_class.ini).
After solving the background, hi_class scans the whole evolution and rejects the model (with an error naming the failed condition and the scale factor where it happened) if any of the four healthy-perturbations conditions is violated:
| Condition | Instability | Quantity tested |
|---|---|---|
| D > 0 | scalar ghost | kinetic term D = α_K + (3/2)α_B² |
| c_s² > 0 | scalar gradient instability | scalar sound speed squared |
| M*² > 0 | tensor ghost | effective Planck mass squared |
| c_T² > 0 | tensor gradient instability | tensor speed squared, c_T² = 1 + α_T |
All four quantities are printed in background.dat at output_background_smg ≥ 1 — see Output files. The tests only run once the model has been tuned to the requested Omega_smg (so intermediate shooting iterations are allowed to wander through unstable regions), and D is allowed to reach exactly zero, which can happen by underflow in models whose kineticity becomes arbitrarily small (e.g. quintessence with tiny initial φ′).
Three sets of parameters modify the tests:
-
skip_stability_tests_smg(defaultno): set toyesto disable all four tests. Use with care — the perturbation equations are still integrated, and an actual instability will usually show up as runaway perturbations or solver failures. -
Thresholds
cs2_safe_smg,ct2_safe_smg,D_safe_smg,M2_safe_smg(all default0.): each test is relaxed to quantity > −|threshold|, i.e. slightly negative values are tolerated. This is meant to absorb numerical noise around zero, not genuine instabilities. Note the code takes the absolute value, so the sign of the threshold does not matter. -
a_min_stability_test_smg(default0): the scan ignores everything at a < a_min. Some shipped models set it because the offending values are numerical artifacts of the deep radiation era, where the scalar is dynamically irrelevant but cancellations make the stability quantities noisy:gravity_models/brans_dicke.iniand thecccg_exp*.inifiles use1e-6, the quintessence models use1e-10.
Section 4 of hi_class.ini. For covariant theories the Friedmann equation is generally cubic in H, with multiple branches. Instead of solving the constraint algebraically at every step, hi_class integrates H dynamically and uses the constraint as a friction term that damps violations:
-
hubble_evolution(defaulty): integrate H from its equation of motion. The constraint is only solved once, to set the initial H. Switching this off makes the code use the constraint equation directly, which will not work for most Lagrangian-based theories (branch ambiguities). -
hubble_friction(default3.): coefficient of the constraint-damping term added to H′. Larger values pull the trajectory back to the constraint surface more aggressively; the sign is chosen automatically so the term is always restoring.
At early times the scalar field perturbation is attracted to a solution driven by the metric perturbations of the radiation era. pert_initial_conditions_smg selects how the scalar is initialized when a mode starts fully dynamical (section 5 of hi_class.ini). The accepted values are:
-
ext_field_attr(default) — external field attractor: assumes Ω_smg and all α's are small at early times, so the scalar does not gravitate; it simply follows the superhorizon metric potential h ∝ τ² created by radiation. Before initialization the code checks for a tachyonic instability of the scalar in radiation domination and aborts if it finds one (the ICs would not be trustworthy). -
gravitating_attr— gravitating attractor: allows the scalar to gravitate at early times (early modified gravity), solving the coupled radiation–scalar system with the assumption of constant Ω_smg and α's during radiation domination. The superhorizon evolution of all other species is modified accordingly (η and the neutrino velocity/shear ICs are recomputed). The code verifies that the standard adiabatic mode h ∝ τ² still dominates; if a faster-growing mode exists, curvature is not conserved on super-horizon scales, the connection to the inflationary amplitude is lost, and the run aborts. Isocurvature initial conditions are not implemented for this choice. -
single_clock— single-clock initial conditions set with respect to the photons: x_smg = δφ/φ̇ equals the common time shift δτ, implemented as x = −δ_γ/(4H) with x′ = 0. -
kin_only— solves the field equation keeping only the kineticity, x″ = 2(aH)²x, giving x ∝ (kτ)². -
zero— start with x = 0 and x′ = 0. Useful to check how much the results depend on the scalar's ICs (for attractor solutions the late-time observables should barely change).
Note that zero and kin_only appear only for completeness/debugging; the physical choices are the two attractors, described in detail in arXiv:1909.01828.
The associated tolerance parameters (defaults in parentheses; all can be set in the .ini):
| Parameter | Default | Role |
|---|---|---|
pert_ic_ini_z_ref_smg |
1e10 |
redshift at which the initial-conditions stability tests above are performed |
pert_ic_tolerance_smg |
2e-2 |
tolerated deviation from the standard growth h ∝ τ² (n = 2) at the reference redshift; a negative value disables the test |
pert_ic_regulator_smg |
1e-15 |
minimum size of denominators in the IC expressions, regulated to prevent infinities; negative disables the regulator |
pert_qs_ic_tolerance_test_smg |
1. (the shipped hi_class.ini uses 10) |
for modes that start quasi-static: maximum contribution of the scalar to superhorizon curvature non-conservation, as a fraction of the standard radiation contribution |
When the scalar's effective mass is large, its perturbations oscillate on timescales far shorter than the Hubble time; integrating those oscillations is expensive and pointless for observables. hi_class can then replace the scalar's equation of motion with its quasi-static (QS) algebraic solution. method_qs_smg (section 6 of hi_class.ini) selects the strategy:
| Value | Behavior |
|---|---|
fully_dynamic (default; abbreviation fd) |
always integrate the full scalar dynamics |
quasi_static (qs) |
force the QS solution at all times |
automatic (a) |
let the code decide, mode by mode and time by time (recommended for stiff models) |
fully_dynamic_debug (fdd) |
integrate fully, but also evaluate the automatic decision machinery (for comparison/debugging) |
quasi_static_debug (qsd) |
force QS, but also evaluate the decision machinery |
What automatic does. For each k-mode the code samples, over the whole integration interval, an effective mass² of the scalar oscillations (in units of aH, including the c_s²k² pressure support), its time derivative, a radiation trigger, a friction coefficient and the decay rate ("slope") of the oscillation envelope; these are the mass2_qs, mass2_qs_p, rad2_qs, friction_qs, slope_qs columns of the perturbations_k*.dat files (Output files). A time is proposed as quasi-static when both
- mass² >
trigger_mass_qs_smg² — the oscillations are fast compared to the expansion, and - rad² >
trigger_rad_qs_smg² — radiation perturbations no longer drive the scalar strongly,
and only at redshifts above z_fd_qs_smg (below it the fully dynamic evolution is always used). The proposed scheme is then compacted to the times where the status actually switches, and each dynamic→QS transition is delayed until the oscillation amplitude, estimated from the slope, has decayed by the factor eps_s_qs_smg, so that the mode lands on the QS solution rather than jumping onto it mid-oscillation. Finally, the scheme is fitted to the transition sequences the integrator implements. The code also checks that at a very early reference time (a_ini_test_qs_smg = 1e-14) all k-modes share the same status, and anticipates the start of integration for a mode if needed.
The knobs (defaults from include/precisions.h, all settable in the .ini):
| Parameter | Default | Role |
|---|---|---|
z_fd_qs_smg |
10. |
minimum redshift for QS: below it perturbations are always evolved fully dynamically |
trigger_mass_qs_smg |
1e3 |
mass threshold (in units of aH) above which QS may switch on |
trigger_rad_qs_smg |
1e3 |
radiation trigger threshold |
eps_s_qs_smg |
0.01 |
required decay of the oscillating solution before switching to QS |
n_min_qs_smg / n_max_qs_smg
|
1e2 / 1e4
|
minimum/maximum number of sampling points used to scan the triggers in time (sampling adapts to how fast the mass varies) |
Raising the triggers or lowering eps_s_qs_smg makes the scheme more conservative (more fully-dynamic evolution); the defaults were validated in arXiv:1909.01828.
Section 7 of hi_class.ini, plus the smg-related adjustments hi_class makes to CLASS defaults.
-
kineticity_safe_smg(default0.): adds a constant to α_K. Historically used to damp the impact of rapid early-time oscillations that slow down the integrator; it should not affect observable scales, but use at your own risk — since v2 the recommended cure is the quasi-static approximation (method_qs_smg = automatic) instead. -
tol_initial_Omega_r(default1e-4): standard CLASS parameter setting how close to total radiation domination the background integration must start. Early-dark-energy-like models where the scalar is non-negligible at early times can fail this check; loosening the tolerance lets the run proceed. -
tol_background_integration(default1e-10): relative tolerance of the background ODE integration. hi_class tightens this from the CLASS default of1e-2— the shooting method and the stability scan need an accurately integrated scalar field. If a covariant model's background integration is unusually slow, this (together withbackground_Nloga) is the knob to inspect. -
background_Nloga: number of stored background table points. Upstream CLASS uses40000; for smg runs hi_class automatically resets it to3000unless you set it explicitly, because in hi_class the background is recomputed at every shooting iteration and the larger table costs roughly an order of magnitude in run time for no measurable accuracy gain. Pure ΛCDM runs (Ω_smg = 0) keep the upstream default and remain directly comparable to CLASS. -
perturbations_sampling_stepsize: automatically capped at0.05for smg runs (CLASS default0.1), otherwise the ISW effect is not sampled accurately in modified-gravity models. - In addition, the shipped
hi_class.inisets a few CLASS parameters to safer-than-default values for modified gravity —start_small_k_at_tau_c_over_tau_h = 1e-4(CLASS default0.0015),start_large_k_at_tau_h_over_tau_k = 1e-4(default0.07), so that modes start being integrated earlier, and a denser multipole samplingl_logstep = 1.045,l_linstep = 50(defaults1.12,40). These are set in the example input file, not in the code: if you write your own.inifrom scratch and need highly accurate C_ℓ's, copy them over.
For the accuracy of the ~k > 10 Mpc⁻¹ modes, see also get_h_from_trace (discussed in hi_class.ini and printed as a warning at high input_verbose): hi_class can obtain the metric perturbation h′ either from the Einstein 00 constraint (default) or from the trace of the ij equation, which avoids a gauge-dependent singularity when a model crosses α_B = 2.
Getting started
Models
Reference
Development
Background
External