Я использую FiPy для решения проблемы, вызванной биологией.Решение PDE с источниками в Python
По существу, я хочу представить 2D-плоскость, где в разных точках у меня есть источники и раковины. Источники излучают субстрат с фиксированной скоростью (разные источники могут иметь разные скорости), а поглотители потребляют субстрат с фиксированной скоростью (разные раковины могут иметь разные скорости). Мой код:
import numpy.matlib
from fipy import CellVariable, Grid2D, Viewer, TransientTerm, DiffusionTerm, ImplicitSourceTerm, ExplicitDiffusionTerm
from fipy.tools import numerix
from time import *
nx = 10
ny = nx
dx = 1.
dy = dx
L = dx*nx
mesh = Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)
arr_grid = numerix.array((
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,),'d')
arr_source = numerix.array((
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0.5,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,),'d')
arr_sink = numerix.array((
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0.5,),'d')
source = CellVariable(mesh=mesh, value = arr_source)
sink = CellVariable(mesh=mesh, value = arr_sink)
phi = CellVariable(name = "solution variable", mesh = mesh, value = arr_grid)
X,Y = mesh.cellCenters
phi.setValue(3.0, where=(X < 2.0) & (X > 1.0))
phi.setValue(-1.0, where=(X < 6.0) & (X > 5.0))
D = 1.
eq = TransientTerm() == DiffusionTerm(coeff=D)
viewer = Viewer(vars=phi, datamin=0., datamax=1.)
steadyState = False
if(steadyState):
print("SteadyState")
DiffusionTerm().solve(var=phi)
viewer.plot()
sleep(20)
else:
print("ByStep")
timeStepDuration = 10 * 0.9 * dx**2/(2 * D)
steps = 500
for step in range(steps):
print(step)
eq.solve(var=phi,
dt=timeStepDuration)
if __name__ == '__main__':
viewer.plot()
Это хорошо работает, но FiPy рассматривает источники, как «невозобновляемые» и в конце концов я получить однородную концентрацию во всем пространстве, как можно было бы ожидать. Альтернативой было удалить:
X,Y = mesh.cellCenters
phi.setValue(3.0, where=(X < 2.0) & (X > 1.0))
phi.setValue(-1.0, where=(X < 6.0) & (X > 5.0))
И изменить уравнение для:
eq = TransientTerm() == DiffusionTerm(coeff=D) + source - sink
Учитывая, что источником и раковина никогда не изменяются эти предлагаемые «бесконечные» источники и поглотители. Однако, когда я пытаюсь решить для стационарного использования
eq = TransientTerm() == DiffusionTerm(coeff=D) + source - sink
я получаю:
C:\Python27\python.exe C:/Users/dario_000/PycharmProjects/mesa-test/mesher.py
SteadyState
C:\Python27\lib\site-packages\fipy-3.1.dev134+g64f7866-py2.7.egg\fipy\solvers\scipy\linearLUSolver.py:71: RuntimeWarning: invalid value encountered in double_scalars
if (numerix.sqrt(numerix.sum(errorVector**2))/error0) <= self.tolerance:
И уравнение не решается. Однако, если я решить «ступеньками», снова используя:
eq = TransientTerm() == DiffusionTerm(coeff=D) + source - sink
Я получаю хорошую картину, сходную с тем, что я бы ожидать:
Любые советы о том, как я могу указать начальная настройка с источниками/приемниками в разных пространственных положениях, каждая с различной частотой излучения/потребления, таким образом, что я могу получить стационарное решение?
Спасибо!
Этот вопрос дублируется в списке рассылки FiPy, где больше обсуждений, см. Http://thread.gmane.org/gmane.comp.python.fipy/4034. – wd15