diff --git a/_sources/about/acknowledgement.md b/_sources/about/acknowledgement.md
new file mode 100644
index 0000000..84ee241
--- /dev/null
+++ b/_sources/about/acknowledgement.md
@@ -0,0 +1,14 @@
+Acknowledgement
+=======================
+
+## Contributors
+
+We welcome and recognize all contributions. You can see a list of current contributors in
+the [contributors
+tab](https://github.com/floriscalkoen/coastalcodebook/graphs/contributors).
+
+## Credits
+
+This project is created using the excellent open source [Jupyter Book
+project](https://jupyterbook.org/) and the [executablebooks/cookiecutter-jupyter-book
+template](https://github.com/executablebooks/cookiecutter-jupyter-book).
\ No newline at end of file
diff --git a/_sources/about/acknowledgements.md b/_sources/about/acknowledgements.md
new file mode 100644
index 0000000..81d3618
--- /dev/null
+++ b/_sources/about/acknowledgements.md
@@ -0,0 +1,14 @@
+Acknowledgements
+=======================
+
+## Contributors
+
+We welcome and recognize all contributions. You can see a list of current contributors in
+the [contributors
+tab](https://github.com/floriscalkoen/coastalcodebook/graphs/contributors).
+
+## Credits
+
+This project is created using the excellent open source [Jupyter Book
+project](https://jupyterbook.org/) and the [executablebooks/cookiecutter-jupyter-book
+template](https://github.com/executablebooks/cookiecutter-jupyter-book).
\ No newline at end of file
diff --git a/_sources/about/credits.md b/_sources/about/credits.md
new file mode 100644
index 0000000..7b1cd9d
--- /dev/null
+++ b/_sources/about/credits.md
@@ -0,0 +1,13 @@
+# Credits
+
+## Contributors
+
+We welcome and recognize all contributions. You can see a list of current contributors in
+the [contributors
+tab](https://github.com/floriscalkoen/coastalcodebook/graphs/contributors).
+
+## Credits
+
+This project is created using the excellent open source [Jupyter Book
+project](https://jupyterbook.org/) and the [executablebooks/cookiecutter-jupyter-book
+template](https://github.com/executablebooks/cookiecutter-jupyter-book).
\ No newline at end of file
diff --git a/_sources/about/introduction.md b/_sources/about/introduction.md
new file mode 100644
index 0000000..7a56469
--- /dev/null
+++ b/_sources/about/introduction.md
@@ -0,0 +1,5 @@
+Introduction
+=======================
+
+There are many ways to write content in Jupyter Book. This short section
+covers a few tips for how to do so.
diff --git a/_sources/about/structure.md b/_sources/about/structure.md
new file mode 100644
index 0000000..cad79d7
--- /dev/null
+++ b/_sources/about/structure.md
@@ -0,0 +1,6 @@
+Course structure
+=======================
+
+There are many ways to write content in Jupyter Book. This short section
+covers a few tips for how to do so.
+What happens now?
diff --git a/_sources/assignments/01_coastal_classification.ipynb b/_sources/assignments/01_coastal_classification.ipynb
index ddf76ed..50e2272 100644
--- a/_sources/assignments/01_coastal_classification.ipynb
+++ b/_sources/assignments/01_coastal_classification.ipynb
@@ -19,12 +19,7 @@
"source": [
"## Import libraries that we use for our analysis\n",
"\n",
- "In the two cells below we import the libraries that we need for the analysis. We also set\n",
- "some path settings to load the data and source code. For example, in the cell below we\n",
- "add the `src` directory to the system path, which allows us to import generic functions\n",
- "from `../../src/coastpy`. \n",
- "\n",
- "A little bit of extra text"
+ "In the two cells below we import the libraries that we need for the analysis. We also set some path settings to load the data and source code. For example, in the cell below we add the `src` directory to the system path, which allows us to import generic functions from `../../src/coastpy`. "
]
},
{
@@ -43,8 +38,7 @@
"# make coastpy library importable by appending root to path\n",
"cwd = pathlib.Path().resolve()\n",
"proj_dir = cwd.parent.parent # this is the root of the CoastalCodeBook\n",
- "sys.path.append(str(proj_dir / \"src\"))\n",
- "\n"
+ "sys.path.append(str(proj_dir / \"src\"))"
]
},
{
diff --git a/_sources/assignments/1_coastal_classification.ipynb b/_sources/assignments/1_coastal_classification.ipynb
new file mode 100644
index 0000000..507f0ba
--- /dev/null
+++ b/_sources/assignments/1_coastal_classification.ipynb
@@ -0,0 +1,774 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2b073407-5430-4071-b9f3-92aeabc484e9",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# %run initialize/1_coastal_classification.ipynb"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c5ee3b6d-9a37-4e12-be67-40d150c235c2",
+ "metadata": {},
+ "source": [
+ "# Characterization of Coastal Systems\n",
+ "\n",
+ "Welcome to the first notebook exercise of Coastal Systems (TU Delft, MSc Coastal Engineering)! This is the first year that we will experiment with notebooks in this course. With these notebooks we hope to provide you with interactive course material that helps you better understand the processes and concepts that we teach in this course. Please let us know how you find the notebooks - we appreciate your feedback!\n",
+ "\n",
+ "Chapter 2 of [Coastal Dynamics Open Textbook](https://textbooks.open.tudelft.nl/textbooks/catalog/view/37/92/383-1) describes the large geographical variation of coasts across the world. It explains how the coasts that we have today are shaped by both present-day processes and processes millions years ago. It distinguishes between three different order of features, which are associated to different orders of of time. In this notebook we will look at coastal systems at these different orders of scale. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "78c55ce4-8013-45c6-9ad4-8dfd4fa53890",
+ "metadata": {},
+ "source": [
+ "## Import libraries that we use for our analysis\n",
+ "\n",
+ "In the two cells below we import the libraries that we need for the analysis. We also set some path settings to load the data and source code. For example, in the cell below we add the `src` directory to the system path, which allows us to import generic functions from `../../src/coastpy`. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ee2ffe05-66ec-43f8-b7e6-2db9302dee83",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "import pathlib\n",
+ "import sys\n",
+ "\n",
+ "import colorcet as cc\n",
+ "import dask.dataframe as dd\n",
+ "import geopandas as gpd\n",
+ "import numpy as np\n",
+ "import panel as pn\n",
+ "import holoviews as hv\n",
+ "import hvplot.pandas # noqa: API import\n",
+ "from bokeh.models import PanTool, WheelZoomTool\n",
+ "\n",
+ "print(\"Packages succesfully loaded\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "d5e278d9",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# THESE PACKAGES ARE NO LONGER USED\n",
+ "\n",
+ "# import os\n",
+ "\n",
+ "# import hvplot.xarray # noqa: API import\n",
+ "# import ipyleaflet\n",
+ "# import pandas as pd\n",
+ "# import matplotlib.pyplot as plt\n",
+ "# import matplotlib.animation as animation\n",
+ "# from geoviews import tile_sources as gvts\n",
+ "# from ipyleaflet import Map, Marker, ScaleControl, basemaps\n",
+ "# import ipywidgets as widgets\n",
+ "# from ipywidgets import HTML, interact, fixed, interact_manual, interactive\n",
+ "# import IPython\n",
+ "# from IPython.display import HTML, display\n",
+ "# from random import shuffle, uniform\n",
+ "# from coastal_dynamics.geometries import geo_bbox\n",
+ "# from PIL import Image"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "6244aec6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Set project directory\n",
+ "cwd = pathlib.Path().resolve()\n",
+ "proj_dir = cwd.parent # this is the root of the CoastalCodeBook\n",
+ "sys.path.append(str(proj_dir / \"src\"))\n",
+ "\n",
+ "DATA_DIR = proj_dir / \"data\"\n",
+ "coastal_systems_fp = DATA_DIR / \"01_coastal_systems.gpkg\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bf5a59ac",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Set up the questions\n",
+ "import coastal_dynamics as cd\n",
+ "from coastal_dynamics.io import load_questions\n",
+ "\n",
+ "# Activate the Panel widget to make the visualizations.\n",
+ "pn.extension()\n",
+ "\n",
+ "QUESTION_DIR = pathlib.Path.cwd().parent / \"notebooks\" / \"questions\"\n",
+ "question_fp = QUESTION_DIR / \"1_coastal_classification.json\"\n",
+ "\n",
+ "questions = load_questions(question_fp)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0aba7093-28fd-44dc-97f6-a626f50f1b2e",
+ "metadata": {},
+ "source": [
+ "## Part 1: Tectonic classification"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5964cab0-7e98-47c6-b3b5-f03e563cfd5c",
+ "metadata": {},
+ "source": [
+ "In this notebook we will start with the broadest (or first order) features of the coast that cover large geographical distances (thousands of kilometres) and are linked to the long-term geological process of plate tectonics. We will do so by using earthquake data from the [USGS](https://earthquake.usgs.gov/earthquakes/search/). The dataset we load contains a sample (10\\%) of observed eartquakes between Jan 2000 and Dec 2018. Why earthquake data? Earthquake data reveals geologists the mysteries of the deep, but also for coastal researchers the data is insightful. Let's first load the data by running the next cells. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "afef8413-6aaf-417a-9151-96bec27d8ae6",
+ "metadata": {},
+ "source": [
+ "### Load the earthquake data\n",
+ "\n",
+ "We load the data (tabular data including geometries) and index the columns to only keep the data in memory that we actually need. In total the dataset contains 2.2 million earthquakes, but here we use a sample (10\\%), so the data contains approx. 220k eartquake entries. If you find that the interactive panel responds slow to how you adjust the widgets, please consider to take another sample. You can do so by uncommenting the sample line in the next cell. So if you set frac=0.1 you have a dataframe with approx. 22k unique earthquakes over the world. \n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4938443e-bf3c-4c14-b171-5b721b19b9c7",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "WEB_MERCATOR_LIMITS = (\n",
+ " -20037508.342789244,\n",
+ " 20037508.342789244,\n",
+ ") # max polar latitudes that can be handled in World Mercator\n",
+ "\n",
+ "df = (\n",
+ " dd.read_parquet(DATA_DIR / \"01_earthquakes_sample.parquet\")\n",
+ " .sample(\n",
+ " frac=0.1\n",
+ " ) # uncomment this line if loading the data takes too long on your computer\n",
+ " .set_index(\"time\")\n",
+ " .compute()\n",
+ " .tz_localize(None)\n",
+ " .sort_index()\n",
+ ")\n",
+ "\n",
+ "\n",
+ "# To save memory we drop most of the columns. Also we drop the polar latitudes that cannot be displayed in the web mercator projection.\n",
+ "df = df[[\"mag\", \"depth\", \"latitude\", \"longitude\", \"place\", \"type\"]][\n",
+ " df[\"northing\"] < WEB_MERCATOR_LIMITS[1]\n",
+ "]\n",
+ "# df.head()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "2fd26216-4946-495d-8b81-66c90dcf08f2",
+ "metadata": {},
+ "source": [
+ "### Visualization of the earthquake data\n",
+ "\n",
+ "To explore the data we use visualization tools from the [Holoviz project](https://holoviz.org/) that makes high-level tools to simplify visualization in Python. In the next cell we enable the interactive mode on the data dataframe, create widgets to explore the data and filter the dataframe accordingly. To explore the eartquake data we create an overlay of the eartquakes on a tileset of ESRI Imagery. Please note that the code in the next cell will only do the computations and store the result in an object called `panel`. To actually see the results you have to run one more cell; the one that calls this object panel. \n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7edf870f-1082-4b16-922f-e46fb7297d24",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "# title_bar = pn.pane.Markdown(\n",
+ "# \"##Exercise 1: Plate tectonics & first-order coastal features\",\n",
+ "# styles={\"color\": \"black\"},\n",
+ "# width=800,\n",
+ "# align='center'\n",
+ "# # margin=(10, 5, 10, 15),\n",
+ "# )\n",
+ "\n",
+ "# define widgets that can be used to index the data\n",
+ "magnitude_slider = pn.widgets.RangeSlider(\n",
+ " name=\"Earthquake magnitude [Richter]\", start=0.1, end=10\n",
+ ")\n",
+ "depth_slider = pn.widgets.RangeSlider(name=\"Earthquake depth [km]\", start=0.1, end=650)\n",
+ "date_slider = pn.widgets.DateRangeSlider(\n",
+ " name=\"Date\", start=df.index[0], end=df.index[-1]\n",
+ ")\n",
+ "column_types = pn.widgets.Select(options=[\"mag\", \"depth\"])\n",
+ "\n",
+ "\n",
+ "@pn.depends(\n",
+ " magnitude_slider.param.value_start,\n",
+ " magnitude_slider.param.value_end,\n",
+ " depth_slider.param.value_start,\n",
+ " depth_slider.param.value_end,\n",
+ " date_slider.param.value_start,\n",
+ " date_slider.param.value_end,\n",
+ " column_types.param.value,\n",
+ ")\n",
+ "def plot_earthquake_panel(\n",
+ " magnitude_start,\n",
+ " magnitude_end,\n",
+ " depth_start,\n",
+ " depth_end,\n",
+ " date_start,\n",
+ " date_end,\n",
+ " column_type,\n",
+ "):\n",
+ " panel = df[\n",
+ " (df.mag > magnitude_start)\n",
+ " & (df.mag < magnitude_end)\n",
+ " & (df.depth > depth_start)\n",
+ " & (df.depth < depth_end)\n",
+ " & (df.index >= date_start)\n",
+ " & (df.index <= date_end)\n",
+ " ]\n",
+ " # inverted fire colormap from colorcet\n",
+ " cmap = cc.CET_L4[::-1]\n",
+ " colorbar_labels = {\"mag\": \"Magnitude [Richter]\", \"depth\": \"Earthquake depth [km]\"}\n",
+ "\n",
+ " p = panel.hvplot.points(\n",
+ " x=\"longitude\",\n",
+ " y=\"latitude\",\n",
+ " geo=True,\n",
+ " color=column_type,\n",
+ " global_extent=True,\n",
+ " tiles=\"ESRI\",\n",
+ " # frame_width=900,\n",
+ " ylabel=\"Latitude [deg]\",\n",
+ " xlabel=\"Longitude [deg]\",\n",
+ " cmap=cmap,\n",
+ " tools=[\"tap\"],\n",
+ " hover_cols=[\"place\", \"time\"],\n",
+ " logz=True,\n",
+ " clim=(1, None),\n",
+ " clabel=colorbar_labels[column_type],\n",
+ " )\n",
+ "\n",
+ " p.opts(width=1000, height=500, tools=[\"wheel_zoom\"])\n",
+ "\n",
+ " return p\n",
+ "\n",
+ "\n",
+ "earthquake_panel = pn.Column(\n",
+ " # pn.Row(title_bar, align='center'),\n",
+ " pn.Row(column_types, align=\"center\"),\n",
+ " pn.Row(magnitude_slider, align=\"center\"),\n",
+ " pn.Row(depth_slider, align=\"center\"),\n",
+ " pn.Row(date_slider, align=\"center\"),\n",
+ " pn.Row(plot_earthquake_panel, align=\"center\"),\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ab73e969-86c6-4145-b408-93189c5df66f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# change value of 'plot_where' to:\n",
+ "# 'inline' if you would like the plot to show in the notebook\n",
+ "# 'pop-out' if you would like the plot to show in a new tab (i.e. seperate window)\n",
+ "\n",
+ "plot_where = \"pop-out\""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6677f6fa-4fae-4b9a-8a7a-457cda4e306e",
+ "metadata": {},
+ "source": [
+ "**If the visualization is too slow, please follow the instructions in loading the data for taking a sample.**\n",
+ "\n",
+ "After running the cell below you will have a panel with several widgets to index the eartquake data; by magnitude, depth and time, while the colors on the map show either the magintude or the depth of the earthquakes. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bae161ca-3551-42bb-b8bd-75d2a34392a3",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "def show_earthquake(plot_where):\n",
+ " if plot_where == \"inline\":\n",
+ " return earthquake_panel\n",
+ " elif plot_where == \"pop-out\":\n",
+ " earthquake_panel.show()\n",
+ " else:\n",
+ " print(\"please use either inline or pop-out for the plot_where variable\")\n",
+ "\n",
+ "\n",
+ "show_earthquake(plot_where);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "133e45b2-9b87-4f73-a97a-e79313bae052",
+ "metadata": {},
+ "source": [
+ "### Explore the earthquake data & questions\n",
+ "Using the earthquake plot, try to answer the questions below. In order to view the questions, run the code cell."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "1d8454ca-ab07-4b54-ab89-88f9b0c52fdc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "q1 = cd.QuestionFactory(questions[\"Q1-1\"]).serve()\n",
+ "q2 = cd.QuestionFactory(questions[\"Q1-2\"]).serve()\n",
+ "q3 = cd.QuestionFactory(questions[\"Q1-3\"]).serve()\n",
+ "q4 = cd.QuestionFactory(questions[\"Q1-4\"]).serve()\n",
+ "\n",
+ "\n",
+ "pn.Column(q1, q2, q3, q4)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9fcedf73-e886-4916-a886-9adf5a2515de",
+ "metadata": {},
+ "source": [
+ "Earthquake data support one of the most fundamental processes in the geology: plate tectonics. Although plate tectonics is a relatively slow process that acts on the geological time scale, it has had an enormous impact on the formation of coastlines and determines the broadest features of the coast."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "f937bf51-4f58-48c4-a6fa-a5fe64c70e73",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "q5 = cd.QuestionFactory(questions[\"Q1-5\"]).serve()\n",
+ "\n",
+ "pn.Column(q5)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "52f05014-d83f-4ea8-b742-39427682b695",
+ "metadata": {},
+ "source": [
+ "For the upcoming questions, consider the east Australian \"Gold Coast\"."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8d503057-e8df-4446-9b2c-3812ee988210",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "q6 = cd.QuestionFactory(questions[\"Q1-6\"]).serve()\n",
+ "q7 = cd.QuestionFactory(questions[\"Q1-7\"]).serve()\n",
+ "q8 = cd.QuestionFactory(questions[\"Q1-8\"]).serve()\n",
+ "q9 = cd.QuestionFactory(questions[\"Q1-9\"]).serve()\n",
+ "\n",
+ "pn.Column(q6, q7, q8, q9)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f60a5c37-420e-4507-a8f1-ccb6a6e159d7",
+ "metadata": {},
+ "source": [
+ "In 1971 Inman, D. L. & Nordstrom, C. E. used plate tectonics to classify the coast. They distinguish three main types of coasts: leading edge, trailing edge and marginal sea. In the questions below, match the correct characteristics to each class."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b9583771-20ce-41cd-841f-5970f68ba261",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "q10 = cd.QuestionFactory(questions[\"Q1-10\"]).serve()\n",
+ "q11 = cd.QuestionFactory(questions[\"Q1-11\"]).serve()\n",
+ "q12 = cd.QuestionFactory(questions[\"Q1-12\"]).serve()\n",
+ "\n",
+ "pn.Column(q10, q11, q12)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5ba87a25-7120-4658-b0cf-152365fb8100",
+ "metadata": {},
+ "source": [
+ "Now that we have looked at the typical characteristics of each coastal type, we will look at some examples. Each question below specifies a different location. Use the earthquake panel to zoom to the locations specified, and classify the coasts to the correct classes. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b58fe7fd-e7cf-4670-bc02-702efd6c4d80",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "q13 = cd.QuestionFactory(questions[\"Q1-13\"]).serve()\n",
+ "q14 = cd.QuestionFactory(questions[\"Q1-14\"]).serve()\n",
+ "q15 = cd.QuestionFactory(questions[\"Q1-15\"]).serve()\n",
+ "q16 = cd.QuestionFactory(questions[\"Q1-16\"]).serve()\n",
+ "\n",
+ "pn.Column(q13, q14, q15, q16)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3060d2bc-ce5a-468a-8219-d41a5b6c602f",
+ "metadata": {},
+ "source": [
+ "Inman, D. L. & Nordstrom (1971) further distinguish Afro-trailing-edge coasts and Amero-trailing-edge coasts based on differences in sediment supplies."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "0a428122-eb63-4bf2-b82c-d07de785e1db",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "q17 = cd.QuestionFactory(questions[\"Q1-17\"]).serve()\n",
+ "q18 = cd.QuestionFactory(questions[\"Q1-18\"]).serve()\n",
+ "q19 = cd.QuestionFactory(questions[\"Q1-19\"]).serve()\n",
+ "\n",
+ "pn.Column(q17, q18, q19)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a12d60a7-59dc-4a2f-b7a0-9cd1a3ed5bfa",
+ "metadata": {},
+ "source": [
+ "####################################################\n",
+ "\n",
+ "TO BE REMOVED\n",
+ "\n",
+ "1) How do the earthquake magnitude and earthquake depth relate to the coasts that we see? (Hint: See Figure 2.3 in the textbook and consider how deep under the ground the plates are moving. Extra hint: How do earthquake magnitude and depth differ for convergent and divergent plate boundaries?)\n",
+ "\n",
+ "2) Earthquake data support one of the most fundamental processes in the geology: plate tectonics. Although plate tectonics is a relatively slow process that acts on the [geological time scale](https://cdn.britannica.com/67/73167-050-B9A74092/chart.jpg), it has had an enormous impact on the formation of coastlines and determines the broadest features of the coast. What are two important inherited aspects of this process? (Hint: see Figure 2.10 and Sec. 2.3.3 in the textbook.) \n",
+ "\n",
+ "3) In 1971 Inman, D. L. & Nordstrom, C. E. used plate tectonics to classify the coast. Explain the classification that they introduced. What are the three different classes that they distinguish? How do they match with the earthquake data as you can explore in the panel? \n",
+ "\n",
+ "4) Can you identify or predict areas around the world where you will find the coasts that are distinguished by Inman, D. L. & Nordstrom, C. E.? For instance, what kind of coasts do you have in Chili? And how are they different to the east coast of the USA? And what is characteristic about the East China sea? \n",
+ "\n",
+ "5) Inman, D. L. & Nordstrom (1971) further distinguish Afro-trailing-edge coasts and Amero-trailing-edge coasts based on differences in sediment supplies. What is the main cause of these differences in sediment supply? And how do you expect the differences in sediment input to show in the coastal geomorphology?\n",
+ "####################################################"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bdf2a34d-2edd-43f4-a45b-793a3779ec74",
+ "metadata": {},
+ "source": [
+ "## Part 2: Process-based coastal classification\n",
+ "\n",
+ "In the section part of this notebook we will explore several coastal systems around the world considering the second and third order scale of features. In chapter two of the Coastal Dynamics open textbook it is explained how coastal systems can be classified according to the processes that characterize these systems. For example, one of the figures (below) shows how the relative influence of fluvial, wave and tidal processes influences the shape of coastal features. The idea of this exercise is that you identify the signatures of the processes that are introduced in chapter 2 in several coastal systems around the world. \n",
+ "\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5704aa4c-3b92-4618-8e45-b2daccf72c7b",
+ "metadata": {},
+ "source": [
+ "### The coastal systems data\n",
+ "\n",
+ "In the cell below we define a small plot function that generates a ESRI World Imagery basemap given a longitude, latitude, zoom level and name. Also, a small sheet of coastal systems around the world is loaded into `geopandas`, a Python library for geospatial tabular data. In the cells afterwards we sample this dataframe and show the coastal system on a map. Since the sample is random you might encounter the same coastal system multiple times; then you can just run the cell again to get another 'coastal draw'. \n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7bb4af63-03f7-4df1-8fd8-4c6a7930b95e",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "coastal_systems = gpd.read_file(coastal_systems_fp)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "e6732048-50e9-4f28-a553-f4221cccdb95",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "title_bar = pn.Row(\n",
+ " pn.pane.Markdown(\n",
+ " \"## Exercise 2: Coastal system characterization\",\n",
+ " styles={\"color\": \"black\"},\n",
+ " width=800,\n",
+ " sizing_mode=\"fixed\",\n",
+ " margin=(10, 5, 10, 15),\n",
+ " ),\n",
+ " pn.Spacer(),\n",
+ ")\n",
+ "\n",
+ "options = coastal_systems.name.to_list()\n",
+ "coastal_systems_slider = pn.widgets.Select(\n",
+ " name=\"Coastal system\", options=options, value=np.random.choice(options)\n",
+ ")\n",
+ "\n",
+ "\n",
+ "@pn.depends(coastal_systems_slider.param.value)\n",
+ "def plot_coastal_system(name):\n",
+ " system = coastal_systems.loc[coastal_systems[\"name\"] == name].copy()\n",
+ " west, south, east, north = system[\n",
+ " [\"west\", \"south\", \"east\", \"north\"]\n",
+ " ].values.flatten()\n",
+ "\n",
+ " p = system.hvplot.points(\n",
+ " x=\"lon\",\n",
+ " y=\"lat\",\n",
+ " geo=True,\n",
+ " color=\"red\",\n",
+ " alpha=0,\n",
+ " xlim=(west, east),\n",
+ " ylim=(south, north),\n",
+ " tiles=\"ESRI\",\n",
+ " frame_width=1100,\n",
+ " ylabel=\"Latitude [deg]\",\n",
+ " xlabel=\"Longitude [deg]\",\n",
+ " )\n",
+ "\n",
+ " p.opts(frame_width=1000, frame_height=500, tools=[\"pan\", \"wheel_zoom\"])\n",
+ "\n",
+ " return p\n",
+ "\n",
+ "\n",
+ "app = pn.Column(\n",
+ " # title_bar,\n",
+ " pn.Row(coastal_systems_slider, align=\"center\"),\n",
+ " pn.Row(plot_coastal_system, align=\"center\"),\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1dff7b26-b616-4add-91c5-1f1bfba2f6ce",
+ "metadata": {},
+ "source": [
+ "After running the cell below you will have a panel showing sattelite images of different coastal systems."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8465c61c-5ced-4498-8e7f-7b8f28a73be8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# change value of 'plot_where' to:\n",
+ "# 'inline' if you would like the plot to show in the notebook\n",
+ "# 'pop-out' if you would like the plot to show in a new tab (i.e. seperate window)\n",
+ "\n",
+ "plot_where = \"pop-out\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "0f18a18f-d7dc-4824-bf92-60a827370c38",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def show_coastal_system(plot_where):\n",
+ " if plot_where == \"inline\":\n",
+ " return app\n",
+ " elif plot_where == \"pop-out\":\n",
+ " app.show()\n",
+ " else:\n",
+ " print(\"please use either 'inline' or 'pop-out' for the 'plot_where' variable\")\n",
+ "\n",
+ "\n",
+ "show_coastal_system(plot_where);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bc77c2cd-0e7c-4733-aa20-20e8518010fa",
+ "metadata": {},
+ "source": [
+ "Using this panel, try to answer the questions below. The questions are seperated by 'theory' and 'application'."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "93daa1d8-3464-4537-b71b-692fdf548017",
+ "metadata": {},
+ "source": [
+ "### Questions 2a: theory\n",
+ "Running the cell below will generate theory questions. Use the sattelite images of different coastal systems to answer the questions."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7e325199-e3e8-49ba-950f-bf43634fdc9f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Questions 2a\n",
+ "q20 = cd.QuestionFactory(questions[\"Q1-20\"]).serve()\n",
+ "q21 = cd.QuestionFactory(questions[\"Q1-21\"]).serve()\n",
+ "q22 = cd.QuestionFactory(questions[\"Q1-22\"]).serve()\n",
+ "q23 = cd.QuestionFactory(questions[\"Q1-23\"]).serve()\n",
+ "q24 = cd.QuestionFactory(questions[\"Q1-24\"]).serve()\n",
+ "q25 = cd.QuestionFactory(questions[\"Q1-25\"]).serve()\n",
+ "q26 = cd.QuestionFactory(questions[\"Q1-26\"]).serve()\n",
+ "q27 = cd.QuestionFactory(questions[\"Q1-27\"]).serve()\n",
+ "q28 = cd.QuestionFactory(questions[\"Q1-28\"]).serve()\n",
+ "q29 = cd.QuestionFactory(questions[\"Q1-29\"]).serve()\n",
+ "q30 = cd.QuestionFactory(questions[\"Q1-30\"]).serve()\n",
+ "q31 = cd.QuestionFactory(questions[\"Q1-31\"]).serve()\n",
+ "q32 = cd.QuestionFactory(questions[\"Q1-32\"]).serve()\n",
+ "q33 = cd.QuestionFactory(questions[\"Q1-33\"]).serve()\n",
+ "\n",
+ "pn.Column(q20, q21, q22, q23, q24, q25, q26, q27, q28, q29, q30, q31, q32, q33)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "657487e3-8e41-48db-b061-96b43c9f7ec9",
+ "metadata": {},
+ "source": [
+ "### Questions 2b: application\n",
+ "Running the cell below will generate application questions. Use the sattelite images of different coastal systems to answer the questions."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8fc19be0-0dbc-4420-b6f1-f1adfdadc724",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Questions 2b\n",
+ "q34 = cd.QuestionFactory(questions[\"Q1-34\"]).serve()\n",
+ "q35 = cd.QuestionFactory(questions[\"Q1-35\"]).serve()\n",
+ "q36 = cd.QuestionFactory(questions[\"Q1-36\"]).serve()\n",
+ "q37 = cd.QuestionFactory(questions[\"Q1-37\"]).serve()\n",
+ "q38 = cd.QuestionFactory(questions[\"Q1-38\"]).serve()\n",
+ "q39 = cd.QuestionFactory(questions[\"Q1-39\"]).serve()\n",
+ "q40 = cd.QuestionFactory(questions[\"Q1-40\"]).serve()\n",
+ "q41 = cd.QuestionFactory(questions[\"Q1-41\"]).serve()\n",
+ "q42 = cd.QuestionFactory(questions[\"Q1-42\"]).serve()\n",
+ "q43 = cd.QuestionFactory(questions[\"Q1-43\"]).serve()\n",
+ "q44 = cd.QuestionFactory(questions[\"Q1-44\"]).serve()\n",
+ "q45 = cd.QuestionFactory(questions[\"Q1-45\"]).serve()\n",
+ "q46 = cd.QuestionFactory(questions[\"Q1-46\"]).serve()\n",
+ "q47 = cd.QuestionFactory(questions[\"Q1-47\"]).serve()\n",
+ "\n",
+ "pn.Column(q34, q35, q36, q37, q38, q39, q40, q41, q42, q43, q44, q45, q46, q47)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7d1e3fdb-e1e5-40f4-8ac8-6ae418ce809f",
+ "metadata": {},
+ "source": [
+ "This is the end of the notebook for week 1. We discussed tectonic and process-based classification of coastal systems. For further reading, see chapter 2 of the book. We hope you had fun!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a8171c69-ab76-47d0-8c9e-5aea130944d5",
+ "metadata": {},
+ "source": [
+ "############################################################################\n",
+ "\n",
+ "TO BE REMOVED\n",
+ "\n",
+ "### Explore the coastal systems\n",
+ "\n",
+ "While sampling over a range of coastal systems, try to answer the following questions. \n",
+ "\n",
+ "1. Find and compare a heavily engineered river-dominated delta and a more natural river-dominated delta\n",
+ "2. Compare the scale of the biggest and smallest tidal basin in the dataset\n",
+ "3. Find the estuarine and deltaic systems with a spit\n",
+ "4. Compare and contrast wave-dominated deltas with high and low sediment supply. How can you tell?\n",
+ "5. Find a tidal estuary with large fine (muddy) sediment supply, then find one with a large coarse (sandy) sediment supply. How can you tell the difference?\n",
+ "6. The eastern and western tips of the Dutch and German Wadden Islands are very different beach ridge environments. How might differences in sediment supply explain this? Where is the sediment coming from?\n",
+ "7. The Dune du Pilat in France is one of the world's largest coastal sand dunes (it is also one of the coolest and you should definitely visit if you get the chance!). Why is it located on the east side of Arcachon Inlet and not the west?\n",
+ "8. Look at the northern Jiangsu coast in China. What might explain the limited sediment supply in this location?\n",
+ "9. Find an estuary or tidal bay with extensive intertidal flats. Do you see salt marshes or mangrove forests nearby? Why or why not?\n",
+ "10. Find an inlet with jetties. How might this affect the way it evolves?\n",
+ "11. Find a delta/estuary/inlet whose shape is constrained by the presence of rocky coastal features. \n",
+ "12. The Albufeira Lagoon in Portugal opens and closes seasonally. In the image shown, is it open or closed? When and how might it open or close? \n",
+ "13. Find examples of heavily urbanized estuaries. How might these human interventions influence the natural processes there?\n",
+ "14. Based on these satellite images, which is the most beautiful site? Taking a moment to appreciate the beauty of these natural systems is an important part of your job as coastal engineers.\n",
+ "\n",
+ "############################################################################"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "eec0ac86-cc6f-4ddb-b1c0-545ff52f08c5",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ceb791dc-c60d-40b3-bdd7-5da642fe2bed",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.6"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/_sources/assignments/Chris/Initialize/Week_3_Initialize.ipynb b/_sources/assignments/Chris/Initialize/Week_3_Initialize.ipynb
deleted file mode 100644
index 8c1d3ca..0000000
--- a/_sources/assignments/Chris/Initialize/Week_3_Initialize.ipynb
+++ /dev/null
@@ -1,783 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import numpy as np\n",
- "import matplotlib.pyplot as plt\n",
- "import ipywidgets as widgets\n",
- "from IPython.display import display, HTML\n",
- "from ipywidgets import interact\n",
- "import matplotlib.animation as animation\n",
- "\n",
- "from matplotlib.ticker import MultipleLocator\n",
- "from matplotlib.animation import FuncAnimation\n",
- "\n",
- "from random import shuffle\n",
- "from random import uniform\n",
- "\n",
- "print('Packages succesfully loaded')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### General settings"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# change the width of the cells on screen \n",
- "from IPython.display import display, HTML\n",
- "display(HTML(\"\"))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "css_results = HTML(\"\"\"\"\"\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Basic functions"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def dispersion(k,h): # calculate omega\n",
- " return (9.81*k*np.tanh(k*h))**0.5"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def wave_length(T,h):\n",
- " L = 9.81*T**2/(2*np.pi)\n",
- " L_all = [L]\n",
- " \n",
- " for i in range(1500):\n",
- " L = 9.81*T**2/(2*np.pi)*np.tanh(2*np.pi*h/L)\n",
- " L_all.append(L)\n",
- " \n",
- " if np.abs(L_all[-1] - L_all[-2]) < 0.0005:\n",
- " break\n",
- " \n",
- " return round(L,13)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def general_text_widget(text):\n",
- " widget_text = widgets.Label(value= text)\n",
- " widget_text.layout.margin = '-10px 0 -10px 0'# remove distance above and below\n",
- " display(widget_text) "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def Numerical_question_body(Question, units, answer):\n",
- " \n",
- " # makes the widgets\n",
- " question_widget = widgets.Label(value= Question)\n",
- " unit_widget = widgets.Label(value= 'Answer:', layout=widgets.Layout(width='50px'))\n",
- " num_widget = widgets.FloatText(value=0, disabled=False, step = 0.01, layout=widgets.Layout(width='80px'))\n",
- " widget_unit = widgets.Label(value= units, layout=widgets.Layout(width='30px'))\n",
- " \n",
- " submit_button = widgets.Button(description='Check',)\n",
- " \n",
- " output_widget = widgets.Text(value= '', placeholder='', description='Feedback:', disabled=False, layout=widgets.Layout(width='500px'))\n",
- " #output_widget.add_class('Broad_widget')\n",
- " \n",
- " HBox1 = widgets.HBox([unit_widget, num_widget, widget_unit, output_widget])\n",
- " #HBox.layout.justify_content = 'flex-start' # dont adjust the layout on the window \n",
- "\n",
- " #place all the horizontal boxes in one vertical box, and display it.\n",
- " quiz_widget = widgets.VBox([question_widget] + [HBox1] + [submit_button])\n",
- " quiz_widget.layout.flex = 'none'\n",
- " \n",
- " display(quiz_widget)\n",
- " \n",
- " def check_answers(button, answer = answer):\n",
- " \n",
- " # get value from widget and check if this corresponds with the answer\n",
- " response = num_widget.value\n",
- "\n",
- " if response == answer: # if the answer is correct\n",
- " output_widget.value = str('Good job, this is correct')\n",
- " else: # the answer is wrong\n",
- " output_widget.value = str('Incorrect, the answer should be ' + str(answer) + str(units) + ', please try again.')\n",
- " \n",
- " submit_button.on_click(check_answers)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Q1"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def Q1():\n",
- " \n",
- " text_general = 'The wavelength can be determined in three different ways: an iterative approach, through tables (Appendix B, table B-3 of the book) and via an explicit formula.'\n",
- " \n",
- " T1 = round(uniform(5, 8), 1)\n",
- " h1 = round(uniform(0.5, 5), 1)\n",
- " \n",
- " text_general = 'The questions below asses the wave length in three different ways.'\n",
- " text_general2 = 'These are an iterative approach, through tables (Appendix B, table B-3 of the book), and via the formula of Fentom.'\n",
- " text_general3 = 'Can you asses the wave length for a wave with a period ($T$) of '+ str(T1) + ' seconds and a water depth ($h$) of ' + str(h1) + ' m?'\n",
- " \n",
- " Q1_text = 'Q1a) What is the deep water wave length?'\n",
- " Q1_unit = ' m'\n",
- " L = 9.81*T1**2/(2*np.pi)\n",
- " Answer1 = round( L ,2)\n",
- " \n",
- " Q2_text = 'Q1b) If you use the dispersion relation expressed in the wave length, what is the wave length in the first iteration?'\n",
- " Q2_unit = ' m'\n",
- " L = 9.81*T1**2/(2*np.pi)*np.tanh(2*np.pi*h1/L)\n",
- " Answer2 = round(L,2)\n",
- " \n",
- " Q3_text = 'Q1c) To what wave length does this iteration converge?'\n",
- " Q3_unit = ' m'\n",
- " Answer3 = round (wave_length(T1,h1) , 2)\n",
- " \n",
- " Q4_text = 'Q2a) Following table B-3 of the book, what is the ratio of h/L0? (Use 3 decimal numbers in this question)'\n",
- " Q4_unit = ''\n",
- " L0 = 9.81*T1**2/(2*np.pi)\n",
- " Answer4 = round(h1/L0, 3)\n",
- " \n",
- " Q5_text = 'Q2b) What is the ratio of h/L, you can linear interpolate. (Use 3 decimal numbers in this question)'\n",
- " Q5_unit = ''\n",
- " \n",
- " # data from table B-3, page 536, of the book CD1\n",
- " h_L0_serie = np.array([0,0.002,0.004,0.006,0.008,0.01,0.015,0.02,0.025,0.03,0.035,0.04,0.045,0.05,0.055,0.06,0.065,0.07,0.075,0.08,0.085,0.09,0.095,0.1,0.11,0.12,0.13,0.14,0.15,0.16,0.17,0.18,0.19,0.2,0.21,0.22,0.23,0.24,0.25,0.26,0.27,0.28,0.29,0.30,0.31,0.32,0.33,0.34,0.35,0.36,0.37,0.38,0.39,0.4,0.41,0.42,0.43,0.44,0.45,0.46,0.47,0.48,0.49,0.5,1])\n",
- " h_L_serie = np.array([0,0.0179,0.0253,0.0311,0.0360,0.0403,0.0496,0.0576,0.0648,0.0713,0.0775,0.0833,0.0888,0.0942,0.0993,0.104,0.109,0.114,0.119,0.123,0.128,0.132,0.137,0.141,0.150,0.158,0.167,0.175,0.183,0.192,0.2,0.208,0.217,0.225,0.234,0.242,0.251,0.259,0.268,0.277,0.285,0.294,0.303,0.312,0.321,0.330,0.339,0.349,0.358,0.367,0.377,0.386,0.395,0.405,0.415,0.424,0.434,0.433,0.453,0.463,0.472,0.482,0.492,0.502,1])\n",
- " \n",
- " # read the table\n",
- " id_lower = np.where(h_L0_serie <= h1/L0)[0][-1]# get the (last) id where the value is below h/L0\n",
- " h_L_lower = h_L_serie[id_lower] # use this id to get the new ratio H/L, the lower boundary\n",
- " h_L_upper = h_L_serie[id_lower+1] # the upper boundary\n",
- " \n",
- " # linear interpolate\n",
- " slope = (h_L_upper - h_L_lower)/(h_L0_serie[id_lower+1]- h_L0_serie[id_lower])\n",
- " h_L = h_L_lower + slope * (h1/L0- h_L0_serie[id_lower])\n",
- " \n",
- " #print(h1/L0, id_lower, h_L_lower, h_L_upper, h_L)\n",
- " Answer5 = round (h_L, 3)\n",
- " \n",
- " Q6_text = 'Q2c) While using the answer of the previous question, what is the wave length?'\n",
- " Q6_unit = ' m'\n",
- " Answer6 = round(h1/h_L,2)\n",
- " \n",
- " \n",
- " Q7_text = 'Q2d) What is the value tanh(kh), you can linear interpolate. (Use 3 decimal numbers in this question)'\n",
- " Q7_unit = ''\n",
- " \n",
- " # data from table B-3\n",
- " tanh_kh_serie = np.array([0,0.112,0.158,0.193,0.222,0.248,0.302,0.347,0.386,0.420,0.452,0.48,0.507,0.531,0.554,0.575,0.595,0.614,0.632,0.649,0.665,0.681,0.695,0.681,0.695,0.709,0.735,0.759,0.780,0.8,0.818,0.835,0.85,0.864,0.877,0.888,0.899,0.909,0.918,0.926,0.933,0.940,0.946,0.952,0.957,0.961,0.965,0.969,0.972,0.975,0.978,0.980,0.983,0.984,0.986,0.988,0.989,0.990,0.991,0.992,0.993,0.994,0.995,0.995,0.996,0.996,1])\n",
- " \n",
- " # read the table\n",
- " id_lower = np.where(h_L0_serie <= h1/L0)[0][-1]# get the (last) id where the value is below h/L0\n",
- " tanh_kh_lower = tanh_kh_serie[id_lower]\n",
- " tanh_kh_upper = tanh_kh_serie[id_lower+1]\n",
- " \n",
- " # linear interpolate\n",
- " slope = (tanh_kh_upper - tanh_kh_lower)/(h_L0_serie[id_lower+1]- h_L0_serie[id_lower])\n",
- " tanh_kh = tanh_kh_lower + slope * (h1/L0- h_L0_serie[id_lower])\n",
- " \n",
- " Answer7 = round(tanh_kh,3)\n",
- " \n",
- " Q8_text = 'Q3a) What is the wave number ($k$), following the explicit formula of Fentom?'\n",
- " Q8_unit = ''\n",
- " \n",
- " def waveNumber_Fenton(T,d): # made by J.A.ArriagaGarcia (Jaime)\n",
- " g=9.81\n",
- " omega = 2*np.pi/T\n",
- " k0 = omega*omega/g\n",
- " alpha = k0*d\n",
- " beta = alpha * (np.tanh(alpha))**-0.5 \n",
- " k = (alpha + beta**2 * np.cosh(beta)**-2) / (np.tanh(beta)+ beta*np.cosh(beta)**-2) / d\n",
- " return k\n",
- " \n",
- " k1 = waveNumber_Fenton(T = T1,d = h1) \n",
- " Answer8 = round(k1,2)\n",
- " \n",
- " Q9_text = 'Q3b) What is the wave length, following the explicit formula of Fentom?'\n",
- " Q9_unit = ' m'\n",
- " Answer9 = round(2*np.pi/k1,2)\n",
- " \n",
- " # organise the questions, units, and answers \n",
- " questions = [Q1_text, Q2_text, Q3_text,Q4_text, Q5_text, Q6_text, Q7_text, Q8_text, Q9_text]\n",
- " units = [Q1_unit, Q2_unit, Q3_unit, Q4_unit, Q5_unit, Q6_unit, Q7_unit, Q8_unit, Q9_unit]\n",
- " Answers = [Answer1, Answer2, Answer3, Answer4, Answer5, Answer6, Answer7, Answer8, Answer9]\n",
- " \n",
- " # make and display tekst widgets\n",
- " general_text_widget(text_general)\n",
- " general_text_widget(text_general2)\n",
- " general_text_widget(text_general3)\n",
- " \n",
- " # make and display the questions\n",
- " for Question, unit, answer in zip(questions,units,Answers):\n",
- " Numerical_question_body(Question, unit, answer)\n",
- " \n",
- "#Q1()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Q2"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def Q2():\n",
- " \n",
- " h = round(uniform(2, 4),1) # m , random value from 2 to 4 (excluding 4)\n",
- " L = round(uniform(25, 30),1) # m\n",
- " k = 2*np.pi/L\n",
- " omega = dispersion(k,h)\n",
- " \n",
- " Ans0 = T = round( 2*np.pi/omega ,2)\n",
- " Q0 = 'What is the wave period ($T$) for a wave with a length ($L$) of '+ str(L) + ' meter when the depth ($h$) is ' + str(h) + ' meters?'\n",
- " unit0 = 's'\n",
- " \n",
- " h = round(uniform(2, 4),1) # m\n",
- " L = round(uniform(20, 30),1) # m\n",
- " k = 2*np.pi/L\n",
- " omega = dispersion(k,h)\n",
- " T = 2*np.pi/omega\n",
- " \n",
- " Ans1 = c = round(L/T,2)\n",
- " Q1 = 'What is the wave celerity ($c$) for waves with a length ($L$) of '+ str(L) + ' meter when the depth ($h$) is ' + str(h) + ' meters?'\n",
- " unit1 = 'm/s'\n",
- " \n",
- " h = round(uniform(1, 2),1)\n",
- " L = round(uniform(20, 30),1) # m\n",
- " omega = dispersion(k,h = 1.5)\n",
- " T = 2*np.pi/omega\n",
- " \n",
- " Ans2 = c = round(L/T,2)\n",
- " Q2 = 'What is the wave celerity ($c$) for waves with a length ($L$) of '+ str(L) + ' meter when the depth ($h$) is '+ str(h) + ' meters?'\n",
- " unit2 = 'm/s'\n",
- " \n",
- " \n",
- " h = round(uniform(1, 2),1)\n",
- " T = round(uniform(5, 7),1)\n",
- " L = wave_length(T,h)\n",
- " Ans3 = round (L,2)\n",
- " Q3 = 'What is the wave length ($L$) for a wave with a period ($T$) of ' + str(T) + ' seconds when the depth ($h$) is '+ str(h) + ' meters?'\n",
- " unit3 = 'm'\n",
- " \n",
- " h = round(uniform(5, 7),1) # km\n",
- " L = 500000# m\n",
- " k = 2*np.pi/L\n",
- " omega = dispersion(k,h*1000) # m to km\n",
- " T = 2*np.pi/omega\n",
- " Ans4 = c = round(L/T /1000*3600,2)\n",
- " Q4 = 'What is the propagation speed ($c$) of a tsunami wave train with ($L$) of 500 km in the deep ocean with a depth ($h$) of ' + str(h) + ' km?'\n",
- " unit4 = 'km/h'\n",
- " \n",
- " h = round(uniform(5, 7),1) # km\n",
- " T = round(uniform(30,38), 0) # min\n",
- " L = wave_length(T*60,h)\n",
- " Ans5 = c = round(L/(T) /1000*60,2)\n",
- " Q5 = 'What is the propagation speed of a tsunami wave train with a period ($T$) of ' + str(T) + ' minutes in the deep ocean with a depth ($h$) of ' + str(h) + ' km?'\n",
- " unit5 = 'km/h'\n",
- " \n",
- " # organize the questions, units, and answers\n",
- " questions = [Q0, Q1, Q2, Q3, Q4, Q5]\n",
- " units = [unit0, unit1, unit2, unit3, unit4, unit5]\n",
- " answers = [Ans0, Ans1, Ans2, Ans3, Ans4, Ans5]\n",
- "\n",
- " # change the order randomly\n",
- " order = np.arange(0,len(questions),1)\n",
- " shuffle(order)\n",
- "\n",
- " # display the questions\n",
- " for i in np.array(order):\n",
- " Numerical_question_body(questions[i], units[i], answers[i])\n",
- " \n",
- "#Q2()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Q3"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def dispersion(k,h):\n",
- " return (9.81*k*np.tanh(k*h))**0.5\n",
- "\n",
- "def wave_celerity(L1, L2, L3):\n",
- " %matplotlib inline\n",
- " # bed profile\n",
- " x = np.arange(0,700+1,1) # cross-shore coordinate [m]\n",
- " slope = 1. / 30. # bed slope [-]\n",
- " d0 = 20. # offshore water depth [m]\n",
- " zbed = -(d0 - slope * x) # bed elevation [m]\n",
- " h = -zbed # still water depth [m]\n",
- " h[h < 0] = 0 # no negative depths\n",
- " \n",
- " # w is zero when h is 0, causes a divide by zero.\n",
- " x0_id = np.argwhere(h == 0)[0][0] # first location where water depth = 0\n",
- " h_water = h[0:x0_id]\n",
- " x_water = x[0:x0_id]\n",
- " \n",
- " #velocity profile\n",
- " c1 = L1/(2*np.pi / dispersion(k = 2*np.pi/L1,h=h_water)) # c = L/T, T = 2 pi / omega\n",
- " c2 = L2/(2*np.pi / dispersion(k = 2*np.pi/L2,h=h_water))\n",
- " c3 = L3/(2*np.pi / dispersion(k = 2*np.pi/L3,h=h_water))\n",
- "\n",
- " plt.figure(figsize=(9, 5))\n",
- " plt.plot(x, zbed, label = 'Bed', color = 'k')\n",
- " plt.plot([0,x[x0_id]], [0,0], color = 'gray', label = 'Still water surface')\n",
- " plt.xlabel('x [m]')\n",
- " plt.ylabel('y [m]')\n",
- " plt.title('cross-section')\n",
- " plt.xlim(0,np.max(x))\n",
- " plt.legend(loc = 'lower right')\n",
- "\n",
- " plt.figure(figsize=(10, 3))\n",
- " plt.title('Wave celerity for 3 waves')\n",
- " plt.plot(x_water, c1, label='wave 1')\n",
- " plt.plot(x_water, c2, label='wave 2')\n",
- " plt.plot(x_water, c3, label='wave 3')\n",
- " plt.legend()\n",
- " plt.xlabel('x-coordinate [m]')\n",
- " plt.ylabel('Celerity')\n",
- " plt.xlim(0,np.max(x));\n",
- "\n",
- "def Q3():\n",
- " # Create interactive widgets\n",
- " L1 = widgets.FloatSlider(value=5, min=0, max=50, step=0.01, description='L1 [m]')\n",
- " L2 = widgets.FloatSlider(value=10, min=0, max=50, step=0.01, description='L2 [m]')\n",
- " L3 = widgets.FloatSlider(value=30, min=0, max=50, step=0.01, description='L3 [m]')\n",
- "\n",
- " # Use the interactive function to update the plot\n",
- " Plot = interact(wave_celerity, L1=L1, L2=L2, L3=L3);\n",
- " display(Plot);\n",
- "\n",
- "#Q3()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Q4"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def Q4():\n",
- " \n",
- " h1 = uniform(0.5, 2)\n",
- " h2 = uniform(0.5, 3.5)\n",
- " h3 = uniform(0.5, 5)\n",
- " h4 = uniform(2, 5)\n",
- " h5 = uniform(0.3, 0.91)\n",
- " \n",
- " L1 = h1 / uniform(0.025, 0.05)# shallow water\n",
- " L2 = h2 / uniform(0.051, 0.49) # intermediate water\n",
- " L3 = h3 / uniform(0.5, 0.75) # deep water\n",
- " L4 = h4 / uniform(0.025, 0.075) # shallow or intermediate water\n",
- " L5 = h5 /uniform(0.25, 0.75) # intermediate water or deep water\n",
- " \n",
- " L_serie = [L1, L2, L3, L4, L5]\n",
- " h_serie = [h1, h2, h3, h4 , h5]\n",
- " \n",
- " Questions = []\n",
- " correct_answers_id = []\n",
- " \n",
- " for L,h in zip(L_serie, h_serie):\n",
- " L = round(L,2)\n",
- " h = round(h,2)\n",
- " Questions.append('L = ' + str(L) + ' m, h = ' + str(h) + ' m')\n",
- " \n",
- " ratio = h/L\n",
- " \n",
- " if ratio <= 0.05:\n",
- " correct_answers_id.append(0)\n",
- " if ratio > 0.05 and ratio < 0.5:\n",
- " correct_answers_id.append(1)\n",
- " if ratio >= 0.5:\n",
- " correct_answers_id.append(2)\n",
- " \n",
- " #print('For debuging, 0-based answers: ' + str(correct_answers_id))\n",
- " answers = ['Shallow', 'Intermediate', 'Deep']\n",
- " \n",
- " text_widget = widgets.Label(value= 'Select if the wave described on the right experiences shallow, intermediate, or deep water.')\n",
- " \n",
- " Hboxes =[]\n",
- " toggle_widgets = []\n",
- " for i in range(len(Questions)):\n",
- " question_widget = widgets.Label(value= Questions[i], layout=widgets.Layout(width='175px'))\n",
- " #question_widget.add_class('Small_widget')\n",
- " toggle_widget = widgets.ToggleButtons(options=answers, description='', disabled=False, button_style='') \n",
- " HBox1 = widgets.HBox([question_widget, toggle_widget])\n",
- " Hboxes.append(HBox1)\n",
- " toggle_widgets.append(toggle_widget) \n",
- " \n",
- " shuffle(Hboxes)\n",
- " \n",
- " submit_button = widgets.Button(description='Submit',)\n",
- " output_widget = widgets.Text(value= '', placeholder='', description='Verify:', disabled=False, layout=widgets.Layout(width='230px'))\n",
- " output_widget.add_class('Broad_widget')\n",
- " \n",
- " HBox_check = widgets.HBox([submit_button, output_widget])\n",
- "\n",
- " VBox = widgets.VBox([text_widget] + Hboxes + [HBox_check])\n",
- " VBox.layout.flex = 'none'\n",
- " display(VBox)\n",
- " \n",
- " def check_answers(button):\n",
- " score = 0\n",
- " \n",
- " for i in range(len(Questions)):\n",
- " if toggle_widgets[i].value == answers[ correct_answers_id[i]]:\n",
- " score += 1\n",
- " \n",
- " #print(toggle_widget.value)\n",
- " output_widget.value = 'Your score is ' + str(score) + '/5.'\n",
- " \n",
- " \n",
- " submit_button.on_click(check_answers)\n",
- " \n",
- "#Q4()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Q5"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def group_stats(k1,k2,w1,w2):\n",
- " Delta_k = np.abs(k2-k1)\n",
- " Delta_w = np.abs(w2-w1)\n",
- " L = 2*np.pi/Delta_k*2\n",
- " T = 2*np.pi/Delta_w*2\n",
- " cg = Delta_w/Delta_k\n",
- " return L,T, cg"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def harmonic_components():# manual set interval between frames in secondes\n",
- " %matplotlib notebook\n",
- " # manual set interval between frames in secondes\n",
- " delta_t = 0.1\n",
- "\n",
- " # Define parameters and widgets\n",
- " a1 = widgets.FloatSlider(value=1.1, min=0, max=20, step=0.01, description='a [m]');\n",
- " a2 = widgets.FloatSlider(value=1, min=0, max=20, step=0.01, description='a [m]');\n",
- "\n",
- " T1 = widgets.FloatSlider(value=5, min=0.01, max=25, step=0.01, description='T [s]')\n",
- " T2 = widgets.FloatSlider(value=5.3, min=0.01, max=25, step=0.01, description='T [s]')\n",
- "\n",
- " depth = widgets.FloatText(value=7.5, min=1, max=250, step=0.01, description='h [m]')\n",
- " n_waves = widgets.FloatSlider(value=3, min=0.1, max=10, step=0.1, description='$n_{waves}$')\n",
- " \n",
- " # Calculate initial values\n",
- " L1 = widgets.FloatText(value=wave_length(T1.value,depth.value), description='L [m]', disabled=True)\n",
- " L2 = widgets.FloatText(value=wave_length(T2.value,depth.value), description='L [m]', disabled=True)\n",
- " \n",
- " L_group, T_group, c_g = group_stats(k1 = 2*np.pi/L1.value,k2 = 2*np.pi/L2.value,w1 = 2*np.pi/T1.value,w2 = 2*np.pi/T2.value)\n",
- "\n",
- " # setup linear mesh (x) and duration before time (t) is reset\n",
- " x_max = L_group*n_waves.value\n",
- " x = np.linspace(0, x_max, 5000)\n",
- " t = np.arange(0,1000,delta_t)\n",
- " \n",
- " # Setup widget layout (User Interface) and display\n",
- " vbox1 = widgets.VBox([widgets.Label('Wave 1', layout=widgets.Layout(align_self='center')),a1, T1, L1])\n",
- " vbox2 = widgets.VBox([widgets.Label('Wave 2', layout=widgets.Layout(align_self='center')),a2, T2, L2])\n",
- " vbox3 = widgets.VBox([widgets.Label('General', layout=widgets.Layout(align_self='center')),depth, n_waves])\n",
- "\n",
- " ui = widgets.HBox([vbox1, vbox2, vbox3])\n",
- " display(ui)\n",
- " \n",
- " # Create figure, set structure and initial layout\n",
- " fig, axs = plt.subplots(figsize = (9,5), sharex=True) \n",
- " ax1 = plt.subplot(411) # axs[0] rather than ax1 could also be used\n",
- " ax2 = plt.subplot(412)\n",
- " ax3 = plt.subplot(413)\n",
- " ax4 = plt.subplot(414) \n",
- " plt.tight_layout()\n",
- " fig.subplots_adjust(hspace=0)\n",
- " fig.subplots_adjust(bottom=0.2)# Add some extra space for the axis at the bottom\n",
- " fig.subplots_adjust(left=0.1)# Add some space for the labels\n",
- " \n",
- " # set grid\n",
- " grid_x = MultipleLocator(base=25)\n",
- " grid_y = MultipleLocator(base=5)\n",
- " ax1.xaxis.set_minor_locator(grid_x)\n",
- " ax1.yaxis.set_minor_locator(grid_y)\n",
- " ax1.grid(which='both', linestyle='-', linewidth='0.5', color='gray', alpha=0.6)\n",
- " ax2.xaxis.set_minor_locator(grid_x)\n",
- " ax2.yaxis.set_minor_locator(grid_y)\n",
- " ax2.grid(which='both', linestyle='-', linewidth='0.5', color='gray', alpha=0.6)\n",
- " ax3.xaxis.set_minor_locator(grid_x)\n",
- " ax3.yaxis.set_minor_locator(grid_y)\n",
- " ax3.grid(which='both', linestyle='-', linewidth='0.5', color='gray', alpha=0.6)\n",
- " ax4.xaxis.set_minor_locator(grid_x)\n",
- " ax4.yaxis.set_minor_locator(grid_y)\n",
- " ax4.grid(which='both', linestyle='-', linewidth='0.5', color='gray', alpha=0.6)\n",
- " \n",
- " # change the axis when related parameters change\n",
- " def update_axis(change):\n",
- " L_group, T_group, c_g = group_stats(k1 = 2*np.pi/L1.value,k2 = 2*np.pi/L2.value,w1 = 2*np.pi/T1.value,w2 = 2*np.pi/T2.value)\n",
- " x_max = L_group * n_waves.value\n",
- " ax1.set_xlim(0, x_max)\n",
- " ax2.set_xlim(0, x_max)\n",
- " ax3.set_xlim(0, x_max)\n",
- " ax4.set_xlim(0, x_max)\n",
- " \n",
- " x = np.linspace(0, x_max, 5000)\n",
- " \n",
- " grid_x = MultipleLocator(base=x_max/100)\n",
- " ax1.xaxis.set_minor_locator(grid_x)\n",
- " ax2.xaxis.set_minor_locator(grid_x)\n",
- " ax3.xaxis.set_minor_locator(grid_x)\n",
- " ax4.xaxis.set_minor_locator(grid_x)\n",
- " \n",
- " ax1.grid(which='both', linestyle='-', linewidth='0.5', color='gray', alpha=0.6)\n",
- " ax2.grid(which='both', linestyle='-', linewidth='0.5', color='gray', alpha=0.6)\n",
- " ax3.grid(which='both', linestyle='-', linewidth='0.5', color='gray', alpha=0.6)\n",
- " ax4.grid(which='both', linestyle='-', linewidth='0.5', color='gray', alpha=0.6)\n",
- " \n",
- " \n",
- " n_waves.observe(update_axis)\n",
- " \n",
- " def update_y_axis(change):\n",
- " # adjust the boundaries of the plot\n",
- " amp = a1.value +a2.value\n",
- " ax1.set_ylim(-amp*1.1, amp*1.1)\n",
- " ax2.set_ylim(-amp*1.1, amp*1.1)\n",
- " ax3.set_ylim(-amp*1.1, amp*1.1)\n",
- " ax4.set_ylim(-amp*1.1, amp*1.1)\n",
- " \n",
- " a1.observe(update_y_axis)\n",
- " a2.observe(update_y_axis)\n",
- " \n",
- " # change the values of L, T of wave components and wave group parameters when T or depth changes \n",
- " def update_param(change):\n",
- " L1.value = wave_length(T1.value,h = depth.value)\n",
- " L2.value = wave_length(T2.value,h = depth.value)\n",
- " L_group, T_group, c_g = group_stats(k1 = 2*np.pi/L1.value,k2 = 2*np.pi/L2.value,w1 = 2*np.pi/T1.value,w2 = 2*np.pi/T2.value)\n",
- " \n",
- " update_axis(change)\n",
- " \n",
- " # debug\n",
- " #ax1.text(0.02, 0.8, L_group, transform=ax1.transAxes, fontsize=8, bbox={'facecolor': 'white'})\n",
- " #ax1.text(0.02, 0.50, T_group, transform=ax1.transAxes, fontsize=8, bbox={'facecolor': 'white'})\n",
- " #ax1.text(0.02, 0.2, c_g, transform=ax1.transAxes, fontsize=8, bbox={'facecolor': 'white'})\n",
- " \n",
- " T1.observe(update_param)\n",
- " T2.observe(update_param)\n",
- " depth.observe(update_param) \n",
- " \n",
- " \n",
- " # Initialize\n",
- " update_param('None')\n",
- " update_axis('None')\n",
- " update_y_axis('None')\n",
- " \n",
- " # set labels\n",
- " ax4.set_xlabel('x [m]')\n",
- " \n",
- " ax1.set_ylabel('$\\eta_1$')\n",
- " ax2.set_ylabel('$\\eta_2$')\n",
- " ax3.set_ylabel('$\\eta_1$ + $\\eta_2$')\n",
- " \n",
- " # remove ticks in upper graphs\n",
- " ax1.set_xticklabels([], fontsize=0)\n",
- " ax2.set_xticklabels([], fontsize=0)\n",
- " ax3.set_xticklabels([], fontsize=0)\n",
- " \n",
- " # Compute initial displacement\n",
- " eta = a1.value*np.sin(2*np.pi/L1.value*x) + a2.value*np.sin(2*np.pi/L2.value*x)\n",
- " eta1 = a1.value*np.sin(2*np.pi/L1.value*x)\n",
- " eta2 = a2.value*np.sin(2*np.pi/L2.value*x)\n",
- " \n",
- " k_bar = (2*np.pi/L1.value + 2*np.pi/L2.value)/2\n",
- " car_wave = (a1.value + a2.value)*np.sin(k_bar*x)\n",
- " \n",
- " k_dif = (2*np.pi/L1.value - 2*np.pi/L2.value)# Delta k\n",
- " var_amp = (a1.value + a2.value)*np.cos(-k_dif/2*x)\n",
- "\n",
- " # Plot initial wave\n",
- " line1, = ax1.plot(x, eta1, label = '$\\u03B7_1$ (wave 1)', linewidth= 0.5, color = '#0b5394')\n",
- " line2, = ax2.plot(x, eta2, label = '$\\u03B7_2$ (wave 2)', linewidth= 0.5, color = '#0b5394')#03396c\n",
- " line, = ax3.plot(x, eta, label = '$\\u03B7$ (wave 1+2)', color = 'k')\n",
- " line_carrier, = ax4.plot(x, car_wave, label = 'Carrier wave [m]', color = 'k')\n",
- " #line_var, = ax3.plot(x, var_amp, label = 'Variable amplitude', color = 'gray')\n",
- " line_var2, = ax4.plot(x, var_amp, label = 'Variable amplitude [-]', color = '#0b5394')\n",
- " \n",
- " # layout line\n",
- " line.set_linewidth(0.75)\n",
- " line_carrier.set_linewidth(0.75)\n",
- " line_var2.set_linewidth(0.75)\n",
- " \n",
- " # make legend of axis 4\n",
- " legend4 = ax4.legend(loc='lower right')\n",
- " for text in legend4.get_texts():\n",
- " text.set_fontsize(7) # Set individual legend item text size\n",
- " \n",
- " # update the graph each frame\n",
- " def update2(frame):\n",
- " x_max = L_group * n_waves.value\n",
- " x = np.linspace(0, x_max, 5000)\n",
- " \n",
- " # get current time\n",
- " t = delta_t * frame\n",
- "\n",
- " # calculate sea surface elevation\n",
- " eta = a1.value*np.sin(2*np.pi/T1.value*t-2*np.pi/L1.value*x) + a2.value*np.sin(2*np.pi/T2.value*t-2*np.pi/L2.value*x)\n",
- " eta1 = a1.value*np.sin(2*np.pi/T1.value*t-2*np.pi/L1.value*x)\n",
- " eta2 = a2.value*np.sin(2*np.pi/T2.value*t-2*np.pi/L2.value*x)\n",
- " \n",
- " omega_bar = (2*np.pi/T1.value + 2*np.pi/T2.value)/2\n",
- " k_bar = (2*np.pi/L1.value + 2*np.pi/L2.value)/2\n",
- " carrier = (a1.value + a2.value)*np.sin(omega_bar*t-k_bar*x)\n",
- " \n",
- " omega_dif = (2*np.pi/T1.value - 2*np.pi/T2.value)\n",
- " k_dif = (2*np.pi/L1.value - 2*np.pi/L2.value)\n",
- " var_amp = np.cos(omega_dif/2*t - k_dif/2*x)#(a1.value + a2.value)\n",
- "\n",
- " # adjust sea surface elevation (line) in plot\n",
- " line.set_ydata(eta)\n",
- " line_carrier.set_ydata(carrier)\n",
- " line_var2.set_ydata(var_amp)\n",
- " \n",
- " line.set_xdata(x)\n",
- " line_carrier.set_xdata(x)\n",
- " line_var2.set_xdata(x)\n",
- "\n",
- " # adjust line of wave component or set thinkness to 0 (not visible) if amplitude is zero\n",
- " if a1.value > 0:\n",
- " line1.set_xdata(x)\n",
- " line1.set_ydata(eta1)\n",
- " line1.set_linewidth(0.75)\n",
- " else:\n",
- " line1.set_linewidth(0)\n",
- "\n",
- " if a2.value > 0:\n",
- " line2.set_xdata(x)\n",
- " line2.set_ydata(eta2)\n",
- " line2.set_linewidth(0.75)\n",
- " else:\n",
- " line2.set_linewidth(0)\n",
- " \n",
- "\n",
- " # Create/call animation and show it\n",
- " anim = FuncAnimation(fig, update2, frames=len(t), interval=delta_t*1000)\n",
- " plt.show()\n",
- " \n",
- " return anim, a1,a2,T1,T2,L1,L2, depth # animation is required to prevent freezing of the picture, a1 is the widget, exporting a1.value will result in not updating the widget value\n",
- "\n",
- "def Q5():\n",
- " anim_5 = harmonic_components()\n",
- " return anim_5\n",
- "\n",
- "#anim_5 = Q5()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.11.4"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/_sources/assignments/Chris/Topic/Bounded_waves.ipynb b/_sources/assignments/Chris/Topic/Bounded_waves.ipynb
deleted file mode 100644
index 250f826..0000000
--- a/_sources/assignments/Chris/Topic/Bounded_waves.ipynb
+++ /dev/null
@@ -1,232 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "850a2a5e",
- "metadata": {},
- "outputs": [],
- "source": [
- "import numpy as np\n",
- "import matplotlib.pyplot as plt\n",
- "from matplotlib.animation import FuncAnimation\n",
- "import ipywidgets as widgets\n",
- "from ipywidgets import interact"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "5117cd50",
- "metadata": {},
- "source": [
- "https://ipywidgets.readthedocs.io/en/7.6.4/examples/Using%20Interact.html"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "a59e6f8f",
- "metadata": {},
- "outputs": [],
- "source": [
- "def wave_length(T,h):\n",
- " Dif = []\n",
- " L_serie = np.arange(0.1,1000,0.01) \n",
- " for L in L_serie:\n",
- " LHS = 2*np.pi/T\n",
- " RHS = 9.81*2*np.pi/L * np.tanh(2*np.pi/L * h)\n",
- " Dif.append(np.abs(LHS-RHS))\n",
- " if len(Dif) > 2 and Dif[-1] > Dif[-2]:\n",
- " break\n",
- " \n",
- " id_best = np.argmin(Dif)\n",
- " L= L_serie[id_best]\n",
- " #plt.plot(Dif)\n",
- " \n",
- " return round(L,13)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "54d7c37d",
- "metadata": {},
- "outputs": [],
- "source": [
- "def plot_phases():\n",
- " \n",
- " # define widgets\n",
- " a1 = widgets.FloatSlider(value=1, min=0, max=20, step=0.01, description='a [m]')\n",
- " a2 = widgets.FloatSlider(value=0.5, min=0, max=20, step=0.01, description='a [m]')\n",
- "\n",
- " T1 = widgets.FloatSlider(value=8, min=0.01, max=250000, step=0.01, description='T [s]')\n",
- " T2 = widgets.FloatSlider(value=4, min=0.01, max=250000, step=0.01, description='T [s]')\n",
- "\n",
- " phi_1 = widgets.FloatSlider(value=0, min=-1, max=1, step=0.01, description='$\\phi$ *2 $\\pi$ [rad]')\n",
- " phi_2 = widgets.FloatSlider(value=0.25, min=-1, max=1, step=0.01, description='$\\phi$ *2 $\\pi$ [rad]')\n",
- "\n",
- " # Setup widget layout (User Interface) and display\n",
- " vbox1 = widgets.VBox([widgets.Label('Wave 1', layout=widgets.Layout(align_self='center')),a1, T1, phi_1])\n",
- " vbox2 = widgets.VBox([widgets.Label('Wave 2', layout=widgets.Layout(align_self='center')),a2, T2, phi_2])\n",
- "\n",
- " ui = widgets.HBox([vbox1, vbox2])\n",
- "\n",
- " def calc_eta(a1,T1,phi_1,a2,T2,phi_2):\n",
- " t = np.arange(0,3*T1,0.1)\n",
- "\n",
- " fig, axs = plt.subplots(figsize = (9,5), sharex=True, sharey = True)\n",
- " fig.subplots_adjust(hspace=0)\n",
- " fig.subplots_adjust(wspace=0.04)\n",
- " \n",
- " # time based\n",
- " ax1 = plt.subplot(321)\n",
- " ax2 = plt.subplot(323)\n",
- " ax3 = plt.subplot(325)\n",
- " # space based\n",
- " ax4 = plt.subplot(322)\n",
- " ax5 = plt.subplot(324)\n",
- " ax6 = plt.subplot(326)\n",
- " \n",
- " # calculate surface \n",
- " eta1 = a1*np.cos(2*np.pi/T1*t-phi_1*(2*np.pi))\n",
- " eta2 = a2*np.cos(2*np.pi/T2*t-phi_2*(2*np.pi))\n",
- " eta = eta1+eta2\n",
- " \n",
- " eta_x1 = a1*np.cos(-2*np.pi/T1*t-phi_1*(2*np.pi))\n",
- " eta_x2 = a2*np.cos(-2*np.pi/T2*t-phi_2*(2*np.pi))\n",
- " eta_x = eta_x1 + eta_x2\n",
- "\n",
- " # calculate surface without phase change\n",
- " eta_1_basic = a1*np.cos(2*np.pi/T1*t)\n",
- " eta_2_basic = a2*np.cos(2*np.pi/T2*t)\n",
- " eta_basic = eta1\n",
- " \n",
- " eta_1x_basic = a1*np.cos(-2*np.pi/T1*t)\n",
- " eta_2x_basic = a2*np.cos(-2*np.pi/T2*t)\n",
- " eta_x_basic = eta_1x_basic + eta_2x_basic\n",
- " \n",
- " # plot surface excluding phase change\n",
- " ax1.plot(t,eta_1_basic, color = 'grey', linestyle = '--', label = 'reference')\n",
- " ax2.plot(t,eta_2_basic, color = 'grey', linestyle = '--', label = 'reference')\n",
- " ax3.plot(t, eta1, color = 'grey', linestyle = '--', label = '$\\eta_1$')\n",
- " ax4.plot(t, eta_1x_basic, color = 'grey', linestyle = '--', label = 'reference')\n",
- " ax5.plot(t, eta_2x_basic, color = 'grey', linestyle = '--', label = 'reference')\n",
- " ax6.plot(t, eta_x1, color = 'grey', linestyle = '--', label = '$\\eta_1$')\n",
- " \n",
- " # plot surface including phase change\n",
- " ax1.plot(t,eta1, label = '$\\eta_1$')\n",
- " ax2.plot(t,eta2, label = '$\\eta_2$' )\n",
- " ax3.plot(t,eta, label = '$\\eta_{1+2}$')\n",
- " \n",
- " ax4.plot(t,eta_x1, label = '$\\eta_1$')\n",
- " ax5.plot(t,eta_x2, label = '$\\eta_2$')\n",
- " ax6.plot(t,eta_x, label = '$\\eta_{1+2}$')\n",
- " \n",
- " # set vertical axis the same\n",
- " amp = (a1+a2)*1.1\n",
- " ax1.set_ylim(-amp,amp)\n",
- " ax2.set_ylim(-amp,amp)\n",
- " ax3.set_ylim(-amp,amp)\n",
- " ax4.set_ylim(-amp,amp)\n",
- " ax5.set_ylim(-amp,amp)\n",
- " ax6.set_ylim(-amp,amp)\n",
- " \n",
- " # set horizontal axis\n",
- " ax1.set_xlim(0,3*T1)\n",
- " ax2.set_xlim(0,3*T1)\n",
- " ax3.set_xlim(0,3*T1)\n",
- " ax4.set_xlim(0,3*T1)\n",
- " ax5.set_xlim(0,3*T1)\n",
- " ax6.set_xlim(0,3*T1)\n",
- " \n",
- " # set labels\n",
- " ax1.set_ylabel('$\\eta_1$ [m]')\n",
- " ax2.set_ylabel('$\\eta_2$ [m]')\n",
- " ax3.set_ylabel('$\\eta_{1+2}$ [m]')\n",
- " \n",
- " ax3.set_xlabel('t/T1 [s]')\n",
- " ax6.set_xlabel('x/L1 [m]')\n",
- " \n",
- " # set scaled ticks\n",
- " ax3.set_xticks([0, T1,T1*2, T1*3])\n",
- " ax3.set_xticklabels([0,1,2,3])\n",
- " \n",
- " ax6.set_xticks([0,T1,T1*2, T1*3])\n",
- " ax6.set_xticklabels([0,1,2,3])\n",
- " \n",
- " # plot legends \n",
- " legend1 = ax4.legend(loc='center left', bbox_to_anchor=(1.001, 0.5))\n",
- " legend2 = ax5.legend(loc='center left', bbox_to_anchor=(1.001, 0.5))\n",
- " legend3 = ax6.legend(loc='center left', bbox_to_anchor=(1.001, 0.5))\n",
- " \n",
- " # set title\n",
- " ax1.set_title('Time based')\n",
- " ax4.set_title('Space based')\n",
- " \n",
- " # remove x and y ticks\n",
- " ax4.set_xticklabels([], fontsize=0)\n",
- " ax5.set_xticklabels([], fontsize=0)\n",
- " \n",
- " ax4.set_yticklabels([], fontsize=0)\n",
- " ax5.set_yticklabels([], fontsize=0)\n",
- " ax6.set_yticklabels([], fontsize=0)\n",
- "\n",
- " # initialize graph\n",
- " #out = calc_eta(a1.value,T1.value,phi_1.value,a2.value,T2.value,phi_2.value)\n",
- " \n",
- " #update graph\n",
- " out = widgets.interactive_output(calc_eta, {'a1': a1,'T1':T1, 'phi_1': phi_1, 'a2': a2,'T2':T2, 'phi_2': phi_2})\n",
- " \n",
- "\n",
- " \n",
- " # display outcomes\n",
- " display(ui, out)\n",
- "\n",
- "plot_phases()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bf7ba0a7",
- "metadata": {},
- "outputs": [],
- "source": [
- "var = 9\n",
- "del(var)\n",
- "\n",
- "if 'var' not in locals():\n",
- " print('var exist')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "86c7dff0",
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.9.12"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/_sources/assignments/Chris/Week 3.ipynb b/_sources/assignments/Chris/Week 3.ipynb
deleted file mode 100644
index eb7909d..0000000
--- a/_sources/assignments/Chris/Week 3.ipynb
+++ /dev/null
@@ -1,255 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- "