【问题标题】:FiPy Transport-reaction with one term depending on two variables on two different equations一项取决于两个不同方程的两个变量的 FiPy 传输反应
【发布时间】:2021-02-24 20:49:34
【问题描述】:

我正在尝试解决传输反应问题,但我有不同的解决方案,具体取决于方法。我认为如果我试图解决耦合方程,就会出现问题。

这些是偏微分方程:

我假设温度恒定(方程式中的 T)以及恒定速度场(vx,vy)。

如您所见,反应项中有一个元素取决于两个变量,并且存在于两个不同的变量中(CBOD 的降解取决于氧 CDO 的浓度,而氧的浓度取决于CBOD 降解量)。

这是我的代码:

# Geometry
Lx = 2  # meters
Ly = 2  # meters
nx = 41 # nodes
ny = 41 # nodes

# Build the mesh:
mesh = Grid2D(Lx=Lx, Ly = Ly, nx=nx, ny=ny)
X,Y = mesh.cellCenters


# Main variable and initial conditions

#Velocity field (constant):
Vf = CellVariable(name='velocity_field',
                 mesh = mesh,
                 value = [vx, vy])

# Dissolved oxygen concentration:
C_DO = CellVariable(name="concentration_DO", 
                 mesh=mesh, 
                 value=0.,
                 hasOld=True)
C_DO.setValue(9.5, where=(Y >= Ly - 0.5))
C_DO.setValue(9.25, where=(Y < Ly - 0.5) & (Y >= Ly - 1.0))
C_DO.setValue(8.9, where=(Y < Ly - 1.0) & (Y >= Ly - 1.5) )
C_DO.setValue(8.8, where=(Y < Ly - 1.5) & (Y >= Ly - 2.0))

# Biochemical Oxygen Demand by Carbonaceous Organic Matter
C_CBOD = CellVariable(name="concentration_CBOD", 
                 mesh=mesh, 
                 value=10.,
                 hasOld=True)

# Biochemical Oxygen Demand by Nitrogenous Organic Matter
C_NBOD = CellVariable(name="concentration_NBOD", 
                 mesh=mesh, 
                 value=10.,
                 hasOld=True)

# Temperature (constant)
T = CellVariable(name="temperature", 
                 mesh=mesh,
                 value=14.4,
                 hasOld=True)


# Transport parameters
D_DO = FaceVariable(name='DO_diff', mesh=mesh, value=1.)
D_DO.constrain(0., mesh.exteriorFaces)

D_CBOD = 1.
D_NBOD = 1.


## Reaction & source terms

# DO
O_r = 1.025
K_r = 1.

# CBOD:
O_CBOD = 1.047
K_CBOD_0 = 0.2
K_CBOD = K_CBOD_0 / DOsat
CBOD_reaction_coeff = K_CBOD * (O_CBOD ** (T - 20))

# NBOD:
O_NBOD = 1.047
K_NBOD_0 = 0.2
K_NBOD = K_NBOD_0 / DOsat
NBOD_reaction_coeff = K_NBOD * (O_NBOD ** (T - 20))

# Boundary conditions
### fixed flux, atmospheric exchange, included in the main equation.

# Equations definition:

# DO transport-reaction
eqDO = (TransientTerm(var = C_DO) == 
        DiffusionTerm(coeff=D_DO, var = C_DO) 
        - ConvectionTerm(coeff=Vf, var=C_DO)
        + ImplicitSourceTerm(coeff= -1 * CBOD_reaction_coeff * C_CBOD, var=C_DO) 
        + ImplicitSourceTerm(coeff= -1 * NBOD_reaction_coeff * C_NBOD, var=C_DO) 
        + (mesh.facesTop * (K_r * (O_r ** (T.faceValue - 20)) * ((14.652 - 0.41022 * T.faceValue + 0.007991 * T.faceValue ** 2 - 0.000077774 * T.faceValue ** 3) - C_DO.faceValue))).divergence))
    
