pylbo

Subpackages

Submodules

Package Contents

Functions

generate_parfiles(→ list[str])

Generates parfiles based on a given configuration dictionary.

run_legolas(→ None)

Runs the legolas executable for a given list of parfiles. If more than one parfile

load(datfile)

Loads a single Legolas datfile.

load_logfile(logfile[, sort])

Reads a Legolas log file.

load_series(datfiles)

Loads multiple Legolas datfiles.

get_equilibrium_balance(→ dict)

disable_logging()

Completely disables logging.

set_loglevel(level)

Sets the logging level.

plot_continua(data[, figsize, interactive])

Plots the continua profiles.

plot_equilibrium(data[, figsize, interactive])

Plots the equilibrium profiles.

plot_equilibrium_balance(data[, figsize, interactive])

Creates a plot of the balance equations.

plot_matrices(data[, figsize])

Plots the continua profiles.

plot_merged_spectrum(data[, figsize, custom_figure, ...])

Creates a merged spectrum from various datasets, useful in plotting multiple

plot_spectrum(data[, figsize, custom_figure, ...])

Plots the spectrum of a single dataset.

plot_spectrum_comparison(ds1, ds2[, figsize, ...])

Compares two spectra.

plot_spectrum_multi(data, xdata[, use_squared_omega, ...])

Plots the spectrum of a dataset series.

plot_1d_temporal_evolution(...)

Plot the temporal evolution of a 1D eigenmode solution, i.e.

plot_2d_slice(...)

Plot a 2D spatial view of the eigenmode solution, i.e.

plot_3d_slice(...)

Plot a 3D spatial view of the eigenmode solution, i.e.

prepare_vtk_export(...)

Prepares for a VTK file export of the eigenmode solution in three dimensions.

pylbo.generate_parfiles(parfile_dict: dict, basename: str = None, output_dir: str | os.PathLike = None, subdir: bool = True, prefix_numbers: bool = True, nb_prefix_digits: int = 4) list[str][source]

Generates parfiles based on a given configuration dictionary. The separate namelists do not have to be taken into account, and a normal dictionary should be supplied where the keys correspond to the namelist items that are required. Typechecking is done automatically during parfile generation.

Parameters:
  • parfile_dict (dict) – Dictionary containing the keys to be placed in the parfile.

  • basename (str) – The basename for the parfile, the .par suffix is added automatically and is not needed. If multiple parfiles are generated, these will be prepended by a 4-digit number (e.g. 0003myparfile.par). If not provided, the basename will default to parfile.

  • output_dir (str, PathLike) – Output directory where the parfiles are saved, defaults to the current working directory if not specified. A subdirectory called parfiles will be created in which the parfiles will be saved.

  • subdir (boolean) – If True (default), creates a subdirectory parfiles in the output folder.

  • prefix_numbers (boolean) – If True prepends the basename by a n-digit number (e.g. xxxxmyparfile.par). The number of digits is specified by nb_prefix_digits.

  • nb_prefix_digits (int) – Number of digits to prepend to the basename if prefix_numbers is True. Defaults to 4.

Notes

This routine is quite flexible and specifically designed for parametric studies. You can specify both single values and list-like items as dictionary items. This routine will automatically generate multiple parfiles if lists/numpy arrays are present.

Returns:

parfiles – A list with the paths to the parfiles that were generated. This list can be passed immediately to pylbo.run_legolas().

Return type:

list

Examples

This will generate a single parfile in a subdirectory parfile of the current working directory.

>>> import pylbo
>>> config = {
>>>    "geometry": "Cartesian",
>>>    "x_start": 0,
>>>    "x_end": 1,
>>>    "equilibrium_type": "resistive_homo",
>>>    "gridpoints": 100,
>>>    "write_eigenfunctions": True,
>>>    "basename_datfile": "my_run",
>>>    "output_folder": "output",
>>> }
>>> parfile = pylbo.generate_parfiles(config)

This will generate 10 parfiles in the directory my_parfiles relative to the current working directory. The first parfile will have x_end = 1.0 and 100 gridpoints, the second one will have x_end = 2.0 and 150 gridpoints, etc.

