我正在尝试解决一个运输反应问题,但根据方法的不同,我有不同的解决方案。我认为,如果我试图求解耦合方程,问题就会出现。
以下是PDE:
我假设恒定的温度(方程式中的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的浓度问题。在一起求解方程时,我可以这样定义前面的元素吗?或者,如果我有这些项,逐个求解方程更好?
发布于 2021-02-23 15:38:12
Term
,它可能会因解决方案而改变,因此必须清除。var=?
在每个Term
在方程式中指定相同的变量,则方程式之间不存在耦合,因此使用&
符号。你只是使用了更多的内存,可能在解决三个独立的方程方面做得更差。var=?
在引入耦合的任务中,您通常会通过一开始不耦合来更容易地获得解决方案。耦合可以有助于收敛,但它经常对稳定性造成严重破坏。ImplicitSourceTerm
可以有助于收敛,但当您尝试求解一组方程时,通常只会使事情变得混乱。我会明确地写下这些源码,例如,- CBOD_reaction_coeff * C_CBOD * C_DO
直到你知道一切正常。描述了一个梯度约束,但是(mesh.facesTop * blahblah).divergence
强加边界流量..。对于您的方程式,通量为
..。你应该使用C_DO.faceGrad.constrain(...)
..。
https://stackoverflow.com/questions/66331362
复制