Skip to content

Commit d9f3b2f

Browse files
Merge branch 'v4-dev' into reference-API-links
2 parents fb29e51 + 2abecb1 commit d9f3b2f

Some content is hidden

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

43 files changed

+1527
-524
lines changed

docs/user_guide/examples/tutorial_Argofloats.ipynb

Lines changed: 50 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -26,70 +26,62 @@
2626
"source": [
2727
"import numpy as np\n",
2828
"\n",
29-
"# Define the new Kernels that mimic Argo vertical movement\n",
29+
"# Define the new Kernel that mimics Argo vertical movement\n",
3030
"driftdepth = 1000 # maximum depth in m\n",
3131
"maxdepth = 2000 # maximum depth in m\n",
3232
"vertical_speed = 0.10 # sink and rise speed in m/s\n",
3333
"cycletime = 10 * 86400 # total time of cycle in seconds\n",
3434
"drifttime = 9 * 86400 # time of deep drift in seconds\n",
3535
"\n",
3636
"\n",
37-
"def ArgoPhase1(particles, fieldset):\n",
38-
" def SinkingPhase(p):\n",
39-
" \"\"\"Phase 0: Sinking with vertical_speed until depth is driftdepth\"\"\"\n",
40-
" p.dz += vertical_speed * particles.dt\n",
41-
" p.cycle_phase = np.where(p.z + p.dz >= driftdepth, 1, p.cycle_phase)\n",
42-
" p.dz = np.where(p.z + p.dz >= driftdepth, driftdepth - p.z, p.dz)\n",
37+
"def ArgoVerticalMovement(particles, fieldset):\n",
38+
" # Split particles based on their current cycle_phase\n",
39+
" ptcls0 = particles[particles.cycle_phase == 0]\n",
40+
" ptcls1 = particles[particles.cycle_phase == 1]\n",
41+
" ptcls2 = particles[particles.cycle_phase == 2]\n",
42+
" ptcls3 = particles[particles.cycle_phase == 3]\n",
43+
" ptcls4 = particles[particles.cycle_phase == 4]\n",
44+
"\n",
45+
" # Phase 0: Sinking with vertical_speed until depth is driftdepth\n",
46+
" ptcls0.dz += vertical_speed * ptcls0.dt\n",
47+
" ptcls0.cycle_phase = np.where(\n",
48+
" ptcls0.z + ptcls0.dz >= driftdepth, 1, ptcls0.cycle_phase\n",
49+
" )\n",
50+
" ptcls0.dz = np.where(\n",
51+
" ptcls0.z + ptcls0.dz >= driftdepth, driftdepth - ptcls0.z, ptcls0.dz\n",
52+
" )\n",
53+
"\n",
54+
" # Phase 1: Drifting at depth for drifttime seconds\n",
55+
" ptcls1.drift_age += ptcls1.dt\n",
56+
" ptcls1.cycle_phase = np.where(ptcls1.drift_age >= drifttime, 2, ptcls1.cycle_phase)\n",
57+
" ptcls1.drift_age = np.where(ptcls1.drift_age >= drifttime, 0, ptcls1.drift_age)\n",
58+
"\n",
59+
" # Phase 2: Sinking further to maxdepth\n",
60+
" ptcls2.dz += vertical_speed * ptcls2.dt\n",
61+
" ptcls2.cycle_phase = np.where(\n",
62+
" ptcls2.z + ptcls2.dz >= maxdepth, 3, ptcls2.cycle_phase\n",
63+
" )\n",
64+
" ptcls2.dz = np.where(\n",
65+
" ptcls2.z + ptcls2.dz >= maxdepth, maxdepth - ptcls2.z, ptcls2.dz\n",
66+
" )\n",
67+
"\n",
68+
" # Phase 3: Rising with vertical_speed until at surface\n",
69+
" ptcls3.dz -= vertical_speed * ptcls3.dt\n",
70+
" ptcls3.temp = fieldset.thetao[ptcls3.time, ptcls3.z, ptcls3.lat, ptcls3.lon]\n",
71+
" ptcls3.cycle_phase = np.where(\n",
72+
" ptcls3.z + ptcls3.dz <= fieldset.mindepth, 4, ptcls3.cycle_phase\n",
73+
" )\n",
74+
" ptcls3.dz = np.where(\n",
75+
" ptcls3.z + ptcls3.dz <= fieldset.mindepth,\n",
76+
" fieldset.mindepth - ptcls3.z,\n",
77+
" ptcls3.dz,\n",
78+
" )\n",
79+
"\n",
80+
" # Phase 4: Transmitting at surface until cycletime is reached\n",
81+
" ptcls4.cycle_phase = np.where(ptcls4.cycle_age >= cycletime, 0, ptcls4.cycle_phase)\n",
82+
" ptcls4.cycle_age = np.where(ptcls4.cycle_age >= cycletime, 0, ptcls4.cycle_age)\n",
83+
" ptcls4.temp = np.nan # no temperature measurement when at surface\n",
4384
"\n",
44-
" SinkingPhase(particles[particles.cycle_phase == 0])\n",
45-
"\n",
46-
"\n",
47-
"def ArgoPhase2(particles, fieldset):\n",
48-
" def DriftingPhase(p):\n",
49-
" \"\"\"Phase 1: Drifting at depth for drifttime seconds\"\"\"\n",
50-
" p.drift_age += particles.dt\n",
51-
" p.cycle_phase = np.where(p.drift_age >= drifttime, 2, p.cycle_phase)\n",
52-
" p.drift_age = np.where(p.drift_age >= drifttime, 0, p.drift_age)\n",
53-
"\n",
54-
" DriftingPhase(particles[particles.cycle_phase == 1])\n",
55-
"\n",
56-
"\n",
57-
"def ArgoPhase3(particles, fieldset):\n",
58-
" def SecondSinkingPhase(p):\n",
59-
" \"\"\"Phase 2: Sinking further to maxdepth\"\"\"\n",
60-
" p.dz += vertical_speed * particles.dt\n",
61-
" p.cycle_phase = np.where(p.z + p.dz >= maxdepth, 3, p.cycle_phase)\n",
62-
" p.dz = np.where(p.z + p.dz >= maxdepth, maxdepth - p.z, p.dz)\n",
63-
"\n",
64-
" SecondSinkingPhase(particles[particles.cycle_phase == 2])\n",
65-
"\n",
66-
"\n",
67-
"def ArgoPhase4(particles, fieldset):\n",
68-
" def RisingPhase(p):\n",
69-
" \"\"\"Phase 3: Rising with vertical_speed until at surface\"\"\"\n",
70-
" p.dz -= vertical_speed * particles.dt\n",
71-
" p.temp = fieldset.thetao[p.time, p.z, p.lat, p.lon]\n",
72-
" p.cycle_phase = np.where(p.z + p.dz <= fieldset.mindepth, 4, p.cycle_phase)\n",
73-
" p.dz = np.where(\n",
74-
" p.z + p.dz <= fieldset.mindepth,\n",
75-
" fieldset.mindepth - p.z,\n",
76-
" p.dz,\n",
77-
" )\n",
78-
"\n",
79-
" RisingPhase(particles[particles.cycle_phase == 3])\n",
80-
"\n",
81-
"\n",
82-
"def ArgoPhase5(particles, fieldset):\n",
83-
" def TransmittingPhase(p):\n",
84-
" \"\"\"Phase 4: Transmitting at surface until cycletime is reached\"\"\"\n",
85-
" p.cycle_phase = np.where(p.cycle_age >= cycletime, 0, p.cycle_phase)\n",
86-
" p.cycle_age = np.where(p.cycle_age >= cycletime, 0, p.cycle_age)\n",
87-
" p.temp = np.nan # no temperature measurement when at surface\n",
88-
"\n",
89-
" TransmittingPhase(particles[particles.cycle_phase == 4])\n",
90-
"\n",
91-
"\n",
92-
"def ArgoPhase6(particles, fieldset):\n",
9385
" particles.cycle_age += particles.dt # update cycle_age"
9486
]
9587
},
@@ -136,9 +128,7 @@
136128
"ArgoParticle = parcels.Particle.add_variable(\n",
137129
" [\n",
138130
" parcels.Variable(\"cycle_phase\", dtype=np.int32, initial=0.0),\n",
139-
" parcels.Variable(\n",
140-
" \"cycle_age\", dtype=np.float32, initial=0.0\n",
141-
" ), # TODO update to \"timedelta64[s]\"\n",
131+
" parcels.Variable(\"cycle_age\", dtype=np.float32, initial=0.0),\n",
142132
" parcels.Variable(\"drift_age\", dtype=np.float32, initial=0.0),\n",
143133
" parcels.Variable(\"temp\", dtype=np.float32, initial=np.nan),\n",
144134
" ]\n",
@@ -155,12 +145,7 @@
155145
"\n",
156146
"# combine Argo vertical movement kernel with built-in Advection kernel\n",
157147
"kernels = [\n",
158-
" ArgoPhase1,\n",
159-
" ArgoPhase2,\n",
160-
" ArgoPhase3,\n",
161-
" ArgoPhase4,\n",
162-
" ArgoPhase5,\n",
163-
" ArgoPhase6,\n",
148+
" ArgoVerticalMovement,\n",
164149
" parcels.kernels.AdvectionRK4,\n",
165150
"]\n",
166151
"\n",

