|
26 | 26 | "source": [ |
27 | 27 | "import numpy as np\n", |
28 | 28 | "\n", |
29 | | - "# Define the new Kernels that mimic Argo vertical movement\n", |
| 29 | + "# Define the new Kernel that mimics Argo vertical movement\n", |
30 | 30 | "driftdepth = 1000 # maximum depth in m\n", |
31 | 31 | "maxdepth = 2000 # maximum depth in m\n", |
32 | 32 | "vertical_speed = 0.10 # sink and rise speed in m/s\n", |
33 | 33 | "cycletime = 10 * 86400 # total time of cycle in seconds\n", |
34 | 34 | "drifttime = 9 * 86400 # time of deep drift in seconds\n", |
35 | 35 | "\n", |
36 | 36 | "\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", |
43 | 84 | "\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", |
93 | 85 | " particles.cycle_age += particles.dt # update cycle_age" |
94 | 86 | ] |
95 | 87 | }, |
|
136 | 128 | "ArgoParticle = parcels.Particle.add_variable(\n", |
137 | 129 | " [\n", |
138 | 130 | " 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", |
142 | 132 | " parcels.Variable(\"drift_age\", dtype=np.float32, initial=0.0),\n", |
143 | 133 | " parcels.Variable(\"temp\", dtype=np.float32, initial=np.nan),\n", |
144 | 134 | " ]\n", |
|
155 | 145 | "\n", |
156 | 146 | "# combine Argo vertical movement kernel with built-in Advection kernel\n", |
157 | 147 | "kernels = [\n", |
158 | | - " ArgoPhase1,\n", |
159 | | - " ArgoPhase2,\n", |
160 | | - " ArgoPhase3,\n", |
161 | | - " ArgoPhase4,\n", |
162 | | - " ArgoPhase5,\n", |
163 | | - " ArgoPhase6,\n", |
| 148 | + " ArgoVerticalMovement,\n", |
164 | 149 | " parcels.kernels.AdvectionRK4,\n", |
165 | 150 | "]\n", |
166 | 151 | "\n", |
|
0 commit comments