Я работаю с fipy и хочу смоделировать поток со свободным потоком BC на некоторых выбранных гранях. После other examples, я пробовал 2 разные техники:
from fipy import *
from fipy.meshes.nonUniformGrid1D import NonUniformGrid1D as Grid1D
from fipy.tools import numerix as np
dx = [1., 1. , 0.78584047]
coeff = 2.
dt = min(0.1, 0.9 * min(dx) ** 2 / (2 * coeff))
steps = 10
mesh = Grid1D(nx = len(dx), dx = dx)
#phi values
phi = CellVariable(mesh = mesh, value=[10., 0., 0.], hasOld = True)
phi.constrain(0., mesh.facesRight) #dirichlet BC
phi2 = CellVariable(mesh = mesh, value=[10., 0., 0.], hasOld = True)
phi2.constrain(0., mesh.facesRight) #dirichlet BC
#outflow value
phi2Out = CellVariable(mesh = mesh, value=[0., 0., 0.], hasOld = True)
intCoef = FaceVariable(mesh, value=coeff)
extCoef = FaceVariable(mesh, value=coeff)
intCoef.constrain(0., where = mesh.facesRight)
extCoef.constrain(0., where = ~mesh.facesRight)
eq1= TransientTerm() == DiffusionTerm(coeff= intCoef * phi.faceValue) \
+ ImplicitSourceTerm(coeff= (extCoef * phi.faceGrad).divergence)
eq2 =TransientTerm() == DiffusionTerm(coeff= intCoef * phi2.faceValue) \
+ phi2 * (extCoef * phi2.faceGrad).divergence
eq3 =TransientTerm() == - phi2 * (extCoef * phi2.faceGrad).divergence
phi.updateOld()
phi2.updateOld()
phi2Out.updateOld()
for _ in range(steps):
res = 1e+10
loop = 0
while res > 1e-4 and loop < 1000:
res = eq1.sweep(var= phi,dt= dt)
res2 = eq2.sweep(var=phi2 ,dt= dt)
res3 = eq3.sweep(var=phi2Out ,dt= dt)
res = max(res, res2, res3)
loop += 1
if res > 1e-4:
print('no convergence! res: ', res)
break
phi.updateOld()
phi2.updateOld()
phi2Out.updateOld()
print('\nphi: ', phi * mesh.cellVolumes, sum(phi* mesh.cellVolumes))
print('phi2: ', phi2* mesh.cellVolumes,sum(phi2* mesh.cellVolumes))
print('phi2_outFlow: ', phi2Out* mesh.cellVolumes, sum(phi2Out* mesh.cellVolumes))
print('phi2_total: ', sum(phi2* mesh.cellVolumes + phi2Out* mesh.cellVolumes))
Вывод после 10 шагов:
фи: [2,21786728 1,82700906 0,63381385] 4,678690190704105
phi2: [2,21786872 1,82701185 0,6338187] 4,678699267591382
phi2_outFlow: [0. 0. 5,32132192] 5,321321918864122
phi2_total: 10.000021186455504
В идеале я хотел бы извлечь значение оттока, чтобы проверить баланс масс и узнать точное значение каждого члена для каждой ячейки (другие термины приемник / источник будут добавлены позже, а также другие границы свободного потока).
Мои вопросы:
- почему значения phi и phi2 немного отличаются?
- как я могу извлечь член оттока для каждой ячейки (когда будет использоваться более сложная сетка), сохранив при этом «ImplicitSourceTerm», что более эффективно?
Спасибо за помощь!
PS: До сих пор я работал с python3, поэтому, хотя меня интересуют решения с участием других решателей, я особенно ищу что-то, что можно реализовать с помощью scipy.