## ----include = FALSE----------------------------------------------------------
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  echo = TRUE
)

## ----setup, include=FALSE,warning = FALSE-------------------------------------
library(knitr)
library(kableExtra)


## ----echo=FALSE---------------------------------------------------------------
data.frame(
  Variable = c("$Q$","$A$","$HLR$","$C_{in}$,$C_{out}$","$C^*$","$k$","$N$"),
  Definition = c("Flow","Area","Hydraulic Looading Rate $HLR = Q/A$",
                 "Inflow/Outflow Concentration","Background concentration",
                 "areal net settling (removal velocity)",
                 "Number of tanks in series"),
  Units = c(
    "$\\mathrm{m^{3}\\ y^{-1}}$",
    "$\\mathrm{m^{2}}$","$\\mathrm{m\\ y^{-1}}$",
    "$\\mathrm{mg\\ m^{-3}\\ or \\ \\mu g\\ L^{-1}}$",
    "$\\mathrm{mg\\ m^{-3}\\ or \\ \\mu g\\ L^{-1}}$",
    "$\\mathrm{m\\ y^{-1}}$","unitless"
  )
)|>
  kable(
  
  caption = "Model variables",
  align = "llc"
)|>
  kable_styling(
    full_width = FALSE
  )



## ----DMSTA plot, echo = FALSE,fig.width = 6.5,fig.height = 7,fig.align="center"----
oldpar <- par(no.readonly = TRUE)
par(mar = c(0.5,0.5,0.5,0.5))
layout(matrix(1:2,1,2),widths = c(0.2,1))
plot(0:1,0:1,type="n",ann=F,axes=F)
text(0.1, 0.95, "One CSTR at Steady-State", adj = c(0, 1),
     font = 3, cex = 1.1,xpd=NA)
text(0.1, 0.89, "Unit Area Storage & Fluxes", adj = c(0, 1),
     font = 3, cex = 0.9,xpd=NA)
text(0.1, 0.85, "Concs in mg/m3", adj = c(0, 1),
     font = 3, cex = 0.8,xpd=NA)
text(0.1, 0.82,  "Fluxes in mg/m2-yr", adj = c(0, 1),
     font = 3, cex = 0.8,xpd=NA)
text(0.1, 0.79, "Storage in mg/m2", adj = c(0, 1),
     font = 3, cex = 0.8,xpd=NA)

plot.new()
plot.window(xlim = c(0, 10), ylim = c(0, 9), asp = 1)
wc <- list(x1 = 3.2, x2 = 9.2, y1 = 6.1, y2 = 8.5)
rect(wc$x1, wc$y1, wc$x2, wc$y2, col = "#C8F7F7", border = "black", lwd = 1)

text((wc$x1+wc$x2)/2, 7.9, "Water Column", cex = 1.0, font = 2)
text((wc$x1+wc$x2)/2, 7.35, "Mass = M", cex = 0.95, font = 2)
text((wc$x1+wc$x2)/2, 6.85, "Conc = C = M / Z", cex = 0.95, font = 2)

# Biomass box
bio <- list(x1 = 3.2, x2 = 9.2, y1 = 2.2, y2 = 4.6)
rect(bio$x1, bio$y1, bio$x2, bio$y2, col = "#CFF7C8", border = "black", lwd = 1)

text((bio$x1+bio$x2)/2, 3.8, "Biomass P Storage", cex = 1.0, font = 2)
text((bio$x1+bio$x2)/2, 3.25, "S", cex = 1.0, font = 2)

# --- Arrows & labels ---
# Inflow L -> into water column (left)
arrows(1.4, 7.3, wc$x1, 7.3, length = 0.1, lwd = 1)
text(2.25, 7.55, "L", cex = 1.1, font = 2)

# Outflow Q C -> out of water column (right)
arrows(wc$x2, 7.3, 10.5, 7.3, length = 0.1, lwd = 1,xpd=NA)
text(10, 7.55, "Q C", cex = 1.0, font = 2)