>>> import pylbo
>>> import numpy as np
>>> config = {
>>>    "geometry": "Cartesian",
>>>    "x_start": 0,
>>>    "x_end": np.arange(1, 11)
>>>    "number_of_runs": 10
>>>    "equilibrium_type": "resistive_homo",
>>>    "gridpoints": np.arange(100, 600, 50),
>>>    "write_eigenfunctions": True,
>>>    "basename_datfile": "my_run",
>>>    "output_folder": "output",
>>> }
>>> parfile_list = pylbo.generate_parfiles(config, output_dir="my_parfiles")
pylbo.run_legolas(parfiles: str | list | os.PathLike, remove_parfiles: bool = False, nb_cpus: int = 1, executable: str | os.PathLike = None) None[source]

Runs the legolas executable for a given list of parfiles. If more than one parfile is passed, the runs can be performed in parallel using the multiprocessing module. Parallelisation can be enabled by setting the nb_cpus kwarg to a number greater than one, and is disabled by default. Every CPU will have a single legolas executable subprocess associated with it.

Parameters:
  • parfiles (str, list, numpy.ndarray) – A string, list or array containing the paths to the parfile(s). Accepts the output of pylbo.generate_parfiles().

  • remove_parfiles (bool) – If True, removes the parfiles after running Legolas. This will also remove the containing folder if it turns out to be empty after the parfiles are removed. If there are other files still in the folder it remains untouched.

  • nb_cpus (int) – The number of CPUs to use when running Legolas. If equal to 1 then parallelisation is disabled. Defaults to the maximum number of CPUs available if a number larger than the available number is specified.

  • executable (str, PathLike) – The path to the legolas executable. If not specified, defaults to the standard one in the legolas home directory.

Notes

If multiprocessing is enabled, it is usually a good idea to have the number of runs requested divisible by the number of CPUs that are available. For example, if 24 runs are requested it is good practice to use either 2, 4, 6 or 8 CPUs, and avoid numbers like 3, 5 and 7.

Examples

The example below will run a list of parfiles using using a local legolas executable from the current directory, on 4 CPU’s.

>>> import pylbo
>>> from pathlib import Path
>>> files = sorted(Path("parfiles").glob("*.dat"))
>>> pylbo.run_legolas(files, nb_cpus=4, executable="legolas")
pylbo.load(datfile)[source]

Loads a single Legolas datfile.

Parameters:

datfile (str, PathLike) – Path to the datfile.

Raises:

ValueError – If datfile is not a single file.

Returns:

ds – A dataset instance for the given datfile.

Return type:

LegolasDataSet

pylbo.load_logfile(logfile, sort=False)[source]

Reads a Legolas log file.

Parameters:
  • logfile (str, PathLike) – The path to the logfile.

  • sort (bool) – If True, sorts the eigenvalues in the logfile. Sorting is done first on the real part, then on the imaginary part.

Returns:

eigenvalues – Array containing the eigenvalues from the logfile.

Return type:

numpy.ndarray

pylbo.load_series(datfiles)[source]

Loads multiple Legolas datfiles.

Parameters:

datfiles (list, numpy.ndarray) – Paths to the datfiles that should be loaded, in list/array form. Every element should be a string or a ~os.PathLike object.

Raises:

ValueError – If an empty list or array is supplied.

Returns:

series – A dataseries instance for the given datfiles.

Return type:

LegolasDataSeries

pylbo.get_equilibrium_balance(ds: pylbo.data_containers.LegolasDataSet) dict[source]
pylbo.disable_logging()[source]

Completely disables logging.

pylbo.set_loglevel(level)[source]

Sets the logging level.

Parameters:

level (int, str) – The level for logging. See Logger, or the allowed levels. Both the string and integer values can be set, case-insensitive.

pylbo.plot_continua(data, figsize=None, interactive=True, **kwargs)[source]

Plots the continua profiles.

Parameters:
  • data (LegolasDataSet) – The dataset or series that should be used.

  • figsize (tuple) – Optional figure size like the usual matplotlib (x, x) size.

  • interactive (bool) – If True (default), enables an interactive legend.

Returns:

