Skip to content
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

[Documentation] Improving documentation #24

Merged
merged 84 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
aab5aa3
initial doc add for abstract type BoundaryFunction
youwuyou Jun 6, 2024
cfea412
added documentation to add all abstract data types
youwuyou Jun 6, 2024
20192e2
added skeleton of documentation for the website to be finished
youwuyou Jun 9, 2024
4e5a4d4
added concept doc for architectures
youwuyou Jun 9, 2024
e11bb71
finished docstrings for distributed architecture
youwuyou Jun 9, 2024
17d7e82
added concept doc for grids and fields
youwuyou Jun 10, 2024
c10934d
using : instead of ; for grid cell figure
youwuyou Jun 10, 2024
93888e2
finished the FunctionField concept doc
youwuyou Jun 10, 2024
1ac100c
add set! for IC in field concept doc
youwuyou Jun 11, 2024
781fe13
added short description in readme
youwuyou Jun 13, 2024
188a31a
added concept doc for task-based parallelism
youwuyou Jun 13, 2024
d59b9de
Update docs/src/concepts/workers.md
youwuyou Jun 14, 2024
7de43f4
renamed tutorials to examples
youwuyou Jun 15, 2024
79235c5
change Tutorials entry in doc content overview to Examples
youwuyou Jun 15, 2024
21cf1a9
95% finished kernels concept doc, remained to detail about performanc…
youwuyou Jun 15, 2024
6b8c8ae
concept docs reordering
youwuyou Jun 15, 2024
1e80be0
changed table of contents
youwuyou Jun 15, 2024
bdf9b93
small complement to grid part regarding field dimensions
youwuyou Jun 16, 2024
be39ca5
naming consistency
youwuyou Jun 16, 2024
3b93d6d
added concept doc for BC, and visualized results from grid scripts
youwuyou Jun 17, 2024
5c6dfdb
finished the concept doc for grid operators (icl. FD operators, maski…
youwuyou Jun 17, 2024
0c4e3ee
clean up
youwuyou Jun 17, 2024
d599e6a
update docstrings
youwuyou Jun 17, 2024
767668b
docstring for launcher
youwuyou Jun 17, 2024
56c570f
docstrings for first order BC structs, set! for fields and function c…
youwuyou Jun 17, 2024
abbb13d
Update docs/src/concepts/grid_operators.md
youwuyou Jun 17, 2024
e25b34e
Update docs/src/concepts/grid_operators.md
youwuyou Jun 17, 2024
02184ca
remove outer_width in the example in kernels.md
youwuyou Jun 18, 2024
58a5272
BC example with y-axis pointing upwards
youwuyou Jun 18, 2024
5f252bb
added concept explaination of indexing for kernels
youwuyou Jun 18, 2024
e6c8ce2
Update docs/src/concepts/fields.md
youwuyou Jun 21, 2024
8daaf2a
Update docs/src/concepts/fields.md
youwuyou Jun 21, 2024
3e0ad23
better KA priority description
youwuyou Jun 24, 2024
a943101
added batched bc explaination
youwuyou Jun 24, 2024
e85617f
update the grid operator lerp example
youwuyou Jun 24, 2024
84d0002
Update docs/src/concepts/architectures.md
youwuyou Jun 24, 2024
013e722
Update docs/src/concepts/bc.md
youwuyou Jun 25, 2024
503237c
removed inaccurate description for batched bc
youwuyou Jun 25, 2024
576fa73
Merge branch 'yw/test-documentation' of github.com:PTsolvers/Chmy.jl …
youwuyou Jun 25, 2024
23f9256
having a clean example overview table to most essential numerical exp…
youwuyou Jul 12, 2024
fe45578
moved runtests instructions to home, added also an installation guide…
youwuyou Jul 12, 2024
00f5768
skeleton for getting started, where the most essential concepts shall…
youwuyou Jul 12, 2024
2825fcf
Update docs/src/index.md
youwuyou Jul 13, 2024
9192a5f
installation from a specific branch in home guide
youwuyou Jul 15, 2024
ea0c687
finished the getting_started section with the 2D diffusion example
youwuyou Jul 17, 2024
5696520
refined the getting started and added it=100 2d diffusion result
youwuyou Jul 17, 2024
c0e2de3
better BC description for precomputed BC & launch with BC
youwuyou Jul 17, 2024
c8d0415
removed the unnecessary launch with BC description as it was detailed…
youwuyou Jul 17, 2024
c714e52
Update docs/src/getting_started.md
youwuyou Jul 18, 2024
3bcee16
coherent description of diffusion coeff with chi, removed unnecessary…
youwuyou Jul 18, 2024
31d2724
removed all unnecessary blanks
youwuyou Jul 18, 2024
8e4ddee
Update docs/src/getting_started.md
youwuyou Jul 18, 2024
79a4432
Update docs/src/getting_started.md
youwuyou Jul 18, 2024
3293009
Add favicon
luraess Jul 18, 2024
d00c86b
Merge branch 'yw/test-documentation' of github.com:PTsolvers/Chmy.jl …
luraess Jul 18, 2024
7424008
Bump version
luraess Jul 18, 2024
fe50443
Update docs/src/getting_started.md
youwuyou Jul 18, 2024
1ecb7a6
Update docs/src/getting_started.md
youwuyou Jul 18, 2024
df655a8
Update docs/src/getting_started.md
youwuyou Jul 18, 2024
b0a7358
Update docs/src/getting_started.md
youwuyou Jul 18, 2024
959c21d
Update docs/src/getting_started.md
youwuyou Jul 18, 2024
8e664f1
Update docs/src/getting_started.md
youwuyou Jul 18, 2024
717fd54
Update docs/src/getting_started.md
youwuyou Jul 18, 2024
44d72b1
Update docs/src/getting_started.md
youwuyou Jul 18, 2024
b86ca2a
Merge branch 'main' into yw/test-documentation
youwuyou Jul 18, 2024
4a3ee36
Move testing to developer documentation
utkinis Jul 23, 2024
8cade89
Add content
utkinis Jul 23, 2024
82946d9
Remove overview page
utkinis Jul 23, 2024
0d302cf
Update architectures
utkinis Jul 23, 2024
4d5d4eb
Update boundary conditions
utkinis Jul 23, 2024
d1c3312
Update grids section
utkinis Jul 23, 2024
0698d99
Update fields section
utkinis Jul 23, 2024
18fc809
Update grid operations section
utkinis Jul 23, 2024
2299ce3
Move workers to dev docs
utkinis Jul 23, 2024
1faabff
Update kernels section
utkinis Jul 23, 2024
0c329cc
Add missing articles
utkinis Jul 23, 2024
a79ac1e
Remove temperature
utkinis Jul 23, 2024
adef64b
Change paths
utkinis Jul 23, 2024
b3d3303
Add favicon to assets
utkinis Jul 23, 2024
1372f0e
fixed not rendered subscript
youwuyou Jul 23, 2024
1080247
using Nvidia instead of NVIDIA
youwuyou Jul 23, 2024
953ef1f
Add minor fixes
luraess Jul 23, 2024
0f3077f
Fix equation numbering
utkinis Jul 24, 2024
b1ea6af
consistency in g(x, t) => g(x,y,t)
youwuyou Jul 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

Hey, that's Chmy.jl 🚀

Chmy.jl provides a backend-agnostic toolkit for finite difference computations on multi-dimensional computational staggered grids. Chmy.jl features task-based distributed memory parallelisation capabilities.

## Documentation
Checkout the [documentation](https://PTsolvers.github.io/Chmy.jl/dev) for API reference and usage.

Expand Down
15 changes: 15 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ makedocs(
warnonly = [:missing_docs],
pages = Any[
"Home" => "index.md",
"Concepts" => Any["concepts/overview.md",
"concepts/architectures.md",
"concepts/grids.md",
"concepts/fields.md",
"concepts/bc.md",
"concepts/grid_operators.md",
"concepts/workers.md",
"concepts/kernels.md"
],
"Examples" => Any["examples/overview.md",
"examples/diffusion_2d.md",
"examples/diffusion_2d_mpi.md",
"examples/diffusion_2d_perf.md",
"examples/batcher.md"
],
"Usage" => Any["usage/runtests.md"],
"Library" => Any["lib/modules.md"]
]
Expand Down
Binary file added docs/src/assets/field_set_ic_gaussian.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/src/assets/field_set_ic_random.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions docs/src/assets/field_type_tree.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/src/assets/grid_2d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/src/assets/grid_3d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/src/assets/mixed_bc_example.png
youwuyou marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/src/assets/staggered_grid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/src/assets/staggered_grid_cell.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 43 additions & 0 deletions docs/src/concepts/architectures.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Architectures

The abstract type `Architecture` can be concretized to be either an architecture of a concrete type `SingleDeviceArchitecture` or a `DistributedArchitecture` for MPI usage.

## Single Device Architecture

An object being the type of `SingleDeviceArchitecture` meaning that it contains the handle to a single CPU or GPU device with a respetive backend, where a device can be specified by an integer ID.

### Backend Selection & Architecture Initialization

We currently support CPU architectures, as well as CUDA and ROC backends for Nvidia and AMD GPUs through a thin wrapper around the [`KernelAbstractions.jl`](https://github.com/JuliaGPU/KernelAbstractions.jl) for users to select desirable backends.

```julia
# Default with CPU
arch = Arch(CPU())
```

```julia
# using CUDA
arch = Arch(CUDABackend())
```

```julia
# using AMDGPU
arch = Arch(ROCBackend())
```

At the beginning of program, one may specify the backend and initialize the architecture they desire to use. The initialized `arch` variable will be required explicitly at creation of some entiries such as grids and kernel launchers.

### Specifying Stream Priority

For advanced users, we provide a convenient wrapper `activate!(arch::SingleDeviceArchitecture; priority=:normal)` for specifying the stream priority owned by the task one is executing. The stream priority will be set to `:normal` by default, where `:low` and `:high` are also possible options given that the target backend has priority control over streams implemented.

For an example implementation, see [`AMDGPU.priority!`](https://amdgpu.juliagpu.org/stable/streams/#AMDGPU.priority!).
youwuyou marked this conversation as resolved.
Show resolved Hide resolved


## Distributed Architecture

Our distributed architecture builds upon the abstraction of having GPU clusters that build on the same GPU architecture. Note that in general, GPU clusters may be equipped with hardware from different vendors, incorporating different types of GPUs to exploit their unique capabilities for specific tasks.

With this abstraction of having homogeneous clusters, an object of type `DistributedArchitecture{ChildArch,Topo}` can have an uniform `child_arch` property representing all child architectures that comprise the distributed architecture. We also provide conveninent getters `get_backend` and `get_device` for obtaining the underlying backend and device of child architectures.

Additionally, a distributed architecture also has a `topo` property that specifies that underlying MPI topology used. We currently support the creation of MPI communicator with Cartesian topology information attached.
46 changes: 46 additions & 0 deletions docs/src/concepts/bc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Boundary Conditions
youwuyou marked this conversation as resolved.
Show resolved Hide resolved

Using [Chmy.jl](https://github.com/PTsolvers/Chmy.jl), we aim to study partial differential equations (PDEs) arising from physical or engineering problems. Generally, PDEs possess infinitely many solutions. Therefore, to obtain a unique solution, additional initial or boundary conditions are necessary for the model problem to be well-posed, ensuring the existence and uniqueness of a stable solution.

We provide a small overview for boundary conditions that one often encounter. Followingly, we consider the unknown function $u : \Omega \mapsto \mathbb{R}$ defined on some bounded computational domain $\Omega \subset \mathbb{R}^d$ in a $d$-dimensional space. With the domain boundary denoted by $\partial \Omega$, we have some function $g : \partial \Omega \mapsto \mathbb{R}$ prescribed on the boundary.


| Type | Form | Example |
|:------------|:------------|:---------|
| Dirichlet | $u = g$ on $\partial \Omega$ | In fluid dynamics, the no-slip condition for viscous fluids states that at a solid boundary the fluid has zero velocity relative to the boundary. |
| Neumann | $\partial_\nu u = g$ on $\partial \Omega$, where $\nu$ is the outer normal vector to $\Omega$ | It specifies the values in which the derivative of a solution is applied within the boundary of the domain. An application in thermodynamics is a prescribed heat flux from a surface, which serves as boundary condition |
| Robin | $u + \alpha \partial_\nu u = g$ on $\partial \Omega$, where $\alpha \in \mathbb{R}$. | Also called impedance boundary conditions from their application in electromagnetic problems |




## Applying Boundary Conditions

Followingly, we describe the syntax in [Chmy.jl](https://github.com/PTsolvers/Chmy.jl) for launching kernels that impose boundary conditions on some `field` that is well-defined on a `grid` with backend specified through `arch`. For Dirichlet and Neumann boundary conditions, they are referred to as homogeneous if $g = 0$, otherwise they are non-homogeneous if $g = v$ holds, for some $v\in \mathbb{R}$.

| | Homogeneous | Non-homogeneous |
|:------------|:------------|:------------|
| Dirichlet | `bc!(arch, grid, field => Dirichlet())` | `bc!(arch, grid, field => Dirichlet(v))` |
| Neumann | `bc!(arch, grid, field => Neumann())` | `bc!(arch, grid, field => Neumann(v))` |

### Mixed Boundary Conditions

In the code example above, by specifying boundary conditions using syntax such as `field => Neumann()`, we essentially launch a kernel that impose the Neumann boundary condition on the entire domain boundary $\partial \Omega$. More often, one may be interested in prescribing different boundary conditions on different parts of $\partial \Omega$.


The following figure showcases a 2D square domain $\Omega$ with different boundary conditions applied on each side:

- The top boundary (red) is a Dirichlet boundary condition where $u = a$.
- The bottom boundary (blue) is also a Dirichlet boundary condition where $u = b$.
- The left and right boundaries (green) are Neumann boundary conditions where $\frac{\partial u}{\partial y} = 0$.


```@raw html
<img src="../assets/mixed_bc_example.png" width="60%"/>
```

To launch a kernel that satisfies these boundary conditions in Chmy.jl, you can use the following code:

```julia
bc!(arch, grid, field => (x = (Dirichlet(a), Dirichlet(b)), y = Neumann()))
```
141 changes: 141 additions & 0 deletions docs/src/concepts/fields.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Fields

With a given grid that allows us to define each point uniquely in a high-dimensional space, we abstract the data values to be defined on the grid under the concept `AbstractField`. Following is the type tree of the abstract field and its derived data types.

```@raw html
<img src="../assets/field_type_tree.svg" width="70%"/>
```

## Defining a multi-dimensional `Field`

Consider the following example, where we predefined a variable `grid` of type `Chmy.UniformGrid`, similar as in the previous section [Grids](./grids.md). We can now define physical properties on the grid.

When defining a scalar field `Field` on the grid, we need to specify the arrangement of the field values. These values can either be stored at the cell centers of each control volume `Center()` or on the cell vertices/faces `Vertex()`.

```julia
# Define geometry, architecture..., a 2D grid
grid = UniformGrid(arch; origin=(-lx/2, -ly/2), extent=(lx, ly), dims=(nx, ny))

# Define pressure as a scalar field
Pr = Field(backend, grid, Center())
```

With the methods `VectorField` and `TensorField`, we can conveniently construct 2-dimensional and 3-dimensional fields, with predefined locations for each field dimension on a staggered grid.

```julia
# Define velocity as a vector field on the 2D grid
V = VectorField(backend, grid)

# Define stress as a tensor field on the 2D grid
τ = TensorField(backend, grid)
```

!!! tip "Acquiring Locations on the Grid Cell"
One could use a convenient getter for obtaining locations of variable on the staggered-grid. Such as `Chmy.location(Pr)` for scalar-valued pressure field and `Chmy.location(τ.xx)` for a tensor field.

### Setup Initial Conditions on `Field`

We could also modify field values in order to set up initial conditions on the values. We first have an empty field variable `C` defined, by using `interior(C)` we can inspect its values being empty equal to zero.

```julia
C = Field(backend, grid, Center())
```

```julia
# Set initial values of the field randomly
set!(C, grid, (_, _) -> rand())

# Set initial values to 2D Gaussian
set!(C, grid, (x, y) -> exp(-x^2 - y^2))
```

```@raw html
<img src="../assets/field_set_ic_random.png" width="50%"/>
```

```@raw html
<img src="../assets/field_set_ic_gaussian.png" width="50%"/>
```



A slightly more complex usage involves passing extra parameters to be used for initial conditions setup.

```julia
# Define a temperature field with values on cell centers
T = Field(backend, grid, Center())

# Function for setting up the initial conditions on T
init_incl(x, y, x0, y0, r, in, out) = ifelse((x - x0)^2 + (y - y0)^2 < r^2, in, out)

# Set up the initial conditions with parameters specified
set!(T, grid, init_incl; parameters=(x0=0.0, y0=0.0, r=0.1lx, in=T0, out=Ta))
youwuyou marked this conversation as resolved.
Show resolved Hide resolved
```

## Defining a parameterized `FunctionField`

A field could also be represented in a parameterized way, having a function that associates a single number to every point in the space.

An object of the concrete type `FunctionField` can be initialized with its constructor. The constructor takes in


1. A function `func`
2. A `grid`
3. A location tuple `loc` for specifying the distribution of variables

Optionally, one can also use the boolean variable `discrete` to indicate if the function field is typed `Discrete` or `Continuous`. Any additional parameters to be used in the function `func` can be passed to the optional parameter `parameters`.

### Example: Creation of a parameterized function field
Followingly, we create a `gravity` variable that is two-dimensional and comprises of two parameterized `FunctionField` objects on a predefined uniform grid `grid`.

**1. Define Functions that Parameterize the Field**

In this step, we specify how the gravity field should be parameterized in x-direction and y-direction, with `η` as the additional parameter used in the parameterization.

```julia
# forcing terms
ρgx(x, y, η) = -0.5 * η * π^2 * sin(0.5π * x) * cos(0.5π * y)
ρgy(x, y, η) = 0.5 * η * π^2 * cos(0.5π * x) * sin(0.5π * y)
```

**2. Define Locations for Variable Positioning**

We specify the location on the fully-staggered grid as introduced in the _Location on a Grid Cell_ section of the concept [Grids](./grids.md).

```julia
vx_node = (Vertex(), Center())
vy_node = (Center(), Vertex())
```

**3. Define the 2D Gravity Field**

By specifying the locations on which the parameterized field should be calculated, as well as concretizing the value `η = η0` by passing it as the optional parameter `parameters` to the constructor, we can define the 2D gravity field:

```julia
η0 = 1.0
gravity = ( x=FunctionField(ρgx, grid, vx_node; parameters=η0),
youwuyou marked this conversation as resolved.
Show resolved Hide resolved
y=FunctionField(ρgy, grid, vy_node; parameters=η0))
youwuyou marked this conversation as resolved.
Show resolved Hide resolved
```

## Defining Constant Fields

For completeness, we also provide an abstract type `ConstantField`, which comprises of a generic `ValueField` type, and two special types `ZeroField`, `OneField` for conveninent usage. With such a construct, we can easily define value fields properties and other parameters using constant values in a straightforward and readable manner. Moreover, explicit information about the grid on which the field should be defined can be abbreviated. For example:

```julia
# Defines a field with constant values 1.0
field = Chmy.ValueField(1.0)
```

Alternatively, we could also use the conveninent and lightweight contructor.

```julia
# Defines a field with constant value 1.0 using the convenient constructor
onefield = Chmy.OneField{Float64}()
```

Notably, these two fields shall equal to each other as expected.

```julia
julia> field == onefield
true
```
110 changes: 110 additions & 0 deletions docs/src/concepts/grid_operators.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Grid Operators

The gist of the finite difference relies on replacing derivatives by difference quotients anchored on structured grids. We currently support various finite difference operators for fields defined in Cartesian coordinates. The table below summarizes the most common usage of grid operators, with the grid `g::StructuredGrid` and index `I = @index(Global, Cartesian)` defined and `P = Field(backend, grid, location)` is some field defined on the grid `g`.

| Mathematical Formulation | Code |
|:-------|:------------|
| $\frac{\partial}{\partial x} P$ | ` ∂x(P, g, I)` |
| $\frac{\partial}{\partial y} P$ | ` ∂y(P, g, I)` |
| $\frac{\partial}{\partial z} P$ | ` ∂z(P, g, I)` |
| $\nabla P$ | ` divg(P, g, I)` |

## Computing the Divergence of a Vector Field

To illustrate the usage of grid operators, we compute the divergence of an vector field $V$ using the `divg` function. We first allocate memory for required fields.

```julia
V = VectorField(backend, grid)
∇V = Field(backend, grid, Center())
# use set! to set up the initial vector field...
```

The kernel that computes the divergence needs to have the grid information passed as for other finite difference operators.

```julia
@kernel inbounds = true function update_∇!(V, ∇V, g::StructuredGrid, O)
I = @index(Global, NTuple)
I = I + O
∇V[I...] = divg(V, g, I...)
end
```

The kernel can then be launched when required as we detailed in section [Kernels](./kernels.md).

```julia
launch(arch, grid, update_∇! => (V, ∇V, grid))
```



## Masking
youwuyou marked this conversation as resolved.
Show resolved Hide resolved

Masking is particularly important when performing finite differences on GPUs, as it allows for efficient and accurate computations by selectively applying operations only where needed, allowing more flexible control over the grid operators and improving performance. Thus, by providing masked grid operators, we enable more flexible control over the domain on which the grid operators should be applied for advanced users.

In the following example, we first define a mask `ω` on the 2D `StructuredGrid`. Then we specify to **not** mask the center area of all Vx, Vy nodes (accessible through `ω.vc`, `ω.cv`) on the staggered grid.

```julia
# define the mask
ω = FieldMask2D(arch, grid) # with backend and grid geometry defined

# define the initial inclusion
r = 2.0
init_inclusion = (x,y) -> ifelse(x^2 + y^2 < r^2, 1.0, 0.0)

# mask all other entries other than the initial inclusion
set!(ω.vc, grid, init_inclusion)
set!(ω.cv, grid, init_inclusion)
```

We can then pass the mask to other grid operators when applying them within the kernel. When computing masked derivatives, a mask being the subtype of `AbstractMask` is premultiplied at the corresponding grid location for each operand:

```julia
@kernel function update_strain_rate!(ε̇, V, ω::AbstractMask, g::StructuredGrid, O)
I = @index(Global, NTuple)
I = I + O
# with masks ω
ε̇.xx[I...] = ∂x(V.x, ω, g, I...)
ε̇.yy[I...] = ∂y(V.y, ω, g, I...)
ε̇.xy[I...] = 0.5 * (∂y(V.x, ω, g, I...) + ∂x(V.y, ω, g, I...))
end
```

The kernel can be launched as follows, with some launcher defined using `launch = Launcher(arch, grid)`:

```julia
# define fields
ε̇ = TensorField(backend, grid)
V = VectorField(backend, grid)

# launch kernel
launch(arch, grid, update_strain_rate! => (ε̇, V, ω, grid))
```


## Interpolation
youwuyou marked this conversation as resolved.
Show resolved Hide resolved

Interpolating physical parameters such as permeability and density between various types of nodes is frequently necessary on a staggered grid. Chmy.jl provides conveninent functions for performing interpolations of field values between different types of nodes.

In the following example, we specify to use the linear interpolation rule `lerp` when interpolating nodal values of the density field `ρ`, defined on pressure nodes (with location `(Center(), Center())`) to `ρvx` and `ρvy`, defined on Vx and Vy nodes respectively.

```julia
# define density ρ on pressure nodes
ρ = Field(backend, grid, Center())
ρ0 = 3.0; set!(ρ, ρ0)

# allocate memory for density on Vx, Vy nodes
ρvx = Field(backend, grid, (Vertex(), Center()))
ρvy = Field(backend, grid, (Center(), Vertex()))
youwuyou marked this conversation as resolved.
Show resolved Hide resolved
```

The kernel `interpolate_ρ!` performs the actual interpolation of nodal values and requires the grid information passed by `g`.

```julia
@kernel function interpolate_ρ!(ρ, ρvx, ρvy, g::StructuredGrid, O)
youwuyou marked this conversation as resolved.
Show resolved Hide resolved
I = @index(Global, NTuple)
I = I + O
# Interpolate from pressure nodes to Vx, Vy nodes
lerp(ρvx, location(ρ), g, I...)
youwuyou marked this conversation as resolved.
Show resolved Hide resolved
lerp(ρvy, location(ρ), g, I...)
youwuyou marked this conversation as resolved.
Show resolved Hide resolved
end
```
Loading