2016-09-18 13 views
2

Как явным образом установить поток нормали к граничной грани в сетке fipy как конкретное значение, не ограничивая компоненты потока внутри грани?Как вы определяете граничное условие Неймана (фиксированный поток от нормали к лицу) в Fipy?

Граничное условие Неймана может быть определено как: (1) постоянная составляющая потока, нормальная к граничной грани, или (2) как полная спецификация потока на грани. Условие fipy по умолчанию - это первое (значение = 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] 

ответ

2

См. Обсуждение на fixed flux boundary conditions. В принципе, вы добавляете источник, содержащий расхождение желаемого граничного потока, к условию отсутствия потока FiPy по умолчанию.

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) не влияет на решение.

+0

Что делать, если вы хотите, чтобы одно граничное условие зависело от величины градиента другого и как таковое, только хотел установить нормальный компонент. Скажем, 'phi1.constrain (fp.numerix.dot (phi2.faceGrad, phi2.faceGrad))', где мы хотим указать только нормальный компонент 'phi2' на границе. Этот ответ означает, что это не сработает? (У меня нет хорошего примера, просто любопытно). Может быть, ответ @ jeguyer подходит в этом случае? – muon

+1

@muon; Я думаю, что метод ограничения терпит неудачу для большинства произвольных сложных взаимозависимых граничных условий и требуется метод источника-источника (ответ @jeguyer). – wd15

+0

Делает смысл. Благодаря! – muon

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()