Skip to content

Commit e1d144b

Browse files
committed
Define new error class and update code and tests
Define the new `TreeMeshNotFinalizedError` class. Update the properties to not pass the `is_property` argument to the error method. Update the tests accordingly.
1 parent 5688c91 commit e1d144b

File tree

3 files changed

+43
-41
lines changed

3 files changed

+43
-41
lines changed

discretize/_extensions/tree_ext.pyx

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ import scipy.sparse as sp
1515
import numpy as np
1616
from .interputils_cython cimport _bisect_left, _bisect_right
1717

18+
class TreeMeshNotFinalizedError(RuntimeError):
19+
"""Raise when a TreeMesh is not finalized."""
20+
1821

1922
cdef class TreeCell:
2023
"""A class for defining cells within instances of :class:`~discretize.TreeMesh`.
@@ -1959,7 +1962,7 @@ cdef class _TreeMesh:
19591962
(n_cells, dim) numpy.ndarray of float
19601963
Gridded cell center locations
19611964
"""
1962-
self._error_if_not_finalized("cell_centers", is_property=True)
1965+
self._error_if_not_finalized("cell_centers")
19631966
cdef np.float64_t[:, :] gridCC
19641967
cdef np.int64_t ii, ind, dim
19651968
if self._cell_centers is None:
@@ -1985,7 +1988,7 @@ cdef class _TreeMesh:
19851988
(n_nodes, dim) numpy.ndarray of float
19861989
Gridded non-hanging node locations
19871990
"""
1988-
self._error_if_not_finalized("nodes", is_property=True)
1991+
self._error_if_not_finalized("nodes")
19891992
cdef np.float64_t[:, :] gridN
19901993
cdef Node *node
19911994
cdef np.int64_t ii, ind, dim
@@ -2014,7 +2017,7 @@ cdef class _TreeMesh:
20142017
(n_hanging_nodes, dim) numpy.ndarray of float
20152018
Gridded hanging node locations
20162019
"""
2017-
self._error_if_not_finalized("hanging_nodes", is_property=True)
2020+
self._error_if_not_finalized("hanging_nodes")
20182021
cdef np.float64_t[:, :] gridN
20192022
cdef Node *node
20202023
cdef np.int64_t ii, ind, dim
@@ -2041,7 +2044,7 @@ cdef class _TreeMesh:
20412044
(n_boundary_nodes, dim) numpy.ndarray of float
20422045
Gridded boundary node locations
20432046
"""
2044-
self._error_if_not_finalized("boundary_nodes", is_property=True)
2047+
self._error_if_not_finalized("boundary_nodes")
20452048
nodes = self.nodes
20462049
x0, xF = self._xs[0], self._xs[-1]
20472050
y0, yF = self._ys[0], self._ys[-1]
@@ -2073,7 +2076,7 @@ cdef class _TreeMesh:
20732076
(n_cells, dim) numpy.ndarray of float
20742077
Gridded cell dimensions
20752078
"""
2076-
self._error_if_not_finalized("h_gridded", is_property=True)
2079+
self._error_if_not_finalized("h_gridded")
20772080
if self._h_gridded is not None:
20782081
return self._h_gridded
20792082
cdef np.float64_t[:, :] gridCH
@@ -2102,7 +2105,7 @@ cdef class _TreeMesh:
21022105
(n_edges_x, dim) numpy.ndarray of float
21032106
Gridded locations of all non-hanging x-edges
21042107
"""
2105-
self._error_if_not_finalized("edges_x", is_property=True)
2108+
self._error_if_not_finalized("edges_x")
21062109
cdef np.float64_t[:, :] gridEx
21072110
cdef Edge *edge
21082111
cdef np.int64_t ii, ind, dim
@@ -2130,7 +2133,7 @@ cdef class _TreeMesh:
21302133
(n_hanging_edges_x, dim) numpy.ndarray of float
21312134
Gridded locations of all hanging x-edges
21322135
"""
2133-
self._error_if_not_finalized("hanging_edges_x", is_property=True)
2136+
self._error_if_not_finalized("hanging_edges_x")
21342137
cdef np.float64_t[:, :] gridhEx
21352138
cdef Edge *edge
21362139
cdef np.int64_t ii, ind, dim
@@ -2156,7 +2159,7 @@ cdef class _TreeMesh:
21562159
(n_edges_y, dim) numpy.ndarray of float
21572160
Gridded locations of all non-hanging y-edges
21582161
"""
2159-
self._error_if_not_finalized("edges_y", is_property=True)
2162+
self._error_if_not_finalized("edges_y")
21602163
cdef np.float64_t[:, :] gridEy
21612164
cdef Edge *edge
21622165
cdef np.int64_t ii, ind, dim
@@ -2184,7 +2187,7 @@ cdef class _TreeMesh:
21842187
(n_haning_edges_y, dim) numpy.ndarray of float
21852188
Gridded locations of all hanging y-edges
21862189
"""
2187-
self._error_if_not_finalized("hanging_edges_y", is_property=True)
2190+
self._error_if_not_finalized("hanging_edges_y")
21882191
cdef np.float64_t[:, :] gridhEy
21892192
cdef Edge *edge
21902193
cdef np.int64_t ii, ind, dim
@@ -2210,7 +2213,7 @@ cdef class _TreeMesh:
22102213
(n_edges_z, dim) numpy.ndarray of float
22112214
Gridded locations of all non-hanging z-edges
22122215
"""
2213-
self._error_if_not_finalized("edges_z", is_property=True)
2216+
self._error_if_not_finalized("edges_z")
22142217
cdef np.float64_t[:, :] gridEz
22152218
cdef Edge *edge
22162219
cdef np.int64_t ii, ind, dim
@@ -2238,7 +2241,7 @@ cdef class _TreeMesh:
22382241
(n_hanging_edges_z, dim) numpy.ndarray of float
22392242
Gridded locations of all hanging z-edges
22402243
"""
2241-
self._error_if_not_finalized("hanging_edges_z", is_property=True)
2244+
self._error_if_not_finalized("hanging_edges_z")
22422245
cdef np.float64_t[:, :] gridhEz
22432246
cdef Edge *edge
22442247
cdef np.int64_t ii, ind, dim
@@ -2266,7 +2269,7 @@ cdef class _TreeMesh:
22662269
(n_boundary_edges, dim) numpy.ndarray of float
22672270
Gridded boundary edge locations
22682271
"""
2269-
self._error_if_not_finalized("boundary_edges", is_property=True)
2272+
self._error_if_not_finalized("boundary_edges")
22702273
edges_x = self.edges_x
22712274
edges_y = self.edges_y
22722275
x0, xF = self._xs[0], self._xs[-1]
@@ -2306,7 +2309,7 @@ cdef class _TreeMesh:
23062309
(n_faces_x, dim) numpy.ndarray of float
23072310
Gridded locations of all non-hanging x-faces
23082311
"""
2309-
self._error_if_not_finalized("faces_x", is_property=True)
2312+
self._error_if_not_finalized("faces_x")
23102313
if(self._dim == 2): return self.edges_y
23112314

