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 presentnx: The number of points in the R directionny: 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:
|
|
|
|
|
|
|
|
|
|
… |
… |
… |
… |
… |
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
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. Ifcocos >= 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
commentis a string, andinteger, nx, nyare 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:
- 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
ffprimeandpprimemay be excluded fromdata, in which case they will be filled with zeros. Similarly,rbdry,zbdry,rlimandzlimmay be excluded, in which case they aren’t added to the end of the file. Ifnbdryandnlimare excluded, they are inferred fromrbdryandrlim, and are set to zero if these aren’t found. Similarly, ifnxornyare excluded, they are inferred frompsi, 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
dictitem 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)