FiPy を使用して、生物学に触発された問題に対処しています。
基本的に、さまざまなポイントにソースとシンクがある 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
私が期待するものに似た素敵な写真が得られます:
定常状態の解を得ることができるように、それぞれ異なる排出/消費率を持つ異なる空間位置にあるソース/シンクで初期設定を指定する方法についてのアドバイスはありますか?
ありがとう!