# 2021-10-08 Finite Difference in 2D

## Last time

* Accuracy vs cost tradeoffs for ODE integrators
* Stiff and non-stiff problems, discussion of costs

## Today

* FD methods in 2D
* Cost profile
* The need for fast algebraic solvers


```julia
using Plots
using LinearAlgebra
using SparseArrays
using Zygote

default(linewidth=4)

function newton(residual, jacobian, u0; maxits=20)
    u = u0
    uhist = [copy(u)]
    normhist = []
    for k in 1:maxits
        f = residual(u)
        push!(normhist, norm(f))
        J = jacobian(u)
        delta_u = - J \ f
        u += delta_u
        push!(uhist, copy(u))
    end
    uhist, normhist
end

function plot_stability(Rz, title; xlims=(-2, 2), ylims=(-2, 2))
    x = LinRange(xlims[1], xlims[2], 100)
    y = LinRange(ylims[1], ylims[2], 100)
    heatmap(x, y, (x, y) -> abs(Rz(x + 1im*y)), c=:bwr, clims=(0, 2), aspect_ratio=:equal, title=title)
end
```




    plot_stability (generic function with 1 method)



# Extending advection-diffusion to 2D

## 1 dimension

\begin{align} u_t + (- \kappa u_x + w u)_x &= f(x) & \text{ on } \Omega &= (a,b) \\
u(a) &= g_D(a) & u'(b) &= g_N(b) \end{align}

* Cell Peclet number $\mathrm{Pe}_h = \frac{\lvert w \rvert h}{\kappa}$
  * $\mathrm{Pe}_h \lesssim 1$ avoids oscillations
  * $\mathrm{Pe}_h \gtrsim 1$ is non-stiff for time-dependent model
* Centered versus upwind for advection
* Need uniformly bounded $\kappa \ge \epsilon > 0$
* "Strong form" not defined at discontinuities in $\kappa$
  * Works okay using divergence form and fluxes at staggered points

## 2 dimensions

\begin{align} u_t + \nabla\cdot\big(- \kappa \nabla u + \mathbf{w} u \big) &= f(x,y) & \text{ on } \Omega & \subset \mathbb R^2 \\
u|_{\Gamma_D} &= g_D(x,y) \\
(-\kappa \nabla u + \mathbf w u) \cdot \hat n|_{\Gamma_N} &= g_N(x,y)
\end{align}

* $\Omega$ is some well-connected open set (we will assume simply connected) and the Dirichlet boundary $\Gamma_D \subset \partial \Omega$ is nonempty.
* Finite difference methods don't have an elegant/flexible way to specify boundaries
* We'll choose $\Omega = (-1, 1) \times (-1, 1)$

# On finite difference grids

* Non-uniform grids can mesh "special" domains
  * Rare in 3D; overset grids, immersed boundary methods
* Concept of staggering is complicated/ambiguous

<div>


</div>



# Time-independent advection-diffusion

## Advection

$$ \nabla\cdot(\mathbf w u) = \mathbf w \cdot \nabla u + (\nabla\cdot \mathbf w) u$$

If we choose divergence-free $\mathbf w$, we can use the stencil

$$ \mathbf w \cdot \nabla u \approx \frac 1 h \begin{bmatrix}
& w_2 & \\
-w_1 & & w_1 \\
& -w_2 &
\end{bmatrix} \!:\! \begin{bmatrix}
u_{i-1, j+1} & u_{i, j+1} & u_{i+1,j+1} \\
u_{i-1, j} & u_{i, j} & u_{i+1,j} \\
u_{i-1, j-1} & u_{i, j-1} & u_{i+1,j-1} \\
\end{bmatrix}
$$

# Diffusion

$$ -\nabla\cdot(\kappa \nabla u) = -\kappa \nabla\cdot \nabla u - \nabla\kappa\cdot \nabla u$$
* When would you trust this decomposition?
* If we have constant $\kappa$, we can write
$$
-\kappa \nabla\cdot \nabla u \approx \frac{\kappa}{h^2} \begin{bmatrix}
& -1 & \\
-1 & 4 & -1 \\
& -1 &
\end{bmatrix} \!:\! \begin{bmatrix}
u_{i-1, j+1} & u_{i, j+1} & u_{i+1,j+1} \\
u_{i-1, j} & u_{i, j} & u_{i+1,j} \\
u_{i-1, j-1} & u_{i, j-1} & u_{i+1,j-1} \\
\end{bmatrix}
$$

# Advection-diffusion in code


