diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..a23ac1d --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,40 @@ +name: Tests + +on: + push: + branches: + - main + - master + pull_request: + workflow_dispatch: + +jobs: + pytest: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: + - "3.10" + - "3.11" + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: pip + cache-dependency-path: | + requirements.txt + pyproject.toml + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Run pytest + run: pytest -q diff --git a/README.md b/README.md index c80fa6b..a4ac26f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ -# charm_kit +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![GitHub Stars](https://img.shields.io/github/stars/KiT-RT/CharmKiT)](https://github.com/KiT-RT/CharmKiT/stargazers) +[![Tests](https://github.com/KiT-RT/CharmKiT/actions/workflows/tests.yml/badge.svg)](https://github.com/KiT-RT/CharmKiT/actions/workflows/tests.yml) + +# charm_kit: A wrapper for KiT-RT to conduct simulation sweeps fast + charm_kit is a benchmarking suite for the CharmNet project, providing automated parameter studies and test case management for the [KiT-RT PDE simulator](https://kit-rt.readthedocs.io/en/develop/index.html). It enables reproducible runs of radiative transfer test cases such as the lattice and hohlraum setups, using Python scripts to manage parameter sweeps, configuration, and result collection. charm_kit supports both high-performance computing (HPC) and local (no-HPC) execution modes, leveraging Singularity containers for reproducibility. @@ -34,6 +38,15 @@ Preliminaries: ``` If on a cluster without root, build the container locally and upload it to `charm_kit/kitrt_code/tools/singularity/`. +## Testing + +Run unit tests from the repo root: + +```bash +poetry install --with dev +poetry run pytest -q +``` + ## How charm_kit Works @@ -68,7 +81,6 @@ Execution and I/O flags: - `--slurm`: Submit jobs through SLURM. - `--singularity`: Run KiT-RT through the CPU Singularity image. - `--cuda`: Run KiT-RT through the CUDA Singularity image (`--nv` is added automatically). -- `--load-from-npz`: Load parameter samples from NPZ input (script-dependent behavior). - `--csv CSV`: Read design parameters from CSV and write QOIs back to that CSV. - `--config CONFIG`: Path to a TOML hyperparameter file. - `-q`, `--quiet`: Suppress solver stdout/stderr output. @@ -108,9 +120,9 @@ Precedence for hyperparameters is: 1. **Local mode, raw (no Singularity)** ```bash - python3 run_lattice.py + poetry run python run_lattice.py # or - python3 run_hohlraum.py + poetry run python run_hohlraum.py ``` Uses local executable: `./kitrt_code/build/KiT-RT`. @@ -118,9 +130,9 @@ Precedence for hyperparameters is: 2. **Local mode + Singularity (CPU)** ```bash - python3 run_lattice.py --singularity + poetry run python run_lattice.py --singularity # or - python3 run_hohlraum.py --singularity + poetry run python run_hohlraum.py --singularity ``` Uses image/executable: @@ -129,9 +141,9 @@ Precedence for hyperparameters is: 3. **Local mode + Singularity + GPU** ```bash - python3 run_lattice.py --cuda + poetry run python run_lattice.py --cuda # or - python3 run_hohlraum.py --cuda + poetry run python run_hohlraum.py --cuda ``` Uses image/executable: @@ -140,9 +152,9 @@ Precedence for hyperparameters is: 4. **SLURM mode, raw (no Singularity)** ```bash - python3 run_lattice.py --slurm + poetry run python run_lattice.py --slurm # or - python3 run_hohlraum.py --slurm + poetry run python run_hohlraum.py --slurm ``` Generated SLURM scripts call: `srun ./kitrt_code/build/KiT-RT ...`. @@ -150,9 +162,9 @@ Precedence for hyperparameters is: 5. **SLURM mode + Singularity (CPU)** ```bash - python3 run_lattice.py --slurm --singularity + poetry run python run_lattice.py --slurm --singularity # or - python3 run_hohlraum.py --slurm --singularity + poetry run python run_hohlraum.py --slurm --singularity ``` Generated SLURM scripts call: diff --git a/benchmarks/half_lattice/.DS_Store b/benchmarks/half_lattice/.DS_Store deleted file mode 100644 index 8fbd4ff..0000000 Binary files a/benchmarks/half_lattice/.DS_Store and /dev/null differ diff --git a/benchmarks/half_lattice/cfg_files/.gitkeep b/benchmarks/half_lattice/cfg_files/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/benchmarks/half_lattice/half_lattice.cfg b/benchmarks/half_lattice/half_lattice.cfg deleted file mode 100644 index adc5b57..0000000 --- a/benchmarks/half_lattice/half_lattice.cfg +++ /dev/null @@ -1,54 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Lattice Benchmarking File SN % -% Author % -% Date 08.01.2024 % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% -% ----IO specification ---- -% -OUTPUT_DIR = result -OUTPUT_FILE = half_lattice -LOG_DIR = result/logs -LOG_FILE = half_lattice -MESH_FILE = mesh/half_lattice_p0.02.su2 -FORCE_CONNECTIVITY_RECOMPUTE = YES -% -% --- Problem definition --- -% -PROBLEM = HALF_LATTICE -TIME_FINAL = 3.2 -SPATIAL_DIM = 2 -SOURCE_MAGNITUDE = 1.0 -LATTICE_DSGN_ABSORPTION_BLUE = 10 -LATTICE_DSGN_SCATTER_WHITE = 1 -% -% ---- Solver specifications ---- -% -% Solver type -HPC_SOLVER = YES -SOLVER = SN_SOLVER -% CFL number -CFL_NUMBER = 0.4 -% Space Integration order -RECONS_ORDER = 1 -% Time integration order -TIME_INTEGRATION_ORDER = 1 -% -% ---- Boundary Conditions ---- -% -BC_NEUMANN = ( reflecting, void ) -% -% ----- Quadrature Specification --- -% -QUAD_TYPE = GAUSS_LEGENDRE_TENSORIZED_2D -QUAD_ORDER = 10 -% -% ----- Output ---- -% -VOLUME_OUTPUT = (MINIMAL) -VOLUME_OUTPUT_FREQUENCY = 0 -SCREEN_OUTPUT = (ITER, MASS, WALL_TIME, RMS_FLUX, CUR_PARTICLE_ABSORPTION, TOTAL_PARTICLE_ABSORPTION, CUR_OUTFLOW_P1, TOTAL_OUTFLOW_P1, CUR_OUTFLOW_P2, TOTAL_OUTFLOW_P2 ) -SCREEN_OUTPUT_FREQUENCY = 100 -HISTORY_OUTPUT = (ITER, MASS, WALL_TIME, RMS_FLUX, CUR_PARTICLE_ABSORPTION, TOTAL_PARTICLE_ABSORPTION, CUR_OUTFLOW_P1, TOTAL_OUTFLOW_P1, CUR_OUTFLOW_P2, TOTAL_OUTFLOW_P2 ) -HISTORY_OUTPUT_FREQUENCY = 1 diff --git a/benchmarks/half_lattice/mesh/.DS_Store b/benchmarks/half_lattice/mesh/.DS_Store deleted file mode 100644 index fcdcf67..0000000 Binary files a/benchmarks/half_lattice/mesh/.DS_Store and /dev/null differ diff --git a/benchmarks/half_lattice/mesh/half_lattice_homogeneous.geo b/benchmarks/half_lattice/mesh/half_lattice_homogeneous.geo deleted file mode 100644 index 468cb13..0000000 --- a/benchmarks/half_lattice/mesh/half_lattice_homogeneous.geo +++ /dev/null @@ -1,214 +0,0 @@ -cl_fine = 0.01; -cl_mid = cl_fine * 2; -cl_coarse = cl_fine * 3; -cl_coarsest = cl_fine * 4; - -Point(2) = {3.5, -3.5, 0, cl_coarsest}; - -Point(4) = {3.5, 3.5, 0, cl_coarsest}; - -// Inner grid -Point(5) = { 0., -2.5, 0, cl_coarse }; -Point(6) = { 0., -1.5, 0, cl_mid }; -Point(7) = { 0., -0.5, 0, cl_fine }; -Point(8) = { 0., 0.5, 0, cl_fine }; -Point(9) = { 0., 1.5, 0, cl_mid }; -Point(10) = { 0., 2.5, 0, cl_coarse }; - -Point(71) = { 0.5, -2.5, 0, cl_coarse }; -Point(73) = { 0.5, -1.5, 0, cl_mid }; -Point(75) = { 0.5, -0.5, 0, cl_fine }; -Point(77) = { 0.5, 0.5, 0, cl_fine }; -Point(79) = { 0.5, 1.5, 0, cl_mid }; -Point(93) = { 1.5, -2.5, 0, cl_coarse }; -Point(95) = { 1.5, -1.5, 0, cl_mid }; -Point(97) = { 1.5, -0.5, 0, cl_mid }; -Point(99) = { 1.5, 0.5, 0, cl_mid }; -Point(101) = { 1.5, 1.5, 0, cl_mid }; -Point(103) = { 1.5, 2.5, 0, cl_coarse }; -Point(115) = { 2.5, -2.5, 0, cl_coarse }; -Point(117) = { 2.5, -1.5, 0, cl_coarse }; -Point(119) = { 2.5, -0.5, 0, cl_coarse }; -Point(121) = { 2.5, 0.5, 0, cl_coarse }; -Point(123) = { 2.5, 1.5, 0, cl_coarse }; -Point(125) = { 2.5, 2.5, 0, cl_coarse }; - -// helper boundary points -Point(131) = { 0.0, -3.5, 0, cl_coarsest }; -//Point(132) = { 0.5, -3.5, 0, cl_coarsest }; -//Point(134) = { 1.5, -3.5, 0, cl_coarsest }; -//Point(136) = { 2.5, -3.5, 0, cl_coarsest }; - -Point(142) = { 0.0, 3.5, 0, cl_coarsest }; -//Point(143) = { 0.5, 3.5, 0, cl_coarsest }; -//Point(145) = { 1.5, 3.5, 0, cl_coarsest }; -//Point(147) = { 2.5, 3.5, 0, cl_coarsest }; - - -//Point(159) = { 3.5, -2.5, 0, cl_coarsest }; -//Point(161) = { 3.5, -1.5, 0, cl_coarsest }; -//Point(163) = { 3.5, -0.5, 0, cl_coarsest }; -//Point(165) = { 3.5, 0.5, 0, cl_coarsest }; -//Point(167) = { 3.5, 1.5, 0, cl_coarsest }; -//Point(169) = { 3.5, 2.5, 0, cl_coarsest }; - -// Horizontal and vertical lines in inner grid -//+ -Line(26) = {142, 10}; -//+ -Line(27) = {10, 9}; -//+ -Line(28) = {9, 8}; -//+ -Line(29) = {8, 7}; -//+ -Line(30) = {7, 6}; -//+ -Line(31) = {6, 5}; -//+ -Line(32) = {5, 131}; -//+ - - -//+ -Line(49) = {7, 75}; -//+ -Line(50) = {75, 77}; -//+ -Line(51) = {77, 8}; -//+ -Line(52) = {77, 79}; -//+ -Line(53) = {79, 101}; -//+ -Line(54) = {101, 99}; -//+ -Line(55) = {99, 77}; -//+ -Line(56) = {75, 73}; -//+ -Line(57) = {73, 95}; -//+ -Line(58) = {95, 97}; -//+ -Line(59) = {97, 75}; -//+ -Line(60) = {95, 93}; -//+ -Line(61) = {93, 115}; -//+ -Line(62) = {115, 117}; -//+ -Line(63) = {117, 95}; -//+ -Line(64) = {99, 97}; -//+ -Line(65) = {97, 119}; -//+ -Line(66) = {119, 121}; -//+ -Line(67) = {121, 99}; -//+ -Line(68) = {101, 123}; -//+ -Line(69) = {123, 125}; -//+ -Line(70) = {125, 103}; -//+ -Line(71) = {103, 101}; -//+ -Line(72) = {73, 71}; -//+ -Line(73) = {71, 5}; -//+ -Line(74) = {6, 73}; -//+ -Line(79) = {103, 10}; -//+ -Line(80) = {123, 121}; -//+ -Line(81) = {119, 117}; -//+ -Line(82) = {93, 71}; -//+ -Curve Loop(1) = {73, -31, 74, 72}; -//+ -Plane Surface(1) = {1}; -//+ -Curve Loop(2) = {74, -56, -49, 30}; -//+ -Plane Surface(2) = {2}; -//+ -Curve Loop(3) = {49, 50, 51, 29}; -//+ -Plane Surface(3) = {3}; -//+ -Curve Loop(4) = {57, 58, 59, 56}; -//+ -Plane Surface(4) = {4}; -//+ -Curve Loop(5) = {60, 61, 62, 63}; -//+ -Plane Surface(5) = {5}; -//+ -Curve Loop(6) = {65, 66, 67, 64}; -//+ -Plane Surface(6) = {6}; -//+ -Curve Loop(7) = {55, -50, -59, -64}; -//+ -Plane Surface(7) = {7}; -//+ -Curve Loop(8) = {54, 55, 52, 53}; -//+ -Plane Surface(8) = {8}; -//+ -Curve Loop(9) = {68, 69, 70, 71}; -//+ -Plane Surface(9) = {9}; -//+ -//+ - -//+ -Line(75) = {131, 2}; -//+ -Line(76) = {2, 4}; -//+ -Line(77) = {4, 142}; -//+ -//+ -Line(78) = {9, 79}; -//+ -Curve Loop(11) = {52, -78, 28, -51}; -//+ -Plane Surface(11) = {11}; -//+ -Curve Loop(12) = {71, -53, -78, -27, -79}; -//+ -Plane Surface(13) = {12}; -//+ -Curve Loop(13) = {80, 67, -54, 68}; -//+ -Plane Surface(14) = {13}; -//+ -Curve Loop(14) = {81, 63, 58, 65}; -//+ -Plane Surface(15) = {14}; -//+ -Curve Loop(15) = {82, -72, 57, 60}; -//+ -Plane Surface(16) = {15}; -//+ -Curve Loop(16) = {75, 76, 77, 26, -79, -70, -69, 80, -66, 81, -62, -61, 82, 73, 32}; -//+ -Plane Surface(17) = {16}; - - -//Curve Loop(12) = {77, 26, 27, 78, 53, 54, -67, -66, -65, -58, -57, 72, 73, 32, 75, 76}; -//+ -//Plane Surface(12) = {5, 9, 12}; -//+ -Physical Curve("reflecting", 79) = {26, 27, 28, 29, 30, 31, 32}; -//+ -Physical Curve("void", 80) = {75, 76, 77}; -//+ diff --git a/benchmarks/half_lattice/mesh/half_lattice_rectangular.geo b/benchmarks/half_lattice/mesh/half_lattice_rectangular.geo deleted file mode 100644 index f103700..0000000 --- a/benchmarks/half_lattice/mesh/half_lattice_rectangular.geo +++ /dev/null @@ -1,27 +0,0 @@ -cl_fine = 0.01; - - -Point(2) = {3.5, -3.5, 0, cl_fine}; - -Point(4) = {3.5, 3.5, 0, cl_fine}; -Point(131) = { 0.0, -3.5, 0, cl_fine }; -Point(142) = { 0.0, 3.5, 0, cl_fine }; - - -Recombine Surface "*"; -//+ -Line(1) = {142, 4}; -//+ -Line(2) = {2, 4}; -//+ -Line(3) = {2, 131}; -//+ -Line(4) = {131, 142}; -//+ -Curve Loop(1) = {4, 1, -2, 3}; -//+ -Plane Surface(1) = {1}; -Transfinite Surface {1}; -Physical Curve("void", 61) = {1, 2, 3}; -Physical Curve("reflecting") = {4}; -//Recombine Surface "*"; \ No newline at end of file diff --git a/benchmarks/half_lattice/slurm_scripts/.gitkeep b/benchmarks/half_lattice/slurm_scripts/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/benchmarks/hohlraum/hyperparams.toml b/benchmarks/hohlraum/hyperparams.toml new file mode 100644 index 0000000..c8e2208 --- /dev/null +++ b/benchmarks/hohlraum/hyperparams.toml @@ -0,0 +1,14 @@ +[hyperparameters] +# Spatial and angular resolution ranges +grid_cell_size = [0.0075] +quad_order = [6] + +# Geometry ranges +green_center_x = [-0.1, 0.0, 0.1] +green_center_y = [-0.075, 0.0, 0.075] +red_right_top = [0.3, 0.4, 0.5] +red_right_bottom = [-0.5, -0.4, -0.3] +red_left_top = [0.3, 0.4, 0.5] +red_left_bottom = [-0.5, -0.4, -0.3] +horizontal_left = [-0.63, -0.6, -0.5] +horizontal_right = [0.5, 0.6, 0.63] diff --git a/benchmarks/lattice/hyperparams.toml b/benchmarks/lattice/hyperparams.toml new file mode 100644 index 0000000..52c9931 --- /dev/null +++ b/benchmarks/lattice/hyperparams.toml @@ -0,0 +1,10 @@ +[hyperparameters] +# Spatial resolution range (characteristic mesh cell size) +grid_cell_size = [0.01] + +# Angular quadrature order range (must be even) +quad_order = [4] + +# Material parameter ranges +abs_blue = [10.0] +scatter_white = [1.0] diff --git a/benchmarks/quarter_hohlraum/.DS_Store b/benchmarks/quarter_hohlraum/.DS_Store deleted file mode 100644 index 4d75d41..0000000 Binary files a/benchmarks/quarter_hohlraum/.DS_Store and /dev/null differ diff --git a/benchmarks/quarter_hohlraum/cfg_files/.gitkeep b/benchmarks/quarter_hohlraum/cfg_files/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/benchmarks/quarter_hohlraum/mesh/quarter_hohlraum.geo b/benchmarks/quarter_hohlraum/mesh/quarter_hohlraum.geo deleted file mode 100644 index 655029d..0000000 --- a/benchmarks/quarter_hohlraum/mesh/quarter_hohlraum.geo +++ /dev/null @@ -1,144 +0,0 @@ -cl_fine = 0.05; -_cl_finer = cl_fine / 3; - -// Outer points -Point(1) = {0.65, 0.65, 0, cl_fine}; -Point(2) = {0., 0.65, 0, cl_fine}; -Point(3) = {0.65, 0., 0, cl_fine}; -Point(4) = {0., 0., 0, cl_fine}; - -// Geometry features -// Black -Point(6) = {0.65, 0.6, 0, cl_fine}; - -Point(13) = {0.65, 0.4, 0, cl_fine}; -Point(14) = {0.6, 0.4, 0, cl_fine}; -Point(15) = {0.6, 0.0, 0, cl_fine}; - - -// Green (and blue) - -Point(19) = {0.2, 0.4, 0, _cl_finer}; -Point(20) = {0, 0.4, 0, _cl_finer}; -Point(21) = {0.2, 0, 0, _cl_finer}; - -Point(22) = {0.15, 0.35, 0, _cl_finer}; -Point(23) = {0.0, 0.35, 0, _cl_finer}; -Point(24) = {0.15, 0.0, 0, _cl_finer}; - - - -// Helper points and lines -Point(27) = {0.6, 0.6, 0, cl_fine}; - - - -Point(44) = { cl_fine, 0.6 , 0, _cl_finer*2}; -Point(45) = { 0, 0.6 , 0, _cl_finer*2}; -Point(46) = {cl_fine, 0.6 - cl_fine, 0, _cl_finer*2}; -Point(47) = {0, 0.6 - cl_fine, 0, _cl_finer*2}; - -Point(52) = {0.4 + cl_fine, cl_fine, 0, _cl_finer*2}; -Point(53) = {0.4 - cl_fine, cl_fine, 0, _cl_finer*2}; -Point(54) = {0.4 + cl_fine, 0, 0, _cl_finer*2}; -Point(55) = {0.4 - cl_fine, 0, 0, _cl_finer*2}; - -//+ -Line(1) = {2, 1}; -//+ -Line(2) = {1, 6}; -//+ -Line(3) = {6, 13}; -//+ -Line(4) = {13, 3}; -//+ -Line(5) = {3, 15}; -//+ -Line(6) = {54, 55}; -//+ -Line(7) = {55, 21}; -//+ -Line(8) = {21, 24}; -//+ -Line(9) = {24, 4}; -//+ -Line(10) = {4, 23}; -//+ -Line(11) = {23, 20}; -//+ -Line(12) = {20, 47}; -//+ -Line(13) = {47, 45}; -//+ -Line(14) = {45, 2}; - - -Line(15) = {24, 22}; -//+ -Line(16) = {22, 23}; -//+ -Line(17) = {20, 19}; -//+ -Line(18) = {19, 21}; -//+ -Line(19) = {55, 53}; -//+ -Line(20) = {53, 52}; -//+ -Line(21) = {52, 54}; -//+ -Line(22) = {47, 46}; -//+ -Line(23) = {46, 44}; -//+ -Line(24) = {44, 45}; -//+ -Line(25) = {44, 27}; -//+ -Line(26) = {27, 6}; -//+ -Line(27) = {27, 14}; -//+ -Line(28) = {14, 13}; -//+ -Line(29) = {54, 15}; -//+ -//+ -Line(30) = {14, 15}; -//+ -Curve Loop(1) = {10, -16, -15, 9}; -//+ -Plane Surface(1) = {1}; -//+ -Curve Loop(2) = {18, 8, 15, 16, 11, 17}; -//+ -Plane Surface(2) = {2}; -//+ -Curve Loop(3) = {7, -18, -17, 12, 22, 23, 25, 27, 30, -29, -21, -20, -19}; -//+ -Plane Surface(3) = {3}; -//+ -Curve Loop(4) = {23, 24, -13, 22}; -//+ -Plane Surface(4) = {4}; -//+ -Curve Loop(5) = {21, 6, 19, 20}; -//+ -Plane Surface(5) = {5}; -//+ -Curve Loop(6) = {5, -30, 28, 4}; -//+ -Plane Surface(6) = {6}; -//+ -Curve Loop(7) = {28, -3, -26, 27}; -//+ -Plane Surface(7) = {7}; -//+ -Curve Loop(8) = {26, -2, -1, -14, -24, 25}; -//+ -Plane Surface(8) = {8}; - - -Physical Curve("inflow", 60) = {3}; -//+ -Physical Curve("void", 61) = {1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12,13,14, 29}; \ No newline at end of file diff --git a/benchmarks/quarter_hohlraum/mesh/quarter_hohlraum_rectangular.geo b/benchmarks/quarter_hohlraum/mesh/quarter_hohlraum_rectangular.geo deleted file mode 100644 index 6a1d183..0000000 --- a/benchmarks/quarter_hohlraum/mesh/quarter_hohlraum_rectangular.geo +++ /dev/null @@ -1,29 +0,0 @@ -cl_fine = 0.05; -upper_right_red = 0.4; -horizontal_right_red = 0.6; - - -// Outer points -Point(1) = {0.65, 0.65, 0, cl_fine}; -Point(2) = {0., 0.65, 0, cl_fine}; -Point(3) = {0.65, 0., 0, cl_fine}; -Point(4) = {0., 0., 0, cl_fine}; -//+ -Line(1) = {2, 1}; -//+ -Line(2) = {1, 3}; -//+ -Line(3) = {3, 4}; -//+ -Line(4) = {4, 2}; -//+ -Curve Loop(1) = {4, 1, 2, 3}; -//+ -Plane Surface(1) = {1}; -//+ -Transfinite Surface {1}; - -Physical Curve("inflow", 60) = {2}; -//+ -Physical Curve("void", 61) = {1, 3, 4}; -//Recombine Surface "*"; \ No newline at end of file diff --git a/benchmarks/quarter_hohlraum/mesh/quarter_hohlraum_variable.geo b/benchmarks/quarter_hohlraum/mesh/quarter_hohlraum_variable.geo deleted file mode 100644 index 0e51d4b..0000000 --- a/benchmarks/quarter_hohlraum/mesh/quarter_hohlraum_variable.geo +++ /dev/null @@ -1,116 +0,0 @@ -cl_fine = 0.005; -cl_coarse =cl_fine*2; -upper_right_red = 0.4; -horizontal_right_red = 0.6; - -// Outer points -Point(1) = {0.65, 0.65, 0, cl_coarse}; -Point(2) = {0., 0.65, 0, cl_coarse}; -Point(3) = {0.65, 0., 0, cl_fine}; -Point(4) = {0., 0., 0, cl_coarse}; - -// Geometry features -// Black -Point(6) = {0.65, 0.6, 0, cl_fine}; - -Point(13) = {0.65,upper_right_red, 0, cl_fine}; -Point(14) = {horizontal_right_red, upper_right_red, 0, cl_fine}; -Point(15) = {horizontal_right_red, 0.0, 0, cl_fine}; - - -// Green (and blue) - -Point(19) = {0.2, 0.4, 0, cl_fine}; -Point(20) = {0, 0.4, 0, cl_fine}; -Point(21) = {0.2, 0, 0, cl_fine}; - -Point(22) = {0.15, 0.35, 0, cl_fine}; -Point(23) = {0.0, 0.35, 0, cl_fine}; -Point(24) = {0.15, 0.0, 0, cl_fine}; - - - -// Helper points and lines -Point(27) = {horizontal_right_red, 0.6, 0, cl_fine}; -Point(28) = {0.4, 0.0, 0, cl_fine}; - - - -Point(45) = { 0, 0.6 , 0, cl_fine*2}; - -//+ -Line(1) = {2, 1}; -//+ -Line(2) = {1, 6}; -//+ -Line(3) = {6, 13}; -//+ -Line(4) = {13, 3}; -//+ -Line(5) = {3, 15}; - -//+ -Line(7) = {28, 21}; -Line(13) = {15, 28}; -//+ -Line(8) = {21, 24}; -//+ -Line(9) = {24, 4}; -//+ -Line(10) = {4, 23}; -//+ -Line(11) = {23, 20}; -//+ -Line(12) = {20, 45}; -//+ -//+ -Line(14) = {45, 2}; - - -Line(15) = {24, 22}; -//+ -Line(16) = {22, 23}; -//+ -Line(17) = {20, 19}; -//+ -Line(18) = {19, 21}; -//+ -Line(24) = {45, 27}; -//+ -Line(26) = {27, 6}; -//+ -Line(27) = {27, 14}; -//+ -Line(28) = {14, 13}; -//+ -//+ -Line(30) = {14, 15}; -//+ -Curve Loop(1) = {10, -16, -15, 9}; -//+ -Plane Surface(1) = {1}; -//+ -Curve Loop(2) = {18, 8, 15, 16, 11, 17}; -//+ -Plane Surface(2) = {2}; -//+ -Curve Loop(3) = {7,13, -18, -17, 12, 24, 27, 30}; -//+ -Plane Surface(3) = {3}; -//+ -Curve Loop(6) = {5, -30, 28, 4}; -//+ -Plane Surface(6) = {6}; -//+ -Curve Loop(7) = {28, -3, -26, 27}; -//+ -Plane Surface(7) = {7}; -//+ -Curve Loop(8) = {24, 26, -2, -1, -14}; -//+ -Plane Surface(8) = {8}; - - -Physical Curve("inflow", 60) = {3,4,2}; -//+ -Physical Curve("void", 61) = {1, 14, 12, 11, 10, 9, 8, 7, 13, 5}; diff --git a/benchmarks/quarter_hohlraum/quarter_hohlraum.cfg b/benchmarks/quarter_hohlraum/quarter_hohlraum.cfg deleted file mode 100644 index bf8ac4b..0000000 --- a/benchmarks/quarter_hohlraum/quarter_hohlraum.cfg +++ /dev/null @@ -1,61 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% QuarterHohlraum Benchmarking File SN% -% Author % -% Date 27.02.2024 % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% ---- File specifications ---- -% -OUTPUT_DIR = result -% Output file -OUTPUT_FILE = quarter_hohlraum -% Log directory -LOG_DIR = result/logs -% Log file -LOG_FILE = quarter_hohlraum -% Mesh File -MESH_FILE = mesh/quarter_hohlraum.su2 -FORCE_CONNECTIVITY_RECOMPUTE = YES -% -% ---- Problem specifications ---- -% -PROBLEM = QUARTER_HOHLRAUM -SPATIAL_DIM = 2 -TIME_FINAL = 2.6 -% -% ---- Design Parameters --- -N_SAMPLING_PTS_LINE_GREEN = 100 -POS_RED_RIGHT_TOP = 0.4 -POS_BORDER_RED_RIGHT = 0.6 -% -% ---- Solver specifications ---- -% - -% Solver type -HPC_SOLVER = YES -SOLVER = SN_SOLVER -% CFL number -CFL_NUMBER = 0.5 -% Space Integration order -RECONS_ORDER =2 -% Time integration order -TIME_INTEGRATION_ORDER = 1 -% -% ---- Boundary Conditions ---- -% -BC_NEUMANN = ( void, inflow ) -% -% ---- Quadrature ---- -% -QUAD_TYPE = GAUSS_LEGENDRE_TENSORIZED_2D -QUAD_ORDER = 10 -% -% ----- Output ---- -% -VOLUME_OUTPUT = (MINIMAL, MOMENTS) -VOLUME_OUTPUT_FREQUENCY = 0 -SCREEN_OUTPUT = ( ITER, WALL_TIME, MASS, RMS_FLUX, VTK_OUTPUT, CSV_OUTPUT, CUR_OUTFLOW, TOTAL_OUTFLOW, MAX_OUTFLOW, TOTAL_PARTICLE_ABSORPTION_CENTER, TOTAL_PARTICLE_ABSORPTION_VERTICAL, TOTAL_PARTICLE_ABSORPTION_HORIZONTAL, PROBE_MOMENT_TIME_TRACE, VAR_ABSORPTION_GREEN) -SCREEN_OUTPUT_FREQUENCY = 100 -HISTORY_OUTPUT = ( ITER, WALL_TIME, MASS, RMS_FLUX, VTK_OUTPUT, CSV_OUTPUT, CUR_OUTFLOW, TOTAL_OUTFLOW, MAX_OUTFLOW, TOTAL_PARTICLE_ABSORPTION_CENTER, TOTAL_PARTICLE_ABSORPTION_VERTICAL, TOTAL_PARTICLE_ABSORPTION_HORIZONTAL, PROBE_MOMENT_TIME_TRACE, VAR_ABSORPTION_GREEN) -HISTORY_OUTPUT_FREQUENCY = 1 - diff --git a/benchmarks/quarter_hohlraum/slurm_scripts/.gitkeep b/benchmarks/quarter_hohlraum/slurm_scripts/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/poetry.lock b/poetry.lock index 802d3c6..39e80bd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,37 @@ # This file is automatically @generated by Poetry 2.3.2 and should not be changed by hand. +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["dev"] +markers = "sys_platform == \"win32\"" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +groups = ["dev"] +markers = "python_version == \"3.10\"" +files = [ + {file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"}, + {file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} + +[package.extras] +test = ["pytest (>=6)"] + [[package]] name = "gmsh" version = "4.15.0" @@ -14,6 +46,18 @@ files = [ {file = "gmsh-4.15.0-py2.py3-none-win_amd64.whl", hash = "sha256:a5b9867f88af59aff269a93abbd009551fbc263eb94a165a25a0c8072bae13db"}, ] +[[package]] +name = "iniconfig" +version = "2.3.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}, + {file = "iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}, +] + [[package]] name = "numpy" version = "2.2.6" @@ -163,6 +207,18 @@ files = [ {file = "numpy-2.4.2.tar.gz", hash = "sha256:659a6107e31a83c4e33f763942275fd278b21d095094044eb35569e86a21ddae"}, ] +[[package]] +name = "packaging" +version = "26.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}, + {file = "packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}, +] + [[package]] name = "pandas" version = "2.3.3" @@ -350,6 +406,61 @@ test = ["hypothesis (>=6.116.0)", "pytest (>=8.3.4)", "pytest-xdist (>=3.6.1)"] timezone = ["pytz (>=2024.2)"] xml = ["lxml (>=5.3.0)"] +[[package]] +name = "pluggy" +version = "1.6.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, + {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["coverage", "pytest", "pytest-benchmark"] + +[[package]] +name = "pygments" +version = "2.19.2" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, + {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pytest" +version = "9.0.2" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b"}, + {file = "pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11"}, +] + +[package.dependencies] +colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""} +iniconfig = ">=1.0.1" +packaging = ">=22" +pluggy = ">=1.5,<2" +pygments = ">=2.7.2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -390,6 +501,77 @@ files = [ {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] +[[package]] +name = "tomli" +version = "2.4.0" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +markers = "python_version == \"3.10\"" +files = [ + {file = "tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867"}, + {file = "tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9"}, + {file = "tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95"}, + {file = "tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76"}, + {file = "tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d"}, + {file = "tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576"}, + {file = "tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a"}, + {file = "tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa"}, + {file = "tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614"}, + {file = "tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1"}, + {file = "tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8"}, + {file = "tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a"}, + {file = "tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1"}, + {file = "tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b"}, + {file = "tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51"}, + {file = "tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729"}, + {file = "tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da"}, + {file = "tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3"}, + {file = "tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0"}, + {file = "tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e"}, + {file = "tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4"}, + {file = "tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e"}, + {file = "tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c"}, + {file = "tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f"}, + {file = "tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86"}, + {file = "tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87"}, + {file = "tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132"}, + {file = "tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6"}, + {file = "tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc"}, + {file = "tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66"}, + {file = "tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d"}, + {file = "tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702"}, + {file = "tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8"}, + {file = "tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776"}, + {file = "tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475"}, + {file = "tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2"}, + {file = "tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9"}, + {file = "tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0"}, + {file = "tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df"}, + {file = "tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d"}, + {file = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f"}, + {file = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b"}, + {file = "tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087"}, + {file = "tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd"}, + {file = "tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4"}, + {file = "tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a"}, + {file = "tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c"}, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +description = "Backported and Experimental Type Hints for Python 3.9+" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +markers = "python_version == \"3.10\"" +files = [ + {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, + {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, +] + [[package]] name = "tzdata" version = "2025.3" @@ -406,4 +588,4 @@ files = [ [metadata] lock-version = "2.1" python-versions = ">=3.10,<3.13" -content-hash = "29584e446de63325ccc1f34d02224ec9ef7b54f8c179bbad63e0f39471df94af" +content-hash = "ab4ff4d38bc164bbcedda8a6e341606b3f91d29bbd820fe198a805982f747a75" diff --git a/pyproject.toml b/pyproject.toml index 3ec4fe5..f737746 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,12 @@ gmsh = "*" numpy = "*" pandas = "*" +[tool.poetry.group.dev.dependencies] +pytest = "*" + +[tool.pytest.ini_options] +pythonpath = ["."] + [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" diff --git a/requirements.txt b/requirements.txt index 4bf9135..87b15df 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ gmsh numpy -pandas \ No newline at end of file +pandas +pytest diff --git a/run_hohlraum.py b/run_hohlraum.py index 5b99e14..edd2112 100644 --- a/run_hohlraum.py +++ b/run_hohlraum.py @@ -7,7 +7,6 @@ from src.simulation_utils import execute_slurm_scripts, wait_for_slurm_jobs from src.general_utils import ( create_hohlraum_samples_from_param_range, - load_hohlraum_samples_from_csv, delete_slurm_scripts, load_toml_hyperparameters, ) @@ -17,13 +16,11 @@ def main(): args = parse_hohlraum_args() print(f"HPC mode = { args.use_slurm}") - print(f"Load from npz = {args.load_from_npz}") print(f"HPC with singularity = { args.use_singularity}") print(f"CUDA mode = {args.cuda}") print(f"Quiet mode = {args.quiet}") hpc_operation = args.use_slurm # Flag when using HPC cluster - load_from_npz = args.load_from_npz use_cuda = args.cuda if use_cuda and hpc_operation: raise SystemExit( @@ -66,70 +63,92 @@ def override_csv_column(df, values, column_name, arg_name): override_csv_column( df, - args.green_center_x - if args.green_center_x is not None - else hyper.get("green_center_x"), + ( + args.green_center_x + if args.green_center_x is not None + else hyper.get("green_center_x") + ), "green_center_x", "--green-center-x", ) override_csv_column( df, - args.green_center_y - if args.green_center_y is not None - else hyper.get("green_center_y"), + ( + args.green_center_y + if args.green_center_y is not None + else hyper.get("green_center_y") + ), "green_center_y", "--green-center-y", ) override_csv_column( df, - args.red_right_top if args.red_right_top is not None else hyper.get("red_right_top"), + ( + args.red_right_top + if args.red_right_top is not None + else hyper.get("red_right_top") + ), "red_right_top", "--red-right-top", ) override_csv_column( df, - args.red_right_bottom - if args.red_right_bottom is not None - else hyper.get("red_right_bottom"), + ( + args.red_right_bottom + if args.red_right_bottom is not None + else hyper.get("red_right_bottom") + ), "red_right_bottom", "--red-right-bottom", ) override_csv_column( df, - args.red_left_top if args.red_left_top is not None else hyper.get("red_left_top"), + ( + args.red_left_top + if args.red_left_top is not None + else hyper.get("red_left_top") + ), "red_left_top", "--red-left-top", ) override_csv_column( df, - args.red_left_bottom - if args.red_left_bottom is not None - else hyper.get("red_left_bottom"), + ( + args.red_left_bottom + if args.red_left_bottom is not None + else hyper.get("red_left_bottom") + ), "red_left_bottom", "--red-left-bottom", ) override_csv_column( df, - args.horizontal_left - if args.horizontal_left is not None - else hyper.get("horizontal_left"), + ( + args.horizontal_left + if args.horizontal_left is not None + else hyper.get("horizontal_left") + ), "horizontal_left", "--horizontal-left", ) override_csv_column( df, - args.horizontal_right - if args.horizontal_right is not None - else hyper.get("horizontal_right"), + ( + args.horizontal_right + if args.horizontal_right is not None + else hyper.get("horizontal_right") + ), "horizontal_right", "--horizontal-right", ) # Allow overwriting spatial and angular resolution override_csv_column( df, - args.grid_cell_size - if args.grid_cell_size is not None - else hyper.get("grid_cell_size"), + ( + args.grid_cell_size + if args.grid_cell_size is not None + else hyper.get("grid_cell_size") + ), "grid_cell_size", "--grid-cell-size", ) @@ -144,20 +163,24 @@ def override_csv_column(df, values, column_name, arg_name): # left_red_top, left_red_bottom, right_red_top, right_red_bottom, # horizontal_left, horizontal_right, green_center_x, green_center_y, # grid_cell_size, quad_order - design_params = df[ - [ - "red_left_top", - "red_left_bottom", - "red_right_top", - "red_right_bottom", - "horizontal_left", - "horizontal_right", - "green_center_x", - "green_center_y", - "grid_cell_size", - "quad_order", + design_params = ( + df[ + [ + "red_left_top", + "red_left_bottom", + "red_right_top", + "red_right_bottom", + "horizontal_left", + "horizontal_right", + "green_center_x", + "green_center_y", + "grid_cell_size", + "quad_order", + ] ] - ].to_numpy().T + .to_numpy() + .T + ) design_param_names = np.array( [ "pos_red_left_top", @@ -172,89 +195,59 @@ def override_csv_column(df, values, column_name, arg_name): "grid_quad_order", ] ) - elif load_from_npz: - design_params, design_param_names = load_hohlraum_samples_from_csv() else: # --- Define parameter ranges --- - - # characteristic length of the cells: #grid cells = O(1/cell_size^2) parameter_range_grid_cell_size = as_list_or_none( args.grid_cell_size if args.grid_cell_size is not None else hyper.get("grid_cell_size") ) or [0.0075] - - # quadrature order (must be an even number): #velocity grid cells = O(order^2) parameter_range_quad_order = as_list_or_none( args.quad_order if args.quad_order is not None else hyper.get("quad_order") ) or [6] if any(int(q) % 2 != 0 for q in parameter_range_quad_order): raise SystemExit("ERROR: --quad-order must be an even number.") - # balance the two roughly (see Paper Fig 6) - - # Define the geometry settings of the test case parameter_range_green_center_x = as_list_or_none( args.green_center_x if args.green_center_x is not None else hyper.get("green_center_x") - ) or [-0.1, 0.0, 0.1] # Default: 0 - parameter_range_green_center_y = ( - as_list_or_none( - args.green_center_y - if args.green_center_y is not None - else hyper.get("green_center_y") - ) - or [-0.075, 0.0, 0.075] - ) # Default: 0 - parameter_range_red_right_top = ( - as_list_or_none( - args.red_right_top - if args.red_right_top is not None - else hyper.get("red_right_top") - ) - or [0.3, 0.4, 0.5] - ) # Default: 0.4 - parameter_range_red_right_bottom = ( - as_list_or_none( - args.red_right_bottom - if args.red_right_bottom is not None - else hyper.get("red_right_bottom") - ) - or [-0.5, -0.4, -0.3] - ) # Default: -0.4 - parameter_range_red_left_top = ( - as_list_or_none( - args.red_left_top - if args.red_left_top is not None - else hyper.get("red_left_top") - ) - or [0.3, 0.4, 0.5] - ) # Default: 0.4 - parameter_range_red_left_bottom = ( - as_list_or_none( - args.red_left_bottom - if args.red_left_bottom is not None - else hyper.get("red_left_bottom") - ) - or [-0.5, -0.4, -0.3] - ) # Default: -0.4 - parameter_range_horizontal_left = ( - as_list_or_none( - args.horizontal_left - if args.horizontal_left is not None - else hyper.get("horizontal_left") - ) - or [-0.63, -0.6, -0.5] - ) # Default: -0.6 - parameter_range_horizontal_right = ( - as_list_or_none( - args.horizontal_right - if args.horizontal_right is not None - else hyper.get("horizontal_right") - ) - or [0.5, 0.6, 0.63] - ) # Default: 0.6 + ) or [0.0] + parameter_range_green_center_y = as_list_or_none( + args.green_center_y + if args.green_center_y is not None + else hyper.get("green_center_y") + ) or [0.0] + parameter_range_red_right_top = as_list_or_none( + args.red_right_top + if args.red_right_top is not None + else hyper.get("red_right_top") + ) or [0.4] + parameter_range_red_right_bottom = as_list_or_none( + args.red_right_bottom + if args.red_right_bottom is not None + else hyper.get("red_right_bottom") + ) or [-0.4] + parameter_range_red_left_top = as_list_or_none( + args.red_left_top + if args.red_left_top is not None + else hyper.get("red_left_top") + ) or [0.4] + parameter_range_red_left_bottom = as_list_or_none( + args.red_left_bottom + if args.red_left_bottom is not None + else hyper.get("red_left_bottom") + ) or [-0.4] + parameter_range_horizontal_left = as_list_or_none( + args.horizontal_left + if args.horizontal_left is not None + else hyper.get("horizontal_left") + ) or [-0.6] + parameter_range_horizontal_right = as_list_or_none( + args.horizontal_right + if args.horizontal_right is not None + else hyper.get("horizontal_right") + ) or [0.6] design_params, design_param_names = create_hohlraum_samples_from_param_range( parameter_range_grid_cell_size, @@ -269,13 +262,19 @@ def override_csv_column(df, values, column_name, arg_name): parameter_range_horizontal_right, ) + def safe_call_models(*model_args, **model_kwargs): + try: + return call_models(*model_args, **model_kwargs) + except (RuntimeError, FileNotFoundError) as e: + raise SystemExit(f"ERROR: {e}") from e + if hpc_operation: print("==== Execute HPC version ====") directory = "./benchmarks/hohlraum/slurm_scripts/" user = read_username_from_config("./slurm_config.txt") delete_slurm_scripts(directory) # delete existing slurm files for hohlraum - call_models( + safe_call_models( design_params, hpc_operation_count=1, singularity_hpc=singularity_hpc, @@ -290,11 +289,11 @@ def override_csv_column(df, values, column_name, arg_name): wait_for_slurm_jobs(user=user, sleep_interval=10) else: print("Username could not be read from slurm config file.") - qois = call_models( + qois = safe_call_models( design_params, hpc_operation_count=2, use_cuda=use_cuda, quiet=args.quiet ) else: - qois = call_models( + qois = safe_call_models( design_params, hpc_operation_count=0, singularity_hpc=singularity_hpc, @@ -305,8 +304,9 @@ def override_csv_column(df, values, column_name, arg_name): if args.csv: # Add all QOI columns to the CSV qoi_names = get_qois_col_names() - for i in range(qois.shape[1]): - df[qoi_names[i]] = qois[:, i] + qoi_df = pd.DataFrame(qois, columns=qoi_names, index=df.index) + # Replace existing QOI columns in one concat to avoid DataFrame fragmentation. + df = pd.concat([df.drop(columns=qoi_names, errors="ignore"), qoi_df], axis=1) df.to_csv(args.csv, index=False) print(f"Updated CSV with QOI columns: {args.csv}") else: diff --git a/run_lattice.py b/run_lattice.py index 6edfaa1..ff4240f 100644 --- a/run_lattice.py +++ b/run_lattice.py @@ -8,7 +8,6 @@ from src.simulation_utils import execute_slurm_scripts, wait_for_slurm_jobs from src.general_utils import ( create_lattice_samples_from_param_range, - load_lattice_samples_from_npz, delete_slurm_scripts, load_toml_hyperparameters, ) @@ -19,13 +18,11 @@ def main(): args = parse_lattice_args() print(f"HPC mode = { args.use_slurm}") - print(f"Load from npz = {args.load_from_npz}") print(f"HPC with singularity = { args.use_singularity}") print(f"CUDA mode = {args.cuda}") print(f"Quiet mode = {args.quiet}") hpc_operation = args.use_slurm # Flag when using HPC cluster - load_from_npz = args.load_from_npz use_cuda = args.cuda if use_cuda and hpc_operation: raise SystemExit( @@ -104,18 +101,14 @@ def override_csv_column(df, values, column_name, arg_name): design_param_names = np.array( ["absorption_blue", "scattering_white", "grid_cl", "grid_quad_order"] ) - elif load_from_npz: # TODO - raise NotImplementedError - design_params, design_param_names = load_lattice_samples_from_npz( - "sampling/pilot-study-samples-hohlraum-05-29-24.npz" - ) - exit("TODO") else: # --- Define parameter ranges --- # characteristic length of the cells: #grid cells = O(1/cell_size^2) parameter_range_grid_cell_size = as_list_or_none( - args.grid_cell_size if args.grid_cell_size is not None else hyper.get("grid_cell_size") + args.grid_cell_size + if args.grid_cell_size is not None + else hyper.get("grid_cell_size") ) or [0.01] # quadrature order (must be an even number): #velocity grid cells = O(order^2) diff --git a/src/general_utils.py b/src/general_utils.py index 2da3eec..0c69f60 100644 --- a/src/general_utils.py +++ b/src/general_utils.py @@ -23,24 +23,12 @@ def _add_common_execution_args(parser): action="store_true", help=argparse.SUPPRESS, ) - parser.add_argument( - "--load-from-npz", - action="store_true", - help="Load parameter samples from NPZ input", - ) parser.add_argument( "--singularity", dest="use_singularity", action="store_true", help="Run KiT-RT through the CPU Singularity image", ) - # Backward-compatible alias (hidden from --help) - parser.add_argument( - "--use-singularity", - dest="use_singularity", - action="store_true", - help=argparse.SUPPRESS, - ) parser.add_argument( "--csv", type=str, diff --git a/tests/test_cli_and_runner_flags.py b/tests/test_cli_and_runner_flags.py new file mode 100644 index 0000000..52cfe4b --- /dev/null +++ b/tests/test_cli_and_runner_flags.py @@ -0,0 +1,436 @@ +import argparse +import sys + +import numpy as np +import pandas as pd +import pytest + +import run_hohlraum +import run_lattice +from src import general_utils + + +def lattice_args(**overrides): + values = { + "use_slurm": False, + "use_singularity": False, + "cuda": False, + "quiet": False, + "csv": None, + "config": None, + "grid_cell_size": None, + "quad_order": None, + "abs_blue": None, + "scatter_white": None, + } + values.update(overrides) + return argparse.Namespace(**values) + + +def hohlraum_args(**overrides): + values = { + "use_slurm": False, + "use_singularity": False, + "cuda": False, + "quiet": False, + "csv": None, + "config": None, + "grid_cell_size": None, + "quad_order": None, + "green_center_x": None, + "green_center_y": None, + "red_right_top": None, + "red_right_bottom": None, + "red_left_top": None, + "red_left_bottom": None, + "horizontal_left": None, + "horizontal_right": None, + } + values.update(overrides) + return argparse.Namespace(**values) + + +def test_parse_lattice_args_supports_current_flags(monkeypatch): + monkeypatch.setattr( + sys, + "argv", + [ + "run_lattice.py", + "--slurm", + "--singularity", + "--cuda", + "--quiet", + "--csv", + "in.csv", + "--grid-cell-size", + "0.02", + "--quad-order", + "6", + "--config", + "cfg.toml", + "--abs-blue", + "10.0", + "11.0", + "--scatter-white", + "1.0", + "2.0", + ], + ) + args = general_utils.parse_lattice_args() + assert args.use_slurm is True + assert args.use_singularity is True + assert args.cuda is True + assert args.quiet is True + assert args.csv == "in.csv" + assert args.grid_cell_size == 0.02 + assert args.quad_order == 6 + assert args.config == "cfg.toml" + assert args.abs_blue == [10.0, 11.0] + assert args.scatter_white == [1.0, 2.0] + assert not hasattr(args, "load_from_npz") + + +def test_parse_hohlraum_args_supports_current_flags(monkeypatch): + monkeypatch.setattr( + sys, + "argv", + [ + "run_hohlraum.py", + "--slurm", + "--singularity", + "--cuda", + "--quiet", + "--csv", + "in.csv", + "--grid-cell-size", + "0.01", + "--quad-order", + "8", + "--config", + "cfg.toml", + "--green-center-x", + "-0.1", + "0.1", + "--green-center-y", + "-0.2", + "0.2", + "--red-right-top", + "0.5", + "--red-right-bottom", + "-0.5", + "--red-left-top", + "0.5", + "--red-left-bottom", + "-0.5", + "--horizontal-left", + "-0.6", + "--horizontal-right", + "0.6", + ], + ) + args = general_utils.parse_hohlraum_args() + assert args.use_slurm is True + assert args.use_singularity is True + assert args.cuda is True + assert args.quiet is True + assert args.csv == "in.csv" + assert args.grid_cell_size == 0.01 + assert args.quad_order == 8 + assert args.config == "cfg.toml" + assert args.green_center_x == [-0.1, 0.1] + assert args.green_center_y == [-0.2, 0.2] + assert args.red_right_top == [0.5] + assert args.red_right_bottom == [-0.5] + assert args.red_left_top == [0.5] + assert args.red_left_bottom == [-0.5] + assert args.horizontal_left == [-0.6] + assert args.horizontal_right == [0.6] + assert not hasattr(args, "load_from_npz") + + +def test_lattice_main_rejects_cuda_with_slurm(monkeypatch): + monkeypatch.setattr( + run_lattice, "parse_lattice_args", lambda: lattice_args(use_slurm=True, cuda=True) + ) + with pytest.raises(SystemExit, match="--cuda cannot be combined with --slurm"): + run_lattice.main() + + +def test_hohlraum_main_rejects_cuda_with_slurm(monkeypatch): + monkeypatch.setattr( + run_hohlraum, + "parse_hohlraum_args", + lambda: hohlraum_args(use_slurm=True, cuda=True), + ) + with pytest.raises(SystemExit, match="--cuda cannot be combined with --slurm"): + run_hohlraum.main() + + +def test_lattice_main_local_cuda_forces_containerized_mode(monkeypatch): + monkeypatch.setattr( + run_lattice, "parse_lattice_args", lambda: lattice_args(cuda=True, use_singularity=False) + ) + monkeypatch.setattr(run_lattice, "load_toml_hyperparameters", lambda _: {}) + monkeypatch.setattr( + run_lattice, + "create_lattice_samples_from_param_range", + lambda *_: ( + np.array([[10.0, 1.0, 0.01, 4]]), + np.array(["absorption_blue", "scattering_white", "grid_cl", "grid_quad_order"]), + ), + ) + calls = [] + + def fake_call_models(*args, **kwargs): + calls.append(kwargs) + return np.array([[1.0] * 8]) + + monkeypatch.setattr(run_lattice, "call_models", fake_call_models) + monkeypatch.setattr(run_lattice.np, "savez", lambda *_, **__: None) + + assert run_lattice.main() == 0 + assert len(calls) == 1 + assert calls[0]["hpc_operation_count"] == 0 + assert calls[0]["singularity_hpc"] is True + assert calls[0]["use_cuda"] is True + + +def test_hohlraum_main_local_cuda_forces_containerized_mode(monkeypatch): + monkeypatch.setattr( + run_hohlraum, + "parse_hohlraum_args", + lambda: hohlraum_args(cuda=True, use_singularity=False), + ) + monkeypatch.setattr(run_hohlraum, "load_toml_hyperparameters", lambda _: {}) + monkeypatch.setattr( + run_hohlraum, + "create_hohlraum_samples_from_param_range", + lambda *_: (np.zeros((10, 1)), np.array(["p"] * 10)), + ) + calls = [] + + def fake_call_models(*args, **kwargs): + calls.append(kwargs) + return np.array([[1.0] * len(run_hohlraum.get_qois_col_names())]) + + monkeypatch.setattr(run_hohlraum, "call_models", fake_call_models) + monkeypatch.setattr(run_hohlraum.np, "savez", lambda *_, **__: None) + + assert run_hohlraum.main() == 0 + assert len(calls) == 1 + assert calls[0]["hpc_operation_count"] == 0 + assert calls[0]["singularity_hpc"] is True + assert calls[0]["use_cuda"] is True + + +def test_lattice_main_slurm_runs_stage_1_and_2(monkeypatch): + monkeypatch.setattr( + run_lattice, + "parse_lattice_args", + lambda: lattice_args(use_slurm=True, use_singularity=True), + ) + monkeypatch.setattr(run_lattice, "load_toml_hyperparameters", lambda _: {}) + monkeypatch.setattr( + run_lattice, + "create_lattice_samples_from_param_range", + lambda *_: (np.array([[10.0, 1.0, 0.01, 4]]), np.array(["a", "b", "c", "d"])), + ) + + calls = [] + + def fake_call_models(*args, **kwargs): + calls.append(kwargs["hpc_operation_count"]) + return np.array([[1.0] * 8]) + + monkeypatch.setattr(run_lattice, "call_models", fake_call_models) + monkeypatch.setattr(run_lattice, "delete_slurm_scripts", lambda *_: None) + monkeypatch.setattr(run_lattice, "read_username_from_config", lambda *_: "alice") + monkeypatch.setattr(run_lattice, "execute_slurm_scripts", lambda *_: None) + monkeypatch.setattr(run_lattice, "wait_for_slurm_jobs", lambda **_: None) + monkeypatch.setattr(run_lattice.np, "savez", lambda *_, **__: None) + + assert run_lattice.main() == 0 + assert calls == [1, 2] + + +def test_hohlraum_main_slurm_runs_stage_1_and_2(monkeypatch): + monkeypatch.setattr( + run_hohlraum, + "parse_hohlraum_args", + lambda: hohlraum_args(use_slurm=True, use_singularity=True), + ) + monkeypatch.setattr(run_hohlraum, "load_toml_hyperparameters", lambda _: {}) + monkeypatch.setattr( + run_hohlraum, + "create_hohlraum_samples_from_param_range", + lambda *_: (np.zeros((10, 1)), np.array(["p"] * 10)), + ) + + calls = [] + + def fake_call_models(*args, **kwargs): + calls.append(kwargs["hpc_operation_count"]) + return np.array([[1.0] * len(run_hohlraum.get_qois_col_names())]) + + monkeypatch.setattr(run_hohlraum, "call_models", fake_call_models) + monkeypatch.setattr(run_hohlraum, "delete_slurm_scripts", lambda *_: None) + monkeypatch.setattr(run_hohlraum, "read_username_from_config", lambda *_: "alice") + monkeypatch.setattr(run_hohlraum, "execute_slurm_scripts", lambda *_: None) + monkeypatch.setattr(run_hohlraum, "wait_for_slurm_jobs", lambda **_: None) + monkeypatch.setattr(run_hohlraum.np, "savez", lambda *_, **__: None) + + assert run_hohlraum.main() == 0 + assert calls == [1, 2] + + +def test_lattice_main_csv_mode_updates_columns_and_qois(monkeypatch, tmp_path): + csv_path = tmp_path / "lattice.csv" + pd.DataFrame( + [ + { + "abs_blue": 10.0, + "scatter_white": 1.0, + "grid_cell_size": 0.01, + "quad_order": 4, + } + ] + ).to_csv(csv_path, index=False) + + monkeypatch.setattr( + run_lattice, + "parse_lattice_args", + lambda: lattice_args( + csv=str(csv_path), + abs_blue=[12.0], + scatter_white=[2.0], + grid_cell_size=0.02, + quad_order=6, + ), + ) + monkeypatch.setattr(run_lattice, "load_toml_hyperparameters", lambda _: {}) + monkeypatch.setattr(run_lattice, "call_models", lambda *_, **__: np.array([[1.0] * 8])) + monkeypatch.setattr( + run_lattice.np, + "savez", + lambda *_, **__: (_ for _ in ()).throw(AssertionError("np.savez should not run in --csv mode")), + ) + + assert run_lattice.main() == 0 + output = pd.read_csv(csv_path) + assert output.loc[0, "abs_blue"] == 12.0 + assert output.loc[0, "scatter_white"] == 2.0 + assert output.loc[0, "grid_cell_size"] == 0.02 + assert output.loc[0, "quad_order"] == 6 + for qoi_name in run_lattice.get_qois_col_names(): + assert qoi_name in output.columns + + +def test_hohlraum_main_csv_mode_updates_columns_and_qois(monkeypatch, tmp_path): + csv_path = tmp_path / "hohlraum.csv" + pd.DataFrame( + [ + { + "red_left_top": 0.4, + "red_left_bottom": -0.4, + "red_right_top": 0.4, + "red_right_bottom": -0.4, + "horizontal_left": -0.6, + "horizontal_right": 0.6, + "green_center_x": 0.0, + "green_center_y": 0.0, + "grid_cell_size": 0.01, + "quad_order": 6, + } + ] + ).to_csv(csv_path, index=False) + + monkeypatch.setattr( + run_hohlraum, + "parse_hohlraum_args", + lambda: hohlraum_args( + csv=str(csv_path), + green_center_x=[0.1], + horizontal_right=[0.55], + grid_cell_size=0.02, + quad_order=8, + ), + ) + monkeypatch.setattr(run_hohlraum, "load_toml_hyperparameters", lambda _: {}) + monkeypatch.setattr( + run_hohlraum, + "call_models", + lambda *_, **__: np.array([[1.0] * len(run_hohlraum.get_qois_col_names())]), + ) + monkeypatch.setattr( + run_hohlraum.np, + "savez", + lambda *_, **__: (_ for _ in ()).throw(AssertionError("np.savez should not run in --csv mode")), + ) + + assert run_hohlraum.main() == 0 + output = pd.read_csv(csv_path) + assert output.loc[0, "green_center_x"] == 0.1 + assert output.loc[0, "horizontal_right"] == 0.55 + assert output.loc[0, "grid_cell_size"] == 0.02 + assert output.loc[0, "quad_order"] == 8 + for qoi_name in run_hohlraum.get_qois_col_names(): + assert qoi_name in output.columns + + +def test_lattice_main_rejects_odd_quad_order(monkeypatch): + monkeypatch.setattr( + run_lattice, "parse_lattice_args", lambda: lattice_args(quad_order=3) + ) + monkeypatch.setattr(run_lattice, "load_toml_hyperparameters", lambda _: {}) + with pytest.raises(SystemExit, match="--quad-order must be an even number"): + run_lattice.main() + + +def test_hohlraum_main_rejects_odd_quad_order(monkeypatch): + monkeypatch.setattr( + run_hohlraum, "parse_hohlraum_args", lambda: hohlraum_args(quad_order=5) + ) + monkeypatch.setattr(run_hohlraum, "load_toml_hyperparameters", lambda _: {}) + with pytest.raises(SystemExit, match="--quad-order must be an even number"): + run_hohlraum.main() + + +def test_lattice_call_models_appends_operation_and_execution_flags(monkeypatch): + captured = [] + + def fake_model(payload): + captured.append(payload[0]) + return [[42.0] * 8] + + monkeypatch.setattr(run_lattice, "model", fake_model) + design_params = np.array([[10.0, 1.0, 0.01, 4]]) + qois = run_lattice.call_models( + design_params, + hpc_operation_count=2, + singularity_hpc=True, + rectangular_mesh=False, + use_cuda=True, + quiet=True, + ) + assert qois.shape == (1, 8) + assert captured[0][-5:] == [2, True, False, True, True] + + +def test_hohlraum_call_models_uses_transposed_design_matrix(monkeypatch): + captured = [] + + def fake_model(payload): + captured.append(payload[0]) + return [[7.0] * len(run_hohlraum.get_qois_col_names())] + + monkeypatch.setattr(run_hohlraum, "model", fake_model) + design_params = np.arange(10).reshape(10, 1) + qois = run_hohlraum.call_models( + design_params, + hpc_operation_count=1, + singularity_hpc=False, + use_cuda=False, + quiet=True, + ) + assert qois.shape == (1, len(run_hohlraum.get_qois_col_names())) + assert captured[0][-4:] == [1, False, False, True] diff --git a/tests/test_model_operations.py b/tests/test_model_operations.py new file mode 100644 index 0000000..fe92976 --- /dev/null +++ b/tests/test_model_operations.py @@ -0,0 +1,208 @@ +import numpy as np +import pytest + +from src.models import hohlraum as hohlraum_model +from src.models import lattice as lattice_model + + +@pytest.fixture +def lattice_mocks(monkeypatch): + calls = {"raw": [], "container": [], "slurm": []} + base_config = {"LOG_DIR": "result/logs", "OUTPUT_DIR": "result"} + + def update_parameter(values, key, new_value): + updated = values.copy() + updated[key] = new_value + return updated + + monkeypatch.setattr(lattice_model, "read_config_file", lambda _: base_config.copy()) + monkeypatch.setattr(lattice_model, "update_lattice_mesh_file", lambda *_, **__: "mesh.su2") + monkeypatch.setattr(lattice_model, "update_parameter", update_parameter) + monkeypatch.setattr(lattice_model, "write_config_file", lambda **_: None) + monkeypatch.setattr(lattice_model, "remove_files", lambda *_: None) + monkeypatch.setattr( + lattice_model, + "write_slurm_file", + lambda *args, **kwargs: calls["slurm"].append((args, kwargs)), + ) + monkeypatch.setattr(lattice_model, "generate_log_filename", lambda _: "result/logs/lattice_run") + monkeypatch.setattr( + lattice_model, + "read_csv_file", + lambda _: { + "Wall_time_[s]": 1.0, + "Mass": 2.0, + "Cur_absorption": 3.0, + "Total_absorption": 4.0, + "Cur_outflow_P1": 5.0, + "Total_outflow_P1": 6.0, + "Cur_outflow_P2": 7.0, + "Total_outflow_P2": 8.0, + }, + ) + monkeypatch.setattr( + lattice_model, + "run_cpp_simulation", + lambda config, quiet=False: calls["raw"].append((config, quiet)), + ) + monkeypatch.setattr( + lattice_model, + "run_cpp_simulation_containerized", + lambda config, use_cuda=False, quiet=False: calls["container"].append( + (config, use_cuda, quiet) + ), + ) + monkeypatch.setattr( + lattice_model.os.path, "exists", lambda path: str(path).endswith(".csv") + ) + monkeypatch.setattr(lattice_model.os, "remove", lambda *_: None) + return calls + + +@pytest.fixture +def hohlraum_mocks(monkeypatch): + calls = {"raw": [], "container": [], "slurm": []} + base_config = {"LOG_DIR": "result/logs", "OUTPUT_DIR": "result", "TIME_FINAL": 1.0} + + def update_parameter(values, key, new_value): + updated = values.copy() + updated[key] = new_value + return updated + + def integrated_probes(*_, **__): + result = {} + for probe in range(4): + for moment in range(3): + result[f"Probe {probe} u_{moment}"] = [float(i) for i in range(10)] + return result + + monkeypatch.setattr(hohlraum_model, "read_config_file", lambda _: base_config.copy()) + monkeypatch.setattr( + hohlraum_model, "update_var_hohlraum_mesh_file", lambda **_: "mesh.su2" + ) + monkeypatch.setattr(hohlraum_model, "update_parameter", update_parameter) + monkeypatch.setattr(hohlraum_model, "write_config_file", lambda **_: None) + monkeypatch.setattr(hohlraum_model, "remove_files", lambda *_: None) + monkeypatch.setattr( + hohlraum_model, + "write_slurm_file", + lambda *args, **kwargs: calls["slurm"].append((args, kwargs)), + ) + monkeypatch.setattr(hohlraum_model, "generate_log_filename", lambda _: "result/logs/hohlraum_run") + monkeypatch.setattr( + hohlraum_model, + "read_csv_file", + lambda _: { + "Wall_time_[s]": 1.0, + "Mass": 2.0, + "Cumulated_absorption_center": 3.0, + "Cumulated_absorption_vertical_wall": 4.0, + "Cumulated_absorption_horizontal_wall": 5.0, + }, + ) + monkeypatch.setattr( + hohlraum_model, + "get_integrated_hohlraum_probe_moments", + integrated_probes, + ) + monkeypatch.setattr( + hohlraum_model, + "run_cpp_simulation", + lambda config, quiet=False: calls["raw"].append((config, quiet)), + ) + monkeypatch.setattr( + hohlraum_model, + "run_cpp_simulation_containerized", + lambda config, use_cuda=False, quiet=False: calls["container"].append( + (config, use_cuda, quiet) + ), + ) + monkeypatch.setattr( + hohlraum_model.os.path, "exists", lambda path: str(path).endswith(".csv") + ) + monkeypatch.setattr(hohlraum_model.os, "remove", lambda *_: None) + return calls + + +def test_lattice_model_local_raw_operation(lattice_mocks): + params = [[10.0, 1.0, 0.01, 4, 0, 0, False, False, True]] + qois = lattice_model.model(params)[0] + assert len(qois) == 8 + assert len(lattice_mocks["raw"]) == 1 + assert lattice_mocks["raw"][0][1] is True + assert lattice_mocks["container"] == [] + + +def test_lattice_model_local_cuda_uses_container(lattice_mocks): + params = [[10.0, 1.0, 0.01, 4, 0, 0, False, True, False]] + qois = lattice_model.model(params)[0] + assert len(qois) == 8 + assert len(lattice_mocks["container"]) == 1 + assert lattice_mocks["container"][0][1] is True + assert lattice_mocks["raw"] == [] + + +def test_lattice_model_slurm_operation_writes_script(lattice_mocks): + params = [[10.0, 1.0, 0.01, 4, 1, 1, False, False, False]] + qois = lattice_model.model(params)[0] + assert qois == [0] * 8 + assert len(lattice_mocks["slurm"]) == 1 + assert lattice_mocks["raw"] == [] + assert lattice_mocks["container"] == [] + + +def test_lattice_model_postprocess_operation_reads_qois(lattice_mocks): + params = [[10.0, 1.0, 0.01, 4, 2, 1, False, False, False]] + qois = lattice_model.model(params)[0] + assert len(qois) == 8 + assert qois[0] == 1.0 + assert lattice_mocks["raw"] == [] + assert lattice_mocks["container"] == [] + + +def test_lattice_model_rejects_cuda_with_slurm(): + params = [[10.0, 1.0, 0.01, 4, 1, 1, False, True, False]] + with pytest.raises(ValueError, match="CUDA mode with SLURM is not supported"): + lattice_model.model(params) + + +def test_hohlraum_model_local_raw_operation(hohlraum_mocks): + params = [[0.4, -0.4, 0.4, -0.4, -0.6, 0.6, 0.0, 0.0, 0.01, 6, 0, 0, False, True]] + qois = hohlraum_model.model(params)[0] + assert len(qois) == 125 + assert len(hohlraum_mocks["raw"]) == 1 + assert hohlraum_mocks["raw"][0][1] is True + assert hohlraum_mocks["container"] == [] + + +def test_hohlraum_model_local_cuda_uses_container(hohlraum_mocks): + params = [[0.4, -0.4, 0.4, -0.4, -0.6, 0.6, 0.0, 0.0, 0.01, 6, 0, 0, True, False]] + qois = hohlraum_model.model(params)[0] + assert len(qois) == 125 + assert len(hohlraum_mocks["container"]) == 1 + assert hohlraum_mocks["container"][0][1] is True + assert hohlraum_mocks["raw"] == [] + + +def test_hohlraum_model_slurm_operation_writes_script(hohlraum_mocks): + params = [[0.4, -0.4, 0.4, -0.4, -0.6, 0.6, 0.0, 0.0, 0.01, 6, 1, 1, False, False]] + qois = hohlraum_model.model(params)[0] + assert qois == [0] * 125 + assert len(hohlraum_mocks["slurm"]) == 1 + assert hohlraum_mocks["raw"] == [] + assert hohlraum_mocks["container"] == [] + + +def test_hohlraum_model_postprocess_operation_reads_qois(hohlraum_mocks): + params = [[0.4, -0.4, 0.4, -0.4, -0.6, 0.6, 0.0, 0.0, 0.01, 6, 2, 1, False, False]] + qois = hohlraum_model.model(params)[0] + assert len(qois) == 125 + assert qois[0] == 1.0 + assert hohlraum_mocks["raw"] == [] + assert hohlraum_mocks["container"] == [] + + +def test_hohlraum_model_rejects_cuda_with_slurm(): + params = [[0.4, -0.4, 0.4, -0.4, -0.6, 0.6, 0.0, 0.0, 0.01, 6, 1, 1, True, False]] + with pytest.raises(ValueError, match="CUDA mode with SLURM is not supported"): + hohlraum_model.model(params) diff --git a/update_KiT-RT.sh b/update_KiT-RT.sh deleted file mode 100755 index b1735ad..0000000 --- a/update_KiT-RT.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -KITRT_REPO_URL="${KITRT_REPO_URL:-git@github.com:KiT-RT/kitrt_code.git}" - -has_cuda_gpu() { - if ! command -v nvidia-smi >/dev/null 2>&1; then - return 1 - fi - nvidia-smi -L >/dev/null 2>&1 -} - -cd kitrt_code -git remote set-url origin "${KITRT_REPO_URL}" -git fetch origin - -default_branch="$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's#^origin/##' || true)" -if [ -z "${default_branch}" ]; then - default_branch="$(git remote show origin | sed -n '/HEAD branch/s/.*: //p' | head -n 1)" -fi -if [ -z "${default_branch}" ]; then - default_branch="$(git rev-parse --abbrev-ref HEAD)" -fi - -git checkout "${default_branch}" -git pull --ff-only origin "${default_branch}" -git submodule update --init --recursive - -cd tools/singularity -chmod +x install_kitrt_singularity.sh install_kitrt_singularity_cuda.sh - -singularity exec kit_rt.sif ./install_kitrt_singularity.sh - -if has_cuda_gpu && [ -f kit_rt_MPI_cuda.sif ]; then - singularity exec --nv kit_rt_MPI_cuda.sif ./install_kitrt_singularity_cuda.sh -fi - -cd ../../../