|
257 | 257 | " )\n", |
258 | 258 | " sim_duration_i = time.time() - start_time\n", |
259 | 259 | " sim_duration[i] = sim_duration_i\n", |
260 | | - " print(f\"Simulation duration (dt = {int(dt / np.timedelta64(1, 's'))} s) = {np.round(sim_duration_i, 2)} seconds\")" |
| 260 | + " print(\n", |
| 261 | + " f\"Simulation duration (dt = {int(dt / np.timedelta64(1, 's'))} s) = {np.round(sim_duration_i, 2)} seconds\"\n", |
| 262 | + " )" |
261 | 263 | ] |
262 | 264 | }, |
263 | 265 | { |
|
494 | 496 | }, |
495 | 497 | { |
496 | 498 | "cell_type": "markdown", |
497 | | - "id": "23", |
| 499 | + "id": "22", |
498 | 500 | "metadata": {}, |
499 | 501 | "source": [ |
500 | 502 | "## Integration schemes\n", |
|
505 | 507 | { |
506 | 508 | "cell_type": "code", |
507 | 509 | "execution_count": null, |
508 | | - "id": "24", |
| 510 | + "id": "23", |
509 | 511 | "metadata": {}, |
510 | 512 | "outputs": [], |
511 | 513 | "source": [ |
|
518 | 520 | { |
519 | 521 | "cell_type": "code", |
520 | 522 | "execution_count": null, |
521 | | - "id": "25", |
| 523 | + "id": "24", |
522 | 524 | "metadata": {}, |
523 | 525 | "outputs": [], |
524 | 526 | "source": [ |
|
529 | 531 | { |
530 | 532 | "cell_type": "code", |
531 | 533 | "execution_count": null, |
532 | | - "id": "26", |
| 534 | + "id": "25", |
533 | 535 | "metadata": {}, |
534 | 536 | "outputs": [], |
535 | 537 | "source": [ |
|
539 | 541 | }, |
540 | 542 | { |
541 | 543 | "cell_type": "markdown", |
542 | | - "id": "27", |
| 544 | + "id": "26", |
543 | 545 | "metadata": {}, |
544 | 546 | "source": [ |
545 | 547 | "The higher-order methods use weighted intermediate steps in time and space to obtain a more accurate estimate of `dlat` and `dlon` for a given timestep.\n", |
|
550 | 552 | { |
551 | 553 | "cell_type": "code", |
552 | 554 | "execution_count": null, |
553 | | - "id": "28", |
| 555 | + "id": "27", |
554 | 556 | "metadata": {}, |
555 | 557 | "outputs": [], |
556 | 558 | "source": [ |
|
564 | 566 | { |
565 | 567 | "cell_type": "code", |
566 | 568 | "execution_count": null, |
567 | | - "id": "29", |
| 569 | + "id": "28", |
568 | 570 | "metadata": { |
569 | 571 | "tags": [ |
570 | 572 | "hide-output" |
|
608 | 610 | " )\n", |
609 | 611 | " sim_duration_ij = time.time() - start_time\n", |
610 | 612 | " sim_duration[i, j] = sim_duration_ij\n", |
611 | | - " print(f\"Simulation duration (dt = {int(dt / np.timedelta64(1, 's'))} s) = {np.round(sim_duration_ij, 2)} seconds\")" |
| 613 | + " print(\n", |
| 614 | + " f\"Simulation duration (dt = {int(dt / np.timedelta64(1, 's'))} s) = {np.round(sim_duration_ij, 2)} seconds\"\n", |
| 615 | + " )" |
612 | 616 | ] |
613 | 617 | }, |
614 | 618 | { |
615 | 619 | "cell_type": "code", |
616 | 620 | "execution_count": null, |
617 | | - "id": "30", |
| 621 | + "id": "29", |
618 | 622 | "metadata": {}, |
619 | 623 | "outputs": [], |
620 | 624 | "source": [ |
|
651 | 655 | }, |
652 | 656 | { |
653 | 657 | "cell_type": "markdown", |
654 | | - "id": "31", |
| 658 | + "id": "30", |
655 | 659 | "metadata": {}, |
656 | 660 | "source": [ |
657 | 661 | "Clearly, for longer timesteps, the RK2 and RK4 schemes perform better. However, if the timestep is appropriate, as we have determined in the previous section, then the Explicit Euler scheme does not perform notably different." |
|
660 | 664 | { |
661 | 665 | "cell_type": "code", |
662 | 666 | "execution_count": null, |
663 | | - "id": "32", |
| 667 | + "id": "31", |
664 | 668 | "metadata": {}, |
665 | 669 | "outputs": [], |
666 | 670 | "source": [ |
|
717 | 721 | }, |
718 | 722 | { |
719 | 723 | "cell_type": "markdown", |
720 | | - "id": "33", |
| 724 | + "id": "32", |
721 | 725 | "metadata": {}, |
722 | 726 | "source": [ |
723 | 727 | "By quantifying the precision of the integration methods, we can see that for a given timestep the Runge-Kutta methods perform orders of magnitude better than the Explicit Euler method. In this example, the error associated with the selected integration methods is smaller than that of the range of timesteps." |
|
726 | 730 | { |
727 | 731 | "cell_type": "code", |
728 | 732 | "execution_count": null, |
729 | | - "id": "34", |
| 733 | + "id": "33", |
730 | 734 | "metadata": {}, |
731 | 735 | "outputs": [], |
732 | 736 | "source": [ |
|
768 | 772 | }, |
769 | 773 | { |
770 | 774 | "cell_type": "markdown", |
771 | | - "id": "35", |
| 775 | + "id": "34", |
772 | 776 | "metadata": {}, |
773 | 777 | "source": [ |
774 | 778 | "In this last figure, we see that the improvement of RK2 by orders of magnitude with respect to EE comes at a small computational cost. Since the RK2 and RK4 methods are practically indistinguishable, using the RK2 method with a timestep of 1 hour or 20 minutes, depending on the application, would be an appropriate choice for this simulation." |
775 | 779 | ] |
776 | 780 | }, |
777 | 781 | { |
778 | 782 | "cell_type": "markdown", |
779 | | - "id": "36", |
| 783 | + "id": "35", |
780 | 784 | "metadata": {}, |
781 | 785 | "source": [ |
782 | 786 | "### Flow conditions\n", |
|
799 | 803 | }, |
800 | 804 | { |
801 | 805 | "cell_type": "markdown", |
802 | | - "id": "37", |
| 806 | + "id": "36", |
803 | 807 | "metadata": {}, |
804 | 808 | "source": [ |
805 | 809 | "## Summary\n", |
|
0 commit comments