23122315
cdef np.float64_t[:, :] gridFx
@@ -2336,7 +2339,7 @@ cdef class _TreeMesh:
23362339
(n_faces_y, dim) numpy.ndarray of float
23372340
Gridded locations of all non-hanging y-faces
23382341
"""
2339-
self._error_if_not_finalized("faces_y", is_property=True)
2342+
self._error_if_not_finalized("faces_y")
23402343
if(self._dim == 2): return self.edges_x
23412344
cdef np.float64_t[:, :] gridFy
23422345
cdef Face *face
@@ -2365,7 +2368,7 @@ cdef class _TreeMesh:
23652368
(n_faces_z, dim) numpy.ndarray of float
23662369
Gridded locations of all non-hanging z-faces
23672370
"""
2368-
self._error_if_not_finalized("faces_z", is_property=True)
2371+
self._error_if_not_finalized("faces_z")
23692372
if(self._dim == 2): return self.cell_centers
23702373

23712374
cdef np.float64_t[:, :] gridFz
@@ -2395,7 +2398,7 @@ cdef class _TreeMesh:
23952398
(n_hanging_faces_x, dim) numpy.ndarray of float
23962399
Gridded locations of all hanging x-faces
23972400
"""
2398-
self._error_if_not_finalized("hanging_faces_x", is_property=True)
2401+
self._error_if_not_finalized("hanging_faces_x")
23992402
if(self._dim == 2): return self.hanging_edges_y
24002403

24012404
cdef np.float64_t[:, :] gridFx
@@ -2423,7 +2426,7 @@ cdef class _TreeMesh:
24232426
(n_hanging_faces_y, dim) numpy.ndarray of float
24242427
Gridded locations of all hanging y-faces
24252428
"""
2426-
self._error_if_not_finalized("hanging_faces_y", is_property=True)
2429+
self._error_if_not_finalized("hanging_faces_y")
24272430
if(self._dim == 2): return self.hanging_edges_x
24282431

