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
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ if(${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU")
message(FATAL_ERROR "Invalid OPENACC_OFFLOAD_TARGET='${OPENACC_OFFLOAD_TARGET}' (expected none|nvptx)")
endif()
endif()

# Build type specific flags
if(CMAKE_BUILD_TYPE MATCHES Debug)
add_compile_options(-Og
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ Convert STELLOPT coils format to simple biotsavart format:

The simple format is compatible with libneo's `neo_biotsavart` module and SIMPLE code.

### ASCOT5 helpers
- `libneo.ascot5.field_from_vmec` – sample a VMEC equilibrium using the f2py-generated
`_magfie` wrappers and produce an ASCOT5-compatible `B_3DS` field (keeps CGS
internally; converts to SI during export).
- `libneo.ascot5.field_from_mgrid` – convert an ASCOT5 mgrid NetCDF file into the same
`B3DSField` dataclass, enabling a unified write path.
- `libneo.ascot5.write_b3ds_hdf5` – emit the field to HDF5 with the correct metadata
layout. See `doc/ascot5.md` for workflow details and troubleshooting.

## src
Fortran source files for the library.
Subfolders contain source for additional tools, also compiled into
Expand Down
47 changes: 47 additions & 0 deletions doc/ascot5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# ASCOT5 Field Export Support

The ASCOT5 helpers live in `python/libneo/ascot5/__init__.py`. They bridge the
VMEC/`_magfie` Fortran wrappers and ASCOT5's `B_3DS` magnetic-field files.

## Units

- The underlying VMEC Fortran routines continue to operate in CGS
(centimetres/Gauss). Python converts to SI only at the final export stage.
- Radii and heights in the returned `B3DSField` dataclass are expressed in
metres; magnetic-field components in the in-memory object are still in Gauss
until `write_b3ds_hdf5` multiplies by `GAUSS_TO_TESLA`.

## Workflow

1. Load VMEC metadata via `_magfie.f2py_vmec_wrappers.splint_vmec_data_wrapper`.
2. Sample the last closed flux surface to establish a cylindrical bounding box.
3. Walk the structured grid, solving for `(s, \vartheta)` and evaluating
`_magfie.f2py_vmec_wrappers.vmec_field_cylindrical_wrapper`.
4. Store the field in a `B3DSField` dataclass and, if needed, write it to HDF5
using `write_b3ds_hdf5`.

`field_from_mgrid` mirrors this process for ASCOT5 mgrid NetCDF inputs.

## Testing

- `pytest -q` exercises VMEC and mgrid conversion via
`test/python/test_ascot5_vmec.py` and `test/python/test_ascot5_mgrid.py`. The
tests also leave diagnostic PNGs in their respective temporary directories. If
the environment variable `PYTEST_ARTIFACTS` is set, the tests copy both the
generated HDF5 and PNG files into that directory for easy inspection.
- `test/python/test_magfie_import.py` provides a regression guard that the
`_magfie` extension and its key VMEC wrappers remain importable.

## Troubleshooting

If `_magfie` fails to import, rebuild the shared object by running `make` (or
`cmake --build --preset default`). Confirm that the active Python interpreter
matches the virtual environment expected by CMake; `bash -lc 'which python'`
should resolve to the project `/.venv` directory.

If the exported field appears hollow it usually means the Newton solver could
not converge for large portions of the padded R/Z bounding box. Increase
`nr`/`nz`/`nphi`, tighten the padding, or raise `max_iter`/`tol` when calling
`field_from_vmec` to obtain a denser valid region. Points very close to the
magnetic axis fall back to an on-axis field evaluation so the B field remains
finite there.
3 changes: 3 additions & 0 deletions python/libneo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@

# Chartmap coordinate utilities
from .chartmap import chartmap_to_rz, vmec_to_chartmap_coords

# ASCOT5 utilities
from .ascot5 import field_from_vmec, field_from_mgrid, write_b3ds_hdf5
Loading