Source code for porespy.simulations.__Porosimetry__

import scipy as sp
from porespy.filters import porosimetry
import matplotlib.pyplot as plt
from collections import namedtuple


[docs]class Porosimetry(object): r""" Simulates a porosimetry experiment on a binary image. This function is equivalent to the morphological image opening and/or the full morphology approaches. Parameters ---------- im : ND-array The Boolean image of the porous material, with True values indicating the pore space """ def __init__(self, im, voxel_size=1,): self.im = im self.voxel_size = voxel_size def _get_result(self): if not hasattr(self, '_result'): print('Simulation has not been run, wait while result is computed') self.run() return self._result result = property(fget=_get_result)
[docs] def run(self, npts=25, sizes=None, inlets=None, access_limited=True): temp = porosimetry(im=self.im, npts=npts, sizes=sizes, inlets=inlets, access_limited=access_limited) self._result = temp return temp
run.__doc__ = porosimetry.__doc__
[docs] def plot_drainage_curve(self, fig=None, **kwargs): r""" """ d = self.get_drainage_data() if fig is None: fig = plt.figure() ax = fig.add_subplot(111) else: try: ax = fig.get_axes()[0] finally: ax = fig.get_axes() ax.plot(d.radius, d.saturation, **kwargs) return fig
[docs] def plot_size_histogram(self, fig=None, **kwargs): r""" """ if fig is None: fig = plt.figure() ax = fig.add_subplot(111) else: ax = fig.get_axes()[0] ax.hist(self.result.flatten(), bins=sp.unique(self.result)[1:]) fig.xlabel('Radius of Invading Sphere') fig.ylabel('Number of Invaded Voxels') return fig
[docs] def get_drainage_data(self): r""" Calculate drainage curve based on the image produced by the ``porosimetry`` function. Returns ------- Rp, Snwp: Two arrays containing (a) the radius of the penetrating sphere (in voxels) and (b) the volume fraction of pore phase voxels that are accessible from the specfied inlets. Notes ----- This function normalizes the invading phase saturation by total pore volume of the dry image, which is assumed to be all voxels with a value equal to 1. To do porosimetry on images with large outer regions, use the ```find_outer_region``` function then set these regions to 0 in the input image. In future, this function could be adapted to apply this check by default. """ im = self.result sizes = sp.unique(im) R = [] Snwp = [] Vp = sp.sum(im > 0) for r in sizes[1:]: R.append(r) Snwp.append(sp.sum(im >= r)) Snwp = [s/Vp for s in Snwp] data = namedtuple('xy_data', ('radius', 'saturation')) return data(R, Snwp)