docs/user_guide/examples/tutorial_diffusion.ipynb

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@
192192
"source": [
193193
"from parcels._datasets.structured.generated import simple_UV_dataset\n",
194194
"\n",
195-
"ds = simple_UV_dataset(dims=(1, 1, Ny, 1), mesh=\"flat\").isel(time=0, depth=0)\n",
195+
"ds = simple_UV_dataset(dims=(1, 1, Ny, 1), mesh=\"flat\")\n",
196196
"ds[\"lat\"][:] = np.linspace(-0.01, 1.01, Ny)\n",
197197
"ds[\"lon\"][:] = np.ones(len(ds.XG))\n",
198198
"ds[\"Kh_meridional\"] = ([\"YG\", \"XG\"], Kh_meridional[:, None])\n",
@@ -205,20 +205,8 @@
205205
"metadata": {},
206206
"outputs": [],
207207
"source": [
208-
"grid = parcels.XGrid.from_dataset(ds, mesh=\"flat\")\n",
209-
"U = parcels.Field(\"U\", ds[\"U\"], grid, interp_method=parcels.interpolators.XLinear)\n",
210-
"V = parcels.Field(\"V\", ds[\"V\"], grid, interp_method=parcels.interpolators.XLinear)\n",
211-
"UV = parcels.VectorField(\"UV\", U, V)\n",
212-
"\n",
213-
"Kh_meridional_field = parcels.Field(\n",
214-
" \"Kh_meridional\",\n",
215-
" ds[\"Kh_meridional\"],\n",
216-
" grid,\n",
217-
" interp_method=parcels.interpolators.XLinear,\n",
218-
")\n",
219-
"fieldset = parcels.FieldSet([U, V, UV, Kh_meridional_field])\n",
208+
"fieldset = parcels.FieldSet.from_sgrid_conventions(ds, mesh=\"flat\")\n",
220209
"fieldset.add_constant_field(\"Kh_zonal\", 1, mesh=\"flat\")\n",
221-
"\n",
222210
"fieldset.add_constant(\"dres\", 0.00005)"
223211
]
224212
},

