66"""
77
88import time
9+
910import numpy as np
1011import pytest
1112from scipy .spatial import Delaunay
1213
13- from flopy .discretization import StructuredGrid , VertexGrid , UnstructuredGrid
14+ from flopy .discretization import StructuredGrid , UnstructuredGrid , VertexGrid
1415from flopy .utils .geospatial_index import GeospatialIndex
1516
1617
@@ -28,6 +29,7 @@ def wrapper(*args, **kwargs):
2829def old_vertex_intersect (grid , x , y ):
2930 """Old O(n²) approach for VertexGrid (no KD-tree)."""
3031 from matplotlib .path import Path
32+
3133 from flopy .utils .geometry import is_clockwise
3234
3335 xv , yv , zv = grid .xyzvertices
@@ -69,7 +71,10 @@ def new_vertex_intersect(grid, x, y):
6971
7072
7173def test_benchmark_vertex_grid_small ():
72- """Benchmark on small VertexGrid (30 cells) - verify correctness and measure speedup."""
74+ """Benchmark on small VertexGrid (30 cells).
75+
76+ Verify correctness and measure speedup.
77+ """
7378 # Create triangular grid using Delaunay
7479 np .random .seed (42 )
7580 n_points = 30
@@ -104,31 +109,47 @@ def test_benchmark_vertex_grid_small():
104109
105110 # CRITICAL: Verify results are identical (treating None and nan as equivalent)
106111 # Convert both to use nan for unfound points
107- results_old_normalized = np .array ([r if r is not None else np .nan for r in results_old ], dtype = float )
108- results_new_normalized = np .array ([r if not (isinstance (r , float ) and np .isnan (r )) else np .nan for r in results_new ], dtype = float )
112+ results_old_normalized = np .array (
113+ [r if r is not None else np .nan for r in results_old ],
114+ dtype = float
115+ )
116+ results_new_normalized = np .array (
117+ [
118+ r if not (isinstance (r , float ) and np .isnan (r ))
119+ else np .nan
120+ for r in results_new
121+ ],
122+ dtype = float
123+ )
109124
110125 # Check matches including nan==nan comparisons
111126 both_valid = ~ np .isnan (results_old_normalized ) & ~ np .isnan (results_new_normalized )
112127 both_invalid = np .isnan (results_old_normalized ) & np .isnan (results_new_normalized )
113- matches = np .sum ((results_old_normalized == results_new_normalized ) & both_valid ) + np .sum (both_invalid )
128+ matches = (
129+ np .sum ((results_old_normalized == results_new_normalized ) & both_valid )
130+ + np .sum (both_invalid )
131+ )
114132 mismatches = n_test - matches
115133
116134 print (f"\n { '=' * 60 } " )
117135 print (f"Small VertexGrid Test ({ ncells } cells, { n_test } points)" )
118136 print (f"{ '=' * 60 } " )
119- print (f "CORRECTNESS:" )
137+ print ("CORRECTNESS:" )
120138 print (f" Matching results: { matches } /{ n_test } ({ 100 * matches / n_test :.1f} %)" )
121139 print (f" Mismatches: { mismatches } " )
122140 if mismatches > 0 :
123- print (f " ERROR: Methods produced different results!" )
141+ print (" ERROR: Methods produced different results!" )
124142 for i in range (len (results_old_normalized )):
125143 old_val = results_old_normalized [i ]
126144 new_val = results_new_normalized [i ]
127145 if not ((old_val == new_val ) or (np .isnan (old_val ) and np .isnan (new_val ))):
128- print (f" Point { i } : ({ test_x [i ]:.2f} , { test_y [i ]:.2f} ) -> Old={ results_old [i ]} , New={ results_new [i ]} " )
146+ print (
147+ f" Point { i } : ({ test_x [i ]:.2f} , { test_y [i ]:.2f} ) -> "
148+ f"Old={ results_old [i ]} , New={ results_new [i ]} "
149+ )
129150
130151 speedup = time_old / time_new
131- print (f "\n PERFORMANCE:" )
152+ print ("\n PERFORMANCE:" )
132153 print (f" Old method (O(n) loop): { time_old * 1000 :.2f} ms" )
133154 print (f" New method (KD-tree + Hull): { time_new * 1000 :.2f} ms" )
134155 print (f" Speedup: { speedup :.2f} x" )
@@ -140,7 +161,10 @@ def test_benchmark_vertex_grid_small():
140161
141162
142163def test_benchmark_vertex_grid_medium ():
143- """Benchmark on medium VertexGrid (500 cells) - verify correctness and measure speedup."""
164+ """Benchmark on medium VertexGrid (~200 cells).
165+
166+ Verify correctness and measure speedup.
167+ """
144168 # Create larger triangular grid
145169 np .random .seed (42 )
146170 n_points = 200
@@ -175,36 +199,52 @@ def test_benchmark_vertex_grid_medium():
175199
176200 # CRITICAL: Verify results are identical (treating None and nan as equivalent)
177201 # Convert both to use nan for unfound points
178- results_old_normalized = np .array ([r if r is not None else np .nan for r in results_old ], dtype = float )
179- results_new_normalized = np .array ([r if not (isinstance (r , float ) and np .isnan (r )) else np .nan for r in results_new ], dtype = float )
202+ results_old_normalized = np .array (
203+ [r if r is not None else np .nan for r in results_old ],
204+ dtype = float
205+ )
206+ results_new_normalized = np .array (
207+ [
208+ r if not (isinstance (r , float ) and np .isnan (r ))
209+ else np .nan
210+ for r in results_new
211+ ],
212+ dtype = float
213+ )
180214
181215 # Check matches including nan==nan comparisons
182216 both_valid = ~ np .isnan (results_old_normalized ) & ~ np .isnan (results_new_normalized )
183217 both_invalid = np .isnan (results_old_normalized ) & np .isnan (results_new_normalized )
184- matches = np .sum ((results_old_normalized == results_new_normalized ) & both_valid ) + np .sum (both_invalid )
218+ matches = (
219+ np .sum ((results_old_normalized == results_new_normalized ) & both_valid )
220+ + np .sum (both_invalid )
221+ )
185222 mismatches = n_test - matches
186223
187224 print (f"\n { '=' * 60 } " )
188225 print (f"Medium VertexGrid Test ({ ncells } cells, { n_test } points)" )
189226 print (f"{ '=' * 60 } " )
190- print (f "CORRECTNESS:" )
227+ print ("CORRECTNESS:" )
191228 print (f" Matching results: { matches } /{ n_test } ({ 100 * matches / n_test :.1f} %)" )
192229 print (f" Mismatches: { mismatches } " )
193230 if mismatches > 0 :
194- print (f " ERROR: Methods produced different results!" )
231+ print (" ERROR: Methods produced different results!" )
195232 # Show first 5 mismatches
196233 count = 0
197234 for i in range (len (results_old_normalized )):
198235 old_val = results_old_normalized [i ]
199236 new_val = results_new_normalized [i ]
200237 if not ((old_val == new_val ) or (np .isnan (old_val ) and np .isnan (new_val ))):
201- print (f" Point { i } : ({ test_x [i ]:.2f} , { test_y [i ]:.2f} ) -> Old={ results_old [i ]} , New={ results_new [i ]} " )
238+ print (
239+ f" Point { i } : ({ test_x [i ]:.2f} , { test_y [i ]:.2f} ) -> "
240+ f"Old={ results_old [i ]} , New={ results_new [i ]} "
241+ )
202242 count += 1
203243 if count >= 5 :
204244 break
205245
206246 speedup = time_old / time_new
207- print (f "\n PERFORMANCE:" )
247+ print ("\n PERFORMANCE:" )
208248 print (f" Old method (O(n) loop): { time_old * 1000 :.2f} ms" )
209249 print (f" New method (KD-tree + Hull): { time_new * 1000 :.2f} ms" )
210250 print (f" Speedup: { speedup :.2f} x" )
@@ -252,23 +292,36 @@ def test_benchmark_vertex_grid_large():
252292
253293 # CRITICAL: Verify results are identical (treating None and nan as equivalent)
254294 # Convert both to use nan for unfound points
255- results_old_normalized = np .array ([r if r is not None else np .nan for r in results_old ], dtype = float )
256- results_new_normalized = np .array ([r if not (isinstance (r , float ) and np .isnan (r )) else np .nan for r in results_new ], dtype = float )
295+ results_old_normalized = np .array (
296+ [r if r is not None else np .nan for r in results_old ],
297+ dtype = float
298+ )
299+ results_new_normalized = np .array (
300+ [
301+ r if not (isinstance (r , float ) and np .isnan (r ))
302+ else np .nan
303+ for r in results_new
304+ ],
305+ dtype = float
306+ )
257307
258308 # Check matches including nan==nan comparisons
259309 both_valid = ~ np .isnan (results_old_normalized ) & ~ np .isnan (results_new_normalized )
260310 both_invalid = np .isnan (results_old_normalized ) & np .isnan (results_new_normalized )
261- matches = np .sum ((results_old_normalized == results_new_normalized ) & both_valid ) + np .sum (both_invalid )
311+ matches = (
312+ np .sum ((results_old_normalized == results_new_normalized ) & both_valid )
313+ + np .sum (both_invalid )
314+ )
262315 mismatches = n_test - matches
263316
264317 speedup = time_old / time_new
265318 print (f"\n { '=' * 60 } " )
266319 print (f"Large VertexGrid Benchmark ({ ncells } cells, { n_test } points)" )
267320 print (f"{ '=' * 60 } " )
268- print (f "CORRECTNESS:" )
321+ print ("CORRECTNESS:" )
269322 print (f" Matching results: { matches } /{ n_test } ({ 100 * matches / n_test :.1f} %)" )
270323 print (f" Mismatches: { mismatches } " )
271- print (f "\n PERFORMANCE:" )
324+ print ("\n PERFORMANCE:" )
272325 print (f" Old method (O(n) loop): { time_old * 1000 :.2f} ms" )
273326 print (f" New method (KD-tree + Hull): { time_new * 1000 :.2f} ms" )
274327 print (f" Speedup: { speedup :.2f} x" )
@@ -312,14 +365,19 @@ def test_benchmark_structured_grid():
312365 rows , cols = results_old
313366 results_old_array = np .where (np .isnan (rows ), - 1 , rows * ncol + cols ).astype (int )
314367 else :
315- results_old_array = np .array ([r if not (np .isscalar (r ) and np .isnan (r )) else - 1 for r in results_old ])
368+ results_old_array = np .array (
369+ [r if not (np .isscalar (r ) and np .isnan (r )) else - 1 for r in results_old ]
370+ )
316371
317372 # Verify results match
318373 assert np .array_equal (results_new_array , results_old_array ), "Results don't match!"
319374
320375 speedup = time_old / time_new
321376 print (f"\n { '=' * 60 } " )
322- print (f"StructuredGrid Benchmark ({ nrow } ×{ ncol } = { nrow * ncol } cells, { n_test } points)" )
377+ print (
378+ f"StructuredGrid Benchmark ({ nrow } x{ ncol } = { nrow * ncol } "
379+ f"cells, { n_test } points)"
380+ )
323381 print (f"{ '=' * 60 } " )
324382 print (f"Old method (optimized): { time_old * 1000 :.2f} ms" )
325383 print (f"New method (KD-tree + Hull): { time_new * 1000 :.2f} ms" )
0 commit comments