-
Notifications
You must be signed in to change notification settings - Fork 7
3D Slice Data
An &SLCF whose XB spans a volume rather than a plane produces a 3-D
slice. readSLCF3Ddata reads every mesh's contribution and interpolates
it onto one grid.
import os
import numpy as np
import pyfdstools as fds
workingDir = os.path.join(
os.path.dirname(fds.__file__), 'examples', 'data', 'case001.zip')
chid = 'case001'
grid, values, times, units = fds.readSLCF3Ddata(
chid, workingDir, 'TEMPERATURE')
print(grid.shape) # (25, 11, 25, 3) -> (NX, NY, NZ, xyz)
print(values.shape) # (25, 11, 25, 6) -> (NX, NY, NZ, NT)
print(units) # CNote the argument order: readSLCF3Ddata takes chid before
workingDir, unlike query2dAxisValue.
| Return value | Contents |
|---|---|
grid |
array(NX, NY, NZ, 3) of absolute coordinates |
values |
array(NX, NY, NZ, NT) of slice values |
times |
timestamp of each frame |
units |
units of the quantity |
Cells outside every mesh are NaN.
If the case wrote no 3-D slice of the requested quantity,
readSLCF3Ddata prints what the case does contain and returns
(False, False, False, False):
grid, values, times, units = fds.readSLCF3Ddata(
chid, workingDir, 'NOT A REAL QUANTITY')
if grid is False:
raise SystemExit('quantity not present in this case')Giving axis and value extracts just that plane. This is much cheaper
than reading the whole volume and slicing it yourself, because only the
meshes intersecting the plane are read:
grid, values, times, units = fds.readSLCF3Ddata(
chid, workingDir, 'TEMPERATURE', axis=3, value=1.0)
print(grid.shape) # (25, 11, 2) -> (N, M, two in-plane coordinates)
print(values.shape) # (25, 11, 6) -> (N, M, NT)Meshes that do not span the requested plane are skipped, and verbose=True
reports which:
grid, values, times, units = fds.readSLCF3Ddata(
chid, workingDir, 'TEMPERATURE', axis=3, value=1.0, verbose=True)If you already have the whole volume in memory, findSliceLocation
takes a plane out of it without going back to disk:
grid, values, times, units = fds.readSLCF3Ddata(
chid, workingDir, 'TEMPERATURE')
x, z, frame = fds.findSliceLocation(grid, values[:, :, :, -1], axis=3, value=1.0)
fig, ax = fds.plotSlice(x, z, frame, axis=3, clabel='Temperature (C)')It picks the nearest grid plane rather than interpolating, so the plane
you get is the one closest to value.
history = fds.extractPoint([2.0, 1.5, 1.0], grid, values)Returns the time history at the nearest grid point, and warns if that point is more than 0.25 m away from the one you asked for.
pyfdstools/examples/dump_3d_slice_to_csv.py writes a 3-D slice out as
one csv per z-plane per frame:
python dump_3d_slice_to_csv.py \
--chid case001 --quantity TEMPERATURE \
--working_dir data/case001.zipA 3-D slice over a long run is large: NX × NY × NZ × NT float32 values
per mesh, plus the assembled array. Two things help:
-
Restrict the time range. Passing
timeanddtreads only the frames inside the window. -
Extract the plane at read time. Passing
axisandvalueavoids materialising the volume at all.
grid, values, times, units = fds.readSLCF3Ddata(
chid, workingDir, 'TEMPERATURE',
time=60, dt=20, axis=3, value=1.0)saveTimesFile=True caches each slice file's timestamps in a csv next
to it, which speeds up repeated reads of a case on disk.
For interactive 3-D work, export to VTK and open the result in ParaView:
fds.exportSl3dDataToVtk(chid, workingDir, outDir='./vtk')Requires the paraview extra. See
Exporting to ParaView.
readSLCF3DdataXYZ does the same job using the .xyz files FDS writes
when WRITE_XYZ=.TRUE. is set on &DUMP. It emits a
DeprecationWarning; use readSLCF3Ddata, which reads the mesh grids
from the smokeview file and so works on any case.
Getting started
Reading results
Working with results
Building models
Reference