pumapy.experimental
pumapy.filters
pumapy.filters.filters
Note: Most of the filters are simple wrappers of functions in either scikitimage or scipy.ndimage. The filters can be run directly in these packages if the user desires, but the wrapping is done for simplicity so that the Workspace class can be used, and the filter executions can be logged by the workspace class in order to document the simulation workflows.
The C++ version of puma implements the filters directly. But for python, there’s no reason to re-invent the wheel when so many great packages exist for image manipulation
- pumapy.filters.filters.filter_closing(ws, cutoff, size=5)[source]
3D morphological closing filter (i.e. erosion first and then dilation).
- Parameters
ws (Workspace) – input workspace
cutoff ((int, int)) – cutoff to binarize image
size (int) – size of the spherical windows used
- Example
>>> import pumapy as puma >>> ws = puma.import_3Dtiff(puma.path_to_example_file("100_fiberform.tif"), 1.3e-6) Importing .../100_fiberform.tif ... Done >>> ws_closing = ws.copy() >>> puma.filter_closing(ws_closing, cutoff=(90, 255), size=3) >>> ws_binary = ws.copy() >>> ws_binary.binarize_range((90, 255)) >>> # puma.compare_slices(ws_binary, ws_closing, 'z', index=1) # to visualize it
- pumapy.filters.filters.filter_dilate(ws, cutoff, size=5)[source]
3D morphological dilation filter.
- Parameters
ws (Workspace) – input workspace
cutoff ((int, int)) – cutoff to binarize image
size (int) – size of the spherical windows used
- Example
>>> import pumapy as puma >>> ws = puma.generate_tpms((100, 100, 100), (0.02, 0.05), 0.201, 0) # generate tpms material Generating TPMS ... >>> ws_dilate = ws.copy() >>> puma.filter_dilate(ws_dilate, cutoff=(1, 1), size=5) # dilating the copy >>> # puma.compare_slices(ws, ws_dilate) # to visualize it
- pumapy.filters.filters.filter_edt(ws, cutoff)[source]
3D Exact euclidean distance transform.
- Parameters
ws (Workspace) – input workspace
cutoff ((int, int)) – cutoff to binarize image
- Example
>>> import pumapy as puma >>> ws = puma.generate_tpms((100, 100, 100), (0.02, 0.05), 0.201, 0) # generate tpms material Generating TPMS... >>> ws_edt = ws.copy() >>> puma.filter_edt(ws_edt, cutoff=(1, 1)) >>> # puma.compare_slices(ws, ws_edt) # to visualize it
- pumapy.filters.filters.filter_erode(ws, cutoff, size=5)[source]
3D morphological erosion filter.
- Parameters
ws (Workspace) – input workspace
cutoff ((int, int)) – cutoff to binarize image
size (int) – size of the spherical windows used
- Example
>>> import pumapy as puma >>> ws = puma.generate_tpms((100, 100, 100), (0.02, 0.05), 0.201, 0) # generate tpms material Generating TPMS ... >>> ws_erode = ws.copy() >>> puma.filter_erode(ws_erode, (1, 1)) # eroding the copy >>> # puma.compare_slices(ws, ws_erode) # to visualize it
- pumapy.filters.filters.filter_gaussian(ws, sigma=1, apply_on_orientation=False)[source]
3D Gaussian filter
- Parameters
ws (Workspace) – input workspace
sigma (int) – size of kernel
apply_on_orientation (bool) – specify whether to apply filter on orientation field
- Example
>>> import pumapy as puma >>> ws = puma.import_3Dtiff(puma.path_to_example_file("100_fiberform.tif"), 1.3e-6) Importing .../100_fiberform.tif ... Done >>> ws_gaussian = ws.copy() >>> puma.filter_gaussian(ws_gaussian, sigma=2, apply_on_orientation=False) >>> # puma.compare_slices(ws, ws_gaussian, 'z', index=1) # to visualize it
- pumapy.filters.filters.filter_mean(ws, size=5)[source]
3D Mean filter.
- Parameters
ws (Workspace) – input workspace
size (int) – size of window
- Example
>>> import pumapy as puma >>> ws = puma.import_3Dtiff(puma.path_to_example_file("100_fiberform.tif"), 1.3e-6) Importing .../100_fiberform.tif ... Done >>> ws_mean = ws.copy() >>> puma.filter_mean(ws_mean, size=10) >>> # puma.compare_slices(ws, ws_mean) # to visualize it
- pumapy.filters.filters.filter_median(ws, size)[source]
3D Median filter
- Parameters
ws (Workspace) – input workspace
size (int) – size of window
- Example
>>> import pumapy as puma >>> ws = puma.import_3Dtiff(puma.path_to_example_file("100_fiberform.tif"), 1.3e-6) Importing .../100_fiberform.tif ... Done >>> ws_median = ws.copy() >>> puma.filter_median(ws_median, size=10) >>> # puma.compare_slices(ws, ws_median) # to visualize it
- pumapy.filters.filters.filter_opening(ws, cutoff, size=5)[source]
3D morphological opening filter (i.e. dilation first and then erosion).
- Parameters
ws (Workspace) – input workspace
cutoff ((int, int)) – cutoff to binarize image
size (int) – size of the spherical windows used
- Example
>>> import pumapy as puma >>> ws = puma.import_3Dtiff(puma.path_to_example_file("100_fiberform.tif"), 1.3e-6) Importing .../100_fiberform.tif ... Done >>> ws_opening = ws.copy() >>> puma.filter_opening(ws_opening, cutoff=(90, 255), size=3) >>> ws_binary = ws.copy() >>> ws_binary.binarize_range((90, 255)) >>> # puma.compare_slices(ws_binary, ws_opening, 'z', index=1) # to visualize it
pumapy.generation
pumapy.generation.cylinder_square_array
- class pumapy.generation.cylinder_square_array.GeneratorSquareArray(size, porosity)[source]
Bases:
object
- pumapy.generation.cylinder_square_array.generate_cylinder_square_array(size, porosity, segmented=True)[source]
Generate a 2D periodic array of circles
- Parameters
size (int) – length of one side of the output domain
porosity (float) – porosity of the output domain
segmented (bool) – return a domain that is already segmented (i.e. each sphere with unique ID) or with grayscales 0-255 with threshold=128 for the input diameter
- Returns
array of circles
- Return type
- Example
>>> import pumapy as puma >>> ws = puma.generate_cylinder_square_array(100, 0.8, segmented=True) Generated in: ... >>> # puma.render_volume(ws) # to visualize it
pumapy.generation.pitting
- class pumapy.generation.pitting.GeneratorPits(workspace, surface_threshold, mean_radius, deviation_radius, volume_fraction_removed, max_pits)[source]
Bases:
object
- pumapy.generation.pitting.generate_pitting(workspace, surface_threshold, mean_radius, deviation_radius, volume_fraction_removed, max_pits=10000)[source]
Generation of pitting into existing workspace
- Parameters
workspace (pumapy.Workspace) – pumapy workspace to add pitting to
surface_threshold (int) – threshold value at which the solid starts. Void phase is contained in (0,surface_threshold-1)
mean_radius (float) – mean radius of the pits
deviation_radius (float) – deviation in the radius of the pits (plus or minus)
volume_fraction_removed (float) – volume fraction to be removed by pits
max_pits (int) – maximum number of pits. To ensure while(true) condition doesn’t occur if specified volume_fraction can’t be reached
- Returns
None
- Return type
None
- Example
>>> import pumapy as puma >>> shape = (200, 200, 200) # size of the domain, in voxels. >>> w = 0.08 # value of w in the equations above >>> q = 0.2 # value of q in the equations above >>> ws_eq0 = puma.generate_tpms(shape, w, q, equation=0, segmented=False) Generating TPMS ... >>> surface_threshold = 128 # threshold value at which the solid starts. Void phase is contained in (0,surface_threshold-1) >>> mean_radius = 4 # Mean radius of the pits, in voxels >>> deviation_radius = 3 # Deviation of the pits, in voxels >>> volume_fraction_removed = 0.01 # Volume fraction of the pits to be removed >>> puma.experimental.generate_pitting(ws_eq0, surface_threshold, mean_radius, deviation_radius, volume_fraction_removed) Volume Fraction for cutoff ... >>> # puma.render_contour(ws_eq0, (128,255)) # to visualize it
pumapy.generation.random_fibers
The following function was copied and modified from the porespy project (distributed under the MIT License). See https://github.com/PMEAL/porespy/blob/dev/porespy/generators/_imgen.py for more information. See https://github.com/PMEAL/porespy/blob/dev/LICENSE for the license.
- pumapy.generation.random_fibers.generate_random_fibers(shape, radius, nfibers=None, porosity=None, phi=90.0, theta=90.0, length=None, max_iter=5, allow_intersect=True, segmented=True)[source]
Generates random fibers from number of fibers or porosity
- Parameters
shape ((int, int, int)) – the shape of the workspace to generate in (Nx, Ny, Nz) where N is the number of voxels.
radius (int) – the radius of the fibers in voxels
nfibers (int or None) – the number of fibers to add to the domain. Adjust this value to control the final porosity, which is not easily specified since cylinders overlap and intersect different fractions of the domain
porosity (float) – the target value for the porosity of the generated mat. The function uses an algorithm for predicting the number of required number of cylinder, and refines this over a certain number of fractional insertions (according to the ‘iterations’ input)
phi (float) – a value between 0 and 90 that controls the amount that the fibers lie out of the XY plane, with 0 meaning all fibers lie in the XY plane, and 90 meaning that cylinders are randomly oriented out of the plane by as much as +/- 90 degrees
theta (float) – a value between 0 and 90 that controls the amount of rotation in the XY plane, with 0 meaning all fibers point in the X-direction, and 90 meaning they are randomly rotated about the Z axis by as much as +/- 90 degrees
length (float) – the length of the cylinders to add. If
None
(default) then the cylinders will extend beyond the domain in both directions so no ends will exist. If a scalar value is given it will be interpreted as the Euclidean distance between the two ends of the cylinder. Note that one or both of the ends may still lie outside the domain, depending on the randomly chosen center point of the cylindermax_iter (int) – the number of fractional fiber insertions used to target the requested porosity. By default a value of 3 is used (and this is typically effective in getting very close to the targeted porosity), but a greater number can be input to improve the achieved porosity
allow_intersect (bool) – allow intersection betweem the fibers
segmented (bool) – return a domain that is already segmented (i.e. each fiber with unique ID) or with grayscales 0-255 with threshold=128 for the input diameter
- Returns
random fibers domain
- Return type
- pumapy.generation.random_fibers.generate_random_fibers_1D(shape, radius, nfibers=None, porosity=None, direction='z', length=None, max_iter=5, allow_intersect=True, segmented=True)[source]
Generates random 1D fibers from number of fibers or porosity
- Parameters
shape ((int, int, int)) – the shape of the workspace to generate in (Nx, Ny, Nz) where N is the number of voxels.
radius (int) – the radius of the fibers in voxels
nfibers (int or None) – the number of fibers to add to the domain. Adjust this value to control the final porosity, which is not easily specified since cylinders overlap and intersect different fractions of the domain
porosity (float) – the target value for the porosity of the generated mat. The function uses an algorithm for predicting the number of required number of cylinder, and refines this over a certain number of fractional insertions (according to the ‘iterations’ input)
direction (string) – Either ‘x’, ‘y’, or ‘z’. The direction of the 1D fibers
length (float) – the length of the cylinders to add. If
None
(default) then the cylinders will extend beyond the domain in both directions so no ends will exist. If a scalar value is given it will be interpreted as the Euclidean distance between the two ends of the cylinder. Note that one or both of the ends may still lie outside the domain, depending on the randomly chosen center point of the cylindermax_iter (int) – the number of fractional fiber insertions used to target the requested porosity. By default a value of 3 is used (and this is typically effective in getting very close to the targeted porosity), but a greater number can be input to improve the achieved porosity
allow_intersect (bool) – allow intersection betweem the fibers
segmented (bool) – return a domain that is already segmented (i.e. each fiber with unique ID) or with grayscales 0-255 with threshold=128 for the input diameter
- Returns
random fibers domain
- Return type
- Example
>>> import pumapy as puma >>> # specify porosity >>> ws_fibers = puma.generate_random_fibers_1D(shape=(100, 100, 100), radius=4, porosity=0.8, direction='x', length=200, allow_intersect=True, segmented=True) Fibers created... >>> # puma.render_volume(ws_fibers, cutoff=(1, ws_fibers.max()), cmap='jet') # to visualize it >>> # puma.render_orientation(ws_fibers) >>> >>> # specify number of fibers >>> ws_fibers = puma.generate_random_fibers_1D(shape=(100, 100, 100), radius=4, nfibers=100, direction='y', length=200, allow_intersect=True, segmented=False) Fibers created... >>> # puma.render_volume(ws_fibers, cutoff=(1, ws_fibers.max()), cmap='jet') # to visualize it >>> # puma.render_orientation(ws_fibers) >>> >>> # don't allow intersection between fibers >>> ws_fibers = puma.generate_random_fibers_1D(shape=(100, 100, 100), radius=4, porosity=0.9, direction='z', length=200, allow_intersect=False, segmented=True) Fibers created... >>> # puma.render_volume(ws_fibers, cutoff=(1, ws_fibers.max()), cmap='jet') # to visualize it >>> # puma.render_orientation(ws_fibers)
- pumapy.generation.random_fibers.generate_random_fibers_helper(shape, radius, nfibers, porosity, angle_type, variation, direction, length, max_iter, allow_intersect=True, segmented=True)[source]
- pumapy.generation.random_fibers.generate_random_fibers_isotropic(shape, radius, nfibers=None, porosity=None, length=None, max_iter=5, allow_intersect=True, segmented=True)[source]
Generates random isotropic fibers from number of fibers or porosity
- Parameters
shape ((int, int, int)) – the shape of the workspace to generate in (Nx, Ny, Nz) where N is the number of voxels.
radius (int) – the radius of the fibers in voxels
nfibers (int or None) – the number of fibers to add to the domain. Adjust this value to control the final porosity, which is not easily specified since cylinders overlap and intersect different fractions of the domain
porosity (float) – the target value for the porosity of the generated mat. The function uses an algorithm for predicting the number of required number of cylinder, and refines this over a certain number of fractional insertions (according to the ‘iterations’ input)
length (float) – the length of the cylinders to add. If
None
(default) then the cylinders will extend beyond the domain in both directions so no ends will exist. If a scalar value is given it will be interpreted as the Euclidean distance between the two ends of the cylinder. Note that one or both of the ends may still lie outside the domain, depending on the randomly chosen center point of the cylindermax_iter (int) – the number of fractional fiber insertions used to target the requested porosity. By default a value of 3 is used (and this is typically effective in getting very close to the targeted porosity), but a greater number can be input to improve the achieved porosity
allow_intersect (bool) – allow intersection betweem the fibers
segmented (bool) – return a domain that is already segmented (i.e. each fiber with unique ID) or with grayscales 0-255 with threshold=128 for the input diameter
- Returns
random fibers domain
- Return type
- Example
>>> import pumapy as puma >>> # specify porosity >>> ws_fibers = puma.generate_random_fibers_isotropic(shape=(100, 100, 100), radius=4, porosity=0.8, length=200, allow_intersect=True, segmented=True) Fibers created... >>> # puma.render_volume(ws_fibers, cutoff=(1, ws_fibers.max()), cmap='jet') # to visualize it >>> # puma.render_orientation(ws_fibers) >>> >>> # specify number of fibers >>> ws_fibers = puma.generate_random_fibers_isotropic(shape=(100, 100, 100), radius=4, nfibers=100, length=200, allow_intersect=True, segmented=False) Fibers created... >>> # puma.render_volume(ws_fibers, cutoff=(1, ws_fibers.max()), cmap='jet') # to visualize it >>> # puma.render_orientation(ws_fibers)
- pumapy.generation.random_fibers.generate_random_fibers_transverseisotropic(shape, radius, nfibers=None, porosity=None, direction='z', variation=0, length=None, max_iter=5, allow_intersect=True, segmented=True)[source]
Generates random transverse isotropic fibers from number of fibers or porosity
- Parameters
shape ((int, int, int)) – the shape of the workspace to generate in (Nx, Ny, Nz) where N is the number of voxels.
radius (int) – the radius of the fibers in voxels
nfibers (int or None) – the number of fibers to add to the domain. Adjust this value to control the final porosity, which is not easily specified since cylinders overlap and intersect different fractions of the domain
porosity (float) – the target value for the porosity of the generated mat. The function uses an algorithm for predicting the number of required number of cylinder, and refines this over a certain number of fractional insertions (according to the ‘iterations’ input)
direction (string) – Either ‘x’, ‘y’, or ‘z’. The direction orthogonal to the plane of the fibers. Example: for fibers oreinted in XY, put ‘z’
variation (float) – The angle variation in the orthogonal direction. 0 for no variation, 90 for full variation.
length (float) – the length of the cylinders to add. If
None
(default) then the cylinders will extend beyond the domain in both directions so no ends will exist. If a scalar value is given it will be interpreted as the Euclidean distance between the two ends of the cylinder. Note that one or both of the ends may still lie outside the domain, depending on the randomly chosen center point of the cylindermax_iter (int) – the number of fractional fiber insertions used to target the requested porosity. By default a value of 3 is used (and this is typically effective in getting very close to the targeted porosity), but a greater number can be input to improve the achieved porosity
allow_intersect (bool) – allow intersection betweem the fibers
segmented (bool) – return a domain that is already segmented (i.e. each fiber with unique ID) or with grayscales 0-255 with threshold=128 for the input diameter
- Returns
random fibers domain
- Return type
- Example
>>> import pumapy as puma >>> # specify porosity >>> ws_fibers = puma.generate_random_fibers_transverseisotropic(shape=(100, 100, 100), radius=4, porosity=0.8, direction='x', variation=15, length=200, allow_intersect=True, segmented=True) Fibers created... >>> # puma.render_volume(ws_fibers, cutoff=(1, ws_fibers.max()), cmap='jet') # to visualize it >>> # puma.render_orientation(ws_fibers) >>> >>> # specify number of fibers >>> ws_fibers = puma.generate_random_fibers_transverseisotropic(shape=(100, 100, 100), radius=4, nfibers=100, direction='y', variation=0, length=200, allow_intersect=True, segmented=False) Fibers created... >>> # puma.render_volume(ws_fibers, cutoff=(1, ws_fibers.max()), cmap='jet') # to visualize it >>> # puma.render_orientation(ws_fibers) >>> >>> # don't allow intersection between fibers >>> ws_fibers = puma.generate_random_fibers_transverseisotropic(shape=(100, 100, 100), radius=4, porosity=0.9, direction='z', variation=30, length=200, allow_intersect=False, segmented=True) Fibers created... >>> # puma.render_volume(ws_fibers, cutoff=(1, ws_fibers.max()), cmap='jet') # to visualize it >>> # puma.render_orientation(ws_fibers)
pumapy.generation.random_spheres
- class pumapy.generation.random_spheres.GeneratorSpheres(size, diameter, porosity, allow_intersect, segmented)[source]
Bases:
object
- pumapy.generation.random_spheres.generate_random_spheres(shape, diameter, porosity, allow_intersect=True, segmented=True)[source]
Generation of random spheres domains
- Parameters
shape ((int, int, int)) – shape of 3D domain (x,y,z)
diameter (float) – diameter of the random spheres in voxels
porosity (float) – target porosity of the generated structure
allow_intersect (bool) – allow the spheres to intersect or not
segmented (bool) – return a domain that is already segmented (i.e. each sphere with unique ID) or with grayscales 0-255 with threshold=128 for the input diameter
- Returns
random spheres domain
- Return type
- Example
>>> import pumapy as puma >>> ws_generated = puma.generate_random_spheres(shape=(100,100,100), diameter=10, porosity=0.8, allow_intersect=True, segmented=True) Approximately ... spheres to be generated... >>> # puma.render_volume(ws_generated, cutoff=(1, ws_generated.max()), cmap='jet') # to visualize it
pumapy.generation.single_sphere
- class pumapy.generation.single_sphere.GeneratorSphere(size, center, diameter)[source]
Bases:
object
- pumapy.generation.single_sphere.generate_sphere(shape, center, diameter, segmented=True)[source]
Generation of a sphere at a given point and diameter
- Parameters
shape ((int, int, int)) – size of 3D domain (x,y,z)
center ((int, int, int)) – centerpoint of sphere (x,y,z)
diameter (float) – diameter of the random spheres in voxels
segmented (bool) – return a domain that is already segmented (i.e. each sphere with unique ID) or with grayscales 0-255 with threshold=128 for the input diameter
- Returns
domain with sphere with input diameter
- Return type
- Example
>>> import pumapy as puma >>> ws = puma.generate_sphere((100, 100, 100), (50, 50, 50), 80) Generated in... >>> # puma.render_volume(ws.matrix[:ws.matrix.shape[0]//2]) # to visualize it
pumapy.generation.tpms
- pumapy.generation.tpms.generate_tpms(shape, w, q, equation=0, segmented=True)[source]
Generation of triply periodic minimal surface material
- Parameters
shape ((int, int, int)) – shape of 3D domain (x,y,z)
w (float or (float, float)) – w parameter for tpms
q (float or (float, float)) – q parameter for tpms (float or tuple)
equation (int) – equation 0, 1, or 2 for tpms
segmented (bool) – return a domain that is already segmented (i.e. 1 for solid and 0 for void) or with grayscales 0-255 with threshold=128 for the solid
- Returns
TPMS domain with grayscales from 0-255 with threshold=128 for the normal TPMS geometry
- Return type
- Example
>>> import pumapy as puma >>> shape = (200, 200, 200) # size of the domain, in voxels. >>> w = 0.08 # value of w in the equations above >>> q = 0.2 # value of q in the equations above >>> ws_eq0 = puma.generate_tpms(shape, w, q, equation=0, segmented=False) Generating TPMS ... >>> ws_eq1 = puma.generate_tpms(shape, w, q, equation=1, segmented=False) Generating TPMS ... >>> ws_eq2 = puma.generate_tpms(shape, w, q, equation=2, segmented=False) Generating TPMS ... >>> # puma.render_contour(ws_eq0, cutoff=(128, 255)) # to visualize them >>> # puma.render_contour(ws_eq1, cutoff=(128, 255)) >>> # puma.render_contour(ws_eq2, cutoff=(128, 255))
pumapy.generation.tpms_utils
- pumapy.generation.tpms_utils.generate(matrix, l_x, l_y, l_z, wmin, wmax, qmin, qmax, equation)
pumapy.generation.tpms_utils
- pumapy.generation.tpms_utils.generate(matrix, l_x, l_y, l_z, wmin, wmax, qmin, qmax, equation)
pumapy.io
pumapy.io.export_texgen_weave
- pumapy.io.export_texgen_weave.export_weave_vtu(filename, weave, domain, max_dim_nvox, round_vox_up=True, export_orientation=True)[source]
Exporting weave to vtu, to be read by pumapy
- Parameters
filename (string) – filepath and name
weave (CTextile or child class of CTextile) – weave object, as defined in TexGen
domain (CDomainPlanes) – domain size object, as defined in TexGen
max_dim_nvox (int) – number of voxels to add in the largest domain dimension
round_vox_up (bool) – for the shorter dimensions, round number of voxels up (for +/-1 vox)
export_orientation (bool) – specify whether to export orientation
- Returns
filename of weave exported (input filename + dimensions)
- Return type
string
pumapy.io.input
- pumapy.io.input.import_3Dtiff(filename, voxel_length=1e-06, import_ws=True)[source]
Function to io 3D tiff
- Parameters
filename (string) – filepath and name
voxel_length (float) – size of a voxel side
import_ws (bool) – if True returns a puma.Workspace, otherwise a ndarray
- Returns
domain
- Return type
pumapy.Workspace or np.ndarray
- Example
>>> import pumapy as puma >>> ws_tiff = puma.import_3Dtiff(puma.path_to_example_file("50_artfibers.tif"), 1.3e-6, import_ws=True) Importing ... >>> ws_tiff.get_shape() (50, 50, 50)
- pumapy.io.input.import_bin(filename)[source]
Import a pumapy.Workspace to binary (.pumapy extension)
- Parameters
filename (string) – filepath and name
- Returns
domain
- Return type
pumapy.Workspace
- Example
>>> import pumapy as puma >>> ws_binary = puma.import_bin(puma.path_to_example_file("fibers_with_orientation.pumapy")) Importing ...
- pumapy.io.input.import_scalar_field_from_chfem(filename, domain_shape, rotate_domain=True)[source]
Import scalar field (e.g. temperature, pressure) output from CHFEM_GPU CUDA kernels (https://gitlab.com/cortezpedro/chfem_gpu)
- Parameters
filename (string) – file path and name of .bin file
domain_shape ((int, int, int)) – shape of domain for which the scalar field was generated
rotate_domain (bool) – rotate the domain to be in the same format as export
- Returns
scalar field (x,y,z)
- Return type
np.ndarray
- pumapy.io.input.import_sparta_implicit_surfaces(filename, dimension=3, voxel_length=1e-06, import_ws=True, extend_to_boundary=True)[source]
Function to io sparta implicit surfaces
- Parameters
filename (string) – filepath and name
dimension (int) – dimensionality of imported sparta structure
voxel_length (float) – size of a voxel side
import_ws (bool) – if True returns a puma.Workspace, otherwise a ndarray
extend_to_boundary (bool) – if True recreates nonzero boundary values as extension of inner structure, otherwise all boundary values equal zero
- Returns
domain
- Return type
pumapy.Workspace or np.ndarray
- Example
>>> import pumapy as puma >>> ws = puma.import_bin(puma.path_to_example_file("fibers_with_orientation.pumapy")) Importing ... >>> puma.experimental.export_sparta_implicit_surfaces("surfaces", ws) Exporting ... >>> surf = puma.experimental.import_sparta_implicit_surfaces("surfaces.pumapy.isurf", dimension=3, voxel_length=1.0e-6, import_ws=False) Importing ...
- pumapy.io.input.import_stress_field_from_chfem(filename, domain_shape, rotate_domain=True)[source]
Import stress fields output from CHFEM_GPU CUDA kernels (https://gitlab.com/cortezpedro/chfem_gpu)
- Parameters
filename (string) – file path and name of .bin file
domain_shape ((int, int, int)) – shape of domain for which the scalar field was generated
rotate_domain (bool) – rotate the domain to be in the same format as export
- Returns
direct stresses (x,y,z,3) and shear stresses (x,y,z,3)
- Return type
(np.ndarray, np.ndarray)
- pumapy.io.input.import_vector_field_from_chfem(filename, domain_shape, rotate_domain=True, correct_direction=None)[source]
Import vector field (e.g. heat flux, displacement, velocity) output from CHFEM_GPU CUDA kernels (https://gitlab.com/cortezpedro/chfem_gpu)
- Parameters
filename (string) – file path and name of .bin file
domain_shape ((int, int, int)) – shape of domain for which the scalar field was generated
rotate_domain (bool) – rotate the domain to be in the same format as export
correct_direction (str) – correct orientation field according to simulation direction, expects ‘x’, ‘y’, or ‘z’
- Returns
vector field (x,y,z,3)
- Return type
np.ndarray
- pumapy.io.input.import_vti(filename, voxel_length=None, import_ws=True)[source]
Function to import either legacy VTK file (.vtk) or vtkImageData (.vti)
- Parameters
filename (string) – filepath and name
voxel_length (float) – voxel_length. If None, voxel_length from the vtk file is used
import_ws (bool) – True returns a puma.Workspace, otherwise a list of ndarrays
- Returns
if import_ws is True, then it returns a Workspace. if import_ws is False, it returns a dictionary of ndarrays as {“name1”: data1, “name2”: data2 …}
- Return type
pumapy.Workspace or {str: np.ndarray}
- Example
>>> import pumapy as puma >>> ws_vtk = puma.import_vti(puma.path_to_example_file("fibers_with_orientation.vti")) Importing ...
- pumapy.io.input.import_weave_vtu(filename, from_texgen_gui=False)[source]
Import TexGen vtu weave in a Workspace
- Parameters
filename (string) – file path and name
from_texgen_gui (bool) – voxel grid exported from the TexGen GUI (Windows) or from TexGen inside PuMA
- Returns
voxelized weave from TexGen
- Return type
pumapy.Workspace
pumapy.io.output
- pumapy.io.output.export_3Dtiff(filename, ws_or_nparray, to8bit=True)[source]
Export either a puma.Workspace or numpy array to 3Dtiff
- Parameters
filename (string) – filepath and name
ws_or_nparray (Workspace or ndarray) – to be exported
to8bit (bool) – if True, it converts the image to 8bit, otherwise 16bit is exported
- Example
>>> import pumapy as puma >>> ws_tiff = puma.import_3Dtiff(puma.path_to_example_file("50_artfibers.tif"), 1.3e-6, import_ws=True) Importing ... >>> puma.export_3Dtiff("50_artfibers.tif", ws_tiff) Exporting ...
- pumapy.io.output.export_bin(filename, ws)[source]
Export a puma.Workspace to binary (.pumapy extension)
- Parameters
filename (string) – filepath and name
ws – to be exported
- Type
pumapy.Workspace
- Example
>>> import pumapy as puma >>> ws_binary = puma.import_bin(puma.path_to_example_file("fibers_with_orientation.pumapy")) Importing ... >>> puma.export_bin("fibers_with_orientation.vti", ws_binary) Exporting ...
- pumapy.io.output.export_for_chfem(filename, ws, analysis, solver=0, export_nf=True, export_json=True, tol=1e-06, max_iter=10000)[source]
Export a puma.Workspace to run an analysis in CHFEM_GPU CUDA kernels (https://gitlab.com/cortezpedro/chfem_gpu) or CHPACK Julia package (https://gitlab.com/lcc-uff/Chpack.jl)
- Parameters
filename (string) – filepath and name
ws (pumapy.Workspace) – to be exported
type_of_analysis (int) – 0 = conductivity, 1 = elasticity, 2 = permeability
type_of_solver (int) – 0 = pcg (default), 1 = cg, 2 = minres
export_nf (bool) – export .nf file with simulations inputs for CHFEM_GPU
export_json (bool) – export .json file with simulations inputs for CHFPACK
tol (float) – solver tolerance for simulation
max_iter (int) – maximum number of iterations
- Example
>>> import pumapy as puma >>> ws = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif"), 1.3e-6) Importing ... >>> puma.export_for_chfem('200_fiberform', ws, 2, tol=1e-6, max_iter=100000)
- pumapy.io.output.export_sparta_implicit_surfaces(filename, ws)[source]
Export a puma.Workspace to binary (.pumapy extension)
- Parameters
filename (string) – filepath and name
ws (pumapy.Workspace) – to be exported
- Example
>>> import pumapy as puma >>> ws = puma.import_bin(puma.path_to_example_file("fibers_with_orientation.pumapy")) Importing ... >>> puma.experimental.export_sparta_implicit_surfaces("surfaces", ws) Exporting ...
- pumapy.io.output.export_stl(filename, ws, cutoff, flag_closed_edges=True, flag_gaussian=False, binary=True)[source]
Export a puma.Workspace to STL
- Parameters
filename (string) – filepath and name
ws (pumapy.Workspace) – to be exported
cutoff ((int, int)) – specify cutoff to binarize material
flag_closed_edges (bool) – close the surface edges on the boundaries
flag_gaussian (bool) – apply Gaussian filter before creating surface
- Example
>>> import pumapy as puma >>> ws_imported = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif"), 1.3e-6) Importing ... >>> puma.export_stl('200_fiberform', ws_imported, cutoff=(100, 255), flag_closed_edges=True) Exporting ...
- pumapy.io.output.export_vti(filename, dict_data, voxel_length=None)[source]
Export either a puma.Workspace or numpy array to vti
- Parameters
filename (string) – filepath and name
dict_data (dict or Workspace or np.ndarray) – dictionary setup as {“name1”: data1, “name2”: data2 …} containing either Workspaces or ndarrays
voxel_length (float) – with voxel length to give to Numpy arrays (if any)
- Example
>>> import pumapy as puma >>> ws_vtk = puma.import_vti(puma.path_to_example_file("fibers_with_orientation.vti")) Importing ... >>> puma.export_vti("fibers_with_orientation.vti", ws_vtk) Exporting ...
pumapy.material_properties
pumapy.material_properties.anisotropic_radiation
- class pumapy.material_properties.anisotropic_radiation.AnisotropicRadiation(workspace, void_cutoff, sources_number, direction, bin_density, export_plot)[source]
Bases:
object
- pumapy.material_properties.anisotropic_radiation.compute_extinction_coefficients_anisotropic(ws, rays_distances, sources_number, bin_density=10000, export_pathname=None)[source]
Compute the extinction coefficient based on the ray casting radiation simulation (this is normally a step inside the compute_radiation function)
- Parameters
ws (pumapy.Workspace) – domain
rays_distances (np.ndarray) – rays distances, as output by compute_radiation function
sources_number (int) – number of light sources spread randomly in the void space (i.e. 0)
bin_density (int) – number of bins used to create histogram of ray distances
export_pathname (str) – path to save curve plot of ray distance distribution
- Returns
extinction coefficient (beta), its standard deviation
- Return type
(float, float)
- pumapy.material_properties.anisotropic_radiation.compute_radiation_anisotropic(workspace, void_cutoff, sources_number, bin_density=10000, export_pathname=None)[source]
Compute the anisotropic radiative thermal conductivity through ray tracing
- Parameters
workspace (pumapy.Workspace) – domain
void_cutoff ((int, int)) – specify the void phase
sources_number (int) – number of light sources spread randomly in the void space (i.e. 0)
bin_density (int) – number of bins used to create histogram of ray distances
export_pathname (str) – path to save curve plot of ray distance distribution
- Returns
extinction coefficient (beta), its standard deviation and of ray distances
- Return type
(float, float, np.ndarray)
pumapy.material_properties.conductivity
Further explained in publication: Semeraro, F., Ferguson, J.C., Acin, M., Panerai, F. and Mansour, N.N., 2021. Anisotropic analysis of fibrous and woven materials part 2: Computation of effective conductivity. Computational Materials Science, 186, p.109956. https://www.sciencedirect.com/science/article/abs/pii/S092702562030447X
- pumapy.material_properties.conductivity.compute_electrical_conductivity(workspace, cond_map, direction, side_bc='p', prescribed_bc=None, tolerance=1e-05, maxiter=10000, solver_type='bicgstab', display_iter=True, method='fv', matrix_free=True)[source]
Compute the electrical conductivity
- Parameters
workspace (pumapy.Workspace) – domain
cond_map (IsotropicConductivityMap or AnisotropicConductivityMap) – local constituents electrical conductivities
direction (string) – direction for solve (‘x’,’y’,’z’, or ‘’ for prescribed_bc). If provided, prescribed_bc is ignored
side_bc (string) – side boundary conditions can be symmetric (‘s’) or periodic (‘p’). Only periodic available when method=’fe’
prescribed_bc (pumapy.IsotropicConductivityBC or pumapy.AnisotropicConductivityBC or None) – object holding dirichlet BC, only available for isotropic of MPFA implementations. Need to set direction=’’ in order to provide it. When prescribed_bc is provided, keff is not printed but it is computed as if direction==’x’ for testing purposes.
tolerance (float) – tolerance for iterative solver
maxiter (int) – maximum Iterations for solver
solver_type (string) – solver type, options: ‘bicgstab’ (default), ‘cg’, ‘gmres’, ‘minres’ (only for method=’fe’), ‘direct’
display_iter (bool) – display iterations and residual
method (string) – whether to use finite volume solver (‘fv’, either isotropic solver if IsotropicConductivityMap is passed, or mpfa if AnisotropicConductivityMap) or finite element Q1-Q1 EBE solver (‘fe’). For the latter method, it is recommended to use solver_type=’minres’ as lighter and faster
matrix_free (bool) – if True, then use matrix-free method if possible (only available for fv isotropic solver or for fe solver when the solver type is not ‘direct’)
- Returns
electrical conductivity, potential field, flux
- Return type
((float, float, float), numpy.ndarray, numpy.ndarray)
- pumapy.material_properties.conductivity.compute_thermal_conductivity(workspace, cond_map, direction, side_bc='p', prescribed_bc=None, tolerance=1e-05, maxiter=10000, solver_type='bicgstab', display_iter=True, method='fv', matrix_free=True)[source]
Compute the thermal conductivity
- Parameters
workspace (pumapy.Workspace) – domain
cond_map (IsotropicConductivityMap or AnisotropicConductivityMap) – local constituents themal conductivities
direction (string) – direction for solve (‘x’,’y’,’z’, or ‘’ for prescribed_bc). If provided, prescribed_bc is ignored
side_bc (string) – side boundary conditions can be symmetric (‘s’) or periodic (‘p’). Only periodic available when method=’fe’
prescribed_bc (pumapy.IsotropicConductivityBC or pumapy.AnisotropicConductivityBC or None) – object holding dirichlet BC, only available for isotropic of MPFA implementations. Need to set direction=’’ in order to provide it. When prescribed_bc is provided, keff is not printed but it is computed as if direction==’x’ for testing purposes.
tolerance (float) – tolerance for iterative solver
maxiter (int) – maximum Iterations for solver
solver_type (string) – solver type, options: ‘bicgstab’ (default), ‘cg’, ‘gmres’, ‘minres’ (only for method=’fe’), ‘direct’
display_iter (bool) – display iterations and residual
method (string) – whether to use finite volume solver (‘fv’, either isotropic solver if IsotropicConductivityMap is passed, or mpfa if AnisotropicConductivityMap) or finite element Q1-Q1 EBE solver (‘fe’). For the latter method, it is recommended to use solver_type=’minres’ as lighter and faster
matrix_free (bool) – if True, then use matrix-free method if possible (only available for fv isotropic solver or for fe solver when the solver type is not ‘direct’)
- Returns
thermal conductivity, temperature field, flux
- Return type
((float, float, float), numpy.ndarray, numpy.ndarray)
- Example
>>> import pumapy as puma >>> ws_fiberform = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif"), 1.3e-6) Importing .../200_fiberform.tif ... Done >>> ws_fiberform.rescale(0.5, segmented=False) Rescaled workspace size: (100, 100, 100) >>> # Conductivity with Isotropic local phases >>> cond_map = puma.IsotropicConductivityMap() >>> cond_map.add_material((0, 89), 0.0257) >>> cond_map.add_material((90, 255), 12) >>> k_eff_x, T_x, q_x = puma.compute_thermal_conductivity(ws_fiberform, cond_map, 'x', 's', matrix_free=True) Approximate memory requirement for simulation... >>> # Conductivity with Anisotropic local phases >>> puma.compute_orientation_st(ws_fiberform, cutoff=(90, 255)) First gradient computation... >>> cond_map = puma.AnisotropicConductivityMap() >>> # conductivity of the void phase to be 0.0257 (air at STP) >>> cond_map.add_isotropic_material((0, 89), 0.0257) >>> # axial fiber conductivity of 12, radial fiber conductivity of 0.7 >>> cond_map.add_material_to_orient((90, 255), 12., 0.7) >>> k_eff_z, T_z, q_z = puma.compute_thermal_conductivity(ws_fiberform, cond_map, 'z', 's') # method='fe' for finite element Approximate memory requirement for simulation... >>> # plot_conductivity_fields(ws, T_z, q_z) # to visualize fields >>> # export_conductivity_fields_vti("path/to/folder", ws, T_z, q_z) # to export fields
- pumapy.material_properties.conductivity.export_conductivity_fields_vti(filepath, workspace, T, q)[source]
Export conductivity fields, as output by the conductivity function
- Parameters
filepath (string) –
workspace (puma.Workspace or numpy.ndarray) – domain
T (numpy.ndarray) – temperature field
q (numpy.ndarray) – flux field
- pumapy.material_properties.conductivity.plot_conductivity_fields(workspace, T, q, show_cbar=True, show_edges=False, xy_view=False, rm_id=None, notebook=False)[source]
Plot the workspace colored by the temperature and flux fields, as output by the conductivity function
- Parameters
workspace (pumapy.Workspace) – domain
T (numpy.ndarray) – temperature field
q (numpy.ndarray) – flux field
show_cbar (bool) – show colorbar in each plot
show_edges (bool) – show edges in mesh
xy_view (bool) – show plot aligned with xy plane
rm_id (float or None) – remove a phase of the material from thresholded mesh
notebook (bool) – plotting interactively in a jupyter notebook (overwrites show_grid to False)
pumapy.material_properties.elasticity
- pumapy.material_properties.elasticity.compute_elasticity(workspace, elast_map, direction, side_bc='p', tolerance=1e-05, maxiter=100000, solver_type='bicgstab', display_iter=True, method='fv', matrix_free=True)[source]
Compute the effective elasticity coefficient
- Parameters
workspace (pumapy.Workspace) – domain
elast_map (pumapy.ElasticityMap) – local elasticity of the constituents
direction (string) – direction for solve (‘x’,’y’, ‘z’, ‘yz’, ‘xz’, ‘xy’)
side_bc (string) – side boundary conditions can be symmetric (‘s’) or periodic (‘p’). Only periodic available when method=’fe’
tolerance – tolerance for iterative solver
maxiter (int) – maximum Iterations for solver
solver_type (string) – solver type, options: ‘bicgstab’ (default), ‘minres’ (only for method=’fe’), ‘gmres’, ‘direct’
display_iter (bool) – display iterations and residual
method (string) – whether to use finite volume solver (‘fv’, i.e. mpsa) or finite element Q1-Q1 EBE solver (‘fe’). For the latter method, it is recommended to use solver_type=’minres’ as lighter and faster
matrix_free (bool) – if True, then use matrix-free method if possible (only available for fe solver when the solver type is not ‘direct’)
- Type
tolerance: float
- Returns
elasticity, displacement field, direct stresses (sigma xx, yy, zz), shear stresses (tau yz, xz, xy)
- Return type
((float, float, float, float, float, float), numpy.ndarray, numpy.ndarray, numpy.ndarray)
- Example
>>> import pumapy as puma >>> ws = puma.Workspace.from_shape_value((20, 20, 20), 1) >>> ws[int(ws.matrix.shape[0] / 2):] = 2 >>> elast_map = puma.experimental.ElasticityMap() >>> elast_map.add_isotropic_material((1, 1), 200, 0.3) >>> elast_map.add_isotropic_material((2, 2), 400, 0.1) >>> C = np.zeros((6, 6)) >>> C[:, 0], u, s, t = puma.experimental.compute_elasticity(ws, elast_map, direction='x', solver_type='direct') Approximate memory requirement for simulation: ... >>> C[:, 1], u, s, t = puma.experimental.compute_elasticity(ws, elast_map, direction='y', solver_type='direct') Approximate memory requirement for simulation: ... >>> C[:, 2], u, s, t = puma.experimental.compute_elasticity(ws, elast_map, direction='z', solver_type='direct') Approximate memory requirement for simulation: ... >>> C[:, 3], u, s, t = puma.experimental.compute_elasticity(ws, elast_map, direction='yz', solver_type='direct') Approximate memory requirement for simulation: ... >>> C[:, 4], u, s, t = puma.experimental.compute_elasticity(ws, elast_map, direction='xz', solver_type='direct') Approximate memory requirement for simulation: ... >>> C[:, 5], u, s, t = puma.experimental.compute_elasticity(ws, elast_map, direction='xy', solver_type='direct') Approximate memory requirement for simulation: ... >>> coeffs = puma.experimental.get_E_nu_from_elasticity(C) E1 ... >>> #puma.plot_elasticity_fields(ws, u, s, t) # to visualize fields >>> #puma.warp_elasticity_fields(ws, u, s, t, 5) # to visualize fields >>> #puma.export_elasticity_fields_vti("path/to/folder", ws, u, s, t) # to export fields >>> C1, u, s, t = puma.experimental.compute_elasticity(ws, elast_map, direction='x', solver_type='direct', method='fe') # finite element solver Approximate memory requirement for simulation: ...
- pumapy.material_properties.elasticity.compute_stress_analysis(workspace, elast_map, prescribed_bc, side_bc='p', tolerance=1e-05, maxiter=100000, solver_type='bicgstab', display_iter=True)[source]
Compute stress analysis based on specific user-input dirichlet boundary conditions
- Parameters
workspace (pumapy.Workspace) – domain
elast_map (pumapy.ElasticityMap) – local elasticity of the constituents
prescribed_bc (pumapy.ElasticityBC) – object holding the elasticity dirichlet boundary conditions
side_bc (string) – side boundary conditions can be symmetric (‘s’) or periodic (‘p’)
tolerance – tolerance for iterative solver
maxiter (int) – maximum Iterations for solver
solver_type (string) – solver type, options: ‘gmres’ (default), ‘bicgstab’, ‘direct’
display_iter (bool) – display iterations and residual
- Type
tolerance: float
- Returns
elasticity, displacement field, direct stresses (sigma xx, yy, zz), shear stresses (tau yz, xz, xy)
- Return type
(numpy.ndarray, numpy.ndarray, numpy.ndarray)
- Example
>>> import pumapy as puma >>> ws = puma.Workspace.from_shape_value((20, 22, 22), 1) >>> ws[ws.matrix.shape[0]//2:] = 2 >>> ws[:, [0, -1]] = 0 >>> ws[:, :, [0, -1]] = 0 >>> elast_map = puma.experimental.ElasticityMap() >>> elast_map.add_isotropic_material((0, 0), 1e-5, 0.3) >>> elast_map.add_isotropic_material((1, 1), 200, 0.3) >>> elast_map.add_isotropic_material((2, 2), 400, 0.1) >>> bc = puma.experimental.ElasticityBC(ws) >>> bc.xfaces[0, :, :, 0] = 0 >>> bc.xfaces[0, :, :, 1] = 0 >>> bc.xfaces[0, :, :, 2] = 0 >>> bc.xfaces[1, :, :, 0] = 0 >>> bc.xfaces[1, :, :, 1] = 1 >>> bc.xfaces[1, :, :, 2] = 0 >>> u, s, t = puma.experimental.compute_stress_analysis(ws, elast_map, bc) Approximate memory requirement for simulation: ... >>> # puma.warp_elasticity_fields(ws[:, 1:-1, 1:-1], u[:, 1:-1, 1:-1], s[:, 1:-1, 1:-1], t[:, 1:-1, 1:-1], 20, show_original=0., show_edges=True) # to visualize
- pumapy.material_properties.elasticity.export_elasticity_fields_vti(filepath, workspace, u, s, t)[source]
Export conductivity fields, as output by the conductivity function
- Parameters
filepath (string) –
workspace (puma.Workspace or numpy.ndarray) – domain
u (numpy.ndarray) – displacement field
s (numpy.ndarray) – direct stress field
t (numpy.ndarray) – shear stress field
- pumapy.material_properties.elasticity.get_E_nu_from_elasticity(C)[source]
Compute Young’s moduli E1, E2, E3, Shear moduli G23, G13, G12, and Poisson’s ratios nu23, nu13, nu12 for an orthotropic material from its symmetric elastic stiffness tensor
- Parameters
C (np.ndarray) – 6x6 elasticity tensor
- Returns
Young’s moduli E1, E2, E3, Shear moduli G23, G13, G12, and Poisson’s ratios nu23, nu13, nu12
- Return type
(float, float, float, float, float, float, float, float, float)
- pumapy.material_properties.elasticity.plot_elasticity_fields(workspace, u, s, t, show_cbar=True, show_edges=False, xy_view=False, rm_id=None, notebook=False)[source]
Plot the workspace according to the displacement and stress fields output by the elasticity functions
- Parameters
workspace (pumapy.Workspace) – domain
u (numpy.ndarray) – displacement field
s (numpy.ndarray) – direct stress field
t (numpy.ndarray) – shear stress field
show_cbar (bool) – show colorbar in each plot
show_edges (bool) – show edges in mesh
xy_view (bool) – show plot aligned with xy plane
rm_id (float or None) – remove a phase of the material from thresholded mesh
notebook (bool) – plotting interactively in a jupyter notebook (overwrites show_grid to False)
- pumapy.material_properties.elasticity.remove_rbms(workspace, void_id, direction)[source]
Remove Rigid Body Movements (RBMs), i.e. unconnected or “floating” voxels, in a segmented domain along a specified direction
- Parameters
workspace (pumapy.Workspace) – domain
void_id (int) – specify the void ID to discard from RBMs identification
direction (str) – Cartesian direction that has to be connected, options: ‘x’, ‘y’, ‘z’
- Returns
workspace without the possible RBMs determined by not being connected from side to side N.B. The output workspace is segmented into 0=void, 1=solid
- Return type
pumapy.Workspace
- Example
>>> import pumapy as puma >>> workspace = puma.import_3Dtiff(puma.path_to_example_file("100_fiberform.tif")) Importing ... >>> workspace.binarize(103) >>> new_ws = puma.experimental.remove_rbms(workspace, void_id=0, direction='y') >>> # puma.render_volume(workspace, (1, 1), solid_color=(255, 255, 255)) # to visualize before and after >>> # puma.render_volume(new_ws, (1, new_ws.max()), solid_color=(255, 255, 255))
- pumapy.material_properties.elasticity.warp_elasticity_fields(workspace, u, s, t, scale_factor=1, show_original=0.0, show_cbar=True, show_edges=False, xy_view=False, rm_id=None, show_axes=True, notebook=False)[source]
Warp the workspace according to the displacement field output by the elasticity functions, and colored by displacement and stress components
- Parameters
workspace (pumapy.Workspace) – domain
u (numpy.ndarray) – displacement field
s (numpy.ndarray) – direct stress field
t (numpy.ndarray) – shear stress field
scale_factor (float) – scaling factor for warp
show_original (float) – opacity of the original workspace before warp
show_cbar (bool) – show colorbar in each plot
show_edges (bool) – show edges in mesh
xy_view (bool) – show plot aligned with xy plane
rm_id (float or None) – remove a phase of the material from warped mesh (only works for 2D slice)
show_axes (float) – show the axes and side dimensions
notebook (bool) – plotting interactively in a jupyter notebook (overwrites show_grid to False)
pumapy.material_properties.mean_intercept_length
- pumapy.material_properties.mean_intercept_length.compute_mean_intercept_length(workspace, void_cutoff)[source]
Computation of the mean intercept length
- Parameters
workspace (pumapy.Workspace) – domain
void_cutoff ((int, int)) – specify the void or gaseous phase of the domain
- Returns
mean intercept length in x,y,z
- Return type
(float, float, float)
- Example
>>> import pumapy as puma >>> ws = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif"), 1.3e-6) Importing ... >>> mil = puma.compute_mean_intercept_length(ws, (0, 89))
pumapy.material_properties.orientation
Further explained in publication: Semeraro, F., Ferguson, J.C., Panerai, F., King, R.J. and Mansour, N.N., 2020. Anisotropic analysis of fibrous and woven materials part 1: Estimation of local orientation. Computational Materials Science, 178, p.109631. (https://www.sciencedirect.com/science/article/abs/pii/S0927025620301221)
- class pumapy.material_properties.orientation.OrientationST(ws, sigma, rho, cutoff, edt)[source]
Bases:
object
- pumapy.material_properties.orientation.compute_angular_differences(matrix, orientation1, orientation2, cutoff)[source]
Compute angular difference between two orientation ndarrays
- Parameters
matrix (np.ndarray) – domain matrix
orientation1 (np.ndarray) – orientation as (x, y, z, 3)
orientation2 (np.ndarray) – orientation as (x, y, z, 3)
cutoff ((int, int)) – to binarize domain
- Returns
angle_errors in degrees, mean, std
- Return type
(np.ndarray, float, float)
- pumapy.material_properties.orientation.compute_orientation_st(ws, cutoff, sigma=0.7, rho=1.4, edt=False)[source]
Compute orientation of the material by the structure tensor algorithm
- Parameters
ws (pumapy.Workspace) – domain
cutoff ((int, int)) – which grayscales to consider
sigma (float) – kernel size parameter for Gaussian derivatives (should be lower than rho)
rho (float) – kernel size parameter for Gaussian filter of derivatives of grayscales (should be higher than sigma)
edt (bool) – indicating if we need to apply Euclidean Distance Transform before computing ST
- Returns
True if successful, False otherwise.
- Return type
bool
- Example
>>> import pumapy as puma >>> import pyvista as pv >>> ws = puma.import_3Dtiff(puma.path_to_example_file("100_fiberform.tif"), 1.3e-6) # import example file Importing ... >>> puma.compute_orientation_st(ws, cutoff=(90, 255), sigma=0.7, rho=1.4) # compute orientation First gradient computation ... >>> # p = pv.Plotter(shape=(1, 2)) # to visualize the orientation field >>> # p.subplot(0, 0) >>> # p.add_text("Microstructure") >>> # puma.render_contour(ws, (90, 255), add_to_plot=p, plot_directly=False) >>> # p.subplot(0, 1) >>> # p.add_text("Detected fiber orientation") >>> # puma.render_orientation(ws, add_to_plot=p, plot_directly=False) >>> # p.show() # to visualize it
pumapy.material_properties.permeability
The following FE numerical method and implementation are based on the following research paper:
Lopes, P.C., Vianna, R.S., Sapucaia, V.W., Semeraro, F., Leiderman, R. and Pereira, A.M., 2023. Simulation toolkit for digital material characterization of large image-based microstructures. Computational Materials Science, 219, p.112021. (https://www.sciencedirect.com/science/article/pii/S0927025623000150)
- pumapy.material_properties.permeability.compute_permeability(workspace, solid_cutoff, direction='xyz', tol=1e-08, maxiter=10000, solver_type='minres', display_iter=True, matrix_free=True, precondition=False, output_fields=True)[source]
Compute the permeability using first-order Q1-Q1 Finite Element solver and periodic BC on the sides.
Note: the iterative solvers have been observed to struggle converging for some cases. This is often connected to having the preconditioner option as True.
- Parameters
workspace (pumapy.Workspace) – domain
solid_cutoff ((int, int)) – specify the solid phase
direction (str) – direction for solve (‘xyz’,’x’,’y’,’z’). Note that if solver_type=”direct”, then the direction is considered as “xyz” automatically because there is no need to invert the A sparse matrix multiple times
tol (float) – tolerance for iterative solver
maxiter (int) – maximum Iterations for solver
solver_type (string) – solver type, options: ‘minres’ (default, only works if precondition=False), ‘cg’, ‘direct’
display_iter (bool) – display iteration in iterative solver
matrix_free (bool) – solve system using matrix-free method (True, recommended) or building the sparse A matrix (False)
precondition (bool) – solve system with Jacobi preconditioner (True) or without (False, default because it reduces memory, but more iterations. The default minres iterative solver does not support this kind of preconditioner)
output_fields (bool) – export velocity and pressure fields (True, default) or not (False, lower memory)
- Returns
effective permeability (3x3 matrix) and, if output_fields=True, the normalized velocity field for the corresponding direction (arranged as tuple of numpy.ndarrays, i.e. (ux, uy, uz). If output_fields=False, then (None, None, None) is output
- Return type
numpy.ndarray, (numpy.ndarray, numpy.ndarray, numpy.ndarray)
- Example
>>> import pumapy as puma >>> import pyvista as pv >>> ws = puma.generate_random_fibers_transverseisotropic(shape=(50, 50, 50), radius=2, porosity=0.7, direction='x', variation=15, length=200, allow_intersect=True, segmented=True) Fibers created... >>> keff, (ux, _, _) = puma.compute_permeability(ws, (1, ws.max()), direction='x', tol=1e-7) Approximate memory requirement for simulation: ... >>> # p = pv.Plotter() # to visualize it >>> # puma.render_orientation(ux, add_to_plot=p, scale_factor=2e12, plot_directly=False) >>> # ws.voxel_length = 1 # the voxel_length is converted to 1 for plotting the workspace together with the velocity >>> # puma.render_volume(ws, cutoff=(1, ws.max()), add_to_plot=p, plot_directly=False, cmap='jet') >>> # p.show()
pumapy.material_properties.radiation
- class pumapy.material_properties.radiation.Radiation(workspace, void_cutoff, sources_number, particles_number, boundary_behavior, bin_density, export_plot)[source]
Bases:
object
- pumapy.material_properties.radiation.compute_extinction_coefficients(ws, rays_distances, sources_number, particles_number, bin_density=10000, export_pathname=None)[source]
Compute the extinction coefficient based on the ray casting radiation simulation (this is normally a step inside the compute_radiation function)
- Parameters
ws (pumapy.Workspace) – domain
rays_distances (np.ndarray) – rays distances, as output by compute_radiation function
sources_number (int) – number of light sources spread randomly in the void space (i.e. 0)
degree_accuracy (int) – angle difference between rays emitted in degrees (has to be an exact divider of 180°)
bin_density (int) – number of bins used to create histogram of ray distances
export_pathname (str) – path to save curve plot of ray distance distribution
- Returns
extinction coefficient (beta), its standard deviation
- Return type
(float, float)
- pumapy.material_properties.radiation.compute_radiation(workspace, void_cutoff, sources_number, particles_number, boundary_behavior=1, bin_density=10000, export_pathname=None)[source]
Compute the radiative thermal conductivity through ray tracing (N.B. 0 material ID in workspace refers to gas phases unless otherwise specified)
- Parameters
workspace (pumapy.Workspace) – domain
void_cutoff ((int, int)) – specify the void phase
sources_number (int) – number of light sources spread randomly in the void space (i.e. 0)
particles_number (int) – number of particles emitted at each source point
boundary_behavior (int) – how to treat particles exiting the domain: 0=kill, 1=periodic (default)
bin_density (int) – number of bins used to create histogram of ray distances
export_pathname (str) – path to save curve plot of ray distance distribution
- Returns
extinction coefficient (beta), its standard deviation and of ray distances
- Return type
(float, float, np.ndarray)
- Example
>>> import pumapy as puma >>> ws_fiberform = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif"), 0.65e-6) Importing ... >>> beta, beta_std, rays_distances = puma.experimental.compute_radiation(ws_fiberform, (0, 89), 100, 500) Number of particles in Ray Tracing simulation...
pumapy.material_properties.surface_area
- class pumapy.material_properties.surface_area.SurfaceArea(workspace, cutoff, flag_gaussian)[source]
Bases:
object
- pumapy.material_properties.surface_area.compute_surface_area(workspace, cutoff, flag_gaussian=False)[source]
Computation of the surface area based on isosurface
- Parameters
workspace (pumapy.Workspace) – domain
cutoff ((int, int)) – specify the solid phase
flag_gaussian (bool) – apply Gaussian filter before generating surface
- Returns
area, specific_area
- Return type
(float, float)
- Example
>>> import pumapy as puma >>> ws = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif"), 1.3e-6) # import workspace Importing ... >>> area, specific_area = puma.compute_surface_area(ws, cutoff=(90, 255)) # computing surface area
pumapy.material_properties.tortuosity
- pumapy.material_properties.tortuosity.compute_continuum_tortuosity(workspace, cutoff, direction, side_bc='p', prescribed_bc=None, tolerance=0.0001, maxiter=10000, solver_type='cg', display_iter=True, matrix_free=True)[source]
Compute the tortuosity modelling the local conductivity as isotropic
- Parameters
workspace (pumapy.Workspace) – domain
cutoff ((int, int)) – cutoff to binarize domain specifying the void phase
direction (string) – direction for solve (‘x’,’y’, or ‘z’)
side_bc (string) – side boundary conditions (string) can be symmetric (‘s’), periodic (‘p’) or dirichlet (‘d’)
prescribed_bc (pumapy.IsotropicConductivityBC or None) – 3D array holding dirichlet BC
tolerance (float) – tolerance for iterative solver
maxiter (int) – maximum Iterations for solver
solver_type (string) – solver type, options: ‘cg’ (default), ‘bicgstab’, ‘direct’
display_iter (bool) – display iterations and residual
matrix_free (bool) – if True, then use matrix-free method
- Returns
tortuosity, diffusivity, porosity, concentration field
- Return type
((float, float, float), float, float, numpy.ndarray)
- Example
>>> import pumapy as puma >>> ws_fiberform = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif"), 1.3e-6) Importing ... >>> n_eff_x, Deff_x, poro, C_x = puma.compute_continuum_tortuosity(ws_fiberform, (0, 89), 'x', side_bc='s', tolerance=1e-4) Approximate memory requirement for simulation...
pumapy.material_properties.volume_fraction
- class pumapy.material_properties.volume_fraction.VolumeFraction(workspace, cutoff, display)[source]
Bases:
object
- pumapy.material_properties.volume_fraction.compute_volume_fraction(workspace, cutoff, display=True)[source]
Compute the volume fraction
- Parameters
workspace (pumapy.Workspace or np.ndarray) – domain
cutoff ((int, int)) – to binarize domain
display (bool) – print result
- Returns
volume fraction
- Return type
float
- Example
>>> import pumapy as puma >>> ws = puma.import_3Dtiff(puma.path_to_example_file("100_fiberform.tif"), 1.3e-6) # import example file Importing ... >>> vf = puma.compute_volume_fraction(ws, cutoff=(90, 255)) # compute volume fraction Volume Fraction for cutoff ...
pumapy.physics_models.finite_element
pumapy.physics_models.finite_element.fe_conductivity
The following FE numerical method and implementation are based on the following research paper:
Lopes, P.C., Vianna, R.S., Sapucaia, V.W., Semeraro, F., Leiderman, R. and Pereira, A.M., 2023. Simulation toolkit for digital material characterization of large image-based microstructures. Computational Materials Science, 219, p.112021. (https://www.sciencedirect.com/science/article/pii/S0927025623000150)
- class pumapy.physics_models.finite_element.fe_conductivity.ConductivityFE(workspace, cond_map, direction, tolerance, maxiter, solver_type, display_iter, matrix_free)[source]
Bases:
pumapy.physics_models.utils.linear_solvers.PropertySolver
pumapy.physics_models.finite_element.fe_elasticity
The following FE numerical method and implementation are based on the following research paper:
Lopes, P.C., Vianna, R.S., Sapucaia, V.W., Semeraro, F., Leiderman, R. and Pereira, A.M., 2023. Simulation toolkit for digital material characterization of large image-based microstructures. Computational Materials Science, 219, p.112021. (https://www.sciencedirect.com/science/article/pii/S0927025623000150)
- class pumapy.physics_models.finite_element.fe_elasticity.ElasticityFE(workspace, elast_map, direction, tolerance, maxiter, solver_type, display_iter, matrix_free)[source]
Bases:
pumapy.physics_models.utils.linear_solvers.PropertySolver
pumapy.physics_models.finite_element.fe_permeability
The following FE numerical method and implementation are based on the following research paper:
Lopes, P.C., Vianna, R.S., Sapucaia, V.W., Semeraro, F., Leiderman, R. and Pereira, A.M., 2023. Simulation toolkit for digital material characterization of large image-based microstructures. Computational Materials Science, 219, p.112021. (https://www.sciencedirect.com/science/article/pii/S0927025623000150)
- class pumapy.physics_models.finite_element.fe_permeability.Permeability(workspace, solid_cutoff, direction, tolerance, maxiter, solver_type, display_iter, matrix_free, preconditioner, output_fields)[source]
Bases:
pumapy.physics_models.utils.linear_solvers.PropertySolver
pumapy.physics_models.finite_volume
pumapy.physics_models.finite_volume.anisotropic_conductivity_utils
- pumapy.physics_models.finite_volume.anisotropic_conductivity_utils.assign_prescribed_bc_cy(not_dir_x, not_dir_y, not_dir_z, Td, dirichlet_bc_xfaces, dirichlet_bc_yfaces, dirichlet_bc_zfaces, len_x, len_y, len_z, i_iv)
- pumapy.physics_models.finite_volume.anisotropic_conductivity_utils.create_Ab_indices_cy(I_A, J_A, I_b, counter_A, counter_b, i_cv, len_x, len_y, len_z, len_xyz, side_bc)
- pumapy.physics_models.finite_volume.anisotropic_conductivity_utils.create_T_ivs_cy(T, tf, i_cv, len_x, len_y, len_z, len_xyz, side_bc, t_sw, t_se, t_nw, t_ne, t_tsw, t_tse, t_tnw, t_tne)
- pumapy.physics_models.finite_volume.anisotropic_conductivity_utils.index_at_p(index, size)
- pumapy.physics_models.finite_volume.anisotropic_conductivity_utils.index_at_s(index, size)
pumapy.physics_models.finite_volume.anisotropic_conductivity_utils
- pumapy.physics_models.finite_volume.anisotropic_conductivity_utils.assign_prescribed_bc_cy(not_dir_x, not_dir_y, not_dir_z, Td, dirichlet_bc_xfaces, dirichlet_bc_yfaces, dirichlet_bc_zfaces, len_x, len_y, len_z, i_iv)
- pumapy.physics_models.finite_volume.anisotropic_conductivity_utils.create_Ab_indices_cy(I_A, J_A, I_b, counter_A, counter_b, i_cv, len_x, len_y, len_z, len_xyz, side_bc)
- pumapy.physics_models.finite_volume.anisotropic_conductivity_utils.create_T_ivs_cy(T, tf, i_cv, len_x, len_y, len_z, len_xyz, side_bc, t_sw, t_se, t_nw, t_ne, t_tsw, t_tse, t_tnw, t_tne)
- pumapy.physics_models.finite_volume.anisotropic_conductivity_utils.index_at_p(index, size)
- pumapy.physics_models.finite_volume.anisotropic_conductivity_utils.index_at_s(index, size)
pumapy.physics_models.finite_volume.elasticity_utils
- pumapy.physics_models.finite_volume.elasticity_utils.assign_prescribed_bc_cy(not_dir_x, not_dir_y, not_dir_z, Dd, dirichlet_bc_xfaces, dirichlet_bc_yfaces, dirichlet_bc_zfaces, len_x, len_y, len_z, i_iv)
- pumapy.physics_models.finite_volume.elasticity_utils.create_Ab_indices_cy(I_A, J_A, I_b, counter_A, counter_b, i_cv, len_x, len_y, len_z, len_xyz, side_bc)
- pumapy.physics_models.finite_volume.elasticity_utils.create_u_ivs_cy(u, uf, i_cv, len_x, len_y, len_z, len_xyz, side_bc, u_sw, u_se, u_nw, u_ne, u_tsw, u_tse, u_tnw, u_tne)
- pumapy.physics_models.finite_volume.elasticity_utils.index_at_p(index, size)
- pumapy.physics_models.finite_volume.elasticity_utils.index_at_p_pad(index, size)
- pumapy.physics_models.finite_volume.elasticity_utils.index_at_s(index, size)
- pumapy.physics_models.finite_volume.elasticity_utils.index_at_s_pad(index, size)
- pumapy.physics_models.finite_volume.elasticity_utils.pad_domain_cy(ws_pad, orient_pad, need_to_orient, len_x, len_y, len_z, side_bc)
pumapy.physics_models.finite_volume.elasticity_utils
- pumapy.physics_models.finite_volume.elasticity_utils.assign_prescribed_bc_cy(not_dir_x, not_dir_y, not_dir_z, Dd, dirichlet_bc_xfaces, dirichlet_bc_yfaces, dirichlet_bc_zfaces, len_x, len_y, len_z, i_iv)
- pumapy.physics_models.finite_volume.elasticity_utils.create_Ab_indices_cy(I_A, J_A, I_b, counter_A, counter_b, i_cv, len_x, len_y, len_z, len_xyz, side_bc)
- pumapy.physics_models.finite_volume.elasticity_utils.create_u_ivs_cy(u, uf, i_cv, len_x, len_y, len_z, len_xyz, side_bc, u_sw, u_se, u_nw, u_ne, u_tsw, u_tse, u_tnw, u_tne)
- pumapy.physics_models.finite_volume.elasticity_utils.index_at_p(index, size)
- pumapy.physics_models.finite_volume.elasticity_utils.index_at_p_pad(index, size)
- pumapy.physics_models.finite_volume.elasticity_utils.index_at_s(index, size)
- pumapy.physics_models.finite_volume.elasticity_utils.index_at_s_pad(index, size)
- pumapy.physics_models.finite_volume.elasticity_utils.pad_domain_cy(ws_pad, orient_pad, need_to_orient, len_x, len_y, len_z, side_bc)
pumapy.physics_models.finite_volume.isotropic_conductivity
- class pumapy.physics_models.finite_volume.isotropic_conductivity.IsotropicConductivity(workspace, cond_map, direction, side_bc, prescribed_bc, tolerance, maxiter, solver_type, display_iter, matrix_free)[source]
Bases:
pumapy.physics_models.utils.linear_solvers.PropertySolver
pumapy.physics_models.finite_volume.isotropic_conductivity_utils
- pumapy.physics_models.finite_volume.isotropic_conductivity_utils.compute_flux(T, cond, l_x, l_y, l_z)
- pumapy.physics_models.finite_volume.isotropic_conductivity_utils.index_at_p(i, j, k, len_x, len_y, len_z)
- pumapy.physics_models.finite_volume.isotropic_conductivity_utils.index_at_s(i, j, k, len_x, len_y, len_z)
- pumapy.physics_models.finite_volume.isotropic_conductivity_utils.setup_matrices_cy(_kf, l_x, l_y, l_z, domain_bc_check, bc_check, prescribed_bc, side_bc)
pumapy.physics_models.finite_volume.isotropic_conductivity_utils
- pumapy.physics_models.finite_volume.isotropic_conductivity_utils.compute_flux(T, cond, l_x, l_y, l_z)
- pumapy.physics_models.finite_volume.isotropic_conductivity_utils.index_at_p(i, j, k, len_x, len_y, len_z)
- pumapy.physics_models.finite_volume.isotropic_conductivity_utils.index_at_s(i, j, k, len_x, len_y, len_z)
- pumapy.physics_models.finite_volume.isotropic_conductivity_utils.setup_matrices_cy(_kf, l_x, l_y, l_z, domain_bc_check, bc_check, prescribed_bc, side_bc)
pumapy.physics_models.finite_volume.mpfa_conductivity
Further explained in publication: Semeraro, F., Ferguson, J.C., Acin, M., Panerai, F. and Mansour, N.N., 2021. Anisotropic analysis of fibrous and woven materials part 2: Computation of effective conductivity. Computational Materials Science, 186, p.109956. https://www.sciencedirect.com/science/article/abs/pii/S092702562030447X
- class pumapy.physics_models.finite_volume.mpfa_conductivity.AnisotropicConductivity(workspace, cond_map, direction, side_bc, dirichlet_bc, tolerance, maxiter, solver_type, display_iter)[source]
Bases:
pumapy.physics_models.utils.linear_solvers.PropertySolver
pumapy.physics_models.finite_volume.mpsa_elasticity
- class pumapy.physics_models.finite_volume.mpsa_elasticity.Elasticity(workspace, elast_map, direction, side_bc, tolerance, maxiter, solver_type, display_iter, dirichlet_bc)[source]
Bases:
pumapy.physics_models.utils.linear_solvers.PropertySolver
pumapy.physics_models.finite_volume.mpxa_matrices
matrices used in MPFA and MPSA functions
- pumapy.physics_models.finite_volume.mpxa_matrices.div_Ed_mpfa(q_sw, q_se, q_nw, q_ne, q_tsw, q_tse, q_tnw, q_tne)[source]
- pumapy.physics_models.finite_volume.mpxa_matrices.div_Ed_mpsa(s_sw, s_se, s_nw, s_ne, s_tsw, s_tse, s_tnw, s_tne)[source]
- pumapy.physics_models.finite_volume.mpxa_matrices.div_Eu_mpfa(E_sw, E_se, E_nw, E_ne, E_tsw, E_tse, E_tnw, E_tne)[source]
pumapy.physics_models.particle
pumapy.physics_models.particle.raycasting
pumapy.physics_models
pumapy.physics_models.utils
pumapy.physics_models.utils.boundary_conditions
- class pumapy.physics_models.utils.boundary_conditions.AnisotropicConductivityBC(workspace)[source]
Bases:
object
pumapy.physics_models.utils.linear_solvers
pumapy.physics_models.utils.property_maps
- class pumapy.physics_models.utils.property_maps.AnisotropicConductivityMap[source]
Bases:
pumapy.physics_models.utils.property_maps.MaterialPropertyMap
- class pumapy.physics_models.utils.property_maps.ElasticityMap[source]
Bases:
pumapy.physics_models.utils.property_maps.MaterialPropertyMap
- class pumapy.physics_models.utils.property_maps.IsotropicConductivityMap[source]
Bases:
pumapy.physics_models.utils.property_maps.MaterialPropertyMap
pumapy
Copyright @ 2017, 2020, 2021 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved. This software may be used, reproduced, and provided to others only as permitted under the terms of the agreement under which it was acquired from the U.S. Government. Neither title to, nor ownership of, the software is hereby transferred. This notice shall remain on all copies of the software. This file is available under the terms of the NASA Open Source Agreement (NOSA), and further subject to the additional disclaimer below: Disclaimer: THE SOFTWARE AND/OR TECHNICAL DATA ARE PROVIDED “AS IS” WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SOFTWARE AND/OR TECHNICAL DATA WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT THE SOFTWARE AND/OR TECHNICAL DATA WILL BE ERROR FREE, OR ANY WARRANTY THAT TECHNICAL DATA, IF PROVIDED, WILL CONFORM TO THE SOFTWARE. IN NO EVENT SHALL THE UNITED STATES GOVERNMENT, OR ITS CONTRACTORS OR SUBCONTRACTORS, BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE AND/OR TECHNICAL DATA, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE AND/OR TECHNICAL DATA. THE UNITED STATES GOVERNMENT DISCLAIMS ALL WARRANTIES AND LIABILITIES REGARDING THIRD PARTY COMPUTER SOFTWARE, DATA, OR DOCUMENTATION, IF SAID THIRD PARTY COMPUTER SOFTWARE, DATA, OR DOCUMENTATION IS PRESENT IN THE NASA SOFTWARE AND/OR TECHNICAL DATA, AND DISTRIBUTES IT “AS IS.” RECIPIENT AGREES TO WAIVE ANY AND ALL CLAIMS AGAINST THE UNITED STATES GOVERNMENT AND ITS CONTRACTORS AND SUBCONTRACTORS, AND SHALL INDEMNIFY AND HOLD HARMLESS THE UNITED STATES GOVERNMENT AND ITS CONTRACTORS AND SUBCONTRACTORS FOR ANY LIABILITIES, DEMANDS, DAMAGES, EXPENSES OR LOSSES THAT MAY ARISE FROM RECIPIENT’S USE OF THE SOFTWARE AND/OR TECHNICAL DATA, INCLUDING ANY DAMAGES FROM PRODUCTS BASED ON, OR RESULTING FROM, THE USE THEREOF. IF RECIPIENT FURTHER RELEASES OR DISTRIBUTES THE NASA SOFTWARE AND/OR TECHNICAL DATA, RECIPIENT AGREES TO OBTAIN THIS IDENTICAL WAIVER OF CLAIMS, INDEMNIFICATION AND HOLD HARMLESS, AGREEMENT WITH ANY ENTITIES THAT ARE PROVIDED WITH THE SOFTWARE AND/OR TECHNICAL DATA.
Root directory for the pumapy package. Please refer to this publication for a detailed software architecture explanation:
- @article{ferguson2021update,
title={Update 3.0 to “puma: The porous microstructure analysis software”,(pii: s2352711018300281)}, author={Ferguson, Joseph C and Semeraro, Federico and Thornton, John M and Panerai, Francesco and Borner, Arnaud and Mansour, Nagi N}, journal={SoftwareX}, volume={15}, pages={100775}, year={2021}, publisher={Elsevier}
}
pumapy.segmentation
pumapy.segmentation.ccl
Functions to relying on Connected Component Labeling (CCL)
- pumapy.segmentation.ccl.fill_closed_pores(workspace, solid_cutoff, fill_value, return_pores=False)[source]
Identify the porespace and fill closed porosity
- Parameters
workspace (pumapy.Workspace) – domain
solid_cutoff ((int, int)) – specify the solid range to discard from pores identification
fill_value (int) – value to fill closed porosity with
return_pores (bool) – specifies whether to return identified pores
- Returns
filled workspace with IDs set as: 0 for void, 1 for solid, fill_value for added filler material. In addition, if return_pores==True, then it also returns the porespace marked as: 0 solid, 1 largest pore (likely open porosity), >1 other pores
- Return type
pumapy.Workspace
- Example
>>> import pumapy as puma >>> ws = puma.generate_random_spheres((100, 100, 100), diameter=20, porosity=0.8, allow_intersect=True, segmented=False) Approximately ... spheres to be generated... >>> # puma.render_volume(ws[:ws.matrix.shape[0] // 2]) # to visualize workspace >>> ws.binarize_range((1, 250)) >>> # puma.render_volume(ws[:ws.matrix.shape[0] // 2]) >>> filled_ws, pores = puma.fill_closed_pores(ws, (1, 1), fill_value=2, return_pores=True) >>> # puma.render_volume(pores, cutoff=(0, pores.max()), cmap='jet') # to visualize pores
- pumapy.segmentation.ccl.identify_porespace(workspace, solid_cutoff, connectivity=None)[source]
Identify the porespace
- Parameters
workspace (pumapy.Workspace) – domain
solid_cutoff ((int, int)) – specify the solid range to discard from pores identification
connectivity (int or None) – Maximum number of orthogonal hops to consider a pixel/voxel as a neighbor (None automatically gives full connectivity of
input.ndim
, which for 3D domain is 3, for 2D is 2)
- Returns
porespace marked as: 0 solid, 1 largest pore (likely open porosity), >1 other pores
- Return type
np.ndarray
- Example
>>> import pumapy as puma >>> ws = puma.generate_sphere((100, 100, 100), (50, 50, 50), 40, segmented=False) Generated in... >>> ws.binarize_range((1, 253)) >>> # puma.render_volume(ws[:ws.matrix.shape[0] // 2], cutoff=(0, 255)) # to visualize workspace >>> pores = puma.identify_porespace(ws, (1, 1)) >>> # puma.render_volume(pores[:pores.shape[0] // 2], cutoff=(0, pores.max())) # to visualize pores
pumapy.utilities
pumapy.utilities.example_files
- pumapy.utilities.example_files.list_example_files()[source]
List all example files available inside the folder python/pumapy/data
- Returns
List of example file names
- Return type
list
- pumapy.utilities.example_files.path_to_example_file(example_filename)[source]
Path to example data that is installed with pumapy (used for testing and tutorial)
- Parameters
example_filename (str) – name of the example file (check python/pumapy/data for a list of example files)
- Returns
path to the example file, which can be used to import it
- Return type
str
- Example
>>> import pumapy as puma >>> ws_example = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif")) # import example file Importing ... >>> # puma.plot_slices(ws_example) # visualize example file
pumapy.utilities.generic_checks
- pumapy.utilities.generic_checks.estimate_max_memory(material_property, workspace_shape, solver_type='iterative', need_to_orient=False, mf=True, perm_fluid_vf=1.0)[source]
Compute an estimate of the extra maximum memory required to run a specified material property on a domain
- Parameters
material_property (string) – property to estimate, options: ‘anisotropic_conductivity’, ‘isotropic_conductivity’, ‘tortuosity’, ‘elasticity’, ‘permeability’
workspace_shape ((int, int, int)) – size of the domain to compute
solver_type (string) – type of solver, options: ‘direct’, ‘iterative’
need_to_orient (bool) – domain with orientation (needed for anisotropic conductivity and elasticity)
mf (bool) – using matrix-free construction of the system (needed for FE methods)
- Returns
number of Bytes
- Return type
int
- pumapy.utilities.generic_checks.set_random_seed(seed)[source]
Set random seed for scipy and numpy to make results reproducible. NB: if you want to generate the same material twice in the same process, you need to call it twice (see example)
- Parameters
seed (int) – random seed
- Example
>>> import pumapy as puma >>> puma.set_random_seed(1) >>> ws = puma.generate_random_spheres((100, 100, 100), 20, 0.5, allow_intersect=True, segmented=False) Approximately ... spheres to be generated... >>> # puma.render_volume(ws) # to visualize it >>> puma.set_random_seed(1) # need to call it again to get the same domain! >>> ws = puma.generate_random_spheres((100, 100, 100), 20, 0.5, allow_intersect=True, segmented=False) Approximately ... spheres to be generated... >>> # puma.render_volume(ws)
pumapy.utilities.isosurface
- class pumapy.utilities.isosurface.Isosurface(workspace, cutoff, flag_closed_edges, flag_gaussian)[source]
Bases:
object
- pumapy.utilities.isosurface.generate_isosurface(workspace, cutoff, flag_closed_edges=True, flag_gaussian=False)[source]
Generation of isosurface based on cutoff provided
- Parameters
workspace (pumapy.Workspace or numpy.ndarray) – domain
cutoff ((int, int)) – specify cutoff to binarize material
flag_closed_edges (bool) – close edges of surfaces on the boundaries
flag_gaussian (bool) – apply Gaussian filter before generating surface
- Returns
triangulated surface
- Return type
pumapy.utilities.logger
- class pumapy.utilities.logger.Colors[source]
Bases:
object
- BOLD = '\x1b[1m'
- ENDC = '\x1b[0m'
- FAIL = '\x1b[91m'
- HEADER = '\x1b[95m'
- OKBLUE = '\x1b[94m'
- OKCYAN = '\x1b[96m'
- OKGREEN = '\x1b[92m'
- UNDERLINE = '\x1b[4m'
- WARNING = '\x1b[93m'
pumapy.utilities.timer
pumapy.utilities.workspace
- class pumapy.utilities.workspace.Workspace(**kwargs)[source]
Bases:
object
- apply_mask(mask, apply_to_orientation=False)[source]
Apply mask of same size as the matrix by leaving the mask’s 1s unchanged and setting mask’s 0s to 0
- Parameters
mask (np.ndarray) – array of type bool with same size as matrix
apply_to_orientation (bool) – specifying whether the mask is to be applied to the orientation (if present)
- Returns
None
- Example
>>> import pumapy as puma >>> ws = puma.Workspace.from_shape_value_vector((10, 10, 10), 1, (0.4, 2, 5)) >>> mask = np.random.randint(255, size=(10, 10, 10)) > 100 >>> ws.apply_mask(mask, apply_to_orientation=True) >>> # puma.render_volume(ws, style='edges') # to visualize it
- binarize(threshold)[source]
Binarize the workspace according to threshold, inclusive for higher range set to 1, lower to 0
- Parameters
threshold (int) – grayscale value dividing the domain into 0s and 1s (threshold turns into 1)
- Returns
None
- Example
>>> import pumapy as puma >>> ws_fiberform = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif"), 1.3e-6) Importing ... >>> ws2 = ws_fiberform.copy() >>> ws2.binarize(100) >>> # puma.compare_slices(ws_fiberform, ws2) # to visualize it
- binarize_range(ones_cutoff)[source]
Binarize the workspace according to range within cutoff, inclusive for cutoff ints set to 1, rest to 0
- Parameters
ones_cutoff ((int, int)) – convert a range of grayscale values specified by the cutoff into 1s, rest into 0s
- Returns
None
- Example
>>> import pumapy as puma >>> ws_fiberform = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif"), 1.3e-6) Importing ... >>> ws2 = ws_fiberform.copy() >>> ws2.binarize_range((100, 255)) >>> # puma.compare_slices(ws_fiberform, ws2) # to visualize it
- copy()[source]
Create a copy of the workspace
- Returns
copy of workspace
- Return type
pumapy.Workspace
- create_orientation()[source]
Create orientation field of the same size as the matrix
- Returns
None
- Example
>>> import pumapy as puma >>> ws = puma.Workspace.from_shape((10, 10, 10)) >>> ws.create_orientation()
- classmethod from_array(nparray)[source]
Generate workspace matrix from numpy array.
- Parameters
nparray (np.ndarray) – array of shape (X,Y,Z) to be assigned to the matrix variable. NB: array is turned into type uint16
- Returns
new workspace
- Return type
pumapy.Workspace
- Example
>>> import pumapy as puma >>> array = np.random.randint(5, size=(10, 10, 10)) >>> ws = puma.Workspace.from_array(array) >>> # puma.render_volume(ws, style='edges') # to visualize it
- classmethod from_shape(shape, orientation=False)[source]
Generate workspace from shape, all matrix value set to zero.
- Parameters
shape ((int, int, int)) – shape of workspace to be created
orientation (bool) – specify if workspace contains orientation
- Returns
new workspace
- Return type
pumapy.Workspace
- Example
>>> import pumapy as puma >>> ws = puma.Workspace.from_shape((10, 11, 12)) >>> # puma.render_volume(ws, style='edges') # to visualize it
- classmethod from_shape_value(shape, value, orientation=False)[source]
Generate workspace from shape, all matrix values set to the value passed.
- Parameters
shape ((int, int, int)) – shape of workspace to be created
value (int) – value to be assigned to the matrix variable
orientation (bool) – specify if workspace contains orientation
- Returns
new workspace
- Return type
pumapy.Workspace
- Example
>>> import pumapy as puma >>> ws = puma.Workspace.from_shape_value((20, 31, 212), 1) >>> # puma.render_volume(ws, style='edges') # to visualize it
- classmethod from_shape_value_vector(shape, value, vector)[source]
Generate workspace from shape, all matrix and orientation set to the values passed.
- Parameters
shape ((int, int, int)) – shape of workspace to be created
value (int) – value to be assigned to the matrix variable
vector ((float, float, float)) – vector to be assigned to the orientation variable
- Returns
new workspace with orientation
- Return type
pumapy.Workspace
- Example
>>> import pumapy as puma >>> ws = puma.Workspace.from_shape_value_vector((5, 6, 2), 1, (0.4, 2, 5)) >>> # puma.render_orientation(ws) # to visualize it
- classmethod from_shape_vector(shape, vector)[source]
Generate workspace from shape, all orientation vectors set to the vector passed.
- Parameters
shape ((int, int, int)) – shape of workspace to be created
vector ((float, float, float)) – vector to be assigned to the orientation variable
- Returns
new workspace with orientation
- Return type
pumapy.Workspace
- Example
>>> import pumapy as puma >>> ws = puma.Workspace.from_shape_vector((5, 6, 2), (0.4, 2, 5)) >>> # puma.render_orientation(ws) # to visualize it
- get_shape()[source]
Return shape of domain
- Returns
shape of domain (matrix)
- Return type
(int, int, int)
- orientation_magnitude()[source]
Return orientation vector’s magnitude
- Returns
orientation field magnitude
- Return type
np.ndarray
- porosity(cutoff=(0, 0), display=False)[source]
Compute porosity of domain
- Parameters
cutoff ((int, int)) – void cutoff
display (bool) – print result
- Returns
volume fraction
- Return type
float
- Example
>>> import pumapy as puma >>> ws = puma.import_3Dtiff(puma.path_to_example_file("100_fiberform.tif"), 1.3e-6) Importing ... >>> ws.porosity(cutoff=(0, 89), display=True) Volume Fraction for cutoff (0, 89): ...
- rescale(scale, segmented, anti_aliasing=True, interpolation_order=1)[source]
Rescale both matrix and orientation (if present) by rescaling the content by a specified factor
- Parameters
scale (float) – specifying the scaling factor
segmented (bool) – specifying whether the domain is already segmented (True) or grayscales (False)
anti_aliasing (bool) – if aliasing is to be prevented applying a Gaussian filter to smooth before scaling. If domain is segmented, automatically set to False in order to preserve domain
interpolation_order (int) – order of the interpolation spline used. For segmented, it is enforced to be 0, which is ‘nearest neighbor’ to preserve the segmentation
- Returns
None
- Example
>>> import pumapy as puma >>> ws_fiberform = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif"), 1.3e-6) Importing ... >>> ws2 = ws_fiberform.copy() >>> ws2.rescale(0.5, segmented=False) Rescaled workspace size: (100, 100, 100) >>> # puma.compare_slices(ws_fiberform, ws2) # to visualize it, pay attention to the shape
- resize(shape, segmented, anti_aliasing=True, interpolation_order=1)[source]
Resize both matrix and orientation (if present) by rescaling the content to specified size
- Parameters
shape ((int, int, int)) – shape of workspace to be resized
segmented (bool) – specifying whether the domain is already segmented (True) or grayscales (False)
anti_aliasing (bool) – if aliasing is to be prevented applying a Gaussian filter to smooth before scaling. If domain is segmented, automatically set to False in order to preserve domain
interpolation_order (int) – order of the interpolation spline used. For segmented, it is enforced to be 0,which is ‘nearest neighbor’ to preserve the segmentation
- Returns
None
- Example
>>> import pumapy as puma >>> ws_fiberform = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif"), 1.3e-6) Importing ... >>> ws2 = ws_fiberform.copy() >>> ws2.resize((100, 200, 200), segmented=False) >>> # puma.compare_slices(ws_fiberform, ws2) # to visualize it
- resize_new_matrix(shape, value=None)[source]
Resize matrix numpy array
- Parameters
shape ((int, int, int)) – shape of workspace to be resized
value (int) – value to be assigned to the new resized matrix variable
- Example
>>> import pumapy as puma >>> ws = puma.Workspace() >>> ws.resize_new_matrix((10, 10, 10), value=3) >>> # puma.render_volume(ws, style='edges') # to visualize it
- resize_new_orientation(shape, orientation_value=None)[source]
Resize orientation numpy array
- Parameters
shape ((int, int, int)) – shape of workspace to be resized
orientation_value ((float, float, float)) – vector to be assigned to the new resized orientation variable
- Example
>>> import pumapy as puma >>> ws = puma.Workspace() >>> ws.resize_new_orientation((10, 10, 10), orientation_value=(1., 0., 0.)) >>> # puma.render_orientation(ws) # to visualize it
- rotate(degrees, around_axis, reshape=True, boundary_mode='reflect', apply_to_orientation=True)[source]
Rotate domain by specified degrees
- Parameters
degrees (float) – degrees to rotate domain
around_axis (string) – specify around what axis to perform the rotation. It can be ‘x’, ‘y’ or ‘z’
reshape (bool) – specify whether to reshape the domain (and therefore contain every voxel - reshape=True) or keep its original size (reshape=False)
boundary_mode (string) – specifying what to do with the boundaries. Options: ‘reflect’, ‘constant’, ‘nearest’, ‘mirror’, ‘wrap’
apply_to_orientation (bool) – specify whether to apply rotation to the orientation, if present
- Returns
None
- Example
>>> import pumapy as puma >>> ws_fiberform = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif"), 1.3e-6) Importing ... >>> ws_copy = ws_fiberform.copy() >>> ws_copy.rotate(45, 'z', reshape=False, boundary_mode='reflect') >>> # puma.compare_slices(ws_fiberform, ws_copy) # to visualize it >>> ws_copy = ws_fiberform.copy() >>> ws_copy.rotate(45, 'z', reshape=True, boundary_mode='constant') >>> # puma.compare_slices(ws_fiberform, ws_copy) # to visualize it >>> ws_copy = ws_fiberform.copy() >>> ws_copy.rotate(45, 'z', reshape=True, boundary_mode='reflect') >>> # puma.compare_slices(ws_fiberform, ws_copy) # to visualize it
- set(matrix_value=None, orientation_value=None)[source]
Set all elements in matrix equal to value (and orientation to vectorvalue is passed)
- Parameters
matrix_value (int) – value to fill to the matrix variable. NB this value will be turned into np.uint16
orientation_value (((float, float, float))) – vector to fill to the orientation variable
- Returns
None
- Example
>>> import pumapy as puma >>> ws = puma.Workspace.from_shape_value((10, 10, 10), 5) >>> ws.set(matrix_value=4)
- set_material_id(cutoff, value)[source]
Threshold the workspace according to cutoff (i.e. tuple with inclusive range to set)
- Parameters
cutoff ((int, int)) – convert a range of grayscale values specified by the cutoff into an single ID number
value (int) – ID number to assign to range
- Returns
None
- Example
>>> import pumapy as puma >>> ws_fiberform = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif"), 1.3e-6) Importing ... >>> ws2 = ws_fiberform.copy() >>> ws2.set_material_id((0, 100), 0) # NB the order of these operations is important! >>> ws2.set_material_id((100, 255), 1) # this is why binarize and binarize_range should be preferred >>> # puma.compare_slices(ws_fiberform, ws2) # to visualize it
- set_matrix(nparray)[source]
Set matrix with numpy array
- Parameters
nparray (np.ndarray) – array of shape (X,Y,Z) to be assigned to the matrix variable
- Returns
None
- Example
>>> import pumapy as puma >>> ws = puma.Workspace() >>> nparray = np.random.randint(5, size=(10, 10, 10)) >>> ws.set_matrix(nparray) # equivalent to ws.matrix = nparray.copy().astype(np.uint16) >>> # puma.render_volume(ws, style='edges') # to visualize it
- set_orientation(nparray)[source]
Set orientation with numpy array
- Parameters
nparray (np.ndarray) – array of shape (X,Y,Z, 3) to be assigned to the orientation variable
- Returns
None
- Example
>>> import pumapy as puma >>> ws = puma.Workspace() >>> ws.set_orientation(np.random.rand(10, 10, 10, 3)) >>> # puma.render_orientation(ws, solid_color=None) # to visualize it
- set_voxel_length(voxel_length)[source]
Set voxel size, which by default is set to 1e-6
- Parameters
voxel_length (float) – size of a voxel side
- Returns
None
- Example
>>> import pumapy as puma >>> array = np.random.randint(5, size=(10, 10, 10)) >>> ws = puma.Workspace.from_array(array) >>> ws.set_voxel_length(1) # equivalent to ws.voxel_length = 1 >>> # puma.render_volume(ws, style='edges') # to visualize it
pumapy.visualization
pumapy.visualization.render
- class pumapy.visualization.render.Renderer(existing_plot=None, filter_type=None, workspace=None, cutoff=None, solid_color=None, style=None, origin=None, window_size=None, opacity=None, background=None, show_grid=None, plot_directly=None, show_axes=None, show_outline=None, cmap=None, scale_factor=None, notebook=None, sampling=None)[source]
Bases:
object
- pumapy.visualization.render.render_contour(workspace, cutoff, solid_color=(255, 255, 255), style='surface', origin=(0.0, 0.0, 0.0), window_size=(1920, 1200), opacity=1.0, background=(0.3, 0.3, 0.3), show_grid=True, plot_directly=True, show_axes=True, show_outline=True, add_to_plot=None, notebook=False)[source]
Contour render using Pyvista Contour filter
- Parameters
workspace (Workspace or np.ndarray) – domain
cutoff ((int, int)) – specifying the values at which the isosurface is created
solid_color ((int, int, int)) – a solid color to color the surface (e.g. for white (255, 255, 255))
style (string) – specifying the representation style (‘surface’, ‘edges’, ‘wireframe’, ‘points’)
origin ((float, float, float)) – origin of the data as
window_size ((int, int)) – with the popup window size
opacity (float) – opacity of contour
background – color of the background from (0., 0., 0.) (black) to (1., 1., 1.) (white)
show_grid (bool) – show the grid with the size of the sides
plot_directly (bool) – whether to return a Plotter object (to make further changes to it) or show the plot directly
show_axes (bool) – show orientation axis in the bottom left corner
show_outline (bool) – show the bounding box outline of the domain
add_to_plot (pyvista.Plotter or None) – pass an already existing plotter object to add on top of this plot
notebook (bool) – plotting interactively in a jupyter notebook (overwrites show_grid to False)
- Type
background: (float, float, float)
- Returns
None is plot_directly is True, otherwise a plotter object
- Return type
pyvista.Plotter or None
- Example
>>> import pumapy as puma >>> ws_contour = puma.import_3Dtiff(puma.path_to_example_file("50_artfibers.tif")) Importing ... >>> # puma.render_contour(ws_contour, (128,255)) # to visualize it
- pumapy.visualization.render.render_contour_multiphase(workspace, cutoffs, solid_colors=None, style='surface', origin=(0.0, 0.0, 0.0), window_size=(1920, 1200), opacity=1.0, background=(0.3, 0.3, 0.3), show_grid=True, plot_directly=True, show_axes=True, show_outline=True, add_to_plot=None, notebook=False)[source]
Contour render for multi-phase materials using Pyvista
- Parameters
workspace (Workspace or ndarray) – domain
cutoffs (tuple) – n cutoffs is the number of materials. specifies the low and high cutoff ranges
solid_colors (tuple or None) – solid colors to color the different phases’ surface e.g. for white ((255, 255, 255), (0, 0, 0), …)
style (string) – specifying the representation style (‘surface’, ‘edges’, ‘wireframe’, ‘points’)
origin ((float, float, float)) – origin of the data as
window_size ((int, int)) – with the popup window size
opacity (float) – opacity of contour
background – color of the background from (0., 0., 0.) (black) to (1., 1., 1.) (white)
show_grid (bool) – show the grid with the size of the sides
plot_directly (bool) – whether to return a Plotter object (to make further changes to it) or show the plot directly
show_axes (bool) – show orientation axis in the bottom left corner
show_outline (bool) – show the bounding box outline of the domain
add_to_plot (pyvista.Plotter or None) – pass an already existing plotter object to add on top of this plot
notebook (bool) – plotting interactively in a jupyter notebook (overwrites show_grid to False)
- Type
background: (float, float, float)
- Returns
None is plot_directly is True, otherwise a plotter object
- Return type
pyvista.Plotter or None
- Example
>>> import pumapy as puma >>> ws_multiphase = puma.import_3Dtiff(puma.path_to_example_file("100_fiberform.tif"), 1.3e-6) Importing ... >>> # puma.render_contour_multiphase(ws_multiphase, ((100, 150), (150, 255))) # to visualize it
- pumapy.visualization.render.render_orientation(workspace, scale_factor=1.0, solid_color=None, style='surface', origin=(0.0, 0.0, 0.0), window_size=(1920, 1200), opacity=1.0, background=(0.3, 0.3, 0.3), show_grid=True, cmap=None, plot_directly=True, show_axes=True, show_outline=True, add_to_plot=None, notebook=False, sampling=None)[source]
Orientation render using Pyvista Glyph filter
- Parameters
workspace (Workspace or np.ndarray) – domain
scale_factor (float) – scale the arrows by a factor
solid_color (None or (int, int, int) or str) – a solid color for the arrows. Deafult is None, which colors the vectors by their magnitude. To color white, input set solid_color=(255, 255, 255)
style (string) – specifying the representation style (‘surface’, ‘edges’, ‘wireframe’, ‘points’)
origin ((float, float, float)) – origin of the data as
window_size ((int, int)) – with the popup window size
opacity (float) – opacity of arrows
background – color of the background from (0., 0., 0.) (black) to (1., 1., 1.) (white)
show_grid (bool) – show the grid with the size of the sides
cmap (str or None) – matplotlib colormap to use (overwritten by solid_color if specified)
plot_directly (bool) – whether to return a Plotter object (to make further changes to it) or show the plot directly
show_axes (bool) – show orientation axis in the bottom left corner
show_outline (bool) – show the bounding box outline of the domain
add_to_plot (pyvista.Plotter or None) – pass an already existing plotter object to add on top of this plot
notebook (bool) – plotting interactively in a jupyter notebook (overwrites show_grid to False)
sampling (int or None) – number of arrows to sample (None means plot an arrow at each voxel)
- Type
background: (float, float, float)
- Returns
None is plot_directly is True, otherwise a plotter object
- Return type
pyvista.Plotter or None
- Example
>>> import pumapy as puma >>> ws_orientation = puma.import_3Dtiff(puma.path_to_example_file("100_fiberform.tif"), 1.3e-6) Importing ... >>> puma.compute_orientation_st(ws_orientation, (90, 255)) First gradient computation ... >>> # puma.render_orientation(ws_orientation) # to visualize it
- pumapy.visualization.render.render_volume(workspace, cutoff=None, solid_color=None, style='surface', origin=(0.0, 0.0, 0.0), window_size=(1920, 1200), opacity=1.0, background=(0.3, 0.3, 0.3), show_grid=True, plot_directly=True, show_axes=True, show_outline=True, cmap='gray', add_to_plot=None, notebook=False)[source]
Volume render using Pyvista Threshold filter
- Parameters
workspace (Workspace or np.ndarray) – domain
cutoff ((int, int) or (float, float) or None) – specifying the values to render
solid_color ((int, int, int) or None) – if set to None (default), the material is colored by the matrix’s values. Otherwise, a solid color can be specified (e.g. for white (255, 255, 255))
style (string) – specifying the representation style (‘surface’, ‘edges’, ‘wireframe’, ‘points’)
origin ((float, float, float)) – origin of the data as
window_size ((int, int)) – with the popup window size
opacity (float) – opacity of volume
background – color of the background from (0., 0., 0.) (black) to (1., 1., 1.) (white)
show_grid (bool) – show the grid with the size of the sides
plot_directly (bool) – whether to return a Plotter object (to make further changes to it) or show the plot directly
show_axes (bool) – show orientation axis in the bottom left corner
show_outline (bool) – show the bounding box outline of the domain
cmap (str) – matplotlib colormap to use (overwritten by solid_color if specified)
add_to_plot (pyvista.Plotter or None) – pass an already existing plotter object to add on top of this plot
notebook (bool) – plotting interactively in a jupyter notebook (overwrites show_grid to False)
- Type
background: (float, float, float)
- Returns
None is plot_directly is True, otherwise a plotter object
- Return type
pyvista.Plotter or None
- Example
>>> import pumapy as puma >>> ws_volume = puma.import_3Dtiff(puma.path_to_example_file("200_fiberform.tif"), 1.3e-6) Importing ... >>> # puma.render_volume(ws_volume) # to visualize it
- pumapy.visualization.render.render_warp(workspace, scale_factor=1.0, color_by='magnitude', style='surface', origin=(0.0, 0.0, 0.0), window_size=(1920, 1200), opacity=1.0, background=(0.3, 0.3, 0.3), show_grid=True, cmap='jet', plot_directly=True, show_axes=True, show_outline=True, add_to_plot=None, notebook=False)[source]
Warp a domain by an orientation field
- Parameters
workspace (Workspace) – domain with both matrix and orientation defined
scale_factor (float) – scale the orientation by a factor
color_by (str) – it can be ‘magnitude’, which colors warped domain by magnitude of vectors, or ‘x’, ‘y’ or ‘z’, which colors it by the orientation component, or ‘matrix’, which colors it by the matrix phases
style (string) – specifying the representation style (‘surface’, ‘edges’, ‘wireframe’, ‘points’)
origin ((float, float, float)) – origin of the data as
window_size ((int, int)) – with the popup window size
opacity (float) – opacity of arrows
background – color of the background from (0., 0., 0.) (black) to (1., 1., 1.) (white)
show_grid (bool) – show the grid with the size of the sides
cmap (str) – matplotlib colormap to use
plot_directly (bool) – whether to return a Plotter object (to make further changes to it) or show the plot directly
show_axes (bool) – show orientation axis in the bottom left corner
show_outline (bool) – show the bounding box outline of the domain
add_to_plot (pyvista.Plotter or None) – pass an already existing plotter object to add on top of this plot
notebook (bool) – plotting interactively in a jupyter notebook (overwrites show_grid to False)
- Type
background: (float, float, float)
- Returns
None is plot_directly is True, otherwise a plotter object
- Return type
pyvista.Plotter or None
- Example
>>> import pumapy as puma >>> import numpy as np >>> dim = 50 >>> ws = puma.generate_cylinder_square_array(dim, 0.44) Generated in: ... >>> ws.matrix = np.repeat(ws.matrix, 5, axis=2) >>> #puma.render_volume(ws) # to visualize it >>> mat_elast = puma.experimental.ElasticityMap() >>> mat_elast.add_isotropic_material((0, 0), 68.3, 0.3) >>> mat_elast.add_isotropic_material((1, 1), 379.3, 0.1) >>> C = np.zeros((6, 6)) >>> C[:, 0], u, s, t = puma.experimental.compute_elasticity(ws, mat_elast, direction='x', side_bc='p', solver_type="bicgstab") Approximate memory requirement for simulation: ... >>> #puma.experimental.warp_elasticity_fields(ws, u, s, t, scale_factor=10, xy_view=True) # to visualize it
pumapy.visualization.slicer
- class pumapy.visualization.slicer.CompareSlicer(img1, img2, slice_direction, color_range1, color_map1, color_range2, color_map2, index, axis_labels, slices1, slices2, rows1, cols1, rows2, cols2)[source]
- class pumapy.visualization.slicer.IndexTracker(img, img2, slice_direction, index, axis_labels, slices, slices_titles)[source]
Bases:
object
- class pumapy.visualization.slicer.PlotSlicer(img, slice_direction, color_range, color_map, index, axis_labels, slices, rows, cols)[source]
- pumapy.visualization.slicer.compare_slices(ws_nparray1, ws_nparray2, slice_direction='z', crange1=None, cmap1='gray', crange2=None, cmap2='gray', index=1)[source]
Plot slices of domain along a specified direction (z default)
- Parameters
ws_nparray1 (Workspace or np.ndarray) – domain
ws_nparray2 (Workspace or np.ndarray) – domain
slice_direction (string) – ‘x’, ‘y’, ‘z’
crange1 ((int, int)) – color range for plot 1, specify min and max grayscale
cmap1 (string) – color map for plot 1, ‘gray’ (default), ‘jet’ or refer to matplotlib for other colormaps
crange2 ((int, int)) – color range for plot 2, specify min and max grayscale
cmap2 (string) – color map for plot 2, ‘gray’ (default), ‘jet’ or refer to matplotlib for other colormaps
index (int) – specifying the slice index in which the plot will be opened
- Returns
slicer object
- Return type
>>> import pumapy as puma >>> ws = puma.import_3Dtiff(puma.path_to_example_file("100_fiberform.tif"), 1.3e-6) Importing ... >>> ws2 = ws.copy() >>> ws2.binarize_range((100, 255)) >>> #puma.compare_slices(ws, ws2) # to visualize it
- pumapy.visualization.slicer.plot_slices(ws_nparray, slice_direction='z', crange=None, cmap='gray', index=1)[source]
Plot slices of domain along a specified direction (z default)
- Parameters
ws_nparray (Workspace or np.ndarray) – domain
slice_direction (string) – ‘x’, ‘y’, ‘z’
crange ((int, int) or None) – color range, i.e. specify min and max grayscale
cmap (string) – color map for the plot, ‘gray’ (default), ‘jet’ or refer to matplotlib for other colormaps
index – specifying the slice index in which the plot will be opened
- Type
int
- Returns
slicer object
- Return type
>>> import pumapy as puma >>> ws = puma.import_3Dtiff(puma.path_to_example_file("100_fiberform.tif"), 1.3e-6) Importing ... >>> #puma.plot_slices(ws) # to visualize it