Consider a problem of solving $$ \begin{align*} -\Delta u &= f, \\ u|_\Gamma &= 0. \end{align*} $$ by a spectral method, where $\Omega = [0,1]^2$ is a unit square and $\Gamma=\partial\Omega$.

In a spectral method you will be working with a representation of the solution in the form $$ u(x,y) = \sum_{i=1}^N \sum_{j=1}^N \hat{u}_{i,j} \sin(\pi i x) \sin(\pi j y), $$ where $\hat{u}^N$ is just an $N\times N$ array.

Knowing $u(x,y)$, it is often practically not possible to compute $\hat{u}_{i,j}$ exactly. Hence one needs to use the Discrete Sine Transform (DST).
The python's `dst` computes a one-dimensional DST, but we need a two-dimensional (2D) DST, which we compute in the following way:

Compute values $u(x,y)$ for $N^2$ points inside the domain $(x,y) = (h k, h \ell)$, $1\leq k,\ell \leq N$, $h = 1/(N+1)$.

Apply

`dst`to each line in this array. This way you will be computing a "partial" 2D DST $$ u(x,y) = \sum_{j=1}^N \tilde{u}_{j}(x) \sin(\pi j y), $$Apply

`dst`to each column in the resulting array. This way you will be computing a full 2D DST.

Part (a)

- Take $u^0(x,y) = \sin(\pi x) \sin(\pi y)$ and compute $f = -\Delta u^0$.
**(6pt)**Calculate, explicitly, the coefficients $\hat{f}_{i,j}$ in $$ f(x,y) = \sum_{i=1}^N \sum_{j=1}^N \hat{f}_{i,j} \sin(\pi i x) \sin(\pi j y). $$ Then, using values of $f$ at $N^2$ points, calculate the coefficients $\hat{f}^{N}_{i,j}$ by the procedure outlined above. (Here $\hat{f}$ is an "infinite array" that you will compute explicitly, while $\hat{f}^N$ will be an NxN array that you will compute using python.) Compare $\hat{f}$ and $\hat{f}^N$.In this case, obviously, a solution to the problem is $u=u_0$, but let us now pretend we do not know it.

**(6pt)**Compute the coefficients $\hat{u}^N$ from $\hat{f}^N$ found in part (a).**(6pt)**We will estimate the error between the two solutions in the following way. We will take $N^2$ points in our domain, of the form $(h k, h \ell)$, same as before. We will then be interested in $$ {\rm err}_N = \max_{1\leq k,\ell\leq N} |u^N(h k, h \ell) - u^0(h k, h \ell)| $$ which we call an error of the solution. Calculate the error of your solution for a number of values of $N$. Explain your results

Part (b)

- Let us now take something a little more complicated, $$ u^0(x,y) = \sin(\pi x^2) \sin(\pi y^2), \qquad\text{and}\qquad f = -\Delta u_0, $$
- You cannot compute the coefficients $\hat{f}$ explicitly, so you'll have to live with only $\hat{f}^N$.
**(6pt)**Compute $\hat{u}^N$, the error ${\rm err}_N$, and report the error for different values of $N$. Would you say the error decays fast as $N$ increases?- Suppose that the spectral method has an order of convergence, in other words the error behaves like ${\rm err}_N = C N^{-\rm ord}$ and you need to find ${\rm ord}$.
**(6pt)**Derive the formula $$ {\rm ord}_N = \frac{\ln({\rm err}_N)-\ln({\rm err}_{2N})}{\ln(2)} $$**(6pt)**Hence compute ${\rm ord}_N$ for $N=1,\ldots,20$ and comment on your results. (You should start with taking each value of $N$ between 1 and 20 to understand the behavior, but you don't need to present all these numbers in your report, as long as you can illustrate the right behavior.)

Part (c)

- Let us now play a "fair game": take $$ f(x,y) = 1. $$ We then do not know the solution.
- Use your code from part (b) to compute $\hat{f}^N$, and $\hat{u}^N$.
**(6t)**Instead of the exact error we have to use the error estimate $$ {\rm errest}_N = \max_{1\leq k,\ell\leq N} |u^N(h k, h \ell) - u^{2N+1}(h k, h \ell)| $$ (Why did we take $2N+1$ instead $2N$?) Report the values of ${\rm errest}_N$ for a sequence of values of $N$.**(6pt)**Hence compute ${\rm errest}_N$ for a sequence of $N$ and comment on your results.**(6pt)**Finally, using the same formula (but with ${\rm errest}$), $$ {\rm ord}_N = \frac{\ln({\rm errest}_N)-\ln({\rm errest}_{2N})}{\ln(2)} $$ compute ${\rm ord}_N$ for a squence of values of $N$. Comment on your results.

**(6pt)**Compare the behavior for ${\rm err}$, ${\rm errest}$, and ${\rm ord}$ for parts (b) and (c). What is the main reason for the qualitative difference in the speed of convergence?

Consider a Poisson equation $$ \begin{align*} -\Delta u &= f, \\ u|_\Gamma &= 0, \end{align*} $$ where $\Omega = [0,1]^d$, $d = 2, 3$ and $\Gamma=\partial\Omega$.

Although the multigrid method has optimal complexity, there are some precomputations to be done. Therefore, it may have a bigger constant than, for instance, the spectral method or even sparse LU. In this problem you will be asked to find out in which case (2D, 3D, grid sizes) multigrid method is more appropriate.

- (
**20 pts**) Implement V- and W-cycles of multigrid method for $d=2$ and $d=3$. Assume that the equations are discretized with finite differences with the standard second order "cross" stencil.**Note:**all operations should be implemented with linear complexity. Take a smoother of your choice.

- (
**5 pts**) Set $N=128$. Choose $f$ such that you know analytical solution. Plot errors as a function of the cycle number for the implemented V-,W-cycles of GMG and for AMG (from PyAMG), $d=2$ and $d=3$. Which approach requires fewer number of iterations? Which approach is faster?**Note:**when doing plottings do not forget to inculde title and axes names

- (
**5 pts**) Implement a spectral method for $d=3$. Implement fast Poisson solver for $d=2$ and $d=3$: the only difference with the spectral method will be eigenvalues $$\lambda_{mn} = -\frac{4}{h^2} \left( \sin^2 \frac{\pi m h}{2} + \sin^2 \frac{\pi n h}{2} \right),$$ (eigenvalues of the discrete problem ($d=2$) with the "cross" stencil) instead of $$ \lambda_{mnl} = -\pi^2(m^2 + n^2) $$ (exact eigenvalues of the initial continuous problem).

- (
**10 pts**) Set $f\equiv1$. Investigate when (for what cases) GMG is more appropriate than the sparse LU, the spectral method or the fast Poisson solver. To do so compare timings for different $N$, $d$ and accuracies. Make conclusions.

```
In [1]:
```from IPython.core.display import HTML
def css_styling():
styles = open("./styles/alex.css", "r").read()
return HTML(styles)
css_styling()

```
Out[1]:
```