overlapping_spheres#

Generates overlapping spheres by inserting random points then dilating them to the specified radius.

import matplotlib.pyplot as plt
import numpy as np
import porespy as ps
[17:46:28] ERROR    PARDISO solver not installed, run `pip install pypardiso`. Otherwise,          _workspace.py:56
                    simulations will be slow. Apple M chips not supported.                                         

Print the function argument and default values:

import inspect
print(inspect.signature(ps.generators.overlapping_spheres))
(shape: List[int], r: int = 5, porosity: float = 0.5, maxiter: int = 10, tol: float = 0.01, seed: int = None)

radius#

Controls the size of the spheres:

fig, ax = plt.subplots(1, 2, figsize=[8, 4])

shape = [200, 200]
e = 0.6
r = 10
im1 = ps.generators.overlapping_spheres(shape=shape, r=r, porosity=e)
ax[0].imshow(im1)
ax[0].axis(False)
ax[0].set_title(f'radius = {r}')

r = 20
im2 = ps.generators.overlapping_spheres(shape=shape, r=r, porosity=e)
ax[1].imshow(im2)
ax[1].axis(False)
ax[1].set_title(f'radius = {r}');
../../../_images/65f33f07840955de7dfc2e39789ee8af13289dd1ac55a906ea4f2f39e7418819.png

porosity#

The number of spheres added is adjusted by meet the requested porosity:

fig, ax = plt.subplots(1, 2, figsize=[8, 4])

r = 10
e = 0.8
im1 = ps.generators.overlapping_spheres(shape=shape, r=r, porosity=e)
ax[0].imshow(im1)
ax[0].axis(False)
ax[0].set_title(f'porosity = {e}')

e = 0.4
im2 = ps.generators.overlapping_spheres(shape=shape, r=r, porosity=e)
ax[1].imshow(im2)
ax[1].axis(False)
ax[1].set_title(f'porosity = {e}');
../../../_images/fdc4dd488503f90d89971e0e6a8d58177d0a6a8faaee6e03773b9df4d1371172.png

max_iter#

Because the spheres overlap randomly, it’s not possible to match the desired porosity perfect so a trial and error approach is used. This parameters control the maximum number of iterations used to match the desired porosity within the specified tolerance.

fig, ax = plt.subplots(1, 2, figsize=[8, 4])
print('target porosity =', e)

np.random.seed(0)
mi = 1
im1 = ps.generators.overlapping_spheres(shape=shape, r=r, porosity=e, maxiter=mi)
ax[0].imshow(im1)
ax[0].axis(False)
ax[0].set_title(f'maxiter = {mi}')
print('porosity = ', ps.metrics.porosity(im1))

np.random.seed(0)
mi = 10
im2 = ps.generators.overlapping_spheres(shape=shape, r=r, porosity=e, maxiter=mi)
ax[1].imshow(im2)
ax[1].axis(False)
ax[1].set_title(f'maxiter = {mi}');
print('porosity = ', ps.metrics.porosity(im2))
target porosity = 0.4
porosity =  0.26175
porosity =  0.406125
../../../_images/43c4b1444ba0b90c5976ebc79fe25109c09390343885938a9c4e410b9f3f8fee.png

tol#

Tolerance for porosity relative to input value. If requesting a porosity of 0.5, then tol=0.1 will halt the iteration once the porosity is within 10% of the desired value, so between 0.45 and 0.55. Note that the procedure may also stop early if maxiter is reached first.

fig, ax = plt.subplots(1, 2, figsize=[8, 4])
print('target porosity =', e)

np.random.seed(0)
t = 1e-2
mi=100
im1 = ps.generators.overlapping_spheres(shape=shape, r=r, porosity=e, maxiter=mi, tol=t)
ax[0].imshow(im1)
ax[0].axis(False)
ax[0].set_title(f'tol = {t}')
print('porosity = ', ps.metrics.porosity(im1))

np.random.seed(0)
t = 1e-4
im2 = ps.generators.overlapping_spheres(shape=shape, r=r, porosity=e, maxiter=mi, tol=t)
ax[1].imshow(im2)
ax[1].axis(False)
ax[1].set_title(f'tol = {t}');
print('porosity = ', ps.metrics.porosity(im2))
target porosity = 0.4
porosity =  0.406125
porosity =  0.400225
../../../_images/821ab92d6fec5360f2328b11c69df3025358968a647972a394be9f04a1a3f737.png