Это должно приблизить вас.Я поместил ваши уравнения в функцию, которую я использую в цикле for.Мне пришлось изменить некоторые ваши формулы, чтобы заставить его работать.Я ничего не знаю о гидрологии, но изменения имели смысл после взгляда на книгу, на которую вы ссылаетесь, и небольшую Википедию.Изменения также привели к получению данных, которые больше напоминают данные в таблице.Ищите #!!!!!!! <COMMENT> !!!!!!!#
, чтобы увидеть, что я изменил.
На пятой итерации / строке формула ftdt=ifelse(to==0, fl, f1*(time-to)+(f0-f1)/k*(1-exp(-k*(time-to))))
дает неверный результат, что приводит к ошибкам в других результатах.Я заменил f1
на fc
, потому что это имело смысл после прочтения соответствующих страниц книги, и результаты были ближе к тому, что вы хотите.Единственное, в чем я не уверен, это переменная времени t , которая в вашей формуле равна time - to
, т.е. время минус смещение времени.Я думаю, что это может быть проблемой.
compute_horton <- function (f, time, inc_rainfall, rainfall_int) {
#->->-> calculates runoff rainfall using the Horton infiltration equation
# constants
f0=6
f1=1
k=2
#fc
gfc = function(fc) {
f - ((f0 - fc) / k) + ((f1 / k) * log((fc - f1) / (f0 - f1)))
}
fc=uniroot(gfc, interval = c(f0, f1))
fc=fc$root
#F'
fl=if(fc>rainfall_int) sum(f,inc_rainfall) else 0
#fc'
gfcl = function(fcl) {
fl - ((f0 - fcl) / k) + ((f1 / k) * log((fcl - f1) / (f0 - f1)))
}
fcl=uniroot(gfcl, interval = c(f0, f1))
fcl=fcl$root
#Fp ou Fs
fporfs=ifelse(fc<rainfall_int,f,
ifelse(fcl<rainfall_int,
(f0-rainfall_int)/k-
f1/k*log((rainfall_int-f1)/(f0-f1)), 0))
#dt'
dtl=ifelse((fc>rainfall_int),
ifelse(fcl<rainfall_int,
(fporfs-f)/rainfall_int,0),0)
#ts
ts=ifelse(fc<rainfall_int,time,
ifelse(fcl<rainfall_int,dtl+time, 0))
#to
hto = function(to) {
fporfs-f1*(ts-to)-(f0-f1)/k*(1-exp(-k*(ts-to)))
}
to=uniroot(hto, interval = c(0, 1))
to=to$root
#Ft+Dt - This value will be the "f" on next row
#!!!!!!! I THINK YOU NEED FC AND NOT F1 !!!!!!!#
#!!!!!!! EVEN SO, FORMULA DOESN'T WORK QUITE RIGHT !!!!!!!#
#ftdt=ifelse(to==0, fl, f1*(time-to)+(f0-f1)/k*(1-exp(-k*(time-to))))
ftdt=ifelse(to==0, fl, fc*(time-to)+(f0-fc)/k*(1-exp(-k*(time-to))))
#Infiltration
#!!!!!!! I THINK InFILTRATION IS DIFFERENCE OF FTDT AND F !!!!!!!#
infiltr=ftdt-f
#Runoff in line 1
#!!!!!!! I THINK RUNOFF IS DIFFERENCE OF RAINFALL AND INFILTRATION !!!!!!!#
runoff1=round(inc_rainfall-infiltr, 3)
#Runoff in line 2 to n
#!!!!!!! THIS ISN'T USED ANYWHERE !!!!!!!#
runoffn=inc_rainfall-(ftdt[2]-ftdt[1])
#### OUTPUT ####
c(time, inc_rainfall, rainfall_int, f, fc, fl, fcl, fporfs, dtl, ts, to,
ftdt, infiltr, runoff1
)
}
# Function input
f=0
dt=0.25
time= seq(from=0, to=2, by=dt)
inc_rainfall=c(0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.4, 0.6, 0.6)
rainfall_int=inc_rainfall/dt
# Matrix column names
cnames <- c("Time", "Incremental Rainfall", "Rainfall Intensity", "F", "fc",
"Fl", "Fcl", "Fp or Fs", "dt", "ts", "to", "Ftdt", "Infiltration",
"Runoff"
)
# Initialize matrix and add column names
hort_mat <- matrix(0, nrow = length(inc_rainfall), ncol = length(cnames))
colnames(hort_mat) <- cnames
for (i in 1:nrow(hort_mat)) {
hort_mat[i,] <- compute_horton(f = hort_mat[ifelse(i-1 > 0, i-1, i), "Ftdt"],
time = time[i],
inc_rainfall = inc_rainfall[i],
rainfall_int = rainfall_int[i]
)
}