Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8557169
let me look through this
FelixWattsYork Jul 13, 2026
9212148
removed theta trapped from gftm input template since gftm doesn't hav…
FelixWattsYork Jul 13, 2026
299b059
when through checking changes to gftm
FelixWattsYork Jul 13, 2026
504a205
Added Template GFTM outputs for testing purposes
FelixWattsYork Jul 13, 2026
688bb66
updated GFTM default input file
FelixWattsYork Jul 14, 2026
553d6cb
let me look through this
FelixWattsYork Jul 13, 2026
3404a54
removed theta trapped from gftm input template since gftm doesn't hav…
FelixWattsYork Jul 13, 2026
ffcfc7a
when through checking changes to gftm
FelixWattsYork Jul 13, 2026
e6640fe
Added Template GFTM outputs for testing purposes
FelixWattsYork Jul 13, 2026
45b4340
updated GFTM default input file
FelixWattsYork Jul 14, 2026
ca38ef8
fixed to nxgrid i think
FelixWattsYork Jul 31, 2026
8a5188d
Merge branch 'feature/gftm' of github.com:pyro-kinetics/pyrokinetics …
FelixWattsYork Sep 25, 2026
1d54e51
Merge remote-tracking branch 'origin/main' into feature/gftm
FelixWattsYork Sep 25, 2026
a41fbfc
Ignore uv lockfile
FelixWattsYork Sep 25, 2026
3fc896c
mirrord the tglf tests with gftm
FelixWattsYork Sep 25, 2026
abbd368
Document TGLF and GFTM input autodetection ambiguity
FelixWattsYork Sep 25, 2026
cdc0221
Distinguish GFTM and TGLF inputs by filename
FelixWattsYork Sep 25, 2026
468822b
Detect GFTM inputs by NU or NE instead of filename
FelixWattsYork Sep 25, 2026
3cadb67
Make GKInputTGLF.add_flags case-insensitive
claude Sep 25, 2026
266a889
Make CGYRO and NEO add_flags case-insensitive
claude Sep 25, 2026
2e27713
Make GFTM add_flags case-insensitive
claude Sep 25, 2026
cdbba51
Make GKInputTGLF.add_flags case-insensitive
claude Sep 25, 2026
a9ceec0
Make CGYRO and NEO add_flags case-insensitive
claude Sep 25, 2026
aff1209
Revert "Make GFTM add_flags case-insensitive"
claude Sep 25, 2026
c06ffdb
Revert "Make CGYRO and NEO add_flags case-insensitive"
claude Sep 25, 2026
0016aa4
Revert "Make GKInputTGLF.add_flags case-insensitive"
claude Sep 25, 2026
5543b59
Make GFTM add_flags case-insensitive
claude Sep 25, 2026
8f5d1c1
Use a single GKInput.add_flags for all codes
claude Sep 25, 2026
f6a95ae
Split add_flags by input format: GKInput and GKInputFlat
claude Sep 25, 2026
7832afd
Merge pull request #585 from pyro-kinetics/feature/gftm
MantasA411 Sep 28, 2026
1a5099d
Merge pull request #598 from pyro-kinetics/claude/Force_Consistent_Ca…
MantasA411 Sep 28, 2026
754e65a
PyroScan: how fields, eigenfunctions and time are reduced when loadin…
claude Sep 29, 2026
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ ipython_config.py
# install all needed dependencies.
#Pipfile.lock

# uv
# for similar reasons for pipenv uv.lock my be ignored

uv.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

Expand Down
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added

### Changed
- `add_flags` has one implementation per input format: `GKInput.add_flags` for grouped inputs and the new `GKInputFlat.add_flags` for flat `KEY = value` inputs. Per-code overrides are removed and `GKInput.add_flags` is no longer abstract
- Changed Pyro kwarg from `gk_type` to `gk_code`

- `PyroScan.load_gk_output` uses one time setting for linear and nonlinear
runs: `time_mode` (`"average"` default, `"last"`, `"trace"`), with
`tolerance_time_range` (default 0.8) setting the averaging window. With
`"average"`, fields and eigenfunctions are `|field|**2` averaged in time,
stored as `phi_squared`, `apar_squared`, `bpar_squared` and
`eigenfunctions_squared`, since a time mean of a complex field is
meaningless. Linear growth rates and fluxes are now averaged rather than
taken at the last time.
- `phi`, `apar`, `bpar` and `eigenfunctions` are no longer reduced to `ky[0]`
and the smallest `|kx|`; they keep `kx` and `ky` unless summed with
`sum_kx` / `sum_ky`. `sum_ky` now defaults to False, for fluxes too.

