0

現在、Python で FiPy を使用してセル変数phiに関する微分方程式 ( eq0 ) を解くためにスイープ ループを使用しています。私の方程式は非線形であるため、以下のコードの抜粋に示すように、スイープループを使用しています。

while  res0 > resphi_tol:    
        res0 = eq0.sweep(var=phi, dt=dt)

しかし、次のエラーが発生し続けます。

C:\Python27\lib\site-packages\fipy\variables\variable.py:1100: Ru​​ntimeWarning: power return self._BinaryOperatorVariable(lambda a,b: pow(a,b), other, value1mattersForUnit=True で無効な値が検出されました)
C:\Python27\lib\site-packages\fipy\variables\variable.py:1186: RuntimeWarning: less_equal return self._BinaryOperatorVariable(lambda a,b: a<=b, other)
トレースバック (最新call last):
.. ファイル "SBM_sphere3.py", 行 59, in
....res0 = eq0.sweep(var=phi, dt=dt)
.. ファイル "C:\Python27\lib\site-packages\ fipy\terms\term.py"、207 行、sweep
....solver._solve()
.. ファイル "C:\Python27\lib\site-packages\fipy\solvers\pysparse\pysparseSolver.py"、行68、_solve
....self で。solve (self.matrix, array, self.RHSvector)
.. ファイル "C:\Python27\lib\site-packages\fipy\solvers\pysparse\linearLUSolver.py"、53 行目、_solve__ 内
....LU = superlu .factorize(L.matrix.to_csr())
..ファイル「C:\Python27\lib\site-packages\pysparse\misc__init__.py」、29行目、newFunc内
....return func(*args, ** kwargs)
.. ファイル "C:\Python27\lib\site-packages\pysparse__init__.py"、47 行目、factorize
....return self.factorizeFnc(*args, **kwargs)
RuntimeError: Factor は厳密に特異です

このエラーは、 eq0に存在する用語 phi^(2/3) が原因であると確信しています。この項を abs(phi)^(2/3) に置き換えると、エラーはなくなります。

スイープ ループは、ある時点でphiのいくつかのセルに対して負の値を返し、整数以外の指数で負の値をパワーすることはできないため、エラーが発生すると仮定します。

だから私の質問は:負の解決策を避けるためにスイープを強制する方法はありますか?

スイープする前に、すべての負の値を 0 に設定する行を含めようとしました。

while  res0 > resphi_tol:    
        phi.setValue(0.,where=phi<0.)
        res0 = eq0.sweep(var=phi, dt=dt)

エラーはまだ残っています (線形化されたシステムを解いた直後に、スイープが係数の新しい行列を計算しようとするためですか?)。

編集: FiPy 3.2でPython 2.7.14を使用しています。クエリに関連すると思われるコードの部分を以下に共有しています。コード全体は非常に拡張されています。いくつかのコンテキスト: サスペンション フローのバランス方程式を解いています。eq0は粒子相の物質収支方程式に対応し、phiは粒子の体積分率です。

from pylab import *
from fipy import *
from fipy.tools import numerix
from scipy import misc
import osmotic_pressure_functions as opf

kic=96.91
lic=0.049

dt=1.e-2
steps=10

tol=1.e-6

Nx=8
Ny=4
Lx=Nx/Ny
dL=1./Ny

mesh = PeriodicGrid2DTopBottom(nx=Nx, ny=Ny, dx=dL, dy=dL)
x, y = mesh.cellCenters

phi = CellVariable(mesh=mesh, hasOld=True, value=0.,name='Volume fraction')

phi.constrain(0.01, mesh.facesLeft)
phi.constrain(0., mesh.facesRight)

rad=0.1

var1 = DistanceVariable(name='distance to center', mesh=mesh, value=numerix.sqrt((x-Nx*dL/2.)**2+(y-Ny*dL/2.)**2))

pi_ci = CellVariable(mesh=mesh, value=0.,name='Colloid-interface energy map')
pi_ci.setValue(kic*exp(-1.*(var1-rad)/(1.*lic)), where=(var1 > rad))
pi_ci.setValue(kic, where=(var1 <= rad))

def pi_cc_entr(x):
    return opf.vantHoff(x)

def pi_cc_vdw(x):
    return opf.van_der_waals(x,0.74,0.1)

def pi_cc(x):
    return pi_cc_entr(x) + pi_cc_vdw(x)

diffusioncoeff = misc.derivative(pi_cc,phi,dx=1.e-6)

eq0 = TransientTerm() + ConvectionTerm(-pi_ci.faceGrad) == DiffusionTerm(coeff=diffusioncoeff)

step=0
t=0.

for step in range(steps):
    print 'Step ', step

    phi.updateOld()
    res0 = 1e+10
    while res0 > tol :
        phi.setValue(0., where=phi<0)
        res0 = eq0.sweep(var=phi, dt=dt) #ERROR HAPPENS HERE

関数vantHoffvan_der_waalsは別のファイルで定義されています。

def vantHoff(phi):
    return phi

def van_der_waals(phi,phi_cp,nd_v):
    return (nd_v*phi**3) / ((phi_cp-(phi_cp)**(1./3.)*(phi)**(2./3.))**2)
4

1 に答える 1

0

の係数DiffusionTermが allであるため、エラーが発生しますnan。これは、拡散係数が次のように定義されているためです。

(((((((Volume fraction + -1e-06) + (((pow((Volume fraction + -1e-06), 3)) * 0.1) / (pow((0.74 - ((pow((Volume fraction + -1e-06), 0.6666666666666666)) * 0.9045041696510275)), 2)))) * -0.5) + 0.0) + (((Volume fraction + 0.0) + (((pow((Volume fraction + 0.0), 3)) * 0.1) / (pow((0.74 - ((pow((Volume fraction + 0.0), 0.6666666666666666)) * 0.9045041696510275)), 2)))) * 0.0)) + (((Volume fraction + 1e-06) + (((pow((Volume fraction + 1e-06), 3)) * 0.1) / (pow((0.74 - ((pow((Volume fraction + 1e-06), 0.6666666666666666)) * 0.9045041696510275)), 2)))) * 0.5)) / 1e-06)

およびVolume fraction( phi) はすべてゼロであるため-1e-06、 は未定義の分数べき乗になります。

の要因は、明らかにシンボリック導関数を計算する-1e-06ために を使用したことから生じますか? scipy.misc.derivative()それが意図されているとは思えません。おそらくSymPyの方がうまくいくでしょう。

于 2019-09-23T18:33:59.933 に答える