Skip to content

Commit 4378521

Browse files
reint-fischerreint-fischer
authored andcommitted
update links and diagrams
1 parent 8df5714 commit 4378521

18 files changed

Lines changed: 210 additions & 48 deletions

docs/user_guide/how-to-guides/images/parcels_user_diagram.png renamed to docs/_static/concepts_diagram.png

File renamed without changes.

docs/user_guide/how-to-guides/images/parcels_user_diagram.svg renamed to docs/_static/concepts_diagram.svg

Lines changed: 5 additions & 5 deletions
Loading

docs/community/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ Are you interested in advanced analysis and diagnostics of Parcels output or Lag
9696
9797
+++
9898
99-
```{button-link} https://github.com/Parcels-code/Lagrangian_diags
99+
```{button-link} https://lagrangian-diags.readthedocs.io/en/latest/
100100
:click-parent:
101101
:color: secondary
102102
:expand:

docs/getting_started/explanation_concepts.md

Lines changed: 128 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,158 @@ file_format: mystnb
33
kernelspec:
44
name: python3
55
---
6+
67
# Parcels concepts
78

8-
Parcels is a set of Python classes and methods to create particle tracking simulations. Here, we will explain the basic concepts defined by the most important classes and functions. This overview can be useful to start understanding the names for different components we use in Parcels, and to structure and make appropriate use of the code in a simulation script.
9+
Parcels is a set of Python classes and methods to create particle tracking simulations. Here, we will explain the basic concepts defined by the most important classes and functions. This overview can be useful to start understanding the different components we use in Parcels, and to structure the code in a simulation script.
910

