boutpy.boutdata – exchanging data to/from BOUT++

Table of Contents

boutgrid – More Information about BOUT++ Grid

class boutpy.boutdata.boutgrid(gridfile)[source]

BOUT++ grid object based on netcdf grid.

Attributes:
yind_omp : int

Yind of outer mid-plane

yind_imp : int

Yind of inner mid-plane

nx, ny : int

grid size

psin : 2D array

Normalized flux

psin95 : float

psin nearest to the 0.95

psin_limit : 1D array

[psin_min, psin_max]

q : 1D array

safety factor

xind_psin95 : int

xind of psin nearest to the 0.95

Methods

get_alpha(V0=0, pressure=None) Return local and global normalized pressure gradient.
get_magnetic_shear(V0=0) Return local and global magnetic shear s.
get_minor_r(method=1) Return minor radius.
get_peak_GradP0() Return peak position of Gradient P0 at outer mid-plane.
get_psin(yind=None, index=False, verbose=True) Get normalized psin from gridfile.
get_xind(psin=0.95) Return xind of psin at outer mid-plane to the psin.
get_q(q95=False) Return Safety Factor q.
get_volume(V0=0) Return volume enclosed by flux surface.
surface_average(var, area=False) Perform surface average.
topology() Check topology of the grid.
get_Va()[source]

Return Alfven Speed Va.

get_alpha(V0=0, pressure=None)[source]

Return local and global normalized pressure gradient.

local \(\alpha\) [6]:

\[\alpha = - \dfrac{2 \mu_0 q^2R_0}{B^2}\dfrac{dP_0}{dr}.\]

global \(\alpha\) [7]:

\[\alpha = - \dfrac{2 \partial_\psi V}{(2\pi)^2} \left(\dfrac{V}{2 \pi^2 R_0}\right)^{1/2} \mu_0 \dfrac{dP}{d\psi}.\]

in which the \(V\) is the volume enclosed by the flux surface.

In BOUT++ grid, it can be expressed as:

\[\begin{split}V(\psi) &= \int_{0}^{\psi} \int_0^{2\pi} \int_0^{2\pi} J(\psi, \theta) d\psi d\theta d\zeta \\ &= 2\pi \int_{0}^{\psi} \int_0^{2\pi} J(\psi, \theta) d\psi d\theta \\ &= V_0 + 2\pi \int_{\psi_{in}}^{\psi} \int_0^{2\pi} J(\psi, \theta) d\psi d\theta\end{split}\]

where the Jacobian is \(J(\psi, \theta) = J(x, y) = hthe/Bp\). The volume inside the inner boundary \(\psi_{in}\) should be calculated separately:

\[V_0 = 2\pi \int_{\psi_0}^{\psi_{in}} \int_0^{2\pi} J(\psi, \theta) d\psi d\theta\]
Parameters:
V0 : float, optional, default: 0

the volume inside the inner boundary \(\psi_{in}\). Generally, the grid excludes the core region. It should be calculated separately: generate new grid with \(\psi\) range \([\psi_0, \psi_{in}]\) and then calculate \(V_0\).

pressure : ndarray, optional, default: None

1D/2D array, using this pressure to calculate the alpha, if pressure == None by default, using the pressure in the grid.

Returns:
tuple(a_local, a_global)
a_local, a_global : tuple of ndarray

return local alpha and global alpha

References

[6]P.W. Xi, et. al., Phys. Rev. Lett. 112, 085001 (2014);
[7]R.L. Miller, et. al., Physics of Plasmas 5, 973 (1998);
get_magnetic_shear(V0=0)[source]

Return local and global magnetic shear s.

local megnetic shear s [8]:

\[s = \dfrac{r}{q}\dfrac{dp}{dr}\]

global megnetic shear s [9] [10]:

\[\begin{split}s & = \dfrac{2V \partial_\psi q}{\partial_\psi V} \\ & = 2V \dfrac{\partial q(\psi)}{\partial V(\psi)} \\ & \approx \dfrac{r}{q}\dfrac{dp}{dr}\end{split}\]

