{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", "from IPython.display import Image\n", "\n", "\n", "from tyssue import config, Sheet, SheetGeometry, History, EventManager\n", "from tyssue.draw import sheet_view\n", "from tyssue.generation import three_faces_sheet\n", "from tyssue.draw.plt_draw import plot_forces\n", "\n", "from tyssue.dynamics import PlanarModel\n", "\n", "from tyssue.solvers.viscous import EulerSolver\n", "from tyssue.draw.plt_draw import create_gif\n", "\n", "\n", "geom = SheetGeometry\n", "model = PlanarModel" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This notebooks demonstrates usage of the time dependant solver `EulerSolver` in the simplest case where we solve\n", "$$\\eta_i \\frac{d\\mathbf{r}_i}{dt} = \\mathbf{F}_i = - \\mathbf{\\nabla}_i E$$\n", "\n", "The model is defined in the same way it is defined for the quasistatic solver." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Simple forward Euler solver\n", "\n", "$$\\mathbf{r}_i(t+dt) = \\mathbf{r}_i(t) + \\frac{\\mathbf{F}_i(t)}{\\eta} dt$$\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sheet = Sheet('3', *three_faces_sheet())\n", "geom.update_all(sheet)\n", "sheet.settings['threshold_length'] = 1e-3\n", "\n", "sheet.update_specs(config.dynamics.quasistatic_plane_spec())\n", "sheet.face_df[\"prefered_area\"] = sheet.face_df[\"area\"].mean()\n", "history = History(sheet, extra_cols={\"edge\":[\"dx\", \"dy\"]})\n", "\n", "sheet.vert_df['viscosity'] = 1.0\n", "sheet.edge_df.loc[[0, 17], 'line_tension'] *= 4\n", "\n", "fig, ax = plot_forces(sheet, geom, model, ['x', 'y'], 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Solver instanciation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "solver = EulerSolver(\n", " sheet,\n", " geom,\n", " model,\n", " history=history,\n", " auto_reconnect=True)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The solver's `solve` method accepts a `on_topo_change` function as argument. This function is executed each time a topology change occurs. Here, we reste the line tension to its original value." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def on_topo_change(sheet):\n", " print(\"reseting tension\")\n", " sheet.edge_df[\"line_tension\"] = sheet.specs[\"edge\"][\"line_tension\"]\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Solving from $t = 0$ to $t = 8$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "res = solver.solve(tf=8, dt=0.05, on_topo_change=on_topo_change,\n", " topo_change_args=(solver.eptm,))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Showing the results" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "create_gif(solver.history, \"sheet3.gif\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Image(\"sheet3.gif\")\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.7.6" } }, "nbformat": 4, "nbformat_minor": 2 }