# rsa#

This function implements ‘random sequential addition’ of spheres. The main benefit of this approach is that sphere overlap can be prevented or controlled. The downside is that the function is a bit on the slow side, though efforts have been made to accelerate it using numba jit.

[1]:

import porespy as ps
import matplotlib.pyplot as plt
import numpy as np

[2]:

import inspect
b = inspect.signature(ps.generators.rsa)
print(b)

(im_or_shape: <built-in function array>, r: int, volume_fraction: int = 1, clearance: int = 0, n_max: int = 100000, mode: str = 'contained', return_spheres: bool = False, smooth: bool = True)


## im_or_shape#

The function can either add spheres an existing image, or create a new image of the given shape and spheres to that. Let’s start with an empty image, and set the void fraction to a low value:

[3]:

shape = [300, 300]
r = 15
im = ps.generators.rsa(im_or_shape=shape, r=r)
fig, ax = plt.subplots(1, 1, figsize=[4, 4])
ax.axis(False)
ax.imshow(im, origin='lower', interpolation='none');


Now let’s fill up the remaining space with as many smaller spheres as possible:

[4]:

r = 5
im = ps.generators.rsa(im_or_shape=im, r=r)
fig, ax = plt.subplots(1, 1, figsize=[4, 4])
ax.axis(False)
ax.imshow(im, origin='lower', interpolation='none');


## mode#

Spheres can either be fully contained within the image or be truncated at the edges by specifying mode:

[5]:

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

r = 20
mode = 'contained'
im1 = ps.generators.rsa(im_or_shape=shape, r=r, mode=mode)
ax[0].imshow(im1, origin='lower', interpolation='none')
ax[0].axis(False)
ax[0].set_title(f'mode = {mode}')

mode = 'extended'
im2 = ps.generators.rsa(im_or_shape=shape, r=r, mode=mode)
ax[1].imshow(im2, origin='lower', interpolation='none')
ax[1].axis(False)
ax[1].set_title(f'mode = {mode}');


## clearance#

Spheres can be made to partially overlap, the so called ‘cherry pit’ model, or to have some clearance:

[6]:

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

c = -4
im1 = ps.generators.rsa(im_or_shape=shape, r=r, clearance=c)
ax[0].imshow(im1, origin='lower', interpolation='none')
ax[0].axis(False)
ax[0].set_title(f'clearance = {c}')

c = 4
im2 = ps.generators.rsa(im_or_shape=shape, r=r, clearance=c)
ax[1].imshow(im2, origin='lower', interpolation='none')
ax[1].axis(False)
ax[1].set_title(f'clearance = {c}');


When adding additional spheres to an existing image, the clearance only applies to new spheres. To enforce clearance between the existing spheres you can dilate them by the amount of clearance desired (or erode them if overlap is desired). In this case you’ll want to set return_sphers=True to obtain an image of only the new spheres, which can be added to the original ones:

[7]:

im3 = ps.filters.fftmorphology(im=im2, strel=ps.tools.ps_disk(5), mode='dilation')
im4 = ps.generators.RSA(im_or_shape=im3, r=5, clearance=5, return_spheres=True)
im5 = im2 + im4
fig, ax = plt.subplots(1, 3, figsize=[10, 4])
ax[0].imshow(im2, origin='lower', interpolation='none')
ax[1].imshow(im4, origin='lower', interpolation='none')
ax[2].imshow(im5, origin='lower', interpolation='none');

/tmp/ipykernel_9089/2892074603.py:2: DeprecationWarning: Call to deprecated function (or staticmethod) RSA. (This function has been renamed to rsa (lowercase to meet pep8)
im4 = ps.generators.RSA(im_or_shape=im3, r=5, clearance=5, return_spheres=True)


## volume_fraction and n_max#

By default it will try to insert as many spheres as possible. This can be controlled by setting the volume fraction or limiting the number of spheres inserted:

[8]:

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

n_max = 5
im1 = ps.generators.rsa(shape, r=r, clearance=c, n_max=n_max)
ax[0].imshow(im1, origin='lower', interpolation='none')
ax[0].axis(False)
ax[0].set_title(f'n_max = {n_max}')

vf = 0.2
im2 = ps.generators.rsa(shape, r=r, clearance=c, volume_fraction=vf)
ax[1].axis(False)
ax[1].set_title(f'volume_fraction = {vf}')
ax[1].imshow(im2, origin='lower', interpolation='none');


Note that this function returns the spheres as True which usually indicates the pore phase in porespy, so these will treated as images of holes. If you intended to make an image of sphers, just invert the image:

[9]:

im1 = ~im1
im2 = ~im2
fig, ax = plt.subplots(1, 2, figsize=[8, 4])
ax[0].imshow(im1, origin='lower', interpolation='none')
ax[0].axis(False)
ax[1].imshow(im2, origin='lower', interpolation='none')
ax[1].axis(False);