-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathiteration_example.py
95 lines (61 loc) · 2.19 KB
/
iteration_example.py
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
#!/usr/bin/env python3
"""
Example of using is_close_to() in an iterative solution for the
disepersion realtionship for garvity waves in the ocean.
The lnear wave theory dispersion equation:
omega**2 = g*k*tanh(k*h)
where omega is the wave frequence, g is the accelartion of gravity, k
is the wave number (2*pi/wave_length), and h is the water depth.
In the usual case, the frequencey(omega) is known, and you want the
wave number. As the wave number appears in two places, there is no
direct solution, so a numerical method must be used.
The simplist iterative solution is something like this: recast the
equation as:
k_2 = omega**2 / (g * tanh(k_1 * h))
- guess a k_1
- compute k_2
- check if k_2 is close to k_1
- if not, set k_1 to k_2 repeat.
"""
import math
import imp
import is_close_to
imp.reload(is_close_to) # because I'm running for ipython
from is_close_to import is_close_to
def dispersion(omega, h, g=9.806):
"compute the dispersion relation"
k_1 = 10.0 # initial guess
while True:
k_2 = omega**2 / (g * math.tanh(k_1 * h))
if is_close_to(k_2, k_1, tol=1e-5):
break
k_1 = k_2
return k_1
def iterate(func, x_initial, *args):
"""
iterate to find a solution to the function passed in
func should be a function that takes x as a first argument,
and computes an approximation to x as a result.
x_initial is an initial guess for the unknown value
"""
x_1 = x_initial
while True:
x_2 = func(x_1, *args)
if is_close_to(x_2, x_1):
break
x_1 = x_2
return x_2
def disp(k, omega, h, g=9.806):
"""
the linear wave dispersion realationship
k as a function of k, omega, h, g
"""
return omega**2 / (g * math.tanh(k * h))
if __name__ == "__main__":
#Try it for a few values:
h = 10 # meters water depth
omega = 2*math.pi / 10 # ten second period
k = dispersion(omega, h)
print("omega: {}, h: {}, k: {}, period: {}, wavelength: {}".format(omega, h, k, 2*math.pi/omega, 2*math.pi/k))
k2 = iterate(disp, 10, omega, h )
print("omega: {}, h: {}, k: {}, period: {}, wavelength: {}".format(omega, h, k2, 2*math.pi/omega, 2*math.pi/k2))