24292432
cdef np.float64_t[:, :] gridhFy
@@ -2451,7 +2454,7 @@ cdef class _TreeMesh:
24512454
(n_hanging_faces_z, dim) numpy.ndarray of float
24522455
Gridded locations of all hanging z-faces
24532456
"""
2454-
self._error_if_not_finalized("hanging_faces_z", is_property=True)
2457+
self._error_if_not_finalized("hanging_faces_z")
24552458
if(self._dim == 2): return np.array([])
24562459

24572460
cdef np.float64_t[:, :] gridhFz
@@ -2481,7 +2484,7 @@ cdef class _TreeMesh:
24812484
(n_boundary_faces, dim) numpy.ndarray of float
24822485
Gridded boundary face locations
24832486
"""
2484-
self._error_if_not_finalized("boundary_faces", is_property=True)
2487+
self._error_if_not_finalized("boundary_faces")
24852488
faces_x = self.faces_x
24862489
faces_y = self.faces_y
24872490
x0, xF = self._xs[0], self._xs[-1]
@@ -2511,7 +2514,7 @@ cdef class _TreeMesh:
25112514
(n_boundary_faces, dim) numpy.ndarray of float
25122515
Outward normals of boundary faces
25132516
"""
2514-
self._error_if_not_finalized("boundary_face_outward_normals", is_property=True)
2517+
self._error_if_not_finalized("boundary_face_outward_normals")
25152518
faces_x = self.faces_x
25162519
faces_y = self.faces_y
25172520
x0, xF = self._xs[0], self._xs[-1]
@@ -2554,7 +2557,7 @@ cdef class _TreeMesh:
25542557
- *3D:* Returns the cell volumes
25552558
25562559
"""
2557-
self._error_if_not_finalized("cell_volumes", is_property=True)
2560+
self._error_if_not_finalized("cell_volumes")
25582561
cdef np.float64_t[:] vol
25592562
if self._cell_volumes is None:
25602563
self._cell_volumes = np.empty(self.n_cells, dtype=np.float64)
@@ -2579,7 +2582,7 @@ cdef class _TreeMesh:
25792582
respectively
25802583
- *3D:* returns the x, y and z-face areas in order
25812584
"""
2582-
self._error_if_not_finalized("face_areas", is_property=True)
2585+
self._error_if_not_finalized("face_areas")
25832586
if self._dim == 2 and self._face_areas is None:
25842587
self._face_areas = np.r_[self.edge_lengths[self.n_edges_x:], self.edge_lengths[:self.n_edges_x]]
25852588
cdef np.float64_t[:] area
@@ -2622,7 +2625,7 @@ cdef class _TreeMesh:
26222625
- *2D:* returns the x-edge and y-edge lengths in order
26232626
- *3D:* returns the x, y and z-edge lengths in order
26242627
"""
2625-
self._error_if_not_finalized("edge_lengths", is_property=True)
2628+
self._error_if_not_finalized("edge_lengths")
26262629
cdef np.float64_t[:] edge_l
26272630
cdef Edge *edge
26282631
cdef int_t ind, offset
@@ -3587,7 +3590,7 @@ cdef class _TreeMesh:
35873590
(n_total_faces_x, n_cells) scipy.sparse.csr_matrix
35883591
The stencil for the x-component of the cell gradient
35893592
"""
3590-
self._error_if_not_finalized("stencil_cell_gradient_x", is_property=True)
3593+
self._error_if_not_finalized("stencil_cell_gradient_x")
35913594
if getattr(self, '_stencil_cell_gradient_x', None) is not None:
35923595
return self._stencil_cell_gradient_x
35933596
cdef np.int64_t[:] I = np.zeros(2*self.n_total_faces_x, dtype=np.int64)
@@ -3665,7 +3668,7 @@ cdef class _TreeMesh:
36653668
(n_total_faces_y, n_cells) scipy.sparse.csr_matrix
36663669
The stencil for the y-component of the cell gradient
36673670
"""
3668-
self._error_if_not_finalized("stencil_cell_gradient_y", is_property=True)
3671+
self._error_if_not_finalized("stencil_cell_gradient_y")
36693672
if getattr(self, '_stencil_cell_gradient_y', None) is not None:
36703673
return self._stencil_cell_gradient_y
36713674

