boutdata package#

Module contents#

Routines for exchanging data to/from BOUT++

boutdata.attributes(varname, path='.', prefix='BOUT.dmp')#

Return a dictionary of variable attributes in an output file

Parameters:
  • varname (str) – Name of the variable

  • path (str, optional) – Path to data files (default: “.”)

  • prefix (str, optional) – File prefix (default: “BOUT.dmp”)

Returns:

A dictionary of attributes of varname

Return type:

dict

boutdata.collect(varname, xind=None, yind=None, zind=None, tind=None, path='.', yguards=False, xguards=True, info=True, prefix='BOUT.dmp', strict=False, tind_auto=False, datafile_cache=None)#

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

Parameters:
  • varname (str) – Name of the variable

  • xind, yind, zind, tind (int, slice or list of int, optional) – Range of X, Y, Z or time indices to collect. Either a single index to collect, a list containing [start, end] (inclusive end), or a slice object (usual python indexing). Default is to fetch all indices

  • path (str, optional) – Path to data files (default: “.”)

  • prefix (str, optional) – File prefix (default: “BOUT.dmp”)

  • yguards (bool or “include_upper”, optional) – Collect Y boundary guard cells? (default: False) If yguards==”include_upper” the y-boundary cells from the upper (second) target are also included.

  • xguards (bool, optional) – Collect X boundary guard cells? (default: True) (Set to True to be consistent with the definition of nx)

  • info (bool, optional) – Print information about collect? (default: True)

  • strict (bool, optional) – Fail if the exact variable name is not found? (default: False)

  • tind_auto (bool, optional) – Read all files, to get the shortest length of time_indices. Useful if writing got interrupted (default: False)

  • datafile_cache (datafile_cache_tuple, optional) – Optional cache of open DataFile instances: namedtuple as returned by create_cache. Used by BoutOutputs to pass in a cache so that we do not have to re-open the dump files to read another variable (default: None)

Examples

>>> collect(name)
BoutArray([[[[...]]]])

Submodules#

boutdata.cbdtoeqdsk module#

class boutdata.cbdtoeqdsk.Bunch#
boutdata.cbdtoeqdsk.cbmtogeqdsk(g)#

boutdata.collect module#

boutdata.collect.attributes(varname, path='.', prefix='BOUT.dmp')#

Return a dictionary of variable attributes in an output file

Parameters:
  • varname (str) – Name of the variable

  • path (str, optional) – Path to data files (default: “.”)

  • prefix (str, optional) – File prefix (default: “BOUT.dmp”)

Returns:

A dictionary of attributes of varname

Return type:

dict

boutdata.collect.collect(varname, xind=None, yind=None, zind=None, tind=None, path='.', yguards=False, xguards=True, info=True, prefix='BOUT.dmp', strict=False, tind_auto=False, datafile_cache=None)#

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

Parameters:
  • varname (str) – Name of the variable

  • xind, yind, zind, tind (int, slice or list of int, optional) – Range of X, Y, Z or time indices to collect. Either a single index to collect, a list containing [start, end] (inclusive end), or a slice object (usual python indexing). Default is to fetch all indices

  • path (str, optional) – Path to data files (default: “.”)

  • prefix (str, optional) – File prefix (default: “BOUT.dmp”)

  • yguards (bool or “include_upper”, optional) – Collect Y boundary guard cells? (default: False) If yguards==”include_upper” the y-boundary cells from the upper (second) target are also included.

  • xguards (bool, optional) – Collect X boundary guard cells? (default: True) (Set to True to be consistent with the definition of nx)

  • info (bool, optional) – Print information about collect? (default: True)

  • strict (bool, optional) – Fail if the exact variable name is not found? (default: False)

  • tind_auto (bool, optional) – Read all files, to get the shortest length of time_indices. Useful if writing got interrupted (default: False)

  • datafile_cache (datafile_cache_tuple, optional) – Optional cache of open DataFile instances: namedtuple as returned by create_cache. Used by BoutOutputs to pass in a cache so that we do not have to re-open the dump files to read another variable (default: None)

Examples

>>> collect(name)
BoutArray([[[[...]]]])
boutdata.collect.create_cache(path, prefix)#

Create a list of DataFile objects to be passed repeatedly to collect.

Parameters:
  • path (str) – Path to data files

  • prefix (str) – File prefix

Returns:

namedtuple – list of DataFile) The cache of DataFiles in a namedtuple along with the file_list, and parallel and suffix attributes

Return type:

