#!/usr/bin/env python # -*- coding: utf-8 -*- """Test of numerical solver. :Date: 2019-05-25 .. module:: test_ode :platform: *nix, Windows :synopsis: Test of numerical solver. .. moduleauthor:: Daniel Weschke """ from __future__ import division, print_function import unittest import math from numpy import linspace, allclose, sqrt, square, concatenate from numpy.linalg import inv from matplotlib.pyplot import figure, subplots, plot, show import os import sys sys.path.insert(0, os.path.abspath('../src')) from numerical.ode import (e1, e2, e4, i1, newmark_newtonraphson, newmark_newtonraphson_rdk) from numerical.ode_model import disk, disk_nm, disk_nmmdk def plotx1rphi(x, t, title): """Plot plane rotation (x, y, phi) """ x1 = x[:, 0] x2 = x[:, 1] x3 = x[:, 2] xp1 = x[:, 3] xp2 = x[:, 4] xp3 = x[:, 5] fig, ax1 = subplots() ax1.set_title(title) ax1.plot(t, x1, 'b-') #ax1.plot(t, x3, 'b-') ax1.set_xlabel('time t in s') # Make the y-axis label and tick labels match the line color. ax1.set_ylabel('x_1', color='b') for tl in ax1.get_yticklabels(): tl.set_color('b') envelope = sqrt(square(x1)+square(x2)) ax1.plot(t, envelope, 'b--', t, -envelope, 'b--') ax2 = ax1.twinx() ax2.plot(t, xp3, 'r') ax2.set_ylabel('phi', color='r') for tl in ax2.get_yticklabels(): tl.set_color('r') if max(xp3) < 2: ax2.set_ylim([0,2]) f = disk fnm = disk_nm fnmmdk = disk_nmmdk class TestODE(unittest.TestCase): Dt = .01 # Delta t tend = .1 # t_end #tend = 300 nt = math.ceil(tend/Dt) # number of timesteps t = linspace(0., tend, nt+1) # time vector x0 = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 # initial conditions p = .01, .002, .015 # parameter of the model def test_e1(self): xe1 = e1(f, self.x0, self.t, *self.p) #plotx1rphi(xe1, self.t, ("Euler (Runge-Kutta 1th order), # increments: %d" % self.nt)) #show() self.assertTrue(allclose(xe1[:, 5], [0., 0.00015, 0.0003, 0.00045, 0.0006, 0.00075, 0.0009, 0.00105, 0.0012, 0.00135, 0.0015 ])) Dt_2 = Dt/5. nt_2 = math.ceil(tend/Dt_2) t_2 = linspace(0., tend, nt_2+1) def test_e1_2(self): xe1_2 = e1(f, self.x0, self.t_2, *self.p) #plotx1rphi(xe1_2, self.t_2, ("Euler (Runge-Kutta 1th order), # increments: %d" % self.nt_2)) #show() self.assertTrue(allclose(xe1_2[:, 5], [0.00000000e+00, 3.00000000e-05, 6.00000000e-05, 8.99999998e-05, 1.19999999e-04, 1.49999998e-04, 1.79999995e-04, 2.09999992e-04, 2.39999987e-04, 2.69999980e-04, 2.99999971e-04, 3.29999960e-04, 3.59999947e-04, 3.89999931e-04, 4.19999913e-04, 4.49999891e-04, 4.79999866e-04, 5.09999837e-04, 5.39999804e-04, 5.69999767e-04, 5.99999726e-04, 6.29999681e-04, 6.59999630e-04, 6.89999575e-04, 7.19999514e-04, 7.49999448e-04, 7.79999376e-04, 8.09999298e-04, 8.39999214e-04, 8.69999123e-04, 8.99999026e-04, 9.29998921e-04, 9.59998810e-04, 9.89998691e-04, 1.01999856e-03, 1.04999843e-03, 1.07999829e-03, 1.10999814e-03, 1.13999798e-03, 1.16999781e-03, 1.19999763e-03, 1.22999744e-03, 1.25999725e-03, 1.28999704e-03, 1.31999682e-03, 1.34999660e-03, 1.37999636e-03, 1.40999611e-03, 1.43999585e-03, 1.46999558e-03, 1.49999530e-03] )) maxIterations = 1000 tol = 1e-9 # against residuum def test_e2(self): xe2 = e2(f, self.x0, self.t, *self.p) #plotx1rphi(xe2, self.t, ("Runge-Kutta 2th order, # increments: %d" % self.nt)) #show() self.assertTrue(allclose(xe2[:, 5], [0., 0.00015, 0.0003, 0.00045, 0.0006, 0.00075, 0.0009, 0.00105, 0.0012, 0.00135, 0.0015 ])) def test_e4(self): xe4 = e4(f, self.x0, self.t, *self.p) #plotx1rphi(xe4, self.t, ("Runge-Kutta 4th order, # increments: %d" % self.nt)) #show() self.assertTrue(allclose(xe4[:, 5], [0., 0.00015, 0.0003, 0.00045, 0.0006, 0.00075, 0.0009, 0.00105, 0.0012, 0.00135, 0.0015 ])) def test_i1(self): xi1, iterations = i1(f, self.x0, self.t, *self.p, self.maxIterations, self.tol) #plotx1rphi(xi1, self.t, ("Backward Euler, increments: %d, # iterations: %d" % (self.nt, sum(iterations)))) #show() self.assertTrue(allclose(xi1[:, 5], [0., 0.00015, 0.0003, 0.00045, 0.0006, 0.00075, 0.0009, 0.00105, 0.0012, 0.00135, 0.0015 ])) gamma = .5 # newmark parameter for velocity beta = .25 # newmark parameter for displacement def test_nm(self): xnm, xpnm, xppnm, iterations = newmark_newtonraphson(fnm, (0,0,0), (0,0,0), (0,0,0), self.t, *self.p, self.gamma, self.beta, 1, self.tol) #print(xnm) #print(xpnm) x = concatenate((xnm, xpnm), axis=1) #plotx1rphi(x, self.t, ("Newmark, increments: %d, # iterations: %d" % (self.nt, sum(iterations)))) #show() self.assertTrue(allclose(x[:, 5], [0.00000000e+00, 7.49999925e-05, 2.24999951e-04, 3.74999839e-04, 5.24999621e-04, 6.74999269e-04, 8.24998752e-04, 9.74998039e-04, 1.12499710e-03, 1.27499591e-03, 1.42499444e-03] )) def test_nm_2(self): xnm, xpnm, xppnm, iterations = newmark_newtonraphson(fnm, (0,0,0), (0,0,0), (0,0,0), self.t, *self.p, self.gamma, self.beta, self.maxIterations, self.tol) #print(xnm) #print(xpnm) x = concatenate((xnm, xpnm), axis=1) #plotx1rphi(x, self.t, ("Newmark, increments: %d, # iterations: %d" % (self.nt, sum(iterations)))) #show() self.assertTrue(allclose(x[:, 5], [0.00000000e+00, 7.49999925e-05, 2.24999951e-04, 3.74999839e-04, 5.24999621e-04, 6.74999269e-04, 8.24998752e-04, 9.74998039e-04, 1.12499710e-03, 1.27499591e-03, 1.42499444e-03] )) def test_nmmdk(self): xnm, xpnm, xppnm, iterations = newmark_newtonraphson_rdk( fnmmdk, (0,0,0), (0,0,0), (0,0,0), self.t, *self.p, self.gamma, self.beta, 1, self.tol) #print(xnm) #print(xpnm) x = concatenate((xnm, xpnm), axis=1) #plotx1rphi(x, self.t, ("Newmark, increments: %d, # iterations: %d" % (self.nt, sum(iterations)))) #show() self.assertTrue(allclose(x[:, 5], [0.00000000e+00, 7.49999963e-05, 2.24999974e-04, 3.74999906e-04, 5.24999764e-04, 6.74999516e-04, 8.24999134e-04, 9.74998586e-04, 1.12499784e-03, 1.27499688e-03, 1.42499566e-03] )) def test_nmmdk_2(self): xnm, xpnm, xppnm, iterations = newmark_newtonraphson_rdk( fnmmdk, (0,0,0), (0,0,0), (0,0,0), self.t, *self.p, self.gamma, self.beta, 100, self.tol) #print(xnm) #print(xpnm) x = concatenate((xnm, xpnm), axis=1) #plotx1rphi(x, self.t, ("Newmark, increments: %d, # iterations: %d" % (self.nt, sum(iterations)))) #show() self.assertTrue(allclose(x[:, 5], [0.00000000e+00, 7.49999963e-05, 2.24999974e-04, 3.74999906e-04, 5.24999764e-04, 6.74999516e-04, 8.24999134e-04, 9.74998586e-04, 1.12499784e-03, 1.27499688e-03, 1.42499566e-03] )) #from scipy.integrate import odeint #xode = odeint(disk, x0, t, p, printmessg=True) #plotx1rphi(xode, t, ("ODE, Inkremente: %d" % nt)) #show() if __name__ == '__main__': unittest.main()