Skip to content

Commit aac7381

Browse files
authored
Merge pull request #22 from EMSL-Computing/joss-edits
More Joss edits
2 parents 5ec8a65 + 84196ab commit aac7381

File tree

4 files changed

+77
-59
lines changed

4 files changed

+77
-59
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
## What is Pore2Chip?
44
Pore2Chip is a Python module designed to streamline the process of analyzing X-ray computed tomography (XCT) images of soil and creating 2D micromodel designs based on that analysis. It leverages the power of open-source libraries like OpenPNM, PoreSpy, and drawsvg to extract key information about the soil's porous structure and translate it into a blueprint for microfluidic simulations or physical `lab-on-a-chip` devices developed using additive manufacturing.
55

6+
Documentation Quick Link: https://emsl-computing.github.io/Pore2Chip/
7+
68
### A workflow for model-data-experiment (ModEx) design:
79

810
Below is a conceptual figure, workflow, and vision for this all-in-one Python tool. The working principle starts with XCT imaging files, which will be characterized for soil structure-property relationships and then transformed into a 2D rendering applicable to pore-scale micromodel building. Micromodel experiments will then be used with PFLOTRAN/OpenFOAM/PINNs process models to simulate flow and reactive transport for calibration and V&V.

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ dynamic = ["dependencies"]
2929
[tool.setuptools.dynamic]
3030
dependencies = {file = ["requirements.txt"]}
3131

32+
[project.optional-dependencies]
33+
extras = [
34+
"pypardiso",
35+
]
36+
3237
[project.urls]
3338
Homepage = "https://www.emsl.pnnl.gov/science/instruments-resources/terraforms-pore2chip"
3439
Source = "https://github.com/EMSL-Computing/Pore2Chip"

tests/test_coordination.py

Lines changed: 67 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
import openpnm as op
55
import porespy as ps
66
from pathlib import Path
7+
import pytest
8+
import numpy as np
79

810
# Uncomment and modify these lines if the pore2chip package is not in the PYTHONPATH
911
#mod_path = Path("__file__").resolve().parents[2]
1012
#sys.path.append(os.path.abspath(mod_path))
1113

1214
from pore2chip.coordination import coordination_nums_2D, coordination_nums_3D
13-
#from pore2chip.src.pore2chip.export import coordination_nums_3D, coordination_nums_2D
14-
1515

1616
def generate_network():
1717
"""
@@ -22,64 +22,75 @@ def generate_network():
2222
"""
2323
network = op.network.Cubic([3, 3]) # Create a 3x3 cubic network
2424
network.add_model_collection(op.models.collections.geometry.
25-
spheres_and_cylinders) # Add geometry models
25+
spheres_and_cylinders) # Add geometry models
2626
network.regenerate_models() # Generate network properties
2727
print(network) # For debugging purposes
2828
return network
2929

30+
class TestCoordination():
3031

