You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> This branch is `v4-dev` - version 4 of Parcels which is in active development. See `main` (or the tags) to browse stable versions of Parcels.
15
+
13
16
**Parcels** (**P**robably **A****R**eally **C**omputationally **E**fficient **L**agrangian **S**imulator) is a set of Python classes and methods to create customisable particle tracking simulations using output from Ocean Circulation models. Parcels can be used to track passive and active particulates such as water, plankton, [plastic](http://www.topios.org/) and [fish](https://github.com/Jacketless/IKAMOANA).
Copy file name to clipboardExpand all lines: docs/examples/tutorial_kernelloop.ipynb
+11-25Lines changed: 11 additions & 25 deletions
Original file line number
Diff line number
Diff line change
@@ -26,17 +26,7 @@
26
26
"\n",
27
27
"When you run a Parcels simulation (i.e. a call to `pset.execute()`), the Kernel loop is the main part of the code that is executed. This part of the code loops through all particles and executes the Kernels that are defined for each particle.\n",
28
28
"\n",
29
-
"In order to make sure that the displacements of a particle in the different Kernels can be summed, all Kernels add to a _change_ in position (`particle_dlon`, `particle_dlat`, and `particle_ddepth`). This is important, because there are situations where movement kernels would otherwise not commute. Take the example of advecting particles by currents _and_ winds. If the particle would first be moved by the currents and then by the winds, the result could be different from first moving by the winds and then by the currents. Instead, by adding the changes in position, the ordering of the Kernels has no consequence on the particle displacement."
30
-
]
31
-
},
32
-
{
33
-
"cell_type": "markdown",
34
-
"metadata": {},
35
-
"source": [
36
-
"<div class=\"alert alert-info\">\n",
37
-
"\n",
38
-
"__Note__ that the variables `particle_dlon`, `particle_dlat`, and `particle_ddepth` are defined by the wrapper function that Parcels generates for each Kernel. This is why you don't have to define these variables yourself when writing a Kernel. See [here](https://github.com/OceanParcels/parcels/blob/daa4b062ed8ae0b2be3d87367d6b45599d6f95db/parcels/kernel.py#L277-L294) for the implementation of the wrapper functions.\n",
39
-
"</div>"
29
+
"In order to make sure that the displacements of a particle in the different Kernels can be summed, all Kernels add to a _change_ in position (`particles.dlon`, `particles.dlat`, and `particles.ddepth`). This is important, because there are situations where movement kernels would otherwise not commute. Take the example of advecting particles by currents _and_ winds. If the particle would first be moved by the currents and then by the winds, the result could be different from first moving by the winds and then by the currents. Instead, by adding the changes in position, the ordering of the Kernels has no consequence on the particle displacement."
40
30
]
41
31
},
42
32
{
@@ -52,29 +42,25 @@
52
42
"source": [
53
43
"Below is a structured overview of the Kernel loop is implemented. Note that this is for longitude only, but the same process is applied for latitude and depth.\n",
54
44
"\n",
55
-
"1. Define an extra variable `particle.lon_nextloop` for each particle, which is the longitude at the end of the Kernel loop. Inititalise it to `particle.lon`.\n",
56
-
"\n",
57
-
"2. Also define an extra variable `particle.time_nextloop` for each particle, which is the time at the end of the Kernel loop. Inititalise it to `particle.time`.\n",
45
+
"1. Initialise an extra Variable `particles.lon=0` and `particles.time_nextloop = particles.time`\n",
58
46
"\n",
59
-
"3. Within the Kernel loop, for each particle:<br>\n",
47
+
"2. Within the Kernel loop, for each particle:<br>\n",
60
48
"\n",
61
-
" 1. Update `particle.lon` with `particle.lon_nextloop`<br>\n",
"7. If `outputdt` is a multiple of `particle.time`, write `particle.lon` and `particle.time` to zarr output file<br>\n",
63
+
"6. If `outputdt` is a multiple of `particle.time`, write `particle.lon` and `particle.time` to zarr output file<br>\n",
78
64
"\n",
79
65
"Besides having commutable Kernels, the main advantage of this implementation is that, when using Field Sampling with e.g. `particle.temp = fieldset.Temp[particle.time, particle.depth, particle.lat, particle.lon]`, the particle location stays the same throughout the entire Kernel loop. Additionally, this implementation ensures that the particle location is the same as the location of the sampled field in the output file."
80
66
]
@@ -268,12 +254,12 @@
268
254
"### 1. Avoid updating particle locations directly in Kernels\n",
269
255
"It is better not to update `particle.lon` directly in a Kernel, as it can interfere with the loop above. Assigning a value to `particle.lon` in a Kernel will throw a warning. \n",
270
256
"\n",
271
-
"Instead, update the local variable `particle_dlon`.\n",
257
+
"Instead, update the local variable `particle.dlon`.\n",
272
258
"\n",
273
259
"### 2. Be careful with updating particle variables that do not depend on Fields.\n",
274
260
"While assigning the interpolated value of a `Field` to a Particle goes well in the loop above, this is not necessarily so for assigning other attributes. For example, a line like `particle.age += particle.dt` is executed directly so may result in the age being `dt` at `time = 0` in the output file. \n",
275
261
"\n",
276
-
"A workaround is to either initialise the age to `-dt`, or to increase the `age` only when `particle.time > 0` (using an `if` statement).\n",
262
+
"A workaround is to either initialise the age to `-dt`, or to increase the `age` only when `particle.time > 0` (using an `np.where` statement).\n",
0 commit comments