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
[01:04:32] 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/a7881832e50cf554f2af7e07ed766d1a689228febea26367bd2e1744281c9196.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/000cd46088c93456e5fbf181ac463672fa76eef6b3e0b5ca137c4dc6780adb16.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/031c16605168ec2e7de225697ad43174318a956ef1d6eb7f330178fa1e826f2f.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/69e4bd5c1ca8dd489c2e7247c96ace9780dfff2399f9e67208ab0ff653db3047.png