Skip to content

Commit

Permalink
Add Ugrid1d.is_cyclic. Fixes #328
Browse files Browse the repository at this point in the history
  • Loading branch information
Huite committed Feb 21, 2025
1 parent e81ed54 commit 0518d18
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ UGRID1D Topology
Ugrid1d.directed_node_node_connectivity
Ugrid1d.directed_edge_edge_connectivity
Ugrid1d.get_connectivity_matrix
Ugrid1d.is_cyclic

Ugrid1d.copy
Ugrid1d.rename
Expand Down
6 changes: 6 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ The format is based on `Keep a Changelog`_, and this project adheres to
Unreleased
----------

Added
~~~~~

- Added :attr:`xugrid.Ugrid1d.is_cyclic` property to check if grid topology
contains cycles.

[0.12.3] 2025-02-17
-------------------

Expand Down
24 changes: 24 additions & 0 deletions tests/test_ugrid1d.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,30 @@ def test_meshkernel():
assert isinstance(grid.meshkernel, mk.MeshKernel)


def test_is_cyclic():
x = np.array([0.0, 1.0, 2.0])
y = np.array([0.0, 1.0, 0.0])
edge_nodes = np.array(
[
[0, 1],
[1, 2],
[2, 0],
]
)
cycle = xugrid.Ugrid1d(x, y, -1, edge_nodes)
assert cycle.is_cyclic

edge_nodes = np.array(
[
[0, 1],
[1, 2],
[0, 2],
]
)
dag = xugrid.Ugrid1d(x, y, -1, edge_nodes)
assert not dag.is_cyclic


def test_from_shapely():
with pytest.raises(TypeError):
xy = np.array(
Expand Down
18 changes: 18 additions & 0 deletions xugrid/ugrid/ugrid1d.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,24 @@ def meshkernel(self) -> "mk.MeshKernel": # type: ignore # noqa
self._meshkernel.mesh1d_set(self.mesh)
return self._meshkernel

@property
def is_cyclic(self) -> bool:
"""
Return True if the directed node node connectivity contains cycles. If
False, then the directed node node connectivity is a directed acyclic
graph (DAG).
Runs a depth-first-search.
"""
# topological sort returns a ValueError if it detects a cycle.
try:
self.topological_sort_by_dfs()
return False
except ValueError as e:
if str(e) == "The graph contains at least one cycle":
return True
raise # Re-raise any other ValueError

@classmethod
def from_geodataframe(cls, geodataframe: "geopandas.GeoDataFrame") -> "Ugrid1d": # type: ignore # noqa
"""
Expand Down

0 comments on commit 0518d18

Please sign in to comment.