From a6c4f95c9fabe1755ec5b7d7ed78dde6543d8ddf Mon Sep 17 00:00:00 2001 From: Christopher Albert Date: Fri, 12 Jun 2026 09:48:45 +0200 Subject: [PATCH] Default GVEC chartmap Bcov to Boozer average --- test/tests/CMakeLists.txt | 9 +++- .../test_gvec_chartmap_converter_static.py | 42 +++++++++++++++++++ test/tests/test_profiles.f90 | 2 +- tools/gvec_to_boozer_chartmap.py | 2 +- 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 test/tests/test_gvec_chartmap_converter_static.py diff --git a/test/tests/CMakeLists.txt b/test/tests/CMakeLists.txt index 0b678090..d45a2f34 100644 --- a/test/tests/CMakeLists.txt +++ b/test/tests/CMakeLists.txt @@ -500,6 +500,13 @@ add_test(NAME test_array_utils COMMAND test_array_utils.x) TIMEOUT 7200) endif() + add_test(NAME test_gvec_chartmap_converter_static + COMMAND ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/test_gvec_chartmap_converter_static.py) + set_tests_properties(test_gvec_chartmap_converter_static PROPERTIES + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + LABELS "unit;python") + # Export tool for e2e test add_executable(export_boozer_chartmap_tool.x export_boozer_chartmap_tool.f90) target_link_libraries(export_boozer_chartmap_tool.x simple) @@ -770,7 +777,7 @@ if(SIMPLE_ENABLE_PYTHON_TOOLS) endif() ################################################## -# NCSX GC Cash–Karp COMPARISON TEST (VMEC vs MEISS) +# NCSX GC Cash-Karp COMPARISON TEST (VMEC vs MEISS) ################################################## add_test( diff --git a/test/tests/test_gvec_chartmap_converter_static.py b/test/tests/test_gvec_chartmap_converter_static.py new file mode 100644 index 00000000..9879c3e5 --- /dev/null +++ b/test/tests/test_gvec_chartmap_converter_static.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +"""Static checks for the GVEC chartmap converter CLI contract.""" + +from __future__ import annotations + +import ast +from pathlib import Path + + +def fail(message: str) -> None: + raise SystemExit(f"FAIL: {message}") + + +def main() -> None: + repo = Path(__file__).resolve().parents[2] + script = repo / "tools" / "gvec_to_boozer_chartmap.py" + tree = ast.parse(script.read_text(encoding="utf-8")) + + for node in ast.walk(tree): + if not isinstance(node, ast.Call): + continue + if not isinstance(node.func, ast.Attribute): + continue + if node.func.attr != "add_argument": + continue + if not node.args or not isinstance(node.args[0], ast.Constant): + continue + if node.args[0].value != "--Bcov": + continue + for keyword in node.keywords: + if keyword.arg == "default" and isinstance(keyword.value, ast.Constant): + if keyword.value.value == "boozer-avg": + print("PASS: GVEC converter defaults to Boozer covariant averaging") + return + fail(f"--Bcov default is {keyword.value.value!r}") + fail("--Bcov has no default") + + fail("--Bcov argument not found") + + +if __name__ == "__main__": + main() diff --git a/test/tests/test_profiles.f90 b/test/tests/test_profiles.f90 index c94b4a51..e37132fe 100644 --- a/test/tests/test_profiles.f90 +++ b/test/tests/test_profiles.f90 @@ -288,7 +288,7 @@ subroutine test_peaked_profile_collision_rates(passed, nfail) end subroutine test_peaked_profile_collision_rates ! Flat radial profiles must reproduce the scalar (constant-coefficient) - ! collision operator bit-for-bit. This checks every intermediate value the + ! collision operator to round-off. This checks every intermediate value the ! stochastic step depends on: the interpolated coefficients at off-node s ! and the coleff outputs dpp/dhh/fpeff over the whole momentum range. subroutine test_flat_intermediate_values(passed, nfail) diff --git a/tools/gvec_to_boozer_chartmap.py b/tools/gvec_to_boozer_chartmap.py index 1eb0d3a0..9a7c8197 100644 --- a/tools/gvec_to_boozer_chartmap.py +++ b/tools/gvec_to_boozer_chartmap.py @@ -37,7 +37,7 @@ def main(): parser.add_argument("--ntheta", type=int, default=36) parser.add_argument("--nphi", type=int, default=81) parser.add_argument("--boozer-factor", type=int, default=1) - parser.add_argument("--Bcov", choices=["avg", "boozer-avg", "boozer-0"], default="avg", help="Method for computing B_theta and B_phi surface functions.") + parser.add_argument("--Bcov", choices=["avg", "boozer-avg", "boozer-0"], default="boozer-avg", help="Method for computing B_theta and B_phi surface functions.") parser.add_argument("--flip", choices=["pol", "tor"], default="tor", help="Flip the sign of the poloidal or toroidal angle (to obtain left-handed coordinates).") args = parser.parse_args()