geqdsk#

G-EQDSK files describe Grad-Shafranov tokamak plasma equilibria. These may be generated via a Grad-Shafranov solver, or by fitting to experimental measurements. Tools that make use of G-EQDSK files include, but are not limited to:

  • EFIT

  • FreeGS

  • SCENE

  • TRANSP

G-EQDSK files begin with a header line containing the following information:

  • comment: This normally includes information such as the software used to generate the file, the date of creation, a shot number, and the time frame within the shot. Unfortunately, the format of this line is not rigorously defined, so each code will tend to define it differently.

  • int: Typically the shot number for experiments, otherwise not used, but usually required to be present

  • nx: The number of points in the R direction

  • ny: The number of points in the Z direction

FreeQDSK will be quite liberal when reading the header line, as long as it ends with three space-separated integers. In particlar, nx and ny are required to correctly parse the rest of the file.

When writing files, FreeQDSK will write the header with the Fortran format (a48,3i4) by default.

After the header, there are 4 lines of floats describing a tokamak plasma equilibrium. Each line contains 5 floats, following the Fortran format (5e16.9). These floats are:

rdim

zdim

rcentr

rleft

zmid

rmagx

zmagx

simagx

sibdry

bcentr

cpasma

simagx

rmagx

zmagx

sibdry

The blank spaces are ignored, and are usually set to zero. Note that rmagx, zmagx, simagx, and sibdry are duplicated. The meaning of these floats are:

rdim

Width of computational domain in R direction, float [meter]

zdim

Height of computational domain in Z direction, float [meter]

rcentr

Reference value of R, float [meter]

rleft

R at left (inner) boundary, float [meter]

zmid

Z at middle of domain, float [meter]

rmagx

R at magnetic axis (0-point), float [meter]

zmagx

Z at magnetic axis (0-point), float [meter]

simagx

Poloidal flux \(\psi\) at magnetic axis, float [weber / radian]

sibdry

Poloidal flux \(\psi\) at plasma boundary, float [weber / radian]

bcentr

Vacuum toroidal magnetic field at rcentr, float [tesla]

cpasma

Plasma current, float [ampere]

This is then followed by a series of grids:

fpol

Poloidal current function \(F(\psi)=RB_t\), 1D array [meter * tesla]

pres

Plasma pressure \(p(\psi)\), 1D array [pascal]

ffprime

