![](/img/trans.png)
[英]Implementing the Backwards Euler method in python to solve a pendulum
[英]Implementing Euler's Method in python to solve ODE
我正在做一個小科學項目,用ODE(常微分方程)模擬機械系統。
我想使用Euler方法來執行此操作,但是我相信我正在做一些工作,因為我創建的輸出數據圖不是應該的樣子,並且我100%確信方程本身是正確的 。 您能看一下我的代碼並告訴我我做錯了什么嗎? 此代碼會將CSV值輸出到控制台和output.csv文件中。
測試:
class Calculus:
def __init__(self):
print "object created"
@staticmethod
def euler(f,y0,a,b,h):
"""y0 - temperatura poczatkowa, a-chwila poczatkowa czasu(warunek brzegowy) , b-chwila koncowa, h - krok"""
t,y = a,y0
time = [t]
value = [y]
while t <= b:
print "%6.3f,%6.3f" % (t,y)
t += h
y += h * f(t,y, h, value)
time.append(t)
value.append(y)
data = {'time' : time, 'value' : value}
return data
class Mechanical_system:
#Constructor
def __init__(self, momentum1, momentum2, b1, b2, N1, N2, w1, Tau, k):
self.system_parameters = {'momentum1': momentum1, 'momentum2': momentum2,
'b1': b1, 'b2' : b2,
'N1': N1, 'N2' : N2,
'w1' : w1,
'Tau' : Tau,
'k' : k};
def ODE(self, time, w, h, value):
"""ODE - ordinary differential equation describing our system"""
#first calculation will only have one value in the list, so we can't calculate delt_value = current - last
#thus, we need to assume that if there is no penault value (index error) let penault = 0
try:
penault = value[len(value) -2]
except IndexError:
penault = 0
momentum1 = self.system_parameters['momentum1']
momentum2 = self.system_parameters['momentum2']
b1 = self.system_parameters['b1']
b2 = self.system_parameters['b2']
N1 = self.system_parameters['N1']
N2 = self.system_parameters['N2']
Tau = self.system_parameters['Tau']
k = self.system_parameters['k']
dOmega = w - penault
dt = h
Omega = float(dOmega) / float(dt)
return (1.0 / (momentum1 + ((N1/N2)**2)*momentum2))*(Tau - (Omega)*(b1 + ((N1/N2)**2)*b2) - w * ((N1/N2)**2)*k)
if __name__ == "__main__":
"""reads values from input boxes and then calculates the value and plot value(time)"""
momentum1 = 1
momentum2 = 2
b1 = 0.5
b2 = 0.6
N1 = 10
N2 = 20
a = 0
b = 100
h = 0.1
w1 = 0
Tau = 100
k = 0.5
system1 = Mechanical_system(momentum1, momentum2, b1, b2, N1, N2, w1, Tau, k)
data = Calculus.euler(system1.ODE, w1, a, b, h)
##writing output to CSV file
f = open('output.csv', 'w')
for index in range(len(data['time'])):
f.write("%s,%s\n" % (data['time'][index], data['value'][index]))
f.close()
del system1
del data
在機械系統中使用Euler通常是個壞主意。 探索該陳述最簡單的測試案例是簡單的振盪器x''+x=0
,您會發現系統的能量迅速增長。
對於一般的機械系統,您有一個運動方程m*x'' = F(t,x,x')
。 這為您提供了矢量值系統
def f(t,y):
x,v = y
return [ v; 1/m*F(t,x,v) ]
請注意,系統功能中沒有h
或dt
。 這對於ODE及其數值處理至關重要。 軌跡遵循的方向場不取決於數值解法的細節。
因此,請在相空間中將您的方程式重構為二階方程式或一階系統。
我認為您的方程式旨在
F(x,v) = Tau - (b1 + ((N1/N2)**2)*b2) * v - ((N1/N2)**2)*k * x
有質量
m = momentum1 + ((N1/N2)**2)*momentum2
或其某些縮放版本。 所以某種彈簧在重力和摩擦力作用下。 如果是這樣,那么您就將物理系統的加速度視為數值實現中的速度。 這只能給出毫無意義的結果。
剝離這些類,可以像這樣反映系統的第二順序:
def euler(f,y0,v0,a,b,h):
t,y,v = a,y0,v0
time = [t]
value = [y]
while t <= b:
print "%6.3f,%6.3f" % (t,y)
accel = f(t,y,v)
t += h
y += h * v
v += h*accel
time.append(t)
value.append(y)
data = {'time' : time, 'value' : value}
return data
def ODE(t,y,v,param):
momentum1, momentum2, b1, b2, N1, N2, Tau, k = param
mass = momentum1 + ((N1/N2)**2)*momentum2
force = Tau - v*(b1 + ((N1/N2)**2)*b2) - y * ((N1/N2)**2)*k
return force/mass
momentum1 = 1
momentum2 = 2
b1 = 0.5
b2 = 0.6
N1 = 10.
N2 = 20.
Tau = 100
k = 0.5
a = 0
b = 100
h = 0.1
y0 = 0
v0 = 0
params = [momentum1, momentum2, b1, b2, N1, N2, Tau, k]
data = euler(lambda t,y,v: ODE(t,y,v,params),y0,v0,a,b,h)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.