in which the \(V\) is the volume enclosed by the flux surface.

Returns:
tuple(s_local, s_global)
s_local, s_global : tuple of ndarray

return local shear and global shear

References

[8]P.W. Xi, et. al., Phys. Rev. Lett. 112, 085001 (2014);
[9]R.L. Miller, et. al., Physics of Plasmas 5, 973 (1998);
[10]F.M. Levinton, et. al., Phys. Rev. Lett. 75, 4417 (1995);
get_minor_r(method=1)[source]

Retrun minor radius.

Parameters:
self : str or dict

name of grid file or dict of grid data

method : 1, 2, 3, optional, default: 1.

method to calculate the minor radius.

  • method = 1: \(r=(R_{xy}[:, omp] - R_{xy}[:, imp])/2\);
  • method = 2: \(r=h_{\theta}=\dfrac{1}{|\nabla \theta|}\);
  • method = 3: \(r = R_{xy}[:, omp] - R_0\).
Returns:
minor_r : ndarray

1D array of minor radius.

get_peak_GradP0(pressure=None)[source]

Return peak position of Gradient P0 at outer mid-plane.

Parameters:
pressure : ndarray, optional, default: None

1D/2D array, using this pressure to calculate the alpha, if pressure == None by default, using the pressure in the grid.

Returns:
tuple(index, psin)
index: int

index of peak position of Gradient P0.

psin: float

psin of peak position of Gradient P0.

get_psin(yind=None, index=False, verbose=False)[source]

Get normalized psi_n from gridfile

\[\psi_n = \dfrac{\psi_{xy} - \psi_{axis}}{\psi_{bndry} - \psi_{axis}}\]
Parameters:
yind : index of y-axis, string omp, imp

by default the psi_n is a 2D array. when yind is specified, only 1D psi_n is calculated. for cbm grid serials, the psi_n is independent on the yind. omp: get psi_n at outer mid-plane imp: get psi_n at inner mid-plane

index : bool, optional, default: False

if index = True, then return indices of both outer & inner mid-plane

verbose : bool, optional, default: True

output more information

Returns:
psi_n : 1D or 2D array according to the yind option
yind_imp, yind_omp : int

y indices of inner & outer mid-plane

If ``index = True``, then return tuple(psin, yind_imp, yind_omp),
otherwise return ``psi_n`` by defualt.
get_q(q95=False)[source]

Return Safety Factor q.

Safety Factor q:

\[q = -\dfrac{\text{ShiftAngle}}{2\pi}\]
Parameters:
q95 : bool, optional, default: False

return q at \(\psi_n = 0.95\) if True.

Returns:
q : scalar, nd-array

1D array safety factor q if q95 = False by default, otherwise return q at \(\psi_n = 0.95\).

get_volume(V0=0)[source]

Return volume enclosed by flux surface.

Parameters:
V0 : float, optional, default: 0

the volume inside the inner boundary \(\psi_{in}\). Generally, the grid excludes the core region. It should be calculated separately: generate new grid with \(\psi\) range \([\psi_0, \psi_{in}]\) and then calculate \(V_0\).

get_xind(psin=0.95)[source]

Return xind of psin at outer mid-plane nearest to the psin.

Parameters:
psin : float
Returns:
tuple(xind, psin)
xind : int
psin : float
surface_average(var, area=False, method=1)[source]

Perform surface average

Parameters:
var : ndarray

3/4D variable in [x, y, z, [t]] order.

area : bool, optional, default: False

average by flux-surface area = (B/Bp)*dl*R*dz. By default, averages over poloidal angle such that surface_average(nu) = q.

Notes

This function is based on IDL function in BOUT_TOP/tools/idllib/surface_average.pro.

topology()[source]

Return the number of xpoint and Check topology of grid.

Returns:
nxpoint : int

the number of xpoints

References

process_grid.pro :
BOUT_TOP/tools/tokamak_grid/gridgen
BOUT++ Topology :
BOUT++ user manual, section 11.1

Field – Field Class

class boutpy.boutdata.Field[source]

Methods

