我很感激设置一般边界条件的帮助,-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
显然是单数的,因为源项未包含在最后一行中。关于如何包含它的任何建议?
答案 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开始。是的,现在一切都很笨拙。