# Second order 2D differentiation DiffEqOperators.jl

**URL:** <https://discourse.julialang.org/t/second-order-2d-differentiation-diffeqoperators-jl/77239>\
**Category:** Numerics\
**Created:** [March 1, 2022, 1:41pm UTC](https://discourse.julialang.org/t/second-order-2d-differentiation-diffeqoperators-jl/77239 "2022-03-01T13:41:26Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Siempie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/siempie/32/32790_2.png) [@Siempie](https://discourse.julialang.org/u/Siempie)\
**Post date:** [March 1, 2022, 1:41pm UTC](https://discourse.julialang.org/t/second-order-2d-differentiation-diffeqoperators-jl/77239/1 "2022-03-01T13:41:26Z")

</div>

Hello i am trying to calculate the **laplacian** of a 2D array for the use in diffeq.jl  
And expand later to 3D hopefully.  
I am currently implementing it using DiffEqOperators.jl with **centereddifference** () and **neuman0BC** ()  
However i dont see an easy way to also implement the neumann BC’s in the y direction.  
So how do i implement the BC’s in both axis?  
And in general i wonder if this is the best way to implement this or if there would be a more direct way.

```julia
dx = 0.01
axis = collect(-1:dx:1);
umesh = [(i, j) for i in axis, j in axis];

sines((x,y)) = sin(pi*x)*sin(pi*y)
u = sines.(umesh)

temp_u = Dirichlet0BC(Float64)*u
xdiff = CenteredDifference{1}(2,2,dx,N)*tempu
ydiff = CenteredDifference{2}(2,2,dx,N)*u
laplacian_of_u = xdif+ydif

```

---

<div class="post-metadata">

**Author:** ![xtalax](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xtalax/32/35293_2.png) [@xtalax](https://discourse.julialang.org/u/xtalax)\
**Post date:** [March 7, 2022, 2:17pm UTC](https://discourse.julialang.org/t/second-order-2d-differentiation-diffeqoperators-jl/77239/2 "2022-03-07T14:17:05Z")

</div>

Hi,

What you want to do is:

```julia
dx = 0.01
axis = collect(-1:dx:1);
umesh = [(i, j) for i in axis, j in axis];

sines((x,y)) = sin(pi*x)*sin(pi*y)
u = sines.(umesh)

Qx, Qy = Dirichlet0BC(Float64, size(u))

Dxx = CenteredDifference{1}(2,2,dx,N)
Dyy = CenteredDifference{2}(2,2,dx,N)

A = (Dxx + Dyy)*compose(Qx, Qy)

laplacian_of_u = A*u

```

Doing things in this way improves performance, as `DiffEqOperators` fuses the stencils of the operators, fusing loops and leveraging GPU convolutions from `NNlib`.

For the extension to 3D you do the obvious thing, note that the BC constructors return a variable number of `Q` operators depending on `ndims(u)`, and compose takes any number of arguments.

I’m working on DiffEqOperators and am happy to support if you have further questions, let me know how you get on!

---

<div class="post-metadata">

**Author:** ![Siempie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/siempie/32/32790_2.png) [@Siempie](https://discourse.julialang.org/u/Siempie)\
**Post date:** [March 16, 2022, 2:12pm UTC](https://discourse.julialang.org/t/second-order-2d-differentiation-diffeqoperators-jl/77239/3 "2022-03-16T14:12:59Z")

</div>

Thanks very much for the reply. I had found the src for the multi\_dim\_bc\_operators already but the info on compose is very handy.

I noticed however the performance is not what i would like it to be. I will respond later with a concrete example.  
I do get this warning however is this of any significance?

```julia
┌ Warning: #= C:\Users\siemd\.julia\packages\DiffEqOperators\z4eVP\src\derivative_operators\convolutions.jl:419 =#:
│ `LoopVectorization.check_args` on your inputs failed; running fallback `@inbounds @fastmath` loop instead.
│ Use `warn_check_args=false`, e.g. `@turbo warn_check_args=false ...`, to disable this warning.
└ @ DiffEqOperators C:\Users\siemd\.julia\packages\LoopVectorization\kVenK\src\condense_loopset.jl:825

```

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [March 16, 2022, 3:23pm UTC](https://discourse.julialang.org/t/second-order-2d-differentiation-diffeqoperators-jl/77239/4 "2022-03-16T15:23:35Z")

</div>

> [@Siempie](#):
>
> I do get this warning however is this of any significance?
> 
> ```julia
> 
> ```

It is of significance for why it would be slower than expected 😅

---

<div class="post-metadata">

**Author:** ![Siempie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/siempie/32/32790_2.png) [@Siempie](https://discourse.julialang.org/u/Siempie)\
**Post date:** [March 17, 2022, 3:19pm UTC](https://discourse.julialang.org/t/second-order-2d-differentiation-diffeqoperators-jl/77239/5 "2022-03-17T15:19:08Z")

</div>

I figured.

I have done some concrete comparisons of the differentiation using DiffEqOperators and my own simple implementations.

For the 1D case i used a simple finite difference Matrix multiplication compared to DiffEqOperators.  
For this i found similar performance.

In de 2D case however i found DiffEqOperators.jl to be ~100x slower.  
For my own implementation i used this method:  
[Kronecker sum Laplacian](https://en.wikipedia.org/wiki/Kronecker_sum_of_discrete_Laplacians)  
And the following implementation for DiffEqOperators

```julia
Qx, Qy = Dirichlet0BC(Float64, size(u));
Dxx = CenteredDifference{1}(2,2,dx,N);
Dyy = CenteredDifference{2}(2,2,dx,N);
A = (Dxx + Dyy)*compose(Qx, Qy);
A*u

```

Which gives me these warnings:

```julia
┌ Warning: #= C:\Users\siemd\.julia\packages\DiffEqOperators\Xddum\src\derivative_operators\convolutions.jl:79 =#:
│ `LoopVectorization.check_args` on your inputs failed; running fallback `@inbounds @fastmath` loop instead.
│ Use `warn_check_args=false`, e.g. `@turbo warn_check_args=false ...`, to disable this warning.
└ @ DiffEqOperators C:\Users\siemd\.julia\packages\LoopVectorization\wLMFa\src\condense_loopset.jl:825
┌ Warning: #= C:\Users\siemd\.julia\packages\DiffEqOperators\Xddum\src\derivative_operators\convolutions.jl:49 =#:
│ `LoopVectorization.check_args` on your inputs failed; running fallback `@inbounds @fastmath` loop instead.
│ Use `warn_check_args=false`, e.g. `@turbo warn_check_args=false ...`, to disable this warning.
└ @ DiffEqOperators C:\Users\siemd\.julia\packages\LoopVectorization\wLMFa\src\condense_loopset.jl:825
┌ Warning: #= C:\Users\siemd\.julia\packages\DiffEqOperators\Xddum\src\derivative_operators\convolutions.jl:98 =#:
│ `LoopVectorization.check_args` on your inputs failed; running fallback `@inbounds @fastmath` loop instead.
│ Use `warn_check_args=false`, e.g. `@turbo warn_check_args=false ...`, to disable this warning.
└ @ DiffEqOperators C:\Users\siemd\.julia\packages\LoopVectorization\wLMFa\src\condense_loopset.jl:825

```

I updated all my packages but still receive these warnings.  
And using Julia version 1.6.3.  
What can i do to fix these warnings and improve performance?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [March 17, 2022, 11:42pm UTC](https://discourse.julialang.org/t/second-order-2d-differentiation-diffeqoperators-jl/77239/6 "2022-03-17T23:42:18Z")

</div>

MethodOfLines.jl is just a better way to do it. DiffEqOperators.jl has been effectively deprecated for years.