```julia
function advdiff_matrix(n; kappa=1, wind=[1, 1]/sqrt(2))
    h = 2 / n
    rows = Vector{Int64}()
    cols = Vector{Int64}()
    vals = Vector{Float64}()
    idx(i, j) = (i-1)*n + j
    stencil_advect = [-wind[1], -wind[2], 0, wind[1], wind[2]] / h
    stencil_diffuse = [-1, -1, 4, -1, -1] * kappa / h^2
    for i in 1:n
        for j in 1:n
            if i in [1, n] || j in [1, n]
                push!(rows, idx(i, j))
                push!(cols, idx(i, j))
                push!(vals, 1.)
            else
                append!(rows, repeat([idx(i,j)], 5))
                append!(cols, [idx(i-1,j), idx(i,j-1), idx(i,j), idx(i+1,j), idx(i,j+1)])
                append!(vals, stencil_advect + stencil_diffuse)
            end
        end
    end
    sparse(rows, cols, vals)
end
```




    advdiff_matrix (generic function with 1 method)



# Spy the matrix


```julia
A = advdiff_matrix(10, wind=[1, 3], kappa=.1)
clim = norm(vec(A), Inf)
spy(A, marker=(:square, 3), c=:bwr, clims=(-clim, clim))
```




    

    




```julia
A = advdiff_matrix(20, wind=[0, 0], kappa=.1)
ev = eigvals(Matrix(A))
scatter(real(ev), imag(ev))
```




    

    



# Plot a solution


```julia
n = 100
x = LinRange(-1, 1, n)
y = x
f = cos.(pi*x/2) * cos.(pi*y/2)'
heatmap(x, y, f, aspect_ratio=:equal)
```




    

    




```julia
A = advdiff_matrix(n, wind=[3,1], kappa=.01)
u = A \ vec(f)
heatmap(x, y, reshape(u, n, n), aspect_ratio=:equal)
```




    

    



* What happens when advection dominates?
* As you refine the grid?

# Cost breadown and optimization


```julia
using ProfileSVG
function assemble_and_solve(n)
    A = advdiff_matrix(n)
    x = LinRange(-1, 1, n)
    f = cos.(pi*x/2) * cos.(pi*x/2)'
    u = A \ vec(f)
end

@profview assemble_and_solve(600)
```




<!DOCTYPE html>
<html>
<body>
<svg version="1.1" width="960" height="436" viewBox="0 0 960 436"
     xmlns="http://www.w3.org/2000/svg" id="fig-6326d75e0427416a8c634688d8688ffe">
<defs>
    <clipPath id="fig-6326d75e0427416a8c634688d8688ffe-clip">
        <rect x="0" y="0" width="960" height="436"/>
    </clipPath>
</defs>
<style type="text/css">
    #fig-6326d75e0427416a8c634688d8688ffe text {
        pointer-events: none;
        font-family: inherit;
        font-size: 12px;
        fill: #000000;
    }
    text#fig-6326d75e0427416a8c634688d8688ffe-caption {
        font-size: 16.8px;
        fill: #000000;
        text-anchor: middle;
    }
    #fig-6326d75e0427416a8c634688d8688ffe-bg {
        fill: #FFFFFF;
    }
    #fig-6326d75e0427416a8c634688d8688ffe-viewport rect, #fig-6326d75e0427416a8c634688d8688ffe-viewport path {
        vector-effect: non-scaling-stroke;
        fill-opacity: 1;
    }
    #fig-6326d75e0427416a8c634688d8688ffe-viewport text {
        stroke: #000000;
        stroke-width: 0;
        stroke-opacity: 0.35;
    }
    #fig-6326d75e0427416a8c634688d8688ffe-viewport rect:hover, #fig-6326d75e0427416a8c634688d8688ffe-viewport path:hover {
        fill-opacity: 0.75;
        stroke: #000000;
        stroke-width: 0.5;
    }
    #fig-6326d75e0427416a8c634688d8688ffe-viewport + rect {
        fill: #FFFFFF;
        opacity: 0.8;
    }
    text#fig-6326d75e0427416a8c634688d8688ffe-details{
        fill: #000000;
    }
