phiflow 2 updates
This commit is contained in:
1 parent
03233b7d78
commit
e99b2a0b4a
10 files changed
+1012
-963
No files matched your search
@@ -6,8 +6,8 @@
|
||||
- file: overview.md
|
||||
sections:
|
||||
- file: overview-equations.md
|
||||
- file: overview-burgers-forw-v2.ipynb
|
||||
- file: overview-ns-forw-v2.ipynb
|
||||
- file: overview-burgers-forw.ipynb
|
||||
- file: overview-ns-forw.ipynb
|
||||
- file: supervised
|
||||
sections:
|
||||
- file: supervised-airfoils.ipynb
|
||||
@@ -26,8 +26,8 @@
|
||||
- file: diffphys-outlook.md
|
||||
- file: old-phiflow1.md
|
||||
sections:
|
||||
- file: overview-burgers-forw.ipynb
|
||||
- file: overview-ns-forw.ipynb
|
||||
- file: overview-burgers-forw-v1.ipynb
|
||||
- file: overview-ns-forw-v1.ipynb
|
||||
- file: diffphys-code-ns.ipynb
|
||||
- file: jupyter-book-reference
|
||||
sections:
|
||||
|
||||
@@ -8,7 +8,14 @@
|
||||
"source": [
|
||||
"# Differentiable Fluid Simulations\n",
|
||||
"\n",
|
||||
"** test version, rough... not newest one **\n",
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",
|
||||
"\n",
|
||||
"**test version, rough... not newest one**\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Next, we'll target a more complex example with the Navier-Stokes equations as model. We'll target a 2D case with velocity $\\mathbf{u}$, no explicit viscosity term, and a marker density $d$ that drives a simple Boussinesq buoyancy term $\\eta d$ adding a force along the y dimension:\n",
|
||||
"\n",
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Simple forward simulation of Burgers equation\n",
|
||||
"\n",
|
||||
"how to run ...\n",
|
||||
"simple model equation \n",
|
||||
"$\n",
|
||||
" \\frac{\\partial u}{\\partial{t}} + u \\nabla u =\n",
|
||||
" \\nu \\nabla\\cdot \\nabla u\n",
|
||||
"$ \n",
|
||||
"\n",
|
||||
"Note, the first command with a \"!\" prefix installs the [Φ<sub>Flow</sub> Python package from GitHub](https://github.com/tum-pbs/PhiFlow) via `pip` in your python environment. (Skip or modify this command if necessary.)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Note, the velocity array has a batch dimension, and 1 channel component in this 1D case: (1, 128, 1)\n",
|
||||
"\n",
|
||||
"Initial velocity state: [[1.2246469e-16]\n",
|
||||
" [4.9453720e-02]\n",
|
||||
" [9.8786421e-02]\n",
|
||||
" [1.4787737e-01]\n",
|
||||
" [1.9660644e-01]] ...\n",
|
||||
"\n",
|
||||
"Last velocity: [[0.00552158]\n",
|
||||
" [0.0165598 ]\n",
|
||||
" [0.02760994]\n",
|
||||
" [0.03866227]\n",
|
||||
" [0.04973169]\n",
|
||||
" [0.06080895]\n",
|
||||
" [0.07190682]\n",
|
||||
" [0.08301631]\n",
|
||||
" [0.09414805]\n",
|
||||
" [0.10529345]] ...\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/home/thuerey/anaconda3/envs/tf/lib/python3.8/_collections_abc.py:743: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
|
||||
" for key in self._mapping:\n",
|
||||
"/home/thuerey/anaconda3/envs/tf/lib/python3.8/_collections_abc.py:744: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
|
||||
" yield (key, self._mapping[key])\n",
|
||||
"/home/thuerey/phiflow/phi/viz/display.py:80: UserWarning: GUI is disabled because of missing dependencies: No module named 'imageio'. To install all dependencies, run $ pip install phiflow[gui]\n",
|
||||
" warnings.warn('GUI is disabled because of missing dependencies: %s. To install all dependencies, run $ pip install phiflow[gui]' % import_error)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!pip install --upgrade --quiet phiflow\n",
|
||||
"from phi.flow import *\n",
|
||||
"\n",
|
||||
"# run with phiflow\n",
|
||||
"n = 128\n",
|
||||
"steps = 32\n",
|
||||
"dt = 1./steps\n",
|
||||
"viscosity = 0.01/np.pi\n",
|
||||
"initial = np.asarray( [ [-math.sin(np.pi * x) * 1.] for x in np.linspace(-1,1,n)] )\n",
|
||||
"\n",
|
||||
"domain = Domain([n], boundaries=PERIODIC, box=box[-1:1])\n",
|
||||
"state = [BurgersVelocity(domain, velocity=initial, viscosity=viscosity)]\n",
|
||||
"\n",
|
||||
"print(\"Note, the velocity array has a batch dimension, and 1 channel component in this 1D case: \"+ format(state[0].velocity.data.shape) ) # -> (1, 128, 1)\n",
|
||||
"print(\"\\nInitial velocity state: \" + format(state[0].velocity.data[0][0:5]) +\" ...\" )\n",
|
||||
"\n",
|
||||
"for i in range(32):\n",
|
||||
"\n",
|
||||
" v = state[-1].velocity\n",
|
||||
" v = diffuse(v, dt * viscosity, substeps=1)\n",
|
||||
" v = advect.semi_lagrangian(v, v, dt)\n",
|
||||
" state.append( state[-1].copied_with(velocity=v, age=v.age + dt) )\n",
|
||||
"\n",
|
||||
" # here, we manually execute the different components of the PDE for clarity, \n",
|
||||
" # in phiflow we could simply use the step() method of the Burgers() class:\n",
|
||||
" #state.append( Burgers().step(state[-1], dt=dt) )\n",
|
||||
" \n",
|
||||
"print(\"\\nLast velocity: \" + format(state[-1].velocity.data[0][0:10]) +\" ...\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"So far so good, but not so easy to evaluate. Show in graph: blue is initial state, then times $10/32, 20/32, 1$ in green, cyan and purple:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[<matplotlib.lines.Line2D at 0x7f17fdeb2610>]"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 432x288 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# we only need \"velocity.data\" from each phiflow state\n",
|
||||
"vels = [x.velocity.data for x in state]\n",
|
||||
"\n",
|
||||
"# print(vels[0][0,:,0].shape)\n",
|
||||
"# print(vels[0].shape[1])\n",
|
||||
"\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"\n",
|
||||
"fig = plt.figure().gca()\n",
|
||||
"fig.plot(np.linspace(-1,1,len(vels[ 0].flatten())), vels[ 0].flatten(), lw=2, color='blue')\n",
|
||||
"fig.plot(np.linspace(-1,1,len(vels[10].flatten())), vels[10].flatten(), lw=2, color='green')\n",
|
||||
"fig.plot(np.linspace(-1,1,len(vels[20].flatten())), vels[20].flatten(), lw=2, color='cyan')\n",
|
||||
"fig.plot(np.linspace(-1,1,len(vels[32].flatten())), vels[32].flatten(), lw=2, color='purple')\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"And as image..."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Vels array shape: (1, 128, 33, 1)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 432x288 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def show_state(a):\n",
|
||||
" # we only have 33 time steps, blow up by a factor of 2^4 to make it easier to see\n",
|
||||
" # (could also be done with more evaluations of network)\n",
|
||||
" for i in range(4):\n",
|
||||
" a = np.concatenate( [a,a] , axis=3)\n",
|
||||
"\n",
|
||||
" a = np.reshape( a, [a.shape[1],a.shape[2]*a.shape[3]] )\n",
|
||||
" #print(\"resulting image size\" +format(a.shape))\n",
|
||||
" plt.imshow(a, origin='upper', cmap='magma')\n",
|
||||
" \n",
|
||||
"vels_img = np.asarray( np.concatenate(vels, axis=-1), dtype=np.float32 )\n",
|
||||
"vels_img = np.reshape(vels_img, list(vels_img.shape)+[1] ) ; print(\"Vels array shape: \"+format(vels_img.shape))\n",
|
||||
"\n",
|
||||
"# save for comparison with reconstructions later on\n",
|
||||
"np.savez_compressed(\"./temp/burgers-groundtruth-solution.npz\", np.reshape(vels_img,[n,steps+1])) # remove batch & channel dimension\n",
|
||||
"\n",
|
||||
"show_state(vels_img)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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.8.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
@@ -1,316 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Simple Forward Simulation of Burgers Equation with Φ<sub>Flow</sub>\n",
|
||||
"\n",
|
||||
"This chapter will give an introduction for how to run _forward_, i.e., regular simulations starting with a given initial state and approximating a later state numerically, with Φ<sub>Flow</sub>.\n",
|
||||
"\n",
|
||||
"Burgers equations is a very simple, yet non-linear and non-trivial, model equation, and hence a very good starting point for experiments. It contains an advection term (motion / transport) and a diffusion term (dissipation due to the second law of thermodynamics). Burgers equation can already lead to interesting shock formations, and is given by:\n",
|
||||
"$\n",
|
||||
" \\frac{\\partial u}{\\partial{t}} + u \\nabla u =\n",
|
||||
" \\nu \\nabla\\cdot \\nabla u\n",
|
||||
"$ \n",
|
||||
"\n",
|
||||
"Let's get some preliminaries out of the way: we'll import the Φ<sub>Flow</sub> library, and define our simulation domain with $n=128$ cells as discretization points for the 1D velocity $u$ in a periodic domain $\\Omega$ for the interval $[-1,1]$. We'll use 32 time `steps` for a time interval of 1, giving us `dt=1/32`. Additionally, we'll use a viscosity of $\\nu=0.01/\\pi$.\n",
|
||||
"\n",
|
||||
"We'll also define an initial state given by $-\\text{sin}(\\pi x)$ in the numpy array `initial`, which we'll use to initialize the velocity $u$ in the simulation in the next cell.\n",
|
||||
"\n",
|
||||
"**Note:** Below, the first command with a \"!\" prefix installs the [Φ<sub>Flow</sub> Python package from GitHub](https://github.com/tum-pbs/PhiFlow) via `pip` in your python environment. (You can skip or modify this command if necessary, depending on your system.)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Using phiflow version: 2.0.0\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/Users/thuerey/miniconda3/envs/tf/lib/python3.8/_collections_abc.py:743: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
|
||||
" for key in self._mapping:\n",
|
||||
"/Users/thuerey/miniconda3/envs/tf/lib/python3.8/_collections_abc.py:744: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
|
||||
" yield (key, self._mapping[key])\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"#!pip install --upgrade --quiet phiflow\n",
|
||||
"#!pip install --upgrade --quiet git+https://github.com/tum-pbs/PhiFlow@develop\n",
|
||||
"\n",
|
||||
"from phi.flow import *\n",
|
||||
"import phi\n",
|
||||
"print(\"Using phiflow version: {}\".format(phi.__version__))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Now that we've loaded phiflow, we can start defining some globals and constants. The `initial` array contains the aforementioned sine wave that we'll use to produce a nice shock in the center of our domain."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"n = 128\n",
|
||||
"steps = 32\n",
|
||||
"dt = 1./steps\n",
|
||||
"nu = 0.01/np.pi\n",
|
||||
"\n",
|
||||
"initial = np.asarray( [-np.sin(np.pi * x) * 1. for x in np.linspace(-1,1,n)] ) # 1D array\n",
|
||||
"#initial = np.asarray( [ [-np.sin(np.pi * x) * 1.] for x in np.linspace(-1,1,n)] ) # with additional component channel"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Next we can define the `domain` to contain $\\Omega$, as outlined above periodically for $[-1,1]$. We also initialize a 1D `velocity` from the `initial` array.\n",
|
||||
"\n",
|
||||
"Just to illustrate, we'll also print some info about the velocity object: it's a `phiflow.math` tensor with a size of 128. Note that the actual grid content is contained in the `values` of the grid. Below we're printing the first five entries via the conversion to a numpy array with `numpy()`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Velocity tensor shape: (x=128)\n",
|
||||
"Velocity tensor type: <class 'phi.math._tensors.NativeTensor'>\n",
|
||||
"Velocity tensor content: [1.2246469e-16 4.9453720e-02 9.8786421e-02 1.4787737e-01 1.9660644e-01]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"domain = Domain(x=n, boundaries=PERIODIC, bounds=Box[-1:1])\n",
|
||||
"velocity = domain.scalar_grid(initial)\n",
|
||||
"#velocity = domain.grid(Noise(vector=1))\n",
|
||||
"#dont use: velocity = domain.staggered_grid(initial) , velocity = domain.grid(initial) \n",
|
||||
"\n",
|
||||
"print(\"Velocity tensor shape: \" + format( velocity.shape )) # == velocity.values.shape\n",
|
||||
"print(\"Velocity tensor type: \" + format( type(velocity.values) ))\n",
|
||||
"print(\"Velocity tensor content: \" + format( velocity.values.numpy()[0:5] ))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Running the simulation\n",
|
||||
"\n",
|
||||
"Now we're ready to run the simulation itself. To compute the diffusion and advection components of our model equation we can simply call the existing `diffusion` and `semi_lagrangian` operators in phiflow:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"New velocity content at t=1.0: [0.00274862 0.01272991 0.02360343 0.03478042 0.0460869 ]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"velocities = [velocity]\n",
|
||||
"age = 0.\n",
|
||||
"for i in range(steps):\n",
|
||||
" v1 = field.diffuse(velocities[-1], nu, dt)\n",
|
||||
" v2 = advect.semi_lagrangian(v1, v1, dt)\n",
|
||||
" age += dt\n",
|
||||
" velocities.append(v2)\n",
|
||||
"\n",
|
||||
"print(\"New velocity content at t={}: {}\".format( age, velocities[-1].values.numpy()[0:5] ))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Here we're actually collecting all time steps in the list `vels`. This is not necessary in general (and could consume lots of memory for long-running sims), but useful here to plot the evolution of the velocity states later on.\n",
|
||||
"\n",
|
||||
"The print statements print a few of the velocity entries, and already shows that something is happening in our simulation, but it's difficult to get an intuition for the behavior of the PDE just from these numbers. Hence, let's visualize the states over time to show what is happening.\n",
|
||||
"\n",
|
||||
"## Visualization\n",
|
||||
"\n",
|
||||
"We can visualize this 1D case easily in a graph: the following code shows the initial state in blue, and then times $10/32, 20/32, 1$ in green, cyan and purple. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[<matplotlib.lines.Line2D at 0x7feeeee4bf10>]"
|
||||
]
|
||||
},
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 432x288 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# we only need \"velocity.data\" from each phiflow state\n",
|
||||
"#vels = [v.values.numpy('x') for v in velocities]\n",
|
||||
"vels = [v.values.numpy('x,vector') for v in velocities] # vel vx\n",
|
||||
"\n",
|
||||
"#import matplotlib.pyplot as plt\n",
|
||||
"import pylab as plt\n",
|
||||
"\n",
|
||||
"fig = plt.figure().gca()\n",
|
||||
"fig.plot(np.linspace(-1,1,len(vels[ 0].flatten())), vels[ 0].flatten(), lw=2, color='blue')\n",
|
||||
"fig.plot(np.linspace(-1,1,len(vels[10].flatten())), vels[10].flatten(), lw=2, color='green')\n",
|
||||
"fig.plot(np.linspace(-1,1,len(vels[20].flatten())), vels[20].flatten(), lw=2, color='cyan')\n",
|
||||
"fig.plot(np.linspace(-1,1,len(vels[32].flatten())), vels[32].flatten(), lw=2, color='purple')\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This nicely shows the shock developing in the center of our domain, which forms from the collision of the two initial velocity \"bumps\", the positive one on left (moving right) and the negative one right of the center (moving left).\n",
|
||||
"\n",
|
||||
"As these lines can overlap quite a bit we'll also use a different visualization in the following chapters that shows the evolution over the course of all time steps in a 2D image. Our 1D domain will be shown along the Y-axis, and each point along X will represent one time step.\n",
|
||||
"\n",
|
||||
"The code below converts our collection of velocity states into a 2D array, repeating individual time steps 8 times to make the image a bit wider. This purely optional, of course, but makes it easier to see what's happening in our Burgers simulation."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Vels array shape: (128, 33, 1)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ename": "TypeError",
|
||||
"evalue": "show() got an unexpected keyword argument 'size'",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
|
||||
"\u001b[0;32m<ipython-input-20-ec96ffb51ece>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 18\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msavez_compressed\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"./temp/burgers-groundtruth-solution.npz\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvels_img\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0msteps\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# remove batch & channel dimension\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 20\u001b[0;31m \u001b[0mshow_state\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvels_img\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
||||
"\u001b[0;32m<ipython-input-20-ec96ffb51ece>\u001b[0m in \u001b[0;36mshow_state\u001b[0;34m(a)\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0mim\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mimshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0morigin\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'upper'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcmap\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'magma'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolorbar\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mim\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#, ax=axes[i])\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 12\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0;31m#vels_img = np.asarray( np.stack(vels), dtype=np.float32 ).transpose() # no component channel\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
||||
"\u001b[0;32m~/miniconda3/envs/tf/lib/python3.8/site-packages/matplotlib/pyplot.py\u001b[0m in \u001b[0;36mshow\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 351\u001b[0m \"\"\"\n\u001b[1;32m 352\u001b[0m \u001b[0m_warn_if_gui_out_of_main_thread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 353\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0m_backend_mod\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 354\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 355\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
|
||||
"\u001b[0;31mTypeError\u001b[0m: show() got an unexpected keyword argument 'size'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXUAAADnCAYAAADhJMY0AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Il7ecAAAACXBIWXMAAAsTAAALEwEAmpwYAAAs40lEQVR4nO2df7AmZ1XnP6e73/fOZPJ7JsYYImCZLc0uZVimoltYq0CCQS2SqmUxuK7ghsq6Bau7ri5hqULNmqq4WyWyJbVFChFEJLC4rLNuNAYC6x8QzEQjgSgmRFgSA8lMksmPmbn37e6zf3TfyZvL7XP63n5/9ns+U2/Nffv0j6fvfd/vc/qc8zyPqCpBEARBP0jm3YAgCIJgcoSoB0EQ9IgQ9SAIgh4Roh4EQdAjQtSDIAh6RDbvBgRBEMyaH/mRy/To0WOt9r377r+9TVWvnHKTJkaIehAEK8fRo8f4/J+/t9W+WfqKA1NuzkQJUQ+CYPVQoCzn3YqpEKIeBMEKopDn827EVAhRD4Jg9VCgp6PpQ9SDIFhBNMIvQRAEvSJEPQiCoCdEojQIgqBPRPglCIKgP6giRVS/BEEQ9Ifw1IMgCHqCAmWUNAZBEPSEiKkHQRD0h6h+CYIg6BMKkSgNgiDoCRFTD4Ig6BMRUw+CIOgXIepBEAQ9QUFC1IMgCPqCxtS7QRAEvUGJRTKCIAj6g0b1SxAEQW+IwUdBEAQ9o6einsy7AUEQBLOnTpS2eTmIyJUi8mUReUBErt/G/i4Ruad+/a2IPDlmK8ZshyZxZ+GpB0GweiiQF51PIyIp8B7gCuAh4C4ROaSq9526lOq/H9v/3wIvHTvFCVW9tHNDxghPPQiCFaQeUdrmZXMZ8ICqPqiqG8AtwFXG/m8APjKhm9iWEPUgCFaPzURpd1G/EPj62PuH6m3fgoi8EHgxcMfY5j0iclhE7hSRq3d/Q88R4ZcgCFaT9iWNB0Tk8Nj7m1X15l1c8Rrg46o6Hvd5oao+LCLfBdwhIveq6ld2ce5ThKgHQbCCKGjr6pcjqnqwwfYwcNHY+xfU27bjGuAtz2uF6sP1/w+KyGeo4u2dRD3CL0EQrB6bU++2edncBVwsIi8WkSGVcH9LFYuIfA9wDvC5sW3niMha/fMB4OXAfVuP3SnhqQdBsHpMqPpFVXMReStwG5AC71fVL4nIDcBhVd0U+GuAW1SfVyP5vcB7RaSkcrBvGq+a2S0h6kEQrCCTm09dVW8Fbt2y7Z1b3v/KNsd9FnjJRBoxRoh6EASrScz9EgRB0BOUnSRKl4oQ9SAIVpCYpTEIgqBfhKgHQRD0hAlVvywiIepBEKweGuGXIAiCftHT+dRD1IMgWE1i4ekgCIKesDlNQA8JUQ+CYAXRSJQGQRD0hvDUgyAIekaIehAEQU+IksYgCIJ+oSHqQRAEPSJKGoMgCHqCAnkMPgqCIOgHEVMPgiDoGSHqQRAE/aGvidJk3g0IgiCYOZuDj9q8HETkShH5sog8ICLXb2N/k4g8JiL31K83j9neKCL31683TuLWwlMPgmA1mYCnLiIp8B7gCuAh4C4ROaSq923Z9aOq+tYtx54L/DJwkKqbubs+9okubQpPPQiC1UMVirLdy+Yy4AFVfVBVN4BbgKtatuJHgNtV9fFayG8Hrtz1PdWEqAdBsHJsrjvd5gUcEJHDY6/rxk51IfD1sfcP1du28s9E5Asi8nERuWiHx+6ICL8EQbB67GxCryOqerDD1f438BFVXReRfw18EHhlh/OZhKceBMFqMplE6cPARWPvX1BvO4WqHlXV9frt+4CXtT12N4SoB0Gwkuwg/GJxF3CxiLxYRIbANcCh8R1E5IKxt68F/rr++Tbg1SJyjoicA7y63taJCL8EQbB6KJB3r35R1VxE3kolxinwflX9kojcABxW1UPAz4nIa4EceBx4U33s4yLyn6k6BoAbVPXxrm0S7emkNkEQBE287IL9+rlrf6zVvms3fujujjH1mRKeehAEq0k/5/MKUQ+CYEXpaZAiRD0IgtVD+zv3S4h6EASrSYRfgiAIeoKC5vNuxHQIUQ+CYOXYnCagj4SoB0GweigRfgmCIOgTfR2iE6IeBMFKEuGXIAiCvhDhlyAIgn5RFvNuwXQIUQ+CYPVQoJR5t2IqhKgHQbBy9LmkcSrzqXurawdBEMwXQbXda9mYuKiPra79GuAS4A0icsmkrxMEQbBrdGKLZCwc0wi/nFpdG0BENlfXvm8K1wqCINgxCpTF8nnhbZiGqG+3Qvb3b92pXpH7OoA9yeBlF+3dP4WmBEHQN+5/9htHVPW8TidR0EiUThZVvRm4GeCSM87XDx+8xtgXSie2pdh2b5ZN7/xdrt3m+q2uM+X43ryfNLv8DWZFm791n1mE2WqvuPPXvzaJ88SI0vbseIXsLC05d9/xRntR2qH/orQTGm6HoGLu4/3xS/yESlfBctvQ4vxdBanrF3raoj1twZ23oC1E0s5pwrwdg50wqd+niFwJvJtqjdL3qepNW+y/ALyZao3Sx4B/papfq20FcG+96/9T1dd2bc80RP3U6tpUYn4N8JPWAWmqnHn2yUZ7MbJFPc8TU/RUxXzUKp0st/ek0CZLbgmC16ls7mOf3zveNFfn6CCKbb4g0+7YJnEN8/oT6DSm3TEswtPOsjzNTCL8MlYYcgVVqPkuETmkquM5xL8EDqrqcRH5N8B/AX6itp1Q1Us7N2SMiYt60+ra1jGSKXvOax7eVZ4szC90ueF46gXmQIOysEXfFfVSKJ0PSJdOpVUbOncKpnkiTyKTOYe7S/P5O4pNV89uEoLbNWQwC9FfBlFXnVj4xS0MUdVPj+1/J/BTE7lyA1OJqavqrcCtbfeXTBgcGDTayxP2eN7ypELZ/OBXjjCfC8sCNLdE28+Uq2HXUuwnidrudRwWXToVaN+xeOewj59vx1OdY/mfRszrz7njgsV4WvARiqJ1RfcBETk89v7mOicILQtDxrgW+OOx93vqc+fATar6v9o2qomFGFEqWUJy3t7tjaUiJ0bm8cnJAs2bvw3JqDRFXXM1V0HRQs3zU/rzSGguZs1rl06j1fFOx+IKsnM8tBDtCTyteHTtWLoeO4mOxz5/9yeiSVzDvn6nw2fDzjz1I6p6sOslReSngIPAD41tfqGqPiwi3wXcISL3qupXulxnIUSdLEHO2ddsP7FheuJyMkdzQzFHtuiTl7bdFXWl3Gg2A+jI/gSZ5wfKkSPqztJcrug7c2G0EvUOISzv+M1z2PbuTyudzj+jTqeLaHeN6c/maWUWIaKJXadVYYiIXA68A/ghVV0/1Q7Vh+v/HxSRzwAvBfog6imce+b2Ni2RtXX703jCsa+PEMu+UaCF0SnkJbphudmKOKLvivqGbU9yNUUjcURdneMpxV1d3X8aMGwtJlByRbdNx2Qdv+CdCixGx9Ll+m33sZhVldGERN0tDBGRlwLvBa5U1UfHtp8DHFfVdRE5ALycKonaicUQ9TSBs05vtg9OmJ46ewaI5amvb4Bh17xARoYqlopsGPGVUtGRY3c6BV1T89OshbohJAvNsc+vzvlLSK3jS0dQJtBpJE69nBei6izaLZ5WunYcyZTDN12fVtq0YRmSuZO6TlNhiIjcABxW1UPAfwVOB/6HiMBzpYvfC7xXREqqKVtu2lI1sysWQ9STFD3DEPUss8MvJ07aor8+gLxZdGUjh8IQ5bxENxzRX7fj/py0XWmxOgWoOgVLVPMWnYKVRMvVnufCmwej9J4E/PMnjuj7om1fw/ekTfNEnja6hLDaHD/tTqVqQ/cnEouZVOioTGyagO0KQ1T1nWM/X95w3GeBl0ykEWMsiKgn6L7mmLokdpZas9QUNBms26K9MXJEvaiEv4migKHxqyxL3249CQAMCvMbLbmXDLY7BUrsvIRie9qltHtasOyFq1hux2Ce3+14fNH3nja6dByT6DQSR/XbCO60Ow6PNh3LJFiOKp2dszCizt6G6hdAE/uXL4nYXupgAEWzosjGCEaGp50XMLDKY0o4aXvqsm5nUtU7fpjboux1CqPCEXWF3Og8S7XzEl6nQAvRdvMCnt0TXJwQkx2CqvZxzo/T8bXoeEz7AjxteB1Hl3PPsnJmIUboToEFEXWBtTXD7njqkpifZhmMTFHXwcgMz1AUyMn1ZruWMGius6csIbPvQdLUtOOEd3SQO568I+p5aYq2Fp6n73QKYOc9StDUUaTM/saLJ/olbt7Ay9LZnr4nqn6n4S6x1qHTec5u5VbEtrfpNCw6diiTQglPfaqoCDocNtolSeyYueeppxu2pz4YwsjwpPMCtURXSyR1ahoz4/hSK7slKFlq5xWcToON3PYCi9I+vxu+UTMZjSoYA7yAdp2CdYmBnVcQJ4QkjuiDl1doIXrO04rXr3lPE91F17t+R7va+0g6q9KX8NSniwikzU1xPfG8jeg3dxq6seGKrgwM0S4K1Gg/ZVmFiCzWHU/d6zRGI1t00xSxvk2OaGteVMJvINbTjif6pULmKILbKdiiXoWQms2VYBrHV+6d2QTr/FVOwPFUnacNMwSGH2ICP+G962Np12l07RgmxTJNPrYTFkPUPZIEa5GmzqKfpk6iNLc99aKwwydaVsncJkr1K3zS1P60b9ievOfpV6JuXL8oXFHW1HlasMpG8cIz6ruxbqdge/p4ou50CuDlFQSx+oxSEecb6Yu+c3zZsmPocH4TL9ntXH9SKOLO/rqsLIeoe3QUfcoSyY1vS5pWomsc74dnnOoXR3TdCp905Ii648nnhd2xlaUj6mUl/I12dZ6GSj+m3qVTAEhLO/yivqh7iVbJWjxNNF0fP9nsnd9LFleCbs9z1EW423QYnTuGCRHhl2miasa8kcRNlpo4oo+UqHV+T/RPXaP5eBUnXuzdn5csdjx52XBi9kVuJ4tLte1aglX2Ca7dHAAGkCV2XsD11AungscX9c6dgvGN69opAJB6ISTLine truncated
|
||||
"text/plain": [
|
||||
"<Figure size 432x288 with 2 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def show_state(a):\n",
|
||||
" # we only have 33 time steps, blow up by a factor of 2^4 to make it easier to see\n",
|
||||
" # (could also be done with more evaluations of network)\n",
|
||||
" for i in range(4):\n",
|
||||
" a = np.concatenate( [a,a] , axis=2)\n",
|
||||
"\n",
|
||||
" a = np.reshape( a, [a.shape[0],a.shape[1]*a.shape[2]] )\n",
|
||||
" #print(\"resulting image size\" +format(a.shape))\n",
|
||||
" im = plt.imshow(a, origin='upper', cmap='magma')\n",
|
||||
" plt.colorbar(im) #, ax=axes[i])\n",
|
||||
" #plt.show(size=(5, 5))\n",
|
||||
" \n",
|
||||
"#vels_img = np.asarray( np.stack(vels), dtype=np.float32 ).transpose() # no component channel\n",
|
||||
"vels_img = np.asarray( np.concatenate(vels, axis=-1), dtype=np.float32 ) # vel vx\n",
|
||||
"vels_img = np.reshape(vels_img, list(vels_img.shape)+[1] ) ; print(\"Vels array shape: \"+format(vels_img.shape))\n",
|
||||
"\n",
|
||||
"# save for comparison with reconstructions later on\n",
|
||||
"np.savez_compressed(\"./temp/burgers-groundtruth-solution.npz\", np.reshape(vels_img,[n,steps+1])) # remove batch & channel dimension\n",
|
||||
"\n",
|
||||
"show_state(vels_img)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Next steps\n",
|
||||
"\n",
|
||||
"Some things to try based on this simulation setup:\n",
|
||||
"\n",
|
||||
"- Feel free to experiment - the setup above is very simple, you can change the simulation parameters, or the initialization. E.g., you can use a noise field via `Noise(vector=1)` to get more chaotic results.\n",
|
||||
"- A bit more complicated: extend the simulation to 2D (or higher). This will require changes throughout, but all operators above support higher dimensions. Before trying this, you probably will want to check out the next example, which covers a 2D Navier-Stokes case."
|
||||
]
|
||||
},
|
||||
{
|
||||
"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.8.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
+152
-83
@@ -4,116 +4,168 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Simple forward simulation of Burgers equation\n",
|
||||
"# Simple Forward Simulation of Burgers Equation with Φ<sub>Flow</sub>\n",
|
||||
"\n",
|
||||
"how to run ...\n",
|
||||
"simple model equation \n",
|
||||
"This chapter will give an introduction for how to run _forward_, i.e., regular simulations starting with a given initial state and approximating a later state numerically, with Φ<sub>Flow</sub>.\n",
|
||||
"\n",
|
||||
"Burgers equations is a very simple, yet non-linear and non-trivial, model equation, and hence a very good starting point for experiments. It contains an advection term (motion / transport) and a diffusion term (dissipation due to the second law of thermodynamics). Burgers equation can already lead to interesting shock formations, and is given by:\n",
|
||||
"$\n",
|
||||
" \\frac{\\partial u}{\\partial{t}} + u \\nabla u =\n",
|
||||
" \\nu \\nabla\\cdot \\nabla u\n",
|
||||
"$ \n",
|
||||
"\n",
|
||||
"Note, the first command with a \"!\" prefix installs the [Φ<sub>Flow</sub> Python package from GitHub](https://github.com/tum-pbs/PhiFlow) via `pip` in your python environment. (Skip or modify this command if necessary.)"
|
||||
"Let's get some preliminaries out of the way: we'll import the Φ<sub>Flow</sub> library, and define our simulation domain with $n=128$ cells as discretization points for the 1D velocity $u$ in a periodic domain $\\Omega$ for the interval $[-1,1]$. We'll use 32 time `steps` for a time interval of 1, giving us `dt=1/32`. Additionally, we'll use a viscosity of $\\nu=0.01/\\pi$.\n",
|
||||
"\n",
|
||||
"We'll also define an initial state given by $-\\text{sin}(\\pi x)$ in the numpy array `initial`, which we'll use to initialize the velocity $u$ in the simulation in the next cell.\n",
|
||||
"\n",
|
||||
"**Note:** Below, the first command with a \"!\" prefix installs the [Φ<sub>Flow</sub> Python package from GitHub](https://github.com/tum-pbs/PhiFlow) via `pip` in your python environment. (You can skip or modify this command if necessary, depending on your system.)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Note, the velocity array has a batch dimension, and 1 channel component in this 1D case: (1, 128, 1)\n",
|
||||
"\n",
|
||||
"Initial velocity state: [[1.2246469e-16]\n",
|
||||
" [4.9453720e-02]\n",
|
||||
" [9.8786421e-02]\n",
|
||||
" [1.4787737e-01]\n",
|
||||
" [1.9660644e-01]] ...\n",
|
||||
"\n",
|
||||
"Last velocity: [[0.00552158]\n",
|
||||
" [0.0165598 ]\n",
|
||||
" [0.02760994]\n",
|
||||
" [0.03866227]\n",
|
||||
" [0.04973169]\n",
|
||||
" [0.06080895]\n",
|
||||
" [0.07190682]\n",
|
||||
" [0.08301631]\n",
|
||||
" [0.09414805]\n",
|
||||
" [0.10529345]] ...\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/home/thuerey/anaconda3/envs/tf/lib/python3.8/_collections_abc.py:743: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
|
||||
" for key in self._mapping:\n",
|
||||
"/home/thuerey/anaconda3/envs/tf/lib/python3.8/_collections_abc.py:744: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
|
||||
" yield (key, self._mapping[key])\n",
|
||||
"/home/thuerey/phiflow/phi/viz/display.py:80: UserWarning: GUI is disabled because of missing dependencies: No module named 'imageio'. To install all dependencies, run $ pip install phiflow[gui]\n",
|
||||
" warnings.warn('GUI is disabled because of missing dependencies: %s. To install all dependencies, run $ pip install phiflow[gui]' % import_error)\n"
|
||||
"Using phiflow version: 2.0.0\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!pip install --upgrade --quiet phiflow\n",
|
||||
"#!pip install --upgrade --quiet git+https://github.com/tum-pbs/PhiFlow@develop\n",
|
||||
"#!pip install --upgrade --quiet phiflow\n",
|
||||
"\n",
|
||||
"from phi.flow import *\n",
|
||||
"\n",
|
||||
"# run with phiflow\n",
|
||||
"n = 128\n",
|
||||
"steps = 32\n",
|
||||
"dt = 1./steps\n",
|
||||
"viscosity = 0.01/np.pi\n",
|
||||
"initial = np.asarray( [ [-math.sin(np.pi * x) * 1.] for x in np.linspace(-1,1,n)] )\n",
|
||||
"\n",
|
||||
"domain = Domain([n], boundaries=PERIODIC, box=box[-1:1])\n",
|
||||
"state = [BurgersVelocity(domain, velocity=initial, viscosity=viscosity)]\n",
|
||||
"\n",
|
||||
"print(\"Note, the velocity array has a batch dimension, and 1 channel component in this 1D case: \"+ format(state[0].velocity.data.shape) ) # -> (1, 128, 1)\n",
|
||||
"print(\"\\nInitial velocity state: \" + format(state[0].velocity.data[0][0:5]) +\" ...\" )\n",
|
||||
"\n",
|
||||
"for i in range(32):\n",
|
||||
"\n",
|
||||
" v = state[-1].velocity\n",
|
||||
" v = diffuse(v, dt * viscosity, substeps=1)\n",
|
||||
" v = advect.semi_lagrangian(v, v, dt)\n",
|
||||
" state.append( state[-1].copied_with(velocity=v, age=v.age + dt) )\n",
|
||||
"\n",
|
||||
" # here, we manually execute the different components of the PDE for clarity, \n",
|
||||
" # in phiflow we could simply use the step() method of the Burgers() class:\n",
|
||||
" #state.append( Burgers().step(state[-1], dt=dt) )\n",
|
||||
" \n",
|
||||
"print(\"\\nLast velocity: \" + format(state[-1].velocity.data[0][0:10]) +\" ...\")"
|
||||
"import phi\n",
|
||||
"print(\"Using phiflow version: {}\".format(phi.__version__))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"So far so good, but not so easy to evaluate. Show in graph: blue is initial state, then times $10/32, 20/32, 1$ in green, cyan and purple:"
|
||||
"Now that we've loaded phiflow, we can start defining some globals and constants. The `initial` array contains the aforementioned sine wave that we'll use to produce a nice shock in the center of our domain.\n",
|
||||
"\n",
|
||||
"First we'll initialize some constants (denote by upper-case names):"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"N = 128\n",
|
||||
"STEPS = 32\n",
|
||||
"DT = 1./STEPS\n",
|
||||
"NU = 0.01/np.pi\n",
|
||||
"\n",
|
||||
"# initialization of velocities\n",
|
||||
"INITIAL = np.asarray( [-np.sin(np.pi * x) * 1. for x in np.linspace(-1,1,N)] ) # 1D array"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Next we can define the `domain` to contain $\\Omega$, as outlined above periodically for $[-1,1]$. We also initialize a 1D `velocity` from the `initial` array.\n",
|
||||
"\n",
|
||||
"Just to illustrate, we'll also print some info about the velocity object: it's a `phiflow.math` tensor with a size of 128. Note that the actual grid content is contained in the `values` of the grid. Below we're printing the first five entries via the conversion to a numpy array with `numpy()`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Velocity tensor shape: (x=128)\n",
|
||||
"Velocity tensor type: <class 'phi.math._tensors.NativeTensor'>\n",
|
||||
"Velocity tensor content: [1.2246469e-16 4.9453720e-02 9.8786421e-02 1.4787737e-01 1.9660644e-01]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"DOMAIN = Domain(x=N, boundaries=PERIODIC, bounds=Box[-1:1])\n",
|
||||
"velocity = DOMAIN.scalar_grid(INITIAL)\n",
|
||||
"#velocity = DOMAIN.grid(Noise(vector=1)) # random init instead of sine curve\n",
|
||||
"\n",
|
||||
"print(\"Velocity tensor shape: \" + format( velocity.shape )) # == velocity.values.shape\n",
|
||||
"print(\"Velocity tensor type: \" + format( type(velocity.values) ))\n",
|
||||
"print(\"Velocity tensor content: \" + format( velocity.values.numpy()[0:5] ))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Running the simulation\n",
|
||||
"\n",
|
||||
"Now we're ready to run the simulation itself. To compute the diffusion and advection components of our model equation we can simply call the existing `diffusion` and `semi_lagrangian` operators in phiflow:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"New velocity content at t=1.0: [0.00274862 0.01272991 0.02360343 0.03478042 0.0460869 ]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"velocities = [velocity]\n",
|
||||
"age = 0.\n",
|
||||
"for i in range(STEPS):\n",
|
||||
" v1 = diffuse.explicit(velocities[-1], NU, DT)\n",
|
||||
" v2 = advect.semi_lagrangian(v1, v1, DT)\n",
|
||||
" age += DT\n",
|
||||
" velocities.append(v2)\n",
|
||||
"\n",
|
||||
"print(\"New velocity content at t={}: {}\".format( age, velocities[-1].values.numpy()[0:5] ))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Here we're actually collecting all time steps in the list `vels`. This is not necessary in general (and could consume lots of memory for long-running sims), but useful here to plot the evolution of the velocity states later on.\n",
|
||||
"\n",
|
||||
"The print statements print a few of the velocity entries, and already shows that something is happening in our simulation, but it's difficult to get an intuition for the behavior of the PDE just from these numbers. Hence, let's visualize the states over time to show what is happening.\n",
|
||||
"\n",
|
||||
"## Visualization\n",
|
||||
"\n",
|
||||
"We can visualize this 1D case easily in a graph: the following code shows the initial state in blue, and then times $10/32, 20/32, 1$ in green, cyan and purple. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[<matplotlib.lines.Line2D at 0x7f17fdeb2610>]"
|
||||
"[<matplotlib.lines.Line2D at 0x7faed7f5eeb0>]"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAD4CAYAAADhNOGaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Il7ecAAAACXBIWXMAAAsTAAALEwEAmpwYAABlyklEQVR4nO2dZ3hURReA30knhBJ66BGQ3kNJgqJ0FAUEKUqxIKAo0vuHSFEEBVEUREAQkCKIFJEuIknovbfQQqhJICF9d74fsyEhpO9uCpn3efbJ3nvnzpy92b3nzplThJQSjUaj0eRebLJaAI1Go9FkLVoRaDQaTS5HKwKNRqPJ5WhFoNFoNLkcrQg0Go0ml2OX1QJkhCJFisjy5ctntRgajUaTozh06NA9KWXRxPtzpCIoX748Bw8ezGoxNBqNJkchhLia1H5tGtJoNJpcjlYEGo1Gk8vRikCj0WhyOVoRaDQaTS5HKwKNRqPJ5VhEEQghFgoh7gghTiZzXAghvhNCXBRCHBdC1EtwrLcQ4oLp1dsS8mg0Go0m7VhqRrAIaJPC8bZAJdOrLzAHQAhRCPgMaAQ0BD4TQrhaSCaNRqPRpAGLxBFIKXcLIcqn0KQ98KtUOa/3CiEKCiHcgJeAbVLKIAAhxDaUQlluCbk0aefWLfDzgzNn4MoVCAyEyEiIjoZ8+aBwYShVCmrUgFq1oFo1sNGGRY3mmSCzAspKAdcTbN8w7Utu/1MIIfqiZhOULVvWOlLmIoxG8PWF1athwwa4fDl95xcpAi1bQvv26uXkZB0508Kj6EecvHOS47ePExAawL3we4THhJPXPi/5HfNTrWg1GpZqSMVCFRFCZJ2gGk02JcdEFksp5wHzADw8PHQ1nQwSFAQLFsCPP6on/zhcXKBxY6hdG9zdoXRpyJMH7OwgLAzu3wd/fzhxAg4dguvXYfly9SpYELp3h8GDoVIl638GKSX7A/bz14W/2HppKwduHsAojameVzp/aT6o9wF96vWhZL6S1hdUo8khZJYiCADKJNgubdoXgDIPJdy/K5NkylUEB8O0afDddxAervaVKwddukCnTuDhAba2aetLSjh/Hv7+G5YuVYphzhyYOxfefBPGj4fq1S3/GS4HX2bB4QUsP7kc/xD/x/vtbOyoXrQ6tUvUxr2gO0Wci5DXPi9h0WEERQRx9PZR9gfs58bDG3y26zMm7Z7ECK8RjG86Hkc7R8sLqtHkNKSUFnkB5YGTyRx7FfgbEEBjYL9pfyHAH3A1vfyBQqmNVb9+falJGzExUs6YIWWBAlKqW7iUrVpJuXGjlLGxlhnj+HEp+/SR0t5e9W9jI+VHH0l59675fRuNRrn5wmbZeklryQQev9y+dpMf//Wx3HhuowyNCk1TPzsu75CdVnaSYoKQTEDW+LGGPHzzsPlCajQ5BOCgTOoendTO9L5Qi7uBQAzKzv8+0B/obzougB+AS8AJwCPBue8BF02vd9MynlYEaWP/finr1IlXAM2aSbl3r/XGu35dKQBbWzVeoUJSLl0qpdGY/r6MRqPccG6DbDCvweObv+MkR9lrbS/5j/8/MtaQcS225+oeWem7SpIJSJcvXKTPNZ8M96XR5CSSUwRC5sDi9R4eHlJnH02e2FiYMgUmTQKDQZmAZs+Gdu0yZ/xTp+DTT2HHDrXdoQP89BMUK5b6uUZp5M+zfzJ592SO3DoCQFHnogz1HMoH9T+gUJ5CFpExPCac99e/z4qTK8jnkI8tPbbgWcbTIn1rNNkVIcQhKaXHU/u1Ini2uHEDunUDHx8QAoYMgc8/h7x5M1cOKWHhQjX+w4dQsiSsXAlNmiR/zr4b+/h086fsC9gHgJuLGyO8R9C3fl+c7Z0tLmOsMZaea3s+Vgb7P9hPlSJVLD6ORpNdSE4RaE/wZ4g9e6B+faUESpaE7dvh668zXwmAUkLvv6+8jJo0gZs34aWXYOZMpSQSEvAwgJ5re9J4QWP2BeyjhEsJZredzeVPLzOo8SCrKAFQi8xLOi7hjapvEBodSs+1PYkxxKTpXAnsB74GrllFOo0m89CK4BlhwQJo1gzu3IHmzeHYMbWd1ZQtCzt3wrBhykw1ZAj07w8xMRAZG8mkfyfx/OznWXp8KY62joxpMoYLn1xgQMMBONlZPzjBzsaOha8vpEz+Mhy8eZAv93yZYvswYAZQBRUOPxz43OpSajTWRZuGcjhSwsSJMGGC2h48WLmJ2mXDCJFVq6BXL4iKAo839vDwpQ84H3QWgE5VOzG95XTcXd2zRLad/jtp/mtz7Gzs2Pv+XuqXrP/E8WBgNvAtEGTa5wyEA03RPs+anIE2DT2DGAzw0UdKCdjYqAXZGTOypxIAFbPw1/aHOHX6iIO1XuB80FkquVbhn97/sLrL6ixTAgDN3JvxaaNPiTXG8unmT+M82rgLjAbKAeNRSqAxsA5lGgLlJqfR5GS0IsihGAzw7rsqiMvJCdasgb59s1qqlNlwbgO991cjsuYcMNrBv//DfsERqji9lNWiATDp5Um4Ornic92H9dd9GAO4A1OBUKA5sBPwBV5HKQdQiiDnzas1mniy6bOjJiUMBujdG5YtUwvBf/0FTZtmtVTJExoVyqDNg1h4dCEAjUo1YnKjn/lkVU1On1VrGbt2pc291Jrkc8xHvyajmBobSacSdTGY9r8C/A81E0iIC1AQCAHuAUUzS1CNxsJoRZDDMBrhvfeUEnBxUWkeUnLJzGr2XNtDr7W98A/xx8nOiS+afcHARgOxtbFl926lBE6eVAns/vkHClkmTCDdPABmAT96DQchMACNIkKYlacgjVI4rzRKEdxAKwJNzkWbhnIQUiqvm19/VTOBzZuzrxKINkQzevtoXvzlRfxD/Klboi6H+h5isOdgbG1UUqOiRZWLa+XKcPw4tGoFoaGZK2cE8BXKBPQZ8FAIygddhIXeFPrjrRSVAChFAHqdQJOz0YogBzF5MsyaBQ4O8Oef4O2d1RIlzYX7F/Bc4MlUn6kIIRj7wlj29tlLtaLVnmpbvLiKQH7uOZW8rnNnVQPB2hiAhahKSaNQXkEvorx/9jsWIE/gEf6++DeXg1POzx2XSVErAk1ORiuCHMKiRSqrp42NSv3cokVWS5Q0v534jXrz6nE48DDuBd3Z/c5uJjebjIOtQ7LnlCoFW7eqNYKtW6FPn6eDziyFBDYAtVAJsQKAusBWlBJoChTNW5QOVToAsPLkyhT70zMCzbOAVgQ5gJ074YMP1PvZs+GNN7JWnqQIjwmnz/o+vP3H24RFh9GleheO9DuCd9m0TVsqVFCL3nnzwpIl8NlnlpdxL+pG/zpwGpUudxlwEGiJyowYR/ca3QFYfjLlYnlaEWieBbQiyOacPavqBcTGwtCh8OGHWS3R05y+e5oGPzdgwZEFONk5MffVuazotIICTgXS1Y+HB/z+u5r1TJoEK1ZYRr5zQCfAE/gPKAzMBM4Cb5H0j6B1xda4Orly4s4JTt05lWzfcYrgerItNJrsj1YE2ZgHD1QZyJAQlcHzq6+yWqKnWXVqFQ1/bsjpu6epUqQK+/vsp59HvwyXhGzbVgXFgYqT2L8/5fYpcQf4EKgO/AHkAcagcqEPAlIqSeNg60Cnqp2AlGcFekageRbQiiCbYjTC22+rSmA1aypzSVoriGUGscZYhm0dRtfVXXkU84i3ar7FwQ8OUrN4TbP7HjhQmcIiI6FjR7h9O33nRwHTgYrAXNS6QB/gAjAFSOs8pXtNZR5acXIFyaViSagIdFCZJqeiFUE2ZcIEZTMvVEh5CLm4ZLVE8dx5dIeWS1ryjd832NnY8V2b71jacSl5HSyT5lQItRYSl7W0WzdlGksNCawFqgEjUNHAr6AqIf0MlEqnHE3LNaWESwkuBV/i4M2kc1vlN70iUJ5HGk1OxCKKQAjRRghxTghxUQgxKonjM4UQR02v80KIkATHDAmOrbeEPDmd7duVq6iNjcrh/9xzWS1RPHtv7KXeT/XYdWUXJVxK8E/vf/ik0ScZNgUlh4ODSlJXooSKOh4zJuX2x1ApIN4ALgNVUbVR/0Iphoxga2NL56qdAdhwfkOy7bR5SJPTMVsRCCFsUWUo26J+c92FEE/89qSUg6WUdaSUdYDvUSbbOCLijkkpXzdXnpzO7dvQo4dyn/zss+zjJiqlZO7Bubz4y4sEhAbgXcabw30P06Ss9SLa3NyUMrC1henTYX0Sjwl3gL4oF9B/UEWwZ6MUQxsLyNCyQksA/r36b7JttCLQ5HQsMSNoCFyUUl6WUkYDK4D2KbTvjqpxrEmE0ajSNN++rYq4jB2b1RIpomKj6LO+Dx/+9SExxhg+afgJO3vvxC2fm9XHfuGF+EXy995TpiJ4ch3gZ8AW+BRV+HoAYG+p8cu+gECw98ZeImIikmyjFYEmp2MJRVCKJ73nbpCMOVYIUQ4Vzb8zwW4nIcRBIcReIUSH5AYRQvQ1tTt49+5dC4id/fj6axVQVaSIyiWUHRaH7zy6Q4slLVh4dCF57PKwpOMSvmv7XYoBYpZm8GCVfuL+fejVG9YYn1wHeBW1DvAt4GrhsV3zuFK7RG2iDdGPS2gmRruQanI6mb1Y3A1YLaU0JNhXzlQo4S3gWyFEhaROlFLOk1J6SCk9ihZ99tJ77d0bPwNYtEiVmsxqTtw+QcOfG7Ln2h5K5SvFnvf20KNWj0yXw8ZGXZOCL8CO0dDZJn4dYDOwEVUxzFo0LadSu+66sivJ4zrNhCanYwlFEED8bwHUA1JAMm27kcgsJKUMMP29jIryr2sBmXIUISHQvbvyjBkyBF59NaslgvXn1uO10IurD67SsFRDDnxwgHpu9bJElhDgKzd4uAtoBtyHkdfhONA6E8aPUwTJrRNo05Amp2MJRXAAqCSEcBdCOKBu9k8t6wkhqqBm7n4J9rkKIRxN74sA3qjo/1zFgAFw5YqKrP0y5ZK5VkdKyVd7vqLDig6ERYfxds232dV7V6aLine truncated
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAD4CAYAAADhNOGaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Il7ecAAAACXBIWXMAAAsTAAALEwEAmpwYAABlgklEQVR4nO2dd3iT1fuH75NOoOxZRtkIKLuMtqDspSxlIyDbjQwZgoAgXxkCoqjsKRvZCMiQn1Ba9t57byhQupPz++OkNEB3k7SRc19Xr+bdT9+k7yfnPEtIKdFoNBrN64shtQ3QaDQaTeqihUCj0Whec7QQaDQazWuOFgKNRqN5zdFCoNFoNK85zqltQHLIkSOHLFSoUGqbodFoNA7FgQMH7kspc7683iGFoFChQuzfvz+1zdBoNBqHQghxJbb1empIo9FoXnO0EGg0Gs1rjhYCjUajec3RQqDRaDSvOVoINBqN5jXHKkIghJgthLgrhDgex3YhhPhZCHFeCHFUCFHRYltnIcQ5809na9ij0Wg0msRjrRHBXKBhPNsbAcXNPz2B3wGEENmA4UBVoAowXAiR1Uo2aTQajSYRWCWPQEr5rxCiUDy7NAPmS1XzOlAIkUUI4QnUBLZIKR8CCCG2oARlsTXs0iSe27chIABOnYLLl+HWLQgLg4gIyJgRsmeHfPngrbegbFkoXRoMaWhi8ebTmwReD+Tsg7NcenSJO8/uYJImAPJmzEvRrEUpn6c87xR6B1cn11S2VqNJW9groSwfcM1i+bp5XVzrX0EI0RM1msDLy8s2Vr5GmEywezesWAHr1sHFi0k7PkcOqFcPmjVTP+7utrEzLsKiwth+aTtrz6xl0/lNXHkca57MK2R2y0zTN5ryte/XlMldxsZWajSOgcNkFksppwPTAby9vXU3nWTy8CHMmgW//aa++Ufj4QHVqkG5clC4MOTPD+nSgbMzBAfDgwdw6RIcOwYHDsC1a7B4sfrJkgXatYM+faB4cdvZLqVk7429zD08lyUnlhAUFvR8Wya3TFTNV5UyucpQOGthPD08cTY4Y5Imrj+5zrmH59h+aTsn7p1gwdEFLDy2kK7luzKq9ijyeOSxndEajQNgLyG4ARSwWM5vXncDNT1kuX6HnWx6rXj0CMaNg59/hpAQta5gQWjdGj74ALy9wckpceeSEs6ehY0b4Y8/lDD8/jtMnQqtWsGwYfDmm9azPcIYwbITy5i8ZzL7b8aUFimXuxwtSragyRtNKJe7HE6GhP+AM/fPMGXvFH7f/zszD81k/bn1rGu3Du+83tYzWKNxNKSUVvkBCgHH49j2LrAREEA1YK95fTbgEpDV/HMJyJbQtSpVqiQ1iSMyUsqJE6XMnFlK9QiXsn59KdevlzIqyjrXOHpUyu7dpXRxUec3GKT89FMp791L2XlDI0PlL3t+kfkn5peMQDICmX1sdtl3U1959PbRFJ379L3T8p0570hGINOPTi/XnF6TMmM1GgcA2C9je0bHtjKpPyjn7i0gEjXP3w34GPjYvF0AvwIXgGOAt8WxXYHz5p8uibmeFoLEsXevlOXLxwhA7dpSBgba7nrXrikBcHJS18uWTco//pDSZEraeaKMUXLmgZky74S8zwWg1JRScsaBGTIkIsRq9oZHhcvOqzpLRiAN3xnkX2f/stq5NZq0iE2FwN4/WgjiJzJSyhEjYh7IBQtKuW6d/a5//LiUderECFDz5lLeuZPwcSaTSW48t1GW+a3McwEoP7W8/PPkn9JoMtrEVpPJJAduGSgZgcw6Jqu8+PBiks8RKaVcIaXcaHXrNBrrooXgNeHaNSn9/NQ7K4SU/fpJGRxsfztMJilnzpQyUyZlS968Uu7cGff+R24fkXXn130uAAUnFZSLji6ymQBYYjQZZZNFTSQjkBWmVkj0qCNUSvmblLKwVB9MNyllhO3M1GhSTFxCkIYiwTUpZdcuqFQJ/P0hb17YuhV+/BEyZLC/LUJAt24qyqh6dbh5E2rWhEmT1DghmuCIYPr/3Z+K0yqy9eJWMrtlZny98Zz+/DTtyrTDIGz/ETUIA/NbzKdo1qIcun2IgVsHxrv/E2Asyin2KcqxBRCOmhvVaBwNLQT/EWbNgtq14e5dqFMHjhxRy6mNlxds3w79+4PRCH37wscfQ2QkrD+7njd/e5MJAROQSD6v/DkXvrxAf9/+uDvbNzEhi3sWVrRegUEY+H3/75x9cPaVfZ4Ao1ECMAi4A1QAlgHRWmu0j7kajVXRQuDgSAnffQfdu6uHa58+sGmTSvhKK7i4wPjxsHQpuLnB9MU3yd+3JU0WN+Hq46tU9KzInu57+KXxL2RPnz3V7CyfpzxdynchyhTFN9u+eb7eUgCGAo+AGsAm4ADQipg47Ch7GqzRWAmHSSjTvIrRCJ9/ruL3DQYVy9+zZ2pbFTetWklOOS/iu32fc9c9CEOUB9/X+p6va36GsyFtfBS/q/kdi44t4s9Tf7Ltxj4C81VmAurhD0oAvkMlvwiL46IzGPSIQOOIpI3/Pk2SMRqhSxdYsECVd1i8GJo3T22r4ubes3t8suET/jz1J7hDumuNCV0+lUWrC9BlC+RJI8m9+TLl41Pfr5lgiqBhjjeef8OPSwCiif5H0kKgcUS0EDggRiN07gwLFypH8IYN8M47qW1V3Kw5vYae63ty99ldMrpm5KeGP1E/Zxfq+QuOH1e+jB07IFeu1LUzEpgJ/FFzOAgDUUCF8KdMcMsYpwBEEz0i0FNDGkdE+wgcDJMJunZVIuDhofwBaVUEnkU8o8faHjRf2py7z+5Ss1BNjn5ylK4VupI/v+Dff1U101OnVAG7hw9Tx04TsBQojYoCuiMM5A66AvPrUm3rIGoRvwiAnhrSODZaCBwIKVXUzfz5aiSwaZMKzUyLHLl9BO8Z3sw8NBM3Jzd+avAT2zpto1CWQs/3yZlThbi+8QYcPQr168PTp/a1cwtQGWiLSm0vASwHNoUFwaVtLD6+iNDI0ATPo4VA48hoIXAgvv8eJk8GV1dYvRr8/FLboleRUjJl7xSqzqzK6funKZ2zNPt67KN3td6x5gTkzg3btkGRIqp4XcuWqgeCrdkH1AXqAweBvKjStieAlkD5POWo5FmJoLAgVp9eneD5dNSQxpHRQuAgzJ2rqnoaDMoxXLdualv0Kg9DH9J8aXO+2PgF4cZwelXqxb4e+xKs+58vH/z9t/IR/P23CoW1TDqzJudR4Z5VgG1AFmAMcA7owYtOs24VugEw69CsBM+rRwQaR0YLgQOwfTv06KFeT5kC77+fuvbExsFbB6k0vRJrz6wli3sWlrdaztT3ppLeJX2iji9aVDm9M2RQkVDDh1vXvkdAX5QfYAXgDgwALgIDgdisbFemHe7O7my7tI3LQZfjPb8WAo0jo4UgjXP6tOoXEBUF/frBJ5+ktkWvMuvgLHxn+XI56DLeeb051OsQLUu3TPJ5vL1h+XI16hk1CpYsSbltkcDPQDFgEmrqpgtqBDAWVfs8LrK4Z+H9Ukp1lxyP3xg9NaRxZLQQpGEeP1ZtIIOCVI7A2LGpbdGLhEWF0X1td7qv6064MZyeFXuys8vOFxzCSaVRI5g4Ub3u0gX27k3eeSSwDngL6A08BGqhMoFnozogJYZmbzQD4O8Lf8e7nx4RaBwZLQRpFJMJOnRQncDKlFHTJYntIGYPLj26hN9sP2YdmoW7sztzms1hWpNpVqkR9OWXaiosLAxatIA7d5J2/BGgHtAUOAsUB9agfAIVkmhLncJ1EAj8r/kTEhkS535aCDSOjBaCNMqIEWrOPFs2FSHk4ZHaFsWw8dxGKk2vxMFbBymStQgB3QL4qPxHVju/EMoXEl21tG1bNTWWELeA7qiH/TbUtM9PwHGUKCSUCxAb2dNnp1LeSkQYI/j3yr9x7qenhjSOjFWEQAjRUAhxRghxXggxKJbtk4QQh80/Z4UQQRbbjBbb1lrDHkdn61YVKmowqEJtRYqktkUKKSWj/x3Nu4ve5VHYI94r8R77e+ynfJ7yVr+WqyssW6ZKT+zYAd98E/e+4cA4VA7ALNS3869QEUK9AdcU2lK/SH0g/ukhPSLQODIpFgIhhBOqDWUjVFBGOyFEact9pJR9pJTlpZTlgV+AlRabQ6O3SSmbptQeR+fOHfjwQxU+OXx42gkTDYkMod2f7Rj6z1AARtUaxZq2a8iaLj53a8rw9FRi4OSkqpeujeVrwl9AGVTkTzDqm/8JlGM4m5XsqFe0HgBbLm6Jcx8tBBpHxhojgirAeSnlRSllBLAEaBbP/u1QPY41L2EyQadOSgxq1oQhQ1LbIsW1x9eoMacGS08sxcPVgzVt1zD07aF2aRpTo0aMk7xrVzVVBCrq5z3gXfPrksBmlC+ghJVt8MnvQwaXDBy/e5ybT2/Guo8uOqdxZKzxn5wPuGaxfN287hWEEAWBwsB2i9XuQoj9QohAIUTzuC4ihOhp3m//vXv3rGB22uPHH1VCVY4cqpZQWnAOB1wLoPKMys/9AYHdAmnyRhO72tCnjyo/8eABdPgYBkp4E9gAZAImAkdRWcK2wM3ZjXcKqYJOWy9ujXUfXXRO48jY21ncFlghpbT84lRQSukNtAd+EkIUje1AKeV0KaW3lNI7Z86c9rDVrgQGxowA5s5VrSZTm3mH51FzXk3uPLtDrUK12Nt9L2/metPudhgMMGcueHwMO6bCOKHyA7qiooL6AC42tiEhP4GeGtI4MtYQghtAAYvl/OZ1sdGWl6aFpJQ3zL8vAjtIeoSfwxMUBO3aqciYvn3h3XdT1x6jyUj/v/vz0ZqPiDBG8Fnlz9j84eZU6x52AGjlCcG/A3lB7IH5Z5RjOLedbKhTpA4AO6/ujHW7FgKNI2MNIdgHFBdCFBZCuKIe9q+49YQQJVERfQEW67IKIdzMr3MAfsBJK9jkUHz2GVy+rDJrf/ghdW15Gv6UZkuaMSFgAs4GZ6a+O5Upjafg4mTLine truncated
|
||||
"text/plain": [
|
||||
"<Figure size 432x288 with 1 Axes>"
|
||||
]
|
||||
@@ -126,14 +178,12 @@
|
||||
],
|
||||
"source": [
|
||||
"# we only need \"velocity.data\" from each phiflow state\n",
|
||||
"vels = [x.velocity.data for x in state]\n",
|
||||
"#vels = [v.values.numpy('x') for v in velocities]\n",
|
||||
"vels = [v.values.numpy('x,vector') for v in velocities] # vel vx\n",
|
||||
"\n",
|
||||
"# print(vels[0][0,:,0].shape)\n",
|
||||
"# print(vels[0].shape[1])\n",
|
||||
"import pylab\n",
|
||||
"\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"\n",
|
||||
"fig = plt.figure().gca()\n",
|
||||
"fig = pylab.figure().gca()\n",
|
||||
"fig.plot(np.linspace(-1,1,len(vels[ 0].flatten())), vels[ 0].flatten(), lw=2, color='blue')\n",
|
||||
"fig.plot(np.linspace(-1,1,len(vels[10].flatten())), vels[10].flatten(), lw=2, color='green')\n",
|
||||
"fig.plot(np.linspace(-1,1,len(vels[20].flatten())), vels[20].flatten(), lw=2, color='cyan')\n",
|
||||
@@ -144,26 +194,30 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"And as image..."
|
||||
"This nicely shows the shock developing in the center of our domain, which forms from the collision of the two initial velocity \"bumps\", the positive one on left (moving right) and the negative one right of the center (moving left).\n",
|
||||
"\n",
|
||||
"As these lines can overlap quite a bit we'll also use a different visualization in the following chapters that shows the evolution over the course of all time steps in a 2D image. Our 1D domain will be shown along the Y-axis, and each point along X will represent one time step.\n",
|
||||
"\n",
|
||||
"The code below converts our collection of velocity states into a 2D array, repeating individual time steps 8 times to make the image a bit wider. This purely optional, of course, but makes it easier to see what's happening in our Burgers simulation."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Vels array shape: (1, 128, 33, 1)\n"
|
||||
"Vels array shape: (128, 33, 1)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 432x288 with 1 Axes>"
|
||||
"<Figure size 1152x360 with 2 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
@@ -177,21 +231,36 @@
|
||||
" # we only have 33 time steps, blow up by a factor of 2^4 to make it easier to see\n",
|
||||
" # (could also be done with more evaluations of network)\n",
|
||||
" for i in range(4):\n",
|
||||
" a = np.concatenate( [a,a] , axis=3)\n",
|
||||
" a = np.concatenate( [a,a] , axis=2)\n",
|
||||
"\n",
|
||||
" a = np.reshape( a, [a.shape[1],a.shape[2]*a.shape[3]] )\n",
|
||||
" a = np.reshape( a, [a.shape[0],a.shape[1]*a.shape[2]] )\n",
|
||||
" #print(\"resulting image size\" +format(a.shape))\n",
|
||||
" plt.imshow(a, origin='upper', cmap='magma')\n",
|
||||
" \n",
|
||||
"vels_img = np.asarray( np.concatenate(vels, axis=-1), dtype=np.float32 )\n",
|
||||
" fig, axes = pylab.subplots(1, 1, figsize=(16, 5))\n",
|
||||
" im = axes.imshow(a, origin='upper', cmap='inferno')\n",
|
||||
" pylab.colorbar(im) \n",
|
||||
" \n",
|
||||
"#vels_img = np.asarray( np.stack(vels), dtype=np.float32 ).transpose() # no component channel\n",
|
||||
"vels_img = np.asarray( np.concatenate(vels, axis=-1), dtype=np.float32 ) # vel vx\n",
|
||||
"vels_img = np.reshape(vels_img, list(vels_img.shape)+[1] ) ; print(\"Vels array shape: \"+format(vels_img.shape))\n",
|
||||
"\n",
|
||||
"# save for comparison with reconstructions later on\n",
|
||||
"np.savez_compressed(\"./temp/burgers-groundtruth-solution.npz\", np.reshape(vels_img,[n,steps+1])) # remove batch & channel dimension\n",
|
||||
"np.savez_compressed(\"./temp/burgers-groundtruth-solution.npz\", np.reshape(vels_img,[N,STEPS+1])) # remove batch & channel dimension\n",
|
||||
"\n",
|
||||
"show_state(vels_img)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Next steps\n",
|
||||
"\n",
|
||||
"Some things to try based on this simulation setup:\n",
|
||||
"\n",
|
||||
"- Feel free to experiment - the setup above is very simple, you can change the simulation parameters, or the initialization. E.g., you can use a noise field via `Noise(vector=1)` to get more chaotic results.\n",
|
||||
"- A bit more complicated: extend the simulation to 2D (or higher). This will require changes throughout, but all operators above support higher dimensions. Before trying this, you probably will want to check out the next example, which covers a 2D Navier-Stokes case."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
|
||||
+14
-5
@@ -7,10 +7,18 @@ In addition we'll discuss some _model equations_ below. Note that we won't use _
|
||||
## Deep Learning and Neural Networks
|
||||
|
||||
There are lots of great introductions to deep learning - hence, we'll keep it short:
|
||||
our goal is to approximate $f^*(x)=y$ with an NN $f(x;\theta)$,
|
||||
given some formulation for an error $e(y,y^*)$ with $y=f(x;\theta)$ being the output
|
||||
of the NN, and $y^*$ denoting a reference or ground truth value.
|
||||
our goal is to approximate an unknown function
|
||||
|
||||
$f^*(x) = y^*$ ,
|
||||
|
||||
where $y^*$ denotes reference or "ground truth" solutions.
|
||||
$f^*(x)$ should be approximated with an NN representation $f(x;\theta)$. We typically determine $f$
|
||||
with the help of some formulation of an error function $e(y,y^*)$, where $y=f(x;\theta)$ is the output
|
||||
of the NN.
|
||||
This gives a minimization problem to find $f(x;\theta)$ such that $e$ is minimized.
|
||||
In the simplest case, we can use an $L^2$ error, giving
|
||||
|
||||
$\text{min}_{\theta} || f(x;\theta) - y^* ||_2^2$
|
||||
|
||||
We typically optimize, i.e. _train_,
|
||||
with some variant of a stochastic gradient descent (SGD) optimizer.
|
||||
@@ -177,7 +185,7 @@ $\begin{aligned}
|
||||
\text{subject to} \quad \nabla \cdot \mathbf{u} &= 0
|
||||
\end{aligned}$
|
||||
|
||||
where, like before, $\nu$ denotes a diffusion constant for viscosity, respectively.
|
||||
where, like before, $\nu$ denotes a diffusion constant for viscosity.
|
||||
|
||||
An interesting variant is obtained by including the Boussinesq approximation
|
||||
for varying densities, e.g., for simple temperature changes of the fluid.
|
||||
@@ -187,13 +195,14 @@ this yields the following set of equations:
|
||||
$\begin{aligned}
|
||||
\frac{\partial u_x}{\partial{t}} + \mathbf{u} \cdot \nabla u_x &= - \frac{1}{\rho} \nabla p
|
||||
\\
|
||||
\frac{\partial u_y}{\partial{t}} + \mathbf{u} \cdot \nabla u_y &= - \frac{1}{\rho} \nabla p + \eta d
|
||||
\frac{\partial u_y}{\partial{t}} + \mathbf{u} \cdot \nabla u_y &= - \frac{1}{\rho} \nabla p + \xi d
|
||||
\\
|
||||
\text{subject to} \quad \nabla \cdot \mathbf{u} &= 0,
|
||||
\\
|
||||
\frac{\partial d}{\partial{t}} + \mathbf{u} \cdot \nabla d &= 0
|
||||
\end{aligned}$
|
||||
|
||||
where $\xi$ denotes the strength of the buoyancy force.
|
||||
|
||||
And finally, we'll also consider 3D cases with the Navier-Stokes model, i.e.:
|
||||
|
||||
|
||||
@@ -0,0 +1,381 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "o4JZ84moBKMr"
|
||||
},
|
||||
"source": [
|
||||
"# Navier-Stokes Forward Simulation with Φ<sub>Flow</sub>\n",
|
||||
"\n",
|
||||
"... now a more complex example with fluid simulations (Navier-Stokes) ... still very simple with phiflow (complexity of the differentiable operators hidden).\n",
|
||||
"\n",
|
||||
"As before, the first command with a \"!\" prefix installs the [Φ<sub>Flow</sub> Python package from GitHub](https://github.com/tum-pbs/PhiFlow) via `pip` in your python environment. (Skip or modify this command if necessary.)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "da1uZcDXdVcF",
|
||||
"outputId": "1082dc87-796c-4b57-e72e-5790fc1444c9"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/home/thuerey/anaconda3/envs/tf/lib/python3.8/_collections_abc.py:743: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
|
||||
" for key in self._mapping:\n",
|
||||
"/home/thuerey/anaconda3/envs/tf/lib/python3.8/_collections_abc.py:744: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
|
||||
" yield (key, self._mapping[key])\n",
|
||||
"/home/thuerey/phiflow/phi/viz/display.py:80: UserWarning: GUI is disabled because of missing dependencies: No module named 'imageio'. To install all dependencies, run $ pip install phiflow[gui]\n",
|
||||
" warnings.warn('GUI is disabled because of missing dependencies: %s. To install all dependencies, run $ pip install phiflow[gui]' % import_error)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!pip install --upgrade --quiet phiflow\n",
|
||||
"from phi.flow import * # The Dash GUI is not supported on Google Colab, ignore the warning\n",
|
||||
"import pylab"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "BVV1IKVqDfLl"
|
||||
},
|
||||
"source": [
|
||||
"## Setting up the simulation\n",
|
||||
"\n",
|
||||
"Φ<sub>Flow</sub> is object-oriented, i.e. you assemble your simulation by constructing a number of objects and adding them to the world.\n",
|
||||
"\n",
|
||||
"The following code sets up four fluid simulations that run in parallel (`batch_size=4`). Each fluid simulation has a circular Inflow at a different location."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"id": "WrA3IXDxv31P"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"world = World()\n",
|
||||
"fluid = world.add(Fluid(Domain([40, 32], boundaries=CLOSED), buoyancy_factor=0.05), physics=IncompressibleFlow())\n",
|
||||
"world.add(Inflow(Sphere(center=[5,14], radius=3), rate=0.2));"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ExA0Pi2sFVka"
|
||||
},
|
||||
"source": [
|
||||
"The inflow affects the fluid's marker density. Because a Boussinesq model with a positive `buoyancy_factor` is active, the marker field `density` creates an upward force. Note that this density is not the density of the fluid, but the amount of marker quantity present in each cell.\n",
|
||||
"\n",
|
||||
"Let's plot the marker density after one simulation frame."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 282
|
||||
},
|
||||
"id": "WmGZdOwswOva",
|
||||
"outputId": "3ae4d68d-b586-4bbe-eca9-a223d7720949"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<matplotlib.image.AxesImage at 0x7f9cf945eee0>"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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\n",
|
||||
"text/plain": [
|
||||
"<Figure size 432x288 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"world.step()\n",
|
||||
"pylab.imshow(fluid.density.data[0,...,0], origin='lower', cmap='magma')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"A lot has happened internally in the `world.step()` call, e.g., for fluids we have a more complex `struct` object that stores the different fields of the simulation. For fluids we have the aforementioned marker density in addition to a velocity."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Fluid state: Fluid[density: Grid[40x32(1), size=[40. 32.], float32], velocity: StaggeredGrid[40x32, size=[40. 32.], float32]]\n",
|
||||
"\n",
|
||||
" Velocity content:\n",
|
||||
"(1, 41, 32, 1)\n",
|
||||
"(1, 40, 33, 1)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(\"Fluid state: \" + format(fluid.state))\n",
|
||||
"print(\"\\nVelocity content:\")\n",
|
||||
"[print(grid.data.shape) for grid in fluid.velocity.unstack()];"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Note that we actually created two variables, one for each velocity component. If you're interested in how this works, have a look at the [Struct documentation](https://github.com/tum-pbs/PhiFlow/blob/master/documentation/Structs.ipynb).\n",
|
||||
"\n",
|
||||
"If you look closely at the output from the last `print` command, you'll notice that the shapes of the variables differ. This is because the velocity is sampled in [staggered form](https://github.com/tum-pbs/PhiFlow/blob/master/documentation/Staggered_Grids.md).\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "PA-2tGuWGHv2"
|
||||
},
|
||||
"source": [
|
||||
"We can run more steps by repeatedly calling `world.step()`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "0hZk5HX3w4Or",
|
||||
"outputId": "f7811af7-4b58-4ff6-a8b6-6e7bedefaa6e"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Computing frame 0\n",
|
||||
"Computing frame 1\n",
|
||||
"Computing frame 2\n",
|
||||
"Computing frame 3\n",
|
||||
"Computing frame 4\n",
|
||||
"Computing frame 5\n",
|
||||
"Computing frame 6\n",
|
||||
"Computing frame 7\n",
|
||||
"Computing frame 8\n",
|
||||
"Computing frame 9\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for frame in range(10):\n",
|
||||
" print('Computing frame %d' % frame)\n",
|
||||
" world.step(dt=1.5)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "GMKKWQBLHIwP"
|
||||
},
|
||||
"source": [
|
||||
"Now the hot plume is starting to rise:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 282
|
||||
},
|
||||
"id": "Mfl80CjZxZcL",
|
||||
"outputId": "92f3a9ba-d403-4799-a543-132ee8ed234c"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<matplotlib.image.AxesImage at 0x7fa84d3553d0>"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 432x288 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"pylab.imshow(fluid.density.data[0,...,0], origin='lower', cmap='magma')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "wnbQJvA-HPSL"
|
||||
},
|
||||
"source": [
|
||||
"Let's compute and show a few more steps of the simulation."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 489
|
||||
},
|
||||
"id": "tkhCOzc0ITsj",
|
||||
"outputId": "f6366c12-1eb5-4ff6-e0d7-94b806bfd8e4"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Computing frame 0\n",
|
||||
"Computing frame 1\n",
|
||||
"Computing frame 2\n",
|
||||
"Computing frame 3\n",
|
||||
"Computing frame 4\n",
|
||||
"Computing frame 5\n",
|
||||
"Computing frame 6\n",
|
||||
"Computing frame 7\n",
|
||||
"Computing frame 8\n",
|
||||
"Computing frame 9\n",
|
||||
"Computing frame 10\n",
|
||||
"Computing frame 11\n",
|
||||
"Computing frame 12\n",
|
||||
"Computing frame 13\n",
|
||||
"Computing frame 14\n",
|
||||
"Computing frame 15\n",
|
||||
"Computing frame 16\n",
|
||||
"Computing frame 17\n",
|
||||
"Computing frame 18\n",
|
||||
"Computing frame 19\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<matplotlib.image.AxesImage at 0x7fa84d2d8790>"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 432x288 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"frames = [fluid.density.data[0,...,0]]\n",
|
||||
"for frame in range(20):\n",
|
||||
" print('Computing frame %d' % frame)\n",
|
||||
" world.step(dt=1.5)\n",
|
||||
" if frame%5==0:\n",
|
||||
" frames.append(fluid.density.data[0,...,0])\n",
|
||||
"\n",
|
||||
"pylab.imshow(np.concatenate(frames,axis=1), origin='lower', cmap='magma')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ooqVxCPM8PXl"
|
||||
},
|
||||
"source": [
|
||||
"It looks simple here, but this is a powerful tool. The simulation could easily be extended to more complex cases or 3D, and they're fully compatible with back-propagation pipelines of deep learning frameworks. \n",
|
||||
"\n",
|
||||
"In the next chapters we'll show how to use these simulations for training NNs, and how to steer and modify them via trained NNs. This will illustrate how much we can improve the training process by having a solver in the loop, and especially by having differentiable solvers."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "BL-AOqwMJmkq"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"collapsed_sections": [],
|
||||
"name": "Forw Simulations with Φ-Flow.ipynb",
|
||||
"provenance": []
|
||||
},
|
||||
"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.8.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 1
|
||||
}
|
||||
@@ -1,451 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "o4JZ84moBKMr"
|
||||
},
|
||||
"source": [
|
||||
"# Navier-Stokes Forward Simulation\n",
|
||||
"\n",
|
||||
"Now let's target a somewhat more complex example: a fluid simulations based on the Navier-Stokes equations. This is still very simple with Φ<sub>Flow</sub>, as differentiable operators for all steps exist. The Navier-Stokes equations (in their incompressible form) introduce an additional pressure field $p$, and a constraint for conservation of mass:\n",
|
||||
"\n",
|
||||
"$\\begin{align}\n",
|
||||
" \\frac{\\partial \\mathbf{u}}{\\partial{t}} + \\mathbf{u} \\nabla \\mathbf{u} &= - \\frac{dt}{\\rho} \\nabla p + \\nu \\nabla\\cdot \\nabla \\mathbf{u} + \\mathbf{g} \\\\\n",
|
||||
" \\nabla \\cdot \\mathbf{u} &= 0 \n",
|
||||
"\\end{align}$ \n",
|
||||
"\n",
|
||||
"Here $\\mathbf{g}$ collects the forcing terms. Below we'll use a simple buoyancy model. We'll solve this PDE on a closed domain with Dirchlet boundary conditions $\\mathbf{u}=0$ for the velocity, and Neumann boundaries $\\frac{\\partial p}{\\partial x}=0$ for pressure, on a domain $\\Omega$ with a physical size of $100 \\times 80$ units. \n",
|
||||
"\n",
|
||||
"## Implementation\n",
|
||||
"\n",
|
||||
"As before, the first command with a \"!\" prefix installs the [Φ<sub>Flow</sub> Python package from GitHub](https://github.com/tum-pbs/PhiFlow) via `pip` in your python environment. (Skip or modify this command if necessary.)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "da1uZcDXdVcF",
|
||||
"outputId": "1082dc87-796c-4b57-e72e-5790fc1444c9"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/Users/thuerey/miniconda3/envs/tf/lib/python3.8/_collections_abc.py:743: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
|
||||
" for key in self._mapping:\n",
|
||||
"/Users/thuerey/miniconda3/envs/tf/lib/python3.8/_collections_abc.py:744: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
|
||||
" yield (key, self._mapping[key])\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"#!pip install --upgrade --quiet git+https://github.com/tum-pbs/PhiFlow@develop\n",
|
||||
"# [ !pip install --upgrade --quiet phiflow ]\n",
|
||||
"from phi.flow import * # The Dash GUI is not supported on Google Colab, ignore the warning\n",
|
||||
"import pylab"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "BVV1IKVqDfLl"
|
||||
},
|
||||
"source": [
|
||||
"## Setting up the simulation\n",
|
||||
"\n",
|
||||
"Φ<sub>Flow</sub> is object-oriented and centered around field data in the form of grids (internally represented by a tensor object). I.e. you assemble your simulation by constructing a number of grids, and updating them over the course of time steps.\n",
|
||||
"\n",
|
||||
"The following code sets up a simulation domain with the physical size, an inflow object to emit a smoke density, and three field: a staggerend `velocity` grid, and two centered grids for the smoke density and a pressure field. We'll use $40\\times32$ cells to discretize our domain, introduce a slight viscosity via $\\nu$, and define the time step to be $\\Delta t=1.5$. \n",
|
||||
"(As the following variables are constants, they have upper case names.)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"id": "WrA3IXDxv31P"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"DOMAIN = Domain(x=40, y=32, boundaries=CLOSED, bounds=Box[0:100, 0:80])\n",
|
||||
"INFLOW = DOMAIN.grid(Sphere(center=(30, 15), radius=10)) * 0.2\n",
|
||||
"\n",
|
||||
"DT = 1.5\n",
|
||||
"NU = 0.01"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ExA0Pi2sFVka"
|
||||
},
|
||||
"source": [
|
||||
"The inflow will be used to inject smoke into the `smoke` grid. Note that we've defined a `Box` of size $100x80$ above. This is the physical scale in terms of spatial units in our simulation, i.e., a velocity of magnitude $1$ will move the smoke density by 1 unit per 1 time unit, which may be larger or smaller than a cell in the discretized grid, depending on the settings for `x,y`. You could parametrize your simulation grid to directly resemble real-world units, or keep conversion factors in mind for conversion. \n",
|
||||
"\n",
|
||||
"The inflow sphere above is already using the \"world\" coordinates: it is located at $x=30$ along the first axis, and $y=15$ (within the $100x80$ domain box).\n",
|
||||
"\n",
|
||||
"Next, we create grids for the quantities we want to simulate. For this example, we require a velocity field and a smoke density field.\n",
|
||||
"We sample the smoke field at the cell centers and the velocity in [staggered form](https://tum-pbs.github.io/PhiFlow/Staggered_Grids.html)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# velocity = domain.staggered_grid(0) # alternatively vector_grid(0)\n",
|
||||
"# smoke = pressure = divergence = domain.grid(0)\n",
|
||||
"\n",
|
||||
"smoke = DOMAIN.scalar_grid(0) # sampled at cell centers\n",
|
||||
"velocity = DOMAIN.staggered_grid(0) # sampled in staggered form at face centers "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let's define the update step, and plot the marker density after one simulation frame."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 282
|
||||
},
|
||||
"id": "WmGZdOwswOva",
|
||||
"outputId": "3ae4d68d-b586-4bbe-eca9-a223d7720949"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Max. velocity and mean density: [0.135354, 0.007865495]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<matplotlib.image.AxesImage at 0x7fb2c07a7c40>"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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\n",
|
||||
"text/plain": [
|
||||
"<Figure size 432x288 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def step(velocity, smoke, pressure, dt=1.0, buoyancy_factor=1.0):\n",
|
||||
" smoke = advect.semi_lagrangian(smoke, velocity, dt) + INFLOW\n",
|
||||
" buoyancy_force = smoke * (0, buoyancy_factor) >> velocity # resamples smoke to velocity sample points\n",
|
||||
" velocity = advect.semi_lagrangian(velocity, velocity, 1) + dt * buoyancy_force\n",
|
||||
" velocity = diffuse.explicit(velocity, NU, dt)\n",
|
||||
" velocity, pressure, iterations, divergence = fluid.make_incompressible(velocity, DOMAIN, pressure_guess=pressure)\n",
|
||||
" return velocity, smoke, pressure\n",
|
||||
"\n",
|
||||
"velocity, smoke, pressure = step(velocity, smoke, None, dt=DT)\n",
|
||||
"\n",
|
||||
"print(\"Max. velocity and mean density: \" + format( [ math.max(velocity.values) , math.mean(smoke.values) ] ))\n",
|
||||
"\n",
|
||||
"pylab.imshow(np.asarray(smoke.values.numpy('y,x')), origin='lower', cmap='magma')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"A lot has happened in this `step()` call: we've advected the smoke field, added an upwards force via a Boussinesq model, advected the velocity field, and finally made it divergence free via a pressure solve.\n",
|
||||
"\n",
|
||||
"The Boussinesq model uses a multiplication by a tuple `(0, buoyancy_factor)` to turn the smoke field into a 2 component force field, sampled at the staggered velocity components via the `>>` operator. \n",
|
||||
"\n",
|
||||
"The pressure projection step in `make_incompressible` is typically the computationally most expensive step in the sequence above. It solves a Poisson equation for the boundary conditions of the domain, and updates the velocity field with the gradient of the computed pressure.\n",
|
||||
"\n",
|
||||
"Just for testing, we've also printed the mean value of the velocities, and the max density after the update. As you can see in the resulting image, we have a first round region of smoke, with a slight upwards motion (which does not show here yet). \n",
|
||||
"\n",
|
||||
"## Datatypes and Dimensions\n",
|
||||
"\n",
|
||||
"The created grids are instances of the class `Grid`.\n",
|
||||
"Like tensors, grids also have the `shape` attribute which lists all batch, spatial and channel dimensions.\n",
|
||||
"[Shapes in Φ<sub>Flow</sub>](https://tum-pbs.github.io/PhiFlow/Math.html#shapes) store not only the sizes of the dimensions but also their names and types."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Smoke: (x=40, y=32)\n",
|
||||
"Velocity: (x=40, y=32, vector=2)\n",
|
||||
"Inflow: (x=40, y=32)\n",
|
||||
"Inflow, spatial only: (x=40, y=32)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(f\"Smoke: {smoke.shape}\")\n",
|
||||
"print(f\"Velocity: {velocity.shape}\")\n",
|
||||
"print(f\"Inflow: {INFLOW.shape}\")\n",
|
||||
"print(f\"Inflow, spatial only: {INFLOW.shape.spatial}\")\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The grid values can be accessed using the `values` property."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"(x=40, y=32) float32 0.0 < ... < 0.2\n",
|
||||
"(x=(41, 40) along vector, y=(32, 33) along vector, vector=2) float32 -0.10927753 < ... < 0.135354\n",
|
||||
"(x=40, y=32) float32 0.0 < ... < 0.2\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(smoke.values)\n",
|
||||
"print(velocity.values)\n",
|
||||
"print(INFLOW.values)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Grids have many more properties which are documented [here](https://tum-pbs.github.io/PhiFlow/phi/field/#phi.field.Grid).\n",
|
||||
"Also note that the staggered grid has a [non-uniform shape](https://tum-pbs.github.io/PhiFlow/Math.html#non-uniform-tensors) because the number of faces is not equal to the number of cells. The `INFLOW` grid naturally has the same dimensions as the `smoke` grid.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Time Evolution\n",
|
||||
"\n",
|
||||
"With this setup, we can easily advance the simulation forward in time a bit more by repeatedly calling the `step` function."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "0hZk5HX3w4Or",
|
||||
"outputId": "f7811af7-4b58-4ff6-a8b6-6e7bedefaa6e"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Computed frame 0, max velocity 0.40485728\n",
|
||||
"Computed frame 1, max velocity 0.80262446\n",
|
||||
"Computed frame 2, max velocity 1.3215623\n",
|
||||
"Computed frame 3, max velocity 1.99783\n",
|
||||
"Computed frame 4, max velocity 2.8307805\n",
|
||||
"Computed frame 5, max velocity 3.756278\n",
|
||||
"Computed frame 6, max velocity 4.5489845\n",
|
||||
"Computed frame 7, max velocity 5.147038\n",
|
||||
"Computed frame 8, max velocity 5.5985193\n",
|
||||
"Computed frame 9, max velocity 6.0121617\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for time_step in range(10):\n",
|
||||
" velocity, smoke, pressure = step(velocity, smoke, pressure, dt=DT)\n",
|
||||
" print('Computed frame {}, max velocity {}'.format(time_step , np.asarray(math.max(velocity.values)) ))\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "GMKKWQBLHIwP"
|
||||
},
|
||||
"source": [
|
||||
"Now the hot plume is starting to rise:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 282
|
||||
},
|
||||
"id": "Mfl80CjZxZcL",
|
||||
"outputId": "92f3a9ba-d403-4799-a543-132ee8ed234c"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<matplotlib.image.AxesImage at 0x7fb2bc1153d0>"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 432x288 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"pylab.imshow(smoke.values.numpy('y,x'), origin='lower', cmap='magma')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "wnbQJvA-HPSL"
|
||||
},
|
||||
"source": [
|
||||
"Let's compute and show a few more steps of the simulation. Because of the inflow being located off-center to the left (with x position 30), the plume will curve towards the right when it hits the top wall of the domain."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 489
|
||||
},
|
||||
"id": "tkhCOzc0ITsj",
|
||||
"outputId": "f6366c12-1eb5-4ff6-e0d7-94b806bfd8e4"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Computing time step 0\n",
|
||||
"Computing time step 1\n",
|
||||
"Computing time step 2\n",
|
||||
"Computing time step 10\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1152x360 with 5 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"steps = [smoke.values.numpy('y,x')]\n",
|
||||
"for time_step in range(20):\n",
|
||||
" if time_step<3 or time_step%10==0: \n",
|
||||
" print('Computing time step %d' % time_step)\n",
|
||||
" velocity, smoke, pressure = step(velocity, smoke, pressure, dt=DT)\n",
|
||||
" if time_step%5==0:\n",
|
||||
" steps.append(smoke.values.numpy('y,x'))\n",
|
||||
"\n",
|
||||
"fig, axes = pylab.subplots(1, len(steps), figsize=(16, 5))\n",
|
||||
"for i in range(len(steps)):\n",
|
||||
" axes[i].imshow(steps[i], origin='lower', cmap='magma')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ooqVxCPM8PXl"
|
||||
},
|
||||
"source": [
|
||||
"It looks simple here, but this simulation setup is a powerful tool. The simulation could easily be extended to more complex cases or 3D, and they're fully compatible with back-propagation pipelines of deep learning frameworks. \n",
|
||||
"\n",
|
||||
"In the next chapters we'll show how to use these simulations for training NNs, and how to steer and modify them via trained NNs. This will illustrate how much we can improve the training process by having a solver in the loop, and especially by having differentiable solvers."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "BL-AOqwMJmkq"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"collapsed_sections": [],
|
||||
"name": "Forw Simulations with Φ-Flow.ipynb",
|
||||
"provenance": []
|
||||
},
|
||||
"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.8.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 1
|
||||
}
|
||||
+227
-103
@@ -6,9 +6,21 @@
|
||||
"id": "o4JZ84moBKMr"
|
||||
},
|
||||
"source": [
|
||||
"# Navier-Stokes Forward Simulation with Φ<sub>Flow</sub>\n",
|
||||
"# Navier-Stokes Forward Simulation\n",
|
||||
"\n",
|
||||
"... now a more complex example with fluid simulations (Navier-Stokes) ... still very simple with phiflow (complexity of the differentiable operators hidden).\n",
|
||||
"Now let's target a somewhat more complex example: a fluid simulations based on the Navier-Stokes equations. This is still very simple with Φ<sub>Flow</sub>, as differentiable operators for all steps exist. The Navier-Stokes equations (in their incompressible form) introduce an additional pressure field $p$, and a constraint for conservation of mass. We're also moving a marker quantity $d$ with the flow, that indicates regions of higher temperature with a bouyance model via the parameter $\\xi$:\n",
|
||||
"\n",
|
||||
"$\\begin{aligned}\n",
|
||||
" \\frac{\\partial \\mathbf{u}}{\\partial{t}} + \\mathbf{u} \\cdot \\nabla \\mathbf{u} &= - \\frac{\\Delta t}{\\rho} \\nabla p + \\nu \\nabla\\cdot \\nabla \\mathbf{u} + (0,1)^T \\xi d\n",
|
||||
" \\quad \\text{s.t.} \\quad \\nabla \\cdot \\mathbf{u} = 0,\n",
|
||||
" \\\\\n",
|
||||
" \\frac{\\partial d}{\\partial{t}} + \\mathbf{u} \\cdot \\nabla d &= 0 \n",
|
||||
"\\end{aligned}$\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Here $\\mathbf{g}$ collects the forcing terms. Below we'll use a simple buoyancy model. We'll solve this PDE on a closed domain with Dirchlet boundary conditions $\\mathbf{u}=0$ for the velocity, and Neumann boundaries $\\frac{\\partial p}{\\partial x}=0$ for pressure, on a domain $\\Omega$ with a physical size of $100 \\times 80$ units. \n",
|
||||
"\n",
|
||||
"## Implementation\n",
|
||||
"\n",
|
||||
"As before, the first command with a \"!\" prefix installs the [Φ<sub>Flow</sub> Python package from GitHub](https://github.com/tum-pbs/PhiFlow) via `pip` in your python environment. (Skip or modify this command if necessary.)"
|
||||
]
|
||||
@@ -28,17 +40,16 @@
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/home/thuerey/anaconda3/envs/tf/lib/python3.8/_collections_abc.py:743: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
|
||||
"/Users/thuerey/miniconda3/envs/tf/lib/python3.8/_collections_abc.py:743: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
|
||||
" for key in self._mapping:\n",
|
||||
"/home/thuerey/anaconda3/envs/tf/lib/python3.8/_collections_abc.py:744: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
|
||||
" yield (key, self._mapping[key])\n",
|
||||
"/home/thuerey/phiflow/phi/viz/display.py:80: UserWarning: GUI is disabled because of missing dependencies: No module named 'imageio'. To install all dependencies, run $ pip install phiflow[gui]\n",
|
||||
" warnings.warn('GUI is disabled because of missing dependencies: %s. To install all dependencies, run $ pip install phiflow[gui]' % import_error)\n"
|
||||
"/Users/thuerey/miniconda3/envs/tf/lib/python3.8/_collections_abc.py:744: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
|
||||
" yield (key, self._mapping[key])\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!pip install --upgrade --quiet phiflow\n",
|
||||
"#!pip install --upgrade --quiet git+https://github.com/tum-pbs/PhiFlow@develop\n",
|
||||
"#!pip install --upgrade --quiet phiflow \n",
|
||||
"from phi.flow import * # The Dash GUI is not supported on Google Colab, ignore the warning\n",
|
||||
"import pylab"
|
||||
]
|
||||
@@ -51,9 +62,10 @@
|
||||
"source": [
|
||||
"## Setting up the simulation\n",
|
||||
"\n",
|
||||
"Φ<sub>Flow</sub> is object-oriented, i.e. you assemble your simulation by constructing a number of objects and adding them to the world.\n",
|
||||
"Φ<sub>Flow</sub> is object-oriented and centered around field data in the form of grids (internally represented by a tensor object). I.e. you assemble your simulation by constructing a number of grids, and updating them over the course of time steps.\n",
|
||||
"\n",
|
||||
"The following code sets up four fluid simulations that run in parallel (`batch_size=4`). Each fluid simulation has a circular Inflow at a different location."
|
||||
"The following code sets up a simulation domain with the physical size, an inflow object to emit a smoke density, and three field: a staggerend `velocity` grid, and two centered grids for the smoke density and a pressure field. We'll use $40\\times32$ cells to discretize our domain, introduce a slight viscosity via $\\nu$, and define the time step to be $\\Delta t=1.5$. \n",
|
||||
"(As the following variables are constants, they have upper case names.)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -64,9 +76,11 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"world = World()\n",
|
||||
"fluid = world.add(Fluid(Domain([40, 32], boundaries=CLOSED), buoyancy_factor=0.05), physics=IncompressibleFlow())\n",
|
||||
"world.add(Inflow(Sphere(center=[5,14], radius=3), rate=0.2));"
|
||||
"DOMAIN = Domain(x=40, y=32, boundaries=CLOSED, bounds=Box[0:100, 0:80])\n",
|
||||
"INFLOW = DOMAIN.grid(Sphere(center=(30, 15), radius=10)) * 0.2\n",
|
||||
"\n",
|
||||
"DT = 1.5\n",
|
||||
"NU = 0.01"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -75,14 +89,37 @@
|
||||
"id": "ExA0Pi2sFVka"
|
||||
},
|
||||
"source": [
|
||||
"The inflow affects the fluid's marker density. Because a Boussinesq model with a positive `buoyancy_factor` is active, the marker field `density` creates an upward force. Note that this density is not the density of the fluid, but the amount of marker quantity present in each cell.\n",
|
||||
"The inflow will be used to inject smoke into the `smoke` grid to represent the marker field $d$ from above. Note that we've defined a `Box` of size $100x80$ above. This is the physical scale in terms of spatial units in our simulation, i.e., a velocity of magnitude $1$ will move the smoke density by 1 unit per 1 time unit, which may be larger or smaller than a cell in the discretized grid, depending on the settings for `x,y`. You could parametrize your simulation grid to directly resemble real-world units, or keep conversion factors in mind for conversion. \n",
|
||||
"\n",
|
||||
"Let's plot the marker density after one simulation frame."
|
||||
"The inflow sphere above is already using the \"world\" coordinates: it is located at $x=30$ along the first axis, and $y=15$ (within the $100x80$ domain box).\n",
|
||||
"\n",
|
||||
"Next, we create grids for the quantities we want to simulate. For this example, we require a velocity field and a smoke density field.\n",
|
||||
"We sample the smoke field at the cell centers and the velocity in [staggered form](https://tum-pbs.github.io/PhiFlow/Staggered_Grids.html)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# velocity = domain.staggered_grid(0) # alternatively vector_grid(0)\n",
|
||||
"# smoke = pressure = divergence = domain.grid(0)\n",
|
||||
"\n",
|
||||
"smoke = DOMAIN.scalar_grid(0) # sampled at cell centers\n",
|
||||
"velocity = DOMAIN.staggered_grid(0) # sampled in staggered form at face centers "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let's define the update step, and plot the marker density after one simulation frame."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
@@ -92,19 +129,26 @@
|
||||
"outputId": "3ae4d68d-b586-4bbe-eca9-a223d7720949"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Max. velocity and mean density: [0.135354, 0.007865495]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<matplotlib.image.AxesImage at 0x7f9cf945eee0>"
|
||||
"<matplotlib.image.AxesImage at 0x7f9317729df0>"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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\n",
|
||||
"image/png": "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\n",
|
||||
"text/plain": [
|
||||
"<Figure size 432x288 with 1 Axes>"
|
||||
]
|
||||
@@ -116,61 +160,113 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"world.step()\n",
|
||||
"pylab.imshow(fluid.density.data[0,...,0], origin='lower', cmap='magma')"
|
||||
"def step(velocity, smoke, pressure, dt=1.0, buoyancy_factor=1.0):\n",
|
||||
" smoke = advect.semi_lagrangian(smoke, velocity, dt) + INFLOW\n",
|
||||
" buoyancy_force = smoke * (0, buoyancy_factor) >> velocity # resamples smoke to velocity sample points\n",
|
||||
" velocity = advect.semi_lagrangian(velocity, velocity, 1) + dt * buoyancy_force\n",
|
||||
" velocity = diffuse.explicit(velocity, NU, dt)\n",
|
||||
" velocity, pressure, iterations, divergence = fluid.make_incompressible(velocity, DOMAIN, pressure_guess=pressure)\n",
|
||||
" return velocity, smoke, pressure\n",
|
||||
"\n",
|
||||
"velocity, smoke, pressure = step(velocity, smoke, None, dt=DT)\n",
|
||||
"\n",
|
||||
"print(\"Max. velocity and mean density: \" + format( [ math.max(velocity.values) , math.mean(smoke.values) ] ))\n",
|
||||
"\n",
|
||||
"pylab.imshow(np.asarray(smoke.values.numpy('y,x')), origin='lower', cmap='magma')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"A lot has happened internally in the `world.step()` call, e.g., for fluids we have a more complex `struct` object that stores the different fields of the simulation. For fluids we have the aforementioned marker density in addition to a velocity."
|
||||
"A lot has happened in this `step()` call: we've advected the smoke field, added an upwards force via a Boussinesq model, advected the velocity field, and finally made it divergence free via a pressure solve.\n",
|
||||
"\n",
|
||||
"The Boussinesq model uses a multiplication by a tuple `(0, buoyancy_factor)` to turn the smoke field into a 2 component force field, sampled at the staggered velocity components via the `>>` operator. \n",
|
||||
"\n",
|
||||
"The pressure projection step in `make_incompressible` is typically the computationally most expensive step in the sequence above. It solves a Poisson equation for the boundary conditions of the domain, and updates the velocity field with the gradient of the computed pressure.\n",
|
||||
"\n",
|
||||
"Just for testing, we've also printed the mean value of the velocities, and the max density after the update. As you can see in the resulting image, we have a first round region of smoke, with a slight upwards motion (which does not show here yet). \n",
|
||||
"\n",
|
||||
"## Datatypes and Dimensions\n",
|
||||
"\n",
|
||||
"The created grids are instances of the class `Grid`.\n",
|
||||
"Like tensors, grids also have the `shape` attribute which lists all batch, spatial and channel dimensions.\n",
|
||||
"[Shapes in Φ<sub>Flow</sub>](https://tum-pbs.github.io/PhiFlow/Math.html#shapes) store not only the sizes of the dimensions but also their names and types."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Fluid state: Fluid[density: Grid[40x32(1), size=[40. 32.], float32], velocity: StaggeredGrid[40x32, size=[40. 32.], float32]]\n",
|
||||
"\n",
|
||||
" Velocity content:\n",
|
||||
"(1, 41, 32, 1)\n",
|
||||
"(1, 40, 33, 1)\n"
|
||||
"Smoke: (x=40, y=32)\n",
|
||||
"Velocity: (x=40, y=32, vector=2)\n",
|
||||
"Inflow: (x=40, y=32)\n",
|
||||
"Inflow, spatial only: (x=40, y=32)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(\"Fluid state: \" + format(fluid.state))\n",
|
||||
"print(\"\\nVelocity content:\")\n",
|
||||
"[print(grid.data.shape) for grid in fluid.velocity.unstack()];"
|
||||
"print(f\"Smoke: {smoke.shape}\")\n",
|
||||
"print(f\"Velocity: {velocity.shape}\")\n",
|
||||
"print(f\"Inflow: {INFLOW.shape}\")\n",
|
||||
"print(f\"Inflow, spatial only: {INFLOW.shape.spatial}\")\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Note that we actually created two variables, one for each velocity component. If you're interested in how this works, have a look at the [Struct documentation](https://github.com/tum-pbs/PhiFlow/blob/master/documentation/Structs.ipynb).\n",
|
||||
"\n",
|
||||
"If you look closely at the output from the last `print` command, you'll notice that the shapes of the variables differ. This is because the velocity is sampled in [staggered form](https://github.com/tum-pbs/PhiFlow/blob/master/documentation/Staggered_Grids.md).\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "PA-2tGuWGHv2"
|
||||
},
|
||||
"source": [
|
||||
"We can run more steps by repeatedly calling `world.step()`."
|
||||
"The grid values can be accessed using the `values` property."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"(x=40, y=32) float32 0.0 < ... < 0.2\n",
|
||||
"(x=(41, 40) along vector, y=(32, 33) along vector, vector=2) float32 -0.10927753 < ... < 0.135354\n",
|
||||
"(x=40, y=32) float32 0.0 < ... < 0.2\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(smoke.values)\n",
|
||||
"print(velocity.values)\n",
|
||||
"print(INFLOW.values)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Grids have many more properties which are documented [here](https://tum-pbs.github.io/PhiFlow/phi/field/#phi.field.Grid).\n",
|
||||
"Also note that the staggered grid has a [non-uniform shape](https://tum-pbs.github.io/PhiFlow/Math.html#non-uniform-tensors) because the number of faces is not equal to the number of cells. The `INFLOW` grid naturally has the same dimensions as the `smoke` grid.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Time Evolution\n",
|
||||
"\n",
|
||||
"With this setup, we can easily advance the simulation forward in time a bit more by repeatedly calling the `step` function."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
@@ -183,23 +279,23 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Computing frame 0\n",
|
||||
"Computing frame 1\n",
|
||||
"Computing frame 2\n",
|
||||
"Computing frame 3\n",
|
||||
"Computing frame 4\n",
|
||||
"Computing frame 5\n",
|
||||
"Computing frame 6\n",
|
||||
"Computing frame 7\n",
|
||||
"Computing frame 8\n",
|
||||
"Computing frame 9\n"
|
||||
"Computed frame 0, max velocity 0.40485728\n",
|
||||
"Computed frame 1, max velocity 0.80262446\n",
|
||||
"Computed frame 2, max velocity 1.3215623\n",
|
||||
"Computed frame 3, max velocity 1.99783\n",
|
||||
"Computed frame 4, max velocity 2.8307805\n",
|
||||
"Computed frame 5, max velocity 3.756278\n",
|
||||
"Computed frame 6, max velocity 4.5489845\n",
|
||||
"Computed frame 7, max velocity 5.147038\n",
|
||||
"Computed frame 8, max velocity 5.5985193\n",
|
||||
"Computed frame 9, max velocity 6.0121617\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for frame in range(10):\n",
|
||||
" print('Computing frame %d' % frame)\n",
|
||||
" world.step(dt=1.5)"
|
||||
"for time_step in range(10):\n",
|
||||
" velocity, smoke, pressure = step(velocity, smoke, pressure, dt=DT)\n",
|
||||
" print('Computed frame {}, max velocity {}'.format(time_step , np.asarray(math.max(velocity.values)) ))\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -213,7 +309,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": 8,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
@@ -226,16 +322,16 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<matplotlib.image.AxesImage at 0x7fa84d3553d0>"
|
||||
"<matplotlib.image.AxesImage at 0x7f93181c4b80>"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 432x288 with 1 Axes>"
|
||||
]
|
||||
@@ -247,7 +343,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"pylab.imshow(fluid.density.data[0,...,0], origin='lower', cmap='magma')"
|
||||
"pylab.imshow(smoke.values.numpy('y,x'), origin='lower', cmap='magma')"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -256,12 +352,12 @@
|
||||
"id": "wnbQJvA-HPSL"
|
||||
},
|
||||
"source": [
|
||||
"Let's compute and show a few more steps of the simulation."
|
||||
"Let's compute and show a few more steps of the simulation. Because of the inflow being located off-center to the left (with x position 30), the plume will curve towards the right when it hits the top wall of the domain."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 9,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
@@ -275,43 +371,17 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Computing frame 0\n",
|
||||
"Computing frame 1\n",
|
||||
"Computing frame 2\n",
|
||||
"Computing frame 3\n",
|
||||
"Computing frame 4\n",
|
||||
"Computing frame 5\n",
|
||||
"Computing frame 6\n",
|
||||
"Computing frame 7\n",
|
||||
"Computing frame 8\n",
|
||||
"Computing frame 9\n",
|
||||
"Computing frame 10\n",
|
||||
"Computing frame 11\n",
|
||||
"Computing frame 12\n",
|
||||
"Computing frame 13\n",
|
||||
"Computing frame 14\n",
|
||||
"Computing frame 15\n",
|
||||
"Computing frame 16\n",
|
||||
"Computing frame 17\n",
|
||||
"Computing frame 18\n",
|
||||
"Computing frame 19\n"
|
||||
"Computing time step 0\n",
|
||||
"Computing time step 1\n",
|
||||
"Computing time step 2\n",
|
||||
"Computing time step 10\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<matplotlib.image.AxesImage at 0x7fa84d2d8790>"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 432x288 with 1 Axes>"
|
||||
"<Figure size 1152x360 with 5 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
@@ -321,14 +391,68 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"frames = [fluid.density.data[0,...,0]]\n",
|
||||
"for frame in range(20):\n",
|
||||
" print('Computing frame %d' % frame)\n",
|
||||
" world.step(dt=1.5)\n",
|
||||
" if frame%5==0:\n",
|
||||
" frames.append(fluid.density.data[0,...,0])\n",
|
||||
"steps = [[ smoke.values, velocity.values.vector[0], velocity.values.vector[1] ]]\n",
|
||||
"for time_step in range(20):\n",
|
||||
" if time_step<3 or time_step%10==0: \n",
|
||||
" print('Computing time step %d' % time_step)\n",
|
||||
" velocity, smoke, pressure = step(velocity, smoke, pressure, dt=DT)\n",
|
||||
" if time_step%5==0:\n",
|
||||
" steps.append( [smoke.values, velocity.values.vector[0], velocity.values.vector[1]] )\n",
|
||||
"\n",
|
||||
"pylab.imshow(np.concatenate(frames,axis=1), origin='lower', cmap='magma')"
|
||||
"fig, axes = pylab.subplots(1, len(steps), figsize=(16, 5))\n",
|
||||
"for i in range(len(steps)):\n",
|
||||
" axes[i].imshow(steps[i][0].numpy('y,x'), origin='lower', cmap='magma')\n",
|
||||
" axes[i].set_title(f\"d at t={i*5}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We can also take a look at the velocities. The `steps` list above already stores `vector[0]` and `vector[1]` components of the velocities as numpy arrays, which we can show next."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1152x360 with 5 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA54AAACuCAYAAABeHdLXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Il7ecAAAACXBIWXMAAAsTAAALEwEAmpwYAABIUUlEQVR4nO29e6xt213f9/2t536cxz7n3uP7tH1t2Sa9RMGOLDAKpATiyhBFSIlbFRLkpi6mSmgd1RJxkiaQlqgkVNBEJBVuIXZaJ5AKhJ2IBLmWKYFS4AZM4ge2r238uK/z3Gc/13OO/rGX7xy/79xrjj33euy51vl+pKOzx5qvMef8jjHnXGt859dCCBBCCCGEEEIIIRZF46IrIIQQQgghhBBivdGDpxBCCCGEEEKIhaIHTyGEEEIIIYQQC0UPnkIIIYQQQgghFooePIUQQgghhBBCLBQ9eAohhBBCCCGEWCh68BRCCCGEEEIIsVD04LkCmNmvmtl/VTL9KTMLZtY65/q/18y+ZGaHZvZLZnb9/LUVojqL1LiZfZuZZWZ2EP17x2w1FqKcBWv6MTP7sJk9P1nHUzS9a2Y/a2Z7Zvaimf1359gFIUq5YI2/38wG1K83z7EbQpzKgvX9Z8zs181sd9JH/+9mdjmavrZ9uB48H3DM7OsB/DSA7wPwCIAjAP/4QislxPx5PoRwKfr3gYuukBAzkAH4NwD+/JTpPwLg9QBeDeBPAfghM3vbcqomxFxIaRwA/j716+Ml1U2IWbkK4EcBPA7gPwLwBIAfj6b/CNa0D9eD5xmYfKPxuqj8fjP70cQynzCzPxuV22Z228zedMq818zsX5nZLTO7N/n7ycm0vwvgWwH81OQbvZ86ZXO/Nvl/dzLPN1fYvb8A4F+GEH4thHAA4G8B+HPxNy9i/VlzjYsHkHXWdAjhpRDCPwbwO1NmeQeA/zGEcC+E8GkA/xuA/+Ks6xerwQOucbHmrLm+/1kI4d+EEI5CCPdw0kf/iWiWte3D9eC5OP4pgL8Ylb8LwAshhN87Zd4GgH+Ck282XgXgGMBPAUAI4W8C+LcAfnDyjd4PnrL8n5z8vzOZ5zfN7FsmP+FP+/ctk2W+HsDvf21FIYTPAxgAeMO591w8KKyKxgHgFWb2kpl90cx+0sy2Z9t1saaskqZPxcyuAXgMUb8++fvrU8uKB4KV13jEXzazu2b278ys7JdR8eCwqvr+kwA+Cax/H34uT6A4E/8ngL9lZldCCHs4Gcr6f5w2YwjhDoBf+Fp58k3Lx2bZeAjh1wHsnGHWSwDu02f3AegXT5FiVTT+BwDeOPn/1QA+AOAnAPzALNsXa8mqaLqMS5P/435dfbr4GuugcQD4hwDegxNt/ycAft7MXgwh/MYc1i1Wl5XTt5m9FSe/cH7T5KO17sP1i+eCCCE8D+A3APx5M9sB8J0APnjavGa2ZWY/bScv+NnDyc/3O7Yco/wBgCv02RUA+0vYtlhhVkXjIYQXQwifCiFkIYQvAvghlPuGxAPKqmg6wcHk/7hfV58uAKyNxhFC+N0Qwp0QwiiE8Ms42Yc/d9H1EhfLqunbzN4C4J8BeHsI4bOTj9e6D9eD59k4ArAVlR8943IfwMlP/v8pgN8MITw3Zb73APg6AN8UQriC/Od7m/wfEtspTDezbzX/tjf+962TWT8J4Bui5V4LoAvgs7xOsdass8ZPW5f6vvXnQdJ0vtITv9ALiPr1yd+fTC0rVo4HUuMl27LkXGKVWGt924nv9MMA/ssQwkdfXuma9+Eaans2Pg7ge83skwDeCuA/BvDMGZb7JZy8IfYRAH+/ZL7LOBlbvmsnUSY/TNNfAvDakuVv4eQNcK/F5IExhPBvkf9cX8YHAfzmpDH8LoD/AcAvhhDW4psVcWY+jjXVuJn9KQBfAPBlAE8C+DEAH0otJ1aej2NNNQ0AZrYB4GvfzHfNbCOE0JuU/ymA/97Mnpnsx/cD+EtnWa9YKT6OB1TjZvZ2nLz19gjAn8bJg8afPXVFYlX5ONZU32b2R3Gi3/8mhPAvT5llbftwfet/Nt6Nkw5tFydvgf2lsywUQjjGyfjx1wD4xZJZ/xcAmwBuA/j/cCLGmH8A4O128tatf3jKdo4A/F0AvzExL7/lLPWbLPtJAP81Th5Ab+KkIf7lsy4v1oa11TiANwH4fwEcTv7/DwD+2wrLi9VknTUNnNwwfW1I1h9Myl/jhwF8HsCXAPw/AH48hMD1E6vPg6zxdwN4Dif7/uMAvj+E8KsV1y/qzTrr+z0AbgD4mejX0PgXzbXtwy2E1C/JYhbM7G8DeEMI4S8mZxZiBZHGxbohTYt1RxoX64z0XV801HaBTH66fydO3qolxNohjYt1Q5oW6440LtYZ6bveaKjtDJjZ35hiHv7XZvb9AL4C4F+HEH4ttS4h6og0LtYNaVqsO9K4WGek79VGQ22FEEIIIYQQQiwU/eIphBBCCCGEEGKh6MFTCCGEEEIIIcRCWerLhTab2+Fqa2eZmxQPIC8Nnr8dQrhxEdvebG6HK9K4WCB7o10cjw8vJCh9S324WAIvXmAfvt3cDjvtnYvYtHiAeL5/gRpvbYdr0rhYMM/1Ttf4Uh88r7Z28H2P/8AyNykeQP7nP/zhL13Utq+0dvAXHpPGxeL44As/fWHbvtrawV96UvoWi+V/+sLF9eE77R38wKukcbFYfvhzF6fxa+0dvPspaVwslh/6g9M1rqG2QgghhBBCCCEWih48hRBCCCGEEEIslKUOtQWAsvQWuxDXUpFGxXpkS0ykUfrNg8uqfkuULXLdag9LJQAYl/XhJcum+lWenJq/Sj/Ns1aVTayzlOZS6551ebFYsgD0xtOnV9F4s2K51eDpYeq8hW1TOdXvsg7HId8Aa3CU8by+zPPz9DLNL7IPr3ovV7f1L4pRBtzun2/ZDgltm54itpr+hHYavtym5buNWON+3lS/Xabhk7KfPoymjxLz8r02t6eUbuO6FOqRaE9l11igXHdVr6MpCS9C46t6LyuEEEIIIYQQYkVIPnia2YaZ/baZ/b6ZfdLM/s7k89eY2W+Z2bNm9vNm1ll8dYWYP9K4WGekb7HuSONi3ZHGxbpwll88+wC+PYTwDQDeCOBtZvYWAH8PwE+GEF4H4B6Ady6slkIsFmlcrDPSt1h3pHGx7kjjYi1IejxDCAHAwaTYnvwLAL4dwPdOPv8AgB8B8L/OUhkeUz2L53OWcclVF51lWxfpUVuk926VmLfG43M6izZS3wots31U0Sm346reo1m2neJB9M8tUt8pYp3xcqzBVJk9bnFx3j6UgneoZFs8b9F35MuzeEAv0uNfl3cwnMY8NZ4BOBrl5YIuaf74uBR8mAXPpi+X+d0AYCPyy7XZ/5aoF/ezrB32uA2j6ezp7NNdUaDp7Fmr4gmd9z2QO1+Jdc/qb0t58ebJPDU+ygJuHecnKbUbsW53yOR5ue3nZU8nez4vt72B+nIrb2wbTT+Nj/84Y836uvTHvtzLqBxN79O6BrxuKhcOUuI60IjaK69rQO3jeOTLwwq6TV0nq1xHT6OsDZz3unsmj6eZNc3s4wBuAvgIgM8D2A0hfO1wfRXAE1OWfZeZPWNmzxyND89XSyEWzLw0fiyNixqiPlysO+rDxbozL433sqOl1FeI0zjTg2cIYRxCeCOAJwF8I4A/ctYNhBDeF0J4cwjhzVvN7fPVUogFMy+Nb0rjooaoDxfrjvpwse7MS+Mbja1FVVGIJJXeahtC2AXwMQDfDGDHzL42VPdJAM/Nt2pCLB9pXKwz0rdYd6Rxse5I42KVSXo8zewGgGEIYdfMNgG8FSdm5o8BeDuAnwPwDgAfWmRFU8ySVTOrP6iS/y2x7Xn6HdY1P3Hex2yRGk/VrVIW4Qy5hrPas9gXULZbKW/RrJ7Ps9ZjVrIZDXWNmpji5qnvVI5n2blNeUtmyUAs+lrKz11G/rZUPlxsW0r5uqr2R+OSBlA1i3EWkn1RjQ3Sc9V4COiXnGRu1u3owLUT/iqGcws32Q/XyqJpXg28bLHf9RsfFbIEfWuNPW492kleN3vWCrmfFXIL593PVrnXm/U9CsvM8Zynxkch4HZ/OHU6n5ONZvPlv6+QxzN1CNjzGXs6AeDGZi9fd/Q3UOzHx6zZUdOVjwbecHo49OX9Uf7Iszf0jz8FDzS3gYpZm3yNKVtXj1Z2SA2I54+vd20SYTPhK2/SflX1iMacV/7JB08AjwH4gJk1cdJO/0UI4V+Z2acA/JyZ/SiA3wPwM+esgxAXjTQu1hnpW6w70rhYd6RxsRac5a22/x7Am075/As4GWMuxEojjYt1RvoW6440LtYdaVysC2f5xbOWVB1ae5HDEOOfyXlb8x69VDY06yKHx86Tuu9HXL1FjsRhTS9S86mhiGXbTQ29ZVLnt3SY70XmTRCLqku4wH0MIWAYnSAe5sbnOr7AlIw8AlDUZCp6ohUNw2olhgsxGamIDym/zr4RVT7zb/xPwmeLh9byMYv1n45eOb8W+NzNGg1Rj4HlszMOwGGUB2IoH5o2inQ5Lozd9DNv+JGB6NL88dBaALjWyYdDblHURLNRPhxvzHEphaG1vnwcVb5JO5JRbMWADsIhx0GQqHkoYdwGqsqueJ2bHjNTFn1zsmximG4iAirerUovTLlgRshwOzuYOj2jXuna+NLLfzfgh6+m+o0uDRHf6Qxc+cbVvB5XbvRL1zUekqaPfIM6POy4cvNo05XjmvQL7YEaJ5FqXxwhFJPSOMer7A99Wx9TP9+2vO481LZDF7/UdbRggUkMzY1ZaJyKEEIIIYQQQghxXvTgKYQQQgghhBBioejBUwghhBBCCCHEQlmqxzOg3IPIT8HxsObUa61T/rYq/rdCvSrGdxRexW/Tp6XqldxWhXqkqI87bn3gY8rnOz5HBc0mXmtdRfOF18inPHAJMZR5leftwS36S6dvoEYWz7Ul9rIY+auK3sr8A044SXkLine truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1152x360 with 5 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"needs_background": "light"
|
||||
},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"fig, axes = pylab.subplots(1, len(steps), figsize=(16, 5))\n",
|
||||
"for i in range(len(steps)):\n",
|
||||
" axes[i].imshow(steps[i][1].numpy('y,x'), origin='lower', cmap='magma')\n",
|
||||
" axes[i].set_title(f\"u_x at t={i*5}\")\n",
|
||||
" \n",
|
||||
"fig, axes = pylab.subplots(1, len(steps), figsize=(16, 5))\n",
|
||||
"for i in range(len(steps)):\n",
|
||||
" axes[i].imshow(steps[i][2].numpy('y,x'), origin='lower', cmap='magma')\n",
|
||||
" axes[i].set_title(f\"u_y at t={i*5}\")\n",
|
||||
" "
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -337,7 +461,7 @@
|
||||
"id": "ooqVxCPM8PXl"
|
||||
},
|
||||
"source": [
|
||||
"It looks simple here, but this is a powerful tool. The simulation could easily be extended to more complex cases or 3D, and they're fully compatible with back-propagation pipelines of deep learning frameworks. \n",
|
||||
"It looks simple here, but this simulation setup is a powerful tool. The simulation could easily be extended to more complex cases or 3D, and they're fully compatible with back-propagation pipelines of deep learning frameworks. \n",
|
||||
"\n",
|
||||
"In the next chapters we'll show how to use these simulations for training NNs, and how to steer and modify them via trained NNs. This will illustrate how much we can improve the training process by having a solver in the loop, and especially by having differentiable solvers."
|
||||
]
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
"source": [
|
||||
"# Burgers Optimization with a Physics-Informed NN\n",
|
||||
"\n",
|
||||
"Warning: this example still needs phiflow1.x and tensorflow 1.x! \n",
|
||||
"\n",
|
||||
"To illustrate how the physics-informed losses work, let's consider a \n",
|
||||
"reconstruction example with a simple yet non-linear equation in 1D:\n",
|
||||
"Burgers equation $\\frac{\\partial u}{\\partial{t}} + u \\nabla u = \\nu \\nabla \\cdot \\nabla u$\n",
|
||||
|
||||
Reference in new issue
Block a user