For a general DAE of type
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import fsolve
def impliciteuler(F=None, inival=None, interval=[0, 1], Nts=100,
dFdx=None, dFdxdot=None):
"""
Parameters:
---
F: callable
the problem in the form F(t,x,x')
Nts: integer
Number of time steps, defaults to `100`.
"""
t0, te = interval[0], interval[1]
h = 1./Nts*(te-t0)
N = inival.size
sollist = [inival.reshape((1, N))]
tlist = [t0]
xk = inival
for k in range(1, Nts+1): # python starts counting with zero...
tkk = t0 + k*h
def impeuler_increment(xkkn):
""" the implicit Euler update for a general F """
return F(tkk,xkkn,1./h*(xkkn-xk)).flatten()
xkk, _, flag, msg = fsolve(func=impeuler_increment, x0=xk, full_output=True)
# call a nonlinear solver for the system f(x)=0
if not flag == 1:
print 'Caution at t={0}: '.format(tkk) + msg
sollist.append(xkk.reshape((1, N)))
tlist.append(tkk)
xk = xkk
sol = np.vstack(sollist)
plt.plot(tlist, sol)
plt.xlabel('t'), plt.ylabel('x')
plt.show()
return sol
Let .
Consider
The problem has infinitely many solutions, namely for any smooth scalar function . The Implicit Euler nevertheless returns a solution (without telling you that there are there are many!!!)
Consider
Consider
## Problem (a)
def E(t):
return np.array([[-t, t*t], [-1, t]])
def A(t):
return np.array([[-1, 0], [0, -1]])
def f(t):
return np.array([0, 0])
def F(t, x, xdot):
return E(t).dot(xdot) - A(t).dot(x) - f(t)
inival = np.array([0, 1])
interval = [0, 10]
sol = impliciteuler(F=F, inival=inival, interval=interval, Nts=500)
## Problem (b)
def E(t):
return np.array([[0, 0], [1, -1]])
def A(t):
return np.array([[-1, t], [0, 0]])
def f(t):
return np.array([np.sin(t), np.cos(t)])
def F(t, x, xdot):
return E(t).dot(xdot) - A(t).dot(x) - f(t)
interval = [0, 2]
inival = np.array([1, 1])
sol = impliciteuler(F=F, inival=inival, interval=interval, Nts=100)
inival = np.array([0, 0])
sol = impliciteuler(F=F, inival=inival, interval=interval, Nts=100)
## Problem (c)
def E(t):
return np.array([[1, 1], [0, 0]])
def A(t):
return np.array([[0, 0], [0, -1]])
def f(t):
return np.array([np.exp(t)+np.cos(t), np.exp(t)])
def F(t, x, xdot):
return E(t).dot(xdot) - A(t).dot(x) - f(t)
interval = [0, 1]
inival = np.array([0, 1])
sol = impliciteuler(F=F, inival=inival, interval=interval, Nts=1000)
inival = np.array([2, -1])
sol = impliciteuler(F=F, inival=inival, interval=interval, Nts=10)