我正在使用带有'solve_ivp`的线的方法来求解非线性PDE:
@njit(fastmath=True,error_model="numpy",cache=True)
def thinFilmEq(t,h,dx,Ma,phiFun,tempFun):
phi = phiFun(h)
temperature = tempFun(h)
hxx = (np.roll(h,1) - 2*h + np.roll(h,-1))/dx**2 # use np.roll as I'm implementing periodic BC
p = phi - hxx
px = (np.roll(p,-1) - np.roll(p,1))/(2*dx)
Tx = (np.roll(temperature,-1) - np.roll(temperature,1))/(2*dx)
flux = h**3*px/3 + Ma*h**2*Tx/2
dhdt = (np.roll(flux,-1) - np.roll(flux,1))/(2*dx)
return dhdt
我收到以下错误:TypingError: non-precise type pyobject
[1] During: typing of argument at C:/Users/yhcha/method_of_lines/test_01_thinFilmEq.py (28)
我怀疑是由于phiFun
和tempFun
引起的。它们是我在调用时提供的功能。我将dhdt函数的函数参数设为只是为了使事情更通用。当我尝试删除phiFun
和tempFun
并在thinFilmEq
内明确给出函数形式时,错误消失了。
然后,我看到以下错误TypingError: Use of unsupported NumPy function 'numpy.roll' or unsupported use of the function.
,尽管官方website中包含了np.roll
,但我认为它可能不受支持。在处理周期性BC的有限差分时,我尝试将数组“扩大”以某种方式手动应用与np.roll
相同的东西:
def augment(x):
x2 = np.empty(len(x)+2)
x2[1:-1] = x
x2[0] = x[-1]
x2[-1] = x[0]
return x2
H = augment(x)
hx = (H[2:]-[H:-2])/dx # use this instead of hx=(roll(h,-1)-roll(h,1))/dx
我的问题是:
似乎我可以让numba
正常工作,但要以降低代码的通用性为代价(不能提供像phiFun
这样的任意函数且比较优雅(例如,不能使用一个可以使用np.roll
进行衬里)。有没有办法解决?还是只是使用numba
“编译”代码时需要付出的代价?
不带numba
的原始版本比我编写的Matlab版本慢近10倍,而numba
版本仍然比Matlab慢3-4倍。我真的不希望scipy
胜过Matlab,但是还有其他方法可以加快代码以弥合差距吗?