moment_xyzt(axis=-1) return (dc, rms) parts at axis=`axis`.
dc(axis=-1) return dc parts at axis=`axis`.
rms(axis=-1) return rms parts at axis=`axis`.
normalize(norm=None) data normalized by norm if norm is given, otherwise maximum used.
plot(*arg, **kwargs) plot line(s) or animated lines for 1D/2D data.
contourf(*args, **kwargs) plot (animated) contour/contourf/surface plot for 2D/3D data.
showdata(*args, **kwargs) Visualiaztion and animation for 1/2/3D data.
contourf(*args, **kwargs)[source]

Plot (animated) contour/contourf/surface plot for 2D/3D data.

Parameters:
kind: str, optional, default: ‘surface’
  • [‘c’, ‘contour’, 1, ‘cf’, ‘contourf’, 2]: contour/contourf plot
  • ‘surface’: 3D-surface plot
newfig: bool, optional, default: True

if Ture[default], create new figure, otherwise, plot on current figure and axes

x/y: 1D array_like, optional, default: None

the size should be same as data in x/y direction.

x/y/zlabel: str, optional, default: None

labels for x/y/z-axis,

zleft: bool, optional, default: True

draw z-axis at left side

x/ylim: 2-elements data, optional, default: None

axis limit for x/y-axis if None, auto-set to its index: [0, 1, …, x/ysize-1]

zlim: 2-elements data, optional, default: None

axis limit for z-axis if None, auto-set to [vmin, vmax]

vmin/vmax: number, optional, default: None

set color limit to [vmin, vmax] if None, auto-set to the range of data

title: str, optional, default: None

figure title in animation, it is passed to ‘title.format(frame_number)’ or ‘index = {}”.format(frame_number) if it is None.

cmap: Colormap, optional, default: plt.cm.bwr

A cm Colormap instance.

colorbar: bool, optional, default: True

if True, plot colorbar

cticks: 1D array_like, optional, default: None

colorbar ticks. if None, auto-set to evenly spaced interval [vmin, vmax] by factor ncticks.

ncticks: int, optional, default: 5

the number of ticks of colorbar when cticks is not set.

levels: 1D array_like, optional, default: None

a list of floating point numbers indicating the level curves to draw, in increasing order. if None, auto-set to evenly spaced interval [vmin, vmax] by factor nlevels.

nlevels: int, optional, default: 40

the number of levels to contour/contourf draw.

output: str, optional, default: None

filename to store the figure or animation. It should include suffix. ‘.gif’ format is recommended.

**key-word arguments for 2D data:**
index: int | array_like, default: 1
  • array_like: only using data[:, index] for animation.
  • int: only using data[:, ::index] for animation, the last
    frame is included as well.
**key-word argments for animation:**
interval: int, optional, default: 20

delay between frames in milliseconds.

fps: number, optional, default: 5

frames per second in the movie.

metadata: dict, optional, default: {artist:$USER}

Dictionary of keys and values for metadata to include in the output file. Some keys that may be use include: title, artist, genre, subject, copyright, srcform, comment.

bitrate: number, optional, default: -1

Specifies the number of bits used per second in the compressed movie, in kilobits per second. A higher number means a higher quality movie, but at the cost of increased file size. -1 means let utility auto-determine.

Returns:
ret: (figure object|animation object, colorbar object if exists)
dc(axis=-1)[source]

return dc part at axis=`axis`.

moment_xyzt(axis=-1)[source]

return (dc, rms) parts at axis=`axis`.

normalize(norm=None)[source]

return normalizaed array.

Parameters:
norm : float, optional

return result normalized to norm if it is given, otherwise result is normalized to maximum value by default.

plot(*args, **kwargs)[source]

plot line(s) or animated lines for 1D/2D data

Parameters:
kind: str, optional, default: ‘surface’

work for 2D data [‘m’, ‘mlines’, ‘multilines’]: multi-lines in one figure ‘animation’: animated lines

newfig: bool, optional, default: True

if Ture[default], create new figure, otherwise, plot on current figure and axes

x/ylabel: str, optional, default: None

labels for x/y-axis,

