2013-02-18 31 views
6

模型I-V。Python中的模型I-V

方法: 執行一個整體,作爲E的函數,其輸出電流對所使用的每個電壓值。對於一系列v_values,這是重複的。該等式可以在下面找到。

enter image description here

雖然在這個方程範圍內-infinf極限,極限必須被限制,以使(E + eV)的^ 2- \德爾塔^ 2> 0和E^2- \德爾塔^ 2> 0,以避免極點。 (\ Delta_1 = \ Delta_2)。因此,目前有兩個積分,其範圍從-inf-gap-e*vgapinf

然而,我的回頭率一個math range error但我相信我已經通過上述的限制排除了麻煩ê值。錯誤的Pastie:http://pastie.org/private/o3ugxtxai8zbktyxtxuvg

道歉這個問題的模糊性。但是,任何人都可以看到明顯的錯誤或代碼濫用?

我嘗試:

from scipy import integrate 
from numpy import * 
import scipy as sp 
import pylab as pl 
import numpy as np 
import math 

e = 1.60217646*10**(-19) 
r = 3000 
gap = 400*10**(-6)*e 
g = (gap)**2 
t = 0.02 
k = 1.3806503*10**(-23) 
kt = k*t 

v_values = np.arange(0,0.001,0.0001) 

I=[] 
for v in v_values: 
    val, err = integrate.quad(lambda E:(1/(e*r))*(abs(E)/np.sqrt(abs(E**2-g)))*(abs(E+e*v)/(np.sqrt(abs((E+e*v)**2-g))))*((1/(1+math.exp((E+e*v)/kt)))-(1/(1+math.exp(E/k*t)))),-inf,(-gap-e*v)*0.9) 
    I.append(val) 
I = array(I) 

I2=[] 
for v in v_values: 
    val2, err = integrate.quad(lambda E:(1/(e*r))*(abs(E)/np.sqrt(abs(E**2-g)))*(abs(E+e*v)/(np.sqrt(abs((E+e*v)**2-g))))*((1/(1+math.exp((E+e*v)/kt)))-(1/(1+math.exp(E/k*t)))),gap*0.9,inf) 
    I2.append(val2) 
I2 = array(I2) 

I[np.isnan(I)] = 0 
I[np.isnan(I2)] = 0 

pl.plot(v_values,I,'-b',v_values,I2,'-b') 
pl.show() 
+0

如果你在軸上有極點,難道你不想在複雜分析中做這個積分嗎?計算殘留物要容易得多。 – tacaswell 2013-02-18 18:08:37

+2

重新調整變量的大小,以便*數值計算*不涉及真正的小浮點數,例如「k」和「e」等。純數學運算時很好,但當浮點數很小時,數值算法通常效果不佳。 – unutbu 2013-02-18 18:31:22

+3

你在第二個玻爾茲曼項中的exp的參數的分母中丟失了大括號,或者你忘記了用'kt'代替'k * t'。此外,你正在集成'[0.9 * gap-ev,0.9 * gap]'。也許你想將它分成兩個整數:一個用'(-inf,-0.9 * gap-ev)'和一個用[[0.9 * gap,inf]')。 – 2013-02-18 19:16:39

回答

1

最後處理此問題的最佳方法是使用heaviside函數來防止E變量超出\Delta變量。

2

的原因數學範圍錯誤是,你的指數趨近​​於無窮。以v = 0.0009E = 5.18e-23,表達exp((E + e*v)/kt)(我糾正錯字在你的Python表達所指出的赫里斯託·裏夫·)是exp(709.984..)這超出你可以用雙精度數字表示範圍(高達約1E308)。

兩個額外的注意事項:

  • 正如其他人所指出的,你應該用一個單元系統,在一個較小的範圍內提供數重新調整你的公式。也許,原子單位是一個可能的選擇,因爲它會設置e = 1,但我沒有嘗試將其轉換成它。 (可能,你的時間步將變得相當大,因爲在原子單位時間單位約爲1/40 fs)。

  • 通常,對浮點數使用指數表示法:e = 1.60217E-19而不是e = 1.60217*10**(-19)

+2

'(E + e * v)/ kt'是無量綱的(能量除以能量),無論單位的選擇如何,它的值都是相同的。對於整個被積函數也是如此,因爲另外兩個表達式也是無量綱的。解決問題的唯一方法是將積分範圍分成多個區間,併爲每個區間推導一個適當的近似表達式(例如使用泰勒級數),這樣不會導致上/下溢。 – 2013-02-19 08:51:49

+0

當然,這是真的。我更多地指的是像SI單位的電子充電這樣的前因子,人們可以擺脫它。但我同意,這不會用指數函數解決問題。 – 2013-02-19 09:06:13

4

此問題更適合於Computational Science網站。這裏還有一些值得你思考的問題。

首先,積分範圍是(-oo, -eV-gap) U (-eV+gap, +oo)(-oo, -gap) U (gap, +oo)的交叉點。有兩種可能的情況:

  • 如果eV < 2*gap然後允許能量值是(-oo, -eV-gap) U (gap, +oo);
  • 如果eV > 2*gap則允許的能量值在(-oo, -eV-gap) U (-eV+gap, -gap) U (gap, +oo)中。

其次,你是在一個非常低的溫度範圍內工作。由於t等於0.02 K,玻爾茲曼因子中的分母是1.7μeV,而能隙是400μeV。在這種情況下,指數的值對於正能量是巨大的,它很快就會超出Python使用的雙精度浮點數的極限。由於這是可能的正能量,所以在高能量情況下情況並不會好轉。負能量的值總是非常接近於零。請注意,在此溫度下,費米 - 狄拉克分佈具有非常尖銳的邊緣,並且類似於反射的θ函數。在E = gap你將有exp(E/kT)約爲6.24E + 100。當您使用E/kT > 709.78E > 3.06*gap時,您會用盡範圍。

因爲在這個溫度下,兩個費米函數之間的差異非常快速地變爲零,而在[-eV, 0]區間之外的差異完全落入對於給定溫度的差距內(012m(0.8mV)),所以沒有意義。這就是爲什麼當偏置電壓小於0.8 mV時,電流會非常接近於零的原因。當它大於0.8 mV時,積分的主要值將來自被積函數(-eV+gap, -gap),儘管某些非零值將來自奇點附近的區域E = gap和一些來自奇點附近的區域E = -eV-gap你不應該回避奇點的DoS攻擊,否則你不會得到在I(V)曲線預期的不連續性(垂直線)(圖片來自Wikipedia拍攝):

STJ current-voltage diagram

相反,你必須在每個奇點附近推導等價的近似表達式,並將其整合。

正如你所看到的,integrand的價值有很多特殊情況,你必須在數值計算時考慮到它們。如果你不想這樣做,你應該轉向其他一些數學軟件包,比如Maple或Mathematica。這些具有更復雜的數值積分例程,並且可能能夠直接處理您的公式。

請注意,這不是試圖回答你的問題,而是一個很長的評論,不適合任何評論領域。