Kinetics Tutorial#

Pyrokinetics can be used to read and analyse plasma kinetic profile files as produced by transport or interpretive modelling codes such as SCENE, JETTO, or other profile generators. These files contain thermodynamic quantities for each plasma species (such as density and temperature) defined on flux surfaces, which may then be used to set up gyrokinetic simulations.

See Reading Files for information about reading files and using Kinetics objects, and Plotting for how to visualise kinetic profiles.

Background#

In gyrokinetics simulations, plasma behaviour is determined not only by the magnetic equilibrium but also by the kinetic state of each particle species. For a given species \(s\), the key quantities typically required are:

  • Density: \(n_s(\psi)\)

  • Temperature: \(T_s(\psi)\)

  • Mass: \(m_s\)

  • Charge: \(Z_s(\psi)\)

  • Toroidal rotation: \(\Omega_s(\psi)\)

These quantities are commonly defined on flux surfaces labelled by the normalised poloidal flux:

\[\psi_N = \frac{\psi - \psi_{\text{axis}}}{\psi_{\text{LCFS}} - \psi_{\text{axis}}}\]

where \(\psi_N = 0\) corresponds to the magnetic axis and \(\psi_N = 1\) corresponds to the last closed flux surface (LCFS). Note charge is usually constant for a given species but in some heavy impurity cases it can be vary due differing charge states

Gradients with respect to the normalised minor radius \(\rho = r/a\) are also frequently used in gyrokinetics, for example:

\[a/L_{T_s} = -\frac{1}{T_s}\frac{\partial T_s}{\partial \rho}\]

These gradients are provided directly through the Species interface.

Reading Files#

Kinetics files may be read using the function read_kinetics. The file type may be specified explicitly, or inferred automatically when possible. ITERDB/UFILE-style profile files are supported with the ITERDB reader; these are expected to contain TE, TI, NE and NM1 profiles, with VROT optional. These files contain similar profile information to the TRANSP kinetics reader, but in an ASCII UFILE-style layout rather than a self-describing NetCDF file. The ITERDB reader maps RHOTOR to psi_n as RHOTOR**2 and uses an equilibrium, when provided, for the minor-radius coordinate used in local gradients. Since NM1 does not identify the ion species, the main ion defaults to deuterium and can be set with main_ion, main_ion_charge and main_ion_mass.

For background on the UFILE-style profile format, see the tokamak profile database manual.

>>> import pyrokinetics as pk
>>> kin = pk.read_kinetics("my_kinetics_file")

We can inspect the contents of the Kinetics object by printing it:

>>> print(kin)
<pyrokinetics.Kinetics>

A Kinetics object contains a collection of Species objects, accessible through the species_data attribute. This behaves like a dictionary, but also allows attribute-style access:

>>> kin.species_data["electron"]
>>> kin.species_data.electron

The number and names of species may be obtained using:

>>> kin.nspec
>>> kin.species_names

Each species provides access to its physical quantities as functions of \(\psi_N\):

>>> psi_n = 0.5
>>> ne = kin.species_data.electron.get_dens(psi_n)
>>> Te = kin.species_data.electron.get_temp(psi_n)

Units are handled using Pint, so returned values carry physical units.

Species Objects#

Each Species object contains the following information:

  • Charge

  • Mass

  • Density profile

  • Temperature profile

  • Rotation profile

  • Normalised minor radius \(\rho = r/a\)

These quantities are typically stored internally as interpolating functions over \(\psi_N\), allowing evaluation at arbitrary flux surfaces.

For example:

>>> electron = kin.species_data.electron
>>> psi_n = 0.3

>>> electron.get_charge(psi_n)
>>> electron.get_mass()
>>> electron.get_dens(psi_n)
>>> electron.get_temp(psi_n)
>>> electron.get_angular_velocity(psi_n)

Normalised gradients frequently used in gyrokinetics are also available:

>>> electron.get_norm_temp_gradient(psi_n)
>>> electron.get_norm_dens_gradient(psi_n)
>>> electron.get_norm_ang_vel_gradient(psi_n)

These correspond to:

\[-\frac{1}{f}\frac{\partial f}{\partial \rho}\]

for the relevant field \(f\).

Writing Files#

Kinetics objects may be written to NetCDF files:

>>> kin.to_netcdf("my_kinetics.nc")

They can later be reloaded using:

>>> kin = pk.read_kinetics("my_kinetics.nc")

Plotting#

The Kinetics class provides built-in plotting utilities using Matplotlib. By default, density, temperature, and rotation profiles for all species are plotted together.

>>> kin.plot(show=True)

This produces three panels showing:

  • Density

  • Temperature

  • Angular frequency

Profiles may be plotted either against \(\psi_N\) (default) or against the normalised minor radius \(r/a\):

>>> kin.plot(x_grid="r/a", show=True)

As with other plotting utilities in Pyrokinetics:

  • A Matplotlib Axes object may optionally be supplied.

  • The function returns the axes used.

  • Passing show=True immediately displays the figure.

Example with custom axes:

import matplotlib.pyplot as plt

fig, ax = plt.subplots(1, 3, figsize=(12, 4))
kin.plot(ax=ax)
plt.show()

See the Kinetics and Species API documentation for more details.