### Fixed
- `add_flags` for TGLF, CGYRO and NEO matches keys case-insensitively, so e.g. `NBASIS_MAX` overwrites the existing TGLF `nbasis_max` instead of writing it twice. New keys take the code's stored case (`flag_key_case`: lowercase for TGLF, uppercase for CGYRO/NEO)
- `add_flags` raises `TypeError` when flags do not match the input structure (a dict of groups for namelist/TOML codes, a flat dict for TGLF/CGYRO/NEO) instead of crashing or writing an invalid file

## [0.0.1] - 2021-01-26

Expand Down
18 changes: 14 additions & 4 deletions src/pyrokinetics/diagnostics/saturation_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,18 @@ def mg_saturation(
shat = pyro.local_geometry.shat

theta = data["theta"].data
eigenfunctions = data["eigenfunctions"]
# The rule needs |eigenfunction|**2: loaded with time_mode="average" it
# is already stored, averaged in time; otherwise take the final time
if "eigenfunctions_squared" in data:
eigenfunctions_squared = data["eigenfunctions_squared"]
else:
eigenfunctions_squared = np.abs(data["eigenfunctions"]) ** 2
if "time" in eigenfunctions_squared.dims:
eigenfunctions_squared = eigenfunctions_squared.isel(time=-1, drop=True)
# The scan keeps kx; the rule uses one kx
if "kx" in eigenfunctions_squared.dims:
kx_min = abs(eigenfunctions_squared["kx"]).argmin().item()
eigenfunctions_squared = eigenfunctions_squared.isel(kx=kx_min, drop=True)
growth_rate_tolerance = data["growth_rate_tolerance"]

growth_rate = data["growth_rate"].where(
Expand All @@ -92,9 +103,8 @@ def mg_saturation(
/ heat_tot
)

field_squared = (
np.abs(eigenfunctions.where(growth_rate_tolerance < gamma_tolerance, 0.0))
** 2
field_squared = eigenfunctions_squared.where(
growth_rate_tolerance < gamma_tolerance, 0.0
)

# Set up Jacobian and k_perp
Expand Down
1 change: 1 addition & 0 deletions src/pyrokinetics/gk_code/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Import built-in input and output readers to register them with GkInput and GkOutput.
from .cgyro import GKInputCGYRO, GKOutputReaderCGYRO # noqa
from .gene import GKInputGENE, GKOutputReaderGENE # noqa
from .gftm import GKInputGFTM, GKOutputReaderGFTM # noqa
from .gk_input import GKInput, read_gk_input, supported_gk_input_types
from .gk_output import GKOutput, read_gk_output, supported_gk_output_types
from .gkw import GKInputGKW, GKOutputReaderGKW # noqa
Expand Down
12 changes: 3 additions & 9 deletions src/pyrokinetics/gk_code/cgyro.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from ..numerics import Numerics
from ..templates import gk_templates
from ..typing import PathLike
from .gk_input import GKInput
from .gk_input import GKInput, GKInputFlat
from .gk_output import (
Coords,
Eigenfunctions,
Expand All @@ -37,13 +37,14 @@
)


class GKInputCGYRO(GKInput, FileReader, file_type="CGYRO", reads=GKInput):
class GKInputCGYRO(GKInputFlat, FileReader, file_type="CGYRO", reads=GKInput):
"""
Class that can read CGYRO input files, and produce
Numerics, LocalSpecies, and LocalGeometry objects
"""

code_name = "CGYRO"
flag_key_case = staticmethod(str.upper)
default_file_name = "input.cgyro"
norm_convention = "cgyro"
_convention_dict = {}
Expand Down Expand Up @@ -265,13 +266,6 @@ def write(
def is_nonlinear(self) -> bool:
return bool(self.data.get("NONLINEAR_FLAG", 0))

def add_flags(self, flags) -> None:
"""
Add extra flags to CGYRO input file
"""
for key, value in flags.items():
self.data[key] = value

def get_local_geometry(self) -> LocalGeometry:
"""
Returns local geometry. Delegates to more specific functions
Expand Down
7 changes: 0 additions & 7 deletions src/pyrokinetics/gk_code/gene.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,13 +304,6 @@ def write(
def is_nonlinear(self) -> bool:
return bool(self.data["general"].get("nonlinear", False))

def add_flags(self, flags) -> None:
"""
Add extra flags to GENE input file
Uses default, which assumes a Fortan90 namelist
"""
super().add_flags(flags)

def get_local_geometry(self) -> LocalGeometry:
"""
Returns local geometry. Delegates to more specific functions
Expand Down
Loading
Loading