0

I am looking to integrate the difference between my numerical and exact solution to the heat equation though I am not sure what would be the best to way to tackle this. Is there a specific integrator that would allow me to do this ? I hope to integrate it wrt to $x$.

I have the following code so far:

import numpy as np 
from matplotlib import pyplot 
from mpl_toolkits.mplot3d import Axes3D
from scipy import linalg
import matplotlib.pyplot as plt
import math


def initial_data(x):
    y = np.zeros_like(x)
    for i in range(len(x)):
        if (x[i] < 0.25):
            y[i] = 0.0
        elif (x[i] < 0.5):
            y[i] = 4.0 * (x[i] - 0.25)
        elif (x[i] < 0.75):
            y[i] = 4.0 * (0.75 - x[i])
        else:
            y[i] = 0.0

    return y

def heat_exact(x, t, kmax = 150):
    """Exact solution from separation of variables"""

    yexact = np.zeros_like(x)
    for k in range(1, kmax):
        d = -8.0* 
      (np.sin(k*np.pi/4.0)-2.0*np.sin(k*np.pi/2.0)+np.sin(3.0*k*np.pi/4.0))/((np.pi*k)**2)
         yexact += d*np.exp(-(k*np.pi)**2*t)*np.sin(k*np.pi*x)

     return yexact

def ftcs_heat(y, ynew, s):
    ynew[1:-1] = (1 - 2.0 * s) * y[1:-1] + s * (y[2:] + y[:-2])
    # Trivial boundary conditions
    ynew[0] = 0.0
    ynew[-1] = 0.0

Nx = 198
h = 1.0 / (Nx + 1.0)
t_end = 0.25
s = 1.0 / 3.0 # s = delta / h^2
delta = s * h**2
Nt = int(t_end / delta)+1

x = np.linspace(0.0, 1.0, Nx+2)
y = initial_data(x)
ynew = np.zeros_like(y)
for n in range(Nt):
    ftcs_heat(y, ynew, s)
    y = ynew


fig = plt.figure(figsize=(8,6))
ax = fig.add_subplot(111)
x_exact = np.linspace(0.0, 1.0, 200)
ax.plot(x, y, 'kx', label = 'FTCS')
ax.plot(x_exact, heat_exact(x_exact, t_end), 'b-', label='Exact solution')
ax.legend()
plt.show()


diff = (y - heat_exact(x_exact,t_end))**2 # squared difference between numerical and exact solutions 

x1 = np.trapz(diff, x=x)  #(works!) 
import scipy.integrate as integrate

x1 = integrate.RK45(diff,diff[0],0,t_end) #(preferred but does not work)

What I am looking to integrate is the variable diff (the squared difference). Any suggestions are welcomed, thanks.

Edit: I would like to use RK45 method however I am not sure what should my y0 be, I have tried x1 = integrate.RK45(diff,diff[0],0,t_end) but get the following output error:

  raise ValueError("`y0` must be 1-dimensional.")

  ValueError: `y0` must be 1-dimensional.
nycetc
  • 1
  • 1

1 Answers1

0

By integration you mean you want to find the area between y and heat_exact? Or do you want to know if they are the same within a specific limit? The latter can be found with numpy.isclose. The former you can use several integration functions builtin numpy.

For example:

np.trapz(diff, x=x)

Oh, shouldn't the last line be diff = (y - heat_exact(x_exact,t_end))**2? My integration of this diff gave 8.32E-12, which looks right judging by the plots you gave me.

Check out also scipy.integrate

K.Cl
  • 1,615
  • 2
  • 9
  • 18
  • Yes I need to use an integration function. Also thanks for pointing out my brackets misplacement! I am though unable to implement rk.45 method which would be the ideal solver to tackle this question. The trapezium method does work though and the result is as expected. I have edited the code to include for the error I now get when trying to implement `scipy.integrate.rk45` – nycetc Jan 09 '20 at 23:08
  • Ok, there's two points I think should be raised. Regarding your error, if you replace `0` by `np.array([0])`, you will supply it with a 1-dimensional array, but you'll get the error `TypeError: 'numpy.ndarray' object is not callable`. From what I can tell, `rk45` works with functions, and `diff` is a numpy array. You should provide `rk45` with what the documentations says it's the `Right-hand side of the system`. I do not know your system, and my ODE knowledge is lacking to say the least. You should define a Python function analogous to the right side of the system and provide it. – K.Cl Jan 09 '20 at 23:36
  • Also, check [this](https://stackoverflow.com/questions/51575544/two-body-problem-scipy-integrate-rk45-gives-broadcasting-error-and-scipy-integr), [this](https://readthedocs.org/projects/idesolver/downloads/pdf/latest/) and [this](https://www.reddit.com/r/learnpython/comments/969gps/what_did_i_miss_while_using_scipyintegraterk45/). Might point you to the right direction. – K.Cl Jan 09 '20 at 23:50