D3plot
There is a youtube tutorial available for this class:
Class used to read LS-Dyna d3plots
arrays: dict
property
writable
Dictionary holding all d3plot arrays
Notes
The corresponding keys of the dictionary can
also be found in `lasso.dyna.ArrayTypes`, which
helps with IDE integration and code safety.
Examples:
>>> d3plot = D3plot("some/path/to/d3plot")
>>> d3plot.arrays.keys()
dict_keys(['irbtyp', 'node_coordinates', ...])
>>> # The following is good coding practice
>>> import lasso.dyna.ArrayTypes.ArrayTypes as atypes
>>> d3plot.arrays[atypes.node_displacmeent].shape
header: D3plotHeader
property
Instance holding all d3plot header information
Returns:
Name | Type | Description |
---|---|---|
header |
D3plotHeader
|
header of the d3plot |
Notes
The header contains a lot of information such as number
of elements, etc.
Examples:
>>> d3plot = D3plot("some/path/to/d3plot")
>>> # number of shells
>>> d3plot.header.n_shells
85624
n_timesteps: int
property
Number of timesteps loaded
__init__(filepath=None, use_femzip=None, n_files_to_load_at_once=None, state_array_filter=None, state_filter=None, buffered_reading=False)
Constructor for a D3plot
Parameters:
Name | Type | Description | Default |
---|---|---|---|
filepath |
str
|
path to a d3plot file |
None
|
use_femzip |
Union[bool, None]
|
Not used anymore. |
None
|
n_files_to_load_at_once |
Union[int, None]
|
DEPRECATED not used anymore, use |
None
|
state_array_filter |
Union[List[str], None]
|
names of arrays which will be the only ones loaded from state data |
None
|
state_filter |
Union[None, Set[int]]
|
which states to load. Negative indexes count backwards. |
None
|
buffered_reading |
bool
|
whether to pull only a single state into memory during reading |
False
|
Examples:
>>> from lasso.dyna import D3plot, ArrayType
>>> # open and read everything
>>> d3plot = D3plot("path/to/d3plot")
>>> # only read node displacement
>>> d3plot = D3plot("path/to/d3plot", state_array_filter=["node_displacement"])
>>> # or with nicer syntax
>>> d3plot = D3plot("path/to/d3plot", state_array_filter=[ArrayType.node_displacement])
>>> # only load first and last state
>>> d3plot = D3plot("path/to/d3plot", state_filter={0, -1})
>>> # our computer lacks RAM so lets extract a specific array
>>> # but only keep one state at a time in memory
>>> d3plot = D3plot("path/to/d3plot",
>>> state_array_filter=[ArrayType.node_displacement],
>>> buffered_reading=True)
Notes
If dyna wrote multiple files for several states,
only give the path to the first file.
check_array_dims(array_dimensions, dimension_name, dimension_size=-1)
This function checks if multiple arrays share an array dimensions with the same size.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
array_dimensions |
Dict[str, int]
|
Array name and expected number of dimensions as dict |
required |
dimension_name |
str
|
Name of the array dimension for error messages |
required |
dimension_size |
int
|
Optional expected size. If not set then all entries must equal the first value collected. |
-1
|
Raises:
Type | Description |
---|---|
ValueError
|
If dimensions do not match in any kind of way. |
compare(d3plot2, array_eps=None)
Compare two d3plots and print the info
Parameters:
Name | Type | Description | Default |
---|---|---|---|
d3plot2 |
second d3plot |
required | |
array_eps |
Union[float, None]
|
tolerance for arrays |
None
|
Returns:
Name | Type | Description |
---|---|---|
hdr_differences |
dict
|
differences in the header |
array_differences |
dict
|
difference between arrays as message |
Examples:
Comparison of a femzipped file and an uncompressed file. Femzip
is a lossy compression, thus precision is traded for memory.
>>> d3plot1 = D3plot("path/to/d3plot")
>>> d3plot2 = D3plot("path/to/d3plot.fz")
>>> hdr_diff, array_diff = d3plot1.compare(d3plot2)
>>> for arraytype, msg in array_diff.items():
>>> print(name, msg)
node_coordinates Δmax = 0.050048828125
node_displacement Δmax = 0.050048828125
node_velocity Δmax = 0.050048828125
node_acceleration Δmax = 49998984.0
element_beam_axial_force Δmax = 6.103515625e-05
element_shell_stress Δmax = 0.0005035400390625
element_shell_thickness Δmax = 9.999999717180685e-10
element_shell_unknown_variables Δmax = 0.0005000010132789612
element_shell_internal_energy Δmax = 188.41957092285156
enable_logger(enable)
staticmethod
Enable the logger for this class
Parameters:
Name | Type | Description | Default |
---|---|---|---|
enable |
bool
|
whether to enable logging for this class |
required |
get_part_filter(filter_type, part_ids, for_state_array=True)
Get a part filter for different entities
Parameters:
Name | Type | Description | Default |
---|---|---|---|
filter_type |
FilterType
|
the array type to filter for (beam, shell, solid, tshell, node) |
required |
part_ids |
Iterable[int]
|
part ids to filter out |
required |
for_state_array |
bool
|
if the filter is meant for a state array. Makes a difference for shells if rigid bodies are in the model (mattyp == 20) |
True
|
Returns:
Name | Type | Description |
---|---|---|
mask |
np.ndarray
|
mask usable on arrays to filter results |
Examples:
>>> from lasso.dyna import D3plot, ArrayType, FilterType
>>> d3plot = D3plot("path/to/d3plot")
>>> part_ids = [13, 14]
>>> mask = d3plot.get_part_filter(FilterType.shell)
>>> shell_stress = d3plot.arrays[ArrayType.element_shell_stress]
>>> shell_stress.shape
(34, 7463, 3, 6)
>>> # select only parts from part_ids
>>> shell_stress_parts = shell_stress[:, mask]
plot(i_timestep=0, field=None, is_element_field=True, fringe_limits=None, export_filepath='')
Plot the d3plot geometry
Parameters:
Name | Type | Description | Default |
---|---|---|---|
i_timestep |
int
|
timestep index to plot |
0
|
field |
Union[np.ndarray, None]
|
Array containing a field value for every element or node |
None
|
is_element_field |
bool
|
if the specified field is for elements or nodes |
True
|
fringe_limits |
Union[Tuple[float, float], None]
|
limits for the fringe bar. Set by default to min and max. |
None
|
export_filepath |
str
|
filepath to export the html to |
''
|
Notes
Currently only shell elements can be plotted, since for
solids the surface needs extraction.
Examples:
Plot deformation of last timestep.
>>> d3plot = D3plot("path/to/d3plot")
>>> d3plot.plot(-1)
>>> # get eff. plastic strain
>>> pstrain = d3plot.arrays[ArrayType.element_shell_effective_plastic_strain]
>>> pstrain.shape
(1, 4696, 3)
>>> # mean across all 3 integration points
>>> pstrain = pstrain.mean(axis=2)
>>> pstrain.shape
(1, 4696)
>>> # we only have 1 timestep here but let's take last one in general
>>> last_timestep = -1
>>> d3plot.plot(0, field=pstrain[last_timestep])
>>> # we don't like the fringe, let's adjust
>>> d3plot.plot(0, field=pstrain[last_timestep], fringe_limits=(0, 0.3))
write_d3plot(filepath, block_size_bytes=2048, single_file=True)
Write a d3plot file again
Parameters:
Name | Type | Description | Default |
---|---|---|---|
filepath |
Union[str, BinaryIO]
|
filepath of the new d3plot file or an opened file handle |
required |
block_size_bytes |
int
|
D3plots are originally written in byte-blocks causing zero-padding at the end of files. This can be controlled by this parameter. Set to 0 for no padding. |
2048
|
single_file |
bool
|
whether to write all states into a single file |
True
|
Examples:
Modify an existing d3plot:
>>> d3plot = D3plot("path/to/d3plot")
>>> hvars = d3plot.array[ArrayType.element_shell_history_vars]
>>> hvars.shape
(1, 4696, 3, 19)
>>> new_history_var = np.random.random((1, 4696, 3, 1))
>>> new_hvars = np.concatenate([hvars, new_history_var], axis=3)
>>> d3plot.array[ArrayType.element_shell_history_vars] = new_hvars
>>> d3plot.write_d3plot("path/to/new/d3plot")
Write a new d3plot from scratch:
>>> d3plot = D3plot()
>>> d3plot.arrays[ArrayType.node_coordinates] = np.array([[0, 0, 0],
... [1, 0, 0],
... [0, 1, 0]])
>>> d3plot.arrays[ArrayType.element_shell_node_indexes] = np.array([[0, 2, 1, 1]])
>>> d3plot.arrays[ArrayType.element_shell_part_indexes] = np.array([0])
>>> d3plot.arrays[ArrayType.node_displacement] = np.array([[[0, 0, 0],
... [1, 0, 0],
... [0, 1, 0]]])
>>> d3plot.write_d3plot("yay.d3plot")