Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New release (minor): v3.3.0 #2836

Merged
merged 26 commits into from
Oct 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0431f14
Merge pull request #2812 from PMEAL/release
ma-sadeghi Sep 1, 2023
e991de1
Bump version number (build part)
actions-user Sep 1, 2023
e3a0977
Changing how rows are computed to accomodate 2Nt long weights
jgostick Sep 6, 2023
eefdd9a
Fixing bug in pore surface area models
jgostick Sep 6, 2023
e91fa4c
Merge pull request #2813 from PMEAL/enhance_create_im
jgostick Sep 6, 2023
613bb67
Bump version number (build part)
actions-user Sep 6, 2023
e296032
new logic for vor-to-am
jgostick Sep 15, 2023
cdb122b
making number of reflected points flexible
jgostick Sep 15, 2023
0fbc71f
adding doc strings and check that 0 < f < 1
jgostick Sep 15, 2023
f486676
adding a fix to the merge_pores function so it behaves as described i…
jgostick Sep 15, 2023
f56e413
added 'backup' code to tri_to_am, but commented out
jgostick Sep 15, 2023
1ddb2b8
tweaks to tri_to_am, vor_to_am, and conns_to_am for speed
jgostick Sep 15, 2023
ec39cac
little tweaks
jgostick Sep 15, 2023
abc2f4a
I'm getting really sick of packages fing with their api for no reason
jgostick Sep 15, 2023
d888ec8
adding f arg to all the right places
jgostick Sep 15, 2023
69ecad5
making return_tri optional
jgostick Sep 15, 2023
9a9c072
pep8 errors
jgostick Sep 15, 2023
c4cc3a9
Had to update 2 tests for the skgraph voronoi_delaunay_dual generator…
jgostick Sep 15, 2023
381843a
adding beta module with my custom relax_points in it, not imported wi…
jgostick Sep 15, 2023
58c5646
Merge pull request #2821 from PMEAL/accelerating_tessellation_generators
jgostick Sep 15, 2023
3aca748
Bump version number (build part)
actions-user Sep 15, 2023
3257b0e
Remove pypardiso as a hard dependency
ma-sadeghi Sep 30, 2023
b4091cf
Fix pep8
ma-sadeghi Oct 1, 2023
d3ad011
Better warning message when pardiso missing
ma-sadeghi Oct 1, 2023
0cced5b
Merge pull request #2835 from PMEAL/fix_arm64
ma-sadeghi Oct 1, 2023
3dbe3e5
Bump version number (build part)
actions-user Oct 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ jobs:
pip install \
-r requirements.txt \
-r requirements/tests.txt
pip install pypardiso

- name: Running tests
run:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ jobs:
run: |
pip install -r requirements.txt
pip install -r requirements/docs.txt
pip install pypardiso

- name: Build the documentation
run: |
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ jobs:
-r requirements.txt \
-r requirements/tests.txt

- name: Install pypardiso on non-macOS
if: (matrix.os != 'macos-latest')
run: |
pip install pypardiso

- name: Running tests
run:
pytest . --color=yes
5 changes: 5 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ jobs:
-r requirements.txt \
-r requirements/tests.txt

- name: Install pypardiso on non-macOS
if: (matrix.os != 'macos-latest')
run: |
pip install pypardiso

- name: Disable numba JIT for codecov to include jitted methods
if: (matrix.python-version == 3.9) && (matrix.os == 'ubuntu-latest')
run: |
Expand Down
43 changes: 26 additions & 17 deletions openpnm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,34 @@

"""

from . import _skgraph
from . import utils
from . import core
from . import models
from . import topotools
from . import network
from . import phase
from . import algorithms
from . import solvers
from . import integrators
from . import io
from . import contrib
from . import visualization

from .utils import Workspace, Project
import logging

from rich.logging import RichHandler

FORMAT = "%(message)s"
logging.basicConfig(
format=FORMAT, datefmt="[%X]", handlers=[RichHandler(rich_tracebacks=True)]
)

import numpy as _np

from . import (
_skgraph,
algorithms,
contrib,
core,
integrators,
io,
models,
network,
phase,
solvers,
topotools,
utils,
visualization,
)
from .utils import Project, Workspace

_np.seterr(divide='ignore', invalid='ignore')

__version__ = utils._get_version()

utils._setup_logger_rich()
2 changes: 1 addition & 1 deletion openpnm/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '3.2.1.dev0'
__version__ = '3.2.1.dev4'
19 changes: 16 additions & 3 deletions openpnm/_skgraph/generators/_delaunay.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@
from openpnm._skgraph.operations import trim_nodes


def delaunay(points, shape=[1, 1, 1], reflect=False, trim=True,
node_prefix='node', edge_prefix='edge'):
def delaunay(
points,
shape=[1, 1, 1],
reflect=False,
f=1,
trim=True,
node_prefix='node',
edge_prefix='edge',
):
r"""
Generate a network based on Delaunay triangulation of random points

