你如何在Fipy中指定Neumann(固定通量法向面)边界条件?

时间:2016-09-18 03:15:24

标签: python mesh pde fipy

如何将fipy网格中的边界面的通量法线显式设置为特定值,而不限制面部内的通量分量?

Neumann边界条件可以指定为:(1)垂直于边界面的通量的固定分量,或(2)作为面的通量的完整规范。默认的fipy条件是前者(value = 0),但显式方法(faceGrad.constrain)是后者。通过将以下代码添加到fipy diffusion.mesh20x20示例的末尾并注意不同的面渐变结果,可以理解该问题。

facesNeumann = mesh.exteriorFaces & ~facesTopLeft & ~facesBottomRight
print 'grad(phi) with default Neumann BC...'
print phi.faceGrad.value.T[facesNeumann.value]
phi.faceGrad.constrain(0.,facesNeumann)
DiffusionTerm().solve(var=phi)
print 'and with explicit Neumann BC...'
print phi.faceGrad.value.T[facesNeumann.value]

3 个答案:

答案 0 :(得分:2)

请参阅有关fixed flux boundary conditions的讨论。基本上,您可以将包含所需边界通量偏差的源添加到FiPy的默认无通量条件。

答案 1 :(得分:2)

就仅仅指定与变量的边界垂直的通量而言,与求解方程无关,似乎没有任何方法可以做到这一点。例如,语法可能是phi.faceGrad[0].constrain(...),但目前在FiPy中不起作用。面向任意面孔也可能难以实现。

然而,出于实际目的,在求解FiPy中的方程时不使用与边界相切的分量,只有正常分量对解决方案有任何影响。例如,请使用以下代码

import fipy as fp
mesh = fp.Grid2D(nx=2, ny=1)
var = fp.CellVariable(mesh=mesh)
var.constrain(1, mesh.facesLeft)
var.constrain(0, mesh.facesRight)
#var.faceGrad.constrain(0, mesh.facesTop)
fp.DiffusionTerm().solve(var)
print 'face gradient on top plane:',var.faceGrad[0, mesh.facesTop.value]
print 'variable value:',var

这给出了

的输出
face gradient on top plane: [-0.5 -0.5]
variable value: [ 0.75  0.25]

答案是正确的,但顶面渐变为-0.5。但是,当取消注释行#var.faceGrad.constrain(0, mesh.facesTop)时,结果为

face gradient on top plane: [ 0.  0.]
variable value: [ 0.75  0.25]

切向面渐变现在为0,但答案是相同的。关键是切向设置面渐变(通过.constrain)对解决方案没有影响。

答案 2 :(得分:1)

关于固定通量边界条件的讨论确实回答了我的问题,但我没有理解文档,这是非常简短的。下面是一个工作示例,演示了如何在简单的2D情况下应用它,类似于mesh20x20示例。

import matplotlib.pyplot as plt
from fipy import *

nx = 20
ny = nx
dx = 1.
dy = dx
L = dx * nx
msh = Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)

xFace, yFace = msh.faceCenters
xCell,yCell = msh.cellCenters    
phi = CellVariable(name = "solution variable",
                   mesh = msh,
                   value = 0.)    
D = FaceVariable(name='diffusion coefficient',mesh=msh,value=1.)

# Dirichlet condition on top face
valueTop = FaceVariable(name='valueTop',mesh=msh,value=xFace*0.1-1)
phi.constrain(valueTop, msh.facesTop)

# Fixed flux (Neumann) on base
D.constrain(0., msh.facesBottom)
fluxBottom = -0.05

eq = DiffusionTerm(coeff=D) + (msh.facesBottom * fluxBottom).divergence
eq.solve(var=phi)

# confirm only y component of gradient is zero
print phi.faceGrad.value.T[msh.facesBottom.value]

plt.scatter(phi.value, yCell)
plt.show()

viewer = Viewer(vars=phi, datamin=-1., datamax=1.)
viewer.plot()