<jupyter_start><jupyter_text>Permeability Simulation Using PoreSpy and OpenPNMThis simulation is based on the original notebook [Berea Sandstone Simulation Using PoreSpy and OpenPNM](https://github.com/PMEAL/OpenPNM/blob/master/examples/simulations/Berea%20Sandstone%20-%20Effective%20Permeability.ipynb)  Start by importing the necessary packages<jupyter_code>import numpy as np
import openpnm as op
import porespy as ps
import matplotlib.pyplot as plt
np.set_printoptions(precision=4)
np.random.seed(10)
%matplotlib inline<jupyter_output><empty_output><jupyter_text>Load Sandstone Data<jupyter_code>resolution = 2.25e-6
name = 'Bentheimer'
# Read input RAW file
raw_file = np.fromfile('Sandstones/'+name+'_2d25um_binary.raw', dtype=np.uint8)
im = (raw_file.reshape(1000,1000,1000))
im = im==0;<jupyter_output><empty_output><jupyter_text>Confirm image and check image porosity<jupyter_code>#NBVAL_IGNORE_OUTPUT
fig, ax = plt.subplots(1, 3, figsize=(12,5))
ax[0].imshow(im[:, :, 100]);
ax[1].imshow(ps.visualization.show_3D(im[:250,:250,:250]));
ax[2].imshow(ps.visualization.sem(im[:250,:250,:250]));
ax[0].set_title("Slice No. 100 View");
ax[1].set_title("3D Sketch");
ax[2].set_title("SEM View");
print(ps.metrics.porosity(im))
print(im.shape)
print(im.dtype)<jupyter_output>0.267188596
(1000, 1000, 1000)
bool<jupyter_text>Extract pore network using SNOW algorithm in PoreSpy The SNOW algorithm (an accronym for Sub-Network from an Oversegmented Watershed) was presented by [Gostick](https://journals.aps.org/pre/abstract/10.1103/PhysRevE.96.023307).<jupyter_code>net = ps.networks.snow(im=im, voxel_size=resolution)<jupyter_output>____________________________________________________________
Beginning SNOW Algorithm
Converting supplied image (im) to boolean
Peforming Distance Transform
Applying Gaussian blur with sigma = 0.4
Initial number of peaks:  58804
Peaks after trimming saddle points:  37258
Peaks after trimming nearby peaks:  36994
____________________________________________________________
Extracting pore and throat information from image<jupyter_text>Import network in OpenPNM The output from the SNOW algorithm above is a plain python dictionary containing all the extracted pore-scale data, but it is NOT yet an OpenPNM network. We need to create an empty network in OpenPNM, then populate it with the data from SNOW:<jupyter_code>ws = op.Workspace()
proj = op.Project()
pn = op.network.GenericNetwork(name=name, project=proj)
pn.update(net)  # Fills 'pn' with data from 'net'<jupyter_output><empty_output><jupyter_text>Optional: load already saved network<jupyter_code>proj = op.io.OpenpnmIO.load_project('Bentheimer.pnm');
pn = proj.network;<jupyter_output><empty_output><jupyter_text>Now we can print the network to see how the transferred worked:<jupyter_code>print(pn)<jupyter_output>――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
openpnm.network.GenericNetwork : net_01
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
#     Properties                                    Valid Values
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
1     pore.area                                     36795 / 36795
2     pore.centroid                                 36795 / 36795
3     pore.coords                                   36795 / 36795
4     pore.diameter                                 36795 / 36795
5     pore.equivalent_diameter                      36795 / 36795
6     pore.extended_diameter                        36795 / 36795
7     pore.inscribed_diameter                       36795 / 36795
8     pore.label                                    36795 / 36795
9     pore.surface_area                             36795 / 36795
10    pore.volume                                   36795 / 3679[...]<jupyter_text>Check network health Remove isolated pores or cluster of pores from the network by checking it network health. Make sure ALL keys in network health functions have no value.<jupyter_code>h = pn.check_network_health()
op.topotools.trim(network=pn, pores=h['trim_pores'])
h = pn.check_network_health()
print(h)<jupyter_output>――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
key                                 value
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
disconnected_clusters               []
isolated_pores                      []
trim_pores                          []
duplicate_throats                   []
bidirectional_throats               []
headless_throats                    []
looped_throats                      []
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――<jupyter_text>Assign geometry<jupyter_code>geo = op.geometry.GenericGeometry(network=pn, pores=pn.Ps, throats=pn.Ts)<jupyter_output><empty_output><jupyter_text>Assign phase In this example air is considered as fluid passing through porous channels.<jupyter_code>water = op.phases.Water(network=pn)<jupyter_output><empty_output><jupyter_text>Assign physics<jupyter_code>phys_water=op.physics.GenericPhysics(network=pn, phase=water, geometry=geo)
R = geo['throat.diameter']/2.0;
L = geo['throat.length'];
phys_water['throat.hydraulic_conductance'] = (np.pi*(R**4))/(8*water['pore.viscosity'].max()*L)<jupyter_output><empty_output><jupyter_text>Calculate effective permeability Caclulate effective permeablity using hagen poiseuille equation. Use cross section area and flow length manually from image dimension.<jupyter_code>A = (1000*1000) *resolution**2
L = 1000 * resolution
mu = water['pore.viscosity'].max()
Pressure = 10e3;
delta_P = Pressure - 0
#X
perm = op.algorithms.StokesFlow(network=pn, project=proj)
perm.setup(phase=water)
perm.set_value_BC(pores=pn.pores('top'), values=0)
perm.set_value_BC(pores=pn.pores('bottom'), values=Pressure)
perm.run()
Q = perm.rate(pores=pn.pores('bottom'), mode='group')
K = Q * L * mu / (A * delta_P)
print('X:', K/0.98e-12*1000, 'mD')

#y
perm = op.algorithms.StokesFlow(network=pn, project=proj)
perm.setup(phase=water)
perm.set_value_BC(pores=pn.pores('front'), values=0)
perm.set_value_BC(pores=pn.pores('back'), values=Pressure)
perm.run()
Q = perm.rate(pores=pn.pores('back'), mode='group')
K = Q * L * mu / (A * delta_P)
print('Y:', K/0.98e-12*1000, 'mD')

#z
perm = op.algorithms.StokesFlow(network=pn, project=proj)
perm.setup(phase=water)
perm.set_value_BC(pores=pn.pores('left'), values=0)
perm.set_value_BC(pores=pn.pores('right'), values=Pressure)
perm.run()
Q = perm.rate(pores=pn.pores('right'), mode='group')
K = Q * L * mu / (A * delta_P)
print('Z:', K/0.98e-12*1000, 'mD')<jupyter_output>X: [999.4799] mD
Y: [976.0905] mD
Z: [960.0699] mD
{'fraction_non_alphanumeric': 0.17775126752162243, 'fraction_numerical': 0.045630778407396363, 'mean_word_length': 4.400161030595813, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 44, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '483424', 'license': 'MIT', 'n_tokens_mistral': 2808, 'n_tokens_neox': 2531, 'n_words': 458, 'path': 'permeability_PoreSpy_OpenPNM.ipynb', 'repo_name': 'mbandreeta/absolute_permeability_simulations', 'size': '6706'}