How akhileshmath/energy-stable-rom works
This repository is a research pipeline for incompressible-flow reduced-order modeling, centered on a single benchmark: the 2D flow past a cylinder at Reynolds 100. The architecture is stage-based: generate full-order snapshots, compress them with POD, assemble a Galerkin ROM, optionally augment it with a trained neural closure, then evaluate trajectories, energy behavior, and error bounds.
1. Full-order simulation layer
The fem_solver/ package is the high-fidelity PDE backend. It contains mesh generation, boundary-condition setup, Navier–Stokes formulation, time stepping, and snapshot collection. This is the only part that depends directly on the finite-element stack, with DOLFINx, Gmsh, MPI, and standard scientific Python libraries.
2. Snapshot production boundary
The main output of the full-order layer is time-resolved velocity snapshot data saved under data/snapshots/. These snapshots are the interface between the PDE solver and the reduced-order pipeline; downstream components do not solve Navier–Stokes directly.
3. POD basis construction layer
The pod_rom/ package builds the reduced basis from snapshots. pod_basis.py computes the POD modes and singular values, while galerkin_projection.py projects the governing equations into reduced coordinates and assembles the reduced operators. The reduced model is driven by modal coefficients rather than the full velocity field.
4. Reduced-order dynamical core
The ROM state is the vector of POD coefficients a(t). The core reduced dynamics are a Galerkin system with linear viscous terms, nonlinear convective/modal-transfer terms, forcing, and an optional closure term. This is the central mathematical boundary in the repo: everything after POD works in reduced coordinates.
5. Neural closure subsystem
The neural_closure/ package adds a learned correction term to the ROM. architecture.py defines the closure network, and trainer.py handles training. The key architectural constraint is dissipativity in reduced coordinates, so the network is not just predictive; it is constrained to avoid spurious energy growth in the ROM.
6. Training and inference split for closure
The closure model is trained offline from reduced-state data and then injected into a separate ROM rollout. That means the training path and simulation path are distinct: snapshots feed POD, POD feeds reduced trajectories, and reduced trajectories feed closure training. The trained model is then reused in enhanced ROM runs.
7. Analysis and stability layer
The analysis/ package contains error_bounds.py, which computes a posteriori indicators and long-time error estimates. This layer does not change the ROM itself; it post-processes reduced trajectories to evaluate stability, energy behavior, and trajectory deviation. It is conceptually downstream of both the standard ROM and the neural-augmented ROM.
8. Experiment orchestration
The scripts/ directory defines the end-to-end workflow in numbered stages:
• snapshot generation
• POD basis computation
• ROM assembly
• standard ROM run
• neural closure training
• enhanced ROM run
• error-bound computation
• figure generation
run_full_pipeline.sh is the top-level orchestrator. scripts/config_utils.py suggests the scripts are configuration-driven rather than hard-coded.
9. Configuration and reproducibility boundary
configs/default.yaml and configs/cylinder_vortex.yaml provide experiment parameters, with the benchmark-specific config likely overriding the default settings for geometry, discretization, time horizon, and ROM dimensions. This configuration layer is what makes the pipeline reproducible across runs.
10. Persistent artifacts and data flow
The repository stores intermediate and final artifacts in a structured way:
• data/snapshots/ for snapshot arrays and ROM matrices
• results/tables/ for computed summary metrics
• paper/figures/ and paper/tables/ for manuscript-ready outputs
The presence of .npz files in data/snapshots/ indicates the pipeline already materializes reduced operators and POD coefficients for reuse.
11. Reporting and publication layer
The paper/ directory is a complete LaTeX manuscript that consumes outputs from the computational pipeline. Figures and tables generated by the scripts are embedded here, so the paper is effectively a downstream consumer of the numerical workflow rather than part of the solver stack.
12. Repository-level execution model
This is not a service or interactive application; it is a batch scientific computing project. The architecture depends on offline numerical simulation, offline model reduction, offline neural training, and offline analysis/plot generation. The main runtime boundary is between MPI-enabled finite-element simulation and single-process or lighter-weight reduced-model training/evaluation.
Overall, the repo is organized as a one-way scientific pipeline: finite-element snapshots → POD compression → reduced Galerkin operators → optional dissipative neural closure → ROM evaluation and error analysis → figures/tables for the manuscript.
Main entry points: scripts Pipeline scripts · galerkin_projection.py Galerkin ROM · config_utils.py Config utils · architecture.py Closure net
Components 19
Pipeline
End-to-end scientific workflow from simulation to analysis and publication outputs.
- Pipeline scripts · Numbered stages that run the repository end-to-end.
scripts - Full pipeline · Top-level shell entrypoint for the complete workflow.
scripts/run_full_pipeline.sh - Config utils · Shared configuration loading and stage setup for scripts.
scripts/config_utils.py
Full order
Finite-element simulation backend and snapshot production.
- Mesh gen · Builds the computational domain and mesh.
fem_solver/mesh_generation.py - Boundary conds · Defines inflow, wall, and outlet conditions.
fem_solver/boundary_conditions.py - Navier-Stokes · High-fidelity incompressible flow formulation.
fem_solver/navier_stokes.py - Time stepping · Advances the finite-element state in time.
fem_solver/time_stepping.py - Snapshot collector · Stores time-resolved full-order fields for downstream reduction.
fem_solver/snapshot_collector.py
ROM core
POD reduction, Galerkin assembly, and learned closure.
- POD basis · Computes modes and singular values from snapshots.
pod_rom/pod_basis.py - Galerkin ROM · Projects governing equations into reduced coordinates.
pod_rom/galerkin_projection.py - Closure net · Dissipative correction network in reduced coordinates.
neural_closure/architecture.py - Closure trainer · Offline training for the learned ROM correction.
neural_closure/trainer.py
Reporting
Batch orchestration, configuration, analysis, and manuscript outputs.
- Default config · Repository-wide default experiment parameters.
configs/default.yaml - Cylinder config · Benchmark-specific settings for cylinder-flow runs.
configs/cylinder_vortex.yaml - Snapshots · Persistent snapshot and reduced-operator data used by the ROM pipeline.
data/snapshots - ROM matrices · Stored reduced operators and POD coefficients for reuse.
data/snapshots/cylinder_vortex_rom_matrices.npz - Coeff data · Reduced-state coefficient snapshots used for ROM runs and closure training.
data/snapshots/cylinder_vortex_pod_coeffs.npz - Error bounds · A posteriori indicators and long-time error estimates.
analysis/error_bounds.py - Paper outputs · Figures, tables, and manuscript files that consume computed results.
paper
Connections 21
- Full pipeline → Pipeline scripts: drives · The shell script executes the staged workflow.
- Pipeline scripts → Config utils: loads · Stages use shared configuration handling.
- Config utils → Default config: reads · Default parameters define the base experiment setup.
- Config utils → Cylinder config: overrides · Benchmark config specializes the default case.
- Pipeline scripts → Mesh gen: stage 1 · Initial full-order preprocessing creates the mesh.
- Mesh gen → Boundary conds: feeds · Geometry and domain setup support PDE boundary specification.
- Boundary conds → Navier-Stokes: defines · Boundary conditions are applied in the flow model.
- Navier-Stokes → Time stepping: solved by · The PDE is advanced through time integration.
- Time stepping → Snapshot collector: emits · Solver states are sampled during the trajectory.
- Snapshot collector → Snapshots: stores · Full-order snapshots are written as persistent artifacts.
- Snapshots → POD basis: input · Snapshot arrays are the basis construction input.
- POD basis → Galerkin ROM: basis for · The computed modes parameterize the reduced equations.
- Galerkin ROM → ROM matrices: writes · Reduced operators and coefficients are materialized for reuse.
- ROM matrices → Coeff data: provides · Reduced-state trajectories feed later stages and training.
- Coeff data → Closure trainer: trains · Reduced trajectories supervise the closure model.
- Closure trainer → Closure net: fits · Training instantiates the dissipative closure network.
- Closure net → Galerkin ROM: augments · The learned correction is injected into the reduced dynamics.
- Galerkin ROM → Error bounds: analyzed by · Reduced trajectories are post-processed for stability and error.
- Closure net → Error bounds: compared in · Enhanced ROM runs are evaluated against standard ROM behavior.
- Error bounds → Paper outputs: publishes · Computed metrics populate figures, tables, and manuscript sections.
- Pipeline scripts → Paper outputs: stage 8 · Final figure and table generation populates the paper.