earthsciencekit 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. earthsciencekit/__init__.py +6 -0
  2. earthsciencekit/_validation.py +62 -0
  3. earthsciencekit/atmosphere/__init__.py +57 -0
  4. earthsciencekit/atmosphere/core/__init__.py +5 -0
  5. earthsciencekit/atmosphere/core/base.py +10 -0
  6. earthsciencekit/atmosphere/systems/__init__.py +1 -0
  7. earthsciencekit/atmosphere/systems/dynamics.py +208 -0
  8. earthsciencekit/atmosphere/systems/hydrostatics.py +214 -0
  9. earthsciencekit/atmosphere/systems/moisture.py +162 -0
  10. earthsciencekit/atmosphere/systems/thermodynamics.py +222 -0
  11. earthsciencekit/atmosphere/tests/__init__.py +0 -0
  12. earthsciencekit/atmosphere/tests/test_models.py +741 -0
  13. earthsciencekit/atmosphere/tests/test_physics.py +81 -0
  14. earthsciencekit/atmosphere/visualizers/__init__.py +9 -0
  15. earthsciencekit/climate/__init__.py +63 -0
  16. earthsciencekit/climate/core/__init__.py +5 -0
  17. earthsciencekit/climate/core/base.py +10 -0
  18. earthsciencekit/climate/systems/__init__.py +1 -0
  19. earthsciencekit/climate/systems/carbon.py +76 -0
  20. earthsciencekit/climate/systems/forcing.py +124 -0
  21. earthsciencekit/climate/systems/radiation.py +214 -0
  22. earthsciencekit/climate/systems/response.py +402 -0
  23. earthsciencekit/climate/systems/sea_level.py +77 -0
  24. earthsciencekit/climate/tests/__init__.py +0 -0
  25. earthsciencekit/climate/tests/test_models.py +1015 -0
  26. earthsciencekit/climate/tests/test_physics.py +16 -0
  27. earthsciencekit/climate/visualizers/__init__.py +9 -0
  28. earthsciencekit/constants/__init__.py +23 -0
  29. earthsciencekit/geophysics/__init__.py +77 -0
  30. earthsciencekit/geophysics/core/__init__.py +5 -0
  31. earthsciencekit/geophysics/core/base.py +10 -0
  32. earthsciencekit/geophysics/systems/__init__.py +1 -0
  33. earthsciencekit/geophysics/systems/deformation.py +161 -0
  34. earthsciencekit/geophysics/systems/dynamo.py +159 -0
  35. earthsciencekit/geophysics/systems/figure.py +292 -0
  36. earthsciencekit/geophysics/systems/gravity.py +235 -0
  37. earthsciencekit/geophysics/systems/magnetism.py +354 -0
  38. earthsciencekit/geophysics/tests/__init__.py +0 -0
  39. earthsciencekit/geophysics/tests/test_models.py +898 -0
  40. earthsciencekit/geophysics/tests/test_physics.py +171 -0
  41. earthsciencekit/geophysics/visualizers/__init__.py +9 -0
  42. earthsciencekit/integrators/__init__.py +62 -0
  43. earthsciencekit/oceanography/__init__.py +61 -0
  44. earthsciencekit/oceanography/core/__init__.py +5 -0
  45. earthsciencekit/oceanography/core/base.py +10 -0
  46. earthsciencekit/oceanography/systems/__init__.py +1 -0
  47. earthsciencekit/oceanography/systems/circulation.py +388 -0
  48. earthsciencekit/oceanography/systems/hydrography.py +212 -0
  49. earthsciencekit/oceanography/systems/inertial.py +86 -0
  50. earthsciencekit/oceanography/systems/waves.py +281 -0
  51. earthsciencekit/oceanography/tests/__init__.py +0 -0
  52. earthsciencekit/oceanography/tests/test_models.py +916 -0
  53. earthsciencekit/oceanography/tests/test_physics.py +102 -0
  54. earthsciencekit/oceanography/visualizers/__init__.py +9 -0
  55. earthsciencekit/plate_tectonics/__init__.py +59 -0
  56. earthsciencekit/plate_tectonics/core/__init__.py +5 -0
  57. earthsciencekit/plate_tectonics/core/base.py +10 -0
  58. earthsciencekit/plate_tectonics/systems/__init__.py +1 -0
  59. earthsciencekit/plate_tectonics/systems/boundaries.py +201 -0
  60. earthsciencekit/plate_tectonics/systems/cooling.py +238 -0
  61. earthsciencekit/plate_tectonics/systems/isostasy.py +157 -0
  62. earthsciencekit/plate_tectonics/systems/kinematics.py +290 -0
  63. earthsciencekit/plate_tectonics/tests/__init__.py +0 -0
  64. earthsciencekit/plate_tectonics/tests/test_models.py +920 -0
  65. earthsciencekit/plate_tectonics/tests/test_physics.py +94 -0
  66. earthsciencekit/plate_tectonics/visualizers/__init__.py +9 -0
  67. earthsciencekit/py.typed +0 -0
  68. earthsciencekit/results.py +73 -0
  69. earthsciencekit/seismology/__init__.py +59 -0
  70. earthsciencekit/seismology/core/__init__.py +5 -0
  71. earthsciencekit/seismology/core/base.py +10 -0
  72. earthsciencekit/seismology/systems/__init__.py +1 -0
  73. earthsciencekit/seismology/systems/interfaces.py +102 -0
  74. earthsciencekit/seismology/systems/rays.py +221 -0
  75. earthsciencekit/seismology/systems/sources.py +249 -0
  76. earthsciencekit/seismology/systems/waves.py +268 -0
  77. earthsciencekit/seismology/tests/__init__.py +0 -0
  78. earthsciencekit/seismology/tests/test_models.py +852 -0
  79. earthsciencekit/seismology/tests/test_physics.py +100 -0
  80. earthsciencekit/seismology/visualizers/__init__.py +9 -0
  81. earthsciencekit/tests/__init__.py +0 -0
  82. earthsciencekit/tests/test_core.py +181 -0
  83. earthsciencekit/tests/test_relations.py +36 -0
  84. earthsciencekit/units/__init__.py +66 -0
  85. earthsciencekit/visualizers/__init__.py +45 -0
  86. earthsciencekit/volcanology/__init__.py +61 -0
  87. earthsciencekit/volcanology/core/__init__.py +5 -0
  88. earthsciencekit/volcanology/core/base.py +10 -0
  89. earthsciencekit/volcanology/systems/__init__.py +1 -0
  90. earthsciencekit/volcanology/systems/eruptions.py +161 -0
  91. earthsciencekit/volcanology/systems/geochemistry.py +226 -0
  92. earthsciencekit/volcanology/systems/geochronology.py +304 -0
  93. earthsciencekit/volcanology/systems/magma.py +190 -0
  94. earthsciencekit/volcanology/tests/__init__.py +0 -0
  95. earthsciencekit/volcanology/tests/test_models.py +485 -0
  96. earthsciencekit/volcanology/tests/test_physics.py +176 -0
  97. earthsciencekit/volcanology/visualizers/__init__.py +9 -0
  98. earthsciencekit-0.2.0.dist-info/METADATA +127 -0
  99. earthsciencekit-0.2.0.dist-info/RECORD +102 -0
  100. earthsciencekit-0.2.0.dist-info/WHEEL +5 -0
  101. earthsciencekit-0.2.0.dist-info/licenses/LICENSE +15 -0
  102. earthsciencekit-0.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,741 @@
