我使用R和deSolve包来解决一组微分方程。变量是WC和C(水含量和土壤层中的浓度)。土壤层数可以在代码中改变,如下所示:
numboxes <- 1 # Number of soil layers
delx <- rep(1,numboxes) # Thickness of soil layers (cm)
delt <- 1
bulk<-0.5;FC<-0.4;Ks<-0.03;Sat<-0.8;Wres<-0.1;kbio=0.01;kd=10 #parameters
## the model
SPEC <- function(t,state,parms) {
with(as.list(c(state,parms)),{
ifelse (WC>=Wres, perc <- (WC*delx*10*bulk-FC*delx*10*bulk)*(1-exp(
-Ks/(Sat*delx*10*bulk-FC*delx*10*bulk))), perc <-0)
#
dWC <- -diff(c(0,perc))*24/(10*delx*bulk)
dC <- -kbio*C
list(c(dWC,dC),perc=perc)
})
}
然后使用deSlove包解决该功能:
WC <-rep(0.5,times=numboxes)
C <- rep(20,times=numboxes)
state <- c(WC=WC,C=C)
times <- seq(from=1, to=5, by=delt)
out <- as.data.frame(ode(times=times,y=state,func=SPEC,parms=0,method="rk4"))
对于单个土壤层(numboxes = 1),一切正常,结果如下:
time WC C perc
1 1 0.5000000 20.00000 0.007444030
2 2 0.4699599 19.80100 0.005207836
3 3 0.4489439 19.60397 0.003643397
4 4 0.4342411 19.40891 0.002548917
5 5 0.4239550 19.21579 0.001783219
但是,当我增加土层数(例如,numboxes = 2)时,解算器会运行,但结果不正确。对于两层:
time WC1 WC2 C1 C2 perc1 perc2
1 1 0.5000000 0.5 20.0 20.0 0.00744403 0.00744403
2 2 0.4642687 0.5 19.8 19.8 0.00744403 0.00744403
3 3 0.4285373 0.5 19.6 19.6 0.00744403 0.00744403
4 4 0.3928060 0.5 19.4 19.4 0.00744403 0.00744403
5 5 0.3570746 0.5 19.2 19.2 0.00744403 0.00744403
两个土层(C1和C2)中的浓度结果是正确的,并且与单层的结果相同。 然而,计算出的水含量不正确(第一层的结果应与使用单层的模拟相同)。它接缝计算渗透(perc)求解器仅使用WC(0.5)的初始值,因此每次迭代计算相同的值(perc1和perc2总是等于0.007,这对于WC = 0.5是正确的)。 / p>
当我使用单层时,情况并非如此。此问题与此处报告的内容类似: Population values not updating in deSolve in R 但是,我在&#34; state = value&#34;中定义了初始值。方式,我仍然面临更新问题。我有什么想法可以解决这个问题,为什么我要面对这个?
答案 0 :(得分:0)
尝试将作业放在perc
之外的ifelse
。
perc <- ifelse(WC >= Wres,
(WC*delx*10*bulk - FC*delx*10*bulk)*
(1 - exp(-Ks/(Sat*delx*10*bulk - FC*delx*10*bulk))),
0)
我甚至不知道在ifelse
内做什么会做什么。
答案 1 :(得分:0)
你的问题是,你定义了你的状态变量是错误的。运行您的代码然后
state
你看,名字不是WC和C,而是WC1 WC2 C1和C2 你的微分方程只需要W和C作为状态变量。
state <- c(WC = 0.5, C = 20)
这会给出您的预期结果!
BTW:将所有参数放在矢量“parms”
中时更清楚parms <- c(
bulk = 0.5,
FC = 0.4,
Ks = 0.03,
Sat = 0.8,
Wres = 0.1,
kbio = 0.01,
kd = 10)
然后使用:
out <- as.data.frame(ode(times=times, y=state, func=SPEC, parms=parms, method="rk4"))
祝福, 约翰内斯