一般边界条件

时间:2017-03-13 17:25:41

标签: fipy

我很感激设置一般边界条件的帮助,-grad(y) + g(y) = 0其中g是未知y的某些功能。这是一个我无法工作的简单的一维示例:

N=3
h=1./(float(N)-1.)

mesh = Grid1D(nx=N, dx=h)

c=CellVariable(mesh=mesh,value=0.5)

## Dirichlet boundary conditions
#c.constrain(2., mesh.facesLeft)
#c.constrain(1., mesh.facesRight)

## Neumann boundary conditions
c.faceGrad.constrain(-1, where=mesh.facesLeft)
c.faceGrad.constrain( -c.faceValue , where=mesh.facesRight)

Eq = DiffusionTerm(coeff=1.0)
Eq.cacheMatrix()
Eq.cacheRHSvector()
Eq.solve(var=c)
m = Eq.matrix.numpyArray
b = Eq.RHSvector

这段代码不会解决,但我确实可以看到矩阵和RHS:

m= array([[-2.,  2.,  0.],
          [ 2., -4.,  2.],
          [ 0.,  2., -2.]])

b= array([-1. ,  0. ,  0.5])

矩阵m显然是单数的,因为源项未包含在最后一行中。关于如何包含它的任何建议?

1 个答案:

答案 0 :(得分:0)

[编辑:添加第一顺序实现的推导和演示]

known issues有一般边界条件。

可以将这种边界条件实现为源。使用discretization of the DiffusionTerm $\sum_f D_f (n\cdot\nabla(y))_f A_f$我们将$f=R$视为一种特殊情况,并替换所需的边界条件-n\cdot\nabla(y) - y = 0。我们通过将D_(f=R)

中的DiffusionTerm置零来实现此目的
c.faceGrad.constrain([-1], where=mesh.facesLeft)

D = 1.
Dface = FaceVariable(mesh=mesh, value=D)
Dface.setValue(0., where=mesh.facesRight)

然后添加隐式来源D_(f=R) (n\cdot\nabla(y))_(f=R) A_(f=R)D_(f=R) (-y)_(f=R) A_(f=R)。源是在单元中心定义的,因此我们将单元定位在$f=R$

附近
mask_coeff = (mesh.facesRight * mesh.faceNormals).divergence

然后添加源

Af = mesh._faceAreas[mesh.facesRight.value][0]
Eq = DiffusionTerm(coeff=Dface) - ImplicitSourceTerm(coeff=mask_coeff * D * Af)

此处理仅为0阶精确,因为ImplicitSourceTerm对单元格中心的值进行操作,而边界条件则定义在相邻的面中心。

我们可以通过从边界条件沿着梯度将单元格值投影到面上,使边界条件在空间中精确一阶: y_(f=R) ~ y_P + n\cdot\nabla(y)_(f=R) dPR其中y_P是距离y最近的单元格中心f=R的值,dPR是从P到{{{}}的距离{1}}。

因此边界条件R变为-n\cdot\nabla(y)_(f=R) - y_(f=R) = 0,我们可以为-n\cdot\nabla(y)_(f=R) - (y_P + n\cdot\nabla(y)_(f=R) dPR) = 0求解。因此,n\cdot\nabla(y)_(f=R) = -y_P / (1 + dPR)的边界对应的隐式源是DiffusionTerm

D_(f=R) (-y_P / (1 + dPR)) A_(f=R)

这是去年夏天在FiPy邮件列表上讨论的,从https://www.mail-archive.com/fipy@nist.gov/msg03671.html开始。是的,现在一切都很笨拙。