Saving and loading in a JSON + NumPy zip container (panels.json_io)#
The objects Shell, StiffPanelBay, with its stiffeners
BladeStiff1D and BladeStiff2D, and MultiDomain
are saved to and loaded from a zip file with:
from panels import Shell
from panels.shell import load
s = Shell(a=1., b=0.5, stack=[0, 90, 90, 0], plyt=1e-3,
laminaprop=(71e9, 0.33), m=8, n=8)
s.name = 'plate'
s.save() # writes plate.shell.zip
s2 = load('plate') # or load('plate.shell.zip')
or with the functions save() and load() of this module, which
handle the three classes. Instead of a file name, both accept a binary file
object, e.g. io.BytesIO, which is how a browser application running
on Pyodide saves without a file system:
import io
buf = io.BytesIO()
s.save(buf)
data = buf.getvalue() # bytes, e.g. offered for download
The file is a zip archive, compressed with ZIP_DEFLATED, containing:
model.json: the inputs, such as the geometry, the number of termsmandn, the boundary conditions, the stacking sequence, the ply thicknesses, the lamina properties and the loads, in the envelope:{ "type": "Shell", "format_version": 1, "panels_version": "0.13.11", "data": {...} }
arrays/<key>.npy: every NumPy array, e.g. the constitutive matricesABDnxnyand the resultsfieldsorresults['eigvecs'], written bynumpy.save()withallow_pickle=False. Inmodel.jsonan array is replaced by{"__ndarray__": "arrays/<key>.npy"}.
The laminates, e.g. Shell.lam, are embedded in model.json with
composites.to_dict(). The JSON is strict, readable by JSON.parse in
JavaScript: the floats nan, inf and -inf are stored as the
strings "NaN", "Infinity" and "-Infinity". Tuples are loaded as
lists and NumPy scalars as Python int or float.
Only an explicit list of attributes of each class is stored, such that the
format does not depend on implementation details. Saving an attribute whose
value is not supported raises TypeError, e.g. the functions of the
distributed loads Shell.add_distr_load_fixed_x() or of a pressure
p(x, y). The following are not stored and are recomputed on demand: the
structural matrices (Shell.matrices, StiffPanelBay.kC,
MultiDomain.kC, MultiDomain.T, …), the number of threads
out_num_cores, which takes the default of the machine that loads the
file, and the attributes of Python subclasses, the loaded object having the
type of the base class.
Loading is safe for files from untrusted sources, unlike pickle: the arrays
are read with allow_pickle=False, the members are read in memory and
never extracted, only the members referenced by model.json are read,
after checking that their uncompressed sizes do not exceed max_size in
total, and unknown keys, missing or extra members and newer format versions
raise ValueError.
The pickle files written by older versions of panels are not loaded, since a
pickle file can execute arbitrary code. One from a trusted source can be
converted by loading it with pickle.load() and saving the object again.
- panels.json_io.save(obj, fname)#
Save an object to a zip file
- Parameters:
- obj
Shell,StiffPanelBayorMultiDomain The object to be saved. It is not modified.
- fnamestr, path-like or file object
Name of the file, or a binary file object opened for writing, e.g.
io.BytesIO.
- obj
- Raises:
- TypeError
If
objis not one of the supported classes, or if one of its stored attributes has a value that cannot be saved, e.g. a function.
- panels.json_io.load(fname, max_size=4294967296)#
Load an object from a zip file created by
save()- Parameters:
- fnamestr, path-like or file object
Name of the file, or a binary file object opened for reading, e.g.
io.BytesIO.- max_sizeint, optional
Maximum total uncompressed size of the members read, in bytes, 4 GiB by default. It is checked before reading, against the sizes declared in the zip file.
- Returns:
- obj
Shell,StiffPanelBayorMultiDomain The object.
- obj
- Raises:
- ValueError
If the file is not a zip file saved by panels, e.g. a pickle file of an older version, is not valid, has unknown keys, missing or extra members, exceeds
max_size, or was saved by a newer format version.