1011
A Parcels simulation is generally built up from four different components:
12+
1113
1. [**FieldSet**](#1-fieldset). The input dataset of gridded fields (e.g. ocean current velocity, temperature) in which virtual particles are defined.
1214
2. [**ParticleSet**](#2-particleset). The dataset of virtual particles. These always contain time, z, lat, and lon, for which initial values must be defined, and may contain other variables.
1315
3. [**Kernels**](#3-kernels). Kernels perform some specific operation on the particles every time step (e.g. interpolate the temperature from the temperature field to the particle location).
1416
4. [**Execute**](#4-execution). Execute the simulation. The core method which integrates the operations defined in Kernels for a given time and timestep, and writes output to a ParticleFile.
1517

16-
We discuss each component in more detail below and link to more detailed [how-to guides](../user_guide/index.md) and the full list of classes and methods in the [API reference](../reference.md). If you want to learn by doing, check out the [quickstart tutorial](./tutorial_quickstart.md) to start creating your first Parcels simulation.
18+
We discuss each component in more detail below. The subsections titled **"Learn how to"** link to more detailed [how-to guide notebooks](../user_guide/index.md) and more detailed _explanations_ of Parcels functionality are included under **"Read more about"** subsections. The full list of classes and methods is in the [API reference](../reference.md). If you want to learn by doing, check out the [quickstart tutorial](./tutorial_quickstart.md) to start creating your first Parcels simulation.
1719

18-
![png](../user_guide/explanations/images/parcels_user_diagram.png)
20+
```{image} ../_static/concepts_diagram.svg
21+
:alt: Parcels concepts diagram
22+
:width: 100%
23+
```
1924

2025
## 1. FieldSet
2126

22-
Parcels provides a framework to simulate particles **within a set of fields**, such as flow velocities and temperature. To start a parcels simulation we must define this dataset with the `FieldSet` class.
27+
Parcels provides a framework to simulate particles **within a set of fields**, such as flow velocities and temperature. To start a parcels simulation we must define this dataset with the **`parcels.FieldSet`** class.
28+
29+
The input dataset from which to create a `parcels.FieldSet` can be an [`xarray.Dataset`](https://docs.xarray.dev/en/stable/user-guide/data-structures.html#dataset) with output from a hydrodynamic model or reanalysis. Such a dataset usually contains a number of gridded variables (e.g. `"U"`), which in Parcels become `parcels.Field` objects. A set of `parcels.Field` objects is stored in a `parcels.FieldSet` in an analoguous way to how `xarray.DataArray` objects combine to make an `xarray.Dataset`.
30+
31+
For several common input datasets, such as the Copernicus Marine Service analysis products, Parcels has a specific method to read and parse the data correctly:
32+
33+
```python
34+
dataset = xr.open_mfdataset("insert_copernicus_data_files.nc")
35+
fieldset = parcels.FieldSet.from_copernicusmarine(dataset)
36+
```
37+
38+
In some cases we might want to combine `parcels.Field`s from different sources in the same `parcels.FieldSet`, such as ocean currents from one dataset and Stokes drift from another. This is possible in Parcels by adding each `parcels.Field` separately:
2339

24-
The input dataset from which to create a `FieldSet` can be an `xarray.Dataset` with output from a hydrodynamic model or reanalysis.
40+
```python
41+
dataset1 = xr.dataset("insert_current_data_files.nc")
42+
dataset2 = xr.dataset("insert_stokes_data_files.nc")
43+
44+
Ucurrent = parcels.Field(name="Ucurrent", data=dataset1["Ucurrent"], grid=parcels.XGrid.from_dataset(dataset1), interp_method=parcels.interpolators.XLinear)
45+
Ustokes = parcels.Field(name="Ustokes", data=dataset2["Ustokes"], grid=parcels.XGrid.from_dataset(dataset2), interp_method=parcels.interpolators.XLinear)
46+
47+
fieldset = parcels.FieldSet([Ucurrent, Ustokes])
48+
```
2549

2650
### Grid
27-
read more about [grids](../user_guide/explanations/explanation_grids.md)
51+
52+
Each `parcels.Field` is defined on a grid. With Parcels we can simulate particles in fields on both structured (**`parcels.XGrid`**) and unstructured (**`parcels.UxGrid`**) grids. The grid is defined by the coordinates of grid cell nodes, edges, and faces. `parcels.XGrid` objects are based on [`xgcm.Grid`](https://xgcm.readthedocs.io/en/latest/grids.html), while `parcels.UxGrid` objects are based on [`uxarray.Grid`](https://uxarray.readthedocs.io/en/stable/generated/uxarray.Grid.html#uxarray.Grid) objects.
53+
54+
#### Read more about grids
55+
56+
- [Grids explanation](../user_guide/examples/explanation_grids.md)
2857

2958
### Interpolation
30-
read more about [interpolation](../user_guide/explanations/explanation_interpolation.md)
59+
60+
To find the value of a `parcels.Field` at any particle location, Parcels uses interpolation. Depending on the variable, grid, and required accuracy, different interpolation methods may be appropriate. Parcels comes with a number of built-in **`parcels.interpolators`**:
61+
62+
```{code-cell}
63+
import parcels
64+
65+
for interpolator in parcels.interpolators.__all__:
66+
print(f"{interpolator}")
67+
```
68+
69+
### Read more about
70+
71+
- [Interpolation explanation](../user_guide/examples/explanation_interpolation.md)
72+
73+
### Learn how to
74+
75+
- [Use interpolation methods](../user_guide/examples/tutorial_interpolation.ipynb)
3176

3277
## 2. ParticleSet
3378

79+
Once the environment has a `parcels.FieldSet` object, you can start defining your particles in a **`parcels.ParticleSet`** object. This object requires:
80+
81+
1. The `parcels.FieldSet` object in which the particles will be released.
82+
2. The type of `parcels.Particle`: A default `Particle` or a custom `Particle`-type with additional `Variable`s.
83+
3. Initial conditions for each `Variable` defined in the `Particle`, most notably the release coordinates of `time`, `z`, `lat` and `lon`.
84+
85+
### Learn how to
86+
87+
- [Release particles at different times](../user_guide/examples/tutorial_delaystart.ipynb)
3488

3589
## 3. Kernels
36-
read more about [Kernels](../user_guide/explanations/explanation_kernelloop.md)
90+
91+
**`parcels.Kernel`** objects are little snippets of code, which are applied to the particles in the `ParticleSet`, for every time step during a simulation. They define the computation or numerical integration done by Parcels, and can represent many processes such as advection, ageing, growth, or simply the sampling of a field.
92+
93+
Basic kernels are included in Parcels, among which several types of advection kernels:
94+
95+
```{code-cell}
96+
for kernel in parcels.kernels.advection.__all__:
97+
print(f"{kernel}")
98+
```
99+
100+
We can also write custom kernels, to add certain types of 'behaviour' to the particles. To do so we write a function with two arguments: `particles` and `fieldset`. We can then write any computation as a function of any variables defined in the `Particle` and any `Field` defined in the `FieldSet`. Kernels can then be combined by creating a `list` of the kernels. Note that the kernels are executed in order:
101+
102+
```python
103+
# Create a custom kernel which displaces each particle southward
104+
105+
def NorthVel(particles, fieldset):
106+
vvel = -1e-4
107+
particles.dlat += vvel * particles.dt
108+
109+
110+
# Create a custom kernel which keeps track of the particle age
111+
112+
def Age(particles, fieldset):
113+
particles.age += particles.dt
114+
115+
# define all kernels to be executed on particles using an (ordered) list
116+
kernels = [Age, NorthVel, parcels.kernels.AdvectionRK4]
117+
```
118+
119+
```{note}
120+
Every Kernel must be a function with the following (and only those) arguments: `(particles, fieldset)`
121+
```
122+
123+
```{warning}
124+
It is advised _not_ to update the particle coordinates (`particles.time`, `particles.z`, `particles.lat`, or `particles.lon`) directly, as that can negatively interfere with the way that particle movements by different kernels are vectorially added. Use a change in the coordinates: `particles.dlon`, `particles.dlat`, `particles.dz`, and/or `particles.dt` instead, and be careful with `particles.dt`. See also the [kernel loop tutorial](https://docs.oceanparcels.org/en/latest/examples/tutorial_kernelloop.html).
125+
```
126+
127+
```{warning}
128+
We have to be careful with writing kernels for vector fields on Curvilinear grids. While Parcels automatically rotates the "U" and "V" field when necessary, this is not the case for other fields such as Stokes drift. [This guide](../user_guide/examples/tutorial_nemo_curvilinear.ipynb) describes how to use a curvilinear grid in Parcels.
129+
```
130+
131+
### Read more about
132+
133+
- [The Kernel loop](../user_guide/examples/explanation_kernelloop.md)
134+
135+
### Learn how to
136+
137+
- [Sample fields like temperature](../user_guide/examples/tutorial_sampling.ipynb).
138+
- [Mimic the behaviour of ARGO floats](../user_guide/examples/tutorial_Argofloats.ipynb).
139+
- [Add diffusion to approximate subgrid-scale processes and unresolved physics](../user_guide/examples/tutorial_diffusion.ipynb).
140+
- [Convert between units in m/s and degree/s](../user_guide/examples/tutorial_unitconverters.ipynb).
37141

38142
## 4. Execution
39143

144+
The execution of the simulation, given the `FieldSet`, `ParticleSet`, and `Kernels` defined in the previous steps, is done using the method **`parcels.ParticleSet.execute()`**. This method requires the following arguments:
145+
146+
1. The kernels to be executed.
147+
2. The `runtime` defining how long the execution loop runs. Alternatively, you may define the `endtime` at which the execution loop stops.
148+
3. The timestep `dt` at which to execute the kernels.
149+
4. (Optional) The `ParticleFile` object to write the output to.
150+
40151
### Output
41-
ParticleFile
152+
153+
To analyse the particle data generated in the simulation, we need to define a `parcels.ParticleFile` and add it as an argument to `parcels.ParticleSet.execute()`. The output will be written in a [zarr format](https://zarr.readthedocs.io/en/stable/), which can be opened as an `xarray.Dataset`. The dataset will contain the particle data with at least `time`, `z`, `lat` and `lon`, for each particle at timesteps defined by the `outputdt` argument.
154+
155+
There are many ways to analyze particle output, and although we provide [a short tutorial to get started](./tutorial_output.ipynb), we recommend writing your own analysis code and checking out other projects such as [trajan](https://opendrift.github.io/trajan/index.html) and [Lagrangian Diagnostics](https://lagrangian-diags.readthedocs.io/en/latest/).
156+
157+
#### Learn how to
158+
159+
- [choose an appropriate timestep](../user_guide/examples/tutorial_numerical_accuracy.ipynb)
160+
- [work with Parcels output](./tutorial_output.ipynb)

docs/getting_started/index.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ Getting started with parcels is easy; here you will find:
66
:maxdepth: 1
77
Installation guide <installation.md>
88
Quickstart tutorial <tutorial_quickstart.md>
9-
Simple output tutorial <tutorial_output.ipynb>
10-
Parcels concepts explanation <explanation_concepts.md>
11-
9+
Output tutorial <tutorial_output.ipynb>
10+
Concepts explanation <explanation_concepts.md>
1211
```
1312

1413
```{note}

docs/getting_started/tutorial_output.ipynb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,15 @@
124124
")"
125125
]
126126
},
127+
{
128+
"cell_type": "markdown",
129+
"metadata": {},
130+
"source": [
131+
"```{note}\n",
132+
"TODO: add section on chunking\n",
133+
"```"
134+
]
135+
},
127136
{
128137
"attachments": {},
129138
"cell_type": "markdown",
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Grids
22

3-
Parcels `Field` objects exist on a (structured) `parcels.XGrid` or (unstructured) `parcels.UXgrid`. Here we describe these grids on a conceptual level.
3+
Parcels `Field` objects exist on a (structured) `parcels.XGrid` or (unstructured) `parcels.Uxgrid`. Here we describe these grids on a conceptual level.
44

55
```{note}
66
The contents for this page are still under development in v4.
77
TODO
88
- link to xgcm.Grid documentation
99
- adapt from v3 grid indexing tutorial (../examples_v3/documentation_indexing.ipynb)
10-
```
10+
```

docs/user_guide/examples/tutorial_nemo_curvilinear.ipynb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
"source": [
1616
"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",
1717
"\n",
18+
"```{note}\n",
19+
"TODO: make explicit how Parcels determines rotation\n",
20+
"```\n",
21+
"\n",
1822
"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 and meridional-velocity is 0 m/s everywhere, and no land). However, because of the curvilinear grid, the `U` and `V` fields vary for the rotated gridcells north of 20N.\n"
1923
]
2024
},
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "0",
6+
"metadata": {},
7+
"source": [
8+
"# Set up an efficient and accurate simulation\n",
9+
"\n",
10+
"```{note}\n",
11+
"TODO: write notebook describing how to use `dt` and integration methods in Kernels to control numerical accuracy. Use [Michaels tutorial](https://github.com/Parcels-code/10year-anniversary-session2/blob/main/advection_and_windage.ipynb) as a starting point.\n",
12+
"```"
13+
]
14+
}
15+
],
16+
"metadata": {
17+
"language_info": {
18+
"name": "python"
19+
}
20+
},
21+
"nbformat": 4,
22+
"nbformat_minor": 5
23+
}
-15.7 KB
Binary file not shown.

0 commit comments

Comments
 (0)