python解隐式⽅程_⽤隐式⽅法求解偏微分⽅程组
我有⼀个偏微分⽅程组(PDE),特别是应⽤于传热和对流的扩散-平流-反应⽅程,我⽤有限差分法求解。
在我的模拟环境中,我有很多不同的部分,⽐如管道,储能器,热交换器等等。。。根据零件的不同,每个零件的PDE可以是1D(在⼤多数情况下)或2D(约占零件的5%)或3D(很少)。由于这些不同的形状,为整个系统构造⼀个三对⾓(或五⾓、间隔-…)太复杂了。
diff函数这个问题发表在SO上⽽不是计算科学上,因为它是关于如何使⽤pde的求解算法的,⽽不是关于pde的求解⽅法。在
因此,⽬前每个部件都有⼀个diff函数,它返回给定输⼊温度的微分。由于材料特性等与温度(和流量)有关,因此PDE是⾮线性的,但由于系数滞后于系数⽽被认为是线性的(在每个步骤使⽤起始温度计算温度和流量相关值,对于在每次迭代中重新计算它们的隐式⽅法)。diff函数返回的微分的形状与零件的值数组形状相同,例如,对于具有10个⽹格点的⼀维管道,这将导致形状(10, )的差分数组。扩散系数和其他系数被认为是diff函数的内部参数,对解算器不可⽤。因此解算器将只知道差分、当前零件温度和步长。
有没有什么⽅法可以⽤python⼀次只执⾏⼀个步骤,使⽤⼀个专门⽤于求解pde的算法来求解这些pde?(以及优选为scipy/numpy的⼀部分并且更优选地已经由numba⽀持的算法。)
到⽬前为⽌我考虑过的事情:scipy.integrate:仅对ode可⾏,⽽PDE可能不在其中。对吗?⾄少我不能⽤它来做PDE的好结果。除此之外,scipy.integrate并不是只⽤于计算⼀个步骤的。在
np.linalg.solve:似乎是最好的⽅法,如果你有三对⾓矩阵和线性⽅程组。但由于我既没有三对⾓矩阵,也没有线性⽅程(线性化了,但系数滞后意味着必须在迭代过程中更新它们)。有没有办法在不增加计算成本的情况下仍然使⽤这个⽅法?在
scipy.optimize:可⾏且易于使⽤。下⾯我的最⼩⼯作⽰例将使⽤此集成⼀个解决⽅案。但是这个是否总是适⽤于pde并且这通常是隐式解决偏微分⽅程的正确⽅法,还是仅仅在这个例⼦中起作⽤⽽我⾛错了⽅向?
⼀个简单迭代函数的⾃⾝积分。也显⽰在下⾯的例⼦中。与scipy.optimize相同:在这个简单的例⼦中,这是有效的,还是对pde⼀般都有效?在
最⼩⼯作⽰例import time
from scipy import optimize
def diff(T): # simply example differential function
time.sleep(0.0001) # dummy timer to slow down the calculation
return np.sqrt(T)
def euler_bdf(y, yprev, h):
return (y - yprev - h*diff(y))
def crank_nicolson(y, yprev, h): # diff(yprev) will be outsourced for performance
return (y - yprev - h / 2 * (diff(y) + diff(yprev)))
def iterate_eulerbdf(y0, h, rtol, diff):
y = y0
f = np.ones_like(y)
i = 0
while np.any(f > rtol):
y_old = y
y = y0 + h * diff(y)
f = (y / y_old - 1) # this will be replaced by least mean squares
i += 1
return y, i
def iterate_cranknicolson(y0, h, rtol, diff):
y = y0
diff_old = diff(y)
f = np.ones_like(y)
i = 0
while np.any(f > rtol):
y_old = y
y = y0 + h / 2 * (diff_old + diff(y))
f = (y / y_old - 1)
i += 1
return y, i
T0 = np.arange(10, 20).astype(float) # starting temperature
eulerbdf_hybr = (euler_bdf, T0, args=(T0, 1.), method='hybr', tol=1e-6)
eulerbdf_dfsane = (euler_bdf, T0, args=(T0, 1.), method='df-sane', tol=1e-6)
eulerbdf_it = iterate_eulerbdf(T0, 1., 1e-6, diff)
cn_hybr = (crank_nicolson, T0, args=(T0, 1.), method='hybr', tol=1e-6)
cn_dfsane = (crank_nicolson, T0, args=(T0, 1.), method='df-sane', tol=1e-6)
cn_it = iterate_cranknicolson(T0, 1., 1e-6, diff)
TL,DR问题摘要
所有的结果似乎都是好的,但这种⽅法对⼀般的实偏微分⽅程⾏吗?
推荐的⽅法是什么?
对于各种不同形状和尺⼨的pde,从(5,)到超过(100, 100, 100),哪种⽅法最有效?因为scipy.integrate⽬前{}似乎是最快的,但我怀疑这是否适⽤于更⼤的问题。
尤其是:还有更好的⽅法吗?
提前谢谢!在
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论