docs/user_guide/examples/tutorial_interaction.ipynb

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -293,18 +293,9 @@
293293
" larger_idx = np.where(mass_j > mass_i, pair_j, pair_i)\n",
294294
" smaller_idx = np.where(mass_j > mass_i, pair_i, pair_j)\n",
295295
"\n",
296-
" # perform transfer and mark deletions\n",
297-
" # TODO note that we use temporary arrays for indexing because of KernelParticle bug (GH #2143)\n",
298-
" masses = particles.mass\n",
299-
" states = particles.state\n",
300-
"\n",
301296
" # transfer mass from smaller to larger and mark smaller for deletion\n",
302-
" masses[larger_idx] += particles.mass[smaller_idx]\n",
303-
" states[smaller_idx] = parcels.StatusCode.Delete\n",
304-
"\n",
305-
" # TODO use particle variables directly after KernelParticle bug (GH #2143) is fixed\n",
306-
" particles.mass = masses\n",
307-
" particles.state = states"
297+
" particles.mass[larger_idx] += particles.mass[smaller_idx]\n",
298+
" particles.state[smaller_idx] = parcels.StatusCode.Delete"
308299
]
309300
},
310301
{

docs/user_guide/examples/tutorial_interpolation.ipynb

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,20 @@
4646
"source": [
4747
"from parcels._datasets.structured.generated import simple_UV_dataset\n",
4848
"\n",
49-
"ds = simple_UV_dataset(dims=(1, 1, 5, 4), mesh=\"flat\").isel(time=0, depth=0)\n",
49+
"ds = simple_UV_dataset(dims=(1, 1, 5, 4), mesh=\"flat\")\n",
5050
"ds[\"lat\"][:] = np.linspace(0.0, 1.0, len(ds.YG))\n",
5151
"ds[\"lon\"][:] = np.linspace(0.0, 1.0, len(ds.XG))\n",
5252
"dx, dy = 1.0 / len(ds.XG), 1.0 / len(ds.YG)\n",
5353
"ds[\"P\"] = ds[\"U\"] + np.random.rand(5, 4) + 0.1\n",
54-
"ds[\"P\"][1, 1] = 0\n",
54+
"ds[\"P\"][:, :, 1, 1] = 0\n",
5555
"ds"
5656
]
5757
},
5858
{
5959
"cell_type": "markdown",
6060
"metadata": {},
6161
"source": [
62-
"From this dataset we create a {py:obj}`parcels.FieldSet`. Parcels requires an interpolation method to be set for each {py:obj}`parcels.Field`, which we will later adapt to see the effects of the different interpolators. A common interpolator for fields on structured grids is (tri)linear, implemented in {py:obj}`parcels.interpolators.XLinear`."
62+
"From this dataset we create a {py:obj}`parcels.FieldSet` using the {py:meth}`parcels.FieldSet.from_sgrid_conventions` constructor, which automatically sets up the grid and fields according to Parcels' s-grid conventions."
6363
]
6464
},
6565
{
@@ -68,12 +68,7 @@
6868
"metadata": {},
6969
"outputs": [],
7070
"source": [
71-
"grid = parcels.XGrid.from_dataset(ds, mesh=\"flat\")\n",
72-
"U = parcels.Field(\"U\", ds[\"U\"], grid, interp_method=parcels.interpolators.XLinear)\n",
73-
"V = parcels.Field(\"V\", ds[\"V\"], grid, interp_method=parcels.interpolators.XLinear)\n",
74-
"UV = parcels.VectorField(\"UV\", U, V)\n",
75-
"P = parcels.Field(\"P\", ds[\"P\"], grid, interp_method=parcels.interpolators.XLinear)\n",
76-
"fieldset = parcels.FieldSet([U, V, UV, P])"
71+
"fieldset = parcels.FieldSet.from_sgrid_conventions(ds, mesh=\"flat\")"
7772
]
7873
},
7974
{

docs/user_guide/examples/tutorial_nemo_curvilinear.ipynb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
"outputs": [],
153153
"source": [
154154
"u, v = fieldset.UV.eval(\n",
155-
" np.array([0]), np.array([0]), np.array([20]), np.array([50]), applyConversion=False\n",
155+
" np.array([0]), np.array([0]), np.array([20]), np.array([50]), apply_conversion=False\n",
156156
") # do not convert m/s to deg/s\n",
157157
"print(f\"(u, v) = ({u[0]:.3f}, {v[0]:.3f})\")\n",
158158
"assert np.isclose(u, 1.0, atol=1e-3)"
@@ -298,7 +298,7 @@
298298
],
299299
"metadata": {
300300
"kernelspec": {
301-
"display_name": "test-notebooks",
301+
"display_name": "default",
302302
"language": "python",
303303
"name": "python3"
304304
},
@@ -312,7 +312,7 @@
312312
"name": "python",
313313
"nbconvert_exporter": "python",
314314
"pygments_lexer": "ipython3",
315-
"version": "3.11.0"
315+
"version": "3.14.2"
316316
}
317317
},
318318
"nbformat": 4,

0 commit comments

Comments
 (0)