2525import underworld3 as uw
2626
2727
28+ def extract_scalar (result ):
29+ """
30+ Extract a scalar value from evaluate() result.
31+
32+ evaluate() returns UnitAwareArray with shape (1,1,1) for single point evaluation.
33+ This helper extracts the scalar value properly.
34+ """
35+ if hasattr (result , 'flat' ):
36+ # UnitAwareArray or numpy array - extract first element
37+ scalar = result .flat [0 ]
38+ if hasattr (scalar , 'item' ):
39+ return scalar .item ()
40+ return float (scalar )
41+ elif hasattr (result , 'item' ):
42+ return result .item ()
43+ else :
44+ return float (result )
45+
46+
47+ def convert_and_extract (result , target_units ):
48+ """
49+ Convert result to target units and extract scalar.
50+
51+ Returns the scalar value in the specified units.
52+ """
53+ if hasattr (result , 'to' ):
54+ converted = result .to (target_units )
55+ return extract_scalar (converted )
56+ else :
57+ # Assume result is already in base units (meters, seconds, etc.)
58+ return extract_scalar (result )
59+
60+
2861@pytest .mark .tier_b # Validated - testing nondimensional scaling
2962@pytest .mark .level_2 # Uses nondimensional model - intermediate complexity
3063class TestEvaluateNondimensionalScaling :
@@ -96,11 +129,10 @@ def test_uwquantity_1_cm(self):
96129
97130 # Convert to cm for comparison
98131 if hasattr (result , 'to' ):
99- result_cm = result .to ('cm' )
100- value = float (result_cm .value ) if hasattr (result_cm , 'value' ) else float (result_cm )
132+ value = convert_and_extract (result , 'cm' )
101133 else :
102134 # If returned as meters
103- value_m = float (result )
135+ value_m = extract_scalar (result )
104136 value = value_m * 100 # m to cm
105137
106138 assert np .allclose (value , 1.0 , rtol = 1e-6 ), \
@@ -114,10 +146,9 @@ def test_uwquantity_1_year(self):
114146 expected_seconds = 31557600.0 # 1 year in seconds
115147
116148 if hasattr (result , 'to' ):
117- result_s = result .to ('s' )
118- value = float (result_s .value ) if hasattr (result_s , 'value' ) else float (result_s )
149+ value = convert_and_extract (result , 's' )
119150 else :
120- value = float (result )
151+ value = extract_scalar (result )
121152
122153 assert np .allclose (value , expected_seconds , rtol = 1e-6 ), \
123154 f"Expected { expected_seconds } seconds, got { value } seconds"
@@ -135,11 +166,10 @@ def test_uwquantity_at_length_scale(self):
135166
136167 # Convert to km for comparison
137168 if hasattr (result , 'to' ):
138- result_km = result .to ('km' )
139- value = float (result_km .value ) if hasattr (result_km , 'value' ) else float (result_km )
169+ value = convert_and_extract (result , 'km' )
140170 else :
141171 # If returned as meters
142- value_m = float (result )
172+ value_m = extract_scalar (result )
143173 value = value_m / 1000 # m to km
144174
145175 assert np .allclose (value , 2900.0 , rtol = 1e-6 ), \
@@ -160,10 +190,9 @@ def test_uwexpression_1_second(self):
160190
161191 # Should be 1 second
162192 if hasattr (result , 'to' ):
163- result_s = result .to ('s' )
164- value = float (result_s .value ) if hasattr (result_s , 'value' ) else float (result_s )
193+ value = convert_and_extract (result , 's' )
165194 else :
166- value = float (result )
195+ value = extract_scalar (result )
167196
168197 assert np .allclose (value , 1.0 , rtol = 1e-6 ), \
169198 f"Expected 1 second, got { value } seconds (Bug: was returning 3.15e13 s = 1 Myr!)"
@@ -175,11 +204,10 @@ def test_uwexpression_at_time_scale(self):
175204
176205 # Convert to Myr for comparison
177206 if hasattr (result , 'to' ):
178- result_Myr = result .to ('Myr' )
179- value = float (result_Myr .value ) if hasattr (result_Myr , 'value' ) else float (result_Myr )
207+ value = convert_and_extract (result , 'Myr' )
180208 else :
181209 # If returned as seconds
182- value_s = float (result )
210+ value_s = extract_scalar (result )
183211 value = value_s / 31557600000000.0 # s to Myr
184212
185213 assert np .allclose (value , 1.0 , rtol = 1e-6 ), \
@@ -191,10 +219,9 @@ def test_uwquantity_temperature(self):
191219
192220 # Should be 1000 K
193221 if hasattr (result , 'to' ):
194- result_K = result .to ('K' )
195- value = float (result_K .value ) if hasattr (result_K , 'value' ) else float (result_K )
222+ value = convert_and_extract (result , 'K' )
196223 else :
197- value = float (result )
224+ value = extract_scalar (result )
198225
199226 assert np .allclose (value , 1000.0 , rtol = 1e-6 ), \
200227 f"Expected 1000 K, got { value } K"
@@ -205,11 +232,10 @@ def test_uwquantity_small_length(self):
205232
206233 # Convert to mm for comparison
207234 if hasattr (result , 'to' ):
208- result_mm = result .to ('mm' )
209- value = float (result_mm .value ) if hasattr (result_mm , 'value' ) else float (result_mm )
235+ value = convert_and_extract (result , 'mm' )
210236 else :
211237 # If returned as meters
212- value_m = float (result )
238+ value_m = extract_scalar (result )
213239 value = value_m * 1000 # m to mm
214240
215241 assert np .allclose (value , 1.0 , rtol = 1e-6 ), \
0 commit comments