</style>
<g id="fig-6326d75e0427416a8c634688d8688ffe-frame" clip-path="url(#fig-6326d75e0427416a8c634688d8688ffe-clip)">
<rect id="fig-6326d75e0427416a8c634688d8688ffe-bg" x="0" y="0" width="960" height="436"/>
<text id="fig-6326d75e0427416a8c634688d8688ffe-caption" x="480" y="24">Profile results</text>
<g id="fig-6326d75e0427416a8c634688d8688ffe-viewport" transform="scale(1)">
<rect x="10" y="383" width="940.57" height="15" rx="2" fill="#FFA000" data-dinfo=""/>
<text x="10" dx="4" y="394.25"> in :-1</text>
<rect x="31.7" y="368" width="908.02" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="31.7" dx="4" y="379.25">#15 in task.jl:411</text>
<rect x="31.7" y="353" width="908.02" height="15" rx="2" fill="#E1B2FF" data-dinfo="/home/jed/.julia/packages/IJulia/e8kqU/src/"/>
<text x="31.7" dx="4" y="364.25">eventloop in eventloop.jl:8</text>
<rect x="31.7" y="338" width="908.02" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="31.7" dx="4" y="349.25">invokelatest in essentials.jl:706</text>
<rect x="31.7" y="323" width="908.02" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="31.7" dx="4" y="334.25">#invokelatest#2 in essentials.jl:708</text>
<rect x="31.7" y="308" width="908.02" height="15" rx="2" fill="#00B58B" data-dinfo="/home/jed/.julia/packages/IJulia/e8kqU/src/"/>
<text x="31.7" dx="4" y="319.25">execute_request in execute_request.jl:67</text>
<rect x="31.7" y="293" width="908.02" height="15" rx="2" fill="#E1B2FF" data-dinfo="/home/jed/.julia/packages/SoftGlobalScope/u4UzH/src/"/>
<text x="31.7" dx="4" y="304.25">softscope_include_string in SoftGlobalScope.jl:65</text>
<rect x="31.7" y="278" width="908.02" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="31.7" dx="4" y="289.25">include_string in loading.jl:1116</text>
<rect x="31.7" y="263" width="908.02" height="15" rx="2" fill="#F3004D" data-dinfo="./"/>
<text x="31.7" dx="4" y="274.25">eval in boot.jl:360</text>
<rect x="66.6" y="248" width="98.59" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="66.6" dx="4" y="259.25">assemble_and_solve in In[133]:3</text>
<rect x="66.6" y="233" width="98.12" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="66.6" dx="4" y="244.25">advdiff_matrix in In[131]:2</text>
<rect x="66.6" y="218" width="21.7" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="66.6" dx="4" y="229.25">#advdiff_matrix#21 in In[131]:11</text>
<rect x="66.6" y="203" width="21.23" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="66.6" dx="4" y="214.25">vect in array.jl:108</text>
<rect x="66.6" y="188" width="19.34" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="66.6" dx="4" y="199.25">_array_for in array.jl:670</text>
<rect x="66.6" y="173" width="19.34" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="66.6" dx="4" y="184.25">_array_for in array.jl:672</text>
<rect x="66.6" y="158" width="19.34" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="66.6" dx="4" y="169.25">similar in abstractarray.jl:784</text>
<rect x="66.6" y="143" width="19.34" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="66.6" dx="4" y="154.25">similar in abstractarray.jl:785</text>
<rect x="66.6" y="128" width="19.34" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="66.6" dx="4" y="139.25">Array in boot.jl:457</text>
<rect x="66.6" y="113" width="19.34" height="15" rx="2" fill="#FFA000" data-dinfo="./"/>
<text x="66.6" dx="4" y="124.25">Array in boot.jl:448</text>
<rect x="67.08" y="98" width="0.47" height="15" rx="2" fill="#00B58B" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="67.08" dx="4" y="109.25">umfpack_free_symbolic in umfpack.jl:591</text>
<rect x="67.08" y="83" width="0.47" height="15" rx="2" fill="#E1B2FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="67.08" dx="4" y="94.25">umfpack_free_numeric in umfpack.jl:606</text>
<rect x="67.08" y="68" width="0.47" height="15" rx="2" fill="#F6A60A" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="67.08" dx="4" y="79.25">umfpack_dl_free_numeric in umfpack.jl:602</text>
<rect x="85.94" y="188" width="1.89" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="85.94" dx="4" y="199.25">setindex! in array.jl:843</text>
<rect x="87.83" y="203" width="0.47" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="87.83" dx="4" y="214.25">in in operators.jl:1136</text>
<rect x="87.83" y="188" width="0.47" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="87.83" dx="4" y="199.25">iterate in array.jl:781</text>
<rect x="87.83" y="173" width="0.47" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="87.83" dx="4" y="184.25">&amp;lt; in int.jl:448</text>
<rect x="87.83" y="158" width="0.47" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="87.83" dx="4" y="169.25">&amp;lt; in int.jl:441</text>
<rect x="88.3" y="218" width="18.87" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="88.3" dx="4" y="229.25">#advdiff_matrix#21 in In[131]:16</text>
<rect x="88.3" y="203" width="6.61" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="88.3" dx="4" y="214.25">repeat in abstractarraymath.jl:224</text>
<rect x="88.3" y="188" width="6.61" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="88.3" dx="4" y="199.25">repeat##kw in abstractarraymath.jl:267</text>
<rect x="88.3" y="173" width="6.61" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="88.3" dx="4" y="184.25">#repeat#1 in abstractarraymath.jl:269</text>
<rect x="88.3" y="158" width="6.61" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="88.3" dx="4" y="169.25">repeat_inner_outer in abstractarraymath.jl:327</text>
<rect x="88.3" y="143" width="4.25" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="88.3" dx="4" y="154.25">repeat_outer in abstractarraymath.jl:347</text>
<rect x="88.3" y="128" width="4.25" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="88.3" dx="4" y="139.25">similar in array.jl:357</text>
<rect x="88.3" y="113" width="4.25" height="15" rx="2" fill="#FFA400" data-dinfo="./"/>
<text x="88.3" dx="4" y="124.25">Array in boot.jl:448</text>
<rect x="92.55" y="143" width="0.47" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="92.55" dx="4" y="154.25">repeat_outer in abstractarraymath.jl:348</text>
<rect x="93.02" y="143" width="1.41" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="93.02" dx="4" y="154.25">repeat_outer in abstractarraymath.jl:350</text>
<rect x="93.02" y="128" width="1.41" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="93.02" dx="4" y="139.25">setindex! in array.jl:870</text>
<rect x="93.02" y="113" width="0.47" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="93.02" dx="4" y="124.25">unsafe_copyto! in array.jl:266</text>
<rect x="93.02" y="98" width="0.47" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="93.02" dx="4" y="109.25">pointer in abstractarray.jl:1119</text>
<rect x="93.02" y="83" width="0.47" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="93.02" dx="4" y="94.25">unsafe_convert in pointer.jl:65</text>
<rect x="93.49" y="113" width="0.94" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="93.49" dx="4" y="124.25">unsafe_copyto! in array.jl:271</text>
<rect x="94.43" y="143" width="0.48" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="94.43" dx="4" y="154.25">repeat_outer in abstractarraymath.jl:352</text>
<rect x="94.91" y="203" width="3.77" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="94.91" dx="4" y="214.25">append! in array.jl:980</text>
<rect x="94.91" y="188" width="3.77" height="15" rx="2" fill="#F6A60A" data-dinfo="./"/>
<text x="94.91" dx="4" y="199.25">_growend! in array.jl:888</text>
<rect x="98.68" y="203" width="1.89" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="98.68" dx="4" y="214.25">append! in array.jl:981</text>
<rect x="98.68" y="188" width="1.89" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="98.68" dx="4" y="199.25">copyto! in array.jl:304</text>
<rect x="100.57" y="203" width="6.6" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="100.57" dx="4" y="214.25">vect in array.jl:108</text>
<rect x="100.57" y="188" width="6.6" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="100.57" dx="4" y="199.25">_array_for in array.jl:670</text>
<rect x="100.57" y="173" width="6.6" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="100.57" dx="4" y="184.25">_array_for in array.jl:672</text>
<rect x="100.57" y="158" width="6.6" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="100.57" dx="4" y="169.25">similar in abstractarray.jl:784</text>
<rect x="100.57" y="143" width="6.6" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="100.57" dx="4" y="154.25">similar in abstractarray.jl:785</text>
<rect x="100.57" y="128" width="6.6" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="100.57" dx="4" y="139.25">Array in boot.jl:457</text>
<rect x="100.57" y="113" width="6.6" height="15" rx="2" fill="#FFA000" data-dinfo="./"/>
<text x="100.57" dx="4" y="124.25">Array in boot.jl:448</text>
<rect x="107.17" y="218" width="13.21" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="107.17" dx="4" y="229.25">#advdiff_matrix#21 in In[131]:17</text>
<rect x="107.17" y="203" width="1.41" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="107.17" dx="4" y="214.25">append! in array.jl:980</text>
<rect x="107.17" y="188" width="1.41" height="15" rx="2" fill="#E4A71C" data-dinfo="./"/>
<text x="107.17" dx="4" y="199.25">_growend! in array.jl:888</text>
<rect x="108.58" y="203" width="0.95" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="108.58" dx="4" y="214.25">append! in array.jl:981</text>
<rect x="108.58" y="188" width="0.48" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="108.58" dx="4" y="199.25">copyto! in array.jl:304</text>
<rect x="109.06" y="188" width="0.47" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="109.06" dx="4" y="199.25">+ in int.jl:87</text>
<rect x="109.53" y="203" width="10.85" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="109.53" dx="4" y="214.25">vect in array.jl:108</text>
<rect x="109.53" y="188" width="10.38" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="109.53" dx="4" y="199.25">_array_for in array.jl:670</text>
<rect x="109.53" y="173" width="10.38" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="109.53" dx="4" y="184.25">_array_for in array.jl:672</text>
<rect x="109.53" y="158" width="10.38" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="109.53" dx="4" y="169.25">similar in abstractarray.jl:784</text>
<rect x="109.53" y="143" width="10.38" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="109.53" dx="4" y="154.25">similar in abstractarray.jl:785</text>
<rect x="109.53" y="128" width="10.38" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="109.53" dx="4" y="139.25">Array in boot.jl:457</text>
<rect x="109.53" y="113" width="10.38" height="15" rx="2" fill="#FFA400" data-dinfo="./"/>
<text x="109.53" dx="4" y="124.25">Array in boot.jl:448</text>
<rect x="119.91" y="188" width="0.47" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="119.91" dx="4" y="199.25">setindex! in array.jl:843</text>
<rect x="120.38" y="218" width="18.87" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="120.38" dx="4" y="229.25">#advdiff_matrix#21 in In[131]:18</text>
<rect x="120.38" y="203" width="4.24" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="120.38" dx="4" y="214.25">append! in array.jl:980</text>
<rect x="120.38" y="188" width="4.24" height="15" rx="2" fill="#F6A60A" data-dinfo="./"/>
<text x="120.38" dx="4" y="199.25">_growend! in array.jl:888</text>
<rect x="124.62" y="203" width="0.95" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="124.62" dx="4" y="214.25">append! in array.jl:981</text>
<rect x="124.62" y="188" width="0.95" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="124.62" dx="4" y="199.25">copyto! in array.jl:304</text>
<rect x="124.62" y="173" width="0.95" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="124.62" dx="4" y="184.25">_copyto_impl! in array.jl:313</text>
<rect x="124.62" y="158" width="0.95" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="124.62" dx="4" y="169.25">unsafe_copyto! in array.jl:271</text>
<rect x="125.57" y="203" width="13.68" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="125.57" dx="4" y="214.25">+ in arraymath.jl:47</text>
<rect x="125.57" y="188" width="13.68" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="125.57" dx="4" y="199.25">broadcast_preserving_zero_d in broadcast.jl:872</text>
<rect x="125.57" y="173" width="13.68" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="125.57" dx="4" y="184.25">materialize in broadcast.jl:883</text>
<rect x="125.57" y="158" width="13.68" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="125.57" dx="4" y="169.25">copy in broadcast.jl:908</text>
<rect x="125.57" y="143" width="0.47" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="125.57" dx="4" y="154.25">copyto! in broadcast.jl:936</text>
<rect x="125.57" y="128" width="0.47" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="125.57" dx="4" y="139.25">copyto! in broadcast.jl:983</text>
<rect x="125.57" y="113" width="0.47" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="125.57" dx="4" y="124.25">macro expansion in simdloop.jl:77</text>
<rect x="125.57" y="98" width="0.47" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="125.57" dx="4" y="109.25">macro expansion in broadcast.jl:984</text>
<rect x="125.57" y="83" width="0.47" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="125.57" dx="4" y="94.25">setindex! in array.jl:843</text>
<rect x="126.04" y="143" width="13.21" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="126.04" dx="4" y="154.25">similar in broadcast.jl:196</text>
<rect x="126.04" y="128" width="13.21" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="126.04" dx="4" y="139.25">similar in broadcast.jl:197</text>
<rect x="126.04" y="113" width="13.21" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="126.04" dx="4" y="124.25">similar in abstractarray.jl:784</text>
<rect x="126.04" y="98" width="13.21" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="126.04" dx="4" y="109.25">similar in abstractarray.jl:785</text>
<rect x="126.04" y="83" width="13.21" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="126.04" dx="4" y="94.25">Array in boot.jl:465</text>
<rect x="126.04" y="68" width="13.21" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="126.04" dx="4" y="79.25">Array in boot.jl:457</text>
<rect x="126.04" y="53" width="13.21" height="15" rx="2" fill="#FFA000" data-dinfo="./"/>
<text x="126.04" dx="4" y="64.25">Array in boot.jl:448</text>
<rect x="139.25" y="218" width="24.52" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="139.25" dx="4" y="229.25">#advdiff_matrix#21 in In[131]:22</text>
<rect x="139.25" y="203" width="24.52" height="15" rx="2" fill="#E1B2FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="139.25" dx="4" y="214.25">sparse in sparsematrix.jl:952</text>
<rect x="139.25" y="188" width="1.88" height="15" rx="2" fill="#2CA3FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="139.25" dx="4" y="199.25">dimlub in sparsematrix.jl:948</text>
<rect x="139.25" y="173" width="1.88" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="139.25" dx="4" y="184.25">maximum in reducedim.jl:873</text>
<rect x="139.25" y="158" width="1.88" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="139.25" dx="4" y="169.25">#maximum#687 in reducedim.jl:873</text>
<rect x="139.25" y="143" width="1.88" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="139.25" dx="4" y="154.25">_maximum in reducedim.jl:877</text>
<rect x="139.25" y="128" width="1.88" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="139.25" dx="4" y="139.25">#_maximum#689 in reducedim.jl:877</text>
<rect x="139.25" y="113" width="1.88" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="139.25" dx="4" y="124.25">_maximum in reducedim.jl:878</text>
<rect x="139.25" y="98" width="1.88" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="139.25" dx="4" y="109.25">#_maximum#690 in reducedim.jl:878</text>
<rect x="139.25" y="83" width="1.88" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="139.25" dx="4" y="94.25">mapreduce in reducedim.jl:310</text>
<rect x="139.25" y="68" width="1.88" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="139.25" dx="4" y="79.25">#mapreduce#672 in reducedim.jl:310</text>
<rect x="139.25" y="53" width="1.88" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="139.25" dx="4" y="64.25">_mapreduce_dim in reducedim.jl:318</text>
<rect x="139.25" y="38" width="1.88" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="139.25" dx="4" y="49.25">_mapreduce in reduce.jl:415</text>
<rect x="141.13" y="188" width="22.64" height="15" rx="2" fill="#00B58B" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="141.13" dx="4" y="199.25">sparse in sparsematrix.jl:956</text>
<rect x="141.13" y="173" width="8.02" height="15" rx="2" fill="#E1B2FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="141.13" dx="4" y="184.25">sparse in sparsematrix.jl:756</text>
<rect x="141.13" y="158" width="8.02" height="15" rx="2" fill="#F6A60A" data-dinfo="./"/>
<text x="141.13" dx="4" y="169.25">Array in boot.jl:448</text>
<rect x="149.15" y="173" width="14.62" height="15" rx="2" fill="#6FDC91" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="149.15" dx="4" y="184.25">sparse in sparsematrix.jl:767</text>
<rect x="149.15" y="158" width="1.89" height="15" rx="2" fill="#2CA3FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="149.15" dx="4" y="169.25">sparse! in sparsematrix.jl:841</text>
<rect x="149.15" y="143" width="1.89" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="149.15" dx="4" y="154.25">iterate in range.jl:674</text>
<rect x="149.15" y="128" width="1.89" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="149.15" dx="4" y="139.25">== in promotion.jl:410</text>
<rect x="151.04" y="158" width="0.47" height="15" rx="2" fill="#00B58B" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="151.04" dx="4" y="169.25">sparse! in sparsematrix.jl:849</text>
<rect x="151.04" y="143" width="0.47" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="151.04" dx="4" y="154.25">setindex! in array.jl:843</text>
<rect x="151.51" y="158" width="0.47" height="15" rx="2" fill="#2CA3FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="151.51" dx="4" y="169.25">sparse! in sparsematrix.jl:857</text>
<rect x="151.51" y="143" width="0.47" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="151.51" dx="4" y="154.25">&amp;gt; in operators.jl:305</text>
<rect x="151.51" y="128" width="0.47" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="151.51" dx="4" y="139.25">&amp;lt; in int.jl:83</text>
<rect x="151.98" y="158" width="1.42" height="15" rx="2" fill="#00B58B" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="151.98" dx="4" y="169.25">sparse! in sparsematrix.jl:861</text>
<rect x="151.98" y="143" width="0.94" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="151.98" dx="4" y="154.25">&amp;gt;= in operators.jl:352</text>
<rect x="151.98" y="128" width="0.94" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="151.98" dx="4" y="139.25">&amp;lt;= in int.jl:442</text>
<rect x="153.4" y="158" width="0.94" height="15" rx="2" fill="#2CA3FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="153.4" dx="4" y="169.25">sparse! in sparsematrix.jl:862</text>
<rect x="153.4" y="143" width="0.94" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="153.4" dx="4" y="154.25">setindex! in array.jl:843</text>
<rect x="154.34" y="158" width="2.83" height="15" rx="2" fill="#00B58B" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="154.34" dx="4" y="169.25">sparse! in sparsematrix.jl:864</text>
<rect x="154.34" y="143" width="1.89" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="154.34" dx="4" y="154.25">getindex in array.jl:805</text>
<rect x="156.23" y="143" width="0.94" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="156.23" dx="4" y="154.25">iterate in range.jl:674</text>
<rect x="156.23" y="128" width="0.94" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="156.23" dx="4" y="139.25">== in promotion.jl:410</text>
<rect x="157.17" y="158" width="0.47" height="15" rx="2" fill="#2CA3FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="157.17" dx="4" y="169.25">sparse! in sparsematrix.jl:875</text>
<rect x="157.17" y="143" width="0.47" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="157.17" dx="4" y="154.25">fill! in array.jl:335</text>
<rect x="157.17" y="128" width="0.47" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="157.17" dx="4" y="139.25">setindex! in array.jl:843</text>
<rect x="157.64" y="158" width="0.94" height="15" rx="2" fill="#00B58B" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="157.64" dx="4" y="169.25">sparse! in sparsematrix.jl:885</text>
<rect x="157.64" y="143" width="0.94" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="157.64" dx="4" y="154.25">!= in operators.jl:204</text>
<rect x="157.64" y="128" width="0.94" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="157.64" dx="4" y="139.25">== in promotion.jl:410</text>
<rect x="158.58" y="158" width="1.89" height="15" rx="2" fill="#2CA3FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="158.58" dx="4" y="169.25">sparse! in sparsematrix.jl:889</text>
<rect x="158.58" y="143" width="1.89" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="158.58" dx="4" y="154.25">+ in int.jl:87</text>
<rect x="160.47" y="158" width="0.47" height="15" rx="2" fill="#00B58B" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="160.47" dx="4" y="169.25">sparse! in sparsematrix.jl:920</text>
<rect x="160.47" y="143" width="0.47" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="160.47" dx="4" y="154.25">- in int.jl:86</text>
<rect x="160.94" y="158" width="0.48" height="15" rx="2" fill="#2CA3FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="160.94" dx="4" y="169.25">sparse! in sparsematrix.jl:922</text>
<rect x="160.94" y="143" width="0.48" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="160.94" dx="4" y="154.25">getindex in array.jl:805</text>
<rect x="161.42" y="158" width="2.35" height="15" rx="2" fill="#00B58B" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="161.42" dx="4" y="169.25">sparse! in sparsematrix.jl:926</text>
<rect x="161.42" y="143" width="0.94" height="15" rx="2" fill="#E1B2FF" data-dinfo="./"/>
<text x="161.42" dx="4" y="154.25">setindex! in array.jl:843</text>
<rect x="162.36" y="143" width="1.41" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="162.36" dx="4" y="154.25">iterate in range.jl:674</text>
<rect x="162.36" y="128" width="1.41" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="162.36" dx="4" y="139.25">== in promotion.jl:410</text>
<rect x="163.77" y="218" width="0.48" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="163.77" dx="4" y="229.25">repeat_outer in abstractarraymath.jl:345</text>
<rect x="164.72" y="233" width="0.47" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="164.72" dx="4" y="244.25">repeat##kw in abstractarraymath.jl:266</text>
<rect x="165.19" y="248" width="774.53" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="165.19" dx="4" y="259.25">assemble_and_solve in In[133]:6</text>
<rect x="165.19" y="233" width="0.47" height="15" rx="2" fill="#E1B2FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="165.19" dx="4" y="244.25">\ in linalg.jl:1564</text>
<rect x="165.19" y="218" width="0.47" height="15" rx="2" fill="#00B58B" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="165.19" dx="4" y="229.25">ishermitian in sparsematrix.jl:3428</text>
<rect x="165.19" y="203" width="0.47" height="15" rx="2" fill="#6FDC91" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="165.19" dx="4" y="214.25">is_hermsym in sparsematrix.jl:3437</text>
<rect x="165.19" y="188" width="0.47" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="165.19" dx="4" y="199.25">copy in array.jl:349</text>
<rect x="165.66" y="233" width="774.06" height="15" rx="2" fill="#6FDC91" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SparseArrays/src/"/>
<text x="165.66" dx="4" y="244.25">\ in linalg.jl:1567</text>
<rect x="165.66" y="218" width="70.28" height="15" rx="2" fill="#2CA3FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/"/>
<text x="165.66" dx="4" y="229.25">\ in factorization.jl:104</text>
<rect x="165.66" y="203" width="70.28" height="15" rx="2" fill="#E1B2FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="165.66" dx="4" y="214.25">ldiv! in umfpack.jl:497</text>
<rect x="165.66" y="188" width="70.28" height="15" rx="2" fill="#00B58B" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="165.66" dx="4" y="199.25">ldiv! in umfpack.jl:510</text>
<rect x="165.66" y="173" width="70.28" height="15" rx="2" fill="#E1B2FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="165.66" dx="4" y="184.25">_Aq_ldiv_B! in umfpack.jl:527</text>
<rect x="165.66" y="158" width="70.28" height="15" rx="2" fill="#2CA3FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="165.66" dx="4" y="169.25">_AqldivB_kernel! in umfpack.jl:532</text>
<rect x="165.66" y="143" width="70.28" height="15" rx="2" fill="#E1B2FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="165.66" dx="4" y="154.25">solve! in umfpack.jl:366</text>
<rect x="235.94" y="218" width="703.78" height="15" rx="2" fill="#00B58B" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="235.94" dx="4" y="229.25">lu in umfpack.jl:155</text>
<rect x="235.94" y="203" width="3.31" height="15" rx="2" fill="#6FDC91" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="235.94" dx="4" y="214.25">#lu#1 in umfpack.jl:156</text>
<rect x="235.94" y="188" width="0.95" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="235.94" dx="4" y="199.25">copy in array.jl:349</text>
<rect x="236.89" y="188" width="2.36" height="15" rx="2" fill="#00B58B" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="236.89" dx="4" y="199.25">decrement in SuiteSparse.jl:15</text>
<rect x="236.89" y="173" width="1.41" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="236.89" dx="4" y="184.25">copy in array.jl:349</text>
<rect x="238.3" y="173" width="0.95" height="15" rx="2" fill="#E1B2FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="238.3" dx="4" y="184.25">decrement! in SuiteSparse.jl:12</text>
<rect x="238.3" y="158" width="0.47" height="15" rx="2" fill="#00B58B" data-dinfo="./"/>
<text x="238.3" dx="4" y="169.25">setindex! in array.jl:843</text>
<rect x="238.77" y="158" width="0.48" height="15" rx="2" fill="#2CA3FF" data-dinfo="./"/>
<text x="238.77" dx="4" y="169.25">iterate in range.jl:674</text>
<rect x="238.77" y="143" width="0.48" height="15" rx="2" fill="#6FDC91" data-dinfo="./"/>
<text x="238.77" dx="4" y="154.25">== in promotion.jl:410</text>
<rect x="239.25" y="203" width="700.47" height="15" rx="2" fill="#E1B2FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="239.25" dx="4" y="214.25">#lu#1 in umfpack.jl:161</text>
<rect x="239.25" y="188" width="700.47" height="15" rx="2" fill="#2CA3FF" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="239.25" dx="4" y="199.25">umfpack_numeric! in umfpack.jl:324</text>
<rect x="239.25" y="173" width="293.39" height="15" rx="2" fill="#6FDC91" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="239.25" dx="4" y="184.25">#umfpack_numeric!#13 in umfpack.jl:325</text>
<rect x="239.25" y="158" width="293.39" height="15" rx="2" fill="#F6A60A" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="239.25" dx="4" y="169.25">umfpack_symbolic! in umfpack.jl:304</text>
<rect x="532.64" y="173" width="407.08" height="15" rx="2" fill="#FFA000" data-dinfo="/build/julia/src/julia-1.6.3/usr/share/julia/stdlib/v1.6/SuiteSparse/src/"/>
<text x="532.64" dx="4" y="184.25">#umfpack_numeric!#13 in umfpack.jl:327</text>
</g></g>



</svg>
</body>
</html>




# What's left?

* Symmetric Dirichlet boundary conditions
* Symmetric Neumann boundary conditions
* Verification with method of manufactured solutions
* Non-uniform grids
* Upwinding for advection-dominated problems
* Variable coefficients
* Time-dependent problems
* Fast algebraic solvers

39d3ea8569bd60bca4a8f01a56338e6f9579aed6
ipynb
Jupyter Notebook
slides/2021-10-08-fd-2d.ipynb
cu-numpde/numpde
e5e1a465a622eba56900004f9a503412407cdccf
MIT
2022-01-01T20:54:51.000Z
2022-01-01T20:54:51.000Z
slides/2021-10-08-fd-2d.ipynb
amta3208/fall21
e5e1a465a622eba56900004f9a503412407cdccf
MIT
slides/2021-10-08-fd-2d.ipynb
amta3208/fall21
e5e1a465a622eba56900004f9a503412407cdccf
MIT
2022-01-01T20:54:46.000Z
2022-01-01T20:54:46.000Z
Qwen/Qwen-72B
1. YES
2. YES