xlim: 2-elements data, optional, default: None

axis limit for x-axis

ylim: [2-elements data | ‘fixed’], optional, default: None

axis limit for y-axis ‘fixed’: automatically set the ylim according to the data limit.

title: str, optional, default: None

figure title in animation, it is passed to ‘title.format(frame_number)’ or ‘index = {}”.format(frame_number) if it is None.

grid: bool, optional, default: True

grid on if True.

output: str, optional, default: None

filename to store the figure or animation. It should include suffix. ‘.gif’ format is recommended.

**key-word arguments for 2D data:**
index: int | array_like, default: 1
  • array_like: only using data[:, index] for animation.
  • int: only using data[:, ::index] for animation, the last
    frame is included as well.
**key-word argments for animation:**
interval: int, optional, default: 20

delay between frames in milliseconds.

fps: number, optional, default: 5

frames per second in the movie.

metadata: dict, optional, default: {artist:$USER}

Dictionary of keys and values for metadata to include in the output file. Some keys that may be use include: title, artist, genre, subject, copyright, srcform, comment.

bitrate: number, optional, default: -1

Specifies the number of bits used per second in the compressed movie, in kilobits per second. A higher number means a higher quality movie, but at the cost of increased file size. -1 means let utility auto-determine.

Returns:
ret: figure object|animation object
rms(axis=-1)[source]

return rms part at axis=`axis`.

showdata(*args, **kwargs)[source]

Visualisation and animation for 1-3D data.

This function is just a wrapper function for plot and contourf. All args and kwargs are passed to these functions according to the dimension of data and key ‘kind’.

Parameters:
kind: str

plot type. the value for different dimension of data:

  • 1D-data:

    None: plot single line

  • 2D-data:

    • ‘surface’: surface plot [default]
    • ‘c’, ‘contour’, 1, ‘cf’, ‘contourf’, 2:
      contour/contourf plot
    • ‘m’, ‘multi’, ‘multilines’: multi-lines in one figure
    • ‘animation’: animated lines
  • 3D-data:
    ‘c’, ‘contour’, 1; ‘cf’, ‘contourf’, 2; ‘surface’:

    animated contour/contourf/surface plot

Other parameters:

check function plot() and boutpy.boutdata.Field.contourf() for details

See also

boutpy.boutdata.Field.plot()
plot 1D data and 2D data(multilines or animation).
boutpy.boutdata.Field.contourf()
plot 2D data and 3D data(contourf/surface or animation)

map_pfile2grid – Map Experimental Profile to Grid

map_1d4grid(x, y, gridfile[, index, ext, …]) Map 1D-profile to grid
map_nc2grid(gridfile, ncfile[, output, Er, …]) Map 1D profiles in ncfile to netcdf grid generated by hypnotoad.pro
map_pfile2grid(gridfile, pfile[, output, …]) Map pfile to netcdf grid generated by hypnotoad.pro

Map 1D experimental profiles to netcdf grid generated by hypernotoad.pro

boutpy.boutdata.map_pfile2grid.map_1d4grid(x, y, gridfile, index=None, ext=u'const', kind=u'cubic', sigma=8, mode=u'nearest', wtitle=u'', Er=None, vfilter=None, units=None, smooth=u'1st', w=None, sfactor=None, verbose=False, check_positive=False, **kwargs)[source]

Map 1D-profile to grid

  1. basic rule: constant in y-direction

  2. map \(E_r\):

    • E_r = er*Rxy*Bpxy/(Rxy*Bpxy)_omp,
    • E_r = omgeb*Rxy*Bpxy
  3. leg regions

    • SOL region: same as the nearest line which has core part
    • private flux region: constant values which are same as separatrix

Warning

The smooth method(smooth=gaussian: gaussian_filter1d) will slightly make the gradient at boundary closer to 0.

Parameters:
x : (N,) array_like

1-D array of independent input data. Must be increasing.

y : (N,) array_like

1-D array of dependent input data, of the same length as x.

psin : (M,) array_like

1-D array of independent data.

index : int array_like or int, optional, default: None

