roms-tools 1.0.1__py3-none-any.whl → 1.1.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.
- roms_tools/__init__.py +0 -1
- roms_tools/_version.py +1 -1
- roms_tools/setup/boundary_forcing.py +12 -28
- roms_tools/setup/grid.py +462 -227
- roms_tools/setup/initial_conditions.py +11 -29
- roms_tools/setup/mixins.py +6 -16
- roms_tools/setup/topography.py +44 -13
- roms_tools/setup/vertical_coordinate.py +0 -377
- roms_tools/tests/test_boundary_forcing.py +11 -21
- roms_tools/tests/test_grid.py +188 -11
- roms_tools/tests/test_initial_conditions.py +18 -43
- roms_tools/tests/test_surface_forcing.py +0 -8
- roms_tools/tests/test_topography.py +8 -6
- roms_tools/tests/test_vertical_coordinate.py +87 -138
- {roms_tools-1.0.1.dist-info → roms_tools-1.1.0.dist-info}/METADATA +2 -3
- roms_tools-1.1.0.dist-info/RECORD +31 -0
- {roms_tools-1.0.1.dist-info → roms_tools-1.1.0.dist-info}/WHEEL +1 -1
- roms_tools-1.0.1.dist-info/RECORD +0 -31
- {roms_tools-1.0.1.dist-info → roms_tools-1.1.0.dist-info}/LICENSE +0 -0
- {roms_tools-1.0.1.dist-info → roms_tools-1.1.0.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
from datetime import datetime
|
|
3
|
-
from roms_tools import BoundaryForcing, Grid
|
|
3
|
+
from roms_tools import BoundaryForcing, Grid
|
|
4
4
|
import numpy as np
|
|
5
5
|
import tempfile
|
|
6
6
|
import os
|
|
@@ -14,30 +14,24 @@ def example_grid():
|
|
|
14
14
|
Fixture for creating a Grid object.
|
|
15
15
|
"""
|
|
16
16
|
grid = Grid(
|
|
17
|
-
nx=2,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def example_vertical_coordinate(example_grid):
|
|
25
|
-
"""
|
|
26
|
-
Fixture for creating a VerticalCoordinate object.
|
|
27
|
-
"""
|
|
28
|
-
vertical_coordinate = VerticalCoordinate(
|
|
29
|
-
grid=example_grid,
|
|
17
|
+
nx=2,
|
|
18
|
+
ny=2,
|
|
19
|
+
size_x=500,
|
|
20
|
+
size_y=1000,
|
|
21
|
+
center_lon=0,
|
|
22
|
+
center_lat=55,
|
|
23
|
+
rot=10,
|
|
30
24
|
N=3, # number of vertical levels
|
|
31
25
|
theta_s=5.0, # surface control parameter
|
|
32
26
|
theta_b=2.0, # bottom control parameter
|
|
33
27
|
hc=250.0, # critical depth
|
|
34
28
|
)
|
|
35
29
|
|
|
36
|
-
return
|
|
30
|
+
return grid
|
|
37
31
|
|
|
38
32
|
|
|
39
33
|
@pytest.fixture
|
|
40
|
-
def boundary_forcing(example_grid
|
|
34
|
+
def boundary_forcing(example_grid):
|
|
41
35
|
"""
|
|
42
36
|
Fixture for creating a BoundaryForcing object.
|
|
43
37
|
"""
|
|
@@ -46,7 +40,6 @@ def boundary_forcing(example_grid, example_vertical_coordinate):
|
|
|
46
40
|
|
|
47
41
|
return BoundaryForcing(
|
|
48
42
|
grid=example_grid,
|
|
49
|
-
vertical_coordinate=example_vertical_coordinate,
|
|
50
43
|
start_time=datetime(2021, 6, 29),
|
|
51
44
|
end_time=datetime(2021, 6, 30),
|
|
52
45
|
physics_source={"name": "GLORYS", "path": fname},
|
|
@@ -54,9 +47,7 @@ def boundary_forcing(example_grid, example_vertical_coordinate):
|
|
|
54
47
|
|
|
55
48
|
|
|
56
49
|
@pytest.fixture
|
|
57
|
-
def boundary_forcing_with_bgc_from_climatology(
|
|
58
|
-
example_grid, example_vertical_coordinate
|
|
59
|
-
):
|
|
50
|
+
def boundary_forcing_with_bgc_from_climatology(example_grid):
|
|
60
51
|
"""
|
|
61
52
|
Fixture for creating a BoundaryForcing object.
|
|
62
53
|
"""
|
|
@@ -66,7 +57,6 @@ def boundary_forcing_with_bgc_from_climatology(
|
|
|
66
57
|
|
|
67
58
|
return BoundaryForcing(
|
|
68
59
|
grid=example_grid,
|
|
69
|
-
vertical_coordinate=example_vertical_coordinate,
|
|
70
60
|
start_time=datetime(2021, 6, 29),
|
|
71
61
|
end_time=datetime(2021, 6, 30),
|
|
72
62
|
physics_source={"name": "GLORYS", "path": fname},
|
roms_tools/tests/test_grid.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
import numpy as np
|
|
3
3
|
import numpy.testing as npt
|
|
4
|
+
import xarray as xr
|
|
4
5
|
from roms_tools import Grid
|
|
5
6
|
import os
|
|
6
7
|
import tempfile
|
|
@@ -8,9 +9,44 @@ import importlib.metadata
|
|
|
8
9
|
import textwrap
|
|
9
10
|
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
@pytest.fixture
|
|
13
|
+
def simple_grid():
|
|
14
|
+
|
|
12
15
|
grid = Grid(nx=1, ny=1, size_x=100, size_y=100, center_lon=-20, center_lat=0, rot=0)
|
|
13
16
|
|
|
17
|
+
return grid
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_grid_creation(simple_grid):
|
|
21
|
+
|
|
22
|
+
assert simple_grid.nx == 1
|
|
23
|
+
assert simple_grid.ny == 1
|
|
24
|
+
assert simple_grid.size_x == 100
|
|
25
|
+
assert simple_grid.size_y == 100
|
|
26
|
+
assert simple_grid.center_lon == -20
|
|
27
|
+
assert simple_grid.center_lat == 0
|
|
28
|
+
assert simple_grid.rot == 0
|
|
29
|
+
assert isinstance(simple_grid.ds, xr.Dataset)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_plot_save_methods(simple_grid, tmp_path):
|
|
33
|
+
|
|
34
|
+
simple_grid.plot(bathymetry=True)
|
|
35
|
+
filepath = tmp_path / "grid.nc"
|
|
36
|
+
simple_grid.save(filepath)
|
|
37
|
+
assert filepath.exists()
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@pytest.fixture
|
|
41
|
+
def simple_grid_that_straddles_dateline():
|
|
42
|
+
|
|
43
|
+
grid = Grid(nx=1, ny=1, size_x=100, size_y=100, center_lon=0, center_lat=0, rot=20)
|
|
44
|
+
|
|
45
|
+
return grid
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_simple_regression(simple_grid):
|
|
49
|
+
|
|
14
50
|
expected_lat = np.array(
|
|
15
51
|
[
|
|
16
52
|
[-8.99249453e-01, -8.99249453e-01, -8.99249453e-01],
|
|
@@ -26,9 +62,158 @@ def test_simple_regression():
|
|
|
26
62
|
]
|
|
27
63
|
)
|
|
28
64
|
|
|
65
|
+
expected_lat_u = np.array(
|
|
66
|
+
[
|
|
67
|
+
[-8.99249453e-01, -8.99249453e-01],
|
|
68
|
+
[-2.39610306e-15, -2.28602368e-15],
|
|
69
|
+
[8.99249453e-01, 8.99249453e-01],
|
|
70
|
+
]
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
expected_lon_u = np.array(
|
|
74
|
+
[
|
|
75
|
+
[339.55036143, 340.44963857],
|
|
76
|
+
[339.55036143, 340.44963857],
|
|
77
|
+
[339.55036143, 340.44963857],
|
|
78
|
+
]
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
expected_lat_v = np.array(
|
|
82
|
+
[[-0.44962473, -0.44962473, -0.44962473], [0.44962473, 0.44962473, 0.44962473]]
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
expected_lon_v = np.array(
|
|
86
|
+
[[339.10072286, 340.0, 340.89927714], [339.10072286, 340.0, 340.89927714]]
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
expected_lat_coarse = np.array(
|
|
90
|
+
[[-1.34887418, -1.34887418], [1.34887418, 1.34887418]]
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
expected_lon_coarse = np.array(
|
|
94
|
+
[[338.65108429, 341.34891571], [338.65108429, 341.34891571]]
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
expected_angle = np.array(
|
|
98
|
+
[
|
|
99
|
+
[0.00000000e00, 0.00000000e00, 0.00000000e00],
|
|
100
|
+
[-3.83707366e-17, -3.83707366e-17, -3.83707366e-17],
|
|
101
|
+
[0.00000000e00, 0.00000000e00, 0.00000000e00],
|
|
102
|
+
]
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
expected_angle_coarse = np.array(
|
|
106
|
+
[[1.91853683e-17, 1.91853683e-17], [1.91853683e-17, 1.91853683e-17]]
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
# TODO: adapt tolerances according to order of magnitude of respective fields
|
|
110
|
+
npt.assert_allclose(simple_grid.ds["lat_rho"], expected_lat, atol=1e-8)
|
|
111
|
+
npt.assert_allclose(simple_grid.ds["lon_rho"], expected_lon, atol=1e-8)
|
|
112
|
+
npt.assert_allclose(simple_grid.ds["lat_u"], expected_lat_u, atol=1e-8)
|
|
113
|
+
npt.assert_allclose(simple_grid.ds["lon_u"], expected_lon_u, atol=1e-8)
|
|
114
|
+
npt.assert_allclose(simple_grid.ds["lat_v"], expected_lat_v, atol=1e-8)
|
|
115
|
+
npt.assert_allclose(simple_grid.ds["lon_v"], expected_lon_v, atol=1e-8)
|
|
116
|
+
npt.assert_allclose(simple_grid.ds["lat_coarse"], expected_lat_coarse, atol=1e-8)
|
|
117
|
+
npt.assert_allclose(simple_grid.ds["lon_coarse"], expected_lon_coarse, atol=1e-8)
|
|
118
|
+
npt.assert_allclose(simple_grid.ds["angle"], expected_angle, atol=1e-8)
|
|
119
|
+
npt.assert_allclose(
|
|
120
|
+
simple_grid.ds["angle_coarse"], expected_angle_coarse, atol=1e-8
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def test_simple_regression_dateline(simple_grid_that_straddles_dateline):
|
|
125
|
+
|
|
126
|
+
expected_lat = np.array(
|
|
127
|
+
[
|
|
128
|
+
[-1.15258151e00, -8.45014017e-01, -5.37470876e-01],
|
|
129
|
+
[-3.07559747e-01, -2.14815958e-15, 3.07559747e-01],
|
|
130
|
+
[5.37470876e-01, 8.45014017e-01, 1.15258151e00],
|
|
131
|
+
]
|
|
132
|
+
)
|
|
133
|
+
expected_lon = np.array(
|
|
134
|
+
[
|
|
135
|
+
[3.59462527e02, 3.07583728e-01, 1.15258257e00],
|
|
136
|
+
[3.59154948e02, 7.81866146e-16, 8.45052212e-01],
|
|
137
|
+
[3.58847417e02, 3.59692416e02, 5.37473154e-01],
|
|
138
|
+
]
|
|
139
|
+
)
|
|
140
|
+
expected_lat_u = np.array(
|
|
141
|
+
[
|
|
142
|
+
[-0.99879776, -0.69124245],
|
|
143
|
+
[-0.15377987, 0.15377987],
|
|
144
|
+
[0.69124245, 0.99879776],
|
|
145
|
+
]
|
|
146
|
+
)
|
|
147
|
+
expected_lon_u = np.array(
|
|
148
|
+
[
|
|
149
|
+
[3.59885055e02, 7.30083149e-01],
|
|
150
|
+
[3.59577474e02, 4.22526106e-01],
|
|
151
|
+
[3.59269917e02, 1.14944713e-01],
|
|
152
|
+
]
|
|
153
|
+
)
|
|
154
|
+
expected_lat_v = np.array(
|
|
155
|
+
[[-0.73007063, -0.42250701, -0.11495556], [0.11495556, 0.42250701, 0.73007063]]
|
|
156
|
+
)
|
|
157
|
+
expected_lon_v = np.array(
|
|
158
|
+
[
|
|
159
|
+
[3.59308737e02, 1.53791864e-01, 9.98817391e-01],
|
|
160
|
+
[3.59001183e02, 3.59846208e02, 6.91262683e-01],
|
|
161
|
+
]
|
|
162
|
+
)
|
|
163
|
+
expected_lat_coarse = np.array(
|
|
164
|
+
[[-1.72887807, -0.80621877], [0.80621877, 1.72887807]]
|
|
165
|
+
)
|
|
166
|
+
expected_lon_coarse = np.array(
|
|
167
|
+
[[359.19378677, 1.72883383], [358.27116617, 0.80621323]]
|
|
168
|
+
)
|
|
169
|
+
expected_angle = np.array(
|
|
170
|
+
[
|
|
171
|
+
[0.34910175, 0.34910175, 0.34910175],
|
|
172
|
+
[0.34906217, 0.34906217, 0.34906217],
|
|
173
|
+
[0.34910175, 0.34910175, 0.34910175],
|
|
174
|
+
]
|
|
175
|
+
)
|
|
176
|
+
expected_angle_coarse = np.array(
|
|
177
|
+
[[0.34912155, 0.34912155], [0.34912155, 0.34912155]]
|
|
178
|
+
)
|
|
179
|
+
|
|
29
180
|
# TODO: adapt tolerances according to order of magnitude of respective fields
|
|
30
|
-
npt.assert_allclose(
|
|
31
|
-
|
|
181
|
+
npt.assert_allclose(
|
|
182
|
+
simple_grid_that_straddles_dateline.ds["lat_rho"], expected_lat, atol=1e-8
|
|
183
|
+
)
|
|
184
|
+
npt.assert_allclose(
|
|
185
|
+
simple_grid_that_straddles_dateline.ds["lon_rho"], expected_lon, atol=1e-8
|
|
186
|
+
)
|
|
187
|
+
npt.assert_allclose(
|
|
188
|
+
simple_grid_that_straddles_dateline.ds["lat_u"], expected_lat_u, atol=1e-8
|
|
189
|
+
)
|
|
190
|
+
npt.assert_allclose(
|
|
191
|
+
simple_grid_that_straddles_dateline.ds["lon_u"], expected_lon_u, atol=1e-8
|
|
192
|
+
)
|
|
193
|
+
npt.assert_allclose(
|
|
194
|
+
simple_grid_that_straddles_dateline.ds["lat_v"], expected_lat_v, atol=1e-8
|
|
195
|
+
)
|
|
196
|
+
npt.assert_allclose(
|
|
197
|
+
simple_grid_that_straddles_dateline.ds["lon_v"], expected_lon_v, atol=1e-8
|
|
198
|
+
)
|
|
199
|
+
npt.assert_allclose(
|
|
200
|
+
simple_grid_that_straddles_dateline.ds["lat_coarse"],
|
|
201
|
+
expected_lat_coarse,
|
|
202
|
+
atol=1e-8,
|
|
203
|
+
)
|
|
204
|
+
npt.assert_allclose(
|
|
205
|
+
simple_grid_that_straddles_dateline.ds["lon_coarse"],
|
|
206
|
+
expected_lon_coarse,
|
|
207
|
+
atol=1e-8,
|
|
208
|
+
)
|
|
209
|
+
npt.assert_allclose(
|
|
210
|
+
simple_grid_that_straddles_dateline.ds["angle"], expected_angle, atol=1e-8
|
|
211
|
+
)
|
|
212
|
+
npt.assert_allclose(
|
|
213
|
+
simple_grid_that_straddles_dateline.ds["angle_coarse"],
|
|
214
|
+
expected_angle_coarse,
|
|
215
|
+
atol=1e-8,
|
|
216
|
+
)
|
|
32
217
|
|
|
33
218
|
|
|
34
219
|
def test_raise_if_domain_too_large():
|
|
@@ -85,9 +270,7 @@ def test_roundtrip_netcdf():
|
|
|
85
270
|
center_lat=0.0,
|
|
86
271
|
rot=0.0,
|
|
87
272
|
topography_source="ETOPO5",
|
|
88
|
-
smooth_factor=2,
|
|
89
273
|
hmin=5.0,
|
|
90
|
-
rmax=0.2,
|
|
91
274
|
)
|
|
92
275
|
|
|
93
276
|
# Create a temporary file
|
|
@@ -121,9 +304,7 @@ def test_roundtrip_yaml():
|
|
|
121
304
|
center_lat=0.0,
|
|
122
305
|
rot=0.0,
|
|
123
306
|
topography_source="ETOPO5",
|
|
124
|
-
smooth_factor=2,
|
|
125
307
|
hmin=5.0,
|
|
126
|
-
rmax=0.2,
|
|
127
308
|
)
|
|
128
309
|
|
|
129
310
|
# Create a temporary file
|
|
@@ -155,9 +336,7 @@ def test_from_yaml_missing_version():
|
|
|
155
336
|
center_lat: 61
|
|
156
337
|
rot: -20
|
|
157
338
|
topography_source: ETOPO5
|
|
158
|
-
smooth_factor: 8
|
|
159
339
|
hmin: 5.0
|
|
160
|
-
rmax: 0.2
|
|
161
340
|
"""
|
|
162
341
|
)
|
|
163
342
|
with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
|
|
@@ -206,9 +385,7 @@ def test_from_yaml_version_mismatch():
|
|
|
206
385
|
center_lat: 61
|
|
207
386
|
rot: -20
|
|
208
387
|
topography_source: ETOPO5
|
|
209
|
-
smooth_factor: 8
|
|
210
388
|
hmin: 5.0
|
|
211
|
-
rmax: 0.2
|
|
212
389
|
"""
|
|
213
390
|
)
|
|
214
391
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
from datetime import datetime
|
|
3
|
-
from roms_tools import InitialConditions, Grid
|
|
3
|
+
from roms_tools import InitialConditions, Grid
|
|
4
4
|
import xarray as xr
|
|
5
5
|
import numpy as np
|
|
6
6
|
import tempfile
|
|
@@ -16,30 +16,24 @@ def example_grid():
|
|
|
16
16
|
Fixture for creating a Grid object.
|
|
17
17
|
"""
|
|
18
18
|
grid = Grid(
|
|
19
|
-
nx=2,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def example_vertical_coordinate(example_grid):
|
|
27
|
-
"""
|
|
28
|
-
Fixture for creating a VerticalCoordinate object.
|
|
29
|
-
"""
|
|
30
|
-
vertical_coordinate = VerticalCoordinate(
|
|
31
|
-
grid=example_grid,
|
|
19
|
+
nx=2,
|
|
20
|
+
ny=2,
|
|
21
|
+
size_x=500,
|
|
22
|
+
size_y=1000,
|
|
23
|
+
center_lon=0,
|
|
24
|
+
center_lat=55,
|
|
25
|
+
rot=10,
|
|
32
26
|
N=3, # number of vertical levels
|
|
33
27
|
theta_s=5.0, # surface control parameter
|
|
34
28
|
theta_b=2.0, # bottom control parameter
|
|
35
29
|
hc=250.0, # critical depth
|
|
36
30
|
)
|
|
37
31
|
|
|
38
|
-
return
|
|
32
|
+
return grid
|
|
39
33
|
|
|
40
34
|
|
|
41
35
|
@pytest.fixture
|
|
42
|
-
def initial_conditions(example_grid
|
|
36
|
+
def initial_conditions(example_grid):
|
|
43
37
|
"""
|
|
44
38
|
Fixture for creating a dummy InitialConditions object.
|
|
45
39
|
"""
|
|
@@ -48,14 +42,13 @@ def initial_conditions(example_grid, example_vertical_coordinate):
|
|
|
48
42
|
|
|
49
43
|
return InitialConditions(
|
|
50
44
|
grid=example_grid,
|
|
51
|
-
vertical_coordinate=example_vertical_coordinate,
|
|
52
45
|
ini_time=datetime(2021, 6, 29),
|
|
53
46
|
physics_source={"path": fname, "name": "GLORYS"},
|
|
54
47
|
)
|
|
55
48
|
|
|
56
49
|
|
|
57
50
|
@pytest.fixture
|
|
58
|
-
def initial_conditions_with_bgc(example_grid
|
|
51
|
+
def initial_conditions_with_bgc(example_grid):
|
|
59
52
|
"""
|
|
60
53
|
Fixture for creating a dummy InitialConditions object.
|
|
61
54
|
"""
|
|
@@ -65,7 +58,6 @@ def initial_conditions_with_bgc(example_grid, example_vertical_coordinate):
|
|
|
65
58
|
|
|
66
59
|
return InitialConditions(
|
|
67
60
|
grid=example_grid,
|
|
68
|
-
vertical_coordinate=example_vertical_coordinate,
|
|
69
61
|
ini_time=datetime(2021, 6, 29),
|
|
70
62
|
physics_source={"path": fname, "name": "GLORYS"},
|
|
71
63
|
bgc_source={"path": fname_bgc, "name": "CESM_REGRIDDED"},
|
|
@@ -73,9 +65,7 @@ def initial_conditions_with_bgc(example_grid, example_vertical_coordinate):
|
|
|
73
65
|
|
|
74
66
|
|
|
75
67
|
@pytest.fixture
|
|
76
|
-
def initial_conditions_with_bgc_from_climatology(
|
|
77
|
-
example_grid, example_vertical_coordinate
|
|
78
|
-
):
|
|
68
|
+
def initial_conditions_with_bgc_from_climatology(example_grid):
|
|
79
69
|
"""
|
|
80
70
|
Fixture for creating a dummy InitialConditions object.
|
|
81
71
|
"""
|
|
@@ -85,7 +75,6 @@ def initial_conditions_with_bgc_from_climatology(
|
|
|
85
75
|
|
|
86
76
|
return InitialConditions(
|
|
87
77
|
grid=example_grid,
|
|
88
|
-
vertical_coordinate=example_vertical_coordinate,
|
|
89
78
|
ini_time=datetime(2021, 6, 29),
|
|
90
79
|
physics_source={"path": fname, "name": "GLORYS"},
|
|
91
80
|
bgc_source={
|
|
@@ -126,33 +115,27 @@ def test_initial_conditions_creation(ic_fixture, request):
|
|
|
126
115
|
|
|
127
116
|
|
|
128
117
|
# Test initialization with missing 'name' in physics_source
|
|
129
|
-
def test_initial_conditions_missing_physics_name(
|
|
130
|
-
example_grid, example_vertical_coordinate
|
|
131
|
-
):
|
|
118
|
+
def test_initial_conditions_missing_physics_name(example_grid):
|
|
132
119
|
with pytest.raises(ValueError, match="`physics_source` must include a 'name'."):
|
|
133
120
|
InitialConditions(
|
|
134
121
|
grid=example_grid,
|
|
135
|
-
vertical_coordinate=example_vertical_coordinate,
|
|
136
122
|
ini_time=datetime(2021, 6, 29),
|
|
137
123
|
physics_source={"path": "physics_data.nc"},
|
|
138
124
|
)
|
|
139
125
|
|
|
140
126
|
|
|
141
127
|
# Test initialization with missing 'path' in physics_source
|
|
142
|
-
def test_initial_conditions_missing_physics_path(
|
|
143
|
-
example_grid, example_vertical_coordinate
|
|
144
|
-
):
|
|
128
|
+
def test_initial_conditions_missing_physics_path(example_grid):
|
|
145
129
|
with pytest.raises(ValueError, match="`physics_source` must include a 'path'."):
|
|
146
130
|
InitialConditions(
|
|
147
131
|
grid=example_grid,
|
|
148
|
-
vertical_coordinate=example_vertical_coordinate,
|
|
149
132
|
ini_time=datetime(2021, 6, 29),
|
|
150
133
|
physics_source={"name": "GLORYS"},
|
|
151
134
|
)
|
|
152
135
|
|
|
153
136
|
|
|
154
137
|
# Test initialization with missing 'name' in bgc_source
|
|
155
|
-
def test_initial_conditions_missing_bgc_name(example_grid
|
|
138
|
+
def test_initial_conditions_missing_bgc_name(example_grid):
|
|
156
139
|
|
|
157
140
|
fname = download_test_data("GLORYS_test_data.nc")
|
|
158
141
|
with pytest.raises(
|
|
@@ -160,7 +143,6 @@ def test_initial_conditions_missing_bgc_name(example_grid, example_vertical_coor
|
|
|
160
143
|
):
|
|
161
144
|
InitialConditions(
|
|
162
145
|
grid=example_grid,
|
|
163
|
-
vertical_coordinate=example_vertical_coordinate,
|
|
164
146
|
ini_time=datetime(2021, 6, 29),
|
|
165
147
|
physics_source={"name": "GLORYS", "path": fname},
|
|
166
148
|
bgc_source={"path": "bgc_data.nc"},
|
|
@@ -168,7 +150,7 @@ def test_initial_conditions_missing_bgc_name(example_grid, example_vertical_coor
|
|
|
168
150
|
|
|
169
151
|
|
|
170
152
|
# Test initialization with missing 'path' in bgc_source
|
|
171
|
-
def test_initial_conditions_missing_bgc_path(example_grid
|
|
153
|
+
def test_initial_conditions_missing_bgc_path(example_grid):
|
|
172
154
|
|
|
173
155
|
fname = download_test_data("GLORYS_test_data.nc")
|
|
174
156
|
with pytest.raises(
|
|
@@ -176,7 +158,6 @@ def test_initial_conditions_missing_bgc_path(example_grid, example_vertical_coor
|
|
|
176
158
|
):
|
|
177
159
|
InitialConditions(
|
|
178
160
|
grid=example_grid,
|
|
179
|
-
vertical_coordinate=example_vertical_coordinate,
|
|
180
161
|
ini_time=datetime(2021, 6, 29),
|
|
181
162
|
physics_source={"name": "GLORYS", "path": fname},
|
|
182
163
|
bgc_source={"name": "CESM_REGRIDDED"},
|
|
@@ -184,15 +165,12 @@ def test_initial_conditions_missing_bgc_path(example_grid, example_vertical_coor
|
|
|
184
165
|
|
|
185
166
|
|
|
186
167
|
# Test default climatology value
|
|
187
|
-
def test_initial_conditions_default_climatology(
|
|
188
|
-
example_grid, example_vertical_coordinate
|
|
189
|
-
):
|
|
168
|
+
def test_initial_conditions_default_climatology(example_grid):
|
|
190
169
|
|
|
191
170
|
fname = download_test_data("GLORYS_test_data.nc")
|
|
192
171
|
|
|
193
172
|
initial_conditions = InitialConditions(
|
|
194
173
|
grid=example_grid,
|
|
195
|
-
vertical_coordinate=example_vertical_coordinate,
|
|
196
174
|
ini_time=datetime(2021, 6, 29),
|
|
197
175
|
physics_source={"name": "GLORYS", "path": fname},
|
|
198
176
|
)
|
|
@@ -201,16 +179,13 @@ def test_initial_conditions_default_climatology(
|
|
|
201
179
|
assert initial_conditions.bgc_source is None
|
|
202
180
|
|
|
203
181
|
|
|
204
|
-
def test_initial_conditions_default_bgc_climatology(
|
|
205
|
-
example_grid, example_vertical_coordinate
|
|
206
|
-
):
|
|
182
|
+
def test_initial_conditions_default_bgc_climatology(example_grid):
|
|
207
183
|
|
|
208
184
|
fname = download_test_data("GLORYS_test_data.nc")
|
|
209
185
|
fname_bgc = download_test_data("CESM_regional_test_data_one_time_slice.nc")
|
|
210
186
|
|
|
211
187
|
initial_conditions = InitialConditions(
|
|
212
188
|
grid=example_grid,
|
|
213
|
-
vertical_coordinate=example_vertical_coordinate,
|
|
214
189
|
ini_time=datetime(2021, 6, 29),
|
|
215
190
|
physics_source={"name": "GLORYS", "path": fname},
|
|
216
191
|
bgc_source={"name": "CESM_REGRIDDED", "path": fname_bgc},
|
|
@@ -194,8 +194,6 @@ def test_successful_initialization_with_regional_data(grid_fixture, request):
|
|
|
194
194
|
|
|
195
195
|
assert sfc_forcing.ds is not None
|
|
196
196
|
|
|
197
|
-
grid.coarsen()
|
|
198
|
-
|
|
199
197
|
sfc_forcing = SurfaceForcing(
|
|
200
198
|
grid=grid,
|
|
201
199
|
use_coarse_grid=True,
|
|
@@ -250,8 +248,6 @@ def test_nan_detection_initialization_with_regional_data(grid_fixture, request):
|
|
|
250
248
|
physics_source={"name": "ERA5", "path": fname},
|
|
251
249
|
)
|
|
252
250
|
|
|
253
|
-
grid.coarsen()
|
|
254
|
-
|
|
255
251
|
with pytest.raises(ValueError, match="NaN values found"):
|
|
256
252
|
SurfaceForcing(
|
|
257
253
|
grid=grid,
|
|
@@ -286,8 +282,6 @@ def test_no_longitude_intersection_initialization_with_regional_data(
|
|
|
286
282
|
physics_source={"name": "ERA5", "path": fname},
|
|
287
283
|
)
|
|
288
284
|
|
|
289
|
-
grid_that_straddles_180_degree_meridian.coarsen()
|
|
290
|
-
|
|
291
285
|
with pytest.raises(
|
|
292
286
|
ValueError, match="Selected longitude range does not intersect with dataset"
|
|
293
287
|
):
|
|
@@ -350,8 +344,6 @@ def test_successful_initialization_with_global_data(grid_fixture, request):
|
|
|
350
344
|
assert "rain" in sfc_forcing.ds["physics"]
|
|
351
345
|
assert sfc_forcing.ds["physics"].attrs["physics_source"] == "ERA5"
|
|
352
346
|
|
|
353
|
-
grid.coarsen()
|
|
354
|
-
|
|
355
347
|
sfc_forcing = SurfaceForcing(
|
|
356
348
|
grid=grid,
|
|
357
349
|
use_coarse_grid=True,
|
|
@@ -31,12 +31,10 @@ def test_rmax_criterion():
|
|
|
31
31
|
center_lon=30,
|
|
32
32
|
center_lat=61,
|
|
33
33
|
rot=20,
|
|
34
|
-
smooth_factor=4,
|
|
35
|
-
rmax=0.2,
|
|
36
34
|
)
|
|
37
35
|
r_eta, r_xi = _compute_rfactor(grid.ds.h)
|
|
38
36
|
rmax0 = np.max([r_eta.max(), r_xi.max()])
|
|
39
|
-
npt.assert_array_less(rmax0,
|
|
37
|
+
npt.assert_array_less(rmax0, 0.2)
|
|
40
38
|
|
|
41
39
|
|
|
42
40
|
def test_hmin_criterion():
|
|
@@ -48,11 +46,15 @@ def test_hmin_criterion():
|
|
|
48
46
|
center_lon=30,
|
|
49
47
|
center_lat=61,
|
|
50
48
|
rot=20,
|
|
51
|
-
|
|
52
|
-
rmax=0.2,
|
|
53
|
-
hmin=5,
|
|
49
|
+
hmin=5.0,
|
|
54
50
|
)
|
|
55
51
|
|
|
52
|
+
assert grid.hmin == 5.0
|
|
53
|
+
assert np.less_equal(grid.hmin, grid.ds.h.min())
|
|
54
|
+
|
|
55
|
+
grid.update_topography_and_mask(hmin=10.0)
|
|
56
|
+
|
|
57
|
+
assert grid.hmin == 10.0
|
|
56
58
|
assert np.less_equal(grid.hmin, grid.ds.h.min())
|
|
57
59
|
|
|
58
60
|
|