如何将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]
答案 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()