Skip to content

Commit a0471dd

Browse files
Merge branch 'main' into fix/spatialslip-zeta-parentheses
2 parents c8155c6 + 5a0df96 commit a0471dd

60 files changed

Lines changed: 966 additions & 470 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/ci/recipe.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ requirements:
4646
- holoviews >= 1.22.0 # https://github.com/prefix-dev/rattler-build/issues/2326
4747
- pooch >=1.8.0
4848
- polars >=1.31.0
49+
- tabulate >=0.10.0
4950

5051
tests:
5152
- python:

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ repos:
2828
- id: ruff-format
2929
types_or: [python, jupyter]
3030
- repo: https://github.com/rbubley/mirrors-prettier # Update mirror as official mirror is deprecated
31-
rev: v3.9.1
31+
rev: v3.9.4
3232
hooks:
3333
- id: prettier
3434

docs/_static/custom.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.bd-article .toctree-wrapper > p.caption {
2+
display: none;
3+
}

docs/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@
187187
# relative to this directory. They are copied after the builtin static files,
188188
# so a file named "default.css" will overwrite the builtin "default.css".
189189
html_static_path = ["_static"]
190+
html_css_files = ["custom.css"]
190191
html_theme_options = {
191192
"logo": {
192193
"alt_text": "Parcels - Home",

docs/getting_started/index.md

Lines changed: 0 additions & 11 deletions
This file was deleted.

docs/index.md

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ _Animation of virtual particles carried by ocean surface flow in the global ocea
1212
You can browse the documentation for older versions by using the version switcher in the bottom right.
1313
```
1414

15-
**Useful links**: [Installation instructions](getting_started/installation.md) | [Discussions on GitHub](https://github.com/Parcels-code/parcels/discussions) | [Issue on GitHub](https://github.com/Parcels-code/parcels/issues) | [Parcels website](https://parcels-code.org/) | [CLAM community website](https://clam-community.github.io/) | [API reference](reference/parcels/index)
15+
**Useful links**: [Installation instructions](user_guide/getting_started/installation) | [Discussions on GitHub](https://github.com/Parcels-code/parcels/discussions) | [Issue on GitHub](https://github.com/Parcels-code/parcels/issues) | [Parcels website](https://parcels-code.org/) | [CLAM community website](https://clam-community.github.io/) | [API reference](reference/parcels/index)
16+
17+
New to **Parcels**? Check out the [installation instructions](user_guide/getting_started/installation), run the [quickstart tutorial](user_guide/getting_started/tutorial_quickstart), and learn the [key concepts](user_guide/getting_started/explanation_concepts) to understand the package.
1618

1719
`````{grid} 1 2 2 2
1820
:gutter: 4
@@ -22,13 +24,12 @@ You can browse the documentation for older versions by using the version switche
2224
````{grid-item-card} Getting started
2325
:shadow: md
2426
25-
New to **Parcels**? Check out the installation guide, run the quickstart tutorial, and learn the key concepts to understand the package.
27+
New to **Parcels**? Check out the [installation instructions](user_guide/getting_started/installation), run the [quickstart tutorial](user_guide/getting_started/tutorial_quickstart), and learn the [key concepts](user_guide/getting_started/explanation_concepts) to understand the package.
2628
2729
+++
2830
29-
```{button-ref} getting_started/index
31+
```{button-ref} user_guide/index
3032
:ref-type: doc
31-
:click-parent:
3233
:color: secondary
3334
:expand:
3435
@@ -38,13 +39,12 @@ Get started!
3839
````{grid-item-card} How to?
3940
:shadow: md
4041
41-
Wondering how to load a `FieldSet` or write a `Kernel`? Find **tutorials** and explainers to these and other questions here:
42+
Wondering how to load a `FieldSet` or write a `Kernel`? Find **tutorials** and explainers to these and other questions here.
4243
4344
+++
4445
4546
```{button-ref} user_guide/index
4647
:ref-type: doc
47-
:click-parent:
4848
:color: secondary
4949
:expand:
5050
@@ -60,7 +60,6 @@ We encourage anyone to help improve **Parcels**: read our guidelines to get star
6060
6161
```{button-ref} development/index
6262
:ref-type: doc
63-
:click-parent:
6463
:color: secondary
6564
:expand:
6665
@@ -76,7 +75,6 @@ Want to interact with other users and **Parcels** developers?
7675
7776
```{button-ref} community/index
7877
:ref-type: doc
79-
:click-parent:
8078
:color: secondary
8179
:expand:
8280
@@ -95,6 +93,5 @@ User guide <user_guide/index>
9593
Community <community/index>
9694
Development <development/index>
9795
API reference <reference/parcels/index>
98-
v4 <v4/index>
9996
Parcels website <https://parcels-code.org/>
10097
```

docs/user_guide/examples/explanation_interpolation.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ particles.temperature = fieldset.temperature[particles]
1414
````{note}
1515
The statement above is shorthand for
1616
```python
17-
particles.temperature = fieldset.temperature[particles.time, particles.z, particles.y, particles.x, particles]
17+
particles.temperature = fieldset.temperature[particles.t, particles.z, particles.y, particles.x, particles]
1818
```
1919
where the `particles` argument at the end provides the grid search algorithm with a first guess for the element indices to interpolate on.
2020
2121
If you want to sample at a different location, or time, that is not necessarily close to the particles location, you can use
2222
```python
23-
particles.temperature = fieldset.temperature[time, z, y, x]
23+
particles.temperature = fieldset.temperature[t, z, y, x]
2424
```
2525
but this could be slower for curvilinear and unstructured Grids because the entire grid needs to be searched.
2626
````
@@ -53,7 +53,7 @@ If we want to create a custom interpolation method, we need to look at the inter
5353
The `particle_positions` dictionary contains:
5454

5555
```
56-
particle_positions = {"time", time, "z", z, "y", y, "x", x}
56+
particle_positions = {"t", t, "z", z, "y", y, "x", x}
5757
```
5858

5959
For structured (`X`) grids, the `grid_positions` dictionary contains:
@@ -63,7 +63,7 @@ grid_positions = {
6363
"T": {"index": ti, "bcoord": tau},
6464
"Z": {"index": zi, "bcoord": zeta},
6565
"Y": {"index": yi, "bcoord": eta},
66-
"X": {"index": xi, "bcoord", xsi},
66+
"X": {"index": xi, "bcoord": xsi},
6767
}
6868
```
6969

docs/user_guide/examples/explanation_kernelloop.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ ds_fields.load() # load the dataset into memory
6262
# Create an idealised wind field and add it to the dataset
6363
tdim, ydim, xdim = (len(ds_fields.time),len(ds_fields.latitude), len(ds_fields.longitude))
6464
ds_fields["UWind"] = xr.DataArray(
65-
data=np.ones((tdim, ydim, xdim)) * np.sin(ds_fields.latitude.values)[None, :, None],
65+
data=0.5 * np.ones((tdim, ydim, xdim)) * np.sin(ds_fields.latitude.values - ds_fields.latitude.values.mean())[None, :, None],
6666
coords=[ds_fields.time, ds_fields.latitude, ds_fields.longitude])
6767
6868
ds_fields["VWind"] = xr.DataArray(
@@ -88,10 +88,12 @@ fieldset = parcels.FieldSet.from_sgrid_conventions(
8888
Now we define a wind Kernel that uses a forward Euler method to apply the wind forcing. Note that we update the `particles.dx` and `particles.dy` variables, rather than `particles.x` and `particles.y` directly.
8989

9090
```{code-cell}
91-
def wind_kernel(particles, fieldset):
92-
uwind, vwind = fieldset.Wind[particles]
93-
particles.dx += uwind * particles.dt
94-
particles.dy += vwind * particles.dt
91+
def windRK2(particles, fieldset):
92+
(u1, v1) = fieldset.Wind[particles]
93+
x1, y1 = (particles.x + u1 * 0.5 * particles.dt, particles.y + v1 * 0.5 * particles.dt)
94+
(u2, v2) = fieldset.Wind[particles.t + 0.5 * particles.dt, particles.z, y1, x1, particles]
95+
particles.dx += u2 * particles.dt
96+
particles.dy += v2 * particles.dt
9597
```
9698

9799
First run a simulation where we apply Kernels as `[AdvectionRK2, wind_kernel]`
@@ -100,22 +102,22 @@ First run a simulation where we apply Kernels as `[AdvectionRK2, wind_kernel]`
100102
:tags: [hide-output]
101103
npart = 10
102104
z = np.repeat(ds_fields.depth[0].values, npart)
103-
lons = np.repeat(31, npart)
105+
lons = np.repeat(32.2, npart)
104106
lats = np.linspace(-32.5, -30.5, npart)
105107
106108
pset = parcels.ParticleSet(fieldset, pclass=parcels.Particle, z=z, y=lats, x=lons)
107109
output_file = parcels.ParticleFile(
108110
path="advection_then_wind.parquet", outputdt=np.timedelta64(6,'h')
109111
)
110112
pset.execute(
111-
[parcels.kernels.AdvectionRK2, wind_kernel],
113+
[parcels.kernels.AdvectionRK2, windRK2],
112114
runtime=np.timedelta64(5,'D'),
113115
dt=np.timedelta64(1,'h'),
114116
output_file=output_file,
115117
)
116118
```
117119

118-
Then also run a simulation where we apply the Kernels in the reverse order as `[wind_kernel, AdvectionRK2]`
120+
Then also run a simulation where we apply the Kernels in the reverse order as `[windRK2, AdvectionRK2]`
119121

120122
```{code-cell}
121123
:tags: [hide-output]
@@ -126,7 +128,7 @@ output_file_reverse = parcels.ParticleFile(
126128
path="wind_then_advection.parquet", outputdt=np.timedelta64(6,"h")
127129
)
128130
pset_reverse.execute(
129-
[wind_kernel, parcels.kernels.AdvectionRK2],
131+
[windRK2, parcels.kernels.AdvectionRK2],
130132
runtime=np.timedelta64(5,"D"),
131133
dt=np.timedelta64(1,"h"),
132134
output_file=output_file_reverse,

docs/user_guide/examples/tutorial_Argofloats.ipynb

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"\n",
6464
" # Phase 3: Rising with vertical_speed until at surface\n",
6565
" ptcls3.dz -= vertical_speed * ptcls3.dt\n",
66-
" ptcls3.temp = fieldset.thetao[ptcls3.time, ptcls3.z, ptcls3.y, ptcls3.x]\n",
66+
" ptcls3.temp = fieldset.thetao[ptcls3.t, ptcls3.z, ptcls3.y, ptcls3.x]\n",
6767
" next_phase = ptcls3.z + ptcls3.dz <= mindepth\n",
6868
" ptcls3.cycle_phase[next_phase] = 4\n",
6969
" ptcls3.dz[next_phase] = mindepth - ptcls3.z[next_phase] # avoid overshoot\n",
@@ -107,9 +107,6 @@
107107
" \"CopernicusMarine_data_for_Argo_tutorial/data\"\n",
108108
")\n",
109109
"\n",
110-
"# TODO check how we can get good performance without loading full dataset in memory\n",
111-
"ds_fields.load() # load the dataset into memory\n",
112-
"\n",
113110
"# Select fields\n",
114111
"fields = {\n",
115112
" \"U\": ds_fields[\"uo\"],\n",
@@ -120,6 +117,7 @@
120117
"# Convert to SGRID-compliant dataset and create FieldSet\n",
121118
"ds_fset = parcels.convert.copernicusmarine_to_sgrid(fields=fields)\n",
122119
"fieldset = parcels.FieldSet.from_sgrid_conventions(ds_fset)\n",
120+
"fieldset.to_windowed_arrays()\n",
123121
"\n",
124122
"# Define a new Particle type including extra Variables\n",
125123
"ArgoParticle = parcels.Particle.add_variable(\n",
@@ -183,8 +181,8 @@
183181
"\n",
184182
"fig = plt.figure(figsize=(13, 6))\n",
185183
"ax = plt.axes()\n",
186-
"ax.plot(df[\"time\"], df[\"z\"], color=\"gray\")\n",
187-
"cb = ax.scatter(df[\"time\"], df[\"z\"], c=df[\"temp\"], s=20, marker=\"o\", zorder=2)\n",
184+
"ax.plot(df[\"t\"], df[\"z\"], color=\"gray\")\n",
185+
"cb = ax.scatter(df[\"t\"], df[\"z\"], c=df[\"temp\"], s=20, marker=\"o\", zorder=2)\n",
188186
"ax.set_xlabel(\"Time [days]\")\n",
189187
"ax.set_ylabel(\"Depth (m)\")\n",
190188
"ax.invert_yaxis()\n",

docs/user_guide/examples/tutorial_croco_3D.ipynb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,8 @@
265265
"```python\n",
266266
"def SampleTempCroco(particles, fieldset):\n",
267267
" \"\"\"Sample temperature field on a CROCO sigma grid by first converting z to sigma levels.\"\"\"\n",
268-
" sigma = convert_z_to_sigma_croco(fieldset, particles.time, particles.z, particles.y, particles.x, particles)\n",
269-
" particles.temp = fieldset.T[particles.time, sigma, particles.y, particles.x, particles]"
268+
" sigma = convert_z_to_sigma_croco(fieldset, particles.t, particles.z, particles.y, particles.x, particles)\n",
269+
" particles.temp = fieldset.T[particles.t, sigma, particles.y, particles.x, particles]"
270270
]
271271
},
272272
{
@@ -278,14 +278,14 @@
278278
"In particular, the following algorithm is used (note that the RK4 version is slightly more complex than this Euler-Forward version, but the idea is identical). Also note that the vertical velocity is linearly interpolated here, which gives much better results than the default C-grid interpolation.\n",
279279
"\n",
280280
"```python\n",
281-
"sigma = particles.z / fieldset.h[particles.time, 0, particles.y, particles.x]\n",
281+
"sigma = particles.z / fieldset.h[particles.t, 0, particles.y, particles.x]\n",
282282
"\n",
283-
"sigma_levels = convert_z_to_sigma_croco(fieldset, particles.time, particles.z, particles.y, particles.x, particles)\n",
284-
"(u, v) = fieldset.UV[time, sigma_levels, particles.y, particles.x, particles]\n",
285-
"w = fieldset.W[time, sigma_levels, particles.y, particles.x, particles]\n",
283+
"sigma_levels = convert_z_to_sigma_croco(fieldset, particles.t, particles.z, particles.y, particles.x, particles)\n",
284+
"(u, v) = fieldset.UV[particles.t, sigma_levels, particles.y, particles.x, particles]\n",
285+
"w = fieldset.W[particles.t, sigma_levels, particles.y, particles.x, particles]\n",
286286
"\n",
287287
"# scaling the w with the sigma level of the particle\n",
288-
"w_sigma = w * sigma / fieldset.h[particles.time, 0, particles.y, particles.x, particles]\n",
288+
"w_sigma = w * sigma / fieldset.h[particles.t, 0, particles.y, particles.x, particles]\n",
289289
"\n",
290290
"x_new = particles.x + u*particles.dt\n",
291291
"y_new = particles.y + v*particles.dt\n",
@@ -294,7 +294,7 @@
294294
"sigma_new = sigma + w_sigma*particles.dt \n",
295295
"\n",
296296
"# converting back from sigma to z, at _new_ location\n",
297-
"z_new = sigma_new * fieldset.h[particles.time, 0, y_new, x_new, particles]\n",
297+
"z_new = sigma_new * fieldset.h[particles.t, 0, y_new, x_new, particles]\n",
298298
"```"
299299
]
300300
}

0 commit comments

Comments
 (0)