|
| 1 | +import sys |
| 2 | +sys.path.append('../src') |
| 3 | + |
| 4 | +import numpy as np |
| 5 | +from scipy import sparse |
| 6 | +from scipy import linalg |
| 7 | +from integrator import integrator |
| 8 | +from trapezoidal import trapezoidal |
| 9 | +from solution_linear import solution_linear |
| 10 | +from nose.tools import * |
| 11 | +import unittest |
| 12 | + |
| 13 | +class TestTrapezoidal(unittest.TestCase): |
| 14 | + |
| 15 | + def setUp(self): |
| 16 | + self.ndof = np.random.randint(255) |
| 17 | + self.A = sparse.spdiags([ np.ones(self.ndof), -2.0*np.ones(self.ndof), np.ones(self.ndof)], [-1,0,1], self.ndof, self.ndof, format="csc") |
| 18 | + self.M = sparse.spdiags([ np.random.rand(self.ndof) ], [0], self.ndof, self.ndof, format="csc") |
| 19 | + self.sol = solution_linear(np.ones(self.ndof), self.A, self.M) |
| 20 | + |
| 21 | + # Can instantiate object |
| 22 | + def test_caninstantiate(self): |
| 23 | + tp = trapezoidal(0.0, 1.0, 10) |
| 24 | + |
| 25 | + # Throws if tend < tstart |
| 26 | + def test_tendbeforetstartthrows(self): |
| 27 | + with self.assertRaises(AssertionError): |
| 28 | + tp = trapezoidal(1.0, 0.0, 10) |
| 29 | + |
| 30 | + # See if run function can be called |
| 31 | + def test_cancallrun(self): |
| 32 | + tp = trapezoidal(0.0, 1.0, 10) |
| 33 | + tp.run(self.sol) |
| 34 | + |
| 35 | + # See if run does the same as the update matrix for a scalar problem |
| 36 | + def test_callcorrectscalar(self): |
| 37 | + eig = -1.0 |
| 38 | + u0 = solution_linear(np.array([1.0]), np.array([[eig]])) |
| 39 | + nsteps = 50 |
| 40 | + tp = trapezoidal(0.0, 1.0, nsteps) |
| 41 | + tp.run(u0) |
| 42 | + assert abs(u0.y - np.exp(-1.0))<5e-3, ("Very wrong solution. Error: %5.2e" % abs(u0.y - np.exp(-1.0))) |
| 43 | + Rmat = tp.get_update_matrix(u0) |
| 44 | + Rmat_ie = Rmat[0,0] |
| 45 | + Rmat_ex = ((1.0 + 0.5*tp.dt*eig)/(1.0 - 0.5*tp.dt*eig))**nsteps |
| 46 | + assert abs(Rmat_ie - Rmat_ex)<1e-14, ("Update function generated by trapezoidal rule for scalar case does not match exact value. Error: %5.3e" % abs(Rmat_ie - Rmat_ex)) |
| 47 | + |
| 48 | + # See if run does the same as the update matrix |
| 49 | + def test_callcorrect(self): |
| 50 | + u0 = solution_linear(np.ones(self.ndof), self.A, self.M) |
| 51 | + nsteps = 13 |
| 52 | + tp = trapezoidal(0.0, 1.0, nsteps) |
| 53 | + tp.run(u0) |
| 54 | + # Compute output through update matrix and compare |
| 55 | + Rmat = tp.get_update_matrix(u0) |
| 56 | + yend = Rmat.dot(np.ones((self.ndof,1))) |
| 57 | + sol_end = solution_linear( yend, self.A, self.M ) |
| 58 | + sol_end.axpy(-1.0, u0) |
| 59 | + assert sol_end.norm()<2e-12, ("Output from trapezoidal rule integrator differs from result computed with power of update matrix -- norm of difference: %5.3e" % sol_end.norm()) |
| 60 | + |
0 commit comments