-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Devito.jl version for cfd/01_convection example #53
base: master
Are you sure you want to change the base?
Conversation
thanks @laughingrice. Looks great! Just a few suggestions:
side-note: I guess after we merge this we will want to combine the |
@laughingrice I believe with the last couple PRs we have Devito.jl wrappers for We are excited and delighted by your contributions to this project! Please let us know if they expose any other functionality that we should add to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great example! I think the suggested changes will work with your script if you rebase your branch off the newest PR.
"#### Devito implementation\n", | ||
"Now we want to re-create the above example via a Devito operator. To do this, we can start by defining our computational grid and creating a function `u` as a symbolic `devito.TimeFunction`. The core thing to note here is that this is one of Devito's symbolic functions, which have a dual role in the creation of finite difference solvers:\n", | ||
"* They behave symbolically like `sympy.Function` objects, so that we can construct derivatives and use them in symbolic expressions, thus inheriting all the power of automated symbolic manipulation that SymPy provides.\n", | ||
"* They act as containers for user data by providing a `.data` property, accessed via the `Devito.data` function that wraps automatically allocated memory space in a neat Julia array.\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"* They act as containers for user data by providing a `.data` property, accessed via the `Devito.data` function that wraps automatically allocated memory space in a neat Julia array.\n", | |
"* They act as containers for user data by providing a `data` property, accessed via the `Devito.data` function that wraps automatically allocated memory space in a neat Julia array.\n", |
"source": [ | ||
"# Specify the `interior` flag so that the stencil is only\n", | ||
"# applied to the interior of the domain.\n", | ||
"eq = Eq(dt(u) + c * dxl(u) + c * dyl(u), subdomain=grid.o.interior)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"eq = Eq(dt(u) + c * dxl(u) + c * dyl(u), subdomain=grid.o.interior)" | |
"eq = Eq(dt(u) + c * dxl(u) + c * dyl(u), subdomain=interior(grid))" |
"# nsimplify: 1.0*x = x\n", | ||
"# pprint(nsimplify(stencil))\n", | ||
"\n", | ||
"Devito.devito.sympy.nsimplify(stencil)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Devito.devito.sympy.nsimplify(stencil)" | |
"stencil = nsimplify(stencil)" |
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"PyCall.builtin.print(op.o.ccode)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"PyCall.builtin.print(op.o.ccode)" | |
"print(ccode(op))" |
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# from devito import solve\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"# from devito import solve\n", |
"* They behave symbolically like `sympy.Function` objects, so that we can construct derivatives and use them in symbolic expressions, thus inheriting all the power of automated symbolic manipulation that SymPy provides.\n", | ||
"* They act as containers for user data by providing a `.data` property, accessed via the `Devito.data` function that wraps automatically allocated memory space in a neat Julia array.\n", | ||
"\n", | ||
"The particular `TimeFunction` type that we will declare our variable $u$ as in this case is aware of the fact that we will want to implement a timestepping algorithm with it. So the object `u` will declare two buffers of shape `(nx, ny)` for us, as defined by the `Grid` object, and present them as `u.data[0]` and `u.data[1]`. Let's fill the initial buffer with some data and look at it:" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"The particular `TimeFunction` type that we will declare our variable $u$ as in this case is aware of the fact that we will want to implement a timestepping algorithm with it. So the object `u` will declare two buffers of shape `(nx, ny)` for us, as defined by the `Grid` object, and present them as `u.data[0]` and `u.data[1]`. Let's fill the initial buffer with some data and look at it:" | |
"The particular `TimeFunction` type that we will declare our variable $u$ as in this case is aware of the fact that we will want to implement a timestepping algorithm with it. So the object `u` will declare two buffers of shape `(nx, ny)` for us, as defined by the `Grid` object, and present them as `data(u)[1]` and `data(u)[2]`. Let's fill the initial buffer with some data and look at it:" |
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Nice. Now we can look at deriving our 3-point stencil using the symbolic capabilities given to our function $u$ by SymPy. For this we will first construct our derivative terms in space and time. For the forward derivative in time we can easily use Devito's shorthand notation `u.dt` to denote the first derivative in time and `u.dxl` and `u.dyl` to denote the space derivatives. Note that the `l` means were using the \"left\" or backward difference here to adhere to the discretization used in the original tutorials.\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Nice. Now we can look at deriving our 3-point stencil using the symbolic capabilities given to our function $u$ by SymPy. For this we will first construct our derivative terms in space and time. For the forward derivative in time we can easily use Devito's shorthand notation `u.dt` to denote the first derivative in time and `u.dxl` and `u.dyl` to denote the space derivatives. Note that the `l` means were using the \"left\" or backward difference here to adhere to the discretization used in the original tutorials.\n", | |
"Nice. Now we can look at deriving our 3-point stencil using the symbolic capabilities given to our function $u$ by SymPy. For this we will first construct our derivative terms in space and time. For the forward derivative in time we can easily use Devito's shorthand notation `dt(u)` to denote the first derivative in time and `dxl(u)` and `dyl(u)` to denote the space derivatives. Note that the `l` means were using the \"left\" or backward difference here to adhere to the discretization used in the original tutorials.\n", |
"# from devito import solve\n", | ||
"# from sympy import nsimplify, pprint\n", | ||
"\n", | ||
"stencil = Devito.devito.solve(eq, forward(u))\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"stencil = Devito.devito.solve(eq, forward(u))\n", | |
"stencil = solve(eq, forward(u))\n", |
"\n", | ||
"# Create an operator that updates the forward stencil point\n", | ||
"# Note that the subs parameter is required for this to work\n", | ||
"op = Operator(Eq(forward(u), stencil, subdomain=grid.o.interior); subs=spacing_map(grid))\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"op = Operator(Eq(forward(u), stencil, subdomain=grid.o.interior); subs=spacing_map(grid))\n", | |
"op = Operator(Eq(forward(u), stencil, subdomain=interior(grid)); subs=spacing_map(grid))\n", |
"Now, despite getting a correct looking result, there is still one problem with the above operator: It doesn't set any boundary conditions as part of the time loop. We also note that the operator includes a time loop, but at this point Devito doesn't actually provide any language constructs to explicitly define different types of boundary conditions (Devito is probably still a kind of prototype at this point). Luckily though, Devito provides a backdoor for us to insert custom expression in the so-called \"indexed\" or \"low-level\" API that allow us to encode the Dirichlet boundary condition of the original example.\n", | ||
"\n", | ||
"#### The \"indexed\" or low-level API\n", | ||
"The `TimeFunction` field we created earlier behaves symbolically like a `sympy.Function` object with the appropriate indices, eg. `u(t, x, y)`. If we take a simple first-order derivative of that we have a term that includes the spacing variable `h`, which Devito uses as the default for encoding $dx$ or $dy$. For example, `u.dx` simply expands to `-u(t, x, y)/h + u(t, x + h, y)/h`.\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"The `TimeFunction` field we created earlier behaves symbolically like a `sympy.Function` object with the appropriate indices, eg. `u(t, x, y)`. If we take a simple first-order derivative of that we have a term that includes the spacing variable `h`, which Devito uses as the default for encoding $dx$ or $dy$. For example, `u.dx` simply expands to `-u(t, x, y)/h + u(t, x + h, y)/h`.\n", | |
"The `TimeFunction` field we created earlier behaves symbolically like a `sympy.Function` object with the appropriate indices, eg. `u(t, x, y)`. If we take a simple first-order derivative of that we have a term that includes the spacing variable `h`, which Devito uses as the default for encoding $dx$ or $dy$. For example, `dx(u)` simply expands to `-u(t, x, y)/h + u(t, x + h, y)/h`.\n", |
In relation to issue #51 - Is there any way to define boundary conditions?
Implemented a Devito.jl version for the first example from the cfd example set under Devito