2013-02-18 35 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。这些具有更复杂的数值积分例程,并且可能能够直接处理您的公式。

请注意,这不是试图回答你的问题,而是一个很长的评论,不适合任何评论领域。