2016-01-31 50 views
-3

代碼停在中間。請幫助 採取所有輸入之後,同時caluculating的caluculation部分程序不運行

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'))) 
k=0 
T=[] 
T.append(T0) 
while k!=i: 
    T.append(Ti) 
    k+=1 
T.append(Tn) 
print(T) 
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 
+0

更正您的代碼,刪除'print'作爲'input'的參數。 ''i = float(input('enter the number of nodes'))' – Zety

+0

我已經將代碼T.append(y)更改爲T [j] = y。然後它的工作 –

+0

感謝您的關注 –

回答

0

讓我們用一些簡單的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=0k=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語法!在這種情況下,可能不是你想要的。在這種情況下,我認爲你不想從0len(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]。我所知道的是錯誤的,因爲你無法從任何地方獲得免費的熱量。

但是,這是我實際上不知道你在做什麼的部分。所以我不知道錯誤在哪裏。我認爲這與節點數量有關,也許你應該要求總長度或厚度並按節點數量進行劃分?無論如何,檢查一下,看看你做了什麼。

+0

感謝您的答案先生,它幫助了我很多。但是無論哪種方式,我都得到了解決方法。即使我是初學者,我仍然需要再次通過這門課程。實際上,在這個問題中,我正在計算不同節點在不同時間步驟的溫度,以解決非穩態熱傳導問題 –

0

我不知道這是否是原因,但條件下使用時floats,從不使用!=代碼停止。相反,使用<=。事實上,0.000001的差異足以讓你的條件永遠不會是真的,在你的代碼中,你大部分的步驟都是1.0。

因此,如果您的輸入i不是圓的,您的第一個while循環將永遠運行。

+0

我已經將代碼T.append(y)更改爲T [j] = y。然後它的工作 –