FiPy:我可以根据相邻单元格直接更改 faceVariables 吗?
FiPy: Can I directly change faceVariables depending on neighboring cells?
我正在研究二维网格上微生物生物量 (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()
除了.arithmeticFaceValue
, FiPy provides other interpolators between cell and face values, such as .harmonicFaceValue
and .minmodFaceValue
。
这些属性是使用 _CellToFaceVariable
, specifically _ArithmeticCellToFaceVariable
, _HarmonicCellToFaceVariable
, and _MinmodCellToFaceVariable
.
的子类实现的
您还可以通过子类化 _CellToFaceVariable
来制作自定义插值器。两个这样的例子是 _LevelSetDiffusionVariable
and ScharfetterGummelFaceVariable
(恐怕都没有很好的记录)。
您需要覆盖 _calc_()
方法以提供您的自定义计算。此方法采用三个参数:
alpha
:一侧的人脸到单元格的距离相对于另一侧单元格到单元格的距离的比值(0-1)的数组第一面
id1
:面部一侧的单元格索引数组
id2
:脸另一侧的细胞索引数组
注意:可以忽略任何子句if inline.doInline:
,看else:
子句下定义的_calc_()
方法
我正在研究二维网格上微生物生物量 (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()
除了.arithmeticFaceValue
, FiPy provides other interpolators between cell and face values, such as .harmonicFaceValue
and .minmodFaceValue
。
这些属性是使用 _CellToFaceVariable
, specifically _ArithmeticCellToFaceVariable
, _HarmonicCellToFaceVariable
, and _MinmodCellToFaceVariable
.
您还可以通过子类化 _CellToFaceVariable
来制作自定义插值器。两个这样的例子是 _LevelSetDiffusionVariable
and ScharfetterGummelFaceVariable
(恐怕都没有很好的记录)。
您需要覆盖 _calc_()
方法以提供您的自定义计算。此方法采用三个参数:
alpha
:一侧的人脸到单元格的距离相对于另一侧单元格到单元格的距离的比值(0-1)的数组第一面id1
:面部一侧的单元格索引数组id2
:脸另一侧的细胞索引数组
注意:可以忽略任何子句if inline.doInline:
,看else:
子句下定义的_calc_()
方法