Getting started
Install
conda create -n qlroms python=3.11 # >=3.10
conda activate qlroms
pip install qlroms
pip install -e ".[dev]" # development
qlroms depends on torch and dynamodels
(the test-case FOMs are dynamodels models). The fluidic-pinball case additionally needs
a FEniCSx install (dolfinx, gmsh) only to generate snapshots or build a model —
importing qlroms.intrusive_qlroms.pinball and reloading a cached model never touches it.
Quickstart
import numpy as np
from qlroms import free_run
from qlroms.intrusive_qlroms import ks1d
from qlroms.intrusive_qlroms.build_ks import build_fom, get_full_trajectory
# A case FOM and its (cached) trajectory: the 1-D KS chaotic regime, short window
fom, cfg = build_fom(ks1d, case="chaotic", overrides={"Ntrain": 20_000, "Ntest": 2_000})
traj = get_full_trajectory(Ntot=cfg["i0"] + cfg["Ntrain"] + cfg["Ntest"], model=fom, i0=cfg["i0"])
Xtrain, x0 = traj[:, :cfg["Ntrain"]], traj[:, cfg["Ntrain"]]
# Charts (k-means + local POD + atlas) and one projected (b, A, B) per chart
rom = ks1d.build_local_model(Xtrain, fom, K=10, r=30, save_dir=".")
# Closed-loop forecast through the shared step(apod) interface
X_rec, cluster_path = free_run(rom, x0, n_steps=500)
# Run it as a dynamodels Model (romda estimators, ntsa analysis)
from qlroms.model import QLModel
model = QLModel(rom, obs_idx=np.arange(0, fom.Nx, 8), psi0=x0)
The same three calls exist for every intrusive case:
| case | module | FOM + data | model |
|---|---|---|---|
| KS 1-D | qlroms.intrusive_qlroms.ks1d |
build_ks.build_fom, build_ks.get_full_trajectory |
ks1d.build_local_model(Xtrain, fom, K, r, save_dir) |
| KS 2-D | qlroms.intrusive_qlroms.ks2d |
same | ks2d.build_local_model(Xtrain, fom, K, r, save_dir, method="galerkin") |
| fluidic pinball (FEniCSx) | qlroms.intrusive_qlroms.pinball |
build_pinball.load_snapshots |
pinball.build_local_model(Xv, Xp, K=, r_velocity=, r_pressure=, reynolds=, dt=, save_dir=) |
Each case package has the same shape: config.py (the TEST_CASES dictionary and the
torch-side grids/operators), fom.py (the full-order model), rom.py (the single-cluster
ROM class and build_local_model, which caches to save_dir and reloads from it).
Caches and data
Trajectories and fitted models are cached under qlroms.utils.paths.data_dir()
(default ~/.cache/qlrom, see qlroms/utils/paths.py for the override and for the
pinball mesh/snapshot/model locations). build_local_model reads a cached model when one
exists, so a second run is seconds, not minutes; the KS caches are keyed on the case's
physical parameters and Ntrain.
Next
- Theory for what the charts, the atlas and the intrusive step are.
- Config-driven builds to fit and evaluate models from a YAML file.
- Tutorials 0–4 walk through the cases, the geometry and the diagnostics.