Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在FiPy中使用扫描函数时的解算器公差和残余误差_Python_Scipy_Fipy - Fatal编程技术网

Python 在FiPy中使用扫描函数时的解算器公差和残余误差

Python 在FiPy中使用扫描函数时的解算器公差和残余误差,python,scipy,fipy,Python,Scipy,Fipy,我正试图使用FiPy解决一组PDE,这时我意识到sweep命令的工作方式与我想象的不一样。下面是我的部分代码示例: from pylab import * import sys from fipy import * viscosity = 5.55555555556e-06 Pe =5. pfi=100. lfi=0.01 Ly=1. Nx =200 Ny=100 Lx=Ly*Nx/Ny dL=Ly/Ny mesh = PeriodicGrid2DTopBottom(nx=Nx, ny

我正试图使用FiPy解决一组PDE,这时我意识到sweep命令的工作方式与我想象的不一样。下面是我的部分代码示例:

from pylab import *
import sys
from fipy import *

viscosity = 5.55555555556e-06 

Pe =5.

pfi=100.
lfi=0.01

Ly=1.
Nx =200
Ny=100
Lx=Ly*Nx/Ny
dL=Ly/Ny
mesh = PeriodicGrid2DTopBottom(nx=Nx, ny=Ny, dx=dL, dy=dL)

x, y = mesh.cellCenters

xVelocity = CellVariable(mesh=mesh, hasOld=True,  name='X velocity')

xVelocity.constrain(Pe, mesh.facesLeft)
xVelocity.constrain(Pe, 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_fi= CellVariable(mesh=mesh, value=0.,name='Fluid-interface energy map')
pi_fi.setValue(pfi*exp(-1.*(var1-rad)/lfi), where=(var1 > rad) )
pi_fi.setValue(pfi, where=(var1 <= rad))

xVelocityEq = DiffusionTerm(coeff=viscosity) - ImplicitSourceTerm(pi_fi)

xres=10.
while (xres > 1.e-6) :
        xVelocity.updateOld()
        mySolver = LinearGMRESSolver(iterations=1000,tolerance=1.e-6)
        xres = xVelocityEq.sweep(var=xVelocity,solver=mySolver)
        print 'Result = ', xres
#Thats it
如您所见,while循环在两次迭代后结束。我的第一个问题是:为什么我的第一个剩余误差(=0.0007856742013190237)高于解算器的容差?我认为,由于xVelocityEq对应于一个线性系统,解算器公差和剩余误差的含义是相同的。

如果我将mySolver中的迭代次数从1000增加到10000,我将得到以下输出:

Result =  0.0007856742013190237
Result =  2.4619110931978988e-09
Result =  0.0007856742013190237
Result =  6.414470433257661e-07
既然第一个残差保持不变,为什么第二个残差会发生变化?

如果我将mySolver中的容差从1.e-6增加到7.e-4,我将得到以下输出:

Result =  0.0007856742013190237
Result =  2.4619110931978988e-09
Result =  0.0007856742013190237
Result =  6.414470433257661e-07
请注意,这些残差与第一次输出中的残差相同。现在,如果我尝试将公差进一步增加到8.e-4,以下是我得到的输出:

Result =  0.0007856742013190237
Result =  0.0007856742013190237
Result =  0.0007856742013190237
Result =  0.0007856742013190237
Result =  0.0007856742013190237
...
在这一点上,我完全迷路了为什么残差对于小于7.e-4的所有解算器公差具有相同的值?对于高于7.e-4的解算器公差,为什么这些残差是常数并等于0.0007856742013190237?

如果我将mySolver更改为LinearLUSolver(迭代次数=1000,容差=1.e-6),我得到的结果如下:

Result =  0.0007856742013190237
Result =  1.6772757200988522e-18
为什么我的第一个残差与以前一样,即使我已经更改了解算器?

为什么我的第一个剩余误差(=0.0007856742013190237)高于解算器的公差

调用解算器以计算新的解向量之前,将计算由
.sweep()
计算的残差。矩阵L和右侧向量b基于解向量x的初始值进行计算

残差是当前解向量满足非线性偏微分方程的程度的度量。解算器公差限制了解算器在满足从PDE离散的线性方程组时的工作强度

即使PDE是线性的(例如,扩散系数不是解变量的函数),初始值也可能无法解PDE,因此残差很大。调用解算器后,x应在解算器公差范围内解算PDE。如果偏微分方程是非线性的,那么线性代数的良好收敛解可能仍然不是偏微分方程的好解;这就是扫地的目的

我认为,由于xVelocityEq对应于一个线性系统,解算器公差和剩余误差将意味着相同的事情

跟踪这两个方面是没有任何用处的。除了解算前的残差和用于终止解算的解算器公差外,还可以使用不同的规格化,并且许多解算器文档可能有点粗略。FiPy使用|Lx-b|u2作为其残差。解算器可以通过b的大小、L的对角线或月亮的相位进行归一化,所有这些都会导致很难直接将残差与公差进行比较

既然第一个保持不变,为什么第二个残差会发生变化

通过允许1000次迭代而不是100次迭代,解算器能够驱动到更精确的公差,这反过来又会导致下一次扫描的残差更小

为什么残差对于小于7.e-4的所有解算器公差具有相同的值?对于高于7.e-4的解算器公差,为什么这些残差是常数并等于0.0007856742013190237

可能是因为解算器失败,因此没有更改解向量的值。有些解算器不报告这一点。在其他情况下,我们应该更好地向你们报告这一事实

为什么我的第一个残差和以前一样,即使我改变了解算器

残差不是解算器的属性。这是近似于PDE的离散化方程组的特性。然后,这些线性代数方程就是解算器的输入