Skip to content

Example usage

Loading Bifrost snapshots

The bifrost module under helita.sim reads and manipulates the native output format from Bifrost simulations (not FITS). To load some data, do:

from helita.sim import bifrost
data = bifrost.BifrostData("cb24bih", snap=300, fdir='/data/cb24bih')

The first argument to BifrostData() is the basename for file names (an underscore, the snapshot number, and file extensions will be added, e.g. cb24bih_300.snap). The object data contains the data for a single snapshot, but when initialised no data is loaded into memory. Simple variables are available as a memmap. These are variables that do not require any transformation before being read (typically scalar variables at cell centres and vector variables at cell faces). A list of such variable names is kept at data.simple_vars, and can be accessed as data.variables[myvar] or data.myvar, e.g.:

>>> data.tg.shape
(504, 504, 496)
>>> data.variables['tg'] is data.tg
True

The method get_var() can be used to read or extract any variable, including composite variables, which typically combine several simple variables and involve shifting variables from cell centres to cell faces or vice-versa. For example, to obtain velocities in the z direction:

vz = data.get_var('uz')

By default, this velocity will be defined at cell faces. To instead obtain it at the cell centres, we need to manually shift the momentum in the z direction (with the cstagger utilities) and divide it by the density, e.g.:

from helita.sim import cstagger
rdt = data.r.dtype
cstagger.init_stagger(data.nz, data.dx, data.dy, data.z.astype(rdt),
                      data.zdn.astype(rdt), data.dzidzup.astype(rdt),
                      data.dzidzdn.astype(rdt))
vz_cell_centre = cstagger.zup(data.pz) / data.r

Converting Bifrost to RH 1.5D and Multi3D atmospheres

The BifrostData object has methods to convert the output into different formats. For example, to save the data from a single snapshot to an input atmosphere for RH 1.5D:

data = bifrost.BifrostData("cb24bih", snap=300, fdir='/data/cb24bih')
data.write_rh15d('myfile.hdf5', desc='Some description')

The interface also allows writing only part of the atmosphere using python slice objects in the x, y, and z dimensions. For example, to write every second point in the x and y directions, and the first 200 points in the z direction, you would do:

sx = sy = slice(None, None, 2)
sz = slice(0, 200)
data.write_rh15d('myfile.hdf5', desc='Some description', sx=sx, sy=sy, sz=sz)

An RH 1.5D atmosphere file can have multiple snapshots. To write additional snapshots to a file using the write_rh15d() method, you need to manually load a new snapshot and then use the append=True option (it can still be True for the first write, as long as the output file doesn't exist already). For example, writing snapshots from 100 to 150 to a single file:

data = bifrost.BifrostData("cb24bih", snap=100, fdir='/data/cb24bih')
for i in range(100, 150):
    data.set_snap(i)
    data.write_rh15d('myfile_s100-150.hdf5', desc='Some description',
                     append=True)

Writing snapshots in Multi3D format is done similarly, but only one snapshot can be written by file. E.g.:

data.write_multi3d('myfile.atmos3d', desc='Some description')

The Multi3D interface also writes a mesh file (default name is mesh.dat).

Bifrost 2D to RH 1.5D

RH 1.5D atmosphere files are always 3D, but the x and y dimensions can have a single element, meaning 1D and 2D geometries are possible. When converting 2D models from Bifrost to RH 1.5D, the resulting atmosphere will therefore have ny = 1. However, when converting many 2D snapshots to RH 1.5D it is advantageous to save the temporal dimension as a y dimension, because RH 1.5D is not parallel in the temporal dimension. There is a function called bifrost2d_to_rh15d() in helita.sim.bifrost that does this. For example:

import numpy as np
snaps = np.arange(100, 500)
bifrost.bifrost2d_to_rh15d(snaps, 'myfile2D.hdf5', 'simroot', 'mesh.dat',
                           '/path/to/simulation/', desc='Some description')

The resulting atmosphere variables will therefore have a shape of (1, nx, nt, nz) instead of (nt, nx, 1, nz).