p – The profile instance containing the continua plots.

Return type:

ContinuumProfile

pylbo.plot_equilibrium(data, figsize=None, interactive=True, **kwargs)[source]

Plots the equilibrium profiles.

Parameters:
  • data (LegolasDataSet) – The dataset or series that should be used.

  • figsize (tuple) – Optional figure size like the usual matplotlib (x, x) size.

  • interactive (bool) – If True (default), enables an interactive legend.

Returns:

p – The profile instance containing the equilibrium plots.

Return type:

EquilibriumProfile

pylbo.plot_equilibrium_balance(data, figsize=None, interactive=True, **kwargs)[source]

Creates a plot of the balance equations. These should be as close to zero as possible over the entire grid.

Parameters:
  • data (LegolasDataSet) – The dataset that should be used

  • figsize (tuple) – Optional figure size like the usual matplotlib (x, x) size.

  • interactive (bool) – If True (default), enables an interactive legend.

Returns:

p – The profile instance containing the equilibrium balance plots.

Return type:

EquilibriumBalance

pylbo.plot_matrices(data, figsize=None, **kwargs)[source]

Plots the continua profiles.

Parameters:
  • data (LegolasDataSet) – The dataset that should be used.

  • figsize (tuple) – Optional figure size like the usual matplotlib (x, x) size.

Returns:

p – The instance containing the matrix plots.

Return type:

MatrixFigure

pylbo.plot_merged_spectrum(data, figsize=None, custom_figure=None, interactive=True, legend=True, **kwargs)[source]

Creates a merged spectrum from various datasets, useful in plotting multiple results from the shift-invert solver, for example. This draws every dataset in a different color by default, and creates a corresponding legend. Supply the optional argument color to draw all points in the same color.

Parameters:
  • data (LegolasDataSeries) –

  • figsize (tuple) – Optional figure size like the usual matplotlib (x, x) size.

  • custom_figure (tuple) – Optional, in the form (fig, ax). If supplied no new figure will be created but this one will be used instead. fig refers to the matplotlib figure and ax to a (single) axes instance, meaning that you can pass a subplot as well.

  • interactive (bool) – If True (default), enables an interactive legend.

  • legend (bool) – If True (default), draws a legend.

Returns:

p – The spectrumfigure instance, containing the plot.

Return type:

MultiSpectrumPlot

pylbo.plot_spectrum(data, figsize=None, custom_figure=None, use_residuals=False, **kwargs)[source]

Plots the spectrum of a single dataset.

Parameters:
  • data (LegolasDataSet) – The dataset that should be used.

  • figsize (tuple) – Optional figure size like the usual matplotlib (x, x) size.

  • custom_figure (tuple) – Optional, in the form (fig, ax). If supplied no new figure will be created but this one will be used instead. fig refers to the matplotlib figure and ax to a (single) axes instance, meaning that you can pass a subplot as well.

  • use_residuals (bool) – If True, colors the spectrum based on the residual in the datfile.

Returns:

p – The spectrum instance which can be used further to add continua, eigenfunctions, etc.

Return type:

SingleSpectrumPlot

pylbo.plot_spectrum_comparison(ds1, ds2, figsize=None, custom_figure=None, lock_zoom=False, use_residuals=False, **kwargs)[source]

Compares two spectra.

Parameters:
  • ds1 (LegolasDataSet) – The first dataset, this one is put on the left panel.

  • ds2 (LegolasDataSet) – The second dataset, this one is put on the right panel.

  • figsize (tuple) – Optional figure size like the usual matplotlib (x, x) size.

  • custom_figure (tuple) – The custom figure to use in the form (fig, axes).

  • lock_zoom (bool) – If True (False by default), locks the zoom of both axis. When locked, zoomin in on one of the axis automatically scales the zoom on the other one as well.

  • use_residuals (bool) – If True, colors the spectrum based on the residual in the datfile.

Returns:

p – The figure instance containing the compared spectrum plot.

Return type:

SpectrumComparisonPlot

pylbo.plot_spectrum_multi(data, xdata, use_squared_omega=False, use_real_parts=True, figsize=None, custom_figure=None, **kwargs)[source]