# Downward arrow: water column -> biomass (uptake)
arrows(5.0, wc$y1, 5.0, bio$y2, length = 0.1, lwd = 1)
# Label left of the downward arrow: Fz K1 S C
text(3.05, 5.35, expression(F[z]~K[1]~S~C), adj = c(0, 0.5),
     cex = 0.95, font = 2)

# Upward arrow: biomass -> water column (recycle)
arrows(7.4, bio$y2, 7.4, wc$y1, length = 0.1, lwd = 1)
# Label to the right: K2 S^2
text(8.25, 5.35, expression(K[2]~S^2), adj = c(0, 0.5),
     cex = 0.95, font = 2)

# Downward arrow: biomass -> sink/burial (K3 S)
arrows((bio$x1+bio$x2)/2, bio$y1, (bio$x1+bio$x2)/2, 1.0, length = 0.1, lwd = 1)
text(7.0, 1.55, expression(K[3]~S), cex = 0.95, font = 2)

# Fz definition under the left flux label
text(0, 4.4, expression(F[z] == Min(1,~Z/Z[x])),
     adj = c(0, 0.5), cex = 0.95, font = 2)

par(oldpar)

## ----echo=FALSE---------------------------------------------------------------
params <- data.frame(
  Symbol = c("M", "S", "Z", "L", "Q", "K1", "K2", "K3"),
  Description = c(
    "Water column P storage",
    "Biomass P storage",
    "Mean water depth",
    "External P load",
    "Outflow rate",
    "Maximum uptake rate",
    "Recycle rate",
    "Burial rate"
  ),
  Units = c(
    "$\\mathrm{mg\\ m^{-2}}$", 
    "$\\mathrm{mg\\ m^{-2}}$",
    "$m$",
    "$\\mathrm{mg\\ m^{-2}\\ yr^{-1}}$",
    "$\\mathrm{m\\ yr^{-1}}$",
    "$\\mathrm{m^{3}\\ mg^{-1}\\ yr^{-1}}$",
    "$\\mathrm{m^{2}\\ mg^{-1}\\ yr^{-1}}$",
    "$\\mathrm{yr^{-1}}$"
  )
)

kable(
  params,
  caption = "DMSTA State Variables and Parameters",
  align = "lll"
)|>
  kable_styling(
    full_width = FALSE
  )|>
  pack_rows("State Variables",     start_row = 1, end_row = 3) |>
  pack_rows("Driving Variables",   start_row = 4, end_row = 5) |>
  pack_rows("Parameter Variables", start_row = 6, end_row = 8)


## ----echo=FALSE---------------------------------------------------------------

data.frame(Compartment = c("Storage:","Overall:", "Solution for C:","Solution for S:"),
           Equation = c(
             "$K1 \\cdot C = K2 \\cdot S + K3$",
             "$L - Q \\cdot C = K3 \\cdot S$",
             "$C = \\frac{(K2 \\cdot L + K3^{2})}{K3 \\cdot K1 + Q \\cdot K2}$",
             "$S = \\frac{(K1 \\cdot C - K3)}{K2}$")
           )|>
  kable(
    caption = "Steady-State Mass Balances 1 CSTR &  Fz = 1",
  align = "lc"
  )|>
  kable_styling(
    full_width = FALSE
  )



## ----DMSTA plot2, echo = FALSE,out.width = "50%",fig.align="center"-----------
oldpar <- par(no.readonly = TRUE)
par(mar=c(0,0,0,0),oma = c(0.1,0.1,0.1,0.1))
plot.new()
plot(0:1,0:1,xlim = c(0, 1), ylim = c(0,1), ann=F,axes=F,type="n")
wc <- list(x1 = 0.2, x2 = 0.8, y1 = 0.4, y2 = 0.8)
rect(wc$x1, wc$y1, wc$x2, wc$y2, col = "#C8F7F7", border = "black", lwd = 1)

text(wc$x1+(wc$x2-wc$x1)/2,
     wc$y1+(wc$y2-wc$y1)/2,
     "C", cex = 0.95, font = 2)
a1 <- list(x0 = 0, y0=wc$y1+(wc$y2-wc$y1)/2,
           x1 = wc$x1, y1 = wc$y1+(wc$y2-wc$y1)/2)
