-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnbdemo.do.txt
150 lines (115 loc) · 3.61 KB
/
nbdemo.do.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
TITLE: Example on interactive live documents versus traditional static documents
AUTHOR: hpl
DATE: today
===== Physics =====
label{ipynbex:physics}
We consider a vibrating mechanical system as shown in Figure ref{ipynbex:physics:fig}.
FIGURE: [../doc/src/ipynb/fig/oscillator_general, width=600 frac=0.8] Oscillating system with spring and damper. label{ipynbex:physics:fig}
===== Mathematics =====
label{ipynbex:math}
A differential equation for the system in Figure ref{ipynbex:physics:fig} reads
!bt
\[ mu'' + f(u') + s(u) = F(t),\quad u(0)=I,\ u'(0)=V\thinspace .\]
!et
In the linear damping case, where $f(u')=bu'$ for some constant
$b\geq 0$, we can solve the problem numerically by a scheme
!bt
\begin{equation}
u^{n+1} = \left(2mu^n + (\frac{b}{2}\Delta t - m)u^{n-1} +
\Delta t^2(F^n - s(u^n))
\right)(m + \frac{b}{2}\Delta t)^{-1},
label{ipynbex:u:scheme:lin}
\end{equation}
!et
for $n=0,1,\ldots$. A special formula is required for $n=0$:
!bt
\begin{equation}
u^1 = u^0 + \Delta t\, V
+ \frac{\Delta t^2}{2m}(-bV - s(u^0) + F^0)
\thinspace .
label{ipynbex:u:scheme0:lin}
\end{equation}
!et
===== Implementation =====
# Note: Plain Markdown cannot refer to equations with numbers.
# This is a DocOnce extension.
The formulas (ref{ipynbex:u:scheme:lin}) and (ref{ipynbex:u:scheme0:lin})
can be implemented as follows in a Python function:
# Next code (hidden code):
# Not strictly needed since zeros inside the next function
# is not called before the main program has imported zeros...
# But in general one may need special imports for the next
# code segments to execute properly.
!bc pyhid
from numpy import zeros
!ec
!bc pycod
def solver_linear_damping(I, V, m, b, s, F, t):
N = t.size - 1 # No of time intervals
dt = t[1] - t[0] # Time step
u = zeros(N+1) # Result array
u[0] = I
u[1] = u[0] + dt*V + dt**2/(2*m)*(-b*V - s(u[0]) + F[0])
for n in range(1,N):
u[n+1] = 1./(m + b*dt/2)*(2*m*u[n] + \
(b*dt/2 - m)*u[n-1] + dt**2*(F[n] - s(u[n])))
return u
!ec
===== Dissection =====
# Code here is not meant to be executed, just shown for discussion.
The array `t` holds all the time points where we want a solution.
The total number of intervals, $N$, is then computed as
!bc pycod-t
N = t.size - 1 # or len(t) - 1
!ec
Creating an array of length $N+1$ where we can store the solution
is done by
!bc pycod-t
u = zeros(N+1)
!ec
% if FORMAT != 'ipynb':
For such a statement to work, we must have done a
!bc pycod
from numpy import zeros
!ec
% endif
For loops over array indices are coded as
!bc pycod-t
for n in range(1, N):
...
!ec
which generates a sequence of integers from 1 up to `N`, *but not
including* `N`.
===== Usage =====
The function `solve_linear_damping` resides in a file `solver.py`.
# Need to tell where solver.py is for the notebook to execute properly.
# For this we use a hidden python code (pyhid). It will be hidden
# in all formats, except in the notebook.
!bc pyhid
# The solver module is in src/solver.py; tell Python about that
import sys
sys.path.insert(0, 'src')
!ec
# For matplotlib we need to insert %matplotlib inline in the notebook.
# (Automatically done by DocOnce.)
!bc pycod
from solver import solver_linear_damping
from numpy import linspace, zeros, pi
def s(u):
return 2*u
T = 10*pi # simulate for t in [0,T]
dt = 0.2
N = int(round(T/dt))
t = linspace(0, T, N+1)
F = zeros(t.size)
I = 1; V = 0
m = 2; b = 0.2
u = solver_linear_damping(I, V, m, b, s, F, t)
from matplotlib.pyplot import *
plot(t, u)
show()
!ec
% if FORMAT != 'ipynb':
The result is the figure below.
FIGURE: [fig/plot, width=500 frac=0.8]
% endif