ignoring data points at index when fitting data. if index is a integer, then ignoring index data points at both ‘x’ boundary for smoothing purposes.

smooth : [‘gaussian’, ‘spline’, ‘1st’, ‘2nd’], optional, default: ‘1st’

smooth method if not None

  • ‘gaussian’: scipy.ndimage.gaussian_filter1d
  • ‘spline’: scipy.interpolate.UnivariantSpline
  • ‘1st’: smooth 1st order derivative
  • ‘2nd’: smooth 2nd order derivative
w : (M,) array_like, optional, default: None

weight for smoothing if ‘spline’ method used

sfactor : float, optional, default: None

smooth_factor for ‘spline’ method

ext : float, (float, float) or ‘const’, optional, default: ‘const’

Controls the extrapolation mode for elements not in the interval defined by the knot sequence.

  • float : slope for the profiles outside the interval
  • (float, float): slopes for both boundary
  • ‘const’: constant value outside the interval
sigma : scalar, default: 8

standard deviation for Gaussian kernel

mode : [‘reflect’, ‘constant’, ‘nearest’, ‘mirror’, ‘wrap’], optional

The mode parameter determines how the array borders are handled, where cval is the value when mode is equal to ‘constant’. Default is ‘nearest’.

wtitle : str, optional, default: ‘’.

addtional title string for plot window

units : str, optional, default: None

additional info for the profile: units. It is shown in the fig title. TODO: convert units in here?

Er : [‘er’, ‘omgeb’], optional, default: None
  • er: map ‘er’ to ‘E_r’, E_r = er*Rxy*Bpxy/(Rxy*Bpxy)_omp
  • omgeb: map ‘omgeb’ to ‘E_r’, E_r = omgeb*Rxy*Bpxy
  • None: constant in y-direction.
vfilter : int|float, optional, default: None

Set the data where are less than vfilter to the one closest to vfilter. Not used by default. It’s recommended for electron temperature, especially when the Spitzer resistivity, which is propotional to Te^{-1.5}, is used in the code.

check_positive : boel, optional, default: False

check that the profile only contains positive value. Raise ValueError if it contains nagetive value or 0.

verbose : bool, optional, default: False

output more details

Other keywords arguments are passed to smooth method.
Returns:
data_2d : 2D-array_like

2D data after mapping 1D to grid

boutpy.boutdata.map_pfile2grid.map_pfile2grid(gridfile, pfile, output=None, Er=u'omgeb', verbose=False, **kwargs)[source]

Map pfile to netcdf grid generated by hypnotoad.pro

Parameters:
gridfile : str

path to gridfile

pfile : str

path to pfile

output : str, None, default: None

output data to file output which is a copy of gridfile, if output is None, the suffix of filename is ‘_exp_constSOL_er’ (Er=’er’) or ‘_exp_constSOL_omgeb’(Er=’omgeb’),

Er : [‘er’|’omgeb’], default: ‘omgeb’
  • er: map ‘er’ to ‘E_r’, E_r = er*Rxy*Bpxy/(Rxy*Bpxy)_omp
  • omgeb: map ‘omgeb’ to ‘E_r’, E_r = omgeb*Rxy*Bpxy
verbose : bool, optional, default: False

output more information.

Other keywords arguments are passed to map_1d4grid()
Returns:
None
boutpy.boutdata.map_pfile2grid.map_nc2grid(gridfile, ncfile, output=None, Er=u'omgeb', verbose=False, **kwargs)[source]

Map 1D profiles in ncfile to netcdf grid generated by hypnotoad.pro

Parameters:
gridfile : str

path to gridfile

ncfile : str

path to ncfile, which includes 1D profiles.

output : str, None, default: None

output data to file output which is a copy of gridfile, if output is None, the suffix of filename is ‘_exp_constSOL_er’ (Er=’er’) or ‘_exp_constSOL_omgeb’(Er=’omgeb’),

Er : [‘er’|’omgeb’], default: ‘omgeb’

‘er’: map ‘er’ to ‘E_r’, E_r = er*Rxy*Bpxy/(Rxy*Bpxy)_omp ‘omgeb’: map ‘omgeb’ to ‘E_r’, E_r = omgeb*Rxy*Bpxy

