fem.post package¶
Submodules¶
fem.post.colormaps module¶
fem.post.create_disp_dat module¶
create_disp_dat.py - generate disp.dat binary from nodout ASCII
- fem.post.create_disp_dat.correct_Enot(line)¶
Correct dropped ‘E’ in -??? scientific notation.
ls-dyna seems to drop the ‘E’ when the negative exponent is three digits, so check for those in the line data and change those to ‘E-100’ so that we can convert to floats
This is a helper function only called by parse_line_regex(), which is currently not being used by default.
- Parameters:
line (str) – string of split raw string data
- Returns:
line with corrected -??? -> -E100
- fem.post.create_disp_dat.correct_neg(line)¶
Add space before negative coefficient numbers.
This is a helper function only called by parse_line_regex(), which is currently not being used by default.
- Parameters:
line (str) – raw read line
- Returns:
line with space(s) added before negative coefficients
- Return type:
line (str)
- fem.post.create_disp_dat.count_timesteps(outfile: str = 'nodout') int ¶
Count timesteps in to outfile.
Searches for ‘time’ in lines, and then removes 1 extra entry that occurs for t = 0. grep will be used on linux systems (way faster).
- Parameters:
outfile (str) – usually ‘nodout’
- Returns:
number of time steps counted - 1
- Return type:
ts_count (int)
- fem.post.create_disp_dat.create_dat(nodout='nodout', dispout='disp.dat', legacynodes=False)¶
Create binary data file from nodout ASCII file.
- Parameters:
nodout (str) – nodout input filename
dispout (str) – binary output filename
legacynodes (Boolean) – (Default value = False)
- fem.post.create_disp_dat.generate_header(data, outfile)¶
generate headers from data matrix of first time step
- Parameters:
data (nparray) – data
outfile (str) – output filename to count times from
- Returns:
- Return type:
header (dict)
- fem.post.create_disp_dat.main()¶
- fem.post.create_disp_dat.open_dispout(dispout)¶
Open dispout file for writing.
- Parameters:
dispout (str) – dispout filename (disp.dat.xz)
- Returns:
file object
- Return type:
dispout (obj)
- fem.post.create_disp_dat.parse_cli()¶
parse command-line interface arguments
- fem.post.create_disp_dat.parse_line(line)¶
Parse raw data line into vector of floats.
- Parameters:
line (str) – raw data line from nodout
- Returns:
[nodeID, xdisp, ydisp, zdisp]
- Return type:
raw_data (list of floats)
- fem.post.create_disp_dat.parse_line_regex(line)¶
Parse raw data line into list of floats using regex.
This regex approach works, but is very slow!! It also requires two helper functions to clean up malformed data written by ls-dyna (done on purpose, probably to save space).
- Parameters:
line (str) – raw data line from nodout
- Returns:
[nodeID, xdisp, ydisp, zdisp]
- Return type:
raw_data (list of floats)
- fem.post.create_disp_dat.process_timestep_data(data, outfile, writenode)¶
write data for the entire timestep to outfile
- Parameters:
data (list) – list of all data, with each entry containing [nodeID, xdisp, ydisp, zdisp]
outfile (obj) – output file object
writenode (Boolean) – Boolean if the node IDs should be written to save ~25% of the disp.dat file size
- Returns:
None
- fem.post.create_disp_dat.write_headers(outfile, header)¶
Write binary header.
Write binary header information to reformat things on read downstream.
- Parameters:
outfile (str) – output file object
header (dict) –
- Returns:
None
fem.post.create_res_sim module¶
create_res_sim.py - extract data for display in different formats from disp.dat binary
- fem.post.create_res_sim.create_zdisp(nodeidlist, disp_slice_z_only, zdisp)¶
create zdisp array from squeezed disp_slice at appropriate index
- Parameters:
nodeidlist – first column of disp_slice with node IDs in row order
disp_slice_z_only – squeezed disp_slice of just zdisp
zdisp –
- Returns:
rows corresponding to node ID
- Return type:
zdisp (ndarray)
- fem.post.create_res_sim.extract3Darfidata(dynadeck='dynadeck.dyn', disp_comp=2, disp_scale=- 10000.0, ressim='res_sim.h5', nodedyn='nodes.dyn', dispout='disp.dat', specific_times=None)¶
Extract 3D volume of specified displacement component.
- Parameters:
dynadeck (str) – LS-DYNA3D input deck (used to get dt)
disp_comp (int) – displacement component to extract (0, 1, 2)
disp_scale (float) – displacement scaling factor (cm -> um)
ressim (str) – output file name [.mat, .h5, .pvd]
nodedyn (str) – node input file
dispout (str) – binary displacement data
specific_times (list) – optional list of specific time indices
- fem.post.create_res_sim.extract_arfi_data(dispout, header, image_plane, disp_comp=2, disp_scale=- 10000.0, legacynodes=False, specific_times=None)¶
extract ARFI data from disp.dat
- Parameters:
dispout (str) – name of disp.dat file
header (dict) – num_nodes, num_dims, num_timesteps
image_plane (ndarray) – matrix of image plane node IDs spatially sorted
disp_comp (int) – disp component index to extract (0, 1, 2 [default, z])
disp_scale (float) – cm -> um
legacynodes (Boolean) – node IDs repeated every timestep
specific_times (list) – optional list of specific time indices to extract
- Returns:
- Return type:
arfidata (ndarray)
- Raises:
IndexError – unexpected arfidata dimensions
- fem.post.create_res_sim.extract_dt(dyn_file)¶
extract time step (dt) from dyna input deck (assume comma-delimited)
- Parameters:
dyn_file (str) – input.dyn filename
- Raises:
FileNotFoundError –
- Returns:
timestep interval
- Return type:
dt (float)
- fem.post.create_res_sim.extract_image_plane(snic, axes, plane_pos: float = 0.0, direction: int = 0)¶
extract 2D imaging plane node IDs
Extract a 2D matrix of the imaging plane node IDs based on the elevation position (mesh coordinates).
- Parameters:
snic – sorted node IDs and coordinates
axes – spatial axes
plane_pos (float) – position of the plane to extract (in the specified plane_orientation)
direction (int) – orientation plane to extract from (0 = elev, 1 = lateral, 2 = axial)
- Raises:
TypeError – deprecated ele_pos passed as keyword argument
ValueError – invalid direction axis specified
- Returns:
image_plane (node IDs)
- fem.post.create_res_sim.main()¶
- fem.post.create_res_sim.open_dispout(dispout)¶
open dispout file for reading, potentially using lzma
- Parameters:
dispout (pathlib / str) – dispout file
- Raises:
FileNotFoundError – disp.dat[.xz] file cannot be found
ImportError – LZMA package not available
- Returns:
open file object
- Return type:
dispout (obj)
- fem.post.create_res_sim.read_header(dispout, word_size_bytes: int = 4)¶
Read header (first 3 words) from dispout
- Parameters:
dispout – disp.dat filename
word_size_bytes (int) – 4
- Returns:
keys: num_nodes, num_dims, num_timesteps
- Return type:
header (dict)
- fem.post.create_res_sim.run(dynadeck, disp_comp=2, disp_scale=- 10000.0, ressim='res_sim.mat', nodedyn='nodes.dyn', dispout='disp.dat', legacynodes=False, plane_pos: float = 0.0, plane_orientation: int = 0, specific_times: Optional[list] = None)¶
helper function to run high-level, 2D plane extraction
look at using extract3Darfidata to get full, 3D datasets exported (e.g., to view in Paraview)
- Parameters:
dynadeck (str) – main dyna input deck
disp_comp (int) – component of displacement to extract
disp_scale (float) – displacement scaling
ressim (str) – result filename to write
nodedyn (str) – node defintion input filename
dispout (str) – binary displacement input filename
legacynodes (Boolean) – node IDs written with each timestep in dispout
plane_pos (float) – position of the plane to extract (in the specified plane_orientation)
plane_orientation (int) – orientation plane to extract from (0 = elev, 1 = lateral, 2 = axial)
specific_times (list) – optional list of specific time indices to extract
- fem.post.create_res_sim.save_res_sim(resfile, arfidata, axes, t, axis_scale=(- 10, 10, - 10), plane_pos=None, plane_orientation=None)¶
Save res_sim.[mat,h5,pvd] file with arfidata and relevant axes.
Data are saved as float32 (single) to save space.
- Parameters:
resfile (str) – res_sim.[mat,h5,pvd] filename
arfidata (ndarray) – arfidata (3D or 4D (added elev dim, axes[0]))
axes (ndarrays tuple) – ele, lat, axial (mesh units)
t (ndarray) – time
axis_scale (floats tuple) – scale axes sign & mag
plane_pos (float) – position of the plane to extract (in the specified plane_orientation)
plane_orientation (int) – orientation plane to extract from (0 = elev, 1 = lateral, 2 = axial)
- Raises:
ValueError – Cannot save 2D PVD timeseries data.
KeyError – Trying to save unknown output type.
- fem.post.create_res_sim.saveh5(**kwargs)¶
Save HDF5 file with gzip compression.
- Parameters:
arfidata (float) – 4D arfidata matrix
axial (float) – depth axis vector [mm]
lat (float) – lateral axis vector [mm]
elev (float) – elevation axis vector [mm]
t (float) – time vector (s)
resfile (str) – ‘res_sim.pvd’
- fem.post.create_res_sim.savemat(**kwargs)¶
Save Matlab v5 file.
- Parameters:
arfidata (float) – 4D arfidata matrix
axial (float) – depth axis vector [mm]
lat (float) – lateral axis vector [mm]
elev (float) – elevation axis vector [mm]
t (float) – time vector (s)
resfile (str) – ‘res_sim.pvd’
- Raises:
TypeError – arfidata >4 GB
- fem.post.create_res_sim.savepvd(ts_start=0, part=0, **kwargs)¶
Save Paraview PVD rectilinear (VTR) time series data.
Paraview data formats: https://www.paraview.org/Wiki/ParaView/Data_formats
- Parameters:
ts_start (int) – override starting timestep index from 0 to this value
arfidata (float) – 4D arfidata matrix
axial (float) – depth axis vector [mm]
lat (float) – lateral axis vector [mm]
elev (float) – elevation axis vector [mm]
t (float) – time vector (s)
resfile (str) – ‘res_sim.pvd’
- Raises:
ValueError – Not saving 3D time series data.
FileExistsError – PVD file directory cannot be created.
fem.post.h52vtr module¶
- class fem.post.h52vtr.H52VTR(h5file=None, axisnames=('elev', 'lat', 'axial'), dataname='arfidata', vtrname='rectilinear')¶
Bases:
object
Convert HDF5 file to rectilinear VTR file.
- Parameters:
h5file (str) – input HDF5 filename
axisnames (str) – (‘elev’, ‘lat’, ‘axial’)
dataname (str) – ‘arfidata’
vtrname (str) – ‘rectilinear’
- read_h5axes()¶
Read axes from HDF5 file.
- read_h5data()¶
Read data in from HDF5 file.
- write_vtr()¶
Write rectilinear VTR file.
fem.post.listedcmap2xml module¶
- fem.post.listedcmap2xml.listedcmap2xml(cmap)¶
Convert ListedColormap to XML format for import into Paraview
Based on: https://www.paraview.org/Wiki/Colormaps
- Parameters:
ListedColormap (ListedColormap) – Matplotlib-formated ListedColormap
fem.post.ressim module¶
- class fem.post.ressim.ResSim(filename='res_sim.mat')¶
Bases:
object
plot and animate res_sim.mat simulation data
- filename¶
name of file to load in (MATv5 or HDF5)
- Type:
str
- arfidata¶
arfidata
- Type:
float ndarray
- axial¶
depth
- Type:
float ndarray
- lat¶
lateral
- Type:
float ndarray
- t¶
time
- Type:
float ndarray
- time_scale_factor¶
time scale factor (e.g., s -> ms)
- Type:
float
- disp_scale_factor¶
displacement scale factor
- Type:
float
- animate(i)¶
- load()¶
load MATv5 or HDF5 data
- Parameters:
filename (str) – input filename
- Raises:
TypeError – MATv5 or HDF5 load exceptions
- play(timerange, xlabel='Lateral (mm)', ylabel='Axial (mm)', show=True)¶
play an animation
Strongly recommend not stepping though each timesteps; use some skips!
- Parameters:
timerange (range) – range generator of time steps to animate
xlabel (str) –
ylabel (str) –
show (Boolean) – show animation
Todo
Add save option
- plot(timestep, show=True, save=False, savename='file', xlabel='Lateral (mm)', ylabel='Axial (mm)', title=None)¶
Plot arfidata at specified timestep.
- Parameters:
timestep (int) –
show (Boolean) – show plot
save (Boolean) – save PNG (objectname_timestep.png)
savename (str) – saved PNG filename prefix
xlabel (str) –
ylabel (str) –
title (str) –
- timeplot(axial, lat, xlabel='Time (ms)', ylabel='Displacement (\\mum)', title=None, show=True)¶
plot arfidata through time at specified ax and lat position (mm)
- Parameters:
axial (ndarray) – axial depth (mm)
lat (ndarray) – lateral position (mm)
xlabel (str) –
ylabel (str) –
title (str) –
show (Boolean) – show the plot
Returns:
fem.post.savevtk module¶
- class fem.post.savevtk.SaveVTK(data, origin, spacing)¶
Bases:
object
Save structured 3D scalar and vector data in legacy ASCII VTK format.
- Parameters:
data (ndarray) – [scalar] 3D numpy array [vector] tuple of 3D numpy arrays (X, Y, Z)
origin (float) – mesh origin tuple (x, y, z)
spacing (float) – node spacing tuple (x, y, z)
- Raises:
IndexError – The shape of the data tuple ndarrays are not equal.
- property data¶
- save_scalar(filename, dataname='scalars', header_comment=None)¶
save 3D scalar data in VTK structure points format
- Parameters:
filename (str) – output filename
dataname (str) – data name
header_comment (str) – optional header comment in output file
- save_vector(filename, dataname='vectors', header_comment=None)¶
save 3D vector array in VTK structure points format
- Parameters:
filename (str) – output filename
dataname (str) – data name
header_comment (str) – optional header comment in output file