Scalar Fields Tutorial#

Scalar fields are a powerful tool to represent the state of a system. up4 provides you with basic tools to extract an visualize different quantities.

Available are:

To generate a 2D field one first needs to generate a 3D grid:

import up4
data = up4.Data("test_filename.hdf5")
grid = up4.Grid(data, num_cells=[50,50,50])

here, we first load the data using our up4.Data class, then generate a 3-D grid using the up4.Grid class constructor. Read the tutorial for grids to see a deeper insight into the generating of grids.

Afterwards generate a field containing the velocity data. The data contains the mean velocity of all particle passes through that each cell.

field = data.velocityfield(grid)
print(field)

"""
Grid3D:
    Cells: [50, 50, 50]
    xlim: [174.02695648134886, 372.21089969650967]
    ylim: [74.71161491723201, 203.37554460929758]
    zlim: [52.291522049547666, 239.25612145076877]
    Data information:
            Mean: NaN
            Std: NaN
            Min: 0.0021862203945679478
            Max: 0.40294214528818545
"""

up4.Grid also contains the weights of each cell. Meaning that it stores the number of particles that crossed the cell. These weights are accessible using the up4.Grid.weights_to_numpy method.

up4.Grid also implements a crude plotting function that allows fast but nonflexible visualisation, for instance to quickly assess if the cell size is adequate. This plotting function generates a depth-averaged 2D Plotly figure of the field and is not editable. The methods of up4.Plotter2D return fully customisable figures, for presenting results calculated by up4.

Simply provide the axis along which the depth averaging should take place to the plotting method:

field.plot(0) # plot x-axis

To accurately visualize 2D fields there are two possibilities: slices and depth-averaged representations. Slices are simply the plane perpendicular to an axis, at a given location along it.

slice_x_axis = field.slice(0, 20) # slice the 3D array at the 20st cell index along x-axis

alternatively, one can slice the field at a given position:

slice_x_axis = field.slice_pos(0, 101.5) # slice the 3D array at x = 101.5 mm

Depth-averaging is achieved by calculating the weighted mean along each axis. The up4.Grid.collapse function uses its internal weights for each cell to fairly weight the contributions of each cell to the average; cells where few particles cross will have less of a contribution to the mean quantity than those will numerous particles.

averaged_y_axis = field.collapse(1) # depth average along the y-axis

one can also generate a 1D representation of the system by collapsing two dimensions:

averaged_y_z_axis = field.collapse_two(1,2) # depth averaging along x and y axis