|
13 | 13 | "import matplotlib.pyplot as plt\n", |
14 | 14 | "import firedrake\n", |
15 | 15 | "from firedrake import inner, grad, dx, ds, exp, min_value, max_value, Constant, derivative\n", |
16 | | - "import irksome" |
| 16 | + "import irksome\n", |
| 17 | + "import icepack\n", |
| 18 | + "from icepack2 import model" |
17 | 19 | ] |
18 | 20 | }, |
19 | 21 | { |
|
86 | 88 | "B = Constant(4e3)\n", |
87 | 89 | "r_b = Constant(150e3 / (2 * π))\n", |
88 | 90 | "expr = B * exp(-inner(x, x) / r_b**2)\n", |
89 | | - "b = firedrake.interpolate(expr, S)" |
| 91 | + "b = firedrake.Function(S).interpolate(expr)" |
90 | 92 | ] |
91 | 93 | }, |
92 | 94 | { |
|
151 | 153 | "r_h = Constant(5e3)\n", |
152 | 154 | "H = Constant(100.0)\n", |
153 | 155 | "expr = H * firedrake.max_value(0, 1 - inner(x, x) / r_h**2)\n", |
154 | | - "h = firedrake.interpolate(expr, Q)\n", |
| 156 | + "h = firedrake.Function(Q).interpolate(expr)\n", |
155 | 157 | "h_0 = h.copy(deepcopy=True)" |
156 | 158 | ] |
157 | 159 | }, |
|
183 | 185 | "metadata": {}, |
184 | 186 | "outputs": [], |
185 | 187 | "source": [ |
186 | | - "s = firedrake.interpolate(b + h, Q)\n", |
187 | | - "a = firedrake.interpolate(smb(s), Q)" |
| 188 | + "s = firedrake.Function(Q).interpolate(b + h)\n", |
| 189 | + "a = firedrake.Function(Q).interpolate(smb(s))" |
188 | 190 | ] |
189 | 191 | }, |
190 | 192 | { |
|
215 | 217 | "metadata": {}, |
216 | 218 | "outputs": [], |
217 | 219 | "source": [ |
218 | | - "from icepack import rate_factor\n", |
219 | 220 | "from icepack2.constants import gravity as g, ice_density as ρ_I, glen_flow_law as n\n", |
220 | | - "\n", |
221 | | - "temp = Constant(273.15)\n", |
222 | | - "A = rate_factor(temp)" |
| 221 | + "A = icepack.rate_factor(Constant(273.15))" |
223 | 222 | ] |
224 | 223 | }, |
225 | 224 | { |
|
300 | 299 | "metadata": {}, |
301 | 300 | "outputs": [], |
302 | 301 | "source": [ |
303 | | - "from icepack2 import model, solvers\n", |
304 | 302 | "fns = [\n", |
305 | 303 | " model.viscous_power,\n", |
306 | 304 | " model.friction_power,\n", |
|
390 | 388 | "F = derivative(L, z)" |
391 | 389 | ] |
392 | 390 | }, |
| 391 | + { |
| 392 | + "cell_type": "markdown", |
| 393 | + "id": "9b8cdb6d-1b52-4e65-abd6-968b5eaf545a", |
| 394 | + "metadata": {}, |
| 395 | + "source": [ |
| 396 | + "For the solution procedure, we'll want to use a linearization of the problem where the thickness is clamped from below." |
| 397 | + ] |
| 398 | + }, |
| 399 | + { |
| 400 | + "cell_type": "code", |
| 401 | + "execution_count": null, |
| 402 | + "id": "46a2aff8-bee5-4d9d-8f16-b4424484bf14", |
| 403 | + "metadata": {}, |
| 404 | + "outputs": [], |
| 405 | + "source": [ |
| 406 | + "h_min = Constant(1e-3)\n", |
| 407 | + "\n", |
| 408 | + "rfields = {\n", |
| 409 | + " \"velocity\": u,\n", |
| 410 | + " \"membrane_stress\": M,\n", |
| 411 | + " \"basal_stress\": τ,\n", |
| 412 | + " \"thickness\": firedrake.max_value(h_min, h),\n", |
| 413 | + " \"surface\": s,\n", |
| 414 | + "}\n", |
| 415 | + "\n", |
| 416 | + "L_r = sum(fn(**rfields, **rheology) for fn in fns)\n", |
| 417 | + "F_r = firedrake.derivative(L_r, z)\n", |
| 418 | + "J_r = firedrake.derivative(F_r, z)" |
| 419 | + ] |
| 420 | + }, |
393 | 421 | { |
394 | 422 | "cell_type": "markdown", |
395 | 423 | "id": "468d2245-b155-4ead-8ca1-c37c474d128f", |
396 | 424 | "metadata": {}, |
397 | 425 | "source": [ |
398 | | - "Now we'll create a regularized second derivative of the Lagrangian.\n", |
399 | | - "Here we assume that all the exponents are equal to 1 and the thickness is bounded below." |
| 426 | + "We'll also want to add a term to the linearization assuming a linear viscous flow law." |
400 | 427 | ] |
401 | 428 | }, |
402 | 429 | { |
|
406 | 433 | "metadata": {}, |
407 | 434 | "outputs": [], |
408 | 435 | "source": [ |
409 | | - "h_min = Constant(2.0)\n", |
410 | | - "λ = Constant(1e-3)\n", |
411 | 436 | "v_c = firedrake.replace(u_c, {h: firedrake.max_value(h, h_min)})\n", |
412 | | - "regularized_rheology = {\n", |
| 437 | + "linear_rheology = {\n", |
413 | 438 | " \"flow_law_exponent\": 1,\n", |
414 | | - " \"flow_law_coefficient\": λ * ε_c / τ_c,\n", |
| 439 | + " \"flow_law_coefficient\": ε_c / τ_c,\n", |
415 | 440 | " \"sliding_exponent\": 1,\n", |
416 | | - " \"sliding_coefficient\": λ * v_c / τ_c,\n", |
| 441 | + " \"sliding_coefficient\": v_c / τ_c,\n", |
417 | 442 | "}\n", |
418 | 443 | "\n", |
419 | | - "regularized_fields = {\n", |
420 | | - " \"velocity\": u,\n", |
421 | | - " \"membrane_stress\": M,\n", |
422 | | - " \"basal_stress\": τ,\n", |
423 | | - " \"thickness\": firedrake.max_value(h, h_min),\n", |
424 | | - "}\n", |
425 | | - "\n", |
426 | | - "K = sum(\n", |
427 | | - " fn(**regularized_fields, **regularized_rheology)\n", |
428 | | - " for fn in [model.viscous_power, model.friction_power]\n", |
429 | | - ")\n", |
430 | | - "J = derivative(derivative(L + K, z), z)" |
| 444 | + "L_1 = sum(fn(**rfields, **linear_rheology) for fn in fns)\n", |
| 445 | + "F_1 = firedrake.derivative(L_1, z)\n", |
| 446 | + "J_1 = firedrake.derivative(F_1, z)" |
| 447 | + ] |
| 448 | + }, |
| 449 | + { |
| 450 | + "cell_type": "markdown", |
| 451 | + "id": "39fbac26-12e1-408a-8aab-6c32e321edd5", |
| 452 | + "metadata": {}, |
| 453 | + "source": [ |
| 454 | + "Finally, the linearization that we'll use for the nonlinear solver is a combination of the two (viscous and Glen)." |
| 455 | + ] |
| 456 | + }, |
| 457 | + { |
| 458 | + "cell_type": "code", |
| 459 | + "execution_count": null, |
| 460 | + "id": "3ad45f70-18a5-44f5-9d6f-2efd2a3c3e46", |
| 461 | + "metadata": {}, |
| 462 | + "outputs": [], |
| 463 | + "source": [ |
| 464 | + "λ = Constant(1e-3)\n", |
| 465 | + "J = J_r + λ * J_1" |
431 | 466 | ] |
432 | 467 | }, |
433 | 468 | { |
|
456 | 491 | "id": "35f45cb5-f7b2-40d7-aced-514de7a1f8dc", |
457 | 492 | "metadata": {}, |
458 | 493 | "source": [ |
459 | | - "The function `try_regularized_solve` will automatically choose a sensible value of how much to regularize $dF$ in order to make things go.\n", |
460 | 494 | "Now we can see our initial value of the velocity.\n", |
461 | 495 | "Note how it's a different magnitude but similar shape to the SIA velocity." |
462 | 496 | ] |
|
468 | 502 | "metadata": {}, |
469 | 503 | "outputs": [], |
470 | 504 | "source": [ |
471 | | - "momentum_solver = firedrake.NonlinearVariationalSolver(momentum_problem)\n", |
472 | | - "solvers.try_regularized_solve(momentum_solver, z, λ, verbose=True)" |
| 505 | + "sparams = {\n", |
| 506 | + " \"snes_type\": \"newtonls\",\n", |
| 507 | + " \"snes_max_it\": 200,\n", |
| 508 | + " \"snes_linesearch_type\": \"nleqerr\",\n", |
| 509 | + " \"ksp_type\": \"gmres\",\n", |
| 510 | + " \"pc_type\": \"lu\",\n", |
| 511 | + " \"pc_factor_mat_solver_type\": \"umfpack\",\n", |
| 512 | + "}\n", |
| 513 | + "momentum_solver = firedrake.NonlinearVariationalSolver(momentum_problem, solver_parameters=sparams)" |
| 514 | + ] |
| 515 | + }, |
| 516 | + { |
| 517 | + "cell_type": "code", |
| 518 | + "execution_count": null, |
| 519 | + "id": "e618ec87-b03f-44a8-8f0d-84b7ba2f58d9", |
| 520 | + "metadata": {}, |
| 521 | + "outputs": [], |
| 522 | + "source": [ |
| 523 | + "momentum_solver.solve()" |
473 | 524 | ] |
474 | 525 | }, |
475 | 526 | { |
|
568 | 619 | " s.interpolate(b + h)\n", |
569 | 620 | " a.interpolate(smb(s))\n", |
570 | 621 | "\n", |
571 | | - " solvers.try_regularized_solve(momentum_solver, z, λ)\n", |
| 622 | + " momentum_solver.solve()\n", |
572 | 623 | "\n", |
573 | 624 | " hs.append(h.copy(deepcopy=True))\n", |
574 | 625 | " us.append(z.subfunctions[0].copy(deepcopy=True))" |
|
594 | 645 | "axes.set_aspect(\"equal\")\n", |
595 | 646 | "axes.set_xlim((0, 10e3))\n", |
596 | 647 | "axes.set_ylim((0, 10e3))\n", |
597 | | - "colors = firedrake.tripcolor(h, num_sample_points=1, shading=\"flat\", axes=axes)\n", |
| 648 | + "colors = firedrake.tripcolor(hs[-1], num_sample_points=1, shading=\"flat\", axes=axes)\n", |
| 649 | + "firedrake.triplot(mesh, axes=axes)\n", |
| 650 | + "firedrake.tricontour(a, levels=[0, 1], colors=\"tab:orange\", axes=axes)\n", |
| 651 | + "fig.colorbar(colors);" |
| 652 | + ] |
| 653 | + }, |
| 654 | + { |
| 655 | + "cell_type": "code", |
| 656 | + "execution_count": null, |
| 657 | + "id": "f01a49bf-f4c5-41b4-b5fc-3d76deaa55fe", |
| 658 | + "metadata": {}, |
| 659 | + "outputs": [], |
| 660 | + "source": [ |
| 661 | + "u, M, τ = z.subfunctions\n", |
| 662 | + "\n", |
| 663 | + "fig, axes = plt.subplots()\n", |
| 664 | + "axes.set_aspect(\"equal\")\n", |
| 665 | + "axes.set_xlim((0, 10e3))\n", |
| 666 | + "axes.set_ylim((0, 10e3))\n", |
| 667 | + "colors = firedrake.tripcolor(u, num_sample_points=1, shading=\"flat\", axes=axes)\n", |
598 | 668 | "firedrake.triplot(mesh, axes=axes)\n", |
599 | 669 | "firedrake.tricontour(a, levels=[0, 1], colors=\"tab:orange\", axes=axes)\n", |
600 | 670 | "fig.colorbar(colors);" |
|
653 | 723 | "name": "python", |
654 | 724 | "nbconvert_exporter": "python", |
655 | 725 | "pygments_lexer": "ipython3", |
656 | | - "version": "3.11.5" |
| 726 | + "version": "3.11.9" |
657 | 727 | } |
658 | 728 | }, |
659 | 729 | "nbformat": 4, |
|
0 commit comments