1
$\begingroup$

I am trying to numerically solve the Poisson's equation

$$ u_{xx} + u_{yy} = - \cos(x) \quad \text{if} - \pi/2 \leq x \leq \pi/2 \quad \text{0 otherwise} $$

The domain is the rectangle with vertices $(-π, 0), (-π,2), (π,0)$ and $(π,2)$. The boundary conditions are mixed:

Dirichlet: $u(x,0) = 0$ Neumann: $u_y(x,2) = 0$ Periodic: $u(-\pi,0) = u(\pi,0) = 0$.

I have the code written, but I can't figure out why my code isn't plotting the correct solution.

My solution:

enter image description here

Correct solution:

https://capture.dropbox.com/4hzsLwatNsc05Fhl

Here is my code:

import numpy as np
from scipy.sparse import diags, csc_matrix
from scipy.sparse.linalg import spsolve
import matplotlib.pyplot as plt
import seaborn as sns
import math

x_min = -np.pi #Left endpoint of x interval
x_max = np.pi  #Right endpoint of x interval
y_min = 0      #Left endpoint of y interval
y_max = 2      #Right endpoint of y interval

nx = 50                                     # Number of grid points in x
ny = 50                                     # Number of grid points in y
dx = (x_max - x_min)/nx                    # Spacing in x direction
dy = (y_max - y_min)/ny                    # Spacing in y direction
n = nx*ny                                  # Dimension of system
x = np.linspace(x_min, x_max-dx, nx)       # Grid points in x-direction
y = np.linspace(y_min+dy, y_max, ny)       # Grid points in y-direction
xg, yg = np.meshgrid(x, y)     

# Create the diagonals
ones = np.full(n, 1)

a=np.ones(ny-1,dtype='float')
b=np.array([0.0],dtype='float')
c=np.concatenate((a,b),axis=0)
upper_diagonal = np.tile(c,nx)

d=np.ones(ny-2,dtype='float')
e=np.array([2.0,0.0],dtype='float')
f=np.concatenate((d,e),axis=0)
lower_diagonal = np.tile(f,nx)

# Create the offsets
offsets = [0, -1, 1, ny, -ny, (nx-1)*ny, -(nx-1)*ny]

# Create the sparse matrix
A = diags([-2*ones/dx**2 -2*ones/dy**2,lower_diagonal/dx**2,upper_diagonal/dx**2,ones/dy**2,ones/dy**2,ones/dy**2,ones/dy**2], offsets, shape=(n, n), dtype=float)

# Construct the RHS
b = np.zeros((ny,nx),dtype=float)

for j in range(nx):
    
    #for i in range(ny):
    
    if abs(x[j]) <= np.pi/2:    

        b[:,j] = -np.cos( x[j] )

b1 = b.reshape(n,1)

#Solve the linear system using a sparse matrix solver
As = csc_matrix(A)
bs = csc_matrix(b1)
u = spsolve(As, bs).reshape(ny, nx)

#Plot the solution
fig = plt.figure(figsize=(8, 8))
ax = plt.axes(projection='3d')
surf = ax.plot_surface(xg, yg, u)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('u');
plt.show()

The only mistake I can think of is in the construction of the matrix $A$. Because I have been able to write a similar code where I can solve a number of BVPs with all Dirichlet conditions. So I must not be taking into account the Neumann and periodic boundary conditions correctly into account. However, I think the matrices I generate are correct. For instance, here's the heatmap of the matrix when $n_y = 7, n_x = 4$:

enter image description here

For simplicity, I have shown the matrix prior to having divided each entry by $\delta x, \delta y$. The distribution of $-4, 1, 2$'s seems right to me, so I don't know what's going wrong. Suggestions?

$\endgroup$
3
  • $\begingroup$ Did you make a new account to repost a slight variant of your earlier question? scicomp.stackexchange.com/questions/42616/… $\endgroup$
    – whpowell96
    Commented Mar 16, 2023 at 1:18
  • $\begingroup$ Yes, actually I have solved the problem where I had all Dirichlet conditions. This was a test case. I am now dealing with the case of mixed boundary conditions. I think the matrix is right, but I'm getting a wrong answer. $\endgroup$
    – user82261
    Commented Mar 16, 2023 at 1:34
  • $\begingroup$ Then, it might be a good idea to post the solution to your first question fisrt. $\endgroup$
    – nicoguaro
    Commented Mar 18, 2023 at 21:17

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.