(list of str, bool, str,

boutdata.collect.dimensions(varname, path='.', prefix='BOUT.dmp')#

Return the names of dimensions of a variable in an output file

Parameters:
  • varname (str) – Name of the variable

  • path (str, optional) – Path to data files (default: “.”)

  • prefix (str, optional) – File prefix (default: “BOUT.dmp”)

Returns:

The elements of the tuple give the names of corresponding variable dimensions

Return type:

tuple of strs

boutdata.collect.findFiles(path, prefix)#

Find files matching prefix in path.

Netcdf (“.nc”, “.ncdf”, “.cdl”) and HDF5 (“.h5”, “.hdf5”, “.hdf”) files are searched.

Parameters:
  • path (str) – Path to data files

  • prefix (str) – File prefix

Returns:

tuple – The first element of the tuple is the list of files, the second is whether the files are a parallel dump file and the last element is the file suffix.

Return type:

(list of str, bool, str)

boutdata.collect.findVar(varname, varlist)#

Find variable name in a list

First does case insensitive comparison, then checks for abbreviations.

Returns the matched string, or raises a ValueError

Parameters:
  • varname (str) – Variable name to look for

  • varlist (list of str) – List of possible variable names

Returns:

The closest match to varname in varlist

Return type:

str

boutdata.data module#

Provides a class BoutData which makes access to code inputs and outputs easier. Creates a tree of maps, inspired by approach used in OMFIT

boutdata.data.BoutData(path='.', prefix='BOUT.dmp', caching=False, **kwargs)#

Returns a dictionary, containing the contents of a BOUT++ output directory.

Does not allow writing, only reading of data. By default there is no cache, so each time a variable is read it is collected; if caching is set to True variables are stored once they are read.

Parameters:
  • path (str, optional) – Path to data files (default: “.”)

  • prefix (str, optional) – File prefix (default: “BOUT.dmp”)

  • caching (bool, float, optional) – Switches on caching of data, so it is only read into memory when first accessed (default False) If caching is set to a number, it gives the maximum size of the cache in GB, after which entries will be discarded in first-in-first-out order to prevent the cache getting too big. If the variable being returned is bigger than the maximum cache size, then the variable will be returned without being added to the cache, and the rest of the cache will be left (default: False)

  • DataFileCaching (bool, optional) – Switch for creation of a cache of DataFile objects to be passed to collect so that DataFiles do not need to be re-opened to read each variable (default: True)

  • **kwargs – Keyword arguments that are passed through to collect()

Returns:

Contents of a BOUT++ output directory, including options and output files

Return type:

dict

Examples

>>> d = BoutData(".")  # Current directory
>>> d.keys()     # List all valid keys
>>> print(d["options"])  # Prints tree of options
>>> d["options"]["nout"]   # Value of nout in BOUT.inp file
>>> print(d["outputs"])    # Print available outputs
>>> d["outputs"]["ne"] # Read "ne" from data files
>>> d = BoutData(".", prefix="BOUT.dmp", caching=True) # Turn on caching
class boutdata.data.BoutOptions(name='root', parent=None)#

This class represents a tree structure. Each node (BoutOptions object) can have several sub-nodes (sections), and several key-value pairs.

Parameters:
  • name (str, optional) – Name of the root section (default: “root”)

  • parent (BoutOptions, optional) – A parent BoutOptions object (default: None)

Examples

>>> optRoot = BoutOptions()  # Create a root

Specify value of a key in a section “test” If the section does not exist then it is created

>>> optRoot.getSection("test")["key"] = 4

Get the value of a key in a section “test” If the section does not exist then a KeyError is raised

>>> print(optRoot["test"]["key"])
4

To pretty print the options

>>> print(optRoot)
[test]
key = 4
as_dict()#

Return a nested dictionary of all the options.

as_tree(indent='')#

Return a string formatted as a pretty version of the options tree

evaluate_scalar(name)#

Evaluate (recursively) scalar expressions

getSection(name)#

Return a section object. If the section does not exist then it is created

Parameters:

name (str) – Name of the section to get/create

Returns:

A new section with the original object as the parent

Return type:

BoutOptions

get_bool(name, default=None)#

Convert an option value to a bool, in (almost) the same way as BOUT++.

Warning

BOUT++ will convert any option value beginning with “y”, “Y”, “t”, “T” or “1” to True, and any beginning with “n”, “N”, “f”, “F” or “0” to False. Because BoutOptions converts option values to int and float, this method cannot be quite so permissive, and will raise an exception for ints other than 0 and 1 and for floats, which BOUT++ might convert to a bool.

Parameters:
  • name (str) – The name of the option to read

  • default (bool, optional) – Value to return if the option is not present. If default is not provided an exception will be raised if the option is not present.

keys()#

Returns all keys, including sections and values

path()#

Returns the path of this section, joining together names of parents

pop(k[, d]) v, remove specified key and return the#

corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised.

rename(old_name, new_name)#

Rename old_name to new_name

sections()#

Return a list of sub-sections

values()#

Return a list of values

class boutdata.data.BoutOptionsFile(filename='BOUT.inp', name='root', gridfilename=None, nx=None, ny=None, nz=None)#

Parses a BOUT.inp configuration file, producing a tree of BoutOptions.

Slight differences from ConfigParser, including allowing values before the first section header.

Parameters:
  • filename (str, optional) – Path to file to read

  • name (str, optional) – Name of root section (default: “root”)

  • gridfilename (str, optional) – If present, path to gridfile from which to read grid sizes (nx, ny, nz)

  • nx, ny (int, optional) –

    • Specify sizes of grid, used when evaluating option strings

    • Cannot be given if gridfilename is specified

    • Must both be given if either is

    • If neither gridfilename nor nx, ny are given then will try to find nx, ny from (in order) the ‘mesh’ section of options, outputfiles in the same directory is the input file, or the grid file specified in the options file (used as a path relative to the current directory)

  • nz (int, optional) – Use this value for nz when evaluating option expressions, if given. Overrides values found from input file, output files or grid files

Examples

>>> opts = BoutOptionsFile("BOUT.inp")
>>> print(opts)   # Print all options in a tree
root
|- nout = 100
|- timestep = 2
...
>>> opts["All"]["scale"] # Value "scale" in section "All"
1.0
COMMENT_REGEX = re.compile('(.*?)(\\s*)([#;].*)')#
VALID_COMMENTS = ('#', ';')#
evaluate(name, *, location='CELL_CENTRE')#

Evaluate (recursively) expressions

Sections and subsections must be given as part of ‘name’, separated by colons

Parameters:

name (str) – Name of variable to evaluate, including sections and subsections

recalculate_xyz(*, nx=None, ny=None, nz=None)#

Recalculate the x, y avd z arrays used to evaluate expressions

write(filename=None, overwrite=False)#

Write to BOUT++ options file

This method will throw an error rather than overwriting an existing file unless the overwrite argument is set to true. Note, no comments from the original input file are transferred to the new one.

Parameters:
  • filename (str) – Path of the file to write (defaults to path of the file that was read in)

  • overwrite (bool) – If False then throw an exception if ‘filename’ already exists. Otherwise, just overwrite without asking. (default False)

class boutdata.data.BoutOutputs(path='.', prefix='BOUT.dmp', suffix=None, caching=False, DataFileCaching=True, info=False, xguards=True, yguards=False, tind=None, xind=None, yind=None, zind=None, tind_auto=False, parallel=False, **kwargs)#

Emulates a map class, represents the contents of a BOUT++ dmp files. Does not allow writing, only reading of data. By default there is no cache, so each time a variable is read it is collected; if caching is set to True variables are stored once they are read. Extra keyword arguments are passed through to collect.

Parameters:
  • path (str, optional) – Path to data files (default: “.”)

  • prefix (str, optional) – File prefix (default: “BOUT.dmp”)

  • suffix (str, optional) – File suffix (default: None, searches all file extensions)

  • caching (bool, float, optional) – Switches on caching of data, so it is only read into memory when first accessed (default False) If caching is set to a number, it gives the maximum size of the cache in GB, after which entries will be discarded in first-in-first-out order to prevent the cache getting too big. If the variable being returned is bigger than the maximum cache size, then the variable will be returned without being added to the cache, and the rest of the cache will be left (default: False)

  • DataFileCaching (bool, optional) – Switch for creation of a cache of DataFile objects to be passed to collect so that DataFiles do not need to be re-opened to read each variable (default: True)

  • info (bool, optional) – Print information about grid and data loading? (default: False)

  • xguards (bool, optional) – Collect X boundary guard cells? (default: True) (Set to True to be consistent with the definition of nx)

  • yguards (bool or “include_upper”, optional) – Collect Y boundary guard cells? (default: False) If yguards==”include_upper” the y-boundary cells from the upper (second) target are also included.

  • xind, yind, zind, tind (int, slice or list of int, optional) – Range of X, Y, Z or time indices to collect. Either a single index to collect, a list containing [start, end] (inclusive end), or a slice object (usual python indexing). Default is to fetch all indices

  • parallel (bool or int, default False) – If set to True or 0, use the multiprocessing library to read data in parallel with the maximum number of available processors. If set to an int, use that many processes.

  • tind_auto (bool, optional) – Read all files, to get the shortest length of time_indices. All data truncated to the shortest length. Useful if writing got interrupted (default: False)

Other Parameters:

keyword arguments that are passed through to collect()

Examples

>>> d = BoutOutputs(".")  # Current directory
>> d.keys()     # List all valid keys
['iteration',
 'zperiod',
 'MYSUB',
 ...
]
>>> d.dimensions["ne"] # Get the dimensions of the field ne
('t', 'x', 'y', 'z')
>>> d["ne"] # Read "ne" from data files
BoutArray([[[[...]]]])
>>> d = BoutOutputs(".", prefix="BOUT.dmp", caching=True) # Turn on caching
property dimensions#

Accesss a dict of dimensions of the variables

evolvingVariables()#

Return a list of names of time-evolving variables

get_attribute(variable, attrname)#

Get an attribute of a variable

Parameters:
  • variable (str) – Name of variable to get attribute from

  • attrname (str) – Name of attribute

Return type:

Value of attribute

get_file_attribute(attrname)#

Get an attribute of the output files.

Attribute is taken from the rank-0 file. No checking is done that the attribute is consistent between all the output files.

Parameters:

attrname (str) – Name of attribute

Return type:

Value of attribute

keys()#

Return a list of available variable names

list_file_attributes()#

List all file attributes of output files

List is taken from the rank-0 file. No checking is done that the file attributes are consistent between all the output files.

Returns:

Names of the file attributes

Return type:

List of str

redistribute(npes, nxpe=None, mxg=2, myg=2, include_restarts=True)#

Create a new set of dump files for npes processors.

Useful for restarting simulations using more or fewer processors.

Existing data and restart files are kept in the directory “redistribution_backups”. redistribute() will fail if this directory already exists, to avoid overwriting anything

Parameters:
  • npes (int) – Number of new files to create

  • nxpe (int, optional) – If nxpe is None (the default), then an ‘optimal’ number will be selected automatically

  • mxg, myg (int, optional) – Number of guard cells in x, y (default: 2)

  • include_restarts (bool, optional) – If True, then restart.redistribute will be used to redistribute the restart files also (default: True)

class boutdata.data.CaseInsensitiveDict(dict=None, /, **kwargs)#

boutdata.gen_surface module#

Flux surface generator for tokamak grid files

boutdata.gen_surface.gen_surface(grid)#

Generator for iterating over flux surfaces

Parameters:

grid (DataFile) – An input grid file to read to find flux surfaces

Yields:

tuple ((int, list of int, bool)) – A tuple containing the x index, list of y indices and whether this flux surface is periodic

boutdata.griddata module#

Routines for manipulating grid files

boutdata.griddata.bout2sonnet(grdname, outf)#

Creates a Sonnet format grid from a BOUT++ grid.

NOTE: Branch cuts are not yet supported

Parameters:
  • grdname (str) – Filename of BOUT++ grid file

  • outf (File) – The file-like object to write to

Examples

>>> with open("output.sonnet", "w") as f:
...     bout2sonnet("BOUT.grd.nc", f)
boutdata.griddata.gridcontourf(grid, data2d, nlevel=31, show=True, mind=None, maxd=None, symmetric=False, cmap=None, ax=None, xlabel='Major radius [m]', ylabel='Height [m]', separatrix=False, log=False, remove_xguards=False)#

Plots a 2D contour plot, taking into account branch cuts (X-points).

Parameters:
  • grid (DataFile) – A DataFile object

  • data2d (array_like) – A 2D (x,y) NumPy array of data to plot

  • nlevel (int, optional) – Number of levels in the contour plot

  • show (bool, optional) – If True, will immediately show the plot

  • mind (float, optional) – Minimum data level

  • maxd (float, optional) – Maximum data level

  • symmetric (bool, optional) – Make mind, maxd symmetric about zero

  • cmap (Colormap, optional) – A matplotlib colormap to use. If None, use the current default

  • ax (Axes, optional) – A matplotlib axes instance to plot to. If None, create a new figure and axes, and plot to that

  • xlabel, ylabel (str, optional) – Labels for the x/y axes

  • separatrix (bool, optional) – Add separatrix

  • log (bool, optional) – Use a logarithmic scale for the color

  • remove_xguards (bool, optional) – Convert two guard cells into one value on the boundary

Returns:

The contourf instance

Return type:

con

Examples

To put a plot into an axis with a color bar:

>>> fig, axis = plt.subplots()
>>> c = gridcontourf(grid, data, show=False, ax=axis)
>>> fig.colorbar(c, ax=axis)
>>> plt.show()
boutdata.griddata.rotate(gridfile, yshift, output=None)#

Shifts a grid file by the specified number of points in y

This moves the branch cut around, and can be used to change the limiter location

Parameters:
  • gridfile (str) – Name of DataFile to rotate

  • yshift (int) – Number of points in y to shift by

  • output (str, optional) – Name of DataFile to write to. If None, will write to a new file with the same name as gridfile + ‘_rot’

boutdata.griddata.slice(infile, outfile, region=None, xind=None, yind=None)#

Copy an X-Y slice from one DataFile to another

Parameters:
  • infile (str) – Name of DataFile to read slice from

  • outfile (str) – Name of DataFile to write slice to. File will be created, and will be overwritten if it already exists

  • region ({0, 1, 2, 3, 4, 5, None}, optional) –

    Copy a whole region. The available regions are:
    • 0: Lower inner leg

    • 1: Inner core

    • 2: Upper inner leg

    • 3: Upper outer leg

    • 4: Outer core

    • 5: Lower outer leg

  • xind, yind ((int, int), optional) – Index ranges for x and y. Range includes first point, but not last point

boutdata.input module#

Fourier transform data for input to BOUT++

boutdata.input.transform3D(arr)#

Fourier transforms a 3D array in the Z dimension

BOUT++ can take 3D inputs to be Fourier transformed in the Z direction.

Parameters:

arr (array_like) – Input 3-D array

Returns:

A 3D array [x,y,kz] where kz is organised in the standard FFT order, with constant (DC, kz=0) component first, followed by real/imaginary pairs.

kz = [0, (real, imag), (real, imag), …]

Return type:

array_like

boutdata.mayavi2 module#

boutdata.mayavi2.aligned_points(grid, nz=1, period=1.0, maxshift=0.4)#
boutdata.mayavi2.create_grid(grid, data, period=1)#

boutdata.mms module#

Functions for calculating sources for the Method of Manufactured Solutions (MMS)

boutdata.mms.D2DX2(f, metric=<boutdata.mms.Metric object>)#
boutdata.mms.D2DXDY(f, metric=<boutdata.mms.Metric object>)#
boutdata.mms.D2DXDZ(f, metric=<boutdata.mms.Metric object>)#
boutdata.mms.D2DY2(f, metric=<boutdata.mms.Metric object>)#
boutdata.mms.D2DYDZ(f, metric=<boutdata.mms.Metric object>)#
boutdata.mms.D2DZ2(f, metric=<boutdata.mms.Metric object>)#
boutdata.mms.DDX(f, metric=<boutdata.mms.Metric object>)#
boutdata.mms.DDY(f, metric=<boutdata.mms.Metric object>)#
boutdata.mms.DDZ(f, metric=<boutdata.mms.Metric object>)#
boutdata.mms.Delp2(f, metric=<boutdata.mms.Metric object>, all_terms=True)#

Laplacian in X-Z

If all_terms is false then first derivative terms are neglected. By default all_terms is true, but can be disabled in the BOUT.inp file (laplace section)

boutdata.mms.Delp4(f, metric=<boutdata.mms.Metric object>)#
boutdata.mms.Div_par(f, metric=<boutdata.mms.Metric object>)#

Divergence of magnetic field aligned vector \(v = \hat{b} f \nabla \cdot (\hat{b} f) = 1/J \partial_y (f/B) = B Grad_par(f/B)\)

boutdata.mms.Grad_par(f, metric=<boutdata.mms.Metric object>)#

The parallel gradient

boutdata.mms.Laplace(f, metric=<boutdata.mms.Metric object>)#

The full Laplace operator

boutdata.mms.Laplace_par(f, metric=<boutdata.mms.Metric object>)#

Div( b (b.Grad(f) ) ) = (1/J) d/dy ( J/g_22 * df/dy )

boutdata.mms.Laplace_perp(f, metric=<boutdata.mms.Metric object>)#

The perpendicular Laplace operator

Laplace_perp = Laplace - Laplace_par

class boutdata.mms.Metric#
class boutdata.mms.ShapedTokamak(Rmaj=6.0, rmin=2.0, dr=0.1, kappa=1.0, delta=0.0, b=0.0, ss=0.0, Bt0=1.0, Bp0=0.2)#
metric()#

Returns an analytic metric tensor

write(nx, ny, filename, MXG=2)#

Outputs a tokamak shape to a grid file

nx - Number of radial grid points, not including guard cells ny - Number of poloidal (parallel) grid points output - boututils.datafile object, e.g., an open netCDF file MXG, Number of guard cells in the x-direction

class boutdata.mms.SimpleTokamak(R=2, Bt=1.0, eps=0.1, dr=0.02, q=<function SimpleTokamak.<lambda>>)#

Simple tokamak

NOTE: This is NOT an equilibrium calculation. The input is intended solely for testing with MMS

add(expr, name)#

Add an additional expression to be written to the grid files

metric()#

Returns an analytic metric tensor

write(nx, ny, output, MXG=2)#

Outputs a tokamak shape to a grid file

nx - Number of radial grid points, not including guard cells ny - Number of poloidal (parallel) grid points output - boututils.datafile object, e.g., an open netCDF file MXG, Number of guard cells in the x-direction

boutdata.mms.Vpar_Grad_par(v, f, metric=<boutdata.mms.Metric object>)#

Parallel advection operator \(v_\parallel \cdot \nabla_\parallel (f)\)

boutdata.mms.b0xGrad_dot_Grad(phi, A, metric=<boutdata.mms.Metric object>)#

Perpendicular advection operator, including derivatives in y

Note: If y derivatives are neglected, then this reduces to bracket(f, g, metric) * metric.B (in a Clebsch coordinate system)

boutdata.mms.bracket(f, g, metric=<boutdata.mms.Metric object>)#

Calculates [f,g] symbolically

boutdata.mms.ddt(f)#

Time derivative

boutdata.mms.exprMag(expr)#

Estimate the magnitude of an expression

boutdata.mms.exprToStr(expr)#

Convert a sympy expression to a string for BOUT++ input

boutdata.mms.trySimplify(expr)#

Tries to simplify an expression

boutdata.pol_slice module#

boutdata.pol_slice.pol_slice(var3d, gridfile, n=1, zangle=0.0, nyInterp=None)#

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

Parameters:
  • var3d (array_like) – The input array. Should be 3D

  • gridfile (str) – The gridfile containing the coordinate system to used

  • n (int, optional) – The number of times the data must be repeated for a full torus, e.g. n=2 is half a torus

  • zangle (float, optional) – The (real) toroidal angle of the result

  • nyInterp (int, optional) – The number of y (theta) points to use in the final result.

Returns:

A 2D-slice of var3d interpolated at a fixed toroidal angle

Return type:

array

boutdata.processor_rearrange module#

Routines for redistributing files over different numbers of processors

boutdata.processor_rearrange.create_processor_layout(old_processor_layout, npes, nxpe=None)#

Convert one processor layout into another one with a different total number of processors

If nxpe is None, use algorithm from BoutMesh to select optimal nxpe. Otherwise, check nxpe is valid (divides npes)

Parameters:
  • old_processor_layout (processor_layout) – The processor layout to convert

  • npes (int) – The new total number of procesors

  • nxpe (int, optional) – The number of procesors in x to use

Returns:

A description of the processor layout and grid sizes

Return type:

processor_layout

boutdata.processor_rearrange.get_processor_layout(boutfile, has_t_dimension=True, mxg=None, myg=None)#

Given a BOUT.restart.* or BOUT.dmp.* file (as a DataFile object), return the processor layout for its data

Parameters:
  • boutfile (DataFile) – Restart or dump file to read

  • has_t_dimension (bool, optional) – Does this file have a time dimension?

  • mxg, myg (int, optional) – Number of x, y guard cells

Returns:

A description of the processor layout and grid sizes

Return type:

processor_layout

class boutdata.processor_rearrange.processor_layout(nxpe, nype, npes, mxsub, mysub, nx, ny, mz, mxg, myg)#

A namedtuple describing the processor layout, including grid sizes and guard cells

Parameters:
  • nxpe, nype (int) – The number of processors in x and y

  • npes (int) – The total number of procesors

  • mxsub, mysub (int) – The size of the grid in x and y on a single processor

  • nx, ny, mz (int) – The total size of the grid in x, y and z

  • mxg (int) – The number of guard cells in x and y

boutdata.processor_rearrange.processor_layout_#

alias of BOUT_processor_layout

boutdata.restart module#

Routines for manipulating restart files

boutdata.restart.addnoise(path='.', var=None, scale=1e-05)#

Add random noise to restart files

Warning

Modifies restart files in place! This is in contrast to most of the functions in this module!

Parameters:
  • path (str, optional) – Path to restart files (default: current directory)

  • var (str, optional) – The variable to modify. By default all 3D variables are modified

  • scale (float) – Amplitude of the noise. Gaussian noise is used, with zero mean and this parameter as the standard deviation

boutdata.restart.addvar(var, value, path='.')#

Adds a variable with constant value to all restart files.

Warning

Modifies restart files in place! This is in contrast to most of the functions in this module!

This is useful for restarting simulations whilst turning on new equations. By default BOUT++ throws an error if an evolving variable is not in the restart file. By setting an option the variable can be set to zero. This allows it to start with a non-zero value.

Parameters:
  • var (str) – The name of the variable to add

  • value (float) – Constant value for the variable

  • path (str, optional) – Input path to data files (default: current directory)

boutdata.restart.change_grid(from_grid_file, to_grid_file, path='data', output='.', interpolator='nearest', show=False)#

Convert a set of restart files from one grid to another

Notes: - Only working for 2D (axisymmetric) simulations with nz = 1 - Does not support evolving Field2D or FieldPerp variables - Does not support grids with y boundary cells

from_grid_filestr

File containing the input grid

to_grid_filestr

File containing the output grid

pathstr, optional

Directory containing input restart files

outputstr, optional

Directory where output restart files will be written

interpolatorstr, optional

Interpolation method to use. Options are ‘nearest’, ‘CloughTocher’, ‘RBF’

showbool, optional

Display the interpolated fields using Matplotlib

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

Create restart files from data (dmp) files.

Parameters:
  • averagelast (int, optional) – Number of time points (counting from final, inclusive) to average over (default is 1 i.e. just take last time-point)

  • final (int, optional) – The last time point to use (default is last, -1)

  • path (str, optional) – Path to original restart files (default: “data”)

  • output (str, optional) – Path to write new restart files (default: current directory)

  • informat (str, optional) – File extension of original files (default: “nc”)

  • outformat (str, optional) – File extension of new files (default: use the same as informat)

boutdata.restart.normal(loc=0.0, scale=1.0, size=None)#

Draw random samples from a normal (Gaussian) distribution.

The probability density function of the normal distribution, first derived by De Moivre and 200 years later by both Gauss and Laplace independently [2], is often called the bell curve because of its characteristic shape (see the example below).

The normal distributions occurs often in nature. For example, it describes the commonly occurring distribution of samples influenced by a large number of tiny, random disturbances, each with its own unique distribution [2].

Note

New code should use the numpy.random.Generator.normal method of a numpy.random.Generator instance instead; please see the random-quick-start.

Parameters:
  • loc (float or array_like of floats) – Mean (“centre”) of the distribution.

  • scale (float or array_like of floats) – Standard deviation (spread or “width”) of the distribution. Must be non-negative.

  • size (int or tuple of ints, optional) – Output shape. If the given shape is, e.g., (m, n, k), then m * n * k samples are drawn. If size is None (default), a single value is returned if loc and scale are both scalars. Otherwise, np.broadcast(loc, scale).size samples are drawn.

Returns:

out – Drawn samples from the parameterized normal distribution.

Return type:

ndarray or scalar

See also

scipy.stats.norm

probability density function, distribution or cumulative density function, etc.

random.Generator.normal

which should be used for new code.

Notes

The probability density for the Gaussian distribution is

\[p(x) = \frac{1}{\sqrt{ 2 \pi \sigma^2 }} e^{ - \frac{ (x - \mu)^2 } {2 \sigma^2} },\]

where \(\mu\) is the mean and \(\sigma\) the standard deviation. The square of the standard deviation, \(\sigma^2\), is called the variance.

The function has its peak at the mean, and its “spread” increases with the standard deviation (the function reaches 0.607 times its maximum at \(x + \sigma\) and \(x - \sigma\) [2]). This implies that normal is more likely to return samples lying close to the mean, rather than those far away.

References

Examples

Draw samples from the distribution:

>>> mu, sigma = 0, 0.1 # mean and standard deviation
>>> s = np.random.normal(mu, sigma, 1000)

Verify the mean and the variance:

>>> abs(mu - np.mean(s))
0.0  # may vary
>>> abs(sigma - np.std(s, ddof=1))
0.1  # may vary

Display the histogram of the samples, along with the probability density function:

>>> import matplotlib.pyplot as plt
>>> count, bins, ignored = plt.hist(s, 30, density=True)
>>> plt.plot(bins, 1/(sigma * np.sqrt(2 * np.pi)) *
...                np.exp( - (bins - mu)**2 / (2 * sigma**2) ),
...          linewidth=2, color='r')
>>> plt.show()

Two-by-four array of samples from the normal distribution with mean 3 and standard deviation 2.5:

>>> np.random.normal(3, 2.5, size=(2, 4))
array([[-4.49401501,  4.00950034, -1.81814867,  7.29718677],   # random
       [ 0.39924804,  4.68456316,  4.99394529,  4.84057254]])  # random
boutdata.restart.redistribute(npes, path='data', nxpe=None, output='.', informat=None, outformat=None, mxg=None, myg=None)#

Resize restart files across NPES processors.

Does not check if new processor arrangement is compatible with the branch cuts. In this respect restart.split() is safer. However, BOUT++ checks the topology during initialisation anyway so this is not too serious.

Parameters:
  • npes (int) – Number of processors for the new restart files

  • path (str, optional) – Path to original restart files (default: “data”)

  • nxpe (int, optional) – Number of processors to use in the x-direction (determines split: npes = nxpe * nype). Default is None which uses the same algorithm as BoutMesh (but without topology information) to determine a suitable value for nxpe.

  • output (str, optional) – Location to save new restart files (default: current directory)

  • informat (str, optional) – Specify file format of old restart files (must be a suffix understood by DataFile, e.g. ‘nc’). Default uses the format of the first ‘BOUT.restart.*’ file listed by glob.glob.

  • outformat (str, optional) – Specify file format of new restart files (must be a suffix understood by DataFile, e.g. ‘nc’). Default is to use the same as informat.

  • mxg, myg (int, optional) – Number of guard cells in x, y to use in the output (default: keep the same as input)

Return type:

True on success

boutdata.restart.resize(newNx, newNy, newNz, mxg=2, myg=2, path='data', output='./', informat='nc', outformat=None, method='linear', maxProc=None, mute=False)#

Increase/decrease the number of points in restart files.

NOTE: Can’t overwrite WARNING: Currently only implemented with uniform BOUT++ grid

Parameters:
  • newNx, newNy, newNz (int) – nx, ny, nz for the new file (including ghost points)

  • mxg, myg (int, optional) – Number of ghost points in x, y (default: 2)

  • path (str, optional) – Input path to data files

  • output (str, optional) – Path to write new files

  • informat (str, optional) – File extension of input

  • outformat ({None, str}, optional) – File extension of output (default: use the same as informat)

  • method ({‘linear’, ‘nearest’}, optional) – What interpolation method to be used

  • maxProc ({None, int}, optional) – Limits maximum processors to use when interpolating if set

  • mute (bool, optional) – Whether or not output should be printed from this function

Returns:

return – True on success, else False

Return type:

bool

boutdata.restart.resize3DField(var, data, coordsAndSizesTuple, method, mute)#

Resize 3D fields

To be called by resize.

Written as a function in order to call it using multiprocess. Must be defined as a top level function in order to be pickable by the multiprocess.

See the function resize for details

boutdata.restart.resizeY(newy, path='data', output='.', informat='nc', outformat=None, myg=2)#

Increase the number of Y points in restart files

Note

  • Can’t overwrite

Parameters:
  • newy (int) – ny for the new file

  • path (str, optional) – Path to original restart files (default: “data”)

  • output (str, optional) – Path to write new restart files (default: current directory)

  • informat (str, optional) – File extension of original files (default: “nc”)

  • outformat (str, optional) – File extension of new files (default: use the same as informat)

  • myg (int, optional) – Number of ghost points in y (default: 2)

Return type:

True on success, else False

boutdata.restart.resizeZ(newNz, path='data', output='./', informat='nc', outformat=None)#

Increase the number of Z points in restart files

Note

  • Can’t overwrite

  • Will not yield a result close to the original if there are asymmetries in the z-direction

Parameters:
  • newNz (int) – nz for the new file

  • path (str, optional) – Path to original restart files (default: “data”)

  • output (str, optional) – Path to write new restart files (default: current directory)

  • informat (str, optional) – File extension of original files (default: “nc”)

  • outformat (str, optional) – File extension of new files (default: use the same as informat)

Return type:

True on success, else False

boutdata.restart.scalevar(var, factor, path='.')#

Scales a variable by a given factor, modifying restart files in place

Warning

Modifies restart files in place! This is in contrast to most of the functions in this module!

Parameters:
  • var (str) – Name of the variable

  • factor (float) – Factor to multiply

  • path (str, optional) – Path to the restart files (default: current directory)

boutdata.restart.shift_v3_to_v4(gridfile, zperiod, path='data', output='.', informat='nc', mxg=2, myg=2)#

Convert a set of restart files from BOUT++ v3 to v4

Assumes that both simulations are using shifted metric coordinates: - v3 restarts are in field-aligned coordinates

(shifted when taking X derivatives)

  • v4 restarts are in shifted coordinates (shifted when taking Y derivatives)

Parameters:
  • gridfile (str) – String containing grid file name

  • zperiod (int) – Number of times the domain is repeated to form a full torus

  • path (str, optional) – Directory containing the input restart files (BOUT++ v3)

  • output (str, optional) – Directory where the output restart files will go

  • informat (str, optional) – File extension of the input restart files

  • mxg (int, optional) – Number of X guard cells

  • myg (int, optional) – Number of Y guard cells

boutdata.settings module#

Parse BOUT.inp settings file

boutdata.settings.get(filename, name, section=None)#

Find and return a single value from a BOUT.inp settings file

Parameters:
  • filename (str) – Name of the settings file

  • name (str) – The name of the setting

  • section (str, optional) – The section to look in (default: the global section)

  • Note that names and sections are case insensitive

Returns:

Value of the setting. If not found, raises a ValueError

Return type:

str

Examples

>>> settings.get("BOUT.inp", "nout")
'100'
>>> settings.get("BOUT.inp", "compress", section="highbeta")
'true'

boutdata.shiftz module#

boutdata.shiftz.shiftz(var, zangle, zperiod=1.0)#

Shift a variable in Z, changing between field-aligned and orthogonal X-Z coordinates. This mainly used for tokamak simulations in field-aligned coordinates.

Parameters:
  • var (array_like) –

    Data to be shifted

    4D [t,x,y,z] 3D [x,y,z] or [t,x,z] 2D [x,z]

  • zangle (array_like) –

    The shift angle

    2D [x,y] (if var is 4D or 3D [x,y,z]) 1D [x] (if var is 3D [t,x,z] or 2D)

  • zperiod (float, optional) – The fraction of 2pi covered by the variable in Z. This corresponds to the ZPERIOD variable in BOUT.inp and multiplies the kz wavenumbers by this factor.

Returns:

A numpy array of the same size and shape as var

Return type:

ndarray

Examples

>>> from boutdata import collect
>>> from boututils.datafile import DataFile
>>> from boutdata.shiftz import shiftz
>>> n = collect("Ne")  # Read 4D variable [t,x,y,z]
>>> d = DataFile("grid.nc")    # Read the grid file
>>> nxz = shiftz(n, d["zShift"], zperiod=4)

nxz is now in orthogonal X-Z coordinates (X is psi).

Note that in older grid files “qinty” is used rather than “zShift”.