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))