Commit 61d1bae6 authored by Martin Bauer's avatar Martin Bauer
Browse files

Tests and documentation for derivative module

parent beec6d3e
......@@ -130,4 +130,4 @@ pages:
tags:
- docker
only:
- master@software/pystencils
- master@pycodegen/pystencils
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
%% Cell type:code id: tags:
``` python
from pystencils.session import *
```
%% Cell type:markdown id: tags:
# Demo: Working with derivatives
## Overview
This notebook demonstrates how to formulate continuous differential operators in *pystencils* and automatically derive finite difference stencils from them.
Instead of using the built-in derivatives in *sympy*, *pystencils* comes with its own derivative objects. They represent spatial derivatives of pystencils fields.
%% Cell type:code id: tags:
``` python
f = ps.fields("f: [2D]")
first_derivative_x = ps.fd.diff(f, 0)
first_derivative_x
```
%%%% Output: execute_result
![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAAAXCAYAAABTYvy6AAAACXBIWXMAAA7EAAAOxAGVKw4bAAADiklEQVRYCdWXjZFSMRDHeYwFMNgB1wFqB9ABjhWIHZxjBQ52cFiBch1wVqBHB0cH3tEB/n8h+yYs78F7EUV3JiSb7Hd294Viu912PBRFMdVeT+N5PLsR3drT/dc4jqdDzsw0BranNQFYaoxsL3eOsm40X2swl3pyZebydaW8hHjTQwkrb1frjQjeayxKwvzFZ7EiD/lk1VDjMpBGTBZwC0/pnq21T01MDW87i5fMQcYorn87g9rakNIXIE1A2fAgujvRv2tC72nEP9HeQvyFP7sE/qxKqYwkBV9qPMrQ20gz0MzIhVdiLEsoV8i5+HyND+X0vYTj9FeNlfBZDAQ6Wxsu3qkGJURNd1hHHPRyQKozBNTekwbNzXd6ujpE1/6sKd6EXzR/rMtL9p5fIdV1A6QwXfujHFlp9mApHs5Ez+eIb/xPZvHQ9Wshyuf8ro5INLNUTlsdyD3BM9B5Xzp2NmgBD06z6IH7oX0yIXR7zaQsRlqmWNM64HM0Qg9lsydAf3nbWufoOMkjueXbwYxH+32VYdq3z1BIc+F0971PkfDaoEXHeBQ91MinkZaBjPQ5Ok7ySA++8GXpdHX9IMCP3XTwG5qSdueRlrR/dFQb4fSIOsC5qhKC/oPGFxZAjo6mPHIYO0n5QdrViVgV8N3+ZEyRAAEpEIh+uuHWfCW+uz1DaTppUKyftNHRhocgj7rRIQr+yiyxWZGh9tai8c3L3zgsPeNL53gbnKXOBRIin9K6dWMdCV8THj7JY7txbnUkQyYYikEaNAIeMONEsC397Xrc6Ji5bXpJVUfH8bq3gZfpccR68DQeh55M6oXPmYxC+RWOa6bmSHsajjfKcH+7lTcqGQCBq3I6HOoHQ1LI0dGGh6zoB8dNqxzleWpPVNsuZ51vFByUVEWybI4xgG9E/1q0ND2ypwowYi+ITXWkwlryYPvaUj2Vc2qNEzgUIDp5i3Lb08zni5IJTulsnpylS4JYVedHdUgupbg0+VHgUZ5EaSivxv/OEsb0hcQ2j569f2wyiE8gTtMwq0pG2zsQLWX1wgXuqA7xDMXzTeOt+MoM1b69KBF+YBeboiFAi9rXlgT+lTMZgbGTHH05fOIJD7WsGxfzWUG3sJTjVV+PWj3ioRGvxGeNrZbWDiIP7/V5To2bnHPO/PW1F2JTuTjQxmlKb4zTKPgnbjwYknGD8DUFBZaSmsvx0IR/ASYAqOQkEypqAAAAAElFTkSuQmCC)
$\displaystyle {\partial_{0} {{f}_{(0,0)}}}$
D(f[0,0])
%% Cell type:markdown id: tags:
This object is the derivative of the field $f$ with respect to the first spatial coordinate $x$. To get a finite difference approximation a discretization strategy is required:
%% Cell type:code id: tags:
``` python
discretize_2nd_order = ps.fd.Discretization2ndOrder(dx=sp.symbols("h"))
discretize_2nd_order(first_derivative_x)
```
%%%% Output: execute_result
![](data:image/png;base64,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)
$\displaystyle \frac{- {{f}_{(-1,0)}} + {{f}_{(1,0)}}}{2 h}$
-f_W + f_E
──────────
2⋅h
%% Cell type:markdown id: tags:
Strictly speaking, derivative objects act on *field accesses*, not *fields*, that why there is a $(0,0)$ index at the field:
%% Cell type:code id: tags:
``` python
first_derivative_x
```
%%%% Output: execute_result
![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAAAXCAYAAABTYvy6AAAACXBIWXMAAA7EAAAOxAGVKw4bAAADiklEQVRYCdWXjZFSMRDHeYwFMNgB1wFqB9ABjhWIHZxjBQ52cFiBch1wVqBHB0cH3tEB/n8h+yYs78F7EUV3JiSb7Hd294Viu912PBRFMdVeT+N5PLsR3drT/dc4jqdDzsw0BranNQFYaoxsL3eOsm40X2swl3pyZebydaW8hHjTQwkrb1frjQjeayxKwvzFZ7EiD/lk1VDjMpBGTBZwC0/pnq21T01MDW87i5fMQcYorn87g9rakNIXIE1A2fAgujvRv2tC72nEP9HeQvyFP7sE/qxKqYwkBV9qPMrQ20gz0MzIhVdiLEsoV8i5+HyND+X0vYTj9FeNlfBZDAQ6Wxsu3qkGJURNd1hHHPRyQKozBNTekwbNzXd6ujpE1/6sKd6EXzR/rMtL9p5fIdV1A6QwXfujHFlp9mApHs5Ez+eIb/xPZvHQ9Wshyuf8ro5INLNUTlsdyD3BM9B5Xzp2NmgBD06z6IH7oX0yIXR7zaQsRlqmWNM64HM0Qg9lsydAf3nbWufoOMkjueXbwYxH+32VYdq3z1BIc+F0971PkfDaoEXHeBQ91MinkZaBjPQ5Ok7ySA++8GXpdHX9IMCP3XTwG5qSdueRlrR/dFQb4fSIOsC5qhKC/oPGFxZAjo6mPHIYO0n5QdrViVgV8N3+ZEyRAAEpEIh+uuHWfCW+uz1DaTppUKyftNHRhocgj7rRIQr+yiyxWZGh9tai8c3L3zgsPeNL53gbnKXOBRIin9K6dWMdCV8THj7JY7txbnUkQyYYikEaNAIeMONEsC397Xrc6Ji5bXpJVUfH8bq3gZfpccR68DQeh55M6oXPmYxC+RWOa6bmSHsajjfKcH+7lTcqGQCBq3I6HOoHQ1LI0dGGh6zoB8dNqxzleWpPVNsuZ51vFByUVEWybI4xgG9E/1q0ND2ypwowYi+ITXWkwlryYPvaUj2Vc2qNEzgUIDp5i3Lb08zni5IJTulsnpylS4JYVedHdUgupbg0+VHgUZ5EaSivxv/OEsb0hcQ2j569f2wyiE8gTtMwq0pG2zsQLWX1wgXuqA7xDMXzTeOt+MoM1b69KBF+YBeboiFAi9rXlgT+lTMZgbGTHH05fOIJD7WsGxfzWUG3sJTjVV+PWj3ioRGvxGeNrZbWDiIP7/V5To2bnHPO/PW1F2JTuTjQxmlKb4zTKPgnbjwYknGD8DUFBZaSmsvx0IR/ASYAqOQkEypqAAAAAElFTkSuQmCC)
$\displaystyle {\partial_{0} {{f}_{(0,0)}}}$
D(f[0,0])
%% Cell type:markdown id: tags:
Sometimes it might be useful to specify derivatives at an offset e.g.
%% Cell type:code id: tags:
``` python
derivative_offset = ps.fd.diff(f[0, 1], 0)
derivative_offset, discretize_2nd_order(derivative_offset)
```
%%%% Output: execute_result
![](data:image/png;base64,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)
$\displaystyle \left( {\partial_{0} {{f}_{(0,1)}}}, \ \frac{- {{f}_{(-1,1)}} + {{f}_{(1,1)}}}{2 h}\right)$
⎛ -f_NW + f_NE⎞
⎜D(f[0,1]), ────────────⎟
⎝ 2⋅h ⎠
%% Cell type:markdown id: tags:
Another example with second order derivatives:
%% Cell type:code id: tags:
``` python
laplacian = ps.fd.diff(f, 0, 0) + ps.fd.diff(f, 1, 1)
laplacian
```
%%%% Output: execute_result
![](data:image/png;base64,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)
$\displaystyle {\partial_{0} {\partial_{0} {{f}_{(0,0)}}}} + {\partial_{1} {\partial_{1} {{f}_{(0,0)}}}}$
D(D(f[0,0])) + D(D(f[0,0]))
%% Cell type:code id: tags:
``` python
discretize_2nd_order(laplacian)
```
%%%% Output: execute_result
![](data:image/png;base64,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)
$\displaystyle \frac{{{f}_{(-1,0)}} - 2 {{f}_{(0,0)}} + {{f}_{(1,0)}}}{h^{2}} + \frac{{{f}_{(0,-1)}} - 2 {{f}_{(0,0)}} + {{f}_{(0,1)}}}{h^{2}}$
f_W - 2⋅f_C + f_E f_S - 2⋅f_C + f_N
───────────────── + ─────────────────
2 2
h h
%% Cell type:markdown id: tags:
## Working with derivative terms
No automatic simplifications are done on derivative terms i.e. linearity relations or product rule are not applied automatically.
%% Cell type:code id: tags:
``` python
f, g = ps.fields("f, g :[2D]")
c = sp.symbols("c")
δ = ps.fd.diff
expr = δ( δ(f, 0) + δ(g, 0) + c + 5 , 0)
expr
```
%%%% Output: execute_result
![](data:image/png;base64,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)
$\displaystyle {\partial_{0} (c + {\partial_{0} {{f}_{(0,0)}}} + {\partial_{0} {{g}_{(0,0)}}} + 5) }$
D(c + Diff(f_C, 0, -1) + Diff(g_C, 0, -1) + 5)
%% Cell type:markdown id: tags:
This nested term can not be discretized automatically.
%% Cell type:code id: tags:
``` python
try:
discretize_2nd_order(expr)
except ValueError as e:
print(e)
```
%% Cell type:markdown id: tags:
### Linearity
The following function expands all derivatives exploiting linearity:
%% Cell type:code id: tags:
``` python
ps.fd.expand_diff_linear(expr)
```
%%%% Output: execute_result
![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPkAAAAXCAYAAADJAeliAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAHBElEQVR4Ae2ci3UUNxSGsz4U4NgdmA4M6cB04KSDmA6ckwpynA5wKiDQgaECYjrAHcTQgfN/Y0mRtJpZze7VzC5enSPrdfXrPnT1moXFw8PDD3lYLBYXqjtUPHZtb0R3l9PtYtlaNmu8XdTpVDy30HULzKn0UT0OTh5HdbxSPPF1yuPsN4pnvm5XU8lgKps1XqxXYaP3N4qXLg02iemeSl46MLUdemuBuY32yB2cHfwmZ1R1p4pf8/pdKot/U9ms8XJdCv+dIhP7XJEZeZ7TPJWyZDe1HXprgbmt9jhA2ii8UP5lVO6yYv6zMofuaJM3Ny9r3HNFdrRNgrVs1nhBNsnKLo5zc4L6oPhKNnivdCeDgf1a6LoF5lbaJ3FyTaTXij/2cMqdHMXsZLCWzRovU+oZZY3xQfEbadb+pIotdN0Cc1uN8qzEmFZejufs6PdSht9BTlQm7nSwls0azyn3J6XfxUOn5WRpoesWmJYyW2AlTu4E/kvAPPj8rXikOu6FbxUJoyee6//vY/fuL7sTx/9Jg7Vs1ngoQ5jcPTkt/aJ4rzJ2YEd/TfpUQyNds5FZz3WuWK8Uvzhb4S+cjqmbL4iB7vFNHHBE/Kp46ut8qjruhrxWXPq6Valo2fURNjwYKQ/O7aq+eTsYitVjF/pby2aKV+B3pa6lj2av7cJemgM5j2PKm9hPfc113QiTzTA8WivP/MeOfH5OHrgp016qt6gTdmK/Z4ymlRKGeM39Q4OUdll/TO/aRM8j2LEiO/Sx+vymNA849Hu1+eM+7d8Uu92JwhTBWjZrvFwHDp/q3nu4aK5inatcY49kqBV9TtR+pDF6eUjAGhXEg/m8bITZbUJSQ3jPku7uNBaawQ+SoPpp7SdmYAAHJ3NIOY+qZ4fvPqEp5UgJk/4EgIDvfJlUAUfuxYtp47z6sBreFiInAngotSVjx3iOF2vZTPEK/KJPVS/bIZIn7AKiXWmPHKumj2iwYRgnxyiVRW9qP+GZ67oRJnMz7OLOTlwHlnzAjR/0qnJz+3lHhZniMVr1fM6hvTsuK8Xhkh/GuPawQKi8JHRpUtTWCW/t47rjzVI2U13lOhC/OMqXvJ6yAhMnLLCubqU9cizwFVfZELsPLqA5bl9ZOGvZT/3MdW2NKTzvzBex/KrndJXY0dFObr8DHR0wJuGfx2TpLysN4drRcoS672r+/8MxnLsTR3/wiKVjPySThUaywb+JrnoUwaTp093vanvr+9XYw9P6tLaPJiw25djur2oeYpLU2nYw3QJTsC+dQvKrDY9ted0s9jtwDJKwupcCL7t/eqM7AiZAHHD6IyocHdkinhTNqj51KPIiJkbJFjFtjRdBd5PmU1wR5XlQiRcA74C99oj6+uyYPiwo3eLtO8+QttC1JSZzn3mff3lCb/l9fBb7HTinZMV5DrNxkENyJ7oTTf6w1gkW0yrP7u3DtTLJZwNWUUXuebkyfB/z1Fo2a7xcYHSkOmLsyB2Z2rxz5t0or7LHun2wVWLHElCLuha6boEp2bvdOraP8vgNIezkcftjU/K3qf38Ts6OdiZG+PkozsgxDYfkxzAlI3e7dsRmUlYf8HhdvFK8IKrMnYVvhksTOMJpkTWVTQxa48Uyd0c/6ShMjqgRJ+9bIBP9iy4vRzAhm9PkZQg5IcSLd+g8UaaFrk0xZSt0hI8w1y+Z88pjJzZH2nyYzX7dJzQxA1PPxSBHae4NHGd4IMgnlS/nhqecOK/65ru/SKYP1rJZ42UaYbKUHNyTxZOGump7eICRfdhhSs4fwbXLttB1I0xsFuwmP+KYHsqRhuaxn4TuXthrUzHMAjD4MluLVUun8VhEwut9bb+xdNay1eCJhoW1e8VWyifC5JXWy6D6U8XkMw1tCqPtUdtHdNwrN35hF0Zz+9XK5PVZk9Zgiib54YmTFcPkPjKb/fxxXTxVB47xP3tqt/vzo5d8lfIkG6dgt8SPGLSWrQaP4x1XJByBBZf3jFJg1+bIl4fBMYTL1evG47vOg32iAYaOmBHZcHYi+9XKNMxs2jqIKZ1iu9tMt9zHryVzvpPPZr+FmEnFqihJKP8LK6jZYbnnfBfBWrZVeGrnvQIH5+GzdEUKehUtu/YLnCZUKjM0htrYQT4q/qp+4deHQ308tmiY5Ozk+YT1JFuV1sg0luEhTLVx0mHuczz3NuS0FfQcjyf6Wey3lpPHjO/z02nATTgedIqTaIgT9eXfEIzqpz78iGhn/3nxkD7maJvLfnsnn8PaG4ypicJOUfri0YuKg6vxs/r5h7peWt/g+vD79b7rgyfdpyM0MIf91rmTjxBpT9pAA91nyZG4OOsYB+foyf9Gs3fwkYquIJ/cfvudvMIq20ayzs48Rgbh8+bC41Fy9x+Dsaft18DU9vsPQY57dOU2asIAAAAASUVORK5CYII=)
$\displaystyle {\partial_{0} c} + {\partial_{0} {\partial_{0} {{f}_{(0,0)}}}} + {\partial_{0} {\partial_{0} {{g}_{(0,0)}}}}$
D(c) + D(D(f[0,0])) + D(D(g[0,0]))
%% Cell type:markdown id: tags:
The symbol $c$ that was included is interpreted as a function by default.
We can control the simplification behaviour by specifying all functions or all constants:
%% Cell type:code id: tags:
``` python
ps.fd.expand_diff_linear(expr, functions=(f[0,0], g[0, 0]))
```
%%%% Output: execute_result
![](data:image/png;base64,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)
$\displaystyle {\partial_{0} {\partial_{0} {{f}_{(0,0)}}}} + {\partial_{0} {\partial_{0} {{g}_{(0,0)}}}}$
D(D(f[0,0])) + D(D(g[0,0]))
%% Cell type:code id: tags:
``` python
ps.fd.expand_diff_linear(expr, constants=[c])
```
%%%% Output: execute_result
![](data:image/png;base64,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)
$\displaystyle {\partial_{0} {\partial_{0} {{f}_{(0,0)}}}} + {\partial_{0} {\partial_{0} {{g}_{(0,0)}}}}$
D(D(f[0,0])) + D(D(g[0,0]))
%% Cell type:markdown id: tags:
The expanded term can then be discretized:
%% Cell type:code id: tags:
``` python
discretize_2nd_order(ps.fd.expand_diff_linear(expr, constants=[c]))
```
%%%% Output: execute_result
![](data:image/png;base64,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)
$\displaystyle \frac{{{f}_{(-1,0)}} - 2 {{f}_{(0,0)}} + {{f}_{(1,0)}}}{h^{2}} + \frac{{{g}_{(-1,0)}} - 2 {{g}_{(0,0)}} + {{g}_{(1,0)}}}{h^{2}}$
f_W - 2⋅f_C + f_E g_W - 2⋅g_C + g_E
───────────────── + ─────────────────
2 2
h h
%% Cell type:markdown id: tags:
### Product rule
The next cells show how to apply product rule and its reverse:
%% Cell type:code id: tags:
``` python
expr = δ(f[0, 0] * g[0, 0], 0 )
expr
```
%%%% Output: execute_result
![](data:image/png;base64,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)
$\displaystyle {\partial_{0} ({{f}_{(0,0)}} {{g}_{(0,0)}}) }$
D(f_C*g_C)
%% Cell type:code id: tags:
``` python
expanded_expr = ps.fd.expand_diff_products(expr)
expanded_expr
```
%%%% Output: execute_result
![](data:image/png;base64,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)
$\displaystyle {{f}_{(0,0)}} {\partial_{0} {{g}_{(0,0)}}} + {{g}_{(0,0)}} {\partial_{0} {{f}_{(0,0)}}}$
f_C⋅D(g[0,0]) + g_C⋅D(f[0,0])
%% Cell type:code id: tags:
``` python
recombined_expr = ps.fd.combine_diff_products(expanded_expr)
recombined_expr
```
%%%% Output: execute_result
![](data:image/png;base64,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)
$\displaystyle {\partial_{0} ({{f}_{(0,0)}} {{g}_{(0,0)}}) }$
D(f_C*g_C)
%% Cell type:code id: tags:
``` python
assert recombined_expr == expr
```
%% Cell type:markdown id: tags:
### Evaluate derivatives
Arguments of derivative need not be to be fields, only when trying to discretize them.
The next cells show how to transform them to *sympy* derivatives and evaluate them.
%% Cell type:code id: tags:
``` python
k = sp.symbols("k")
expr = δ(k**3 + 2 * k, 0 )
expr
```
%%%% Output: execute_result
![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGYAAAAZCAYAAADDq1t2AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFHklEQVRoBe2ZjXUTORCAY14K4KAD0kE4KrjQAT8VQDrgSrhHOuCo4A46INfBJR0kHQDuIHyfLK0lWbvedcyLnYfem5U0OzOaH0kzXs9ubm4O9qHNZrP36PkVOAIeAW/QfU5/L9uDfbCKoHxAzysCcQacMv4GfNoH3TfVcS8CE43zpKR2weAkTe5jP9uXqyx3fjxBT9D9eY6/T+PDfTOGoDxE51fAH/um+xR9m4HB+LcI0QGPo7AP7M7rKYJzWuQ9YX6CjL9z/NQxct7B8xr4C1mXU/l3lR67XqDbZeFjJgc5QGD14zUR8IwN0BdAxxa0Y+aJv6ZNePrvgIl9tGzoLQa+TOHZJi1r6xN1CHqoC3BcrwEu+W6tjdBazCz9ngvjhSdlxWBwx8D3nHbsGD4TdbdgzRffeyKnBMYTaJ3/YgrfNmhZU2d/ymUxdzOrT3PzgtcHgzbyXrkXSW7hDJmBZgDAu/DbxDimlx5Yp9Cgg+FXYXdctyMZp8BM0ifpDL9Xx7s0n9LDp48e1jzg1HHId2s3EfwGOOhVBKZeLJ/DcAUMOjmndxx5hk6LJa+EK4bmsmo5zA24jhjky2XkY/huE5jmtYRMryJtKexlPsrG6K+wCR33JX+vrt+BbxB9pre5S4VRLSZ8Az9UNFjuXkMzXyP0Je9PkekvfwsS9Xg6gg+yrTftOUYXN0VLb52bt7E26qs5cq+BkyIwIAzIR8Dj+i/wCJzH6x/ANuTkBcXy6a48X06bI3dTR8Na8vi55SnwHkXDevRWYDtRhaGLurWavrPVPhpl44I1PPXHy+4qY6KA4i5HifAevFWHx3Rx/9EzDvehfaLLe/Dy9OYA3rmzlBnuXnplehLUQ3wvb77OJmNkb3yVtdbLdC58AX6yjdoNXCTH6xCD0kyI4M0vOkunydgpwFgjiypF5Wny9CY83wESqrxBCfkizn9aUKJu2w6MtrZ8MNlG5MhzlQKTElczmUJo0ELFEZgIUL5zwAUHVzh5CrrqfagAoZlUUOQy1o2R7am2VK1BR6pfjXe+4uChdaDXjqYN8Z3rNN+35ELrldhdVTq2q6FzBvDpOIZdHZiy0lVamosXpyPihgITdhl0yvXaa57WXJdtjVlrKycm6t7rdN5PthGeEJhDEq6Ot/2/6FaeXl02P6ekqmweMMuHn+FN2nkTl2Tn+IO4prJOcfY5cyu/K3o/S3TFQMG0YxN0NbhH6OvfEKGBC/4BZ2Wl7ZvYqB+vHyxEhqfRbTUX9n+QPBg6vW51EKxO6mAlnlcOsiAkeUEGRnkF7WxDP3f1szwoUVmDldqmNhrM+aEOZyF3af5/RxAO3tzj74w/A2L50OF5oFoBuISmr7S0tu9ORtRB6XWpKW6nGj7RcfrlM+O0gdxQ+sCvE2f0tk1t1GfnKfm7mCfGiLuI85WkFt+ZVLrPIyjCdFGxOU4Azgqu+XESvDmlzknmGte0bxYhSfZte9d2nU3kwGeBoNEt6Ozl/UY2RvnHxR9l7AAVfgYYpHMUX9nB0Pgu5Ab60MCp5G/Q56fIXCLt85acBefdPKOdfjpJu/tuFKlWRS8PhUXYURGYiq45hdkd3SW9aORrhPnZpGi8s3Dw00mXIAuCO5pEB3i6i410R+p0y6KXV+NX9DqbHBilIMDgPHZM89rpdTy0HmlP2MrpC9y/HsEDcbP8h59CXt4oMFN8GRf0R5vJ8Ffr8UC9gX96YNSDRS0m/LF5q7+We2zaezT+8covcvoPmAxjo38wBv8AAAAASUVORK5CYII=)
$\displaystyle {\partial_{0} (k^{3} + 2 k) }$
D(k**3 + 2*k)
%% Cell type:code id: tags:
``` python
ps.fd.evaluate_diffs(expr, var=k)
```
%%%% Output: execute_result
![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEMAAAAWCAYAAACbiSE3AAAACXBIWXMAAA7EAAAOxAGVKw4bAAADIElEQVRYCdWYgVFbMQyGkx4DhG7QsAFtN4ANaEdoNoARerABjFDYoOkEbdkARqDZgH6fa706jssFyAuvujO2ZMlP/i3JDuP7+/tRnzQej09Zf0Kb0m5pJ3xzQT84GvcJRgbinG8Iwgj+km4K/3ZwSODQq56dOqrW/wy/DyhGyeCobzDccLnxSI9SNhhQdvr0hHTYq9bfz/yPSj4IdhuRUW7UYjr8AprzeFZ47ila/K4KmUXQm8FC+I521zj9Ur0bY5duFfTLb3Tz2xhk3/VDilT1cK6ThEFMuPFRNIQWPyc/hazskf+kLdmU8+XYNdbVLe02Oeb76RDLNZEJjHs8UJ42D3OchUeVsoo3pSzGLf2YK3v0DminIcv8fvCP6bH1gI4fYxO62J3TJsFHj+yXTT5qhmFipY9qz7CjFRnh5gal+Z+u/Rc9U030vzM+sjE+oaV3B/026SMfM5prcg8TfJum2wRUFOyWWtlxRSJa0yGCW+xWgKoUv8FPaNaYjtaw63Q3OPAAfOMYHS2/J82rVQMMPdEzDC8aDhkZXVRk4F4j82VpSqSTp18CuLHO1kT48q9Xb1z3t5EmySk2NaUJguHkZn0xLlEGygW+OgFvvTHNBMBCGSnEcNiE7/rqreKhL7rbA2ZpjIKbtLikShvz8HHLGD3qpKJkT2vePGH73J71n1xAW99mvRvaZcw9+EMN5ARDeoNByjNk1hCL0RdkvbwZ+IbR2YowATcdWwXYGvaBubUo78MA+LsHGI0NFX9N1tFhKqjQXbmME5r0RoXzT7rq6m+tw/OtjURG9n3ljbTDhOQGzf9dnEoRIF8T856MwM3Qm8P7Or2hv5av9YfI46uA7uFvFxHI3FP3zhCAeQOIpOScypDpYfQEfycPCZJgGt6DJfyz8L8vgcjOCtAoIsOH0BJlBCMKIlp8XwQQgrJAT7tWDi+t99IMfroX3ztXjOPQPERrkC/iswQGgwsUDmjlA0vjQ+a6zcNrXOrAphflDFtTbeUqVmEglP7Lhi/WuprSYT54m9QWL80DuOFsoT/rw5f/DYxUmwAj0najmPwGLo1pDG9WS+oAAAAASUVORK5CYII=)
$\displaystyle 3 k^{2} + 2$
2
3⋅k + 2
......@@ -15,6 +15,6 @@ It is a good idea to download them and run them directly to be able to play arou
/notebooks/05_tutorial_phasefield_spinodal_decomposition.ipynb
/notebooks/06_tutorial_phasefield_dentritic_growth.ipynb
/notebooks/demo_assignment_collection.ipynb
/notebooks/demo_derivatives.ipynb
/notebooks/demo_benchmark.ipynb
/notebooks/demo_wave_equation.ipynb
import sympy as sp
from collections import namedtuple, defaultdict
from pystencils import Field
from pystencils.sympyextensions import normalize_product, prod
......@@ -214,6 +213,11 @@ def diff_terms(expr):
This function yields different results than 'expr.atoms(Diff)' when nested derivatives are in the expression,
since this function only returns the outer derivatives
Example:
>>> x, y = sp.symbols("x, y")
>>> diff_terms( diff(x, 0, 0) )
{Diff(Diff(x, 0, -1), 0, -1)}
"""
result = set()
......
......@@ -11,6 +11,7 @@ from .derivation import FiniteDifferenceStencilDerivation
def fd_stencils_standard(indices, dx, fa):
order = len(indices)
assert all(i >= 0 for i in indices), "Can only discretize objects with (integer) subscripts"
if order == 1:
idx = indices[0]
return (fa.neighbor(idx, 1) - fa.neighbor(idx, -1)) / (2 * dx)
......@@ -122,7 +123,6 @@ def discretize_spatial(expr, dx, stencil=fd_stencils_standard):
def discretize_spatial_staggered(expr, dx, stencil=fd_stencils_standard):
def staggered_visitor(e, coordinate, sign):
if isinstance(e, Diff):
arg, *indices = diff_args(e)
......
import sympy as sp
import pystencils as ps
from sympy.printing.latex import LatexPrinter
from pystencils.fd import *
from sympy.abc import a, b, t, x, y, z
def test_derivative_basic():
x, y, z, t = sp.symbols("x y z t")
d = diff
op1, op2, op3 = DiffOperator(), DiffOperator(target=x), DiffOperator(target=x, superscript=1)
......@@ -18,4 +19,31 @@ def test_derivative_basic():
assert diff_term == dx**2 + 2 * dx * dy + dy**2 + 1
assert DiffOperator.apply(diff_term, t) == d(t, x, x) + 2 * d(t, x, y) + d(t, y, y) + t
assert ps.fd.Diff(0) == 0
expr = ps.fd.diff(ps.fd.diff(x, 0, 0), 1, 1)
assert expr.get_arg_recursive() == x
assert expr.change_arg_recursive(y).get_arg_recursive() == y
def test_derivative_expand_collect():
original = Diff(x*y*z)
result = combine_diff_products(combine_diff_products(expand_diff_products(original))).expand()
assert original == result
original = -3 * y * z * Diff(x) + 2 * x * z * Diff(y)
result = expand_diff_products(combine_diff_products(original)).expand()
assert original == result
original = a + b * Diff(x ** 2 * y * z)
expanded = expand_diff_products(original)
collect_res = combine_diff_products(combine_diff_products(combine_diff_products(expanded)))
assert collect_res == original
def test_diff_expand_using_linearity():
eps = sp.symbols("epsilon")
funcs = [a, b]
test = Diff(eps * Diff(a+b))
result = expand_diff_linear(test, functions=funcs)
assert result == eps * Diff(Diff(a)) + eps * Diff(Diff(b))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment