Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

### AI Disclosure

<!--- Please review our AI & contribution guidelines (https://docs.oceanparcels.org/en/main/development/policies.html#use-of-ai-in-development). Remove this section if your PR does not contain AI-generated content. --->
<!--- Please review our AI & contribution guidelines (https://docs.parcels-code.org/en/main/development/policies.html#use-of-ai-in-development). Remove this section if your PR does not contain AI-generated content. --->

- [ ] This PR contains AI-generated content.
- [ ] I have tested any AI-generated content in my PR.
Expand Down
2 changes: 1 addition & 1 deletion docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#

# You can set these variables from the command line.
SPHINXOPTS =
SPHINXOPTS = --show-traceback --fail-on-warning --keep-going --jobs auto
SPHINXBUILD = sphinx-build
SPHINXATUOBUILD = sphinx-autobuild
PAPER =
Expand Down
3 changes: 2 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""autoSphinx configuration file for Parcels documentation."""
# parcels documentation build configuration file, created by
# Parcels documentation build configuration file, created by
# sphinx-quickstart on Tue Oct 20 09:58:20 2015.
#
# This file is execfile()d with the current directory set to its
Expand Down Expand Up @@ -522,6 +522,7 @@ def linkcode_resolve(domain, info):
nb_execution_excludepatterns = ["jupyter_execute", ".jupyter_cache"]
nb_execution_raise_on_error = True
nb_execution_timeout = 75
suppress_warnings = ["mystnb.unknown_mime_type"]

# -- Options for autoapi --------------------------------------------------
autoapi_dirs = ["../src/parcels"]
Expand Down
2 changes: 1 addition & 1 deletion docs/development/maintainer.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@
- Parcels development status
- Check feature tiles
- (once package is available on conda) Re-build the Binder
- Ask for the shared parcels environment on [Lorenz](https://github.com/IMAU-oceans/Lorenz) to be updated
- Ask for the shared Parcels environment on [Lorenz](https://github.com/IMAU-oceans/Lorenz) to be updated
1 change: 0 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ Connect with our community!
:hidden:

Home <self>
Getting started <getting_started/index>
User guide <user_guide/index>
Community <community/index>
Development <development/index>
Expand Down
38 changes: 23 additions & 15 deletions docs/user_guide/examples/explanation_interpolation.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ particles.temperature = fieldset.temperature[particles]
````{note}
The statement above is shorthand for
```python
particles.temperature = fieldset.temperature[particles.t, particles.z, particles.y, particles.x, particles]
particles.temperature = fieldset.temperature[
particles.t,
particles.z,
particles.y,
particles.x,
particles
]
Comment on lines +17 to +23

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious if this is a result of an autoformatter? (if not, I think it would be a good ideal to include an autoformatter for python code cells in docs)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I hand-formatted this for better readability. An autoformatter would indeed be a good idea

@VeckoTheGecko VeckoTheGecko Aug 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, I'll see if I can include that in this/a separate PR

```
where the `particles` argument at the end provides the grid search algorithm with a first guess for the element indices to interpolate on.

Expand All @@ -38,27 +44,29 @@ the requested value at the particles location.

The interpolators included in Parcels are designed for common interpolation schemes in Parcels simulations; see the [Using the built-in interpolators tutorial](./tutorial_interpolation.ipynb).

If we want to create a custom interpolation method, we need to look at the interpolator API. Each interpolator is a class that inherits from either the `ScalarInterpolator` or `VectorInterpolator` class. The `ScalarInterpolator` class is used for scalar fields, such as temperature or salinity, while the `VectorInterpolator` class is used for vector fields, such as velocity. An interpolator class than has to have a `.interp()` method with the following signature:
If we want to create a custom interpolation method, we need to look at the interpolator API. Each interpolator is a class that inherits from either the `ScalarInterpolator` or `VectorInterpolator` class. The `ScalarInterpolator` class is used for scalar fields, such as temperature or salinity, while the `VectorInterpolator` class is used for vector fields, such as velocity.

An interpolator class must have a `.interp()` method with the following signature:

```python
def interp(
self,
particle_positions: dict[str, float | np.ndarray],
grid_positions: dict[ptyping.XgridAxis, dict[str, int | float | np.ndarray]],
field: Field,
):
...
def interp(
self,
particle_positions: dict[str, float | np.ndarray],
grid_positions: dict[ptyping.XgridAxis, dict[str, int | float | np.ndarray]],
field: Field,
):
...
```

The `particle_positions` dictionary contains:

```
particle_positions = {"t", t, "z", z, "y", y, "x", x}
```python
particle_positions = {"t": t, "z": z, "y": y, "x": x}
```

For structured (`X`) grids, the `grid_positions` dictionary contains:

```
```python
grid_positions = {
"T": {"index": ti, "bcoord": tau},
"Z": {"index": zi, "bcoord": zeta},
Expand All @@ -71,14 +79,14 @@ where `index` is the grid index in the corresponding dimension, and `bcoord` is

For unstructured (`UX`) grids, the same dictionary is defined as:

```
```python
grid_positions = {
"T": {"index": ti, "bcoord": tau},
"Z": {"index": zi, "bcoord": zeta},
"FACE": {"index": fi, "bcoord": bcoord}
}
```

The `.interp()` method should return a float (in the case o a `ScalarInterpolator` or a tuple of three floats `(u, v, w)` in the case of a `VectorInterpolator`).
The `.interp()` method should return a float (in the case of a `ScalarInterpolator` or a tuple of three floats `(u, v, w)` in the case of a `VectorInterpolator`).

Writing custom interpolators is not trivial, so we recommend that you have a look at the built-in interpolators in `parcels.interpolators._xinterpolators` or `parcels.interpolators._uxinterpolators` to see how they are implemented.
Writing custom interpolators is not trivial, so we recommend that you have a look at the built-in interpolators in {py:func}`parcels.interpolators._xinterpolators` or {py:func}`parcels.interpolators._uxinterpolators` to see how they are implemented.
12 changes: 9 additions & 3 deletions docs/user_guide/examples/explanation_performance.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
---
file_format: mystnb
kernelspec:
name: python3
---

# 📖 Squeezing performance in Parcels

In many Parcels simulations, the bottle-neck in terms of performance is the retrieval of the hydrodynamic field data from disk. This is especially true for simulations with a relatively small number of particles, where the time spent on retrieving the fields can be much larger than the time spent on computing the particle trajectories.
Expand All @@ -18,7 +24,7 @@ _Uses Parcels Backend: Numpy_

For relatively small Datasets (less than a few GB), it is possible to load the entire FieldSet into memory. This can be done by calling the `load()` method on the `xarray.Dataset` object:

```{code-cell}
```{code-block} python
ds = ds.load()
```

Comment thread
VeckoTheGecko marked this conversation as resolved.
Expand All @@ -38,7 +44,7 @@ _Uses Parcels Backend: Zarr_

If your Dataset is too large to fit into memory, but your particles are only distributed over a small part of the domain, it could be efficient to use cached zarr files. This can be done by using the (experimental) `zarr.CacheStore` in combination with the `parcels.open_raw_zarr()` function. This will make Parcels only load the chunks that are needed for the particles, and cache these chunks in memory for future use.

```{code-cell}
```{code-block} python
source_store = zarr.storage.LocalStore(filenames)
cache_store = zarr.storage.MemoryStore()

Expand Down Expand Up @@ -69,7 +75,7 @@ If your Dataset is so large that it doesn't fit into memory, you can use the `fi

The two timeslices (the current and the next) are fully loaded into memory, so this method is especially useful if your particles are distributed over the entire domain, as all data will then have to be accessed anyway.

```{code-cell}
```{code-block} python
fieldset.to_windowed_arrays()
```

Expand Down
2 changes: 1 addition & 1 deletion docs/user_guide/examples/tutorial_croco_3D.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"metadata": {},
"source": [
"```{note}\n",
"In the code below, we use the `w` velocity field for vertical velocity. However, it is unclear whether this is always the right choice. CROCO (and ROMS) also output an `omega` field, which may be more appropriate to use. The idealised simulation below only works when using `w`, though. In other simulations, it is recommended to test whether `omega` provides more realistic results. See https://github.com/OceanParcels/Parcels/discussions/1728 for more information.\n",
"In the code below, we use the `w` velocity field for vertical velocity. However, it is unclear whether this is always the right choice. CROCO (and ROMS) also output an `omega` field, which may be more appropriate to use. The idealised simulation below only works when using `w`, though. In other simulations, it is recommended to test whether `omega` provides more realistic results. See https://github.com/Parcels-code/Parcels/discussions/1728 for more information.\n",
"```"
]
},
Expand Down
2 changes: 1 addition & 1 deletion docs/user_guide/examples/tutorial_delaystart.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@
"source": [
"<div class=\"alert alert-info\">\n",
"\n",
"Note that the `repeatdt` argument in `parcels.ParticleSet` used in previous versions of parcels is no longer supported as of v4\n",
"Note that the `repeatdt` argument in `parcels.ParticleSet` used in previous versions of Parcels is no longer supported as of v4\n",
"</div>"
]
},
Expand Down
18 changes: 3 additions & 15 deletions docs/user_guide/examples/tutorial_diffusion.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,7 @@
"\n",
"The extra term in the M1 scheme provides extra accuracy at negligible computational cost.\n",
"\n",
"The spatial derivatives in the EM and M1 schemes can be approximated by a central difference. Higher order numerical schemes (see [Gräwe et al., 2012](https://doi.org/10.1007/s10236-012-0523-y)) include higher order derivatives.\n",
"\n",
"```{note}\n",
"TODO: explore higher order derivatives and numerical schemes (using cubic spline interpolation) in v4 \n",
"```\n",
"The spatial derivatives in the EM and M1 schemes can be approximated by a central difference. Higher order numerical schemes (see [Gräwe et al., 2012](https://doi.org/10.1007/s10236-012-0523-y)) include higher order derivatives. It should be possible to also use cubic spline interpolation in Parcels to compute the derivatives, which may be more accurate than finite differences. This is to be explored.\n",
"\n",
"An overview of numerical approximations for SDEs in a particle tracking setting can be found in [Gräwe (2011)](https://doi.org/10.1016/j.ocemod.2010.10.002).\n",
"\n",
Expand Down Expand Up @@ -516,19 +512,11 @@
"fields = {\"U\": ds_fields[\"uo\"], \"V\": ds_fields[\"vo\"]}\n",
"ds_fset = parcels.convert.copernicusmarine_to_sgrid(fields=fields)\n",
"\n",
"# TODO implement zero-dimension support on fieldset dimensions (#2727)\n",
"# ds_fset[\"cell_areas\"] = ([\"lat\", \"lon\"], calc_cell_areas(ds_fields))\n",
"ds_fset[\"cell_areas\"] = ([\"lat\", \"lon\"], calc_cell_areas(ds_fields))\n",
"\n",
"fieldset = parcels.FieldSet.from_sgrid_conventions(ds_fset)\n",
"fieldset.add_context(\"Cs\", 0.1)\n",
"\n",
"# TODO remove if previous TODO fixed\n",
"ds_cell_areas = ds_fset[[\"grid\", \"lon\", \"lat\"]]\n",
"ds_cell_areas[\"cell_areas\"] = ([\"lat\", \"lon\"], calc_cell_areas(ds_fields))\n",
"fset2 = parcels.FieldSet.from_sgrid_conventions(ds_cell_areas)\n",
"\n",
"fieldset += fset2\n",
"\n",
"# Convert the FieldSet to windowed arrays for better performance\n",
"fieldset = fieldset.to_windowed_arrays()"
]
Expand Down Expand Up @@ -629,7 +617,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Parcels:docs (3.14.6)",
"display_name": "Parcels:test (3.14.6)",
"language": "python",
"name": "python3"
},
Expand Down
4 changes: 2 additions & 2 deletions docs/user_guide/examples/tutorial_interpolation.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@
"source": [
"### Interpolation at boundaries\n",
"In some cases, we need to implement specific boundary conditions, for example to prevent particles from \n",
"getting \"stuck\" near land. [This guide](../examples_v3/documentation_unstuck_Agrid.ipynb) describes \n",
"how to implement this in parcels using {py:obj}`parcels.interpolators.XFreeslip` and {py:obj}`parcels.interpolators.XPartialslip`."
"getting \"stuck\" near land. [This guide](./tutorial_unstuck_Agrid.ipynb) describes \n",
"how to implement this in Parcels using {py:obj}`parcels.interpolators.XFreeslip` and {py:obj}`parcels.interpolators.XPartialslip`."
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion docs/user_guide/examples/tutorial_nemo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"Parcels supports [curvilinear grids](https://www.nemo-ocean.eu/doc/node108.html) such as those used in the [NEMO models](https://www.nemo-ocean.eu/).\n",
"\n",
"```{note}\n",
"TODO: make explicit how Parcels determines rotation\n",
"Parcels assumes that the velocities on curvilinear C-grids are in the `i` and `j` directions of the curvilinear grid, which are not necessarily aligned with the `x` and `y` directions. Parcels will rotate the velocities to the `x` and `y` directions under the hood. On A-grids, on the other hand, the velocities are assumed to be in the `x` and `y` directions.\n",
"```\n",
"\n",
"We will be using the example dataset `NemoCurvilinear_data`. These fields are a purely zonal flow on an aqua-planet (so zonal-velocity is 1 m s<sup>-1</sup> and meridional-velocity is 0 m s<sup>-1</sup> everywhere, and no land). However, because of the curvilinear grid, the `U` and `V` fields vary for the rotated grid cells north of 20N."
Expand Down
4 changes: 2 additions & 2 deletions docs/user_guide/examples/tutorial_sampling.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"source": [
"## Basic sampling\n",
"\n",
"We import both the packages that we need to set up the simulation, as well as the parcels package."
"We import both the packages that we need to set up the simulation, as well as the Parcels package."
]
},
{
Expand All @@ -47,7 +47,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Suppose we want to study the environmental temperature for plankton drifting in the Agulhas current. We have a CopernicusMarine dataset with surface ocean velocities and the corresponding potential temperature (\"thetao\") stored in netcdf files in the [parcels example dataset repository](https://github.com/OceanParcels/parcels-data). Loading in the FieldSet, parcels detects U and V because they have CF standard names and tells us that they are assumed as the velocity fields to be used in the simulation.\n"
"Suppose we want to study the environmental temperature for plankton drifting in the Agulhas current. We have a CopernicusMarine dataset with surface ocean velocities and the corresponding potential temperature (\"thetao\") stored in netcdf files in the [Parcels example dataset repository](https://github.com/Parcels-code/parcels-data). Loading in the FieldSet, Parcels detects U and V because they have CF standard names and tells us that they are assumed as the velocity fields to be used in the simulation.\n"
]
},
{
Expand Down
Loading