讓我們用一些簡單的Python特性重寫你的代碼。 (我會留下明年的高級功能;-)
首先,瞭解整數和浮點數之間的差異。如果你期望有一個小數點並做精確的數學運算,那麼浮點數就是你使用的。編程的一部分是非常難以不使用浮點數,除非必須 - 浮點數佔用更多空間,並且它們會讓程序在大約99%的時間內運行得更慢。
二,raw_input([prompt])
需要一個字符串作爲提示。不需要print
。 (這將成爲input()
在Python 3) 所以:
i=float(input(print('enter the number of nodes')))
T0=float(input(print('Enter the first boundary condition')))
Tn=float(input(print('Enter the second boundary condition')))
a=float(input(print('Enter the Thermal cunductivity value')))
Ti=float(input(print('Enter the initial condition')))
n=float(input(print('Enter the number of time steps')))
dt=float(input(print('Enter the change in time dt')))
變爲:
num_nodes = int(input("Enter the number of nodes: "))
boundary1 = float(input("Enter the first boundary condition: "))
boundary2 = float(input("Enter the second boundary condition: "))
conductivity = float(input("Enter the thermal conductivity: "))
initial_cond = float(input("Enter the initial condition: "))
num_ticks = int(input("Enter the number of time steps: "))
delta_t = float(input("Enter the change in time, dT: "))
現在,讓我們初始化一些東西:
k=0
T=[]
T.append(T0)
while k!=i:
T.append(Ti)
k+=1
T.append(Tn)
print(T)
k=0
從這個代碼,k=0
到k=0
告訴我k只是用作循環計數器。循環只是將相同的值反覆附加到T列表中。另外,您正在使用T=[]
,然後立即使用T.append(T0)
。對於這些東西,Python已經有了一個很酷的語法。但T列表是什麼?另外,邊界是否與節點的數量相比?他們應該嗎?
T = ([boundary1]
+ [initial_cond] * num_nodes
+ [boundary2]
)
現在,我們得到的代碼的最後一部分:
k=0
dx=1/(i+1)
while k!=n:
j=0
while j!=len(T):
y=(a*dt/(dx**2))*(T[j-1]+T[j+1])+(1-2*((a*dt)/(dx**2)))*T[j]
T.append(y)
j+=1
print(T)
k+=1
再次使用k
作爲循環計!這也是一種Pythonic的方式,但讓我們看看循環內部,我們看到j
也被用作循環計數器。但至少j
被重新用作索引!我們也有一個成語索引。
在Python中,當你想循環一些次數你可以使用range([start=0], stop, [step=1])
。默認情況下,您獲得值0 .. n-1
。
time_sec = 0.0
for t in range(num_ticks):
time_sec += delta_t
現在,讓我們看看dx
。我看你在這裏定義它:
dx=1/(i+1)
而你在這裏使用它:
y=(a*dt/(dx**2))*(T[j-1]+T[j+1])+(1-2*((a*dt)/(dx**2)))*T[j]
而這一切。但是,如果我們拆開這個公式,並添加一組括號來處理換行符,以及一些空間,我們得到這樣的:
y = (
(a*dt /(dx**2)) * (T[j-1] + T[j+1])
+(1 - 2 * ((a*dt)/(dx**2))) * T[j]
)
你從來不會使用dx
不使用a*dt/dx**2
。所以讓我們擺脫dx
並用更大的計算代替它!
adt_per_dx2 = a * dt/(1/(i+1)) ** 2
哪些因素來:
adt_per_dx2 = a * dt * (i+1)**2
確定有關的公式?
無論如何,它改變算算:我認爲這是
y = adt_per_dx2 * (T[j-1] + T[j+2]) + (1 - 2 * adt_per_dx2) * T[j]
:
y = T[j] + (T[j-1] - T[j]) * adt_per_dx2 + (T[j+1] - T[j]) * adt_per_dx2
我想回到這一點,因爲我們可以用它進行優化。 (請記住當我說浮點運算是昂貴的嗎?)
讓我們暫停一分鐘,看看T
。當你開始時,我認爲T看起來像一個「材料」。也就是說,它看起來像有一個邊界,然後是一些內部節點,然後是另一個邊界。幾乎就像你在整個厚度的不同點上模擬一塊材料的溫度。
但後來你追加到T列表。這使材料更厚?或者僅僅意味着你有一個bug,你應該用取代的值,而不是追加到列表的末尾。
我會嘗試替換值。如果我弄錯了,你可以告訴我。 (我猜在這裏,你正在試圖做什麼)
此外,考慮一下:
lst = [1,2,3]
index = 0
print(lst[index-1] + lst[index] + lst[index+1])
如果你喂的是成Python,你會得到6
。爲什麼?
因爲lst[-1]
從列表中拉出最後一項!特殊的神奇Python語法!在這種情況下,可能不是你想要的。在這種情況下,我認爲你不想從0
到len(T)
。相反,您希望跨越內部節點並離開邊界。 (或者,也許你想添加一些超出邊界的其他值,你必須告訴我)。
所以我們只需要處理內部的節點,並忽略邊界。幸運的是,range()
函數需要開始參數!但請記住,它停止了停止的說法。在這種情況下,我們需要添加一個:
T_new = T[:] # Make a copy of T
for j in range(1, num_nodes+1):
T_new[j] = (T[j]
+ (T[j-1] - T[j]) * adt_per_dx2
+ (T[j+1] - T[j]) * adt_per_dx2
)
T = T_new # Replace the old T with the new T.
我做噸對T_new的事情,這樣計算的中間結果不會影響到減法(T [J-1] - T [J])。
現在,讓我們優化一點。注意j正在增加?所以在循環'N'上,我們有T [j + 1]。但在循環N + 1將是T [j]!如果我們不介意改變標誌,我們可以節省一些中間結果。也就是說,T[j+1] - T[j]
最終會變成T[j] - T[j-1]
。如果我們只是否定它,那將是我們想要保留的T[j-1] - T[j]
!
更重要的是,如果我們可以節省計算,我們將不再需要任何T_new
更多,因爲T_new
的唯一原因是因爲在此之前,我們可以用它來計算T[j]
T[j-1]
得到了更新。
讓我們試着保存T[j+1] - T[j]
計算,並否定它。
saved = T[1] - T[0]
for j in range(1, num_nodes+1):
T[j] = (T[j]
+ -saved * adt_per_dx2
+ (T[j+1] - T[j]) * adt_per_dx2
)
saved = T[j+1] - T[j]
好的,這工作一點。它擺脫了T_new
變量。我們可以做更多嗎?讓我們再添加一個臨時變量,乘:
saved = (T[1] - T[0]) * adt_per_dx2
for j in range(1, num_items+1):
temp = (T[j+1] - T[j]) * adt_per_dx2
T[j] += temp - saved
saved = temp
而且我們打印的時候,用T的電流陣列:
print("Time={}s, T={}r\n".format(time_sec, T))
全部放在一起:
num_nodes = int(input("Enter the number of nodes: "))
boundary1 = float(input("Enter the first boundary condition: "))
boundary2 = float(input("Enter the second boundary condition: "))
conductivity = float(input("Enter the thermal conductivity: "))
initial_cond = float(input("Enter the initial condition: "))
num_ticks = int(input("Enter the number of time steps: "))
delta_t = float(input("Enter the change in time, dT: "))
T = ([boundary1]
+ [initial_cond] * num_nodes
+ [boundary2]
)
adt_per_dx2 = conductivity * delta_t * (num_nodes + 1)**2
time_sec = 0.0
for t in range(num_ticks):
time_sec += delta_t
saved = (T[1] - T[0]) * adt_per_dx2
for j in range(1, num_nodes+1):
temp = (T[j+1] - T[j]) * adt_per_dx2
T[j] += temp - saved
saved = temp
print("Time={}s, T={}r\n".format(time_sec, T))
現在,當我運行它時出現問題。我認爲「adt_per_dx2」應該小於1。事實並非如此。這意味着節點之間的Δ-T增加,並且增加的數量增加到T [j]。我所知道的是錯誤的,因爲你無法從任何地方獲得免費的熱量。
但是,這是我實際上不知道你在做什麼的部分。所以我不知道錯誤在哪裏。我認爲這與節點數量有關,也許你應該要求總長度或厚度並按節點數量進行劃分?無論如何,檢查一下,看看你做了什麼。
更正您的代碼,刪除'print'作爲'input'的參數。 ''i = float(input('enter the number of nodes'))' – Zety
我已經將代碼T.append(y)更改爲T [j] = y。然後它的工作 –
感謝您的關注 –