@@ -3744,7 +3747,7 @@ cdef class _TreeMesh:
37443747
(n_total_faces_z, n_cells) scipy.sparse.csr_matrix
37453748
The stencil for the z-component of the cell gradient
37463749
"""
3747-
self._error_if_not_finalized("stencil_cell_gradient_z", is_property=True)
3750+
self._error_if_not_finalized("stencil_cell_gradient_z")
37483751
if getattr(self, '_stencil_cell_gradient_z', None) is not None:
37493752
return self._stencil_cell_gradient_z
37503753

@@ -5045,7 +5048,7 @@ cdef class _TreeMesh:
50455048
50465049
phi_f = Acf @ phi_c
50475050
"""
5048-
self._error_if_not_finalized("average_cell_to_face", is_property=True)
5051+
self._error_if_not_finalized("average_cell_to_face")
50495052
if self._average_cell_to_face is not None:
50505053
return self._average_cell_to_face
50515054
stacks = [self.average_cell_to_face_x, self.average_cell_to_face_y]
@@ -5106,7 +5109,7 @@ cdef class _TreeMesh:
51065109
in the x-direction. For boundary faces, nearest neighbor is used to extrapolate
51075110
the values.
51085111
"""
5109-
self._error_if_not_finalized("average_cell_vector_to_face", is_property=True)
5112+
self._error_if_not_finalized("average_cell_vector_to_face")
51105113
if self._average_cell_vector_to_face is not None:
51115114
return self._average_cell_vector_to_face
51125115
stacks = [self.average_cell_to_face_x, self.average_cell_to_face_y]
@@ -5130,7 +5133,7 @@ cdef class _TreeMesh:
51305133
(n_faces_x, n_cells) scipy.sparse.csr_matrix
51315134
The scalar averaging operator from cell centers to x faces
51325135
"""
5133-
self._error_if_not_finalized("average_cell_to_face_x", is_property=True)
5136+
self._error_if_not_finalized("average_cell_to_face_x")
51345137
if self._average_cell_to_face_x is not None:
51355138
return self._average_cell_to_face_x
51365139
cdef np.int64_t[:] I = np.zeros(2*self.n_total_faces_x, dtype=np.int64)
@@ -5247,7 +5250,7 @@ cdef class _TreeMesh:
52475250
(n_faces_y, n_cells) scipy.sparse.csr_matrix
52485251
The scalar averaging operator from cell centers to y faces
52495252
"""
5250-
self._error_if_not_finalized("average_cell_to_face_y", is_property=True)
5253+
self._error_if_not_finalized("average_cell_to_face_y")
52515254
if self._average_cell_to_face_y is not None:
52525255
return self._average_cell_to_face_y
52535256
cdef np.int64_t[:] I = np.zeros(2*self.n_total_faces_y, dtype=np.int64)
@@ -5364,7 +5367,7 @@ cdef class _TreeMesh:
53645367
(n_faces_z, n_cells) scipy.sparse.csr_matrix
53655368
The scalar averaging operator from cell centers to z faces
53665369
"""
5367-
self._error_if_not_finalized("average_cell_to_face_z", is_property=True)
5370+
self._error_if_not_finalized("average_cell_to_face_z")
53685371
if self.dim == 2:
53695372
raise Exception('TreeMesh has no z-faces in 2D')
53705373
if self._average_cell_to_face_z is not None:
@@ -5455,7 +5458,7 @@ cdef class _TreeMesh:
54555458
scipy.sparse.csr_matrix
54565459
(n_boundary_faces, n_faces) Projection matrix with shape
54575460
"""
5458-
self._error_if_not_finalized("project_face_to_boundary_face", is_property=True)
5461+
self._error_if_not_finalized("project_face_to_boundary_face")
54595462
faces_x = self.faces_x
54605463
faces_y = self.faces_y
54615464

@@ -5491,7 +5494,7 @@ cdef class _TreeMesh:
54915494
(n_boundary_edges, n_edges) scipy.sparse.csr_matrix
54925495
Projection matrix with shape
54935496
"""
5494-
self._error_if_not_finalized("project_edge_to_boundary_edge", is_property=True)
5497+
self._error_if_not_finalized("project_edge_to_boundary_edge")
54955498
edges_x = self.edges_x
54965499
edges_y = self.edges_y
54975500