Expand All @@ -22,6 +29,12 @@ def delaunay(points, shape=[1, 1, 1], reflect=False, trim=True,
prior to performing the tessellation. These reflected points are
automatically trimmed. Enabling this behavior prevents long-range
connections between surface pores.
f : float
The fraction of points which should be reflected. The default is 1 which
reflects all the points in the domain, but this can lead to a lot of
unnecessary points, so setting to 0.1 or 0.2 helps speed, but risks that
the tessellation may not have smooth faces if not enough points are
reflected.
trim : boolean, optional (default = ``True``)
If ``True`` then any points laying outside the domain are removed. This is
mostly only useful if ``reflect=True``.
Expand All @@ -33,7 +46,7 @@ def delaunay(points, shape=[1, 1, 1], reflect=False, trim=True,
tri : Delaunay tessellation object
The Delaunay tessellation object produced by ``scipy.spatial.Delaunay``
"""
points = tools.parse_points(points=points, shape=shape, reflect=reflect)
points = tools.parse_points(points=points, shape=shape, reflect=reflect, f=f)
mask = ~np.all(points == 0, axis=0)
tri = sptl.Delaunay(points=points[:, mask])
coo = tri_to_am(tri)
Expand Down
20 changes: 17 additions & 3 deletions openpnm/_skgraph/generators/_voronoi.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,16 @@
from openpnm._skgraph.operations import trim_nodes


def voronoi(points, shape=[1, 1, 1], trim=True, reflect=False, relaxation=0,
node_prefix='node', edge_prefix='edge'):
def voronoi(
points,
shape=[1, 1, 1],
trim=True,
reflect=False,
f=1,
relaxation=0,
node_prefix='node',
edge_prefix='edge',
):
r"""
Generate a network based on a Voronoi tessellation of base points

Expand All @@ -24,6 +32,12 @@ def voronoi(points, shape=[1, 1, 1], trim=True, reflect=False, relaxation=0,
If ``True`` then points are reflected across each face of the domain
prior to performing the tessellation. Enabling this behavior creates
flat faces on all sizes of the domain.
f : float
The fraction of points which should be reflected. The default is 1 which
reflects all the points in the domain, but this can lead to a lot of
unnecessary points, so setting to 0.1 or 0.2 helps speed, but risks that
the tessellation may not have smooth faces if not enough points are
reflected.
relaxation : int, optional (default = 0)
The number of iterations to use for relaxing the base points. This is
sometimes called `Lloyd's algorithm
Expand All @@ -42,7 +56,7 @@ def voronoi(points, shape=[1, 1, 1], trim=True, reflect=False, relaxation=0,
The Voronoi tessellation object produced by ``scipy.spatial.Voronoi``

"""
points = tools.parse_points(points=points, shape=shape, reflect=reflect)
points = tools.parse_points(points=points, shape=shape, reflect=reflect, f=f)
mask = ~np.all(points == 0, axis=0)
# Perform tessellation
vor = sptl.Voronoi(points=points[:, mask])
Expand Down
117 changes: 80 additions & 37 deletions openpnm/_skgraph/generators/_voronoi_delaunay_dual.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,17 @@
from openpnm._skgraph.queries import find_neighbor_nodes


def voronoi_delaunay_dual(points, shape, trim=True, reflect=True, relaxation=0,
node_prefix='node', edge_prefix='edge'):
def voronoi_delaunay_dual(
points,
shape,
trim=True,
reflect=True,
f=1,
relaxation=0,
node_prefix='node',
edge_prefix='edge',
return_tri=False,
):
r"""
Generate a dual Voronoi-Delaunay network from given base points

Expand All @@ -25,6 +34,12 @@
reflect : bool, optionl
If ``True`` (Default) then points are reflected across each face of the
domain prior to performing the tessellation.
f : float
The fraction of points which should be reflected. The default is 1 which
reflects all the points in the domain, but this can lead to a lot of
unnecessary points, so setting to 0.1 or 0.2 helps speed, but risks that
the tessellation may not have smooth faces if not enough points are
reflected.
relaxation : int, optional (default = 0)
The number of iterations to use for relaxing the base points. This is
sometimes called `Lloyd's algorithm
Expand All @@ -42,11 +57,17 @@
vor : Voronoi object
The Voronoi tessellation object produced by ``scipy.spatial.Voronoi``
tri : Delaunay object
The Delaunay triangulation object produced ``scipy.spatial.Delaunay``
The Delaunay triangulation object produced by ``scipy.spatial.Delaunay``

"""
# Generate a set of base points if scalar was given
points = tools.parse_points(points=points, shape=shape, reflect=reflect)
points = tools.parse_points(
points=points,
shape=shape,
reflect=reflect,
f=1,
)

# Generate mask to remove any dims with all 0's
mask = ~np.all(points == 0, axis=0)

Expand All @@ -55,45 +76,36 @@
for _ in range(relaxation):
points = tools.lloyd_relaxation(vor, mode='fast')
vor = sptl.Voronoi(points=points[:, mask])
tri = sptl.Delaunay(points=points[:, mask])

# Combine points
pts_all = np.vstack((vor.points, vor.vertices))
Nall = np.shape(pts_all)[0]

# Create adjacency matrix in lil format for quick construction
am = sprs.lil_matrix((Nall, Nall))
for ridge in vor.ridge_dict.keys():
# Make Delaunay-to-Delaunay connections
for i in ridge:
am.rows[i].extend([ridge[0], ridge[1]])
# Get Voronoi vertices for current ridge
row = vor.ridge_dict[ridge].copy()
# Index Voronoi vertex numbers by number of Delaunay points
row = [i + vor.npoints for i in row if i > -1]
# Make Voronoi-to-Delaunay connections
for i in ridge:
am.rows[i].extend(row)
# Make Voronoi-to-Voronoi connections
row.append(row[0])
for i in range(len(row)-1):
am.rows[row[i]].append(row[i+1])

# Finalize adjacency matrix by assigning data values
am.data = am.rows # Values don't matter, only shape, so use 'rows'
# Convert to COO format for direct acces to row and col
am = am.tocoo()
# Extract rows and cols
conns = np.vstack((am.row, am.col)).T

# Convert to sanitized adjacency matrix
# Collect delaunay edges
conns_del = vor.ridge_points
# Deal with voronoi edges
v = vor.ridge_vertices.copy() # Assuming 'ridge' means facet between regions
# Add row [0] to close the facet on itself, add -1 to break connection to
# next facet in list as connections with -1 get deleted later
_ = [row.extend([row[0], -1]) for row in v]
v = np.hstack(v)
conns_vor = np.vstack((v[:-1], v[1:])).T
mask = np.any(conns_vor < 0, axis=1)
conns_vor = conns_vor[~mask] + vor.npoints
# Finally, get interconnecting edges
idx = [vor.regions[vor.point_region[i]] for i in range(0, len(vor.regions)-1)]
conns_inter = [([i]*len(idx[i]), idx[i]) for i in range(0, len(idx))]
conns_inter = np.hstack(conns_inter).astype(int).T
mask = np.any(conns_inter < 0, axis=1)
conns_inter = conns_inter[~mask, :] + np.array([0, vor.npoints], dtype=int)
conns = np.vstack((conns_del, conns_vor, conns_inter))

# Tidy up
am = conns_to_am(conns)
# Finally, retreive conns back from am
conns = np.vstack((am.row, am.col)).T

# Convert coords to 3D if necessary
# Combine delaunay and voronoi points
pts_all = np.vstack((vor.points, vor.vertices))
# Rounding is crucial since some voronoi verts endup outside domain
pts_all = np.around(pts_all, decimals=10)
# Convert coords to 3D if necessary
mask = ~np.all(points == 0, axis=0)
if mask.sum() < 3:
coords = np.zeros([pts_all.shape[0], 3], dtype=float)
coords[:, mask] = pts_all
Expand Down Expand Up @@ -142,4 +154,35 @@
inds = np.where(trim)[0]
network = trim_nodes(network=network, inds=inds)

if return_tri:
tri = sptl.Delaunay(points=points[:, mask])

Check warning on line 158 in openpnm/_skgraph/generators/_voronoi_delaunay_dual.py

View check run for this annotation

Codecov / codecov/patch

openpnm/_skgraph/generators/_voronoi_delaunay_dual.py#L158

Added line #L158 was not covered by tests
else:
tri = None
return network, vor, tri


if __name__ == "__main__":
import openpnm as op
pn, vor, tri = voronoi_delaunay_dual(
points=500,
shape=[1, 1, 0],
trim=True,
reflect=True,
f=0.2,
relaxation=0,
node_prefix='pore',
edge_prefix='throat',
)
net = op.network.Network()
net.update(pn)
h = None
h = op.visualization.plot_connections(
net, throats=pn['throat.delaunay'], c='b', ax=h)
h = op.visualization.plot_connections(
net, throats=pn['throat.voronoi'], c='g', ax=h)
h = op.visualization.plot_connections(
net, throats=pn['throat.interconnect'], c='r', ax=h)
h = op.visualization.plot_coordinates(
net, pores=pn['pore.voronoi'], c='g', markersize=150, ax=h)
h = op.visualization.plot_coordinates(
net, pores=pn['pore.delaunay'], c='b', markersize=150, ax=h)
Loading