\(FF'(\psi)\), 1D array [meter**2 * tesla**2 * radian / weber]

pprime

\(p'(\psi)\), 1D array [pascal * radian / weber]

psi

Poloidal flux \(\psi\), 2D array [weber / radian]

qpsi

Safety factor \(q(\psi)\), 1D array [dimensionless]

The 1D arrays are expressed on a linearly spaced \(\psi\) grid which may be generated using numpy.linspace(simagx, sibdry, nx). The 2D \(\psi\) grid is instead expressed on a linearly spaced grid extending the range [rleft, rleft + rdim] in the R direction and [zmid - zdim/2, zmid + zdim/2] in the Z direction. Each grid is printed over multiple lines using the Fortran format (5e16.9), with the final line containing some blank spaces if the total grid size is not a multiple of 5. Note that the psi grid is expressed in a flattened state using Fortran ordering, meaning it increments in the columns direction first, then in rows.

The G-EQDSK file then gives information on the plasma boundary and the surrounding limiter contour. The next line gives the dimensions of these grids in the format (2i5):

nbdry

Number of points in the boundary grid, int

nlim

Number of points in the limiter grid, int

Finally, the boundary and limiter grids are specified as lists of (R, Z) coordinates, again using the format (5e16.9):

rbdry

R of boundary points, 1D array [meter]

zbdry

Z of boundary points, 1D array [meter]

rlim

R of limiter points, 1D array [meter]

zlim

Z of limiter points, 1D array [meter]

Note that these grids are interleaved, so are expressed as:

rbdry[0]

zbdry[0]

rbdry[1]

zbdry[1]

rbdry[2]

zbdry[2]

rbdry[3]

zbdry[3]

rbdry[4]

rbdry[4]

A note on coordinate conventions#

Various conventions regarding the orientation of the toroidal angle \(\varphi\) and the poloidal angle \(\theta\) are in use. For example, if looking from the top \(\nabla\varphi = \frac{1}{R}\hat e_\varphi\) can either point clockwise or counter-clockwise depending on whether \((R,Z,\varphi)\) or \((R,\varphi,Z)\) is used as cylindrical coordinates. This observations led to the formal definition of the COCOS conventions in O. Sauter and S. Y Medvedev, “Tokamak Coordinate Conventions: COCOS”, Comput. Phys. Commun. 184 (2013) 293 From the paper the magnetic field can be generally expressed as

\[\vec B = F(\psi) \nabla \varphi + \sigma_{B_p} \frac{1}{(2\pi)^{e_{B_p}}} \nabla\varphi \times \nabla\psi\]

where \(\sigma_{B_P} = \pm 1\) and \(e_{B_p} \in \{ 0,1\}\) depends on the convention in use. The orientation of the poloidal angle \(\theta\) largely affects the sign of \(q\) (if \((\rho,\theta,\varphi)\) is right-handed then q is positive for right-handed field winding while if \((\rho,\theta,\varphi)\) is left-handed then q is positive for left-handed winding). However, some tools define q as always positive so the paper warns against using it as a consistency check.

Note the table of conventions in https://crppwww.epfl.ch/~sauter/cocos/

SPDX-FileCopyrightText: © 2016 Ben Dudson, University of York.

SPDX-License-Identifier: MIT

geqdsk.read(cocos=1, header_fmt=None, data_fmt=None, bdry_lim_fmt=None)#

Read a G-EQDSK formatted equilibrium file. The format is specified here.

Parameters:
  • fh (TextIO) – File handle to read from. Should be opened in a text read mode, i.e. open(filename, "r").

  • cocos (int (default: 1)) – COordinate COnventionS. This feature is not fully handled yet, and only determines whether psi is divided by \(2\pi\) or not. If cocos >= 10, \(\psi\) is divided by \(2\pi\), and otherwise it is left unchanged. See Sauter et al, 2013.

  • header_fmt (Optional[str] (default: None)) –

    Fortran IO format for G-EQDSK header line. By default, tries to be liberal with parsing the header, but it is expected to be in the form:

    comment integer nx ny
    

    where comment is a string, and integer, nx, ny are all integers.

  • data_fmt (Optional[str] (default: None)) – Fortran IO format for G-EQDSK data. If not provided, uses (5e16.9).

  • bdr_lim_fmt – Fortran IO format specifying the lengths of the boundary/limiter grids. If not provided, defaults to (2i5)

Warns:

UserWarning – If any of the entries that are duplicated in the file do not match. These include ‘rmagx’, ‘zmagx’, ‘simagx’ and ‘sibdry’. The value returned will be the last found.

Return type:

GEQDSKFile

geqdsk.write(fh, label=None, shot=0, time=0, header_fmt=None, data_fmt=None, bdry_lim_fmt=None)#

Write a G-EQDSK equilibrium file, given a dictionary of data.

Parameters:
  • data (GEQDSKFile | GeqdskDataDict) – G-EQDSK data to write. See the ‘Notes’ section below for info.

  • fh (TextIO) – File handle to write to. Should be opened in a text write mode, i.e. open(filename, "w").

  • label (Optional[str] (default: None)) – Text label to put in the file. Defaults to ‘FREEGS’ if not provided.

  • shot (int (default: 0)) – Shot number to put in the file.

  • time (int (default: 0)) – Time in milliseconds to put in the file.

  • header_fmt (Optional[str] (default: None)) – Fortran IO format for G-EQDSK header line. If not provided, uses (a48,3i4), corresponding to a comment, a dummy int, nx, and ny.

  • data_fmt (Optional[str] (default: None)) – Fortran IO format for G-EQDSK data. If not provided, uses (5e16.9).

  • bdry_lim_fmt (Optional[str] (default: None)) – Fortran IO format specifying the lengths of the boundary/limiter grids. If not provided, defaults to (2i5).

Raises:
  • KeyError – If required information is missing from data.

  • ValueError – If the provided arrays have incorrect dimensions, or if the data provided is of the wrong type.

Notes

Return type:

None

ffprime and pprime may be excluded from data, in which case they will be filled with zeros. Similarly, rbdry, zbdry, rlim and zlim may be excluded, in which case they aren’t added to the end of the file. If nbdry and nlim are excluded, they are inferred from rbdry and rlim, and are set to zero if these aren’t found. Similarly, if nx or ny are excluded, they are inferred from psi, which should have the shape (nx, ny).

class freeqdsk.geqdsk.GEQDSKFile(comment, shot, nx, ny, rdim, zdim, rcentr, rleft, zmid, rmagx, zmagx, simagx, sibdry, bcentr, cpasma, fpol, pres, ffprime, pprime, psi, qpsi, nbdry, nlim, rbdry=None, zbdry=None, rlim=None, zlim=None)#

G-EQDSK equilibrium.

Includes some common synonyms for the “canonical” names, as well as some more human-readable ones. In the Attributes section below, canonical names are listed first.

When creating an instance, if keyword arguments are used, they should be the canonical names.

comment#

Header comment

shot#

Header shot number

nx, nw, nr

Number of radial points

ny, nh, nz

Number of vertical points

rdim#

Width of computational domain in R direction, float [meter]

zdim#

Height of computational domain in Z direction, float [meter]

rcentr#

Reference value of R, float [meter]

rleft#

R at left (inner) boundary, float [meter]

zmid#

Z at middle of domain, float [meter]

rmagx, rmaxis

R at magnetic axis (0-point), float [meter]

zmagx, zmaxis

Z at magnetic axis (0-point), float [meter]

simagx, psi_axis

Poloidal flux \(\psi\) at magnetic axis, float [weber / radian]

sibdry, psi_boundary

Poloidal flux \(\psi\) at plasma boundary, float [weber / radian]

bcentr#

Vacuum toroidal magnetic field at rcentr, float [tesla]

cpasma, current

Plasma current, float [ampere]

fpol#

Poloidal current function \(F(\psi)=RB_t\), 1D array [meter * tesla]

pres, pressure

Plasma pressure \(p(\psi)\), 1D array [pascal]

ffprime#

\(FF'(\psi)\), 1D array [meter**2 * tesla**2 * radian / weber]

pprime#

\(p'(\psi)\), 1D array [pascal * radian / weber]

psi, f, psirz

Poloidal flux \(\psi\), 2D array [weber / radian]

qpsi#

Safety factor \(q(\psi)\), 1D array [dimensionless]

nbdry, nbbbs

Number of points in the boundary grid, int

nlim, limitr

Number of points in the limiter grid, int

rbdry, rbbbs

R of boundary points, 1D array [meter]

zbdry, zbbbs

Z of boundary points, 1D array [meter]

rlim#

R of limiter points, 1D array [meter]

zlim#

Z of limiter points, 1D array [meter]

Examples

Variables can be accessed with either the attribute dot syntax or dict item access. For example, the poloidal flux on the magnetic axis can be accessed via any one of the following:

>>> gfile = GEQDSKFile(...)
>>> print(gfile["simagx"])
>>> print(gfile.simagx)
>>> print(gfile.psi_axis)