Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion test/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -770,7 +777,7 @@ if(SIMPLE_ENABLE_PYTHON_TOOLS)
endif()

##################################################
# NCSX GC CashKarp COMPARISON TEST (VMEC vs MEISS)
# NCSX GC Cash-Karp COMPARISON TEST (VMEC vs MEISS)
##################################################

add_test(
Expand Down
42 changes: 42 additions & 0 deletions test/tests/test_gvec_chartmap_converter_static.py
Original file line number Diff line number Diff line change
@@ -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()
2 changes: 1 addition & 1 deletion test/tests/test_profiles.f90
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion tools/gvec_to_boozer_chartmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
Loading