Plots the spectrum of a dataset series.

Parameters:
  • data (LegolasDataSeries) – The dataseries that should be used.

  • xdata (str, list, numpy.ndarray) – Data to use for the horizontal axis. This can either be a key from the parameters dictionary, or a list/numpy array containing actual data.

  • use_squared_omega (bool) – If True, this will square the eigenvalues when they are plotted on the vertical axis. If False (default), either the real or imaginary part of the eigenvalues will be plotted depending on the value of use_real_parts.

  • figsize (tuple) – Optional figure size like the usual matplotlib (x, x) size.

  • custom_figure (tuple) – Optional, in the form (fig, ax). If supplied no new figure will be created but this one will be used instead. fig refers to the matplotlib figure and ax to a (single) axes instance, meaning that you can pass a subplot as well.

Returns:

p – The spectrum instance which can be used further to add continua, eigenfunctions, etc.

Return type:

MultiSpectrumPlot

pylbo.plot_1d_temporal_evolution(ds: pylbo.data_containers.LegolasDataSet, omega: complex | list[complex] | numpy.ndarray, ef_name: str, u2: float, u3: float, time: list | numpy.ndarray, figsize: tuple[int, int] = None, add_background: bool = False, use_real_part: bool = True, complex_factor: complex = None, show_ef_panel: bool = True, **kwargs) pylbo.visualisation.modes.temporal_1d.TemporalEvolutionPlot1D[source]

Plot the temporal evolution of a 1D eigenmode solution, i.e.

\(f(u_1, u_2, u_3, t) = f_1(u_1) \exp\left(ik_2u_2 + ik_3u_3 - i\omega t\right)\),

for a particular set of coordinates \((u_2, u_3)\) over a time interval.

Parameters:
  • ds (LegolasDataSet) – The data set containing the eigenfunction.

  • omega (complex, list[complex], np.ndarray) – The (approximate) eigenvalue of the mode(s) to visualise.

  • ef_name (str) – The name of the eigenfunction to visualise.

  • u2 (float) – The y or \(\theta\) coordinate of the eigenmode solution.

  • u3 (float) – The z coordinate of the eigenmode solution.

  • time (list or np.ndarray) – The time interval to visualise.

  • figsize (tuple[int, int]) – The size of the figure.

  • add_background (bool) – Whether to add the equilibrium background to the plot.

  • use_real_part (bool) – Whether to use the real part of the eigenmode solution.

  • complex_factor (complex) – A complex factor to multiply the eigenmode solution with.

  • show_ef_panel (bool) – Whether to show the eigenfunction panel.

  • kwargs (dict) – Additional keyword arguments to pass to imshow().

Returns:

The plot object.

Return type:

TemporalEvolutionPlot1D

pylbo.plot_2d_slice(ds: pylbo.data_containers.LegolasDataSet, omega: complex | list[complex] | numpy.ndarray, ef_name: str, u2: float | numpy.ndarray, u3: float | numpy.ndarray, time: float, slicing_axis: str, figsize: tuple[int, int] = None, add_background: bool = False, use_real_part: bool = True, complex_factor: complex = None, show_ef_panel: bool = True, polar: bool = False, **kwargs) pylbo.visualisation.modes.cartesian_2d.CartesianSlicePlot2D[source]

Plot a 2D spatial view of the eigenmode solution, i.e.

\(f(u_1, u_2, u_3, t) = f_1(u_1) \exp\left(ik_2u_2 + ik_3u_3 - i\omega t\right)\),

for a particular set of coordinates. If slicing_axis = ‘z’ then a 2D view is created for a given slicing point along the ‘z’-axis (hence a ‘xy’-view), for slicing_axis = ‘y’ a ‘xz’-view will be created. The given spatial coordinates u2 and u3 must be consistent with the slicing axis. For cylindrical geometries slices in both Cartesian and polar coordinates can be created.