@@ -5534,7 +5537,7 @@ cdef class _TreeMesh:
55345537
(n_boundary_nodes, n_nodes) scipy.sparse.csr_matrix
55355538
Projection matrix with shape
55365539
"""
5537-
self._error_if_not_finalized("project_node_to_boundary_node", is_property=True)
5540+
self._error_if_not_finalized("project_node_to_boundary_node")
55385541
nodes = self.nodes
55395542
x0, xF = self._xs[0], self._xs[-1]
55405543
y0, yF = self._ys[0], self._ys[-1]
@@ -6998,7 +7001,7 @@ cdef class _TreeMesh:
69987001
"""
69997002
return self.get_cells_in_aabb(*rectangle.reshape(self.dim, 2).T)
70007003

7001-
def _error_if_not_finalized(self, method: str, is_property: bool):
7004+
def _error_if_not_finalized(self, method: str):
70027005
"""
70037006
Raise error if mesh is not finalized.
70047007
"""

discretize/tree_mesh.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,12 @@
9292
from discretize.base import BaseTensorMesh
9393
from discretize.operators import InnerProducts, DiffOperators
9494
from discretize.mixins import InterfaceMixins, TreeMeshIO
95-
from discretize._extensions.tree_ext import _TreeMesh, TreeCell # NOQA F401
95+
from discretize._extensions.tree_ext import _TreeMesh, TreeCell, TreeMeshNotFinalizedError # NOQA F401
9696
import numpy as np
9797
import scipy.sparse as sp
9898
from discretize.utils.code_utils import deprecate_property
9999
from scipy.spatial import Delaunay
100100

101-
102101
class TreeMesh(
103102
_TreeMesh,
104103
InnerProducts,
@@ -768,7 +767,7 @@ def total_nodes(self):
768767
(n_total_nodes, dim) numpy.ndarray of float
769768
Gridded hanging and non-hanging node locations
770769
"""
771-
self._error_if_not_finalized("total_nodes", is_property=True)
770+
self._error_if_not_finalized("total_nodes")
772771
return np.vstack((self.nodes, self.hanging_nodes))
773772

774773
@property

tests/tree/test_safeguards.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import pytest
77

88
from discretize import TreeMesh
9+
from discretize.tree_mesh import TreeMeshNotFinalizedError
910

1011

1112
@pytest.fixture
@@ -82,10 +83,9 @@ def test_errors(self, mesh, prop_name, refine):
8283
if refine:
8384
refine_mesh(mesh)
8485
msg = re.escape(
85-
f"The `{prop_name}` property cannot be accessed before "
86-
"the mesh is finalized."
86+
f"`TreeMesh.{prop_name}` requires a finalized mesh. "
8787
)
88-
with pytest.raises(AttributeError, match=msg):
88+
with pytest.raises(TreeMeshNotFinalizedError, match=msg):
8989
getattr(mesh, prop_name)
9090

9191
@pytest.mark.parametrize("prop_name", PROPERTIES)

0 commit comments

Comments
 (0)