phiflow version updates, preparing for 2.2

This commit is contained in:
NT committed 2022-08-18 13:32:11 +02:00
1 parent f0032519e1
commit dc64cbf008
9 files changed
+537 -562

No files matched your search

+10 -10
View File
@@ -28,7 +28,7 @@
"metadata": {},
"outputs": [],
"source": [
"!pip install --upgrade --quiet phiflow\n",
"!pip install --upgrade --quiet phiflow==2.2\n",
"from phi.tf.flow import *\n",
"\n",
"N = 128\n",
@@ -38,11 +38,11 @@
"NU = 0.01/(N*np.pi)\n",
"\n",
"# allocate velocity grid\n",
"velocity = CenteredGrid(0, extrapolation.PERIODIC, x=N, bounds=Box[-1:1])\n",
"velocity = CenteredGrid(0, extrapolation.PERIODIC, x=N, bounds=Box(x=(-1,1)))\n",
"\n",
"# and a grid with the reference solution \n",
"REFERENCE_DATA = math.tensor([0.008612174447657694, 0.02584669669548606, 0.043136357266407785, 0.060491074685516746, 0.07793926183951633, 0.0954779141740818, 0.11311894389663882, 0.1308497114054023, 0.14867023658641343, 0.1665634396808965, 0.18452263429574314, 0.20253084411376132, 0.22057828799835133, 0.23865132431365316, 0.25673879161339097, 0.27483167307082423, 0.2929182325574904, 0.3109944766354339, 0.3290477753208284, 0.34707880794585116, 0.36507311960102307, 0.38303584302507954, 0.40094962955534186, 0.4188235294008765, 0.4366357052408043, 0.45439856841363885, 0.4720845505219581, 0.4897081943759776, 0.5072391070000235, 0.5247011051514834, 0.542067187709797, 0.5593576751669057, 0.5765465453632126, 0.5936507311857876, 0.6106452944663003, 0.6275435911624945, 0.6443221318186165, 0.6609900633731869, 0.67752574922899, 0.6939334022562877, 0.7101938106059631, 0.7263049537163667, 0.7422506131457406, 0.7580207366534812, 0.7736033721649875, 0.7889776974379873, 0.8041371279965555, 0.8190465276590387, 0.8337064887158392, 0.8480617965162781, 0.8621229412131242, 0.8758057344502199, 0.8891341984763013, 0.9019806505391214, 0.9143881632159129, 0.9261597966464793, 0.9373647624856912, 0.9476871303793314, 0.9572273019669029, 0.9654367940878237, 0.9724097482283165, 0.9767381835635638, 0.9669484658390122, 0.659083299684951, -0.659083180712816, -0.9669485121167052, -0.9767382069792288, -0.9724097635533602, -0.9654367970450167, -0.9572273263645859, -0.9476871280825523, -0.9373647681120841, -0.9261598056102645, -0.9143881718456056, -0.9019807055316369, -0.8891341634240081, -0.8758057205293912, -0.8621229450911845, -0.8480618138204272, -0.833706571569058, -0.8190466131476127, -0.8041372124868691, -0.7889777195422356, -0.7736033858767385, -0.758020740007683, -0.7422507481169578, -0.7263049162371344, -0.7101938950789042, -0.6939334061553678, -0.677525822052029, -0.6609901538934517, -0.6443222327338847, -0.6275436932970322, -0.6106454472814152, -0.5936507836778451, -0.5765466491708988, -0.5593578078967361, -0.5420672759411125, -0.5247011730988912, -0.5072391580614087, -0.4897082914472909, -0.47208460952428394, -0.4543985995006753, -0.4366355580500639, -0.41882350871539187, -0.40094955631843376, -0.38303594105786365, -0.36507302109186685, -0.3470786936847069, -0.3290476440540586, -0.31099441589505206, -0.2929180880304103, -0.27483158663081614, -0.2567388003912687, -0.2386513127155433, -0.22057831776499126, -0.20253089403524566, -0.18452269630486776, -0.1665634500729787, -0.14867027528284874, -0.13084990929476334, -0.1131191325854089, -0.09547794429803691, -0.07793928430794522, -0.06049114408297565, -0.0431364527809777, -0.025846763281087953, -0.00861212501518312] , math.spatial('x'))\n",
"SOLUTION_T16 = CenteredGrid( REFERENCE_DATA, extrapolation.PERIODIC, x=N, bounds=Box[-1:1])"
"SOLUTION_T16 = CenteredGrid( REFERENCE_DATA, extrapolation.PERIODIC, x=N, bounds=Box(x=(-1,1)))"
]
},
{
@@ -136,7 +136,7 @@
"outputs": [
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
@@ -237,7 +237,7 @@
"outputs": [
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
@@ -342,7 +342,7 @@
"outputs": [
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
@@ -376,7 +376,7 @@
"outputs": [
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
@@ -414,7 +414,7 @@
"outputs": [
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<Figure size 1152x360 with 2 Axes>"
]
@@ -475,7 +475,7 @@
},
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<Figure size 1152x360 with 2 Axes>"
]
@@ -527,7 +527,7 @@
},
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<Figure size 1152x360 with 2 Axes>"
]
+284 -287
View File
@@ -2,6 +2,9 @@
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "o4JZ84moBKMr"
},
"source": [
"# Differentiable Fluid Simulations\n",
"\n",
@@ -28,13 +31,13 @@
" \\frac{\\partial s}{\\partial{t}} + \\mathbf{u} \\cdot \\nabla s &= 0 \n",
"\\end{aligned}$$\n",
"\n"
],
"metadata": {
"id": "o4JZ84moBKMr"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "pwmMK-LW_trZ"
},
"source": [
"## Formulation\n",
"\n",
@@ -57,124 +60,141 @@
"Hence, the optimization can only change $\\mathbf{u}_0$ to align $y_{t_e,i}$ with the references $y^*_{t_e,i}$ as closely as possible.\n",
"\n",
"\n"
],
"metadata": {
"id": "pwmMK-LW_trZ"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "omVCYK5f_tra"
},
"source": [
"## Starting the Implementation\n",
"\n",
"First, let's get the loading of python modules out of the way. By importing `phi.torch.flow`, we get fluid simulation functions that work within pytorch graphs and can provide gradients (`phi.tf.flow` would be the alternative for tensorflow).\n",
"\n"
],
"metadata": {
"id": "omVCYK5f_tra"
}
]
},
{
"cell_type": "code",
"execution_count": 1,
"source": [
"!pip install --upgrade --quiet phiflow\n",
"from phi.torch.flow import * \n",
"import pylab # for visualizations later on\n"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": []
}
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "da1uZcDXdVcF",
"outputId": "66973d88-ec2c-4137-ed5b-1696848be36f"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": []
}
],
"source": [
"!pip install --upgrade --quiet phiflow==2.2\n",
"from phi.torch.flow import * \n",
"import pylab # for visualizations later on"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "rdSTbMoaS0Uz"
},
"source": [
"## Batched simulations\n",
"\n",
"Now we can set up the simulation, which will work in line with the previous \"regular\" simulation example from the {doc}`overview-ns-forw`. However, now we'll directly include an additional dimension, similar to a mini-batch used for NN training. For this, we'll introduce a named dimension called `inflow_loc`. This dimension will exist \"above\" the previous spatial dimensions `y`, `x` and the channel dimensions `vector`. As indicated by the name `inflow_loc`, the main differences for this dimension will lie in different locations of the inflow, in order to obtain different flow simulations. The named dimensions in phiflow make it very convenient to broadcast information across matching dimensions in different tensors.\n",
"\n",
"The `Domain` object is allocated just like before, but the `INFLOW_LOCATION` tensor now receives a string\n",
"`'inflow_loc,vector'` that indicates the names of the two dimensions. This leads to the creation of an `inflow_loc` dimensions in addition to the two spatial dimensions (the `vector` part).\n"
],
"metadata": {
"id": "rdSTbMoaS0Uz"
}
"Now we can set up the simulation, which will work in line with the previous \"regular\" simulation example from the {doc}`overview-ns-forw`. However, now we'll directly include an additional dimension, similar to a mini-batch used for NN training. For this, we'll introduce a named dimension called `inflow_loc`. This dimension will exist \"above\" the previous spatial dimensions `y`, `x` which are declared as dimensions for the `vector` channel. As indicated by the name `inflow_loc`, the main differences for this dimension will lie in different locations of the inflow, in order to obtain different flow simulations. The named dimensions in phiflow make it very convenient to broadcast information across matching dimensions in different tensors.\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"source": [
"# closed domain\n",
"INFLOW_LOCATION = tensor([(12, 4), (13, 6), (14, 5), (16, 5)], batch('inflow_loc'), channel('vector'))\n",
"INFLOW = (1./3.) * CenteredGrid(Sphere(center=INFLOW_LOCATION, radius=3), extrapolation.BOUNDARY, x=32, y=40, bounds=Box[0:32, 0:40])\n",
"BND = extrapolation.ZERO # closed, boundary conditions for velocity grid below\n",
"\n",
"# uncomment this for a slightly different open domain case\n",
"#INFLOW_LOCATION = tensor([(11, 6), (12, 4), (14, 5), (16, 5)], batch('inflow_loc'), channel('vector'))\n",
"#INFLOW = (1./4.) * CenteredGrid(Sphere(center=INFLOW_LOCATION, radius=3), extrapolation.BOUNDARY, x=32, y=40, bounds=Box[0:32, 0:40])\n",
"#BND = extrapolation.BOUNDARY # open boundaries \n",
"\n",
"INFLOW.shape"
],
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"(inflow_locᵇ=4, xˢ=32, yˢ=40)"
]
},
"metadata": {
"tags": []
},
"execution_count": 2
}
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "mphMP0sYIOz-",
"outputId": "0c3cea02-a1b2-4d88-e756-afbaef0544b0"
},
"outputs": [
{
"data": {
"text/plain": [
"(inflow_locᵇ=4, xˢ=32, yˢ=40)"
]
},
"execution_count": 2,
"metadata": {
"tags": []
},
"output_type": "execute_result"
}
],
"source": [
"# closed domain\n",
"INFLOW_LOCATION = tensor([(12, 4), (13, 6), (14, 5), (16, 5)], batch('inflow_loc'), channel(vector=\"x,y\"))\n",
"INFLOW = (1./3.) * CenteredGrid(Sphere(center=INFLOW_LOCATION, radius=3), extrapolation.BOUNDARY, x=32, y=40, bounds=Box(x=(0,32), y=(0,40)))\n",
"BND = extrapolation.ZERO # closed, boundary conditions for velocity grid below\n",
"\n",
"# uncomment this for a slightly different open domain case\n",
"#INFLOW_LOCATION = tensor([(11, 6), (12, 4), (14, 5), (16, 5)], batch('inflow_loc'), channel(vector=\"x,y\"))\n",
"#INFLOW = (1./4.) * CenteredGrid(Sphere(center=INFLOW_LOCATION, radius=3), extrapolation.BOUNDARY, x=32, y=40, bounds=Box(x=(0,32), y=(0,40)))\n",
"#BND = extrapolation.BOUNDARY # open boundaries \n",
"\n",
"INFLOW.shape"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VSisaefX_trh"
},
"source": [
"The last statement verifies that our `INFLOW` grid likewise has an `inflow_loc` dimension in addition to the spatial dimensions `x` and `y`. You can test for the existence of a tensor dimension in phiflow with the `.exists` boolean, which can be evaluated for any dimension name. E.g., above `INFLOW.inflow_loc.exists` will give `True`, while `INFLOW.some_unknown_dim.exists` will give `False`. The $^b$ superscript indicates that `inflow_loc` is a batch dimension.\n",
"\n",
"Phiflow tensors are automatically broadcast to new dimensions via their names, and hence typically no-reshaping operations are required. E.g., you can easily add or multiply tensors with differing dimensions. Below we'll multiply a staggered grid with a tensor of ones along the `inflow_loc` dimension to get a staggered velocity that has `x,y,inflow_loc` as dimensions via `StaggeredGrid(...) * math.ones(batch(inflow_loc=4))`."
],
"metadata": {
"id": "VSisaefX_trh"
}
]
},
{
"cell_type": "markdown",
"source": [
"We can easily simulate a few steps now starting with these different initial conditions. Thanks to the broadcasting, the exact same code we used for the single forward simulation in the overview chapter will produce four simulations with different smoke inflow positions."
],
"metadata": {
"id": "SDmFUYlI_tri"
}
},
"source": [
"We can easily simulate a few steps now starting with these different initial conditions. Thanks to the broadcasting, the exact same code we used for the single forward simulation in the overview chapter will produce four simulations with different smoke inflow positions."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 263
},
"id": "2PccI2r5_trj",
"outputId": "8dc97fa4-6c27-4406-e0c1-cdfb9c95b5e5"
},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 720x432 with 4 Axes>"
]
},
"metadata": {
"needs_background": "light",
"tags": []
},
"output_type": "display_data"
}
],
"source": [
"smoke = CenteredGrid(0, extrapolation.BOUNDARY, x=32, y=40, bounds=Box[0:32, 0:40]) # sampled at cell centers\n",
"velocity = StaggeredGrid(0, BND, x=32, y=40, bounds=Box[0:32, 0:40]) # sampled in staggered form at face centers \n",
"smoke = CenteredGrid(0, extrapolation.BOUNDARY, x=32, y=40, bounds=Box(x=(0,32), y=(0,40))) # sampled at cell centers\n",
"velocity = StaggeredGrid(0, BND, x=32, y=40, bounds=Box(x=(0,32), y=(0,40))) # sampled in staggered form at face centers \n",
"\n",
"def step(smoke, velocity):\n",
" smoke = advect.mac_cormack(smoke, velocity, dt=1) + INFLOW\n",
@@ -193,44 +213,24 @@
" axes[i].imshow(smoke_final.values.numpy('inflow_loc,y,x')[i,...], origin='lower', cmap='magma')\n",
" axes[i].set_title(f\"Inflow {INFLOW_LOCATION.numpy('inflow_loc,vector')[i]}\" + (\", Reference\" if i==3 else \"\"))\n",
"pylab.tight_layout()\n"
],
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 720x432 with 4 Axes>"
],
"image/png": "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 truncated
},
"metadata": {
"needs_background": "light",
"tags": []
}
}
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 263
},
"id": "2PccI2r5_trj",
"outputId": "8dc97fa4-6c27-4406-e0c1-cdfb9c95b5e5"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "V1tfVLqJ_trj"
},
"source": [
"The last image shows the state of the advected smoke fields after 20 simulation steps. The final smoke shape of simulation `[3]` with an inflow at `(16,5)`, with the straight plume on the far right, will be our **reference state** below. The initial velocity of the other three will be modified in the optimization procedure below to match this reference.\n",
"\n",
"(As a small side note: phiflow tensors will keep track of their chain of operations using the backend they were created for. E.g. a tensor created with NumPy will keep using NumPy/SciPy operations unless a PyTorch or TensorFlow tensor is also passed to the same operation. Thus, it is a good idea to verify that tensors are using the right backend once in a while, e.g., via `GRID.values.default_backend`.)\n"
],
"metadata": {
"id": "V1tfVLqJ_trj"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "vjIJq_Uz_trk"
},
"source": [
"## Gradients\n",
"\n",
@@ -245,17 +245,30 @@
"It is important that our initial velocity has the `inflow_loc` dimension before we record the gradients, such that we have the full \"mini-batch\" of four versions of our velocity (three of which will be updated via gradients in our optimization later on). To get the appropriate velocity tensor, we initialize a `StaggeredGrid` with a tensor of zeros along the `inflow_loc` batch dimension. As the staggered grid already has `y,x` and `vector` dimensions, this gives the desired four dimensions, as verified by the print statement below.\n",
"\n",
"Phiflow provides a unified API for gradients across different platforms by using functions that need to return a loss values, in addition to optional state values. It uses a loss function based interface, for which we define the `simulate` function below. `simulate` computes the $L^2$ error outlined above and returns the evolved `smoke` and `velocity` states after 20 simulation steps.\n"
],
"metadata": {
"id": "vjIJq_Uz_trk"
}
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "_j7fUGvQ_trl",
"outputId": "f06dea67-cc48-4af1-a963-46500f90d138"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Velocity dimensions: (inflow_locᵇ=4, xˢ=32, yˢ=40, vectorᵛ=2)\n"
]
}
],
"source": [
"initial_smoke = CenteredGrid(0, extrapolation.BOUNDARY, x=32, y=40, bounds=Box[0:32, 0:40])\n",
"initial_velocity = StaggeredGrid(math.zeros(batch(inflow_loc=4)), BND, x=32, y=40, bounds=Box[0:32, 0:40])\n",
"initial_smoke = CenteredGrid(0, extrapolation.BOUNDARY, x=32, y=40, bounds=Box(x=(0,32), y=(0,40)))\n",
"initial_velocity = StaggeredGrid(math.zeros(batch(inflow_loc=4)), BND, x=32, y=40, bounds=Box(x=(0,32), y=(0,40)))\n",
"print(\"Velocity dimensions: \"+format(initial_velocity.shape))\n",
"\n",
"def simulate(smoke: CenteredGrid, velocity: StaggeredGrid):\n",
@@ -267,97 +280,84 @@
" #loss = field.l2_loss(diffuse.explicit(smoke - field.stop_gradient(smoke.inflow_loc[-1]), 1, 1, 10))\n",
" \n",
" return loss, smoke, velocity\n"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Velocity dimensions: (inflow_locᵇ=4, xˢ=32, yˢ=40, vectorᵛ=2)\n"
]
}
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "_j7fUGvQ_trl",
"outputId": "f06dea67-cc48-4af1-a963-46500f90d138"
}
},
{
"cell_type": "markdown",
"metadata": {
"id": "pjqeVedM_trm"
},
"source": [
"Phiflow's `field.functional_gradient()` function is the central function to compute gradients. Next, we'll use it to obtain the gradient with respect to the initial velocity. Since the velocity is the second argument of the `simulate()` function, we pass `wrt=[1]`. (Phiflow also has a `field.spatial_gradient` function which instead computes derivatives of tensors along spatial dimensions, like `x,y`.)\n",
"\n",
"`functional_gradient` generates a gradient function. As a demonstration, the next cell evaluates the gradient once with the initial states for smoke and velocity. The last statement prints a summary of a part of the resulting gradient tensor.\n"
],
"metadata": {
"id": "pjqeVedM_trm"
}
]
},
{
"cell_type": "code",
"execution_count": 5,
"source": [
"sim_grad = field.functional_gradient(simulate, wrt=[1], get_output=False)\n",
"(velocity_grad,) = sim_grad(initial_smoke, initial_velocity)\n",
"\n",
"print(\"Some gradient info: \" + format(velocity_grad))\n",
"print(format(velocity_grad.values.inflow_loc[0].vector[0])) # one example, location 0, x component, automatically prints size & content range\n"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Some gradient info: StaggeredGrid[(inflow_locᵇ=4, xˢ=32, yˢ=40, vectorᵛ=2), size=(32, 40), extrapolation=0]\n",
"(xˢ=31, yˢ=40) float32 -17.366662979125977 < ... < 14.014090538024902\n"
]
}
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "grYi0l-g_trn",
"outputId": "93dae39b-1b31-429a-cf81-f615e23bbf7d"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Some gradient info: StaggeredGrid[(inflow_locᵇ=4, xˢ=32, yˢ=40, vectorᵛ=2), size=(32, 40), extrapolation=0]\n",
"(xˢ=31, yˢ=40) float32 -17.366662979125977 < ... < 14.014090538024902\n"
]
}
],
"source": [
"sim_grad = field.functional_gradient(simulate, wrt=[1], get_output=False)\n",
"(velocity_grad,) = sim_grad(initial_smoke, initial_velocity)\n",
"\n",
"print(\"Some gradient info: \" + format(velocity_grad))\n",
"print(format(velocity_grad.values.inflow_loc[0].vector[0])) # one example, location 0, x component, automatically prints size & content range\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "-drJBAe2_tro"
},
"source": [
"The last two lines just print some information about the resulting gradient field. Naturally, it has the same shape as the velocity itself: it's a staggered grid with four inflow locations. The last line shows how to access the x-components of one of the gradients.\n",
"\n",
"We could use this to take a look at the content of the computed gradient with regular plotting functions, e.g., by converting the x component of one of the simulations to a numpy array via `velocity_grad.values.inflow_loc[0].vector[0].numpy('y,x')`. However, below we'll use phiflow's `view()` function instead. It automatically analyzes the grid content and provides UI buttons to choose different viewing modes. You can use them to show arrows, single components of the 2-dimensional velocity vectors, or their magnitudes. (Because of its interactive nature, the corresponding image won't show up outside of Jupyter, though.)\n"
],
"metadata": {
"id": "-drJBAe2_tro"
}
"We could use this to take a look at the content of the computed gradient with regular plotting functions, e.g., by converting the x component of one of the simulations to a numpy array via `velocity_grad.values.inflow_loc[0].vector[0].numpy('y,x')`. An interactive alternative would be phiflow's `view()` function, which automatically analyzes the grid content and provides UI buttons to choose different viewing modes. You can use them to show arrows, single components of the 2-dimensional velocity vectors, or their magnitudes. Because of its interactive nature, the corresponding image won't show up outside of Jupyter, though, and hence we're showing the vector length below via `plot()` instead.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# neat phiflow helper function:\n",
"view(velocity_grad)\n"
],
"outputs": [],
"metadata": {
"id": "2LTHHjtZ_tro"
}
},
"outputs": [],
"source": [
"# neat phiflow helper function:\n",
"vis.plot(field.vec_length(velocity_grad)) # show magnitude"
]
},
{
"cell_type": "markdown",
"source": [
"Not surprisingly, the fourth gradient on the left is zero (it's already matching the reference). The other three gradients have detected variations for the initial round inflow positions shown as positive and negative regions around the circular shape of the inflow. The ones for the larger distances on the left are also noticeably larger."
],
"metadata": {
"id": "J7IgFG4o_trp"
}
},
"source": [
"Not surprisingly, the fourth gradient on the left is zero (it's already matching the reference). The other three gradients have detected variations for the initial round inflow positions shown as positive and negative regions around the circular shape of the inflow. The ones for the larger distances on the left are also noticeably larger."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3mpyowRYUSS4"
},
"source": [
"\n",
"\n",
@@ -370,27 +370,22 @@
"The following cell implements a simple steepest gradient descent optimization: it re-evaluates the gradient function, and iterates several times to optimize $\\mathbf{u}_0$ with a learning rate (step size) `LR`.\n",
"\n",
"`field.functional_gradient` has a parameter `get_output` that determines whether the original results of the function (`simulate()` in our case) are returned, or only the gradient. As it's interesting to track how the loss evolves over the course of the iterations, let's redefine the gradient function with `get_output=True`. \n"
],
"metadata": {
"id": "3mpyowRYUSS4"
}
]
},
{
"cell_type": "code",
"execution_count": 7,
"source": [
"sim_grad_wloss = field.functional_gradient(simulate, wrt=[1], get_output=True) # if we need outputs...\n",
"\n",
"LR = 1e-03 \n",
"for optim_step in range(80): \n",
" (loss, _smoke, _velocity), (velocity_grad,) = sim_grad_wloss(initial_smoke, initial_velocity)\n",
" initial_velocity = initial_velocity - LR * velocity_grad\n",
" if optim_step<3 or optim_step%10==9: print('Optimization step %d, loss: %f' % (optim_step, np.sum(loss.numpy()) ))\n"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "0U8h7_-b_trq",
"outputId": "11df5469-5c45-41b4-ba21-81114d2a3431"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"output_type": "stream",
"text": [
"Optimization step 0, loss: 1193.145020\n",
"Optimization step 1, loss: 1165.816650\n",
@@ -405,51 +400,30 @@
]
}
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "0U8h7_-b_trq",
"outputId": "11df5469-5c45-41b4-ba21-81114d2a3431"
}
"source": [
"sim_grad_wloss = field.functional_gradient(simulate, wrt=[1], get_output=True) # if we need outputs...\n",
"\n",
"LR = 1e-03 \n",
"for optim_step in range(80): \n",
" (loss, _smoke, _velocity), (velocity_grad,) = sim_grad_wloss(initial_smoke, initial_velocity)\n",
" initial_velocity = initial_velocity - LR * velocity_grad\n",
" if optim_step<3 or optim_step%10==9: print('Optimization step %d, loss: %f' % (optim_step, np.sum(loss.numpy()) ))\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "PI3xY-7m_trr"
},
"source": [
"The loss should have gone down significantly, from above 1100 to below 700, and now we can also visualize the initial velocities that were obtained in the optimization. \n",
"\n",
"The following images show the resulting three initial velocities in terms of their x (first set), and y components (second set of images). We're skipping the fourth set with `inflow_loc[0]` because it only contains zeros.\n"
],
"metadata": {
"id": "PI3xY-7m_trr"
}
]
},
{
"cell_type": "code",
"execution_count": 8,
"source": [
"fig, axes = pylab.subplots(1, 3, figsize=(10, 4))\n",
"for i in range(INFLOW.shape.get_size('inflow_loc')-1):\n",
" im = axes[i].imshow(initial_velocity.staggered_tensor().numpy('inflow_loc,y,x,vector')[i,...,0], origin='lower', cmap='magma')\n",
" axes[i].set_title(f\"Ini. vel. X {INFLOW_LOCATION.numpy('inflow_loc,vector')[i]}\")\n",
" pylab.colorbar(im,ax=axes[i])\n",
"pylab.tight_layout()\n"
],
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 720x288 with 6 Axes>"
],
"image/png": "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 truncated
},
"metadata": {
"needs_background": "light",
"tags": []
}
}
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
@@ -457,34 +431,34 @@
},
"id": "FdL_orrX_trr",
"outputId": "b716256c-9b8a-40d9-fc01-d75e261a728c"
}
},
{
"cell_type": "code",
"execution_count": 9,
"source": [
"fig, axes = pylab.subplots(1, 3, figsize=(10, 4))\n",
"for i in range(INFLOW.shape.get_size('inflow_loc')-1):\n",
" im = axes[i].imshow(initial_velocity.staggered_tensor().numpy('inflow_loc,y,x,vector')[i,...,1], origin='lower', cmap='magma')\n",
" axes[i].set_title(f\"Ini. vel. Y {INFLOW_LOCATION.numpy('inflow_loc,vector')[i]}\")\n",
" pylab.colorbar(im,ax=axes[i])\n",
"pylab.tight_layout()\n"
],
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 720x288 with 6 Axes>"
],
"image/png": "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 truncated
]
},
"metadata": {
"needs_background": "light",
"tags": []
}
},
"output_type": "display_data"
}
],
"source": [
"fig, axes = pylab.subplots(1, 3, figsize=(10, 4))\n",
"for i in range(INFLOW.shape.get_size('inflow_loc')-1):\n",
" im = axes[i].imshow(initial_velocity.staggered_tensor().numpy('inflow_loc,y,x,vector')[i,...,0], origin='lower', cmap='magma')\n",
" axes[i].set_title(f\"Ini. vel. X {INFLOW_LOCATION.numpy('inflow_loc,vector')[i]}\")\n",
" pylab.colorbar(im,ax=axes[i])\n",
"pylab.tight_layout()\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
@@ -492,24 +466,70 @@
},
"id": "mLhwxsZd_trs",
"outputId": "5bb43835-6e21-4d97-bb07-17b17215bbc8"
},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 720x288 with 6 Axes>"
]
},
"metadata": {
"needs_background": "light",
"tags": []
},
"output_type": "display_data"
}
],
"source": [
"fig, axes = pylab.subplots(1, 3, figsize=(10, 4))\n",
"for i in range(INFLOW.shape.get_size('inflow_loc')-1):\n",
" im = axes[i].imshow(initial_velocity.staggered_tensor().numpy('inflow_loc,y,x,vector')[i,...,1], origin='lower', cmap='magma')\n",
" axes[i].set_title(f\"Ini. vel. Y {INFLOW_LOCATION.numpy('inflow_loc,vector')[i]}\")\n",
" pylab.colorbar(im,ax=axes[i])\n",
"pylab.tight_layout()\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3mitRMPx_trt"
},
"source": [
"## Re-simulation\n",
"\n",
"We can also visualize how the full simulation over the course of 20 steps turns out, given the new initial velocity conditions for each of the inflow locations. This is what happened internally at optimization time for every gradient calculation, and what was measured by our loss function. Hence, it's good to get an intuition for which solutions the optimization has found.\n",
"\n",
"Below, we re-run the forward simulation with the new initial conditions from `initial_velocity`:\n"
],
"metadata": {
"id": "3mitRMPx_trt"
}
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 263
},
"id": "OINe99pf_trt",
"outputId": "a7c9ade3-3685-40e6-a5f1-97a5084deec9"
},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 720x432 with 4 Axes>"
]
},
"metadata": {
"needs_background": "light",
"tags": []
},
"output_type": "display_data"
}
],
"source": [
"smoke = initial_smoke \n",
"velocity = initial_velocity\n",
@@ -522,45 +542,45 @@
" axes[i].imshow(smoke_final.values.numpy('inflow_loc,y,x')[i,...], origin='lower', cmap='magma')\n",
" axes[i].set_title(f\"Inflow {INFLOW_LOCATION.numpy('inflow_loc,vector')[i]}\" + (\", Reference\" if i==3 else \"\"))\n",
"pylab.tight_layout()\n"
],
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 720x432 with 4 Axes>"
],
"image/png": "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 truncated
},
"metadata": {
"needs_background": "light",
"tags": []
}
}
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 263
},
"id": "OINe99pf_trt",
"outputId": "a7c9ade3-3685-40e6-a5f1-97a5084deec9"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ootUIrQq_tru"
},
"source": [
"Naturally, the image on the right is the same (this is the reference), and the other three simulations now exhibit a shift towards the right. As the differences are a bit subtle, let's visualize the difference between the target configuration and the different final states.\n",
"\n",
"The following images contain the difference between the evolved simulated and target density. Hence, dark regions indicate where the target should be, but isn't. The top row shows the original states with the initial velocity being zero, while the bottom row shows the versions after the optimization has tuned the initial velocities. Hence, in each column you can compare before (top) and after (bottom): \n"
],
"metadata": {
"id": "ootUIrQq_tru"
}
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 410
},
"id": "7lm9Rrel640-",
"outputId": "6ef7914a-8f63-49af-9a1a-fde1aed37682"
},
"outputs": [
{
"data": {
"image/png": "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 truncated
"text/plain": [
"<Figure size 720x432 with 12 Axes>"
]
},
"metadata": {
"needs_background": "light",
"tags": []
},
"output_type": "display_data"
}
],
"source": [
"fig, axes = pylab.subplots(2, 3, figsize=(10, 6))\n",
"for i in range(INFLOW.shape.get_size('inflow_loc')-1):\n",
@@ -571,44 +591,24 @@
" axes[1,i].imshow(smoke.values.numpy('inflow_loc,y,x')[i,...] - smoke_final.values.numpy('inflow_loc,y,x')[3,...], origin='lower', cmap='magma')\n",
" axes[1,i].set_title(f\"Result {INFLOW_LOCATION.numpy('inflow_loc,vector')[i]}\")\n",
" pylab.colorbar(im,ax=axes[1,i])"
],
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 720x432 with 12 Axes>"
],
"image/png": "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 truncated
},
"metadata": {
"needs_background": "light",
"tags": []
}
}
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 410
},
"id": "7lm9Rrel640-",
"outputId": "6ef7914a-8f63-49af-9a1a-fde1aed37682"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cuGIjhGx_trw"
},
"source": [
"These difference images clearly show that the optimization managed to align the upper region of the plumes very well. Each original image (at the top) shows a clear misalignment in terms of a black halo, while the states after optimization largely overlap the target smoke configuration of the reference, and exhibit differences closer to zero for the front of each smoke cloud.\n",
"\n",
"Note that all three simulations need to \"work\" with a fixed inflow, hence they cannot simply \"produce\" marker density out of the blue to match the target. Also each simulation needs to take into account how the non-linear model equations change the state of the system over the course of 20 time steps. So the optimization goal is quite difficult, and it is not possible to exactly satisfy the constraints to match the reference simulation in this scenario. E.g., this is noticeable at the stems of the smoke plumes, which still show a black halo after the optimization. The optimization was not able to shift the inflow position, and hence needs to focus on aligning the upper regions of the plumes.\n"
],
"metadata": {
"id": "cuGIjhGx_trw"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "jHdQureE_trx"
},
"source": [
"## Conclusions\n",
"\n",
@@ -616,13 +616,13 @@
"complex PDEs. Above, we've optimized for a mini-batch of 20 steps of a full Navier-Stokes solver.\n",
"\n",
"This is a powerful basis to bring NNs into the picture. As you might have noticed, our degrees of freedom were still a regular grid, and we've jointly solved a single inverse problem. There were three cases to solve as a mini-batch, of course, but nonetheless the setup still represents a direct optimization. Thus, in line with the PINN example of {doc}`physicalloss-code` we've not really dealt with a _machine learning_ task here. However, DP training allows for a range of flexible compinations with NNs that will be the topic of the next chapters.\n"
],
"metadata": {
"id": "jHdQureE_trx"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ffaDxZ3x_try"
},
"source": [
"## Next steps\n",
"\n",
@@ -631,10 +631,7 @@
"- Modify the setup of the simulation to differ more strongly across the four instances, run longer, or use a finer spatial discretization (i.e. larger grid size). Note that this will make the optimization problem tougher, and hence might not converge directly with this simple setup.\n",
"\n",
"- As a larger change, add a multi-resolution optimization to handle cases with larger differences. I.e., first solve with a coarse discretization, and then uses this solution as an initial guess for a finer discretization. \n"
],
"metadata": {
"id": "ffaDxZ3x_try"
}
]
}
],
"metadata": {
+1 -1
View File
@@ -168,7 +168,7 @@
},
"outputs": [],
"source": [
"!pip install --upgrade --quiet phiflow\n",
"!pip install --upgrade --quiet phiflow==2.1\n",
"#!pip install --upgrade --quiet git+https://github.com/tum-pbs/PhiFlow@develop\n",
"\n",
"from phi.tf.flow import *\n",
+6 -6
View File
@@ -50,7 +50,7 @@
}
],
"source": [
"!pip install --upgrade --quiet phiflow\n",
"!pip install --upgrade --quiet phiflow==2.2\n",
"from phi.flow import *\n",
"\n",
"from phi import __version__\n",
@@ -116,10 +116,10 @@
}
],
"source": [
"velocity = CenteredGrid(INITIAL, extrapolation.PERIODIC, x=N, bounds=Box[-1:1])\n",
"velocity = CenteredGrid(INITIAL, extrapolation.PERIODIC, x=N, bounds=Box(x=(-1,1)))\n",
"vt = advect.semi_lagrangian(velocity, velocity, DT)\n",
"#velocity = CenteredGrid(lambda x: -math.sin(np.pi * x), extrapolation.PERIODIC, x=N, bounds=Box[-1:1])\n",
"#velocity = CenteredGrid(Noise(), extrapolation.PERIODIC, x=N, bounds=Box[-1:1]) # random init\n",
"#velocity = CenteredGrid(lambda x: -math.sin(np.pi * x), extrapolation.PERIODIC, x=N, bounds=Box(x=(-1,1)))\n",
"#velocity = CenteredGrid(Noise(), extrapolation.PERIODIC, x=N, bounds=Box(x=(-1,1))) # random init\n",
"\n",
"print(\"Velocity tensor shape: \" + format( velocity.shape )) # == velocity.values.shape\n",
"print(\"Velocity tensor type: \" + format( type(velocity.values) ))\n",
@@ -194,7 +194,7 @@
},
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
@@ -237,7 +237,7 @@
"outputs": [
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<Figure size 1152x360 with 2 Axes>"
]
+226 -226
View File
@@ -2,6 +2,9 @@
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "o4JZ84moBKMr"
},
"source": [
"# Navier-Stokes Forward Simulation\n",
"\n",
@@ -19,101 +22,137 @@
"We'll solve this PDE on a closed domain with Dirichlet 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",
"[[run in colab]](https://colab.research.google.com/github/tum-pbs/pbdl-book/blob/main/overview-ns-forw.ipynb)\n",
"\n"
],
"metadata": {
"id": "o4JZ84moBKMr"
}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Implementation\n",
"\n",
"As in the previous section, the first command with a \"!\" prefix installs the [phiflow python package from GitHub](https://github.com/tum-pbs/PhiFlow) via `pip` in your python environment. (Skip or modify this command if necessary.)"
],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": 1,
"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 * # The Dash GUI is not supported on Google colab, ignore the warning\n",
"import pylab"
],
"outputs": [],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "da1uZcDXdVcF",
"outputId": "1082dc87-796c-4b57-e72e-5790fc1444c9"
}
},
"outputs": [],
"source": [
"!pip install --upgrade --quiet phiflow==2.2\n",
"#!pip install --upgrade --quiet git+https://github.com/tum-pbs/PhiFlow@develop\n",
"\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",
"The following code sets up a few constants, which are denoted by upper case names. We'll use $40 \\times 32$ cells to discretize our domain, introduce a slight viscosity via $\\nu$, and define the time step to be $\\Delta t=1.5$. \n",
"\n",
"We're creating a first `CenteredGrid` here, which is initialized by a `Sphere` geometry object. This will represent the inflow region `INFLOW` where hot smoke is generated."
],
"metadata": {
"id": "BVV1IKVqDfLl"
}
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"id": "WrA3IXDxv31P"
},
"outputs": [],
"source": [
"DT = 1.5\n",
"NU = 0.01\n",
"\n",
"INFLOW = CenteredGrid(Sphere(center=(30,15), radius=10), extrapolation.BOUNDARY, x=32, y=40, bounds=Box[0:80, 0:100]) * 0.2\n"
],
"outputs": [],
"metadata": {
"id": "WrA3IXDxv31P"
}
"INFLOW = CenteredGrid(Sphere(center=tensor([30,15], channel(vector='x,y')), radius=10), extrapolation.BOUNDARY, x=32, y=40, bounds=Box(x=(0,80),y=(0,100))) * 0.2\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ExA0Pi2sFVka"
},
"source": [
"The inflow will be used to inject smoke into a second centered grid `smoke` that represents the marker field $d$ from above. Note that we've defined a `Box` of size $100 \\times 80$ 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 appropriate conversion factors in mind. \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 $100 \\times 80$ 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."
],
"metadata": {
"id": "ExA0Pi2sFVka"
}
]
},
{
"cell_type": "code",
"execution_count": 3,
"source": [
"smoke = CenteredGrid(0, extrapolation.BOUNDARY, x=32, y=40, bounds=Box[0:80, 0:100]) # sampled at cell centers\n",
"velocity = StaggeredGrid(0, extrapolation.ZERO, x=32, y=40, bounds=Box[0:80, 0:100]) # sampled in staggered form at face centers "
],
"metadata": {},
"outputs": [],
"metadata": {}
"source": [
"smoke = CenteredGrid(0, extrapolation.BOUNDARY, x=32, y=40, bounds=Box(x=(0,80),y=(0,100))) # sampled at cell centers\n",
"velocity = StaggeredGrid(0, extrapolation.ZERO, x=32, y=40, bounds=Box(x=(0,80),y=(0,100))) # sampled in staggered form at face centers "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We sample the smoke field at the cell centers and the velocity in [staggered form](https://tum-pbs.github.io/PhiFlow/Staggered_Grids.html). The staggered grid internally contains 2 centered grids with different dimensions, and can be converted into centered grids (or simply numpy arrays) via the `unstack` function, as explained in the link above.\n",
"\n",
"Next we define the update step of the simulation, which calls the necessary functions to advance the state of our fluid system by `dt`. The next cell computes one such step, and plots the marker density after one simulation frame."
],
"metadata": {}
]
},
{
"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 marker density: [0.15530995, 0.008125]\n"
]
},
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7fa2f8d16eb0>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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",
"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",
@@ -128,49 +167,11 @@
"print(\"Max. velocity and mean marker 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')"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Max. velocity and mean marker density: [0.15530995, 0.008125]\n"
]
},
{
"output_type": "execute_result",
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7fa2f8d16eb0>"
]
},
"metadata": {},
"execution_count": 4
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
],
"image/png": "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"
},
"metadata": {
"needs_background": "light"
}
}
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 282
},
"id": "WmGZdOwswOva",
"outputId": "3ae4d68d-b586-4bbe-eca9-a223d7720949"
}
},
{
"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",
@@ -185,21 +186,16 @@
"The variables we created for the fields of the simulation here 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 phiflow](https://tum-pbs.github.io/PhiFlow/Math.html#shapes) store not only the sizes of the dimensions but also their names and types."
],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": 5,
"source": [
"print(f\"Smoke: {smoke.shape}\")\n",
"print(f\"Velocity: {velocity.shape}\")\n",
"print(f\"Inflow: {INFLOW.shape}, spatial only: {INFLOW.shape.spatial}\")\n"
],
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"output_type": "stream",
"text": [
"Smoke: (xˢ=32, yˢ=40)\n",
"Velocity: (xˢ=32, yˢ=40, vectorᵛ=2)\n",
@@ -207,60 +203,55 @@
]
}
],
"metadata": {}
"source": [
"print(f\"Smoke: {smoke.shape}\")\n",
"print(f\"Velocity: {velocity.shape}\")\n",
"print(f\"Inflow: {INFLOW.shape}, spatial only: {INFLOW.shape.spatial}\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that the phiflow output here indicates the type of a dimension, e.g., $^S$ for a spatial, and $^V$ for a vector dimension. Later on for learning, we'll also introduce batch dimensions.\n",
"\n",
"The actual content of a shape object can be obtained via `.sizes`, or alternatively we can query the size of a specific dimension `dim` via `.get_size('dim')`. Here are two examples:"
],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": 6,
"source": [
"print(f\"Shape content: {velocity.shape.sizes}\")\n",
"print(f\"Vector dimension: {velocity.shape.get_size('vector')}\")"
],
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"output_type": "stream",
"text": [
"Shape content: (32, 40, 2)\n",
"Vector dimension: 2\n"
]
}
],
"metadata": {}
"source": [
"print(f\"Shape content: {velocity.shape.sizes}\")\n",
"print(f\"Vector dimension: {velocity.shape.get_size('vector')}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The grid values can be accessed using the `values` property. This is an important difference to a phiflow tensor object, which does not have `values`, as illustrated in the code example below."
],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": 7,
"source": [
"print(\"Statistics of the different simulation grids:\")\n",
"print(smoke.values)\n",
"print(velocity.values)\n",
"\n",
"# in contrast to a simple tensor:\n",
"test_tensor = math.tensor(numpy.zeros([2, 5, 3]), spatial('x,y'), channel('vector'))\n",
"print(\"Reordered test tensor shape: \" + format(test_tensor.numpy('vector,y,x').shape) )\n",
"#print(test_tensor.values.numpy('y,x')) # error! tensors don't return their content via \".values\"\n"
],
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"output_type": "stream",
"text": [
"Statistics of the different simulation grids:\n",
"(xˢ=32, yˢ=40) float32 0.0 < ... < 0.20000000298023224\n",
@@ -269,37 +260,48 @@
]
}
],
"metadata": {}
"source": [
"print(\"Statistics of the different simulation grids:\")\n",
"print(smoke.values)\n",
"print(velocity.values)\n",
"\n",
"# in contrast to a simple tensor:\n",
"test_tensor = math.tensor(numpy.zeros([3, 5, 2]), spatial('x,y'), channel(vector=\"x,y\"))\n",
"print(\"Reordered test tensor shape: \" + format(test_tensor.numpy('vector,y,x').shape) ) # reorder to vector,y,x \n",
"#print(test_tensor.values.numpy('y,x')) # error! tensors don't return their content via \".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 (in this example the x component has $31 \\times 40$ cells, while y has $32 \\times 39$). The `INFLOW` grid naturally has the same dimensions as the `smoke` grid.\n"
],
"metadata": {}
]
},
{
"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."
],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": 8,
"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"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "0hZk5HX3w4Or",
"outputId": "f7811af7-4b58-4ff6-a8b6-6e7bedefaa6e"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"output_type": "stream",
"text": [
"Computed frame 0, max velocity 0.4609803557395935\n",
"Computed frame 1, max velocity 0.8926814794540405\n",
@@ -314,53 +316,24 @@
]
}
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "0hZk5HX3w4Or",
"outputId": "f7811af7-4b58-4ff6-a8b6-6e7bedefaa6e"
}
"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",
"source": [
"Now the hot plume is starting to rise:"
],
"metadata": {
"id": "GMKKWQBLHIwP"
}
},
"source": [
"Now the hot plume is starting to rise:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"source": [
"pylab.imshow(smoke.values.numpy('y,x'), origin='lower', cmap='magma')"
],
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7fa2f902cf40>"
]
},
"metadata": {},
"execution_count": 9
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
],
"image/png": "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 truncated
},
"metadata": {
"needs_background": "light"
}
}
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
@@ -368,20 +341,79 @@
},
"id": "Mfl80CjZxZcL",
"outputId": "92f3a9ba-d403-4799-a543-132ee8ed234c"
},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7fa2f902cf40>"
]
},
"execution_count": 9,
"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",
"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."
],
"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": 10,
"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, velocity.values.vector[0], velocity.values.vector[1] ]]\n",
"for time_step in range(20):\n",
@@ -395,50 +427,45 @@
"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}\")"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Computing time step 0\n",
"Computing time step 1\n",
"Computing time step 2\n",
"Computing time step 10\n"
]
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 1152x360 with 5 Axes>"
],
"image/png": "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 truncated
},
"metadata": {
"needs_background": "light"
}
}
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 489
},
"id": "tkhCOzc0ITsj",
"outputId": "f6366c12-1eb5-4ff6-e0d7-94b806bfd8e4"
}
},
{
"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."
],
"metadata": {}
]
},
{
"cell_type": "code",
"execution_count": 11,
"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": "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 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",
@@ -450,54 +477,27 @@
" 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",
" "
],
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 1152x360 with 5 Axes>"
],
"image/png": "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 truncated
},
"metadata": {
"needs_background": "light"
}
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 1152x360 with 5 Axes>"
],
"image/png": "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 truncated
},
"metadata": {
"needs_background": "light"
}
}
],
"metadata": {}
]
},
{
"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 it is already fully compatible with backpropagation 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, especially when the solver is _differentiable_. Before moving to these more complex training processes, we will cover a simpler supervised approach in the next chapter. This is very fundamental: even when aiming for advanced physics-based learning setups, a working supervised training is always the first step."
],
"metadata": {
"id": "ooqVxCPM8PXl"
}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Next steps\n",
"\n",
"You could create a variety of nice fluid simulations based on this setup. E.g., try changing the spatial resolution, the buoyancy factors, and the overall length of the simulation run."
],
"metadata": {}
]
}
],
"metadata": {
+6 -6
View File
@@ -51,11 +51,11 @@ We'll need a few tools for the derivations below, which are summarized here for
Not surprisingly, we'll need some Taylor-series expansions. With the notation above it reads:
$$L(x+\Delta) = L + J^T \Delta + \frac{1}{2} H \Delta^2 + \cdots$$
$$L(x+\Delta) = L + J \Delta + \frac{1}{2} H \Delta^2 + \cdots$$
Then we also need the _Lagrange form_, which yields an exact solution for a $\xi$ from the interval $[x, x+\Delta]$:
$$L(x+\Delta) = L + J^T \Delta + \frac{1}{2} H(\xi) \Delta^2$$
$$L(x+\Delta) = L + J \Delta + \frac{1}{2} H(\xi) \Delta^2$$
In several instances we'll make use of the fundamental theorem of calculus, repeated here for completeness:
@@ -134,27 +134,27 @@ with lower loss values.
First, we apply the fundamental theorem to L
$$
L(x + \lambda \Delta) = L + \int_0^1 \text{ds}~ J^T(x + s \lambda \Delta) \lambda \Delta \ ,
L(x + \lambda \Delta) = L + \int_0^1 \text{ds}~ J(x + s \lambda \Delta) \lambda \Delta \ ,
$$
and likewise express $J$ around this location with it:
$$\begin{aligned}
J^T(x + s \lambda \Delta) &= J^T + \int_0^1 \text{dt}~ H(x + s t \lambda \Delta) s \lambda \Delta
J(x + s \lambda \Delta) = J + s \lambda \Delta^T \int_0^1 \text{dt}~ H(x + s t \lambda \Delta)
\end{aligned}$$
Inserting this $J^T$ into $L$ yields:
$$\begin{aligned}
L(x + \lambda \Delta) - L(x)
&= \int_0^1 \text{d}s \Big[ J^T + \int_0^1 \text{d}t~ H(x + s t \lambda \Delta) ~ s \lambda \Delta \Big]^T \lambda \Delta \\
&= \int_0^1 \text{d}s \Big[ J + s \lambda \Delta^T \int_0^1 \text{d}t~ H(x + s t \lambda \Delta) \Big]^T \lambda \Delta \\
&= \int_0^1 \text{d}s \Big[ -H \Delta + \int_0^1 \text{d}t H(x + s t \lambda \Delta) ~ s \lambda \Delta \Big]^T \lambda \Delta \\
&= \int_0^1 \text{d}s \int_0^1 \text{d}t \big[ -H \Delta + H(x + s t \lambda \Delta) ~ s \lambda \Delta \big]^T \lambda \Delta \\
&= \int_0^1 \text{d}s \int_0^1 \text{d}t \big[ -H \Delta (1+\lambda s) + [ H(x + s t \lambda \Delta) - H ] ~ s \lambda \Delta \big]^T \lambda \Delta \\
&= -(H\Delta)^T \big( 1+\frac{\lambda}{2} \big) \lambda \Delta + \lambda^2 \int_0^1 \text{d}s ~ s \int_0^1 \text{d}t \big[ [ H(x + s t \lambda \Delta) - H ] ~ \Delta \big]^T \Delta \\
\end{aligned}$$ (newton-step-size-conv1)
Here we've first used $\Delta = - J^T/H$, and moved it into the integral in the third line.
Here we've first used $\Delta = - J^T/H$, and moved it into the integral in the third line, alongside the $s \lambda \Delta$ term.
Line four factors out $H \Delta$. This allows us to evaluate the integral for the first term
$ -H \Delta (1+\lambda s)$ in the last line of equation {eq}`newton-step-size-conv1` above.
+2 -1
View File
@@ -67,7 +67,8 @@
},
"outputs": [],
"source": [
"!pip install --upgrade --quiet git+https://github.com/tum-pbs/PhiFlow\n",
"!pip install --upgrade --quiet phiflow==2.2\n",
"#!pip install --upgrade --quiet git+https://github.com/tum-pbs/PhiFlow\n",
"from phi.torch.flow import * # switch to TF with \"phi.tf.flow\""
]
},
+1 -4
View File
@@ -785,12 +785,9 @@
"metadata": {
"colab": {
"collapsed_sections": [],
"name": "LinearChain_GD_PG_HIG-fromSlack-colab.ipynb",
"name": "physgrad-hig-code.ipynb",
"provenance": []
},
"interpreter": {
"hash": "60a46218545510a486eb79ffac0761a327b44b02462576ac242e6c15f2abc4b7"
},
"kernelspec": {
"display_name": "Python 3.8.10 64-bit ('tf250': conda)",
"name": "python3"
+1 -21
View File
@@ -74,23 +74,6 @@
"name": "stderr",
"output_type": "stream",
"text": []
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Could not load resample cuda libraries: CUDA binaries not found at /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/cuda/build/resample.so. Run \"python setup.py cuda\" to compile them\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" for key in self._mapping:\n",
" yield (key, self._mapping[key])\n",
"$ python setup.py tf_cuda\n",
"before reinstalling phiflow.\n"
]
}
],
"source": [
@@ -210,10 +193,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Instructions for updating:\n",
"Use keras.layers.Dense instead.\n",
"Instructions for updating:\n",
"Please use `layer.__call__` method instead.\n"
"\n"
]
}
],