Parameters:
  • ds (LegolasDataSet) – The data set containing the eigenfunction.

  • omega (complex, list[complex], np.ndarray) – The (approximate) eigenvalue of the mode(s) to visualise.

  • ef_name (str) – The name of the eigenfunction to visualise.

  • u2 (float, np.ndarray) – The y or \(\theta\) coordinate of the eigenmode solution.

  • u3 (float, np.ndarray) – The z coordinate of the eigenmode solution.

  • time (float) – The time at which to visualise the eigenmode solution.

  • slicing_axis (str) – The axis to slice the 2D view along, either ‘z’, ‘y’ or ‘theta’

  • figsize (tuple[int, int]) – The size of the figure.

  • add_background (bool) – Whether to add the equilibrium background to the plot.

  • use_real_part (bool) – Whether to use the real part of the eigenmode solution.

  • complex_factor (complex) – A complex factor to multiply the eigenmode solution with.

  • show_ef_panel (bool) – Whether to show the eigenfunction panel.

  • polar (bool) – Whether to use polar coordinates for the 2D view. Only used if the dataset geometry is cylindrical. Default is False.

  • kwargs (dict) – Additional keyword arguments to pass to the plotting function.

Returns:

p – The plot object.

Return type:

CartesianSlicePlot2D or CylindricalSlicePlot2D

pylbo.plot_3d_slice(ds: pylbo.data_containers.LegolasDataSet, omega: complex | list[complex] | numpy.ndarray, ef_name: str, u2: float | numpy.ndarray, u3: float | numpy.ndarray, time: float, slicing_axis: str, figsize: tuple[int, int] = None, add_background: bool = False, use_real_part: bool = True, complex_factor: complex = None, **kwargs) pylbo.visualisation.modes.cartesian_3d.CartesianSlicePlot3D[source]

Plot a 3D spatial view of the eigenmode solution, i.e.

\(f(u_1, u_2, u_3, t) = f_1(u_1) \exp\left(ik_2u_2 + ik_3u_3 - i\omega t\right)\),

for a particular set of coordinates. Several 2D slices are superimposed on each other for every value of \(u_3\).

Parameters:
  • ds (LegolasDataSet) – The data set containing the eigenfunction.

  • omega (complex, list[complex], np.ndarray) – The (approximate) eigenvalue of the mode(s) to visualise.

  • ef_name (str) – The name of the eigenfunction to visualise.

  • u2 (float, np.ndarray) – The y or \(\theta\) coordinate of the eigenmode solution.

  • u3 (float, np.ndarray) – The z coordinate of the eigenmode solution.

  • time (float) – The time at which to visualise the eigenmode solution.

  • slicing_axis (str) – The axis to slice the 2D view along, either ‘z’, ‘y’ or ‘theta’

  • figsize (tuple[int, int]) – The size of the figure.

  • add_background (bool) – Whether to add the equilibrium background to the plot.

  • use_real_part (bool) – Whether to use the real part of the eigenmode solution.

  • complex_factor (complex) – A complex factor to multiply the eigenmode solution with.

  • kwargs (dict) – Additional keyword arguments to pass to the plotting function.

Returns:

p – The plot object.

Return type:

CartesianSlicePlot3D or CylindricalSlicePlot3D

pylbo.prepare_vtk_export(ds: pylbo.data_containers.LegolasDataSet, omega: complex | list[complex] | numpy.ndarray, u2: numpy.ndarray, u3: numpy.ndarray, use_real_part: bool = True, complex_factor: complex = None) pylbo.visualisation.modes.vtk_export.VTKCartesianData | pylbo.visualisation.modes.vtk_export.VTKCylindricalData[source]

Prepares for a VTK file export of the eigenmode solution in three dimensions. Returns a VTKDataCube3D object which can be used to generate VTK files.

Parameters:
  • ds (LegolasDataSet) – The data set containing the eigenfunction.

  • omega (complex, list[complex], np.ndarray) – The (approximate) eigenvalue of the mode(s) to visualise.

  • u2 (np.ndarray) – The y or \(\theta\) coordinates of the eigenmode solution.

  • u3 (np.ndarray) – The z coordinates of the eigenmode solution.

  • use_real_part (bool) – Whether to use the real part of the eigenmode solution.

Returns:

Object that can be used to generate VTK files.

Return type:

VTKCartesianData or VTKCylindricalData