|
58 | 58 | "import xarray as xr\n", |
59 | 59 | "from matplotlib.animation import FuncAnimation\n", |
60 | 60 | "\n", |
61 | | - "plt.rcParams[\"animation.html\"] = \"jshtml\"\n", |
| 61 | + "import parcels\n", |
62 | 62 | "\n", |
63 | | - "import parcels" |
| 63 | + "# for interactive display of animations\n", |
| 64 | + "plt.rcParams[\"animation.html\"] = \"jshtml\"" |
64 | 65 | ] |
65 | 66 | }, |
66 | 67 | { |
|
73 | 74 | "def Pull(particles, fieldset):\n", |
74 | 75 | " \"\"\"InterActionKernel that \"pulls\" all neighbor particles\n", |
75 | 76 | " toward the attracting particle with a constant velocity\"\"\"\n", |
76 | | - " distances = []\n", |
77 | | - " na_neighbors = []\n", |
78 | | - " # only execute kernel for particles that are 'attractor'\n", |
79 | | - " if not particles.attractor:\n", |
80 | | - " return StateCode.Success\n", |
81 | | - " for n in neighbors:\n", |
82 | | - " if n.attractor:\n", |
83 | | - " continue\n", |
84 | | - " x_p = np.array([particle.depth, particle.lat, particle.lon])\n", |
85 | | - " x_n = np.array([n.depth, n.lat, n.lon])\n", |
86 | | - "\n", |
87 | | - " # compute distance between attracted and attracting particle\n", |
88 | | - " distances.append(np.linalg.norm(x_p - x_n))\n", |
89 | | - " na_neighbors.append(n)\n", |
90 | | - "\n", |
91 | | - " velocity = 0.04 # predefined attracting velocity\n", |
92 | | - " for n in na_neighbors:\n", |
93 | | - " assert n.dt == particle.dt\n", |
94 | | - " dx = np.array(\n", |
95 | | - " [particle.lat - n.lat, particle.lon - n.lon, particle.depth - n.depth]\n", |
96 | | - " )\n", |
97 | | - " dx_norm = np.linalg.norm(dx)\n", |
| 77 | + " interaction_distance = 0.5\n", |
| 78 | + " velocity = -0.04 # predefined attracting velocity\n", |
98 | 79 | "\n", |
99 | | - " # calculate vector of position change\n", |
100 | | - " distance = velocity * n.dt\n", |
101 | | - " d_vec = distance * dx / dx_norm\n", |
| 80 | + " lon_a = particles.lon[np.where(particles.attractor)[0]]\n", |
| 81 | + " dx = particles.lon - lon_a[:, None]\n", |
| 82 | + " lat_a = particles.lat[np.where(particles.attractor)[0]]\n", |
| 83 | + " dy = particles.lat - lat_a[:, None]\n", |
102 | 84 | "\n", |
103 | | - " # define mutation function for mutator\n", |
104 | | - " def f(n, dlat, dlon, ddepth):\n", |
105 | | - " n.lat_nextloop += (\n", |
106 | | - " dlat # note that we need to change the locations for the next loop\n", |
107 | | - " )\n", |
108 | | - " n.lon_nextloop += dlon\n", |
109 | | - " n.depth_nextloop += ddepth\n", |
| 85 | + " distances = np.sqrt(dx**2 + dy**2) # TODO use np.linalg.norm?\n", |
| 86 | + "\n", |
| 87 | + " dx = np.where(distances < interaction_distance, dx, 0.0)\n", |
| 88 | + " dy = np.where(distances < interaction_distance, dy, 0.0)\n", |
| 89 | + "\n", |
| 90 | + " dx_norm = np.where(distances > 0, dx / distances, 0)\n", |
| 91 | + " particles.dlon += (\n", |
| 92 | + " np.sum(dx_norm, axis=0) * velocity\n", |
| 93 | + " ) # * particles.dt / np.timedelta64(1, \"s\")\n", |
110 | 94 | "\n", |
111 | | - " # add mutation to the mutator\n", |
112 | | - " mutator[n.id].append((f, d_vec))" |
| 95 | + " dy_norm = np.where(distances > 0, dy / distances, 0)\n", |
| 96 | + " particles.dlat += (\n", |
| 97 | + " np.sum(dy_norm, axis=0) * velocity\n", |
| 98 | + " ) # * particles.dt / np.timedelta64(1, \"s\")" |
113 | 99 | ] |
114 | 100 | }, |
115 | 101 | { |
|
163 | 149 | "\n", |
164 | 150 | "kernels = [\n", |
165 | 151 | " parcels.kernels.DiffusionUniformKh,\n", |
166 | | - " # Pull, # Add the Pull kernel defined above\n", |
| 152 | + " Pull, # Add the Pull kernel defined above\n", |
167 | 153 | "]\n", |
168 | 154 | "\n", |
169 | 155 | "pset.execute(\n", |
|
0 commit comments