Try PyDSTool integrator, cgeneralize simulations in notebook
This commit is contained in:
parent
4c5c4ca124
commit
8df782ab92
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,222 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%matplotlib notebook\n",
|
||||
"\n",
|
||||
"import numpy as np\n",
|
||||
"from scipy.integrate import odeint\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from matplotlib import animation\n",
|
||||
"plt.rcParams[\"animation.html\"] = \"jshtml\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"m1 = 1\n",
|
||||
"m2 = 1\n",
|
||||
"c1 = 0.1\n",
|
||||
"c2 = 0.1\n",
|
||||
"c3 = 0.1\n",
|
||||
"a1 = 0.1\n",
|
||||
"a2 = 0.1\n",
|
||||
"a3 = 0.1\n",
|
||||
"k1 = 0.05\n",
|
||||
"k2 = 0.21\n",
|
||||
"k3 = 0.11\n",
|
||||
"C1 = 0.15\n",
|
||||
"C2 = 0.30\n",
|
||||
"omega = 0.1\n",
|
||||
"\n",
|
||||
"f1 = lambda t: C1*np.cos(omega*t)\n",
|
||||
"f2 = lambda t: C2*np.cos(omega*t)\n",
|
||||
"\n",
|
||||
"def deriv(X, t):\n",
|
||||
" \"\"\"Return the derivatives dx/dt and d2x/dt2.\"\"\"\n",
|
||||
" x1, x2, xd1, xd2 = X\n",
|
||||
" F1 = f1(t)\n",
|
||||
" F2 = f2(t)\n",
|
||||
" xdd1 = F1 - xd1*(c1 + c2) + xd2*c2 - x1*(k1 + k2) + x2*k2 - a1*x1**3 + a2*(x2 - x1)**3\n",
|
||||
" xdd2 = F2 - xd2*(c2 + c3) + xd1*c1 - x2*(k2 + k3) + x1*k2 - a3*x2**3 + a2*(x2 - x1)**3\n",
|
||||
" return xd1, xd2, xdd1/m1, xdd2/m2\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def solve_duffing(tmax, dt_per_period, t_trans, x0, v0):\n",
|
||||
" \"\"\"Solve the Duffing equation with the standard odeint solver.\n",
|
||||
" \n",
|
||||
" Find the numerical solution to the Duffing equation using a suitable\n",
|
||||
" time grid: tmax is the maximum time (s) to integrate to; t_trans is\n",
|
||||
" the initial time period of transient behaviour until the solution\n",
|
||||
" settles down (if it does) to some kind of periodic motion (these data\n",
|
||||
" points are dropped) and dt_per_period is the number of time samples\n",
|
||||
" (of duration dt) to include per period of the driving motion (frequency\n",
|
||||
" omega).\n",
|
||||
" \n",
|
||||
" Returns the time grid, t (after t_trans), position, x, and velocity,\n",
|
||||
" xdot, dt, and step, the number of array points per period of the driving\n",
|
||||
" motion.\n",
|
||||
" \n",
|
||||
" \"\"\"\n",
|
||||
" # Time point spacings and the time grid\n",
|
||||
"\n",
|
||||
" period = 2*np.pi/omega\n",
|
||||
" dt = 2*np.pi/omega / dt_per_period\n",
|
||||
" step = int(period / dt)\n",
|
||||
" t = np.arange(0, tmax, dt)\n",
|
||||
" # Initial conditions: x, xdot\n",
|
||||
" X0 = x0 + v0\n",
|
||||
" X = odeint(deriv, X0, t)\n",
|
||||
" idx = int(t_trans / dt)\n",
|
||||
" return t[idx:], X[idx:], dt, step"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Set up the motion for a oscillator with initial positions and velocities\n",
|
||||
"x0, v0 = (0.5, -0.5), (0.5, -0.1)\n",
|
||||
"tmax, t_trans = 150, 0\n",
|
||||
"dt_per_period = 100"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Solve the equation of motion.\n",
|
||||
"t, X, dt, pstep = solve_duffing(tmax, dt_per_period, t_trans, x0, v0)\n",
|
||||
"print(\"# samples: %d\" % len(t))\n",
|
||||
"print(\"dt: %.4f\" % dt)\n",
|
||||
"print(\"Steps per period: %d\" % pstep)\n",
|
||||
"x1, x2, xd1, xd2 = X.T"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"fig1, ((ax11, ax12), (ax21, ax22)) = plt.subplots(nrows=2, ncols=2)\n",
|
||||
"\n",
|
||||
"ax11.plot(t, x1)\n",
|
||||
"ax11.set_xlabel(r'$x_1$')\n",
|
||||
"ax12.plot(t, x2)\n",
|
||||
"ax12.set_xlabel(r'$x_2$')\n",
|
||||
"ax21.plot(t, xd1)\n",
|
||||
"ax21.set_xlabel(r'$v_1$')\n",
|
||||
"ax22.plot(t, xd2)\n",
|
||||
"ax22.set_xlabel(r'$v_2$')\n",
|
||||
"plt.tight_layout()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%capture\n",
|
||||
"fig2, ((ax11, ax12), (ax21, ax22)) = plt.subplots(nrows=2, ncols=2)\n",
|
||||
"\n",
|
||||
"# Positions\n",
|
||||
"ax11.set_xlabel(r'$x_1$')\n",
|
||||
"ax11.set_ylabel(r'$x_2$')\n",
|
||||
"ln11, = ax11.plot([], [])\n",
|
||||
"ax11.set_xlim([np.min(x1), np.max(x1)])\n",
|
||||
"ax11.set_ylim([np.min(x2), np.max(x2)])\n",
|
||||
"\n",
|
||||
"# Velocities\n",
|
||||
"ax12.set_xlabel(r'$v_1$')\n",
|
||||
"ax12.set_ylabel(r'$v_2$')\n",
|
||||
"ln12, = ax12.plot([], [])\n",
|
||||
"ax12.set_xlim([np.min(xd1), np.max(xd1)])\n",
|
||||
"ax12.set_ylim([np.min(xd2), np.max(xd2)])\n",
|
||||
"\n",
|
||||
"# Phase spaces\n",
|
||||
"ax21.set_xlabel(r'$\\mathbf{x}$')\n",
|
||||
"ax21.set_ylabel(r'$\\mathbf{v}$')\n",
|
||||
"ln21a, = ax21.plot([], [])\n",
|
||||
"ln21b, = ax21.plot([], [])\n",
|
||||
"ax21.set_xlim([min(np.min(x1), np.min(x2)), max(np.max(x1), np.max(x2))])\n",
|
||||
"ax21.set_ylim([min(np.min(xd1), np.min(xd2)), max(np.max(xd1), np.max(xd2))])\n",
|
||||
"\n",
|
||||
"# F(t)\n",
|
||||
"F1 = f1(t)\n",
|
||||
"F2 = f2(t)\n",
|
||||
"ax22.set_xlabel(r'$t$')\n",
|
||||
"ax22.set_ylabel(r'$\\mathbf{F}(t)$')\n",
|
||||
"ln22a, = ax22.plot([], [])\n",
|
||||
"ln22b, = ax22.plot([], [])\n",
|
||||
"ax22.set_xlim([t[0], t[-1]])\n",
|
||||
"ax21.set_ylim([min(np.min(F1), np.min(F2)), max(np.max(F1), np.max(F2))])\n",
|
||||
"\n",
|
||||
"plt.tight_layout()\n",
|
||||
"\n",
|
||||
"def animate(i):\n",
|
||||
" ln11.set_data(x1[:i], x2[:i])\n",
|
||||
" ln12.set_data(xd1[:i], xd2[:i])\n",
|
||||
" ln21a.set_data(x1[:i], xd1[:i])\n",
|
||||
" ln21b.set_data(x2[:i], xd2[:i])\n",
|
||||
" ln22a.set_data(t[:i], F1[:i])\n",
|
||||
" ln22b.set_data(t[:i], F2[:i])\n",
|
||||
" \n",
|
||||
"\n",
|
||||
"anim = animation.FuncAnimation(fig2, animate, frames=len(t), interval=100, repeat_delay=1000)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"anim"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"anaconda-cloud": {},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.5.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 1
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
144
pydstool_integrator.py
Normal file
144
pydstool_integrator.py
Normal file
@ -0,0 +1,144 @@
|
||||
"""Simulate duffing model with PyDSTool integrator.
|
||||
|
||||
See
|
||||
https://github.com/robclewley/pydstool/blob/master/examples/forced_spring.py
|
||||
|
||||
for forced-spring example.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
import PyDSTool
|
||||
|
||||
|
||||
def simulate(T, t_trans, steps, x0, v0, omega, p):
|
||||
x1, x2 = x0
|
||||
xd1, xd2 = v0
|
||||
C1, C2, m1, m2, c1, c2, c3, k1, k2, k3, a1, a2, a3 = p
|
||||
|
||||
args = PyDSTool.args(name='duffing-stuffing')
|
||||
args.varspecs = {
|
||||
'x1': 'xd1',
|
||||
'x2': 'xd2',
|
||||
'xd1': 'C1*F(t)/m1 - xd1*(c1 + c3) + xd2*c3 - x1*(k1 + k3) + x2*k3 - a1*pow(x1, 3) + a3*pow(x2 - x1, 3)',
|
||||
'xd2': 'C2*F(t)/m2 - xd2*(c2 + c3) + xd1*c3 - x2*(k2 + k3) + x1*k3 - a2*pow(x2, 3) + a3*pow(x2 - x1, 3)'
|
||||
}
|
||||
args.fnspecs = {
|
||||
'F': (['t'], 'cos(omega*t)')
|
||||
}
|
||||
args.pars = {
|
||||
'omega': omega,
|
||||
'C1': C1, 'C2': C2,
|
||||
'm1': m1, 'm2': m2,
|
||||
'c1': c1, 'c2': c2, 'c3': c3,
|
||||
'k1': k1, 'k2': k2, 'k3': k3,
|
||||
'a1': a1, 'a2': a2, 'a3': a3
|
||||
}
|
||||
args.ics = {
|
||||
'x1': x0[0], 'x2': x0[1],
|
||||
'xd1': v0[0], 'xd2': v0[1]
|
||||
}
|
||||
args.xdomain = {
|
||||
'x1': [-10, 10], 'x2': [-10, 10],
|
||||
'xd1': [-1e6, 1e6], 'xd2': [-1e6, 1e6]
|
||||
}
|
||||
#args.tdomain = [0, T]
|
||||
args.tdata = [0, T]
|
||||
|
||||
# Integrator
|
||||
ds = PyDSTool.Generator.Vode_ODEsystem(args)
|
||||
traj = ds.compute('experiment')
|
||||
pts = traj.sample(dt=(T-t_trans)/steps, precise=True)
|
||||
return np.stack([
|
||||
pts['x1'][-steps:],
|
||||
pts['x2'][-steps:],
|
||||
pts['xd1'][-steps:],
|
||||
pts['xd2'][-steps:]
|
||||
])
|
||||
|
||||
|
||||
def test():
|
||||
C1 = 1.5e5
|
||||
C2 = 1.5e5
|
||||
m1 = 1.0 #1e-3
|
||||
m2 = 1.0 #1e-3
|
||||
|
||||
c1 = 9647.403
|
||||
c2 = 10282.101
|
||||
c3 = 0.000
|
||||
k1 = 2326809592.681
|
||||
k2 = 2643039774.512
|
||||
k3 = 0.000
|
||||
a1 = 0.000
|
||||
a2 = 0.000
|
||||
a3 = 0.000
|
||||
|
||||
p = (
|
||||
C1, C2,
|
||||
m1, m2,
|
||||
c1, c2, c3,
|
||||
k1, k2, k3,
|
||||
a1, a2, a3
|
||||
)
|
||||
|
||||
omega = 2*np.pi*5e3
|
||||
|
||||
x0, v0 = (0.00001, 0.00002), (0.000001, 0.0002)
|
||||
T = 0.6
|
||||
t_trans = 0.1
|
||||
steps = 100
|
||||
|
||||
return simulate(T, t_trans, steps, x0, v0, omega, p)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
X = test()
|
||||
print(X.shape)
|
||||
print(X.mean(axis=1))
|
||||
print(X.std(axis=1))
|
||||
print(X)
|
||||
|
||||
|
||||
#pars = {'D1': 1.0 , 'D2': 10.0, 'A': 2.1, 'B': 3.5, 'lambda': 5}
|
||||
#
|
||||
#tdomain = [0,50]
|
||||
#
|
||||
#icdict = {'X1': 1.087734, 'X2': 1.087734, 'X3': 4.124552, \
|
||||
# 'Y1': 1.8488063, 'Y2': 1.8488063, 'Y3': 1.0389936}
|
||||
#
|
||||
## Set up model
|
||||
#X1str = 'D1*(X2 - 2*X1 + X3) + lambda*(A - (B+1)*X1 + pow(X1,2)*Y1)'
|
||||
#X2str = 'D1*(X3 - 2*X2 + X1) + lambda*(A - (B+1)*X2 + pow(X2,2)*Y2)'
|
||||
#X3str = 'D1*(X1 - 2*X3 + X2) + lambda*(A - (B+1)*X3 + pow(X3,2)*Y3)'
|
||||
#Y1str = 'D2*(Y2 - 2*Y1 + Y3) + lambda*(B*X1 - pow(X1,2)*Y1)'
|
||||
#Y2str = 'D2*(Y3 - 2*Y2 + Y1) + lambda*(B*X2 - pow(X2,2)*Y2)'
|
||||
#Y3str = 'D2*(Y1 - 2*Y3 + Y2) + lambda*(B*X3 - pow(X3,2)*Y3)'
|
||||
#
|
||||
#DSargs = args(name='Brusselator')
|
||||
#DSargs.tdomain = tdomain
|
||||
#DSargs.pars = pars
|
||||
#DSargs.varspecs = {'X1': X1str, 'X2': X2str, 'X3': X3str, 'Y1': Y1str, 'Y2': Y2str, 'Y3': Y3str}
|
||||
#DSargs.xdomain = {'X1': [0, 50], 'X2': [0, 50], 'X3': [0, 50], 'Y1': [0, 50], 'Y2': [0, 50], 'Y3': [0, 50]}
|
||||
#DSargs.ics = icdict
|
||||
#
|
||||
#testDS = Generator.Vode_ODEsystem(DSargs)
|
||||
#
|
||||
## Set up continuation class
|
||||
#PyCont = ContClass(testDS)
|
||||
#
|
||||
#PCargs = args(name='EQ1', type='EP-C')
|
||||
#PCargs.freepars = ['lambda']
|
||||
#PCargs.StepSize = 5e-3
|
||||
#PCargs.LocBifPoints = ['BP','LP']
|
||||
#PCargs.verbosity = 2
|
||||
#PCargs.SaveEigen = True
|
||||
#PyCont.newCurve(PCargs)
|
||||
#
|
||||
#print('Computing curve...')
|
||||
#start = clock()
|
||||
#PyCont['EQ1'].forward()
|
||||
#print('done in %.3f seconds!' % (clock()-start))
|
||||
#
|
||||
## Plot
|
||||
#PyCont['EQ1'].display(('lambda','X1'), stability=True)
|
||||
#PyCont.plot.toggleAll('off', byname='P1')
|
||||
#show()
|
||||
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
scipy>=0.5.1,<1.0
|
||||
PyDSTool
|
||||
Loading…
x
Reference in New Issue
Block a user