From 8697aeb5974b202f375d3a347e4b9522e3b45feb Mon Sep 17 00:00:00 2001 From: Seung Whan Chung Date: Wed, 7 Oct 2026 16:20:13 -0700 Subject: [PATCH 1/2] steady ns workflow example. --- examples/CMakeLists.txt | 1 + examples/steady_ns/.gitignore | 7 + examples/steady_ns/CMakeLists.txt | 17 ++ examples/steady_ns/README.md | 15 ++ examples/steady_ns/generate_configs.py | 123 +++++++++++ examples/steady_ns/jobs/00_mesh.sbatch | 17 ++ examples/steady_ns/jobs/01_samples.sbatch | 27 +++ examples/steady_ns/jobs/02_basis.sbatch | 16 ++ examples/steady_ns/jobs/03_auxiliary.sbatch | 17 ++ examples/steady_ns/jobs/04_build_rom.sbatch | 16 ++ examples/steady_ns/jobs/05_fom_16x16.sbatch | 17 ++ .../jobs/06_rom_compare_16x16.sbatch | 19 ++ examples/steady_ns/jobs/common.bash | 19 ++ examples/steady_ns/prepare_meshes.sh | 43 ++++ examples/steady_ns/report_results.py | 30 +++ examples/steady_ns/steady_ns.yml | 201 ++++++++++++++++++ examples/steady_ns/submit_workflow.sh | 34 +++ 17 files changed, 619 insertions(+) create mode 100644 examples/steady_ns/.gitignore create mode 100644 examples/steady_ns/CMakeLists.txt create mode 100644 examples/steady_ns/README.md create mode 100755 examples/steady_ns/generate_configs.py create mode 100755 examples/steady_ns/jobs/00_mesh.sbatch create mode 100755 examples/steady_ns/jobs/01_samples.sbatch create mode 100755 examples/steady_ns/jobs/02_basis.sbatch create mode 100755 examples/steady_ns/jobs/03_auxiliary.sbatch create mode 100755 examples/steady_ns/jobs/04_build_rom.sbatch create mode 100755 examples/steady_ns/jobs/05_fom_16x16.sbatch create mode 100755 examples/steady_ns/jobs/06_rom_compare_16x16.sbatch create mode 100644 examples/steady_ns/jobs/common.bash create mode 100755 examples/steady_ns/prepare_meshes.sh create mode 100755 examples/steady_ns/report_results.py create mode 100644 examples/steady_ns/steady_ns.yml create mode 100755 examples/steady_ns/submit_workflow.sh diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index cbcf2828..1004ac47 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -5,3 +5,4 @@ add_subdirectory(poisson) add_subdirectory(linelast) add_subdirectory(stokes) +add_subdirectory(steady_ns) diff --git a/examples/steady_ns/.gitignore b/examples/steady_ns/.gitignore new file mode 100644 index 00000000..7e4f7895 --- /dev/null +++ b/examples/steady_ns/.gitignore @@ -0,0 +1,7 @@ +basis/ +configs/ +logs/ +meshes/ +results/ +rom/ +snapshots/ diff --git a/examples/steady_ns/CMakeLists.txt b/examples/steady_ns/CMakeLists.txt new file mode 100644 index 00000000..aadc6333 --- /dev/null +++ b/examples/steady_ns/CMakeLists.txt @@ -0,0 +1,17 @@ +# Copyright 2026 Lawrence Livermore National Security, LLC. +# SPDX-License-Identifier: MIT + +set(STEADY_NS_EXAMPLE_FILES + README.md + generate_configs.py + prepare_meshes.sh + report_results.py + steady_ns.yml + submit_workflow.sh) + +foreach(example_file IN LISTS STEADY_NS_EXAMPLE_FILES) + configure_file(${example_file} ${example_file} COPYONLY) +endforeach() + +file(COPY jobs DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + diff --git a/examples/steady_ns/README.md b/examples/steady_ns/README.md new file mode 100644 index 00000000..f283c25e --- /dev/null +++ b/examples/steady_ns/README.md @@ -0,0 +1,15 @@ +# Steady Navier--Stokes paper workflow + +This reproduces the paper's representative 16x16, Re=25 tensorial-ROM case. It uses five component types, 2,000 random 2x2 training arrays (five jobs of 400), and 40 velocity, pressure, and supremizer modes per component. Meshes and HDF5 configurations are generated at run time and are not stored in the repository. + +Install and build on Dane, then run from the configured build example: + +```bash +./script/install_dane.bash +cd build/examples/steady_ns +./submit_workflow.sh +``` + +The submission chain runs mesh/configuration generation, sampling, `train_rom` POD and supremizer training, tensorial operator construction, a 16x16 FOM solve, and the dependent ROM comparison. If `train_rom` writes the POD bases but reaches its wall-time limit during supremizer enrichment, resume that step with `sbatch jobs/03_auxiliary.sbatch`; this fallback job is not part of the normal chain. Jobs use the paper/legacy Dane settings (`pbatch`, account `sosu`; one 2 GB single-thread task for online runs; 5 nodes and 36 MPI ranks for POD training). Override Slurm options when needed, for example `./submit_workflow.sh --account=my_account`. + +Outputs are under `snapshots/`, `basis/`, `rom/`, and `results/`; logs are under `logs/`. After completion, `python3 report_results.py` prints FOM/ROM times and velocity/pressure relative errors. Each `jobs/*.sbatch` file may also be submitted separately. diff --git a/examples/steady_ns/generate_configs.py b/examples/steady_ns/generate_configs.py new file mode 100755 index 00000000..cce3225a --- /dev/null +++ b/examples/steady_ns/generate_configs.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 +"""Generate the component catalog, training meshes, and paper 16x16 mesh.""" + +import argparse +import os +import sys +from pathlib import Path + + +def find_utilities(start: Path) -> Path: + configured_root = os.environ.get("SCALEUPROM_ROOT") + if configured_root: + candidate = Path(configured_root) / "utils" / "python" + if (candidate / "box_channel_config.py").is_file(): + return candidate + for parent in (start, *start.parents): + candidate = parent / "utils" / "python" + if (candidate / "box_channel_config.py").is_file(): + return candidate + raise FileNotFoundError("cannot locate scaleupROM/utils/python") + + +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(find_utilities(HERE))) + +from box_channel_config import BoxChannelConfig # noqa: E402 +from config import Empty, ObjectInSpace # noqa: E402 + + +def components(): + return [ + Empty(), + ObjectInSpace("square-circle"), + ObjectInSpace("square-square"), + ObjectInSpace("square-triangle"), + ObjectInSpace("square-star"), + ] + + +def add_components(config): + for component in components(): + config.addComponent(component) + + +def write_component_catalog(path: Path): + catalog = BoxChannelConfig(1, 5) + add_components(catalog) + + # Register every oriented component/face pairing. BuildROM uses this + # compact configuration to construct all reusable component operators. + for component1 in catalog.comps: + for displacement, face1 in component1.face_map.items(): + opposite = tuple(-value for value in displacement) + for component2 in catalog.comps: + if opposite in component2.face_map: + catalog.appendRefPort( + component1.name, + component2.name, + face1, + component2.face_map[opposite], + ) + + for component_index in range(len(catalog.comps)): + catalog.addMesh(component_index, 0) + catalog.close() + catalog.save(str(path)) + + +# Component ordering extracted from the 16x16 configuration used by the paper. +# 0=empty, 1=circle, 2=square, 3=triangle, 4=star. +PAPER_16X16_COMPONENTS = [ + 1, 1, 3, 0, 2, 1, 4, 1, 2, 4, 0, 2, 4, 1, 4, 2, + 0, 4, 1, 2, 4, 0, 3, 3, 0, 1, 3, 0, 0, 1, 3, 1, + 0, 3, 4, 0, 1, 1, 1, 2, 1, 4, 0, 4, 1, 4, 4, 3, + 1, 4, 0, 0, 3, 3, 0, 3, 4, 0, 0, 4, 2, 1, 0, 2, + 0, 1, 4, 1, 0, 3, 3, 1, 3, 4, 4, 3, 4, 3, 1, 0, + 3, 3, 0, 2, 0, 2, 0, 0, 2, 1, 0, 2, 3, 3, 1, 1, + 3, 4, 2, 2, 4, 2, 0, 2, 3, 2, 0, 2, 0, 0, 3, 0, + 2, 4, 3, 1, 4, 1, 2, 3, 3, 1, 1, 4, 1, 1, 4, 3, + 3, 2, 3, 4, 4, 0, 0, 1, 2, 1, 2, 3, 1, 2, 1, 0, + 1, 1, 1, 0, 0, 2, 0, 4, 4, 4, 3, 2, 4, 3, 0, 2, + 0, 0, 1, 1, 0, 4, 0, 3, 0, 3, 3, 3, 4, 0, 2, 4, + 3, 4, 4, 3, 4, 4, 3, 1, 4, 2, 1, 0, 4, 3, 4, 0, + 1, 0, 3, 4, 2, 2, 2, 4, 4, 2, 3, 3, 1, 0, 2, 0, + 3, 1, 2, 0, 0, 4, 1, 0, 1, 0, 4, 1, 1, 1, 0, 4, + 1, 4, 0, 0, 1, 3, 3, 4, 2, 2, 3, 0, 0, 2, 1, 3, + 4, 3, 1, 4, 4, 1, 2, 0, 2, 4, 4, 1, 0, 3, 4, 3, +] + + +def write_paper_target(path: Path): + target = BoxChannelConfig(16, 16) + add_components(target) + for component_index in PAPER_16X16_COMPONENTS: + target.addMesh(component_index, 0) + target.close() + target.save(str(path)) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--output", type=Path, default=HERE / "configs") + args = parser.parse_args() + + output = args.output.resolve() + training = output / "training" + training.mkdir(parents=True, exist_ok=True) + + write_component_catalog(output / "component_catalog.h5") + + samples = BoxChannelConfig(2, 2) + add_components(samples) + samples.prefix = str(training / "box-channel.config") + count = samples.GenerateAllConfigs(0) + if count != 625: + raise RuntimeError(f"expected 625 training configurations, generated {count}") + + write_paper_target(output / "paper.16x16.h5") + print(f"Generated {count} training configurations and {output / 'paper.16x16.h5'}") + + +if __name__ == "__main__": + main() diff --git a/examples/steady_ns/jobs/00_mesh.sbatch b/examples/steady_ns/jobs/00_mesh.sbatch new file mode 100755 index 00000000..b8fd08b3 --- /dev/null +++ b/examples/steady_ns/jobs/00_mesh.sbatch @@ -0,0 +1,17 @@ +#!/bin/bash +#SBATCH --job-name=ns-mesh +#SBATCH --nodes=1 +#SBATCH --ntasks=1 +#SBATCH --cpus-per-task=1 +#SBATCH --mem=2G +#SBATCH --time=00:30:00 +#SBATCH --partition=pbatch +#SBATCH --account=sosu +#SBATCH --output=logs/%x-%j.out + +set -euo pipefail +example_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd) +cd "${example_dir}" +mkdir -p logs +./prepare_meshes.sh + diff --git a/examples/steady_ns/jobs/01_samples.sbatch b/examples/steady_ns/jobs/01_samples.sbatch new file mode 100755 index 00000000..20f1dbb7 --- /dev/null +++ b/examples/steady_ns/jobs/01_samples.sbatch @@ -0,0 +1,27 @@ +#!/bin/bash +#SBATCH --job-name=ns-samples +#SBATCH --array=1-5 +#SBATCH --nodes=1 +#SBATCH --ntasks=1 +#SBATCH --cpus-per-task=1 +#SBATCH --mem=2G +#SBATCH --time=24:00:00 +#SBATCH --partition=pbatch +#SBATCH --account=sosu +#SBATCH --output=logs/%x-%A_%a.out + +# shellcheck source=jobs/common.bash +source "$(dirname -- "${BASH_SOURCE[0]}")/common.bash" + +batch_id=${SLURM_ARRAY_TASK_ID:-${1:-}} +if [[ -z ${batch_id} || ${batch_id} -lt 1 || ${batch_id} -gt 5 ]]; then + echo "Batch index must be in [1, 5]." >&2 + exit 2 +fi + +mkdir -p "snapshots/batch-${batch_id}" +# RandomSampleGenerator seeds from wall time. Offset simultaneous array tasks +# so that independent batches cannot receive the same one-second seed. +sleep $((5 * batch_id)) +"${MAIN_BIN}" -i steady_ns.yml -f \ + "main/mode=sample_generation:main/use_rom=false:sample_generation/file_path/prefix=snapshots/batch-${batch_id}/steady_ns" diff --git a/examples/steady_ns/jobs/02_basis.sbatch b/examples/steady_ns/jobs/02_basis.sbatch new file mode 100755 index 00000000..ae34a81e --- /dev/null +++ b/examples/steady_ns/jobs/02_basis.sbatch @@ -0,0 +1,16 @@ +#!/bin/bash +#SBATCH --job-name=ns-basis +#SBATCH --nodes=5 +#SBATCH --ntasks=36 +#SBATCH --cpus-per-task=1 +#SBATCH --mem-per-cpu=2G +#SBATCH --time=24:00:00 +#SBATCH --partition=pbatch +#SBATCH --account=sosu +#SBATCH --output=logs/%x-%j.out + +# shellcheck source=jobs/common.bash +source "$(dirname -- "${BASH_SOURCE[0]}")/common.bash" + +srun --ntasks=36 "${MAIN_BIN}" -i steady_ns.yml -f \ + "main/mode=train_rom:main/use_rom=true" diff --git a/examples/steady_ns/jobs/03_auxiliary.sbatch b/examples/steady_ns/jobs/03_auxiliary.sbatch new file mode 100755 index 00000000..f31127bb --- /dev/null +++ b/examples/steady_ns/jobs/03_auxiliary.sbatch @@ -0,0 +1,17 @@ +#!/bin/bash +# Manual recovery only: train_rom normally calls aux_train_rom itself. +#SBATCH --job-name=ns-supremizer +#SBATCH --nodes=1 +#SBATCH --ntasks=1 +#SBATCH --cpus-per-task=1 +#SBATCH --mem=2G +#SBATCH --time=02:00:00 +#SBATCH --partition=pbatch +#SBATCH --account=sosu +#SBATCH --output=logs/%x-%j.out + +# shellcheck source=jobs/common.bash +source "$(dirname -- "${BASH_SOURCE[0]}")/common.bash" + +"${MAIN_BIN}" -i steady_ns.yml -f \ + "main/mode=aux_train_rom:main/use_rom=true:basis/number_of_basis=40:basis/number_of_supremizer=40" diff --git a/examples/steady_ns/jobs/04_build_rom.sbatch b/examples/steady_ns/jobs/04_build_rom.sbatch new file mode 100755 index 00000000..4580d6b1 --- /dev/null +++ b/examples/steady_ns/jobs/04_build_rom.sbatch @@ -0,0 +1,16 @@ +#!/bin/bash +#SBATCH --job-name=ns-build +#SBATCH --nodes=1 +#SBATCH --ntasks=1 +#SBATCH --cpus-per-task=1 +#SBATCH --mem=2G +#SBATCH --time=02:00:00 +#SBATCH --partition=pbatch +#SBATCH --account=sosu +#SBATCH --output=logs/%x-%j.out + +# shellcheck source=jobs/common.bash +source "$(dirname -- "${BASH_SOURCE[0]}")/common.bash" + +"${MAIN_BIN}" -i steady_ns.yml -f \ + "main/mode=build_rom:main/use_rom=true:basis/number_of_basis=40:basis/number_of_supremizer=40:model_reduction/nonlinear_handling=tensor:model_reduction/save_operator/prefix=rom/steady_ns_nb40" diff --git a/examples/steady_ns/jobs/05_fom_16x16.sbatch b/examples/steady_ns/jobs/05_fom_16x16.sbatch new file mode 100755 index 00000000..475b7415 --- /dev/null +++ b/examples/steady_ns/jobs/05_fom_16x16.sbatch @@ -0,0 +1,17 @@ +#!/bin/bash +#SBATCH --job-name=ns-fom-16 +#SBATCH --nodes=1 +#SBATCH --ntasks=1 +#SBATCH --cpus-per-task=1 +#SBATCH --mem=2G +#SBATCH --time=02:00:00 +#SBATCH --partition=pbatch +#SBATCH --account=sosu +#SBATCH --output=logs/%x-%j.out + +# shellcheck source=jobs/common.bash +source "$(dirname -- "${BASH_SOURCE[0]}")/common.bash" + +mkdir -p results/paraview/fom +"${MAIN_BIN}" -i steady_ns.yml -o results/fom_timings.h5 -f \ + "main/mode=single_run:main/use_rom=false:mesh/component-wise/global_config=configs/paper.16x16.h5:model_reduction/compare_solution/enabled=false:save_solution/enabled=true:save_solution/file_path/prefix=results/fom_solution:visualization/enabled=true:visualization/file_path/prefix=results/paraview/fom/steady_ns" diff --git a/examples/steady_ns/jobs/06_rom_compare_16x16.sbatch b/examples/steady_ns/jobs/06_rom_compare_16x16.sbatch new file mode 100755 index 00000000..c6f22169 --- /dev/null +++ b/examples/steady_ns/jobs/06_rom_compare_16x16.sbatch @@ -0,0 +1,19 @@ +#!/bin/bash +#SBATCH --job-name=ns-rom-16 +#SBATCH --nodes=1 +#SBATCH --ntasks=1 +#SBATCH --cpus-per-task=1 +#SBATCH --mem=2G +#SBATCH --time=02:00:00 +#SBATCH --partition=pbatch +#SBATCH --account=sosu +#SBATCH --output=logs/%x-%j.out + +# shellcheck source=jobs/common.bash +source "$(dirname -- "${BASH_SOURCE[0]}")/common.bash" + +mkdir -p results/paraview/rom +"${MAIN_BIN}" -i steady_ns.yml -o results/rom_vs_fom.h5 -f \ + "main/mode=single_run:main/use_rom=true:mesh/component-wise/global_config=configs/paper.16x16.h5:basis/number_of_basis=40:basis/number_of_supremizer=40:model_reduction/nonlinear_handling=tensor:model_reduction/save_operator/prefix=rom/steady_ns_nb40:model_reduction/compare_solution/enabled=true:model_reduction/compare_solution/load_solution=true:model_reduction/compare_solution/fom_solution_file=results/fom_solution.h5:save_solution/enabled=false:visualization/enabled=true:visualization/file_path/prefix=results/paraview/rom/steady_ns" + +python3 report_results.py diff --git a/examples/steady_ns/jobs/common.bash b/examples/steady_ns/jobs/common.bash new file mode 100644 index 00000000..672e4704 --- /dev/null +++ b/examples/steady_ns/jobs/common.bash @@ -0,0 +1,19 @@ +set -euo pipefail + +EXAMPLE_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd) +cd "${EXAMPLE_DIR}" + +if [[ -n ${SCALEUPROM_MAIN:-} ]]; then + MAIN_BIN=${SCALEUPROM_MAIN} +elif [[ -x ../../bin/main ]]; then + MAIN_BIN=../../bin/main +elif [[ -x ../../build/bin/main ]]; then + MAIN_BIN=../../build/bin/main +else + echo "Cannot find the scaleupROM main executable; set SCALEUPROM_MAIN." >&2 + exit 1 +fi + +export OMP_NUM_THREADS=1 +mkdir -p logs results rom basis snapshots + diff --git a/examples/steady_ns/prepare_meshes.sh b/examples/steady_ns/prepare_meshes.sh new file mode 100755 index 00000000..53815ecf --- /dev/null +++ b/examples/steady_ns/prepare_meshes.sh @@ -0,0 +1,43 @@ +#!/bin/bash +set -euo pipefail + +example_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) + +repo_root=${SCALEUPROM_ROOT:-} +if [[ -z ${repo_root} ]]; then + search_dir=${example_dir} + while [[ ${search_dir} != / ]]; do + if [[ -d ${search_dir}/utils/python && -d ${search_dir}/examples/stokes/meshes ]]; then + repo_root=${search_dir} + break + fi + search_dir=$(dirname -- "${search_dir}") + done +fi + +if [[ -z ${repo_root} ]]; then + echo "Could not locate the scaleupROM source root." >&2 + exit 1 +fi + +converter=${SCALEUPROM_GMSH2MFEM:-${repo_root}/build/utils/gmsh2mfem} +if [[ ! -x ${converter} ]]; then + echo "Missing ${converter}; build scaleupROM before preparing this example." >&2 + exit 1 +fi + +cd "${example_dir}" +mkdir -p meshes configs + +for mesh in square-circle.msh.mfem square-square.msh.mfem \ + square-triangle.msh.mfem square-star.msh.mfem; do + cp "${repo_root}/examples/stokes/meshes/${mesh}" "meshes/${mesh}" +done + +# Promote the linear triangular empty-cell mesh to the exact cubic mesh used +# by the paper. gmsh2mfem appends ".mfem" to its input name. +cp "${repo_root}/test/meshes/square.tri.mesh" meshes/square.tri.mesh +"${converter}" -m meshes/square.tri.mesh -o 3 +mv meshes/square.tri.mesh.mfem meshes/square.tri-elem.mesh + +python3 generate_configs.py --output configs diff --git a/examples/steady_ns/report_results.py b/examples/steady_ns/report_results.py new file mode 100755 index 00000000..87e65efe --- /dev/null +++ b/examples/steady_ns/report_results.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +"""Print the timing and relative-error datasets from the 16x16 runs.""" + +from pathlib import Path + +import h5py +import numpy as np + + +def scalar(handle, key): + return float(np.asarray(handle[key][()]).reshape(-1)[0]) + + +results = Path(__file__).resolve().parent / "results" +with h5py.File(results / "fom_timings.h5", "r") as fom: + fom_assemble = scalar(fom, "fom_assemble") + fom_solve = scalar(fom, "fom_solve") + +with h5py.File(results / "rom_vs_fom.h5", "r") as rom: + rom_assemble = scalar(rom, "rom_assemble") + rom_solve = scalar(rom, "rom_solve") + error = np.asarray(rom["rel_error"][()]).reshape(-1) + +print(f"FOM assembly: {fom_assemble:.6g} s") +print(f"FOM solve: {fom_solve:.6g} s") +print(f"ROM assembly: {rom_assemble:.6g} s") +print(f"ROM solve: {rom_solve:.6g} s") +print(f"Velocity relative error: {error[0]:.6%}") +print(f"Pressure relative error: {error[1]:.6%}") + diff --git a/examples/steady_ns/steady_ns.yml b/examples/steady_ns/steady_ns.yml new file mode 100644 index 00000000..d389f6e4 --- /dev/null +++ b/examples/steady_ns/steady_ns.yml @@ -0,0 +1,201 @@ +main: + mode: single_run + use_rom: true + solver: steady-ns + +navier-stokes: + operator-type: base + +mesh: + type: component-wise + uniform_refinement: 1 + component-wise: + vertex_gap_threshold: 1.0e-9 + global_config: configs/component_catalog.h5 + components: + - name: empty + file: meshes/square.tri-elem.mesh + - name: square-circle + file: meshes/square-circle.msh.mfem + - name: square-square + file: meshes/square-square.msh.mfem + - name: square-triangle + file: meshes/square-triangle.msh.mfem + - name: square-star + file: meshes/square-star.msh.mfem + +domain-decomposition: + type: interior_penalty + +discretization: + order: 2 + full-discrete-galerkin: false + +solver: + direct_solve: true + print_level: 1 + max_iter: 100 + absolute_tolerance: 1.0e-10 + relative_tolerance: 1.0e-10 + +rom_solver: + print_level: 1 + max_iter: 100 + use_restart: false + absolute_tolerance: 1.0e-10 + relative_tolerance: 1.0e-10 + +visualization: + enabled: false + unified_paraview: false + visualize_error: true + file_path: + prefix: results/paraview/steady_ns + +save_solution: + enabled: false + file_path: + prefix: results/fom_solution + +parameterized_problem: + name: flow_past_array + +single_run: + choose_from_random_sample: false + flow_past_array: + nu: 0.04 + u0_x: 1.5 + u0_y: -0.8 + du_x: 0.0 + du_y: 0.0 + +sample_generation: + maximum_number_of_snapshots: 25000 + type: random + random_sample_generator: + number_of_samples: 400 + report_frequency: 10 + file_path: + prefix: snapshots/batch-1/steady_ns + parameters: + - key: mesh/component-wise/global_config + type: filename + minimum: 0 + maximum: 624 + format: configs/training/box-channel.config-%05d.h5 + - key: single_run/flow_past_array/u0_x + type: double + minimum: -1.0 + maximum: 1.0 + - key: single_run/flow_past_array/u0_y + type: double + minimum: -1.0 + maximum: 1.0 + - key: single_run/flow_past_array/du_x + type: double + minimum: -0.1 + maximum: 0.1 + - key: single_run/flow_past_array/du_y + type: double + minimum: -0.1 + maximum: 0.1 + - key: single_run/flow_past_array/offsets_x + type: double + minimum: 0.0 + maximum: 1.0 + - key: single_run/flow_past_array/offsets_y + type: double + minimum: 0.0 + maximum: 1.0 + - key: single_run/flow_past_array/k_u_x + type: double + minimum: -0.5 + maximum: 0.5 + - key: single_run/flow_past_array/k_u_y + type: double + minimum: -0.5 + maximum: 0.5 + - key: single_run/flow_past_array/k_v_x + type: double + minimum: -0.5 + maximum: 0.5 + - key: single_run/flow_past_array/k_v_y + type: double + minimum: -0.5 + maximum: 0.5 + +basis: + prefix: basis/steady_ns + number_of_basis: 40 + number_of_supremizer: 40 + tags: + - name: empty_vel + snapshot_format: + minimum: 1 + maximum: 5 + format: snapshots/batch-%d/steady_ns_sample_empty_vel_snapshot + - name: empty_pres + snapshot_format: + minimum: 1 + maximum: 5 + format: snapshots/batch-%d/steady_ns_sample_empty_pres_snapshot + - name: square-circle_vel + snapshot_format: + minimum: 1 + maximum: 5 + format: snapshots/batch-%d/steady_ns_sample_square-circle_vel_snapshot + - name: square-circle_pres + snapshot_format: + minimum: 1 + maximum: 5 + format: snapshots/batch-%d/steady_ns_sample_square-circle_pres_snapshot + - name: square-square_vel + snapshot_format: + minimum: 1 + maximum: 5 + format: snapshots/batch-%d/steady_ns_sample_square-square_vel_snapshot + - name: square-square_pres + snapshot_format: + minimum: 1 + maximum: 5 + format: snapshots/batch-%d/steady_ns_sample_square-square_pres_snapshot + - name: square-triangle_vel + snapshot_format: + minimum: 1 + maximum: 5 + format: snapshots/batch-%d/steady_ns_sample_square-triangle_vel_snapshot + - name: square-triangle_pres + snapshot_format: + minimum: 1 + maximum: 5 + format: snapshots/batch-%d/steady_ns_sample_square-triangle_pres_snapshot + - name: square-star_vel + snapshot_format: + minimum: 1 + maximum: 5 + format: snapshots/batch-%d/steady_ns_sample_square-star_vel_snapshot + - name: square-star_pres + snapshot_format: + minimum: 1 + maximum: 5 + format: snapshots/batch-%d/steady_ns_sample_square-star_pres_snapshot + svd: + save_spectrum: true + update_right_sv: false + visualization: + enabled: false + prefix: results/paraview/basis/steady_ns + +model_reduction: + separate_variable_basis: true + linear_solver_type: direct + linear_system_type: us + nonlinear_handling: tensor + subdomain_training: universal + save_operator: + level: component + prefix: rom/steady_ns_nb40 + compare_solution: + enabled: true + load_solution: true + fom_solution_file: results/fom_solution.h5 diff --git a/examples/steady_ns/submit_workflow.sh b/examples/steady_ns/submit_workflow.sh new file mode 100755 index 00000000..2c7e7158 --- /dev/null +++ b/examples/steady_ns/submit_workflow.sh @@ -0,0 +1,34 @@ +#!/bin/bash +set -euo pipefail + +example_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) +cd "${example_dir}" +mkdir -p logs + +extra_sbatch_args=("$@") + +submit() { + local dependency=$1 + local script=$2 + local result + local args=(--parsable) + if [[ -n ${dependency} ]]; then + args+=("--dependency=afterok:${dependency}") + fi + result=$(sbatch "${args[@]}" "${extra_sbatch_args[@]}" "${script}") + printf '%s' "${result%%;*}" +} + +mesh_id=$(submit "" jobs/00_mesh.sbatch) +samples_id=$(submit "${mesh_id}" jobs/01_samples.sbatch) +basis_id=$(submit "${samples_id}" jobs/02_basis.sbatch) +build_id=$(submit "${basis_id}" jobs/04_build_rom.sbatch) +fom_id=$(submit "${mesh_id}" jobs/05_fom_16x16.sbatch) +rom_id=$(submit "${build_id}:${fom_id}" jobs/06_rom_compare_16x16.sbatch) + +printf 'mesh: %s\n' "${mesh_id}" +printf 'samples: %s\n' "${samples_id}" +printf 'basis: %s\n' "${basis_id}" +printf 'ROM build: %s\n' "${build_id}" +printf '16x16 FOM: %s\n' "${fom_id}" +printf '16x16 ROM: %s\n' "${rom_id}" From 1210aefd8e643f80c497d225693763505210505d Mon Sep 17 00:00:00 2001 From: Seung Whan Chung Date: Wed, 7 Oct 2026 16:25:29 -0700 Subject: [PATCH 2/2] changing account --- examples/steady_ns/jobs/00_mesh.sbatch | 2 +- examples/steady_ns/jobs/01_samples.sbatch | 2 +- examples/steady_ns/jobs/02_basis.sbatch | 2 +- examples/steady_ns/jobs/03_auxiliary.sbatch | 2 +- examples/steady_ns/jobs/04_build_rom.sbatch | 2 +- examples/steady_ns/jobs/05_fom_16x16.sbatch | 2 +- examples/steady_ns/jobs/06_rom_compare_16x16.sbatch | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/steady_ns/jobs/00_mesh.sbatch b/examples/steady_ns/jobs/00_mesh.sbatch index b8fd08b3..ad2d12ad 100755 --- a/examples/steady_ns/jobs/00_mesh.sbatch +++ b/examples/steady_ns/jobs/00_mesh.sbatch @@ -6,7 +6,7 @@ #SBATCH --mem=2G #SBATCH --time=00:30:00 #SBATCH --partition=pbatch -#SBATCH --account=sosu +#SBATCH --account=genddfem #SBATCH --output=logs/%x-%j.out set -euo pipefail diff --git a/examples/steady_ns/jobs/01_samples.sbatch b/examples/steady_ns/jobs/01_samples.sbatch index 20f1dbb7..df07e6e6 100755 --- a/examples/steady_ns/jobs/01_samples.sbatch +++ b/examples/steady_ns/jobs/01_samples.sbatch @@ -7,7 +7,7 @@ #SBATCH --mem=2G #SBATCH --time=24:00:00 #SBATCH --partition=pbatch -#SBATCH --account=sosu +#SBATCH --account=genddfem #SBATCH --output=logs/%x-%A_%a.out # shellcheck source=jobs/common.bash diff --git a/examples/steady_ns/jobs/02_basis.sbatch b/examples/steady_ns/jobs/02_basis.sbatch index ae34a81e..fa746673 100755 --- a/examples/steady_ns/jobs/02_basis.sbatch +++ b/examples/steady_ns/jobs/02_basis.sbatch @@ -6,7 +6,7 @@ #SBATCH --mem-per-cpu=2G #SBATCH --time=24:00:00 #SBATCH --partition=pbatch -#SBATCH --account=sosu +#SBATCH --account=genddfem #SBATCH --output=logs/%x-%j.out # shellcheck source=jobs/common.bash diff --git a/examples/steady_ns/jobs/03_auxiliary.sbatch b/examples/steady_ns/jobs/03_auxiliary.sbatch index f31127bb..d620b698 100755 --- a/examples/steady_ns/jobs/03_auxiliary.sbatch +++ b/examples/steady_ns/jobs/03_auxiliary.sbatch @@ -7,7 +7,7 @@ #SBATCH --mem=2G #SBATCH --time=02:00:00 #SBATCH --partition=pbatch -#SBATCH --account=sosu +#SBATCH --account=genddfem #SBATCH --output=logs/%x-%j.out # shellcheck source=jobs/common.bash diff --git a/examples/steady_ns/jobs/04_build_rom.sbatch b/examples/steady_ns/jobs/04_build_rom.sbatch index 4580d6b1..d63e0f1a 100755 --- a/examples/steady_ns/jobs/04_build_rom.sbatch +++ b/examples/steady_ns/jobs/04_build_rom.sbatch @@ -6,7 +6,7 @@ #SBATCH --mem=2G #SBATCH --time=02:00:00 #SBATCH --partition=pbatch -#SBATCH --account=sosu +#SBATCH --account=genddfem #SBATCH --output=logs/%x-%j.out # shellcheck source=jobs/common.bash diff --git a/examples/steady_ns/jobs/05_fom_16x16.sbatch b/examples/steady_ns/jobs/05_fom_16x16.sbatch index 475b7415..2bf1e5ab 100755 --- a/examples/steady_ns/jobs/05_fom_16x16.sbatch +++ b/examples/steady_ns/jobs/05_fom_16x16.sbatch @@ -6,7 +6,7 @@ #SBATCH --mem=2G #SBATCH --time=02:00:00 #SBATCH --partition=pbatch -#SBATCH --account=sosu +#SBATCH --account=genddfem #SBATCH --output=logs/%x-%j.out # shellcheck source=jobs/common.bash diff --git a/examples/steady_ns/jobs/06_rom_compare_16x16.sbatch b/examples/steady_ns/jobs/06_rom_compare_16x16.sbatch index c6f22169..54028645 100755 --- a/examples/steady_ns/jobs/06_rom_compare_16x16.sbatch +++ b/examples/steady_ns/jobs/06_rom_compare_16x16.sbatch @@ -6,7 +6,7 @@ #SBATCH --mem=2G #SBATCH --time=02:00:00 #SBATCH --partition=pbatch -#SBATCH --account=sosu +#SBATCH --account=genddfem #SBATCH --output=logs/%x-%j.out # shellcheck source=jobs/common.bash