31-
def test_coordination_nums_3D(network):
32-
"""
33-
Test coordination_nums_2D function given an OpenPNM network.
32+
def test_coordination_nums_3D(self):
33+
"""
34+
Test coordination_nums_2D function given an OpenPNM network.
3435
35-
Args:
36-
network (dict): The network structure and coordination numbers (e.g., op.network.Cubic).
37-
38-
Returns:
39-
coordination_numbers (ndarray): An array of coordination numbers for each pore in the network..
40-
"""
41-
coordination_numbers = coordination_nums_3D(pn=network)
42-
print(coordination_numbers) # For debugging purposes
43-
print(coordination_numbers.mean()) # For debugging purposes
44-
print(coordination_numbers.shape) # For debugging purposes
45-
return coordination_numbers
46-
47-
48-
def test_coordination_nums_2D(img_list):
49-
"""
50-
Test coordination_nums_2D function given a list of images.
36+
Args:
37+
network (dict): The network structure and coordination numbers (e.g., op.network.Cubic).
38+
39+
Returns:
40+
coordination_numbers (ndarray): An array of coordination numbers for each pore in the network..
41+
"""
42+
network = generate_network()
43+
coordination_numbers = coordination_nums_3D(pn=network)
44+
assert coordination_numbers.any() == np.array([2,3,2,3,4,3,2,3,2],dtype=int).any()
45+
#print(coordination_numbers) # For debugging purposes
46+
#print(coordination_numbers.mean()) # For debugging purposes
47+
#print(coordination_numbers.shape) # For debugging purposes
48+
#return coordination_numbers
49+
50+
51+
def test_coordination_nums_2D(self):
52+
"""
53+
Test coordination_nums_2D function given a list of images.
5154
52-
Args:
53-
img_list (ndarray): 3D image list
54-
55-
Returns:
56-
coordination_numbers (ndarray): An array of coordination numbers for each pore in the network..
57-
"""
58-
coordination_numbers = coordination_nums_2D(img_list)
59-
print(coordination_numbers)
60-
print(coordination_numbers.mean())
61-
print(coordination_numbers.shape)
62-
return coordination_numbers
63-
64-
65-
def main():
66-
"""
67-
Main function to generate a network, test coordination number computations on 3D networks
68-
and 2D image slices.
69-
"""
70-
71-
# Generate network
72-
network = generate_network()
73-
74-
# Test coordination 3D on generated network
75-
test_coordination_nums_3D(network)
76-
77-
# Generate a 3D image using PoreSpy with specified dimensions and random seed
78-
blobs = ps.generators.blobs([5, 100, 100], seed=1)
79-
80-
# Test coordination 2D on image list
81-
test_coordination_nums_2D(blobs)
82-
83-
84-
if __name__ == "__main__":
85-
main()
55+
Args:
56+
img_list (ndarray): 3D image list
57+
58+
Returns:
59+
coordination_numbers (ndarray): An array of coordination numbers for each pore in the network..
60+
"""
61+
blobs = ps.generators.blobs([1, 100, 100], seed=1)
62+
coordination_numbers = coordination_nums_2D(blobs)
63+
assert coordination_numbers.any() == np.array(
64+
[3, 3, 1, 0, 3, 1, 0, 1, 1, 3, 2, 2, 3, 3, 1, 2, 3, 2, 2, 1, 2, 1, 3, 1,
65+
2, 2, 5, 2, 0, 0, 1, 3, 1, 2, 1, 0, 1, 3, 4, 0, 3, 3, 0, 1, 2, 2, 3, 3,
66+
2, 2, 2, 2, 3, 3, 0, 4, 1, 2, 4, 2, 1, 2, 3, 3, 2, 3, 5, 4, 1, 1, 2, 1,
67+
2, 1, 2, 3, 3, 2, 2, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
68+
1, 1, 1, 1, 1, 1, 1, 1, 1,]
69+
,dtype=float).any()
70+
#print(coordination_numbers)
71+
#print(coordination_numbers.mean())
72+
#print(coordination_numbers.shape)
73+
#return coordination_numbers
74+
75+
76+
#def main():
77+
#"""
78+
#Main function to generate a network, test coordination number computations on 3D networks
79+
#and 2D image slices.
80+
#"""
81+
82+
## Generate network
83+
#network = generate_network()
84+
85+
## Test coordination 3D on generated network
86+
#test_coordination_nums_3D(network)
87+
88+
## Generate a 3D image using PoreSpy with specified dimensions and random seed
89+
#blobs = ps.generators.blobs([5, 100, 100], seed=1)
90+
91+
## Test coordination 2D on image list
92+
#test_coordination_nums_2D(blobs)
93+
94+
95+
#if __name__ == "__main__":
96+
#main()

tests/test_generate.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ def create_random_properties():
2525
- coordination_nums (np.ndarray): Array of random coordination numbers (converted to integers).
2626
"""
2727
# Generating random pore diameters within specified range
28-
pore_diameters = np.random.uniform(low=1.0, high=10.0, size=20)
28+
pore_diameters = np.random.uniform(low=1.0, high=10.0, size=20, seed=1)
2929

3030
# Generating random throat diameters within specified range
31-
throat_diameters = np.random.uniform(low=0.5, high=6.0, size=20)
31+
throat_diameters = np.random.uniform(low=0.5, high=6.0, size=20, seed=1)
3232

3333
# Generating random coordination numbers within specified range and converting to integers
3434
coordination_nums = np.random.uniform(low=0, high=8,
35-
size=20).astype(np.int64)
35+
size=20, seed=1).astype(np.int64)
3636
return pore_diameters, throat_diameters, coordination_nums
3737

3838

0 commit comments

Comments
 (0)