# CBOD transport-reaction
eqCBOD = (TransientTerm(var = C_CBOD) == 
          DiffusionTerm(coeff=D_CBOD, var = C_CBOD) 
          - ConvectionTerm(coeff=Vf, var=C_CBOD) 
          + ImplicitSourceTerm(coeff= -1 * CBOD_reaction_coeff * C_DO, var=C_CBOD))

# NBOD transport-reaction
eqNBOD = (TransientTerm(var = C_NBOD) == 
          DiffusionTerm(coeff=D_NBOD, var = C_NBOD) 
          - ConvectionTerm(coeff=Vf, var=C_NBOD) 
          + ImplicitSourceTerm(coeff= -1 * NBOD_reaction_coeff * C_DO, var=C_NBOD))

eqQ = eqDO & eqCBOD & eqNBOD

# PDESolver hyperparameters
steps = 230 
dt = 1e-2

for step in range(steps):
  C_DO.updateOld()
  C_CBOD.updateOld()
  C_NBOD.updateOld()

  eqQ.solve(dt=dt)

取决于我是分别求解三个方程(eqDO.solve(dt=dt)、eqCBOD.solve(dt=dt)、eqNBOD.solve(dt=dt)),还是耦合在一个系统中(eqQ.solve (dt=dt)),我得到不同的结果(网格中的分布相同,但值不同)。我不知道我是否可以在两个不同的方程中使用具有不同变量的这个术语;例如:

eqDO = ... + ImplicitSourceTerm(coeff= -1 * CBOD_reaction_coeff * C_CBOD, var=C_DO) <--- Is this OK?
eqCBOD = ... + ImplicitSourceTerm(coeff= -1 * CBOD_reaction_coeff * C_DO, var=C_CBOD) <--- Is this OK?

我想一起求解浓度 CBOD、NBOD 和 DO。一起求解方程时,我可以这样定义前面的元素吗?或者,如果我有这些条件,是否更好地解决方程?

【问题讨论】:

    标签: fipy


    【解决方案1】:
    • 如果反应项在它们各自的控制方程之间完全相同,则守恒性质可能会更好,但如果你扫描(你应该这样做),它可能并不重要。
    • 您需要sweep。方程之间存在非线性依赖关系。无论您是作为耦合系统求解还是连续求解方程都没有关系。任何显示为Term 的系数(可能会因解而改变)都必须扫除。
    • 当方程中的每个Term 中的每个var=? 指定相同的变量时,方程之间就没有耦合,因此使用&amp; 表示法没有意义。您只是使用更多的内存来解决三个独立的方程可能会做得更差。
    • 即使您调整了一些var=? 分配以引入耦合,通常一开始不耦合,您会更容易获得解决方案。耦合可以帮助收敛,但通常会对稳定性造成严重破坏。
    • 同样,明智地使用ImplicitSourceTerm 可以帮助收敛,但当您尝试求解一组方程时,往往只会使事情变得混乱。我会明确写出这些来源,例如 - CBOD_reaction_coeff * C_CBOD * C_DO,直到您知道一切正常为止。
    • 描述了对 gradient 的约束,但 (mesh.facesTop * blahblah).divergence 强加了边界 flux。对于您的方程式,通量为。你应该使用C_DO.faceGrad.constrain(...)

    【讨论】:

    • 非常感谢您的回答。我真的很感激您花时间回答我们的问题!这就是我所做的:* 我现在正在扫地。 *目前,我已经明确编写了源代码,并且我一一解决了方程式(我还不需要太多的准确性)。 * 至于边界条件,你是对的:我实现的是固定通量而不是固定梯度(这是我的问题所需要的;换句话说,图像中的 BC 对于氧气来说是错误的交换),顺便说一句,代码中有错误(应该写在括号之间而不是方括号之间)。
    • @ToniP 我很乐意提供帮助。如果此答案解决了您的问题,请accept it。如果这些方程式出现其他问题,请随时提出新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    相关资源
    最近更新 更多