我正在研究二维网格上微生物生物量(b1)分布的生物学模型。从生物量中产生一种蛋白质(p1)。生物质能在网格上扩散,而蛋白质则不扩散。只有当产生一定量的蛋白质(p > p_lim)时,生物量才会扩散。我试图通过使用一个虚拟单元变量z与扩散系数相乘来实现这一点,并且只在p> p_lim的单元格中将其设置为0到1。
条件很好,当在单元中达到p的临界量时,z被设置为1,然后发生扩散。然而,扩散仍然不能与我想要的速度工作,因为在计算扩散时,使用的是面变量,而不是单元本身的值。Z的面始终是带有z=1的单元格的平均值,而它的相邻的单元是z=0的均衡器。然而,我希望扩散以原来的速度工作,即使相邻的细胞仍在p< p_lim。
所以,我的问题是:我可以以某种方式访问faceVariable并更改它吗?例如,如果任何相邻的单元格已到达p1 > p_lim,则将其设置为1?我想这不是一个合适的数学问题,但我想不出另一种方法来模拟这个问题。
下面我将展示我的模型的一个非常简化的形式。无论如何,我非常感谢您的时间!
##### produce mesh
nx= 5.
ny= nx
dx = 1.
dy = dx
L = nx*dx
mesh = Grid2D(nx=nx,ny=ny,dx=dx,dy=dy)
#parameters
h1 = 0.5 # production rate of p
Db = 10. # diffusion coeff of b
p_lim=0.1
# cell variables
z = CellVariable(name="z",mesh=mesh,value=0.)
b1 = CellVariable(name="b1",mesh=mesh,hasOld=True,value=0.)
p1= CellVariable(name="p1",mesh=mesh,hasOld=True,value=0.)
# equations
eqb1 = (TransientTerm(var=b1)== DiffusionTerm(var=b1,coeff=Db*z.arithmeticFaceValue)-ImplicitSourceTerm(var=b1,coeff=h1))
eqp1 = (TransientTerm(var=p1)==ImplicitSourceTerm(var=b1,coeff=h1))
# set b1 to 10. in the center of the grid
b1.setValue(10.,where=((x>2.)&(x<3.)&(y>2.)&(y<3.)))
vi=Viewer(vars=(b1,p1),FIPY_VIEWER="matplotlib")
eq = eqb1 & eqp1
from builtins import range
for t in range(10):
b1.updateOld()
p1.updateOld()
z.setValue(z + 0.1,where=((p1>=p_lim) & (z < 1.)))
eq.solve(dt=0.1)
vi.plot()发布于 2020-11-23 01:34:50
除了.arithmeticFaceValue之外,FiPy还在单元格和面值之间提供了其他插值器,例如.harmonicFaceValue和.minmodFaceValue。
这些属性是使用_CellToFaceVariable的子类(特别是_ArithmeticCellToFaceVariable、_HarmonicCellToFaceVariable和_MinmodCellToFaceVariable )实现的。
您还可以通过子类_CellToFaceVariable创建自定义内插器。两个这样的例子是_LevelSetDiffusionVariable和ScharfetterGummelFaceVariable (恐怕这两个例子都没有很好的文档)。
您需要重写_calc_()方法以提供自定义计算。这个方法有三个参数:
alpha::脸到一侧细胞距离的比值(0-1)的数组,相对于从另一侧的单元到第一sideid1:上的单元格的距离,faceid2:一边的单元格的一组指数和脸另一侧的单元格的指数数组。
注意:--您可以忽略任何if inline.doInline:子句,并查看在else:子句下定义的_calc_()方法。
https://stackoverflow.com/questions/64956464
复制相似问题