|
40 | 40 | "metadata": {},
|
41 | 41 | "outputs": [],
|
42 | 42 | "source": [
|
43 |
| - "def tt_head(xs, ys, zs, xr, yr, zr, y1, v1, v2):\n", |
44 |
| - " theta = np.arcsin(v1/v2)\n", |
45 |
| - " l1 = (y1 - ys) / np.cos(theta)\n", |
46 |
| - " l2 = np.sqrt((xr-xs)**2 + (zr-zs)**2) - np.tan(theta) * (2 * y1 - ys - yr)\n", |
47 |
| - " l3 = (y1 - yr) / np.cos(theta)\n", |
48 |
| - " return ((l1 + l3) / v1 + l2 / v2)\n", |
49 |
| - "\n", |
50 |
| - "def tt_direct(xs, ys, zs, xr, yr, zr, v1):\n", |
51 |
| - " return (np.sqrt((xr-xs)**2 + (yr-ys)**2 + (zr-zs)**2) / v1)\n", |
52 |
| - "\n", |
53 | 43 | "def plot(solver, ix=None, iy=None, iz=None, attr='uu', rays=None, cbar_label='Travel-time [s]'):\n",
|
54 | 44 | " grid = pykonal.GridND(ndim=3)\n",
|
55 | 45 | " grid.min_coords = solver.pgrid.min_coords\n",
|
|
140 | 130 | " fig.tight_layout()"
|
141 | 131 | ]
|
142 | 132 | },
|
| 133 | + { |
| 134 | + "cell_type": "markdown", |
| 135 | + "metadata": {}, |
| 136 | + "source": [ |
| 137 | + "### Define function to instantiate EikonalSolver with uniform velocity model" |
| 138 | + ] |
| 139 | + }, |
| 140 | + { |
| 141 | + "cell_type": "code", |
| 142 | + "execution_count": null, |
| 143 | + "metadata": {}, |
| 144 | + "outputs": [], |
| 145 | + "source": [ |
| 146 | + "def init_solver():\n", |
| 147 | + " # Initialize the solver\n", |
| 148 | + " solver = pykonal.EikonalSolver()\n", |
| 149 | + "\n", |
| 150 | + " # Initialize the velocity grid with a uniform velocity model.\n", |
| 151 | + " # EikonalSolver.vgrid.min_coords specifies the minimum coordinates of the velocity grid\n", |
| 152 | + " solver.vgrid.min_coords = 0, 0, 0 # xmin, ymin, zmin\n", |
| 153 | + " # EikonalSolver.vgrid.node_intervals specifies the spacing between velocity grid nodes\n", |
| 154 | + " solver.vgrid.node_intervals = 1, 1, 1 # dx, dy, dz\n", |
| 155 | + " # EikonalSolver.vgrid.npts specifies the number of grid nodes along each axis\n", |
| 156 | + " solver.vgrid.npts = 11, 11, 11 # nx, ny, nz\n", |
| 157 | + " # EikonalSolver.vv holds the velocity at each grid node and should be a numpy.ndarray\n", |
| 158 | + " # with shape == EikonalSolver.vgrid.npts.\n", |
| 159 | + " solver.vv = np.ones(solver.vgrid.npts)\n", |
| 160 | + " return (solver)" |
| 161 | + ] |
| 162 | + }, |
143 | 163 | {
|
144 | 164 | "cell_type": "markdown",
|
145 | 165 | "metadata": {},
|
|
154 | 174 | "outputs": [],
|
155 | 175 | "source": [
|
156 | 176 | "# Initialize the solver\n",
|
157 |
| - "solver = pykonal.EikonalSolver()\n", |
158 |
| - "\n", |
159 |
| - "# Initialize the velocity grid with a uniform velocity model.\n", |
160 |
| - "# EikonalSolver.vgrid.min_coords specifies the minimum coordinates of the velocity grid\n", |
161 |
| - "solver.vgrid.min_coords = 0, 0, 0 # xmin, ymin, zmin\n", |
162 |
| - "# EikonalSolver.vgrid.node_intervals specifies the spacing between velocity grid nodes\n", |
163 |
| - "solver.vgrid.node_intervals = 1, 1, 1 # dx, dy, dz\n", |
164 |
| - "# EikonalSolver.vgrid.npts specifies the number of grid nodes along each axis\n", |
165 |
| - "solver.vgrid.npts = 11, 11, 11 # nx, ny, nz\n", |
166 |
| - "# EikonalSolver.vv holds the velocity at each grid node and should be a numpy.ndarray\n", |
167 |
| - "# with shape == EikonalSolver.vgrid.npts.\n", |
168 |
| - "solver.vv = np.ones(solver.vgrid.npts)\n", |
169 |
| - "\n", |
170 |
| - "# Initialize the propagation grid to coincide with velocity grid exactly.\n", |
171 |
| - "# Attributes of the propagation grid are analogous to those of the velocity grid.\n", |
172 |
| - "solver.pgrid.min_coords = solver.vgrid.min_coords\n", |
173 |
| - "solver.pgrid.node_intervals = solver.vgrid.node_intervals\n", |
174 |
| - "solver.pgrid.npts = solver.vgrid.npts\n", |
| 177 | + "solver = init_solver()\n", |
175 | 178 | "\n",
|
176 | 179 | "# Add a source in the center of the computational domain.\n",
|
177 |
| - "# Source locations need to be specified in physical coordinates.\n", |
178 |
| - "src = (5, 5, 5)\n", |
179 |
| - "solver.add_source(src)\n", |
| 180 | + "src_idx = (5, 5, 5) # The source location as an array index\n", |
| 181 | + "solver.uu[src_idx] = 0 # Set the traveltime at the source location to zero\n", |
| 182 | + "solver.is_far[src_idx] = False # Set the is_far flag to False for the source node\n", |
| 183 | + "solver.close.push(*src_idx) # Push the source index onto the close heap\n", |
180 | 184 | "\n",
|
181 | 185 | "# Solve the Eikonal equation.\n",
|
182 | 186 | "solver.solve()\n",
|
|
199 | 203 | "metadata": {},
|
200 | 204 | "outputs": [],
|
201 | 205 | "source": [
|
| 206 | + "# Initialize the solver\n", |
| 207 | + "solver = init_solver()\n", |
202 | 208 | "# Decrease the node interval by a factor of 2\n",
|
203 | 209 | "solver.pgrid.node_intervals = solver.vgrid.node_intervals / 2\n",
|
204 | 210 | "# And increase the number of points by a factor of 2, making sure to not go beyond the\n",
|
205 | 211 | "# boundaries of the velocity grid\n",
|
206 | 212 | "solver.pgrid.npts = solver.vgrid.npts * 2 - 1\n",
|
207 | 213 | "\n",
|
| 214 | + "\n", |
| 215 | + "# Add a source in the center of the computational domain.\n", |
| 216 | + "src_idx = (10, 10, 10) # The source location as an array index\n", |
| 217 | + "solver.uu[src_idx] = 0 # Set the traveltime at the source location to zero\n", |
| 218 | + "solver.is_far[src_idx] = False # Set the is_far flag to False for the source node\n", |
| 219 | + "solver.close.push(*src_idx) # Push the source index onto the close heap\n", |
| 220 | + "\n", |
208 | 221 | "# Solve the Eikonal equation again.\n",
|
209 | 222 | "solver.solve()\n",
|
210 | 223 | "\n",
|
|
226 | 239 | "metadata": {},
|
227 | 240 | "outputs": [],
|
228 | 241 | "source": [
|
| 242 | + "solver = init_solver()\n", |
229 | 243 | "solver.pgrid.node_intervals = solver.vgrid.node_intervals / 10\n",
|
230 | 244 | "solver.pgrid.npts = solver.vgrid.npts * 10 - 9\n",
|
| 245 | + "\n", |
| 246 | + "# Add a source in the center of the computational domain.\n", |
| 247 | + "src_idx = (50, 50, 50) # The source location as an array index\n", |
| 248 | + "solver.uu[src_idx] = 0 # Set the traveltime at the source location to zero\n", |
| 249 | + "solver.is_far[src_idx] = False # Set the is_far flag to False for the source node\n", |
| 250 | + "solver.close.push(*src_idx) # Push the source index onto the close heap\n", |
| 251 | + "\n", |
231 | 252 | "solver.solve()\n",
|
232 | 253 | "plot(solver)"
|
233 | 254 | ]
|
|
245 | 266 | "metadata": {},
|
246 | 267 | "outputs": [],
|
247 | 268 | "source": [
|
248 |
| - "solver.clear_sources()\n", |
249 |
| - "solver.add_source((0, 5, 10))\n", |
| 269 | + "solver = init_solver()\n", |
| 270 | + "solver.pgrid.node_intervals = solver.vgrid.node_intervals / 10\n", |
| 271 | + "solver.pgrid.npts = solver.vgrid.npts * 10 - 9\n", |
| 272 | + "\n", |
| 273 | + "src_idx = (25, 50, 75) # The source location as an array index\n", |
| 274 | + "solver.uu[src_idx] = 0 # Set the traveltime at the source location to zero\n", |
| 275 | + "solver.is_far[src_idx] = False # Set the is_far flag to False for the source node\n", |
| 276 | + "solver.close.push(*src_idx) # Push the source index onto the close heap\n", |
| 277 | + "\n", |
250 | 278 | "solver.solve()\n",
|
251 | 279 | "plot(solver)"
|
252 | 280 | ]
|
|
264 | 292 | "metadata": {},
|
265 | 293 | "outputs": [],
|
266 | 294 | "source": [
|
267 |
| - "solver.add_source((10, 5, 0))\n", |
| 295 | + "solver = init_solver()\n", |
| 296 | + "solver.pgrid.node_intervals = solver.vgrid.node_intervals / 10\n", |
| 297 | + "solver.pgrid.npts = solver.vgrid.npts * 10 - 9\n", |
| 298 | + "\n", |
| 299 | + "for src_idx in ((25, 50, 75), (75, 50, 25)):\n", |
| 300 | + " solver.uu[src_idx] = 0 # Set the traveltime at the source location to zero\n", |
| 301 | + " solver.is_far[src_idx] = False # Set the is_far flag to False for the source node\n", |
| 302 | + " solver.close.push(*src_idx) # Push the source index onto the close heap\n", |
| 303 | + "\n", |
268 | 304 | "solver.solve()\n",
|
269 | 305 | "plot(solver)"
|
270 | 306 | ]
|
|
282 | 318 | "metadata": {},
|
283 | 319 | "outputs": [],
|
284 | 320 | "source": [
|
285 |
| - "solver.add_source((5, 5, 5), t0=2.5)\n", |
| 321 | + "solver = init_solver()\n", |
| 322 | + "solver.pgrid.node_intervals = solver.vgrid.node_intervals / 10\n", |
| 323 | + "solver.pgrid.npts = solver.vgrid.npts * 10 - 9\n", |
| 324 | + "\n", |
| 325 | + "for src_idx, t0 in (((25, 50, 75), 0), ((75, 50, 25), 2.5)):\n", |
| 326 | + " solver.uu[src_idx] = t0 # Set the traveltime at the source location to t0\n", |
| 327 | + " solver.is_far[src_idx] = False # Set the is_far flag to False for the source node\n", |
| 328 | + " solver.close.push(*src_idx) # Push the source index onto the close heap\n", |
| 329 | + "\n", |
| 330 | + "solver.solve()\n", |
| 331 | + "plot(solver)\n", |
286 | 332 | "solver.solve()\n",
|
287 | 333 | "plot(solver)"
|
288 | 334 | ]
|
|
300 | 346 | "metadata": {},
|
301 | 347 | "outputs": [],
|
302 | 348 | "source": [
|
| 349 | + "solver = init_solver()\n", |
| 350 | + "\n", |
303 | 351 | "vy = np.linspace(1, 5, solver.vgrid.npts[1])\n",
|
304 | 352 | "for iy in range(len(vy)):\n",
|
305 | 353 | " solver.vv[:,iy] = vy[iy]\n",
|
306 | 354 | " \n",
|
307 |
| - "# This will plot the velocity model\n", |
308 |
| - "plot(solver, attr='vv_p', cbar_label='Velocity [km/s]')\n", |
309 |
| - "\n", |
310 |
| - "solver.clear_sources()\n", |
311 |
| - "solver.add_source((5, 5, 5))\n", |
312 |
| - "solver.solve()\n", |
313 |
| - "plot(solver)" |
314 |
| - ] |
315 |
| - }, |
316 |
| - { |
317 |
| - "cell_type": "code", |
318 |
| - "execution_count": null, |
319 |
| - "metadata": {}, |
320 |
| - "outputs": [], |
321 |
| - "source": [ |
322 |
| - "solver.vv[:, int(solver.vgrid.npts[1]//2):] = 5\n", |
| 355 | + "solver.pgrid.node_intervals = solver.vgrid.node_intervals / 10\n", |
| 356 | + "solver.pgrid.npts = solver.vgrid.npts * 10 - 9\n", |
323 | 357 | "\n",
|
324 |
| - "plot(solver, attr='vv_p', cbar_label='Velocity [km/s]')\n", |
| 358 | + "src_idx = (25, 50, 75)\n", |
| 359 | + "solver.uu[src_idx] = 0 # Set the traveltime at the source location to zero\n", |
| 360 | + "solver.is_far[src_idx] = False # Set the is_far flag to False for the source node\n", |
| 361 | + "solver.close.push(*src_idx) # Push the source index onto the close heap\n", |
325 | 362 | "\n",
|
326 |
| - "solver.clear_sources()\n", |
327 |
| - "solver.add_source((1, 3, 1))\n", |
328 | 363 | "solver.solve()\n",
|
| 364 | + "\n", |
| 365 | + "# This will plot the velocity model\n", |
| 366 | + "plot(solver, attr='vvp', cbar_label='Velocity [km/s]')\n", |
329 | 367 | "plot(solver)"
|
330 | 368 | ]
|
331 | 369 | },
|
|
343 | 381 | "outputs": [],
|
344 | 382 | "source": [
|
345 | 383 | "ray = solver.trace_ray((9.5, 0, 9.5))\n",
|
346 |
| - "plot(solver, rays=[ray])" |
| 384 | + "plot(solver,rays=[ray])" |
347 | 385 | ]
|
348 | 386 | },
|
349 | 387 | {
|
|
391 | 429 | }
|
392 | 430 | },
|
393 | 431 | "nbformat": 4,
|
394 |
| - "nbformat_minor": 2 |
| 432 | + "nbformat_minor": 4 |
395 | 433 | }
|
0 commit comments