1
+ """Golden checks and invalid-input contracts for every public model."""
2
+
3
+ import numpy as np
4
+ import pytest
5
+
6
+ from earthsciencekit import atmosphere as domain
7
+ from earthsciencekit.constants import EPSILON_WATER
8
+
9
+
10
+ def test_dry_air_density_reference():
11
+ result = domain.dry_air_density(*[86115.0, 300])
12
+ np.testing.assert_allclose(result, 1, rtol=1e-11, atol=1e-12)
13
+
14
+
15
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
16
+ def test_dry_air_density_rejects_invalid(bad):
17
+ args = [86115.0, 300]
18
+ args[0] = bad
19
+ with pytest.raises(ValueError):
20
+ domain.dry_air_density(*args)
21
+
22
+
23
+ def test_scale_height_reference():
24
+ result = domain.scale_height(*[300, 10])
25
+ np.testing.assert_allclose(result, 8611.5, rtol=1e-11, atol=1e-12)
26
+
27
+
28
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
29
+ def test_scale_height_rejects_invalid(bad):
30
+ args = [300, 10]
31
+ args[0] = bad
32
+ with pytest.raises(ValueError):
33
+ domain.scale_height(*args)
34
+
35
+
36
+ def test_barometric_pressure_reference():
37
+ result = domain.barometric_pressure(*[100000.0, 0, 300, 10])
38
+ np.testing.assert_allclose(result, 1e5, rtol=1e-11, atol=1e-12)
39
+
40
+
41
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
42
+ def test_barometric_pressure_rejects_invalid(bad):
43
+ args = [100000.0, 0, 300, 10]
44
+ args[0] = bad
45
+ with pytest.raises(ValueError):
46
+ domain.barometric_pressure(*args)
47
+
48
+
49
+ def test_potential_temperature_reference():
50
+ result = domain.potential_temperature(*[300, 100000.0, 100000.0])
51
+ np.testing.assert_allclose(result, 300, rtol=1e-11, atol=1e-12)
52
+
53
+
54
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
55
+ def test_potential_temperature_rejects_invalid(bad):
56
+ args = [300, 100000.0, 100000.0]
57
+ args[0] = bad
58
+ with pytest.raises(ValueError):
59
+ domain.potential_temperature(*args)
60
+
61
+
62
+ def test_temperature_from_potential_reference():
63
+ result = domain.temperature_from_potential(*[300, 100000.0, 100000.0])
64
+ np.testing.assert_allclose(result, 300, rtol=1e-11, atol=1e-12)
65
+
66
+
67
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
68
+ def test_temperature_from_potential_rejects_invalid(bad):
69
+ args = [300, 100000.0, 100000.0]
70
+ args[0] = bad
71
+ with pytest.raises(ValueError):
72
+ domain.temperature_from_potential(*args)
73
+
74
+
75
+ def test_dry_adiabatic_lapse_rate_reference():
76
+ result = domain.dry_adiabatic_lapse_rate(*[10, 1000])
77
+ np.testing.assert_allclose(result, 0.01, rtol=1e-11, atol=1e-12)
78
+
79
+
80
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
81
+ def test_dry_adiabatic_lapse_rate_rejects_invalid(bad):
82
+ args = [10, 1000]
83
+ args[0] = bad
84
+ with pytest.raises(ValueError):
85
+ domain.dry_adiabatic_lapse_rate(*args)
86
+
87
+
88
+ def test_saturation_vapor_pressure_reference():
89
+ result = domain.saturation_vapor_pressure(*[273.15])
90
+ np.testing.assert_allclose(result, 611.2, rtol=1e-11, atol=1e-12)
91
+
92
+
93
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
94
+ def test_saturation_vapor_pressure_rejects_invalid(bad):
95
+ args = [273.15]
96
+ args[0] = bad
97
+ with pytest.raises(ValueError):
98
+ domain.saturation_vapor_pressure(*args)
99
+
100
+
101
+ def test_mixing_ratio_reference():
102
+ result = domain.mixing_ratio(*[1000, 100000])
103
+ np.testing.assert_allclose(result, EPSILON_WATER / 99, rtol=1e-11, atol=1e-12)
104
+
105
+
106
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
107
+ def test_mixing_ratio_rejects_invalid(bad):
108
+ args = [1000, 100000]
109
+ args[0] = bad
110
+ with pytest.raises(ValueError):
111
+ domain.mixing_ratio(*args)
112
+
113
+
114
+ def test_specific_humidity_reference():
115
+ result = domain.specific_humidity(*[1])
116
+ np.testing.assert_allclose(result, 0.5, rtol=1e-11, atol=1e-12)
117
+
118
+
119
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
120
+ def test_specific_humidity_rejects_invalid(bad):
121
+ args = [1]
122
+ args[0] = bad
123
+ with pytest.raises(ValueError):
124
+ domain.specific_humidity(*args)
125
+
126
+
127
+ def test_virtual_temperature_reference():
128
+ result = domain.virtual_temperature(*[300, 0])
129
+ np.testing.assert_allclose(result, 300, rtol=1e-11, atol=1e-12)
130
+
131
+
132
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
133
+ def test_virtual_temperature_rejects_invalid(bad):
134
+ args = [300, 0]
135
+ args[0] = bad
136
+ with pytest.raises(ValueError):
137
+ domain.virtual_temperature(*args)
138
+
139
+
140
+ def test_relative_humidity_reference():
141
+ result = domain.relative_humidity(*[500, 1000])
142
+ np.testing.assert_allclose(result, 0.5, rtol=1e-11, atol=1e-12)
143
+
144
+
145
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
146
+ def test_relative_humidity_rejects_invalid(bad):
147
+ args = [500, 1000]
148
+ args[0] = bad
149
+ with pytest.raises(ValueError):
150
+ domain.relative_humidity(*args)
151
+
152
+
153
+ def test_coriolis_parameter_reference():
154
+ result = domain.coriolis_parameter(*[0])
155
+ np.testing.assert_allclose(result, 0, rtol=1e-11, atol=1e-12)
156
+
157
+
158
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
159
+ def test_coriolis_parameter_rejects_invalid(bad):
160
+ args = [0]
161
+ args[0] = bad
162
+ with pytest.raises(ValueError):
163
+ domain.coriolis_parameter(*args)
164
+
165
+
166
+ def test_brunt_vaisala_squared_reference():
167
+ result = domain.brunt_vaisala_squared(*[300, 0.003, 10])
168
+ np.testing.assert_allclose(result, 0.0001, rtol=1e-11, atol=1e-12)
169
+
170
+
171
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
172
+ def test_brunt_vaisala_squared_rejects_invalid(bad):
173
+ args = [300, 0.003, 10]
174
+ args[0] = bad
175
+ with pytest.raises(ValueError):
176
+ domain.brunt_vaisala_squared(*args)
177
+
178
+
179
+ def test_geostrophic_speed_reference():
180
+ result = domain.geostrophic_speed(*[0.001, 1, 0.0001])
181
+ np.testing.assert_allclose(result, 10, rtol=1e-11, atol=1e-12)
182
+
183
+
184
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
185
+ def test_geostrophic_speed_rejects_invalid(bad):
186
+ args = [0.001, 1, 0.0001]
187
+ args[0] = bad
188
+ with pytest.raises(ValueError):
189
+ domain.geostrophic_speed(*args)
190
+
191
+
192
+ def test_rossby_number_reference():
193
+ result = domain.rossby_number(*[10, 1000000.0, 0.0001])
194
+ np.testing.assert_allclose(result, 0.1, rtol=1e-11, atol=1e-12)
195
+
196
+
197
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
198
+ def test_rossby_number_rejects_invalid(bad):
199
+ args = [10, 1000000.0, 0.0001]
200
+ args[0] = bad
201
+ with pytest.raises(ValueError):
202
+ domain.rossby_number(*args)
203
+
204
+
205
+ def test_dry_air_density_broadcasting():
206
+ args = [86115.0, 300]
207
+ reference = domain.dry_air_density(*args)
208
+ args[0] = np.full((2, 1), args[0])
209
+ result = domain.dry_air_density(*args)
210
+ assert result.shape == (2, 1)
211
+ np.testing.assert_allclose(result, reference)
212
+
213
+
214
+ def test_dry_air_density_pressure_physical_bound():
215
+ args = [86115.0, 300]
216
+ args[0] = 0
217
+ with pytest.raises(ValueError):
218
+ domain.dry_air_density(*args)
219
+
220
+
221
+ def test_dry_air_density_temperature_physical_bound():
222
+ args = [86115.0, 300]
223
+ args[1] = 0
224
+ with pytest.raises(ValueError):
225
+ domain.dry_air_density(*args)
226
+
227
+
228
+ def test_scale_height_broadcasting():
229
+ args = [300, 10]
230
+ reference = domain.scale_height(*args)
231
+ args[0] = np.full((2, 1), args[0])
232
+ result = domain.scale_height(*args)
233
+ assert result.shape == (2, 1)
234
+ np.testing.assert_allclose(result, reference)
235
+
236
+
237
+ def test_scale_height_temperature_physical_bound():
238
+ args = [300, 10]
239
+ args[0] = 0
240
+ with pytest.raises(ValueError):
241
+ domain.scale_height(*args)
242
+
243
+
244
+ def test_scale_height_gravity_physical_bound():
245
+ args = [300, 10]
246
+ args[1] = 0
247
+ with pytest.raises(ValueError):
248
+ domain.scale_height(*args)
249
+
250
+
251
+ def test_barometric_pressure_broadcasting():
252
+ args = [100000.0, 0, 300, 10]
253
+ reference = domain.barometric_pressure(*args)
254
+ args[0] = np.full((2, 1), args[0])
255
+ result = domain.barometric_pressure(*args)
256
+ assert result.shape == (2, 1)
257
+ np.testing.assert_allclose(result, reference)
258
+
259
+
260
+ def test_barometric_pressure_surface_pressure_physical_bound():
261
+ args = [100000.0, 0, 300, 10]
262
+ args[0] = 0
263
+ with pytest.raises(ValueError):
264
+ domain.barometric_pressure(*args)
265
+
266
+
267
+ def test_barometric_pressure_temperature_physical_bound():
268
+ args = [100000.0, 0, 300, 10]
269
+ args[2] = 0
270
+ with pytest.raises(ValueError):
271
+ domain.barometric_pressure(*args)
272
+
273
+
274
+ def test_barometric_pressure_gravity_physical_bound():
275
+ args = [100000.0, 0, 300, 10]
276
+ args[3] = 0
277
+ with pytest.raises(ValueError):
278
+ domain.barometric_pressure(*args)
279
+
280
+
281
+ def test_potential_temperature_broadcasting():
282
+ args = [300, 100000.0, 100000.0]
283
+ reference = domain.potential_temperature(*args)
284
+ args[0] = np.full((2, 1), args[0])
285
+ result = domain.potential_temperature(*args)
286
+ assert result.shape == (2, 1)
287
+ np.testing.assert_allclose(result, reference)
288
+
289
+
290
+ def test_potential_temperature_temperature_physical_bound():
291
+ args = [300, 100000.0, 100000.0]
292
+ args[0] = 0
293
+ with pytest.raises(ValueError):
294
+ domain.potential_temperature(*args)
295
+
296
+
297
+ def test_potential_temperature_pressure_physical_bound():
298
+ args = [300, 100000.0, 100000.0]
299
+ args[1] = 0
300
+ with pytest.raises(ValueError):
301
+ domain.potential_temperature(*args)
302
+
303
+
304
+ def test_potential_temperature_reference_pressure_physical_bound():
305
+ args = [300, 100000.0, 100000.0]
306
+ args[2] = 0
307
+ with pytest.raises(ValueError):
308
+ domain.potential_temperature(*args)
309
+
310
+
311
+ def test_temperature_from_potential_broadcasting():
312
+ args = [300, 100000.0, 100000.0]
313
+ reference = domain.temperature_from_potential(*args)
314
+ args[0] = np.full((2, 1), args[0])
315
+ result = domain.temperature_from_potential(*args)
316
+ assert result.shape == (2, 1)
317
+ np.testing.assert_allclose(result, reference)
318
+
319
+
320
+ def test_temperature_from_potential_potential_temperature_physical_bound():
321
+ args = [300, 100000.0, 100000.0]
322
+ args[0] = 0
323
+ with pytest.raises(ValueError):
324
+ domain.temperature_from_potential(*args)
325
+
326
+
327
+ def test_temperature_from_potential_pressure_physical_bound():
328
+ args = [300, 100000.0, 100000.0]
329
+ args[1] = 0
330
+ with pytest.raises(ValueError):
331
+ domain.temperature_from_potential(*args)
332
+
333
+
334
+ def test_temperature_from_potential_reference_pressure_physical_bound():
335
+ args = [300, 100000.0, 100000.0]
336
+ args[2] = 0
337
+ with pytest.raises(ValueError):
338
+ domain.temperature_from_potential(*args)
339
+
340
+
341
+ def test_dry_adiabatic_lapse_rate_broadcasting():
342
+ args = [10, 1000]
343
+ reference = domain.dry_adiabatic_lapse_rate(*args)
344
+ args[0] = np.full((2, 1), args[0])
345
+ result = domain.dry_adiabatic_lapse_rate(*args)
346
+ assert result.shape == (2, 1)
347
+ np.testing.assert_allclose(result, reference)
348
+
349
+
350
+ def test_dry_adiabatic_lapse_rate_gravity_physical_bound():
351
+ args = [10, 1000]
352
+ args[0] = 0
353
+ with pytest.raises(ValueError):
354
+ domain.dry_adiabatic_lapse_rate(*args)
355
+
356
+
357
+ def test_dry_adiabatic_lapse_rate_heat_capacity_physical_bound():
358
+ args = [10, 1000]
359
+ args[1] = 0
360
+ with pytest.raises(ValueError):
361
+ domain.dry_adiabatic_lapse_rate(*args)
362
+
363
+
364
+ def test_saturation_vapor_pressure_broadcasting():
365
+ args = [273.15]
366
+ reference = domain.saturation_vapor_pressure(*args)
367
+ args[0] = np.full((2, 1), args[0])
368
+ result = domain.saturation_vapor_pressure(*args)
369
+ assert result.shape == (2, 1)
370
+ np.testing.assert_allclose(result, reference)
371
+
372
+
373
+ def test_saturation_vapor_pressure_temperature_physical_bound():
374
+ args = [273.15]
375
+ args[0] = 100
376
+ with pytest.raises(ValueError):
377
+ domain.saturation_vapor_pressure(*args)
378
+
379
+
380
+ def test_mixing_ratio_broadcasting():
381
+ args = [1000, 100000]
382
+ reference = domain.mixing_ratio(*args)
383
+ args[0] = np.full((2, 1), args[0])
384
+ result = domain.mixing_ratio(*args)
385
+ assert result.shape == (2, 1)
386
+ np.testing.assert_allclose(result, reference)
387
+
388
+
389
+ def test_mixing_ratio_vapor_pressure_physical_bound():
390
+ args = [1000, 100000]
391
+ args[0] = -1
392
+ with pytest.raises(ValueError):
393
+ domain.mixing_ratio(*args)
394
+
395
+
396
+ def test_mixing_ratio_total_pressure_physical_bound():
397
+ args = [1000, 100000]
398
+ args[1] = 0
399
+ with pytest.raises(ValueError):
400
+ domain.mixing_ratio(*args)
401
+
402
+
403
+ def test_specific_humidity_broadcasting():
404
+ args = [1]
405
+ reference = domain.specific_humidity(*args)
406
+ args[0] = np.full((2, 1), args[0])
407
+ result = domain.specific_humidity(*args)
408
+ assert result.shape == (2, 1)
409
+ np.testing.assert_allclose(result, reference)
410
+
411
+
412
+ def test_specific_humidity_mixing_ratio_physical_bound():
413
+ args = [1]
414
+ args[0] = -1
415
+ with pytest.raises(ValueError):
416
+ domain.specific_humidity(*args)
417
+
418
+
419
+ def test_virtual_temperature_broadcasting():
420
+ args = [300, 0]
421
+ reference = domain.virtual_temperature(*args)
422
+ args[0] = np.full((2, 1), args[0])
423
+ result = domain.virtual_temperature(*args)
424
+ assert result.shape == (2, 1)
425
+ np.testing.assert_allclose(result, reference)
426
+
427
+
428
+ def test_virtual_temperature_temperature_physical_bound():
429
+ args = [300, 0]
430
+ args[0] = 0
431
+ with pytest.raises(ValueError):
432
+ domain.virtual_temperature(*args)
433
+
434
+
435
+ def test_virtual_temperature_specific_humidity_physical_bound():
436
+ args = [300, 0]
437
+ args[1] = 1.1
438
+ with pytest.raises(ValueError):
439
+ domain.virtual_temperature(*args)
440
+
441
+
442
+ def test_relative_humidity_broadcasting():
443
+ args = [500, 1000]
444
+ reference = domain.relative_humidity(*args)
445
+ args[0] = np.full((2, 1), args[0])
446
+ result = domain.relative_humidity(*args)
447
+ assert result.shape == (2, 1)
448
+ np.testing.assert_allclose(result, reference)
449
+
450
+
451
+ def test_relative_humidity_vapor_pressure_physical_bound():
452
+ args = [500, 1000]
453
+ args[0] = -1
454
+ with pytest.raises(ValueError):
455
+ domain.relative_humidity(*args)
456
+
457
+
458
+ def test_relative_humidity_saturation_pressure_physical_bound():
459
+ args = [500, 1000]
460
+ args[1] = 0
461
+ with pytest.raises(ValueError):
462
+ domain.relative_humidity(*args)
463
+
464
+
465
+ def test_coriolis_parameter_broadcasting():
466
+ args = [0]
467
+ reference = domain.coriolis_parameter(*args)
468
+ args[0] = np.full((2, 1), args[0])
469
+ result = domain.coriolis_parameter(*args)
470
+ assert result.shape == (2, 1)
471
+ np.testing.assert_allclose(result, reference)
472
+
473
+
474
+ def test_coriolis_parameter_latitude_physical_bound():
475
+ args = [0]
476
+ args[0] = 2
477
+ with pytest.raises(ValueError):
478
+ domain.coriolis_parameter(*args)
479
+
480
+
481
+ def test_brunt_vaisala_squared_broadcasting():
482
+ args = [300, 0.003, 10]
483
+ reference = domain.brunt_vaisala_squared(*args)
484
+ args[0] = np.full((2, 1), args[0])
485
+ result = domain.brunt_vaisala_squared(*args)
486
+ assert result.shape == (2, 1)
487
+ np.testing.assert_allclose(result, reference)
488
+
489
+
490
+ def test_brunt_vaisala_squared_potential_temperature_physical_bound():
491
+ args = [300, 0.003, 10]
492
+ args[0] = 0
493
+ with pytest.raises(ValueError):
494
+ domain.brunt_vaisala_squared(*args)
495
+
496
+
497
+ def test_brunt_vaisala_squared_gravity_physical_bound():
498
+ args = [300, 0.003, 10]
499
+ args[2] = 0
500
+ with pytest.raises(ValueError):
501
+ domain.brunt_vaisala_squared(*args)
502
+
503
+
504
+ def test_geostrophic_speed_broadcasting():
505
+ args = [0.001, 1, 0.0001]
506
+ reference = domain.geostrophic_speed(*args)
507
+ args[0] = np.full((2, 1), args[0])
508
+ result = domain.geostrophic_speed(*args)
509
+ assert result.shape == (2, 1)
510
+ np.testing.assert_allclose(result, reference)
511
+
512
+
513
+ def test_geostrophic_speed_density_physical_bound():
514
+ args = [0.001, 1, 0.0001]
515
+ args[1] = 0
516
+ with pytest.raises(ValueError):
517
+ domain.geostrophic_speed(*args)
518
+
519
+
520
+ def test_geostrophic_speed_coriolis_physical_bound():
521
+ args = [0.001, 1, 0.0001]
522
+ args[2] = 0
523
+ with pytest.raises(ValueError):
524
+ domain.geostrophic_speed(*args)
525
+
526
+
527
+ def test_rossby_number_broadcasting():
528
+ args = [10, 1000000.0, 0.0001]
529
+ reference = domain.rossby_number(*args)
530
+ args[0] = np.full((2, 1), args[0])
531
+ result = domain.rossby_number(*args)
532
+ assert result.shape == (2, 1)
533
+ np.testing.assert_allclose(result, reference)
534
+
535
+
536
+ def test_rossby_number_speed_physical_bound():
537
+ args = [10, 1000000.0, 0.0001]
538
+ args[0] = -1
539
+ with pytest.raises(ValueError):
540
+ domain.rossby_number(*args)
541
+
542
+
543
+ def test_rossby_number_length_physical_bound():
544
+ args = [10, 1000000.0, 0.0001]
545
+ args[1] = 0
546
+ with pytest.raises(ValueError):
547
+ domain.rossby_number(*args)
548
+
549
+
550
+ def test_rossby_number_coriolis_physical_bound():
551
+ args = [10, 1000000.0, 0.0001]
552
+ args[2] = 0
553
+ with pytest.raises(ValueError):
554
+ domain.rossby_number(*args)
555
+
556
+
557
+ def test_barometer_column_height_reference():
558
+ result = domain.barometer_column_height(*[12, 2, 3])
559
+ np.testing.assert_allclose(result, 2, rtol=1e-11, atol=1e-12)
560
+
561
+
562
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
563
+ def test_barometer_column_height_rejects_invalid(bad):
564
+ args = [12, 2, 3]
565
+ args[0] = bad
566
+ with pytest.raises(ValueError):
567
+ domain.barometer_column_height(*args)
568
+
569
+
570
+ def test_barometer_column_height_broadcasting():
571
+ args = [12, 2, 3]
572
+ reference = domain.barometer_column_height(*args)
573
+ args[0] = np.full((2, 1), args[0])
574
+ result = domain.barometer_column_height(*args)
575
+ assert result.shape == (2, 1)
576
+ np.testing.assert_allclose(result, reference)
577
+
578
+
579
+ def test_barometer_column_height_pressure_physical_bound():
580
+ args = [12, 2, 3]
581
+ args[0] = -1
582
+ with pytest.raises(ValueError):
583
+ domain.barometer_column_height(*args)
584
+
585
+
586
+ def test_barometer_column_height_liquid_density_physical_bound():
587
+ args = [12, 2, 3]
588
+ args[1] = 0
589
+ with pytest.raises(ValueError):
590
+ domain.barometer_column_height(*args)
591
+
592
+
593
+ def test_barometer_column_height_gravity_physical_bound():
594
+ args = [12, 2, 3]
595
+ args[2] = 0
596
+ with pytest.raises(ValueError):
597
+ domain.barometer_column_height(*args)
598
+
599
+
600
+ def test_two_layer_temperature_reference():
601
+ result = domain.two_layer_temperature(*[5000, 288, 0.006, 10000])
602
+ np.testing.assert_allclose(result, 258, rtol=1e-11, atol=1e-12)
603
+
604
+
605
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
606
+ def test_two_layer_temperature_rejects_invalid(bad):
607
+ args = [5000, 288, 0.006, 10000]
608
+ args[0] = bad
609
+ with pytest.raises(ValueError):
610
+ domain.two_layer_temperature(*args)
611
+
612
+
613
+ def test_two_layer_temperature_broadcasting():
614
+ args = [5000, 288, 0.006, 10000]
615
+ reference = domain.two_layer_temperature(*args)
616
+ args[0] = np.full((2, 1), args[0])
617
+ result = domain.two_layer_temperature(*args)
618
+ assert result.shape == (2, 1)
619
+ np.testing.assert_allclose(result, reference)
620
+
621
+
622
+ def test_two_layer_temperature_height_physical_bound():
623
+ args = [5000, 288, 0.006, 10000]
624
+ args[0] = -1
625
+ with pytest.raises(ValueError):
626
+ domain.two_layer_temperature(*args)
627
+
628
+
629
+ def test_two_layer_temperature_surface_temperature_physical_bound():
630
+ args = [5000, 288, 0.006, 10000]
631
+ args[1] = 0
632
+ with pytest.raises(ValueError):
633
+ domain.two_layer_temperature(*args)
634
+
635
+
636
+ def test_two_layer_temperature_lapse_rate_physical_bound():
637
+ args = [5000, 288, 0.006, 10000]
638
+ args[2] = -1
639
+ with pytest.raises(ValueError):
640
+ domain.two_layer_temperature(*args)
641
+
642
+
643
+ def test_two_layer_temperature_tropopause_height_physical_bound():
644
+ args = [5000, 288, 0.006, 10000]
645
+ args[3] = 0
646
+ with pytest.raises(ValueError):
647
+ domain.two_layer_temperature(*args)
648
+
649
+
650
+ def test_richardson_number_reference():
651
+ result = domain.richardson_number(*[0.0001, 0.02])
652
+ np.testing.assert_allclose(result, 0.25, rtol=1e-11, atol=1e-12)
653
+
654
+
655
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
656
+ def test_richardson_number_rejects_invalid(bad):
657
+ args = [0.0001, 0.02]
658
+ args[0] = bad
659
+ with pytest.raises(ValueError):
660
+ domain.richardson_number(*args)
661
+
662
+
663
+ def test_richardson_number_broadcasting():
664
+ args = [0.0001, 0.02]
665
+ reference = domain.richardson_number(*args)
666
+ args[0] = np.full((2, 1), args[0])
667
+ result = domain.richardson_number(*args)
668
+ assert result.shape == (2, 1)
669
+ np.testing.assert_allclose(result, reference)
670
+
671
+
672
+ def test_richardson_number_shear_physical_bound():
673
+ args = [0.0001, 0.02]
674
+ args[1] = 0
675
+ with pytest.raises(ValueError):
676
+ domain.richardson_number(*args)
677
+
678
+
679
+ def test_surface_pressure_tendency_reference():
680
+ result = domain.surface_pressure_tendency(*[1e-05, 100000.0])
681
+ np.testing.assert_allclose(result, -1, rtol=1e-11, atol=1e-12)
682
+
683
+
684
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
685
+ def test_surface_pressure_tendency_rejects_invalid(bad):
686
+ args = [1e-05, 100000.0]
687
+ args[0] = bad
688
+ with pytest.raises(ValueError):
689
+ domain.surface_pressure_tendency(*args)
690
+
691
+
692
+ def test_surface_pressure_tendency_broadcasting():
693
+ args = [1e-05, 100000.0]
694
+ reference = domain.surface_pressure_tendency(*args)
695
+ args[0] = np.full((2, 1), args[0])
696
+ result = domain.surface_pressure_tendency(*args)
697
+ assert result.shape == (2, 1)
698
+ np.testing.assert_allclose(result, reference)
699
+
700
+
701
+ def test_surface_pressure_tendency_surface_pressure_physical_bound():
702
+ args = [1e-05, 100000.0]
703
+ args[1] = 0
704
+ with pytest.raises(ValueError):
705
+ domain.surface_pressure_tendency(*args)
706
+
707
+
708
+ def test_rossby_wave_speed_reference():
709
+ result = domain.rossby_wave_speed(*[10, 2e-11, 1e-06])
710
+ np.testing.assert_allclose(result, -10, rtol=1e-11, atol=1e-12)
711
+
712
+
713
+ @pytest.mark.parametrize("bad", [np.nan, np.inf, -np.inf, [], "bad", True, 1j])
714
+ def test_rossby_wave_speed_rejects_invalid(bad):
715
+ args = [10, 2e-11, 1e-06]
716
+ args[0] = bad
717
+ with pytest.raises(ValueError):
718
+ domain.rossby_wave_speed(*args)
719
+
720
+
721
+ def test_rossby_wave_speed_broadcasting():
722
+ args = [10, 2e-11, 1e-06]
723
+ reference = domain.rossby_wave_speed(*args)
724
+ args[0] = np.full((2, 1), args[0])
725
+ result = domain.rossby_wave_speed(*args)
726
+ assert result.shape == (2, 1)
727
+ np.testing.assert_allclose(result, reference)
728
+
729
+
730
+ def test_rossby_wave_speed_beta_physical_bound():
731
+ args = [10, 2e-11, 1e-06]
732
+ args[1] = -1
733
+ with pytest.raises(ValueError):
734
+ domain.rossby_wave_speed(*args)
735
+
736
+
737
+ def test_rossby_wave_speed_wavenumber_physical_bound():
738
+ args = [10, 2e-11, 1e-06]
739
+ args[2] = 0
740
+ with pytest.raises(ValueError):
741
+ domain.rossby_wave_speed(*args)