From b0a62a36d311fe0da31aab06ced4a5b65359f70e Mon Sep 17 00:00:00 2001 From: SlAzeez Date: Wed, 7 Sep 2022 15:24:51 -0400 Subject: [PATCH] Adding initial files --- porespy/metrics/_funcs.py | 51 ++++++++++----------------------------- porespy/tools/_funcs.py | 21 ++++++++++++++++ 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/porespy/metrics/_funcs.py b/porespy/metrics/_funcs.py index 422915cc9..84771343e 100644 --- a/porespy/metrics/_funcs.py +++ b/porespy/metrics/_funcs.py @@ -4,7 +4,7 @@ from scipy import fft as sp_ft from skimage.measure import regionprops from deprecated import deprecated -from porespy.tools import extend_slice +from porespy.tools import extend_slice, extend_slice_2 from porespy.tools import _check_for_singleton_axes from porespy.tools import Results from porespy import settings @@ -13,8 +13,7 @@ from numba import njit tqdm = get_tqdm() - -def representative_elementary_volume(im, npoints=1000): +def representative_elementary_volume_porosity(im, AR=([1,1,1]), npoints=1000): r""" Calculates the porosity of an image as a function subdomain size. @@ -25,6 +24,9 @@ def representative_elementary_volume(im, npoints=1000): ---------- im : ndarray The image of the porous material + AR : (,3) array + This is the aspect ratio of the subdomain. Each element is the ratio to the x-axis. + AR = ([x:x.y:x,z:x]). The default is 1:1:1 to get a cubic shape. npoints : int The number of randomly located and sized boxes to sample. The default is 1000. @@ -38,30 +40,12 @@ def representative_elementary_volume(im, npoints=1000): The total volume of each cubic subdomain tested 'porosity' The porosity of each subdomain tested - - These attributes can be conveniently plotted by passing the Results - object to matplotlib's ``plot`` function using the - \* notation: ``plt.plot(\*result, 'b.')``. The resulting plot is - similar to the sketch given by Bachmat and Bear [1]_ - - Notes - ----- - This function is frustratingly slow. Profiling indicates that all the time - is spent on scipy's ``sum`` function which is needed to sum the number of - void voxels (1's) in each subdomain. - References ---------- .. [1] Bachmat and Bear. On the Concept and Size of a Representative Elementary Volume (Rev), Advances in Transport Phenomena in Porous Media (1987) - Examples - -------- - `Click here - `_ - to view online example. - """ # TODO: this function is a prime target for parallelization since the # ``npoints`` are calculated independenlty. @@ -76,7 +60,7 @@ def representative_elementary_volume(im, npoints=1000): for i in tqdm(np.arange(0, N), **settings.tqdm): s = slices[i] p = pads[i] - new_s = extend_slice(s, shape=im.shape, pad=p) + new_s = extend_slice_2(s, AR, shape=im.shape, pad=p) temp = im[new_s] Vp = np.sum(temp) Vt = np.size(temp) @@ -87,7 +71,6 @@ def representative_elementary_volume(im, npoints=1000): profile.porosity = porosity return profile - def porosity(im): r""" Calculates the porosity of an image assuming 1's are void space and 0's @@ -646,12 +629,8 @@ def _radial_profile(autocorr, bins, pf=None, voxel_size=1): else: raise Exception('Image dimensions must be 2 or 3') if np.max(bins) > np.max(dt): - msg = ( - 'Bins specified distances exceeding maximum radial distance for' - ' image size. Radial distance cannot exceed distance from center' - ' of image to corner.' - ) - raise Exception(msg) + raise Exception('Bins specified distances exceeding maximum radial distance for image size. \n' + 'Radial distance cannot exceed distance from center of image to corner.') bin_size = bins[1:] - bins[:-1] radial_sum = _get_radial_sum(dt, bins, bin_size, autocorr) @@ -670,7 +649,6 @@ def _radial_profile(autocorr, bins, pf=None, voxel_size=1): tpcf.relfreq = h.relfreq return tpcf - @njit(parallel=True) def _get_radial_sum(dt, bins, bin_size, autocorr): radial_sum = np.zeros_like(bins[:-1]) @@ -679,7 +657,6 @@ def _get_radial_sum(dt, bins, bin_size, autocorr): radial_sum[i] = np.sum(np.ravel(autocorr)[np.ravel(mask)]) / np.sum(mask) return radial_sum - def two_point_correlation(im, voxel_size=1, bins=100): r""" Calculate the two-point correlation function using Fourier transforms @@ -690,14 +667,12 @@ def two_point_correlation(im, voxel_size=1, bins=100): The image of the void space on which the 2-point correlation is desired, in which the phase of interest is labelled as True voxel_size : scalar - The size of a voxel side in preferred units. The default is 1, so - the user can apply the scaling to the returned results after the - fact. + The size of a voxel side in preferred units. The default is 1, so the + user can apply the scaling to the returned results after the fact. bins : scalar or array_like - Either an array of bin sizes to use, or the number of bins that - should be automatically generated that span the data range. The - maximum value of the bins, if passed as an array, cannot exceed - the distance from the center of the image to the corner. + Either an array of bin sizes to use, or the number of bins that should + be automatically generated that span the data range. The maximum value of the bins, + if passed as an array, cannot exceed the distance from the center of the image to the corner Returns ------- diff --git a/porespy/tools/_funcs.py b/porespy/tools/_funcs.py index ccad29c14..f3bb736f7 100644 --- a/porespy/tools/_funcs.py +++ b/porespy/tools/_funcs.py @@ -17,6 +17,7 @@ 'align_image_with_openpnm', 'bbox_to_slices', 'extend_slice', + 'extend_slice_2', 'extract_cylinder', 'extract_subsection', 'extract_regions', @@ -599,6 +600,26 @@ def extend_slice(slices, shape, pad=1): a.append(slice(start, stop, None)) return tuple(a) +def extend_slice_2(slices, AR,shape, pad=1): + shape = np.array(shape) + pad = np.array(pad).astype(int)*(shape > 0) + a = [] + for i, s in enumerate(slices): + if i!=0:#looking at y & z-coord slice + start = 0 + stop = shape[i] + start = max(s.start - round(AR[i]*pad[i]), 0)#reduce the extension by aspect ratio(AR) of y/z + stop = min(s.stop + round(AR[i]*pad[i]), shape[i]) + a.append(slice(start, stop, None)) + else: + start = 0 + stop = shape[i] + start = max(s.start - pad[i], 0) + stop = min(s.stop + pad[i], shape[i]) + a.append(slice(start, stop, None)) + return tuple(a) + + def randomize_colors(im, keep_vals=[0]): r'''