Skip to content

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.