def step4(self): u_old = copy(self.u) u_new = copy(self.u) self.ndd = NewtonDD(self.x, u_old, self.f) f = zeros_like(self.u) v = zeros_like(self.u) for i in range(self.Nb+5, self.N-self.Nb-5): L = self.calc_poly(i, 4) r = i - L if r == -1: v[i] = 25.0/12.0*u_old[i-r+0] - 23.0/12.0*u_old[i-r+1] + 13.0/12.0*u_old[i-r+2] - 1.0/4.0*u_old[i-r+3] elif r == 0: v[i] = 1.0/4.0*u_old[i-r+0] + 13.0/12.0*u_old[i-r+1] - 5.0/12.0*u_old[i-r+2] + 1.0/12.0*u_old[i-r+3] elif r == 1: v[i] = -1.0/12.0*u_old[i-r+0] + 7.0/12.0*u_old[i-r+1] + 7.0/12.0*u_old[i-r+2] - 1.0/12.0*u_old[i-r+3] elif r == 2: v[i] = 1.0/12.0*u_old[i-r+0] - 5.0/12.0*u_old[i-r+1] + 13.0/12.0*u_old[i-r+2] + 1.0/4.0*u_old[i-r+3] elif r == 3: v[i] = -1.0/4.0*u_old[i-r+0] + 13.0/12.0*u_old[i-r+1] - 23.0/12.0*u_old[i-r+2] + 25.0/12.0*u_old[i-r+3] else: print "Error" for i in range(self.Nb+6, self.N-self.Nb-6): self.alpha = 1.01 #f[i] = 0.5*(self.f(v[i]) + self.f(v[i+1]) - self.alpha*(v[i+1]-v[i])) f[i] = self.f(v[i]) for i in range(self.Nb+7, self.N-self.Nb-7): self.u[i] -= self.dt/self.dx*(f[i]-f[i-1])
def newstep(self): u_old = copy(self.u) u_new = copy(self.u) self.ndd = NewtonDD(self.x, u_old, self.f) f = zeros_like(self.u) v = zeros_like(self.u) for i in range(self.Nb+4, self.N-self.Nb-4): L = self.calc_poly(i, 3) r = i - L if r == -1: v[i] = 11.0/6.0*u_old[i-r+0] - 7.0/6.0*u_old[i-r+1] + 1.0/3.0*u_old[i-r+2] elif r == 0: v[i] = 1.0/3.0*u_old[i-r+0] + 5.0/6.0*u_old[i-r+1] - 1.0/6.0*u_old[i-r+2] elif r == 1: v[i] = -1.0/6.0*u_old[i-r+0] + 5.0/6.0*u_old[i-r+1] + 1.0/3.0*u_old[i-r+2] elif r == 2: v[i] = 1.0/3.0*u_old[i-r+0] - 7.0/6.0*u_old[i-r+1] + 11.0/6.0*u_old[i-r+2] else: print "Error" for i in range(self.Nb+5, self.N-self.Nb-5): self.alpha = 1.01 #f[i] = 0.5*(self.f(v[i]) + self.f(v[i+1]) - self.alpha*(v[i+1]-v[i])) f[i] = self.f(v[i]) for i in range(self.Nb+6, self.N-self.Nb-6): self.u[i] -= self.dt/self.dx*(f[i]-f[i-1])
def step(self): u_old = copy(self.u) u_new = copy(self.u) self.ndd = NewtonDD(self.x, u_old, self.f) f = zeros_like(self.u) for i in range(self.Nb, self.N-self.Nb): L = self.calc_poly(i) d = zeros([self.order+1,2]) d[0][0] = 1 d[0][1] = 1 sum = 0 for k in range(self.order): sum += d[k][1]*self.ndd.calc(L, L+k+1) d[k+1][0] = (self.x[i] - self.x[L+k-1])*d[k][0] d[k+1][1] = d[k+1][0] + (self.x[i]-self.x[L+k])*d[k][1] f[i] = sum for i in range(self.Nb+1, self.N-self.Nb-1): self.u[i] -= self.dt/self.dx*(f[i]-f[i-1])
class Solver: def __init__(self): self.N = 100 self.x = linspace(-2,2,self.N+1) self.Nb = 10 self.xc = zeros(self.N) self.u = zeros(self.N) self.cfl = 0.4 for i in range(self.N): self.xc[i] = 0.5*(self.x[i] + self.x[i+1]) if abs(self.xc[i]) < 1/3.0: self.u[i] = 1 self.dx = self.xc[1] - self.xc[0] self.f = Burgers() self.order = 3 def calc_poly(self, i, order): if abs(self.u[i+1]-self.u[i]) > SMALL: abar = (self.f(self.u[i+1]) - self.f(self.u[i]))/(self.u[i+1]-self.u[i]) else: abar = 0 if abar >= 0: k = i else: k = i + 1 L = 2 for i in range(order-1): a = self.ndd.calc(k, k+L) b = self.ndd.calc(k-1, k+L-1) if abs(a) >= abs(b): k = k-1 L += 1 return k def step(self): u_old = copy(self.u) u_new = copy(self.u) self.ndd = NewtonDD(self.x, u_old, self.f) f = zeros_like(self.u) for i in range(self.Nb, self.N-self.Nb): L = self.calc_poly(i) d = zeros([self.order+1,2]) d[0][0] = 1 d[0][1] = 1 sum = 0 for k in range(self.order): sum += d[k][1]*self.ndd.calc(L, L+k+1) d[k+1][0] = (self.x[i] - self.x[L+k-1])*d[k][0] d[k+1][1] = d[k+1][0] + (self.x[i]-self.x[L+k])*d[k][1] f[i] = sum for i in range(self.Nb+1, self.N-self.Nb-1): self.u[i] -= self.dt/self.dx*(f[i]-f[i-1]) def newstep(self): u_old = copy(self.u) u_new = copy(self.u) self.ndd = NewtonDD(self.x, u_old, self.f) f = zeros_like(self.u) v = zeros_like(self.u) for i in range(self.Nb+4, self.N-self.Nb-4): L = self.calc_poly(i, 3) r = i - L if r == -1: v[i] = 11.0/6.0*u_old[i-r+0] - 7.0/6.0*u_old[i-r+1] + 1.0/3.0*u_old[i-r+2] elif r == 0: v[i] = 1.0/3.0*u_old[i-r+0] + 5.0/6.0*u_old[i-r+1] - 1.0/6.0*u_old[i-r+2] elif r == 1: v[i] = -1.0/6.0*u_old[i-r+0] + 5.0/6.0*u_old[i-r+1] + 1.0/3.0*u_old[i-r+2] elif r == 2: v[i] = 1.0/3.0*u_old[i-r+0] - 7.0/6.0*u_old[i-r+1] + 11.0/6.0*u_old[i-r+2] else: print "Error" for i in range(self.Nb+5, self.N-self.Nb-5): self.alpha = 1.01 #f[i] = 0.5*(self.f(v[i]) + self.f(v[i+1]) - self.alpha*(v[i+1]-v[i])) f[i] = self.f(v[i]) for i in range(self.Nb+6, self.N-self.Nb-6): self.u[i] -= self.dt/self.dx*(f[i]-f[i-1]) def step4(self): u_old = copy(self.u) u_new = copy(self.u) self.ndd = NewtonDD(self.x, u_old, self.f) f = zeros_like(self.u) v = zeros_like(self.u) for i in range(self.Nb+5, self.N-self.Nb-5): L = self.calc_poly(i, 4) r = i - L if r == -1: v[i] = 25.0/12.0*u_old[i-r+0] - 23.0/12.0*u_old[i-r+1] + 13.0/12.0*u_old[i-r+2] - 1.0/4.0*u_old[i-r+3] elif r == 0: v[i] = 1.0/4.0*u_old[i-r+0] + 13.0/12.0*u_old[i-r+1] - 5.0/12.0*u_old[i-r+2] + 1.0/12.0*u_old[i-r+3] elif r == 1: v[i] = -1.0/12.0*u_old[i-r+0] + 7.0/12.0*u_old[i-r+1] + 7.0/12.0*u_old[i-r+2] - 1.0/12.0*u_old[i-r+3] elif r == 2: v[i] = 1.0/12.0*u_old[i-r+0] - 5.0/12.0*u_old[i-r+1] + 13.0/12.0*u_old[i-r+2] + 1.0/4.0*u_old[i-r+3] elif r == 3: v[i] = -1.0/4.0*u_old[i-r+0] + 13.0/12.0*u_old[i-r+1] - 23.0/12.0*u_old[i-r+2] + 25.0/12.0*u_old[i-r+3] else: print "Error" for i in range(self.Nb+6, self.N-self.Nb-6): self.alpha = 1.01 #f[i] = 0.5*(self.f(v[i]) + self.f(v[i+1]) - self.alpha*(v[i+1]-v[i])) f[i] = self.f(v[i]) for i in range(self.Nb+7, self.N-self.Nb-7): self.u[i] -= self.dt/self.dx*(f[i]-f[i-1]) def step2(self): u_old = copy(self.u) u_new = copy(self.u) self.ndd = NewtonDD(self.x, u_old, self.f) f = zeros_like(self.u) v = zeros_like(self.u) for i in range(self.Nb+5, self.N-self.Nb-5): L = self.calc_poly(i, 2) r = i - L if r == -1: v[i] = 3.0/2.0*u_old[i-r+0] - 1.0/2.0*u_old[i-r+1] elif r == 0: v[i] = 1.0/2.0*u_old[i-r+0] + 1.0/2.0*u_old[i-r+1] elif r == 1: v[i] = -1.0/2.0*u_old[i-r+0] + 3.0/2.0*u_old[i-r+1] else: print "Error" for i in range(self.Nb+6, self.N-self.Nb-6): self.alpha = 1.01 #f[i] = 0.5*(self.f(v[i]) + self.f(v[i+1]) - self.alpha*(v[i+1]-v[i])) f[i] = self.f(v[i]) for i in range(self.Nb+7, self.N-self.Nb-7): self.u[i] -= self.dt/self.dx*(f[i]-f[i-1]) def set_dt(self): umax = max(abs(self.u)) self.dt = self.cfl*(self.x[1]-self.x[0])/umax print self.dt def analytical(self, tf): shift = tf/self.dx u = copy(self.u) for i in range(self.N): try: u[i+shift] = self.u[i] except: pass plot(self.xc, u, 'x-') def solve(self, tf, order): t = 0 while t < tf: self.set_dt() if order == 3: self.newstep() elif order == 4: self.step4() elif order == 2: self.step2() else: break t += self.dt