Other keywords arguments are passed to map_1d4grid()
Returns:
None

collect – collect data

Function is for collecting data parallelly and more efficiently.

boutpy.boutdata.collect.collect(varname, xind=None, yind=None, zind=None, tind=None, path='data', yguards=False, info=False, prefix='BOUT.dmp', nthreads=None, shift=True, checkt=False)[source]

Collect a variable from a set of BOUT++ outputs in parallel.

Parameters:
varname : str

Name of the variable.

xind, yind, zind, tind: int or list[min, max], optional, default: None

Range for X/Y/Z/T indices to collect. If it’s None, it will collect all the data in this dimension.

path : str, optional, default: “./data”

Path to data files

prefix : str, optional, default: “BOUT.dmp”

File prefix

nthreads : int, optional, default: None

Using nthreads threads to speed up collocting. If nthreads=None, it is set to the number of the cpus in current node/system.

yguards : bool, optional, default: False

Collect Y boundary guard cells if yguards=True

checkt : bool, optional, default: False

Check t_array of each dump file and print broken files’ name if True.

shift : bool, optional, default: True

Shift axis if the variables is time-dependent .. centered:: [t, x, …] –> [x, …, t]

info : bool, optional, defalt: False

Print information about collect if True

Returns:
collect : Field

Notes

the shift option is set to True by default, which means it returns the data in [x, y, z, t] order which is different from the previous version in [t, x, y, z] order.

restart – manipulate restart files

Routines for manipulating restart files.

boutpy.boutdata.restart.split(nxpe, nype, path='data', output='./', informat='nc', outformat=None)[source]

Split restart files across NXPE x NYPE processors.

Returns True on success

boutpy.boutdata.restart.expand(newz, path='data', output='./', informat='nc', outformat=None)[source]

Increase the number of Z points in restart files

boutpy.boutdata.restart.create(averagelast=1, final=-1, path='data', output='./', informat='nc', outformat=None)[source]

Create restart files from data (dmp) files.

Parameters:
averagelast : int, optional, default: 1

Number of time points to average over. Just take last time-point by default.

final : int, optional, default: -1

The last time point to use. Default is last (-1)

path : str, optional, default: “data”

Path to the input data files

output : str, optional, default: “./”

Path where the output restart files should go

informat : str, optional, default: “nc”

Format of the input data files

outformat : str, optional, default: None

Format of the output restart files, it’s same as informat by default.

gen_surface – Flux Surface Generator

boutpy.boutdata.gen_surface.gen_surface(grid)[source]

Generator of flux surface indices

pol_slice – Poloidal Slice

Takes a 3D variable, and returns a 2D slice at fixed toroidal angle.

N sets the number of times the data must be repeated for a full torus, e.g. n=2 is half a torus zangle gives the (real) toroidal angle of the result

boutpy.boutdata.pol_slice.pol_slice(data3d, 'gridfile', n=1, zangle=0.0)[source]

data2d = pol_slice(data3d, ‘gridfile’, n=1, zangle=0.0)

Parameters:
var3d : 3D-array

3D vars in [x, y, z [, t]] order

gridfile : str

path to gridfile

n : int, optional, default: 1

zperiod used in simulation

zangle : float, optional, default: 0

get result at toroidal angle zangle (in degree)

Returns:
var2d : 2D-array

value of poloidal cross-section at toroidal angle zangle.

boutpy.boutdata.pol_slice.polslice(var3d, gridfile, n=1, zangle=0.0, profile=None)[source]

Return a 2D slice by interpolation.

Parameters:
var3d : 3D-array

3D vars in [x, y, z] order

gridfile : str | dict

path to gridfile (srt) or dict data of grid (dict)

n : int, optional, default: 1

zperiod used in simulation

zangle : float, optional, default: 0

get result at toroidal angle zangle (in degree).

profile : ndarray, optional, default: None

equilibrium profile.

Returns:
var2d : 2D-array

value of poloidal cross-section at toroidal angle zangle.