with(a1,arrows(x0,y0, x1,y1, length = 0.1, lwd = 1))
text(a1$x0+(a1$x1-a1$x0)/2, a1$y0, "L", cex = 1, font = 2,pos=3,offset = 0.25)

a2 <- list(x0 =  wc$x2, y0 = wc$y1+(wc$y2-wc$y1)/2,
           x1 = 1, y1 = wc$y1+(wc$y2-wc$y1)/2)
with(a2,arrows(x0,y0, x1,y1, length = 0.1, lwd = 1))
text(a2$x0+(a2$x1-a2$x0)/2, a2$y0, "Q C", cex = 1.0, font = 2,pos=3,offset = 0.25)

a3 <- list(x0 = wc$x1+(wc$x2-wc$x1)/2,y0 = wc$y1,
           x1 = wc$x1+(wc$x2-wc$x1)/2, y1 = wc$y1*0.75)
with(a3,arrows(x0,y0, x1,y1, length = 0.1, lwd = 1))
text(a3$x0, a3$y1, "K (C - C0)", cex = 1, font = 2,pos=1,offset = 0.25)
par(oldpar)

## -----------------------------------------------------------------------------
# Forward NKC* (tanks-in-series) prediction
nkc_out <- function(Cin, k, HLR, N = 1, Cstar) {
  Cstar + (Cin - Cstar) / (1 + k / (N * HLR))^N
}

# Solve for HLR given target Cout
nkc_hlr <- function(Cin, Cout, k, N = 1, Cstar) {
  r <- (Cin - Cstar) / (Cout - Cstar)
  (k / N) / (r^(1/N) - 1)
}

# Solve for k given observed Cin/Cout and HLR
nkc_k <- function(Cin, Cout, HLR, N = 1, Cstar) {
  if (any(Cout <= Cstar))
    stop("Cout must be greater than Cstar")
  
  r <- (Cin - Cstar) / (Cout - Cstar)
  N * HLR * (r^(1/N) - 1)
}

# DMSTA parameter translations 
dmsta_KC_to_K123 <- function(K, C0, C1) {
  K3 <- K * (C1 - C0) / 1000
  K1 <- K3 / C0
  K2 <- K3 * K1 / K
  list(K1 = K1, K2 = K2, K3 = K3)
}

dmsta_K123_to_KC <- function(K1, K2, K3) {
  C0 <- K3 / K1
  K  <- (K1 * K3) / K2
  C1 <- (1000 * K2 + K3) / K1
  list(K = K, C0 = C0, C1 = C1)
}

# Estimate k from plug and flow
estimate_k_plug <- function(
  Cin, Cout,
  HLR,
  Cstar
) {
  if (any(Cout <= Cstar))
    stop("Cout must be greater than Cstar")

  HLR * log( (Cin - Cstar) / (Cout - Cstar) )
}


## ----include = FALSE,eval = FALSE---------------------------------------------
# ## Estimate k from CSTR
# estimate_k_CSTR <- function(
#   Cin, Cout,
#   HLR,
#   N = 1,
#   Cstar
# ) {
#   if (any(Cout <= Cstar))
#     stop("Cout must be greater than Cstar")
# 
#   N * HLR * (( (Cin - Cstar) / (Cout - Cstar) )^(1/N) - 1)
# }
# 

## -----------------------------------------------------------------------------
## Example Data
Cin <-  122
Cout <- 17
k  <-  66.5
HLR <- 9.5
Cstar <- 2

K <- 16.8
C0 <- 2
C1 <- 22

K1 <- 0.168
K2 <- 0.00336
K3 <- 0.336

# Estimated Cout given Cin, k, & HLR
nkc_out(Cin, k, HLR, N = 1, Cstar)

# Estimated HLR given Cin, Cout & k
nkc_hlr(Cin,Cout,k,N = 1,Cstar)

# vs more tanks
nkc_hlr(Cin,Cout,k,N = 3,Cstar)

## Estimate k 
nkc_k(Cin,Cout,HLR,1,Cstar)

# estimate model parameters
dmsta_KC_to_K123(K,C0,C1)

dmsta_K123_to_KC(K1,K2,K3)

