#' Scorch height using an isotherm, including target species
#'
#' Calculates the height to which vegetation will be consumed,
#' and the height to a designated temperature isotherm reached for one second.
#'
#' Output fields are:
#' Height - overall scorch height (m)
#' ns, e, m, c - height of consumption in each stratum (m)
#' b1, b2, b3, b4 - percentage of strata 1 (ns) to strata 4 (c) consumed
#' sc1, sc2, sc3, sc4 - percentage of strata 1 (ns) to strata 4 (c) scorched
#' d1, d2, d3, d4 - death (1) or survival (0) of standing foliage per stratum (50% or more scorch)
#'
#' @param Surf The dataframe produced by the function 'summary',
#' @param Plant The dataframe produced by the function 'repFlame'.
#' @param Param A parameter dataframe used for FRaME,
#' such as produced using readLegacyParamFile
#' @param Test The temperature of the flora, default 70 degC
#' @param targSp Name of species to be watched for scorch
#'
#' @return dataframe
#' @export
floraTarget <- function(Surf, Plant, Param = Param, targSp = "a", Test = 70)
{
S <- strata(Param)
n <- max(S$stratum)
#Max burn height
c <- Plant[Plant$level == "Canopy", ]%>%
group_by(repId) %>%
summarise(across(where(is.numeric), ~ max(.x, na.rm = TRUE)))%>%
mutate(c = y1)%>%
select(repId, c)%>%
right_join(Surf)
c[is.na(c)] <- 0
m <- Plant[Plant$level == "MidStorey", ]%>%
group_by(repId) %>%
summarise(across(where(is.numeric), ~ max(.x, na.rm = TRUE)))%>%
mutate(m = y1)%>%
select(repId, m)%>%
right_join(c)%>%
mutate(m = ifelse(c>0, S$top[3], m))
m[is.na(m)] <- 0
e <- Plant[Plant$level == "Elevated", ]%>%
group_by(repId) %>%
summarise(across(where(is.numeric), ~ max(.x, na.rm = TRUE)))%>%
mutate(e = y1)%>%
select(repId, e)%>%
right_join(m)%>%
mutate(e = ifelse(m>0, S$top[2], e))
e[is.na(e)] <- 0
ns <- Plant[Plant$level == "NearSurface", ]%>%
group_by(repId) %>%
summarise(across(where(is.numeric), ~ max(.x, na.rm = TRUE)))%>%
mutate(ns = y1)%>%
select(repId, ns)%>%
right_join(e)%>%
mutate(ns = ifelse(e>0, S$top[1], ns))
ns[is.na(ns)] <- 0
#Heating from surface fire
ground <- ns%>%
mutate(Alpha = 1/(2*lengthSurface^2),
C = 950*lengthSurface*exp(-Alpha*lengthSurface^2),
pAlpha = abs(C/(Test-temperature)),
R = pAlpha*cos(angleSurface),
El = R * tan((slope_degrees * pi)/180),
ht = (sin(angleSurface)*pAlpha - El) * extinct,
ns = ns * extinct,
e = e * extinct,
m = m * extinct,
c = c * extinct
)%>%
select(repId, extinct, temperature, slope_degrees, wind_kph, ht, ns, e, m, c)
#Heating from plants
plant<-Plant%>%
left_join(ground)%>%
mutate(Angle = atan((y1-y0)/(x1-x0)),
Alpha = 1/(2*flameLength*(flameLength-length)),
C = 950*flameLength*exp(-Alpha*(flameLength-length)^2),
pAlpha = abs(C/(Test-temperature)),
Reach = pAlpha*cos(Angle),
El = Reach * tan((slope_degrees * pi)/180),
htP = (sin(Angle)*pAlpha + y0 - El) * extinct)%>%
select(repId, htP)%>%
group_by(repId) %>%
summarise(across(where(is.numeric), ~ max(.x, na.rm = TRUE)))%>%
right_join(ground)
plant[is.na(plant)] <- 0
#Find the corresponding number of each stratum
NS <- S[S$name == "near surface", ]
nNS <-ifelse(count(NS)==0, 0,as.numeric(as.character(NS$stratum)))
E <- S[S$name == "elevated", ]
nE <- ifelse(count(E)==0, 0,as.numeric(as.character(E$stratum)))
M <- S[S$name == "midstorey", ]
nM <-ifelse(count(M)==0, 0,as.numeric(as.character(M$stratum)))
C <- S[S$name == "canopy", ]
nC <- ifelse(count(C)==0, 0,as.numeric(as.character(C$stratum)))
nSp <- targSp %in% unique(Param$value[which(Param$param=="name")])
#Final heating
Iso <- plant%>%
mutate(Height = pmax(ht, htP),
nsBase = ifelse(count(NS)==0, 0, S$base[which(S$name == "near surface")]),
eBase = ifelse(count(E)==0, 0, S$base[which(S$name == "elevated")]),
mBase = ifelse(count(M)==0, 0, S$base[which(S$name == "midstorey")]),
cBase = ifelse(count(C)==0, 0, S$base[which(S$name == "canopy")]),
nsTop = ifelse(count(NS)==0, 0, S$top[which(S$name == "near surface")]),
eTop = ifelse(count(E)==0, 0, S$top[which(S$name == "elevated")]),
mTop = ifelse(count(M)==0, 0, S$top[which(S$name == "midstorey")]),
cTop = ifelse(count(C)==0, 0, S$top[which(S$name == "canopy")]),
spBase = ifelse(nSp, as.numeric(filter(Param, species==targSp & param == "hc")$value), 0),
spTop = ifelse(nSp, as.numeric(filter(Param, species==targSp & param == "hp")$value), 0),
#Calculate scorch and burn
b1 = ifelse(nsTop == 0, 0, round(pmin(100,pmax(0,100*(ns-nsBase)/(nsTop-nsBase))),0)),
b2 = ifelse(eTop == 0, 0, round(pmin(100,pmax(0,100*(e-eBase)/(eTop-eBase))),0)),
b3 = ifelse(mTop == 0, 0, round(pmin(100,pmax(0,100*(m-mBase)/(mTop-mBase))),0)),
b4 = ifelse(cTop == 0, 0, round(pmin(100,pmax(0,100*(c-cBase)/(cTop-cBase))),0)),
sc1 = ifelse(nsTop == 0, 0, round(pmin(100,pmax(0,100*(Height-nsBase)/(nsTop-nsBase))),0)),
sc2 = ifelse(eTop == 0, 0, round(pmin(100,pmax(0,100*(Height-eBase)/(eTop-eBase))),0)),
sc3 = ifelse(mTop == 0, 0, round(pmin(100,pmax(0,100*(Height-mBase)/(mTop-mBase))),0)),
sc4 = ifelse(cTop == 0, 0, round(pmin(100,pmax(0,100*(Height-cBase)/(cTop-cBase))),0)),
severity = case_when(b4 > 50 ~ 5,
b4 > 0 ~ 4,
sc4 > 0 ~ 3,
b1+b2 > 50 ~ 2,
b1+b2 > 0 ~ 1,
TRUE ~ 0),
targSp = ifelse(spTop == 0, 0, round(pmin(100,pmax(0,100*(Height-spBase)/(spTop-spBase))),0)))%>%
select(repId, wind_kph, Height, ns, e, m, c, b1, b2, b3, b4, sc1, sc2, sc3, sc4, severity, targSp)
return(Iso)
}
#' Scorch height using an isotherm
#'
#' Calculates the height to which vegetation will be consumed,
#' and the height to a designated temperature isotherm reached for one second.
#'
#' Output fields are:
#' Height - overall scorch height (m)
#' ns, e, m, c - height of consumption in each stratum (m)
#' b1, b2, b3, b4 - percentage of strata 1 (ns) to strata 4 (c) consumed
#' sc1, sc2, sc3, sc4 - percentage of strata 1 (ns) to strata 4 (c) scorched
#' d1, d2, d3, d4 - death (1) or survival (0) of standing foliage per stratum (50% or more scorch)
#'
#' @param Surf The dataframe produced by the function 'summary',
#' @param Plant The dataframe produced by the function 'repFlame'.
#' @param Param A parameter dataframe used for FRaME,
#' such as produced using readLegacyParamFile
#' @param Test The temperature of the flora, default 70 degC
#'
#' @return dataframe
#' @export
flora <- function(Surf, Plant, Param = Param, Test = 70)
{
S <- strata(Param)
n <- max(S$stratum)
#Max burn height
c <- Plant[Plant$level == "Canopy", ]%>%
group_by(repId) %>%
summarise(across(where(is.numeric), ~ max(.x, na.rm = TRUE)))%>%
mutate(c = y1)%>%
select(repId, c)%>%
right_join(Surf)
c[is.na(c)] <- 0
m <- Plant[Plant$level == "MidStorey", ]%>%
group_by(repId) %>%
summarise(across(where(is.numeric), ~ max(.x, na.rm = TRUE)))%>%
mutate(m = y1)%>%
select(repId, m)%>%
right_join(c)%>%
mutate(m = ifelse(c>0, S$top[3], m))
m[is.na(m)] <- 0
e <- Plant[Plant$level == "Elevated", ]%>%
group_by(repId) %>%
summarise(across(where(is.numeric), ~ max(.x, na.rm = TRUE)))%>%
mutate(e = y1)%>%
select(repId, e)%>%
right_join(m)%>%
mutate(e = ifelse(m>0, S$top[2], e))
e[is.na(e)] <- 0
ns <- Plant[Plant$level == "NearSurface", ]%>%
group_by(repId) %>%
summarise(across(where(is.numeric), ~ max(.x, na.rm = TRUE)))%>%
mutate(ns = y1)%>%
select(repId, ns)%>%
right_join(e)%>%
mutate(ns = ifelse(e>0, S$top[1], ns))
ns[is.na(ns)] <- 0
#Heating from surface fire
ground <- ns%>%
mutate(Alpha = 1/(2*lengthSurface^2),
C = 950*lengthSurface*exp(-Alpha*lengthSurface^2),
pAlpha = abs(C/(Test-temperature)),
R = pAlpha*cos(angleSurface),
El = R * tan((slope_degrees * pi)/180),
ht = (sin(angleSurface)*pAlpha - El) * extinct,
ns = ns * extinct,
e = e * extinct,
m = m * extinct,
c = c * extinct
)%>%
select(repId, extinct, temperature, slope_degrees, wind_kph, ht, ns, e, m, c)
#Heating from plants
plant<-Plant%>%
left_join(ground)%>%
mutate(Angle = atan((y1-y0)/(x1-x0)),
Alpha = 1/(2*flameLength*(flameLength-length)),
C = 950*flameLength*exp(-Alpha*(flameLength-length)^2),
pAlpha = abs(C/(Test-temperature)),
Reach = pAlpha*cos(Angle),
El = Reach * tan((slope_degrees * pi)/180),
htP = (sin(Angle)*pAlpha + y0 - El) * extinct)%>%
select(repId, htP)%>%
group_by(repId) %>%
summarise(across(where(is.numeric), ~ max(.x, na.rm = TRUE)))%>%
right_join(ground)
plant[is.na(plant)] <- 0
#Find the corresponding number of each stratum
NS <- S[S$name == "near surface", ]
nNS <-ifelse(count(NS)==0, 0,as.numeric(as.character(NS$stratum)))
E <- S[S$name == "elevated", ]
nE <- ifelse(count(E)==0, 0,as.numeric(as.character(E$stratum)))
M <- S[S$name == "midstorey", ]
nM <-ifelse(count(M)==0, 0,as.numeric(as.character(M$stratum)))
C <- S[S$name == "canopy", ]
nC <- ifelse(count(C)==0, 0,as.numeric(as.character(C$stratum)))
#Final heating
Iso <- plant%>%
mutate(Height = pmax(ht, htP),
nsBase = if(count(NS)==0){0} else {S$base[which(S$name == "near surface")]},
eBase = if(count(E)==0) {0} else {S$base[which(S$name == "elevated")]},
mBase = if(count(M)==0) {0} else {S$base[which(S$name == "midstorey")]},
cBase = if(count(C)==0) {0} else {S$base[which(S$name == "canopy")]},
nsTop = if(count(NS)==0) {0} else {S$top[which(S$name == "near surface")]},
eTop = if(count(E)==0) {0} else {S$top[which(S$name == "elevated")]},
mTop = if(count(M)==0) {0} else {S$top[which(S$name == "midstorey")]},
cTop = if(count(C)==0) {0} else {S$top[which(S$name == "canopy")]},
#Calculate scorch and burn
b1 = ifelse(nsTop == 0, 0, round(pmin(100,pmax(0,100*(ns-nsBase)/(nsTop-nsBase))),0)),
b2 = ifelse(eTop == 0, 0, round(pmin(100,pmax(0,100*(e-eBase)/(eTop-eBase))),0)),
b3 = ifelse(mTop == 0, 0, round(pmin(100,pmax(0,100*(m-mBase)/(mTop-mBase))),0)),
b4 = ifelse(cTop == 0, 0, round(pmin(100,pmax(0,100*(c-cBase)/(cTop-cBase))),0)),
sc1 = ifelse(nsTop == 0, 0, round(pmin(100,pmax(0,100*(Height-nsBase)/(nsTop-nsBase))),0)),
sc2 = ifelse(eTop == 0, 0, round(pmin(100,pmax(0,100*(Height-eBase)/(eTop-eBase))),0)),
sc3 = ifelse(mTop == 0, 0, round(pmin(100,pmax(0,100*(Height-mBase)/(mTop-mBase))),0)),
sc4 = ifelse(cTop == 0, 0, round(pmin(100,pmax(0,100*(Height-cBase)/(cTop-cBase))),0)),
severity = case_when(b4 > 50 ~ 5,
b4 > 0 ~ 4,
sc4 > 0 ~ 3,
b1+b2 > 50 ~ 2,
b1+b2 > 0 ~ 1,
TRUE ~ 0))%>%
select(repId, wind_kph, Height, ns, e, m, c, b1, b2, b3, b4, sc1, sc2, sc3, sc4, severity)
return(Iso)
}
#####################################################################
#' Finds radial bole necrosis depth
#'
#' Depth to which the cambium of a tree recieves lethal heating
#'
#' Utilises the output tables from 'threat' and 'radiation', and adds to these
#' the Reynolds Number, heat transfer coefficients, Newton's convective energy transfer coefficient,
#' and the temperature of the object each second.
#'
#' Reynolds Number utilises a standard formulation (e.g. Gordon, N. T., McMahon, T. A. & Finlayson, B. L.
#' Stream hydrology: an introduction for ecologists. (Wiley, 1992))
#'
#' Convective heat transfer coefficients use the widely adopted formulations of
#' Williams, F. A. Urban and wildland fire phenomenology. Prog. Energy Combust. Sci. 8, 317–354 (1982),
#' and Drysdale, D. An introduction to fire dynamics. (John Wiley and Sons, 1985)
#' utilising a Prandtl number of 0.7.
#'
#' Heat is transferred into the bark and timber using Fourier's Law
#'
#' Thermal conductivity of bark is modelled as per Martin, R. E.
#' Thermal properties of bark. For. Prod. J. 13, 419–426 (1963)
#'
#' Specific heat of bark is modelled using Kain, G., Barbu, M. C., Hinterreiter, S., Richter, K. & Petutschnigg, A.
#' Using bark as a heat insulation material. BioResources 8, 3718–3731 (2013)
#'
#' Thermal conductivity of wood is modelled using an approach from Kollmann, F. F. P. & Cote, W. A.
#' Principles of wood science and technology I. Solid wood. (Springer-Verlag, 1968)
#'
#' Evaporates water at 100 degrees C
#'
#' Specific heat of wood is derived from an established empirical relationship in Volbehr, B.
#' Swelling of wood fiber. PhD Thesis. (University of Kiel, 1896)
#'
#' Continues heating of the bole in the wake of the front for the duration of the surface fire for a period determined using
#' Burrows, N. D. Flame residence times and rates of weight loss of eucalypt forest fuel particles.
#' Int. J. Wildl. Fire 10, 137–143 (2001). Flame lengths are decreased exponentially over this period
#'
#' Bark is assumed to ignite, and burn for an average of resBark seconds, with the default value of 45s used as a mean for
#' figure 6c in Penman, T. D., Cawson, J. G., Murphy, S. & Duff, T. J.
#' Messmate Stringybark: bark ignitability and burning sustainability in relation to fragment dimensions,
#' hazard and time since fire. Int. J. Wildl. Fire 26, 866–876 (2017).
#'
#' Heats an area of 0.01m2
#'
#'
#'
#' @param Surf The dataframe produced by the function 'summary',
#' @param Plant The dataframe produced by the function 'repFlame'.
#' @param percentile defines which heating statistics are used for each second, from 0 (min) to 1 (max)
#' @param Height The height on the bole directly over ground (m)
#' @param woodDensity The density of wood in the tree or log housing the hollow (kg/m3)
#' @param barkDensity The density of bark in the tree or log housing the hollow (kg/m3)
#' @param comBark Temperature directly under the burning bark (C)
#' @param bark The thickness of bark on the thinnest side of the hollow (m)
#' @param resBark Flame residence in the tree bark (s)
#' @param phloem Thickness of the tree phloem (depth to cambium, m)
#' @param RH The relative humidity (0-1)
#' @param moisture The proportion oven-dry weight of moisture in the wood
#' @param bMoisture The proportion oven-dry weight of moisture in the bark
#' @param distance The furthest horizontal distance between the flame origin and the point (m)
#' @param trail The number of seconds to continue modelling after all flames have extinguished
#' @param var The angle in degrees that the plume spreads above/below a central vector
#' @param diameter depth of the litter layer (mm)
#' @param Pressure Sea level atmospheric pressure (hPa)
#' @param Altitude Height above sea level (m)
#' @param startTemp The starting temperature of wood and bark (deg C)
#' @param necT Temperature of necrosis (deg C)
#' @param surfDecl adjusts the rate at which surface flame length declines after the front
#' @param updateProgress Progress bar for use in the dashboard
#'
#' @return dataframe
#' @export
cambium <- function(Surf, Plant, percentile = 0.95, Height = 0.1, woodDensity = 700, barkDensity = 500,
bark = 0.04, comBark = 700, resBark = 45, phloem = 0.01, RH = 0.2,
moisture = 1, bMoisture = 0.2, distance = 50, trail = 100, var = 10, diameter = 20, Pressure = 1013.25,
Altitude = 0, startTemp = 25, necT = 60, surfDecl = 10,updateProgress=NULL)
{
# Post-front surface flame heating
lengthSurface <- mean(Surf$lengthSurface)
residence <- 0.871*diameter^1.875
depth <- diameter/1000
# Collect step distance, time, and total distance
ROS <- mean(Surf$ros_kph)/3.6
Ta <- round(distance/ROS+residence)
Tb <- round(distance/ROS)
TIME <- Ta + trail
Horiz <- distance
# Description of the protection
# Convert units from kg/m^3 to kg
massB <- 0.01 * bark * barkDensity
massW <- 0.0001 * woodDensity
R <- sqrt(0.01/pi)
startM <- moisture
barkTemp <- startTemp
woodTemp <- startTemp
#Starting values
Ca <- threat(Surf, Plant, Horiz, Height, var, Pressure, Altitude)%>%
mutate(t = 1,
#Convective transfer
Re = (Plume_velocity*Density)/viscosity,
h = 0.35 + 0.47*Re^(1/2)*0.837,
#Incoming heat from surface
pt = pmax(0, t-Tb),
comBark = ifelse(pt <= resBark, comBark, 0),
postS = bole(lengthSurface,residence, depth, h = Height,
surfDecl = 10, t = pt),
tempS = ifelse(Horiz <=0, pmax(tempAir, postS, comBark), tempAir),
qc = h * (tempS - barkTemp),
att = tau(D=Horiz, flameTemp=flameTemp, temperature=(temperature+273.15), rh=RH),
qr = 0.86*qr*att,
Qi = pmax(0, qc)+qr,
#BARK________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWater = bMoisture*massB,
# Energy removed by current water quantity
drain = ifelse(barkTemp>95,
ifelse(bMoisture>0,mWater*2256400,0),0),
# Adjusted incoming energy
QiA = max(Qi-drain,0),
#Bark thermal values
rhoM = (bMoisture+bMoisture^2)*barkDensity,
cpBark = ((1105+4.85*barkTemp)*(1-bMoisture)+bMoisture*4185+1276*bMoisture)/1000,
kBark = (2.104*barkDensity+5.544*rhoM+3.266*barkTemp-166.216)*10^-4,
# Fourier conduction
fourierA = ifelse(Horiz>0, pmin(QiA,(kBark * pmax(0,tempS - barkTemp)) / bark),
(kBark * pmax(0,tempS - barkTemp)) / bark),
barkTemp = pmax(barkTemp, (0.001 * fourierA / (massB * cpBark) + barkTemp)),
# Change in proportion water this step
moistureA = ifelse(bMoisture>0,max(0,bMoisture-((fourierA/2256400)/mWater)),
bMoisture),
#1ST CM________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water (kg)
mWater = moisture*massW,
# Energy removed by current water quantity
drain = ifelse(woodTemp>95,
ifelse(moisture>0,mWater*2256400,0),0),
# Adjusted incoming energy
QiB = max(fourierA-drain,0),
#Thermal values
kAir = 0.00028683*(woodTemp+273.15)^0.7919,
cpWoodB = 1.08+0.00408*(100*moisture)+0.00253*woodTemp+0.0000628*(100*moisture)*woodTemp,
kWoodB = kWood(woodTemp, woodDensity, kAir),
# Fourier conduction
fourierB = pmin(QiB,(kWoodB * pmax(0,barkTemp - woodTemp)) / 0.01),
woodTempB = pmax(woodTemp, (0.001 * fourierB / (massW * cpWoodB) + woodTemp)),
# Change in proportion water this step
moistureB = ifelse(moisture>0,max(0,moisture-((fourierB/2256400)/mWater)),
moisture),
# Heat draw-down from above
barkTemp = pmax(barkTemp, barkTemp + (0.001 * fourierB / (massB * cpBark))),
#2ND CM________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWater = moisture*massW,
# Energy removed by current water quantity
drain = ifelse(woodTemp>95,
ifelse(moisture>0,mWater*2256400,0),0),
# Adjusted incoming energy
QiC = max(fourierB-drain,0),
#Thermal values
kAir = 0.00028683*(woodTemp+273.15)^0.7919,
cpWoodC = 1.08+0.00408*(100*moisture)+0.00253*woodTemp+0.0000628*(100*moisture)*woodTemp,
kWoodC = kWood(woodTemp, woodDensity, kAir),
# Fourier conduction
fourierC = pmin(QiC,(kWoodC * pmax(0,woodTempB - woodTemp)) / 0.01),
woodTempC = pmax(woodTemp, (0.001 * fourierC / (massW * cpWoodC) + woodTemp)),
# Change in proportion water this step
moistureC = ifelse(moisture>0,max(0,moisture-((fourierC/2256400)/mWater)),
moisture),
# Heat draw-down from above
woodTempB = pmax(woodTempB, woodTempB + (0.001 * fourierC / (massW * cpWoodB))),
#3RD CM________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWater = moisture*massW,
# Energy removed by current water quantity
drain = ifelse(woodTemp>95,
ifelse(moisture>0,mWater*2256400,0),0),
# Adjusted incoming energy
QiD = max(fourierC-drain,0),
#Thermal values
kAir = 0.00028683*(woodTemp+273.15)^0.7919,
cpWoodD = 1.08+0.00408*(100*moisture)+0.00253*woodTemp+0.0000628*(100*moisture)*woodTemp,
kWoodD = kWood(woodTemp, woodDensity, kAir),
# Fourier conduction
fourierD = pmin(QiD,(kWoodD * pmax(0,woodTempC - woodTemp)) / 0.01),
woodTempD = pmax(woodTemp, (0.001 * fourierD / (massW * cpWoodD) + woodTemp)),
# Change in proportion water this step
moistureD = ifelse(moisture>0,max(0,moisture-((fourierD/2256400)/mWater)),
moisture),
# Heat draw-down from above
woodTempC = pmax(woodTempC, woodTempC + (0.001 * fourierD / (massW * cpWoodC))),
#4TH CM________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWater = moisture*massW,
# Energy removed by current water quantity
drain = ifelse(woodTemp>95,
ifelse(moisture>0,mWater*2256400,0),0),
# Adjusted incoming energy
QiE = max(fourierD-drain,0),
#Thermal values
kAir = 0.00028683*(woodTemp+273.15)^0.7919,
cpWoodE = 1.08+0.00408*(100*moisture)+0.00253*woodTemp+0.0000628*(100*moisture)*woodTemp,
kWoodE = kWood(woodTemp, woodDensity, kAir),
# Fourier conduction
fourierE = pmin(QiE,(kWoodE * pmax(0,woodTempD - woodTemp)) / 0.01),
woodTempE = pmax(woodTemp, (0.001 * fourierE / (massW * cpWoodE) + woodTemp)),
# Change in proportion water this step
moistureE = ifelse(moisture>0,max(0,moisture-((fourierE/2256400)/mWater)),
moisture),
# Heat draw-down from above
woodTempD = pmax(woodTempD, woodTempD + (0.001 * fourierE / (massW * cpWoodD))),
#Outgoing BARK________________________________________________________
fourierOA = pmin(0,(kBark * (tempS - barkTemp)) / bark),
barkTemp = pmin(barkTemp, barkTemp + (0.001 * fourierOA / (massB * cpBark))),
qrO = pmin(0,0.86*0.0000000000567*((tempS+273.15)^4 - (barkTemp+273.15)^4)),
qR = qr + qrO,
Q = qc + qR,
#Outgoing 1ST________________________________________________________
fourierOB = pmin(0,(kWoodB * (barkTemp - woodTempB)) / 0.01),
woodTempB = pmin(woodTempB, woodTempB + (0.001 * fourierOB / (massW * cpWoodB))),
#Outgoing 2ND________________________________________________________
fourierOC = pmin(0,(kWoodC * (woodTempB - woodTempC)) / 0.01),
woodTempC = pmin(woodTempC, woodTempC + (0.001 * fourierOC / (massW * cpWoodC))),
#Outgoing 3RD________________________________________________________
fourierOD = pmin(0,(kWoodD * (woodTempC - woodTempD)) / 0.01),
woodTempD = pmin(woodTempD, woodTempD + (0.001 * fourierOD / (massW * cpWoodD))),
#Outgoing 4TH________________________________________________________
fourierOE = pmin(0,(kWoodE * (woodTempD - woodTempE)) / 0.01),
woodTempE = pmin(woodTempE, woodTempE + (0.001 * fourierOE / (massW * cpWoodE))))
barkTemp <- quantile(Ca$barkTemp, percentile)
moistureA <- quantile(Ca$moistureA, percentile)
woodTempB <- quantile(Ca$woodTempB, percentile)
moistureB <- quantile(Ca$moistureB, percentile)
woodTempC <- quantile(Ca$woodTempC, percentile)
moistureC <- quantile(Ca$moistureC, percentile)
woodTempD <- quantile(Ca$woodTempD, percentile)
moistureD <- quantile(Ca$moistureD, percentile)
woodTempE <- quantile(Ca$woodTempE, percentile)
moistureE <- quantile(Ca$moistureE, percentile)
# Advance one second's travel
Horiz = Horiz - ROS
pbar <- txtProgressBar(max = TIME, style = 3)
# Loop through each time step and collect outputs
for(t in 2:TIME){
Cb <-threat(Surf, Plant, Horiz, Height, var, Pressure, Altitude) %>%
mutate(t = t,
#Convective transfer
Re = (Plume_velocity*Density)/viscosity,
h = 0.35 + 0.47*Re^(1/2)*0.837,
#Incoming heat from surface
pt = pmax(0, t-Tb),
comBark = ifelse(pt <= resBark, comBark, 0),
postS = bole(lengthSurface,residence, depth, h = Height,
surfDecl = 10, t = pt),
tempS = ifelse(t>Ta, tempAir, ifelse(Horiz <=0, pmax(tempAir, postS, comBark), tempAir)),
qc = h * (tempS - barkTemp),
att = tau(D=Horiz, flameTemp=flameTemp, temperature=(temperature+273.15), rh=RH),
qr = 0.86*qr*att,
Qi = pmax(0, qc)+qr,
#BARK________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWater = moistureA*massB,
# Energy removed by current water quantity
drain = ifelse(barkTemp>95,
ifelse(moistureA>0,mWater*2256400,0),0),
# Adjusted incoming energy
QiA = max(Qi-drain,0),
#Bark thermal values
rhoM = (moistureA+moistureA^2)*barkDensity,
cpBark = ((1105+4.85*barkTemp)*(1-moistureA)+moistureA*4185+1276*moistureA)/1000,
kBark = (2.104*barkDensity+5.544*rhoM+3.266*barkTemp-166.216)*10^-4,
# Fourier conduction
fourierA = ifelse(Horiz>0, pmin(QiA,(kBark * pmax(0,tempS - barkTemp)) / bark),
(kBark * pmax(0,tempS - barkTemp)) / bark),
barkTemp = pmax(barkTemp, (0.001 * fourierA / (massB * cpBark) + barkTemp)),
# Change in proportion water this step
moistureA = ifelse(moistureA>0,max(0,moistureA-((fourierA/2256400)/mWater)),
moistureA),
#1ST CM________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWater = moistureB*massW,
# Energy removed by current water quantity
drain = ifelse(woodTempB>95,
ifelse(moistureB>0,mWater*2256400,0),0),
# Adjusted incoming energy
QiB = max(fourierA-drain,0),
#Thermal values
kAir = 0.00028683*(woodTempB+273.15)^0.7919,
cpWoodB = 1.08+0.00408*(100*moistureB)+0.00253*woodTempB+0.0000628*(100*moistureB)*woodTempB,
kWoodB = kWood(woodTempB, woodDensity, kAir),
# Fourier conduction
fourierB = pmin(QiB,(kWoodB * pmax(0,barkTemp - woodTempB)) / 0.01),
woodTempB = pmax(woodTempB, (0.001 * fourierB / (massW * cpWoodB) + woodTempB)),
# Change in proportion water this step
moistureB = ifelse(moistureB>0,max(0,moistureB-((fourierB/2256400)/mWater)),
moistureB),
# Heat draw-down from above
barkTemp = pmin(barkTemp, barkTemp - (0.001 * fourierB / (massB * cpBark))),
#2ND CM________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWater = moistureC*massW,
# Energy removed by current water quantity
drain = ifelse(woodTempC>95,
ifelse(moistureC>0,mWater*2256400,0),0),
# Adjusted incoming energy
QiC = max(fourierB-drain,0),
#Thermal values
kAir = 0.00028683*(woodTempC+273.15)^0.7919,
cpWoodC = 1.08+0.00408*(100*moistureC)+0.00253*woodTempC+0.0000628*(100*moistureC)*woodTempC,
kWoodC = kWood(woodTempC, woodDensity, kAir),
# Fourier conduction
fourierC = pmin(QiC,(kWoodC * pmax(0,woodTempB - woodTempC)) / 0.01),
woodTempC = pmax(woodTempC, (0.001 * fourierC / (massW * cpWoodC) + woodTempC)),
# Change in proportion water this step
moistureC = ifelse(moistureC>0,max(0,moistureC-((fourierC/2256400)/mWater)),
moistureC),
# Heat draw-down from above
woodTempB = pmin(woodTempB, woodTempB - (0.001 * fourierC / (massW * cpWoodB))),
#3RD CM________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWater = moistureD*massW,
# Energy removed by current water quantity
drain = ifelse(woodTempD>95,
ifelse(moistureD>0,mWater*2256400,0),0),
# Adjusted incoming energy
QiD = max(fourierC-drain,0),
#Thermal values
kAir = 0.00028683*(woodTempD+273.15)^0.7919,
cpWoodD = 1.08+0.00408*(100*moistureD)+0.00253*woodTempD+0.0000628*(100*moistureD)*woodTempD,
kWoodD = kWood(woodTempD, woodDensity, kAir),
# Fourier conduction
fourierD = pmin(QiD,(kWoodD * pmax(0,woodTempC - woodTempD)) / 0.01),
woodTempD = pmax(woodTempD, (0.001 * fourierD / (massW * cpWoodD) + woodTempD)),
# Change in proportion water this step
moistureD = ifelse(moistureD>0,max(0,moistureD-((fourierD/2256400)/mWater)),
moistureD),
# Heat draw-down from above
woodTempC = pmin(woodTempC, woodTempC - (0.001 * fourierD / (massW * cpWoodC))),
#4TH CM________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWater = moistureE*massW,
# Energy removed by current water quantity
drain = ifelse(woodTempE>95,
ifelse(moistureE>0,mWater*2256400,0),0),
# Adjusted incoming energy
QiE = max(fourierD-drain,0),
#Thermal values
kAir = 0.00028683*(woodTempE+273.15)^0.7919,
cpWoodE = 1.08+0.00408*(100*moistureE)+0.00253*woodTempE+0.0000628*(100*moistureE)*woodTempE,
kWoodE = kWood(woodTempE, woodDensity, kAir),
# Fourier conduction
fourierE = pmin(QiE,(kWoodE * pmax(0,woodTempD - woodTempE)) / 0.01),
woodTempE = pmax(woodTempE, (0.001 * fourierE / (massW * cpWoodE) + woodTempE)),
# Change in proportion water this step
moistureE = ifelse(moistureE>0,max(0,moistureE-((fourierE/2256400)/mWater)),
moistureE),
# Heat draw-down from above
woodTempD = pmin(woodTempD, woodTempD - (0.001 * fourierE / (massW * cpWoodD))),
#Outgoing 1st________________________________________________________
fourierOA = pmin(0,(kBark * (tempS - barkTemp)) / bark),
barkTemp = pmin(barkTemp, barkTemp + (0.001 * fourierOA / (massB * cpBark))),
qrO = pmin(0,0.86*0.0000000000567*((tempS+273.15)^4 - (barkTemp+273.15)^4)),
qR = qr + qrO,
Q = qc + qR,
#Outgoing 1ST________________________________________________________
fourierOB = pmin(0,(kWoodB * (barkTemp - woodTempB)) / 0.01),
woodTempB = pmin(woodTempB, woodTempB + (0.001 * fourierOB / (massW * cpWoodB))),
#Outgoing 2ND________________________________________________________
fourierOC = pmin(0,(kWoodC * (woodTempB - woodTempC)) / 0.01),
woodTempC = pmin(woodTempC, woodTempC + (0.001 * fourierOC / (massW * cpWoodC))),
#Outgoing 3RD________________________________________________________
fourierOD = pmin(0,(kWoodD * (woodTempC - woodTempD)) / 0.01),
woodTempD = pmin(woodTempD, woodTempD + (0.001 * fourierOD / (massW * cpWoodD))),
#Outgoing 4TH________________________________________________________
fourierOE = pmin(0,(kWoodE * (woodTempC - woodTempE)) / 0.01),
woodTempE = pmin(woodTempE, woodTempD + (0.001 * fourierOE / (massW * cpWoodE))))
Ca <- rbind(Ca, Cb)
barkTemp <- quantile(Cb$barkTemp, percentile)
moistureA <- quantile(Cb$moistureA, percentile)
woodTempB <- quantile(Cb$woodTempB, percentile)
moistureB <- quantile(Cb$moistureB, percentile)
woodTempC <- quantile(Cb$woodTempC, percentile)
moistureC <- quantile(Cb$moistureC, percentile)
woodTempD <- quantile(Cb$woodTempD, percentile)
moistureD <- quantile(Cb$moistureD, percentile)
woodTempE <- quantile(Cb$woodTempE, percentile)
moistureE <- quantile(Cb$moistureE, percentile)
setTxtProgressBar(pbar,t)
## progress bar
Sys.sleep(0.25)
####UpdateProgress
if (is.function(updateProgress)) {
text <- paste0("Number of remaining steps is ", TIME - t)
updateProgress(detail = text)
}
t = t + 1
Horiz = Horiz - ROS
}
# Create table
Ca <- Ca %>%
select(t, repId, tempS, barkTemp, woodTempB, woodTempC, woodTempD, woodTempE,
moistureA, moistureB, moistureC, moistureD, moistureE)%>%
mutate(necrosis = ifelse(woodTempE>=necT, 4,
ifelse(woodTempD>=necT, 3,
ifelse(woodTempC>=necT, 2,
ifelse(woodTempB>=necT, 1, 0)))),
girdling = ifelse(necrosis>=phloem, 1, 0))
return(Ca)
}
#########################################################################
#' Finds radial bole necrosis depth, dividing bark into four steps
#'
#' Depth to which the stem of a plant recieves lethal heating
#'
#' Utilises the output tables from 'threat' and 'radiation', and adds to these
#' the Reynolds Number, heat transfer coefficients, Newton's convective energy transfer coefficient,
#' and the temperature of the object each second.
#'
#' Reynolds Number utilises a standard formulation (e.g. Gordon, N. T., McMahon, T. A. & Finlayson, B. L.
#' Stream hydrology: an introduction for ecologists. (Wiley, 1992))
#'
#' Convective heat transfer coefficients use the widely adopted formulations of
#' Williams, F. A. Urban and wildland fire phenomenology. Prog. Energy Combust. Sci. 8, 317–354 (1982),
#' and Drysdale, D. An introduction to fire dynamics. (John Wiley and Sons, 1985)
#' utilising a Prandtl number of 0.7.
#'
#' Heat is transferred into the bark and timber using Fourier's Law
#'
#' Thermal conductivity of bark is modelled as per Martin, R. E.
#' Thermal properties of bark. For. Prod. J. 13, 419–426 (1963)
#'
#' Specific heat of bark is modelled using Kain, G., Barbu, M. C., Hinterreiter, S., Richter, K. & Petutschnigg, A.
#' Using bark as a heat insulation material. BioResources 8, 3718–3731 (2013)
#'
#' Thermal conductivity of wood is modelled using an approach from Kollmann, F. F. P. & Cote, W. A.
#' Principles of wood science and technology I. Solid wood. (Springer-Verlag, 1968)
#'
#' Evaporates water at 100 degrees C
#'
#' Specific heat of wood is derived from an established empirical relationship in Volbehr, B.
#' Swelling of wood fiber. PhD Thesis. (University of Kiel, 1896)
#'
#' Continues heating of the bole in the wake of the front for the duration of the surface fire for a period determined using
#' Burrows, N. D. Flame residence times and rates of weight loss of eucalypt forest fuel particles.
#' Int. J. Wildl. Fire 10, 137–143 (2001). Flame lengths are decreased exponentially over this period
#'
#' Bark is assumed to ignite, and burn for an average of resBark seconds, with the default value of 45s used as a mean for
#' figure 6c in Penman, T. D., Cawson, J. G., Murphy, S. & Duff, T. J.
#' Messmate Stringybark: bark ignitability and burning sustainability in relation to fragment dimensions,
#' hazard and time since fire. Int. J. Wildl. Fire 26, 866–876 (2017).
#'
#' Heats an area of 0.01m2
#'
#'
#'
#' @param Surf The dataframe produced by the function 'summary',
#' @param Plant The dataframe produced by the function 'repFlame'
#' @param Height The height on the bole directly over ground (m)
#' @param woodDensity The density of wood in the plant or log housing the hollow (kg/m3)
#' @param barkDensity The density of bark in the plant or log housing the hollow (kg/m3)
#' @param comBark Temperature directly under the burning bark (C)
#' @param bark The thickness of bark on the thinnest side of the hollow (m)
#' @param resBark Flame residence in the plant bark (s)
#' @param phloem Thickness of the plant phloem (depth to cambium, m)
#' @param RH The relative humidity (0-1)
#' @param moisture The proportion oven-dry weight of moisture in the wood
#' @param bMoisture The proportion oven-dry weight of moisture in the bark
#' @param distance The furthest horizontal distance between the flame origin and the point (m)
#' @param trail The number of seconds to continue modelling after all flames have extinguished
#' @param var The angle in degrees that the plume spreads above/below a central vector
#' @param diameter depth of the litter layer (mm)
#' @param Pressure Sea level atmospheric pressure (hPa)
#' @param Altitude Height above sea level (m)
#' @param startTemp The starting temperature of wood and bark (deg C)
#' @param necT Temperature of necrosis (deg C)
#' @param surfDecl adusts the rate at which surface flame length declines after the front
#' @param updateProgress Progress bar for use in the dashboard
#'
#' @return dataframe
#' @export
#'
girdle <- function(Surf, Plant, Height = 0.1, woodDensity = 700, barkDensity = 500,
bark = 0.04, comBark = 700, resBark = 45, phloem = 0.01, RH = 0.2,
moisture = 0.6, bMoisture = 0.5, distance = 5, trail = 100, var = 10,
diameter = 20, Pressure = 1013.25,Altitude = 0, startTemp = 25,
necT = 60, surfDecl = 10,updateProgress=NULL)
{
# Post-front surface flame heating
lengthSurface <- mean(Surf$lengthSurface)
residence <- 0.871*diameter^1.875
depth <- diameter/1000
# Collect step distance, time, and total distance
ROS <- mean(Surf$ros_kph)/3.6
Ta <- round(distance/ROS+residence)
Tb <- round(distance/ROS)
TIME <- Ta + trail
Horiz <- distance
# Description of the protection
step <- bark/4
# Convert units from kg/m^3 to kg
mass <- step * barkDensity
massW <- phloem * woodDensity
R <- sqrt(0.01/pi)
startM <- moisture
#Starting values
Ca <- threat(Surf, Plant, Horiz, Height, var, Pressure, Altitude) %>%
summarise_all(mean)%>%
mutate(t = 1,
#Convective transfer
Re = (Plume_velocity*Density)/viscosity,
h = 0.35 + 0.47*Re^(1/2)*0.837,
#Incoming heat from surface
pt = pmax(0, t-Tb),
comBark = ifelse(pt <= resBark, comBark, 0),
postS = bole(lengthSurface,residence, depth, h = Height,
surfDecl = 10, t = pt),
tempS = ifelse(Horiz <=0, pmax(tempAir, postS, comBark), tempAir),
qc = h * (tempS - startTemp),
att = tau(D=Horiz, flameTemp=flameTemp, temperature=(temperature+273.15), rh=RH),
qr = 0.86*qr*att,
Qi = pmax(0, qc)+qr,
#STEP A ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterA = bMoisture*mass,
# Energy removed by current water quantity
drainA = ifelse(startTemp>99,
ifelse(bMoisture>0,mWaterA*2256400,0),0),
#Thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (bMoisture+bMoisture^2)*barkDensity,
cpA = ((1105+4.85*startTemp)*(1-bMoisture)+bMoisture*4185+1276*bMoisture),
kA = (2.104*barkDensity+5.544*rhoM+3.266*startTemp-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fAD = ((kA * (tempS - startTemp)) / step),
fAU = 0,
fourierA = fAD + fAU - max(0, min((fAD + fAU), drainA)),
tempA = (fourierA / (mass * cpA) + startTemp),
# Change in proportion water this step
moistureA = ifelse(startTemp>99,ifelse(bMoisture>0,max(0,bMoisture-((Qi/2256400)/mWaterA)),
bMoisture),bMoisture),
#STEP B ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water (kg)
mWaterB = bMoisture*mass,
# Energy removed by current water quantity
drainB = ifelse(startTemp>99,
ifelse(moisture>0,mWaterB*2256400,0),0),
#Thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (bMoisture+bMoisture^2)*barkDensity,
cpB = ((1105+4.85*startTemp)*(1-bMoisture)+bMoisture*4185+1276*bMoisture),
kB = (2.104*barkDensity+5.544*rhoM+3.266*startTemp-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fBD = ((kB * (tempA - startTemp)) / step),
fBU = 0,
fourierB = fBD + fBU - max(0, min((fBD + fBU), drainB)),
tempB = (fourierB / (mass * cpB) + startTemp),
# Change in proportion water this step
moistureB = ifelse(startTemp>99,ifelse(bMoisture>0,max(0,bMoisture-((fourierA/2256400)/mWaterB)),
bMoisture), bMoisture),
#STEP C ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterC = bMoisture*mass,
# Energy removed by current water quantity
drainC = ifelse(startTemp>99,
ifelse(moisture>0,mWaterC*2256400,0),0),
#Thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (bMoisture+bMoisture^2)*barkDensity,
cpC = ((1105+4.85*startTemp)*(1-bMoisture)+bMoisture*4185+1276*bMoisture),
kC = (2.104*barkDensity+5.544*rhoM+3.266*startTemp-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fCD = ((kC * (tempB - startTemp)) / step),
fCU = 0,
fourierC = fCD + fCU - max(0, min((fCD + fCU), drainC)),
tempC = (fourierC / (mass * cpC) + startTemp),
# Change in proportion water this step
moistureC = ifelse(startTemp>99,ifelse(bMoisture>0,max(0,bMoisture-((fourierB/2256400)/mWaterC)),
bMoisture),bMoisture),
#STEP D ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterD = bMoisture*mass,
# Energy removed by current water quantity
drainD = ifelse(startTemp>99,
ifelse(moisture>0,mWaterD*2256400,0),0),
#Thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (bMoisture+bMoisture^2)*barkDensity,
cpD = ((1105+4.85*startTemp)*(1-bMoisture)+bMoisture*4185+1276*bMoisture),
kD = (2.104*barkDensity+5.544*rhoM+3.266*startTemp-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fDD = ((kD * (tempC - startTemp)) / step),
fDU = 0,
fourierD = fDD + fDU - max(0, min((fDD + fDU), drainD)),
tempD = (fourierD / (mass * cpD) + startTemp),
# Change in proportion water this step
moistureD = ifelse(startTemp>99,ifelse(bMoisture>0,max(0,bMoisture-((fourierC/2256400)/mWaterD)),
bMoisture),bMoisture),
#Phloem ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterE = moisture*massW,
# Energy removed by current water quantity
drainE = ifelse(startTemp>99,
ifelse(moisture>0,mWaterE*2256400,0),0),
#Thermal values - (cp: J/g/deg, k: W/m/deg)
kAir = 0.00028683*(startTemp+273.15)^0.7919,
cpE = 1080+408*moisture+2.53*startTemp+6.28*moisture*startTemp,
kE = kWood(startTemp, woodDensity, kAir),
# Conduction from above and below, less latent heat of evaporation
fED = ((kE * (tempD - startTemp)) / step),
fEU = 0,
fourierE = fED + fEU - max(0, min((fED + fEU), drainE)),
tempE = (fourierE / (massW * cpE) + startTemp),
# Change in proportion water this step
moistureE = ifelse(startTemp>99,ifelse(moisture>0,max(0,moisture-((fourierD/2256400)/mWaterE)),
moisture),moisture))
#Collect values for the next step
tempA <- Ca$tempA
moistureA <- Ca$moistureA
kA <- Ca$kA
tempB <- Ca$tempB
moistureB <- Ca$moistureB
kB <- Ca$kB
tempC <- Ca$tempC
moistureC <- Ca$moistureC
kC <- Ca$kC
tempD <- Ca$tempD
moistureD <- Ca$moistureD
kD <- Ca$kD
tempE <- Ca$tempE
moistureE <- Ca$moistureE
kE <- Ca$kE
# Advance one second's travel
Horiz <- Horiz - ROS
pbar <- txtProgressBar(max = TIME, style = 3)
# Loop through each time step and collect outputs
for(t in 2:TIME){
Cb <-threat(Surf, Plant, Horiz, Height, var, Pressure, Altitude) %>%
summarise_all(mean)%>%
mutate(t = t,
#Convective transfer
Re = (Plume_velocity*Density)/viscosity,
h = 0.35 + 0.47*Re^(1/2)*0.837,
#Incoming heat from surface
pt = pmax(0, t-Tb),
comBark = ifelse(pt <= resBark, comBark, 0),
postS = bole(lengthSurface,residence, depth, h = Height,
surfDecl = 10, t = pt),
tempS = ifelse(t>Ta, tempAir, ifelse(Horiz <=0, pmax(tempAir, postS, comBark), tempAir)),
qc = h * (tempS - tempA),
att = tau(D=Horiz, flameTemp=flameTemp, temperature=(temperature+273.15), rh=RH),
qr = 0.86*qr*att,
Qi = pmax(0, qc)+qr,
#STEP A ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterA = moistureA*mass,
# Energy removed by current water quantity
drainA = ifelse(tempA>99,
ifelse(moistureA>0,mWaterA*2256400,0),0),
#Bark thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (moistureA+moistureA^2)*barkDensity,
cpA = ((1105+4.85*tempA)*(1-moistureA)+moistureA*4185+1276*moistureA),
kA = (2.104*barkDensity+5.544*rhoM+3.266*tempA-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fAD = ((kA * (tempS - tempA)) / step),
fAU = ((kB * (tempB - tempA)) / step),
fourierA = fAD + fAU - max(0, min((fAD + fAU), drainA)),
tempA = (fourierA / (mass * cpA) + tempA),
# Change in proportion water this step
moistureA = ifelse(tempA>99,ifelse(moistureA>0,max(0,moistureA-((Qi/2256400)/mWaterA)),
moistureA),moistureA),
#STEP B ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterB = moistureB*mass,
# Energy removed by current water quantity
drainB = ifelse(tempB>99,
ifelse(moistureB>0,mWaterB*2256400,0),0),
#Thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (moistureB+moistureB^2)*barkDensity,
cpB = ((1105+4.85*tempB)*(1-moistureB)+moistureB*4185+1276*moistureB),
kB = (2.104*barkDensity+5.544*rhoM+3.266*tempB-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fBD = ((kB * (tempA - tempB)) / step),
fBU = ((kC * (tempC - tempB)) / step),
fourierB = fBD + fBU - max(0, min((fBD + fBU), drainB)),
tempB = (fourierB / (mass * cpB) + tempB),
# Change in proportion water this step
moistureB = ifelse(tempB>99,ifelse(moistureB>0,max(0,moistureB-((fourierA/2256400)/mWaterB)),
moistureB),moistureB),
#STEP C ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterC = moistureC*mass,
# Energy removed by current water quantity
drainC = ifelse(tempC>99,
ifelse(moistureC>0,mWaterC*2256400,0),0),
#Thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (moistureC+moistureC^2)*barkDensity,
cpC = ((1105+4.85*tempC)*(1-moistureC)+moistureC*4185+1276*moistureC),
kC = (2.104*barkDensity+5.544*rhoM+3.266*tempC-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fCD = ((kC * (tempB - tempC)) / step),
fCU = ((kC * (tempD - tempC)) / step),
fourierC = fCD + fCU - max(0, min((fCD + fCU), drainC)),
tempC = (fourierC / (mass * cpC) + tempC),
# Change in proportion water this step
moistureC = ifelse(tempC>99,ifelse(moistureC>0,max(0,moistureC-((fourierB/2256400)/mWaterC)),
moistureC),moistureC),
#STEP D ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterD = moistureD*mass,
# Energy removed by current water quantity
drainD = ifelse(tempD>99,
ifelse(moistureD>0,mWaterD*2256400,0),0),
#Thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (moistureD+moistureD^2)*barkDensity,
cpD = ((1105+4.85*tempD)*(1-moistureD)+moistureD*4185+1276*moistureD),
kD = (2.104*barkDensity+5.544*rhoM+3.266*tempD-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fDD = ((kD * (tempC - tempD)) / step),
fDU = ((kD * (tempE - tempD)) / step),
fourierD = fDD + fDU - max(0, min((fDD + fDU), drainD)),
tempD = (fourierD / (mass * cpD) + tempD),
# Change in proportion water this step
moistureD = ifelse(tempD>99,ifelse(moistureD>0,max(0,moistureD-((fourierC/2256400)/mWaterD)),
moistureD),moistureD),
#phloem ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterE = moistureE*massW,
# Energy removed by current water quantity
drainE = ifelse(tempE>99,
ifelse(moistureE>0,mWaterE*2256400,0),0),
#Thermal values - (cp: J/g/deg, k: W/m/deg)
kAir = 0.00028683*(tempE+273.15)^0.7919,
cpE = 1080+408*moistureE+2.53*tempE+6.28*moistureE*tempE,
kE = kWood(tempE, woodDensity, kAir),
# Conduction from above and below, less latent heat of evaporation. Below unknown.
fED = ((kE * (tempD - tempE)) / phloem),
fEU = 0,
fourierE = fED + fEU - max(0, min((fED + fEU), drainE)),
tempE = (fourierE / (massW * cpE) + tempE),
# Change in proportion water this step
moistureE = ifelse(tempE>99,ifelse(moistureE>0,max(0,moistureE-((fourierD/2256400)/mWaterE)),
moistureE),moistureE))
Ca <- rbind(Ca, Cb)
#Collect values for the next step
tempA <- Cb$tempA
moistureA <- Cb$moistureA
kA <- Cb$kA
tempB <- Cb$tempB
moistureB <- Cb$moistureB
kB <- Cb$kB
tempC <- Cb$tempC
moistureC <- Cb$moistureC
kC <- Cb$kC
tempD <- Cb$tempD
moistureD <- Cb$moistureD
kD <- Cb$kD
tempE <- Cb$tempE
moistureE <- Cb$moistureE
kE <- Cb$kE
setTxtProgressBar(pbar,t)
## progress bar
Sys.sleep(0.25)
####UpdateProgress
if (is.function(updateProgress)) {
text <- paste0("Number of remaining steps is ", TIME - t)
updateProgress(detail = text)
}
t <- t + 1
Horiz <- Horiz - ROS
}
# Create table
Ca <- Ca %>%
select(t, repId, tempS, tempA, tempB, tempC, tempD, tempE,
moistureA, moistureB, moistureC, moistureD, moistureE)%>%
mutate(girdling = ifelse(tempE>=necT, 1, 0))
return(Ca)
}
#####################################################################
#' Air temperature above ambient at the tree bole behind the flame front
#'
#' Dynamic air temperature at bole height, declining flame length exponentially
#'
#' Air temperature is modelled from dynamic flame segments using
#' Weber R.O., Gill A.M., Lyons P.R.A., Moore P.H.R., Bradstock R.A., Mercer G.N. (1995)
#' Modelling wildland fire temperatures. CALMScience Supplement, 4, 23–26.
#'
#' pAlphas is set to bole height - depth of surface litter
#'
#' @param lengthSurface
#' @param residence
#' @param depth
#' @param h
#' @param surfDecl
#' @param t
#'
#' @return value
#' @export
#'
bole <- function(lengthSurface = 2, residence = 300, depth = 0.05, h = 0.1, surfDecl = 10, t = 1)
{
surfPost <- lengthSurface*exp(-(surfDecl/residence)*t)
Alpha <- 1/(2 * surfPost^2)
C <- 950 * surfPost * exp(-Alpha * surfPost^2)
pAlphas <- pmax(0,h-depth)
return(ifelse(pAlphas < surfPost,
950 + exp(-Alpha * pAlphas^2),
C/pAlphas))
}
#####################################################################
#' Thermal conductivity of dry wood
#'
#' Model drawn from Kollmann, F. F. P. & Cote, W. A.
#' Principles of wood science and technology I. Solid wood. (Springer-Verlag, 1968)
#'
#' @param rhoW
#' @param kAir
#'
#' @return value
#' @export
#'
kWood <- function(T=100, rhoW=700, kAir = 0.026)
{
T <- T+273.15
bridge <- 0.0019*T+0.0503
r <- 1-(rhoW/1500)
kA <- (1-r)*0.766+r*kAir
kB <- 1/((1-r)/0.43+(r/kAir))
return(bridge*kA+(1-bridge)*kB)
}
#' Collects flame segments for a specified plant in a stratum
#'
#' @param paths Output table from the function repFlame
#' @param Stratum Name of the stratum being studied
#' @param Species Name of the species being studied
#' @param repId Number of the repId being studied
#'
#' @return dataframe
#' @export
#'
#' @examples balga <- plantFlame(IPW, "NearSurface", "Xanthorrhoea preissii", 6)
plantFlame <- function(paths, Stratum, Species, repId) {
IP <- paths[paths$level == Stratum & paths$species == Species & paths$repId == repId,] %>%
mutate(angle = atan((y1-y0)/(x1-x0)),
x2 = flameLength * cos(angle) + x0,
y2 = flameLength * sin(angle) + y0)
x0 <- IP %>%
select(segIndex, x0)
x1 <- IP %>%
select(segIndex, x1)
IPX <- left_join(x0, x1)
x2 <- IP %>%
select(segIndex, x2)
IPX <- left_join(IPX,x2)
X <- reshape2::melt(IPX, id.vars="segIndex") %>%
mutate(x = value,
point = case_when(variable == "x0" ~ "A",
variable == "x1" ~ "B",
variable == "x2" ~ "C")) %>%
select(segIndex, point, x)
y0 <- IP %>%
select(segIndex, y0)
y1 <- IP %>%
select(segIndex, y1)
IPy <- left_join(y0, y1)
y2 <- IP %>%
select(segIndex, y2)
IPy <- left_join(IPy,y2)
Y <- reshape2::melt(IPy, id.vars="segIndex") %>%
mutate(y = value,
point = case_when(variable == "y0" ~ "A",
variable == "y1" ~ "B",
variable == "y2" ~ "C")) %>%
select(segIndex, point, y)
XY <- left_join(X,Y, by = c("segIndex", "point"))
out <- XY[order(XY$segIndex),]
return(out)
}
#' Calculates LAI for a slice of a plant
#'
#' @param base.params
#' @param sp Number of the species
#' @param yu Height at the top of the slice (m)
#' @param yl Height at the base of the slice (m)
#'
#' @return list
#' @export
#'
LAIp <- function(base.params, sp = 1, yu = 100, yl = 0)
{
# Subset species
spPar <- subset(base.params, species == sp)
# Collect parameters
Cd <- as.numeric(spPar$value[spPar$param == "clumpDiameter"])
Cs <- as.numeric(spPar$value[spPar$param == "clumpSeparation"])
ram <- as.numeric(spPar$value[spPar$param == "stemOrder"])
hc <- as.numeric(spPar$value[spPar$param == "hc"])
he <- as.numeric(spPar$value[spPar$param == "he"])
ht <- as.numeric(spPar$value[spPar$param == "ht"])
hp <- as.numeric(spPar$value[spPar$param == "hp"])
W <- as.numeric(spPar$value[spPar$param == "w"])
ll <- as.numeric(spPar$value[spPar$param == "leafLength"])
lw <- as.numeric(spPar$value[spPar$param == "leafWidth"])
ls <- as.numeric(spPar$value[spPar$param == "leafSeparation"])
if (yu <= min(hc,he)) {
l <- 0
LA <- 0
} else if (yl >= max(ht,hp)) {
l <- 0
LA <- 0
} else {
# Find w at cutoff cones
topRise <- abs(hp-ht)
baseFall <- abs(he-hc)
# Top of slice, plant top
wa <- ifelse(topRise==0,
W,
(W/topRise)*max(0,(hp-max(ht,yu))))
# Base of slice, plant top
wb <- ifelse(topRise==0,
W,
(W/topRise)*abs(hp-max(yl,ht)))
# Top of slice, plant base
wc <- ifelse(baseFall==0,
W,
(W/baseFall)*abs(min(he,yu)-hc))
# Base of slice, plant base
wd <- ifelse(baseFall==0,
W,
(W/baseFall)*max(0,(min(he,yl)-hc)))
# Leaf area per clump
clumpLeaves <- 0.88*(Cd*ram/ls)^1.18
laClump <- (ll*lw/2) * clumpLeaves
# Plant volume in slice
upperAboveSlice <- max(0,(hp-max(ht,yu))*(pi*(wa/2)^2))/3
upperFull <- ((hp-max(yl,ht))*(pi*(wb/2)^2))/3
upper <- max(0,upperFull-upperAboveSlice)
centre <- max(0,(min(yu,ht)-max(yl,he)))*(pi*(W/2)^2)
lowerFull <- ((min(yu,he)-hc)*(pi*(wc/2)^2))/3
lowerBelowSlice <- (max(0,(min(he,yl)-hc))*(pi*(wd/2)^2))/3
lower <- max(0,lowerFull-lowerBelowSlice)
vol <- upper+centre+lower
# Clumps in slice
volC <- ((4/3)*pi*((Cd+Cs)/2)^3)
nClumps <- vol/volC
#LAI per plant in slice
LA <- laClump * nClumps
l<- ifelse(max(wa,wb,wc,wd)==0,
0,
LA/(pi*(max(wa,wb,wc,wd)/2)^2))
}
return(list(l,LA))
}
#' Calculates LAI for a horizontal slice of a plant community
#'
#' @param base.params
#' @param yu Top of slice (m)
#' @param yl Base of slice (m)
#'
#' @return value
#' @export
LAIcomm <- function(base.params, yu = 100, yl = 0)
{
# Collect plant figures
spec <- species(base.params)
str <- strata(base.params)
l <- data.frame()
c <- data.frame()
cover <- data.frame()
s <- data.frame()
w <- data.frame()
N <- nrow(spec)
n <- 1
while(n <= N[1]) {
spPar <- subset(base.params, species == n)
laiN <- (LAIp(base.params, sp = n, yu = yu, yl = yl))[[1]]
l <- rbind(l,laiN)
c <- rbind(c,as.numeric(spec$comp[n]))
cover <- rbind(cover, as.numeric(str$cover[spec$st[n]]))
s <- rbind(s, as.numeric(str$separation[as.numeric(spPar$stratum[1])]))
w <- rbind(w,as.numeric(spPar$value[spPar$param == "w"]))
n <- n + 1
}
# Construct table
colnames(l) <- c("LAIp")
l$ID <- seq.int(nrow(l))
colnames(c) <- c("Weight")
c$ID <- seq.int(nrow(c))
colnames(cover) <- c("Cover")
cover$ID <- seq.int(nrow(cover))
LAIplant <- left_join(l,c, by = "ID")%>%
mutate(Weight = ifelse(LAIp>0,
Weight,
0))%>%
left_join(cover)
# Calculate LAI
LAIplant <- LAIplant %>%
mutate(LAIw = LAIp*Cover*Weight)
LAI <- sum(LAIplant$LAIw)
LAI[is.nan(LAI)] <- 0
return(LAI)
}
#' Title
#'
#' @param base.params
#' @param yu
#' @param yl
LAIcommX <- function(base.params, yu = 100, yl = 0)
{
# Collect plant figures
l <- data.frame()
c <- data.frame()
s <- data.frame()
w <- data.frame()
N <- count(species(base.params))
str <- strata(base.params)
n <- 1
while(n <= N[1]) {
spPar <- subset(base.params, species == n)
laiN <- LAIp(base.params, sp = n, yu = yu, yl = yl)[[1]]
l <- rbind(l,laiN)
c <- rbind(c,as.numeric(spPar$value[spPar$param == "composition"]))
s <- rbind(s, as.numeric(str$separation[as.numeric(spPar$stratum[1])]))
w <- rbind(w,as.numeric(spPar$value[spPar$param == "w"]))
n <- n + 1
}
# Construct table
colnames(l) <- c("LAIp")
l$ID <- seq.int(nrow(l))
colnames(c) <- c("Weight")
c$ID <- seq.int(nrow(c))
colnames(s) <- c("Separation")
s$ID <- seq.int(nrow(s))
colnames(w) <- c("Width")
w$ID <- seq.int(nrow(w))
LAIplant <- left_join(l,c)%>%
left_join(s)%>%
mutate(Weight = ifelse(LAIp>0,
Weight,
0))%>%
left_join(w)
# Calculate LAI
all <- sum(LAIplant$Weight)
LAIplant <- LAIplant %>%
mutate(Weight = Weight/all,
Cover = (Width^2/Separation^2)*Weight,
LAIw = LAIp*Cover)
LAI <- sum(LAIplant$LAIw)
LAI[is.nan(LAI)] <- 0
return(LAI)
}
#' Calculates a vertical wind profile
#'
#' @param base.params
#' @param slices Number of horizontal slices to use in calculation
#'
#' @return dataframe
#' @export
#'
profileDet <- function(base.params, slices = 10)
{
# Collect slice details
top <- max(species(base.params)$hp)
slice <- top/slices
yu <- top
# Loop through slices
l <- data.frame("l"=0)
gam <- data.frame("gam"=0)
W <- data.frame("w"=1)
w <- 1
n <- 1
while(n <= slices) {
yl <- yu-slice
LAIslice <- LAIcomm(base.params = base.params, yl=yl, yu = yu)
g <- 1.785*LAIslice^0.372
w <- w*exp(g*((yl/yu)-1))
l <- rbind(l,LAIslice)
gam <- rbind(gam,g)
W <- rbind(W,w)
yu <- yl
n = n+1
}
# Construct table
l$Slice <- seq.int(nrow(l))
gam$Slice <- seq.int(nrow(gam))
W$Slice <- seq.int(nrow(W))
wind <- left_join(l,gam)%>%
left_join(W)%>%
mutate(z = 1-((Slice-1)*(1/slices)),
hm = z*top)
return(wind)
}
#' Finds the Wind Reduction Factor for a param file
#'
#' @param base.params
#' @param test Height at which the WRF is calculated (m)
#'
#' @return value
#' @export
#'
windReduction <- function(base.params, test = 1.2)
{
s <- strata(base.params)
t <- max(s$top, na.rm = TRUE)
slice <- round(t/test)
det <- profileDet(base.params, slices = slice)
w <- det[nrow(det)-1,]
wrf <- as.numeric(round(1/w$w[1], 1))
return(wrf)
}
#' Calculates likelihood of basal scarring on a tree
#'
#' Assumes lee-side vortex at bole causes flame to lean backward to a distance 2.5*DBH
#' Estimate taken from Malcolm Gill A 1974
#' Toward an understanding of fire scar formation: field observation and laboratory simulation
#' For. Sci. 20 198–205
#'
#' @param Surf
#' @param Plant
#' @param DBH
#' @param Height
#' @param woodDensity
#' @param barkDensity
#' @param bark
#' @param comBark
#' @param resBark
#' @param phloem
#' @param RH
#' @param moisture
#' @param bMoisture
#' @param distance
#' @param trail
#' @param var
#' @param diameter
#' @param Pressure
#' @param Altitude
#' @param startTemp
#' @param necT
#' @param surfDecl
#' @param updateProgress
#'
#' @return dataframe
#'
dryside <- function(Surf, Plant, DBH = 1, Height = 0.1, woodDensity = 700, barkDensity = 500,
bark = 0.04, comBark = 700, resBark = 45, phloem = 0.01, RH = 0.2,
moisture = 0.6, bMoisture = 0.5, distance = 5, trail = 100, var = 10,
diameter = 20, Pressure = 1013.25,Altitude = 0, startTemp = 25,
necT = 60, surfDecl = 10,updateProgress=NULL)
{
# Post-front surface flame heating
lengthSurface <- mean(Surf$lengthSurface)
residence <- 0.871*diameter^1.875
depth <- diameter/1000
# Collect step distance, time, and total distance
ROS <- mean(Surf$ros_kph)/3.6
Ta <- round(distance/ROS+residence)
Tb <- round(distance/ROS)
TIME <- Ta + trail
Horiz <- distance
# Duration of post-front vortex
vortex <- round(2.5*DBH/ROS,0)
# Description of the protection
step <- bark/4
# Convert units from kg/m^3 to kg
mass <- step * barkDensity
massW <- phloem * woodDensity
R <- sqrt(0.01/pi)
startM <- moisture
#Starting values
Ca <- threat(Surf, Plant, Horiz, Height, var, Pressure, Altitude) %>%
summarise_all(mean)%>%
mutate(tS = 1,
#Convective transfer
Re = (Plume_velocity*Density)/viscosity,
h = 0.35 + 0.47*Re^(1/2)*0.837,
#Incoming heat from surface
Pt = pmax(0, tS - Tb),
comBark = ifelse(Pt <= resBark, comBark, 0),
postS = if(Pt < vortex) {950} else {bole(lengthSurface,residence, depth, h = Height,
surfDecl = 10, t = Pt)},
tempS = ifelse(Horiz <=0, pmax(tempAir, postS, comBark), tempAir),
qc = h * (tempS - startTemp),
att = frame:::tau(D=Horiz, flameTemp=flameTemp, temperature=(temperature+273.15), rh=RH),
qr = 0.86*qr*att,
Qi = pmax(0, qc)+qr,
#STEP A ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterA = bMoisture*mass,
# Energy removed by current water quantity
drainA = ifelse(startTemp>99,
ifelse(bMoisture>0,mWaterA*2256400,0),0),
#Thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (bMoisture+bMoisture^2)*barkDensity,
cpA = ((1105+4.85*startTemp)*(1-bMoisture)+bMoisture*4185+1276*bMoisture),
kA = (2.104*barkDensity+5.544*rhoM+3.266*startTemp-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fAD = ((kA * (tempS - startTemp)) / step),
fAU = 0,
fourierA = fAD + fAU - max(0, min((fAD + fAU), drainA)),
tempA = (fourierA / (mass * cpA) + startTemp),
# Change in proportion water this step
moistureA = ifelse(startTemp>99,ifelse(bMoisture>0,max(0,bMoisture-((Qi/2256400)/mWaterA)),
bMoisture),bMoisture),
#STEP B ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water (kg)
mWaterB = bMoisture*mass,
# Energy removed by current water quantity
drainB = ifelse(startTemp>99,
ifelse(moisture>0,mWaterB*2256400,0),0),
#Thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (bMoisture+bMoisture^2)*barkDensity,
cpB = ((1105+4.85*startTemp)*(1-bMoisture)+bMoisture*4185+1276*bMoisture),
kB = (2.104*barkDensity+5.544*rhoM+3.266*startTemp-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fBD = ((kB * (tempA - startTemp)) / step),
fBU = 0,
fourierB = fBD + fBU - max(0, min((fBD + fBU), drainB)),
tempB = (fourierB / (mass * cpB) + startTemp),
# Change in proportion water this step
moistureB = ifelse(startTemp>99,ifelse(bMoisture>0,max(0,bMoisture-((fourierA/2256400)/mWaterB)),
bMoisture), bMoisture),
#STEP C ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterC = bMoisture*mass,
# Energy removed by current water quantity
drainC = ifelse(startTemp>99,
ifelse(moisture>0,mWaterC*2256400,0),0),
#Thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (bMoisture+bMoisture^2)*barkDensity,
cpC = ((1105+4.85*startTemp)*(1-bMoisture)+bMoisture*4185+1276*bMoisture),
kC = (2.104*barkDensity+5.544*rhoM+3.266*startTemp-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fCD = ((kC * (tempB - startTemp)) / step),
fCU = 0,
fourierC = fCD + fCU - max(0, min((fCD + fCU), drainC)),
tempC = (fourierC / (mass * cpC) + startTemp),
# Change in proportion water this step
moistureC = ifelse(startTemp>99,ifelse(bMoisture>0,max(0,bMoisture-((fourierB/2256400)/mWaterC)),
bMoisture),bMoisture),
#STEP D ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterD = bMoisture*mass,
# Energy removed by current water quantity
drainD = ifelse(startTemp>99,
ifelse(moisture>0,mWaterD*2256400,0),0),
#Thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (bMoisture+bMoisture^2)*barkDensity,
cpD = ((1105+4.85*startTemp)*(1-bMoisture)+bMoisture*4185+1276*bMoisture),
kD = (2.104*barkDensity+5.544*rhoM+3.266*startTemp-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fDD = ((kD * (tempC - startTemp)) / step),
fDU = 0,
fourierD = fDD + fDU - max(0, min((fDD + fDU), drainD)),
tempD = (fourierD / (mass * cpD) + startTemp),
# Change in proportion water this step
moistureD = ifelse(startTemp>99,ifelse(bMoisture>0,max(0,bMoisture-((fourierC/2256400)/mWaterD)),
bMoisture),bMoisture),
#Phloem ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterE = moisture*massW,
# Energy removed by current water quantity
drainE = ifelse(startTemp>99,
ifelse(moisture>0,mWaterE*2256400,0),0),
#Thermal values - (cp: J/g/deg, k: W/m/deg)
kAir = 0.00028683*(startTemp+273.15)^0.7919,
cpE = 1080+408*moisture+2.53*startTemp+6.28*moisture*startTemp,
kE = kWood(startTemp, woodDensity, kAir),
# Conduction from above and below, less latent heat of evaporation
fED = ((kE * (tempD - startTemp)) / step),
fEU = 0,
fourierE = fED + fEU - max(0, min((fED + fEU), drainE)),
tempE = (fourierE / (massW * cpE) + startTemp),
# Change in proportion water this step
moistureE = ifelse(startTemp>99,ifelse(moisture>0,max(0,moisture-((fourierD/2256400)/mWaterE)),
moisture),moisture))
#Collect values for the next step
tempA <- Ca$tempA
moistureA <- Ca$moistureA
kA <- Ca$kA
tempB <- Ca$tempB
moistureB <- Ca$moistureB
kB <- Ca$kB
tempC <- Ca$tempC
moistureC <- Ca$moistureC
kC <- Ca$kC
tempD <- Ca$tempD
moistureD <- Ca$moistureD
kD <- Ca$kD
tempE <- Ca$tempE
moistureE <- Ca$moistureE
kE <- Ca$kE
# Advance one second's travel
Horiz <- Horiz - ROS
pbar <- txtProgressBar(max = TIME, style = 3)
# Loop through each time step and collect outputs
for(tS in 2:TIME){
Cb <-threat(Surf, Plant, Horiz, Height, var, Pressure, Altitude) %>%
summarise_all(mean)%>%
mutate(tS = tS,
#Convective transfer
Re = (Plume_velocity*Density)/viscosity,
h = 0.35 + 0.47*Re^(1/2)*0.837,
#Incoming heat from surface
Pt = pmax(0, tS - Tb),
comBark = ifelse(Pt <= resBark, comBark, 0),
postS = if(Pt < vortex) {950} else {bole(lengthSurface,residence, depth, h = Height,
surfDecl = 10, t = Pt)},
tempS = ifelse(tS > Ta, tempAir, ifelse(Horiz <=0, pmax(tempAir, postS, comBark), tempAir)),
qc = h * (tempS - tempA),
att = frame:::tau(D=Horiz, flameTemp=flameTemp, temperature=(temperature+273.15), rh=RH),
qr = 0.86*qr*att,
Qi = pmax(0, qc)+qr,
#STEP A ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterA = moistureA*mass,
# Energy removed by current water quantity
drainA = ifelse(tempA>99,
ifelse(moistureA>0,mWaterA*2256400,0),0),
#Bark thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (moistureA+moistureA^2)*barkDensity,
cpA = ((1105+4.85*tempA)*(1-moistureA)+moistureA*4185+1276*moistureA),
kA = (2.104*barkDensity+5.544*rhoM+3.266*tempA-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fAD = ((kA * (tempS - tempA)) / step),
fAU = ((kB * (tempB - tempA)) / step),
fourierA = fAD + fAU - max(0, min((fAD + fAU), drainA)),
tempA = (fourierA / (mass * cpA) + tempA),
# Change in proportion water this step
moistureA = ifelse(tempA>99,ifelse(moistureA>0,max(0,moistureA-((Qi/2256400)/mWaterA)),
moistureA),moistureA),
#STEP B ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterB = moistureB*mass,
# Energy removed by current water quantity
drainB = ifelse(tempB>99,
ifelse(moistureB>0,mWaterB*2256400,0),0),
#Thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (moistureB+moistureB^2)*barkDensity,
cpB = ((1105+4.85*tempB)*(1-moistureB)+moistureB*4185+1276*moistureB),
kB = (2.104*barkDensity+5.544*rhoM+3.266*tempB-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fBD = ((kB * (tempA - tempB)) / step),
fBU = ((kC * (tempC - tempB)) / step),
fourierB = fBD + fBU - max(0, min((fBD + fBU), drainB)),
tempB = (fourierB / (mass * cpB) + tempB),
# Change in proportion water this step
moistureB = ifelse(tempB>99,ifelse(moistureB>0,max(0,moistureB-((fourierA/2256400)/mWaterB)),
moistureB),moistureB),
#STEP C ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterC = moistureC*mass,
# Energy removed by current water quantity
drainC = ifelse(tempC>99,
ifelse(moistureC>0,mWaterC*2256400,0),0),
#Thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (moistureC+moistureC^2)*barkDensity,
cpC = ((1105+4.85*tempC)*(1-moistureC)+moistureC*4185+1276*moistureC),
kC = (2.104*barkDensity+5.544*rhoM+3.266*tempC-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fCD = ((kC * (tempB - tempC)) / step),
fCU = ((kC * (tempD - tempC)) / step),
fourierC = fCD + fCU - max(0, min((fCD + fCU), drainC)),
tempC = (fourierC / (mass * cpC) + tempC),
# Change in proportion water this step
moistureC = ifelse(tempC>99,ifelse(moistureC>0,max(0,moistureC-((fourierB/2256400)/mWaterC)),
moistureC),moistureC),
#STEP D ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterD = moistureD*mass,
# Energy removed by current water quantity
drainD = ifelse(tempD>99,
ifelse(moistureD>0,mWaterD*2256400,0),0),
#Thermal values - (cp: J/kg/deg, k: W/m/deg)
rhoM = (moistureD+moistureD^2)*barkDensity,
cpD = ((1105+4.85*tempD)*(1-moistureD)+moistureD*4185+1276*moistureD),
kD = (2.104*barkDensity+5.544*rhoM+3.266*tempD-166.216)*10^-4,
# Conduction from above and below, less latent heat of evaporation
fDD = ((kD * (tempC - tempD)) / step),
fDU = ((kD * (tempE - tempD)) / step),
fourierD = fDD + fDU - max(0, min((fDD + fDU), drainD)),
tempD = (fourierD / (mass * cpD) + tempD),
# Change in proportion water this step
moistureD = ifelse(tempD>99,ifelse(moistureD>0,max(0,moistureD-((fourierC/2256400)/mWaterD)),
moistureD),moistureD),
#phloem ________________________________________________________
### Water effects: evaporation and energy drain
# Mass of water
mWaterE = moistureE*massW,
# Energy removed by current water quantity
drainE = ifelse(tempE>99,
ifelse(moistureE>0,mWaterE*2256400,0),0),
#Thermal values - (cp: J/g/deg, k: W/m/deg)
kAir = 0.00028683*(tempE+273.15)^0.7919,
cpE = 1080+408*moistureE+2.53*tempE+6.28*moistureE*tempE,
kE = kWood(tempE, woodDensity, kAir),
# Conduction from above and below, less latent heat of evaporation. Below unknown.
fED = ((kE * (tempD - tempE)) / phloem),
fEU = 0,
fourierE = fED + fEU - max(0, min((fED + fEU), drainE)),
tempE = (fourierE / (massW * cpE) + tempE),
# Change in proportion water this step
moistureE = ifelse(tempE>99,ifelse(moistureE>0,max(0,moistureE-((fourierD/2256400)/mWaterE)),
moistureE),moistureE))
Ca <- rbind(Ca, Cb)
#Collect values for the next step
tempA <- Cb$tempA
moistureA <- Cb$moistureA
kA <- Cb$kA
tempB <- Cb$tempB
moistureB <- Cb$moistureB
kB <- Cb$kB
tempC <- Cb$tempC
moistureC <- Cb$moistureC
kC <- Cb$kC
tempD <- Cb$tempD
moistureD <- Cb$moistureD
kD <- Cb$kD
tempE <- Cb$tempE
moistureE <- Cb$moistureE
kE <- Cb$kE
setTxtProgressBar(pbar,tS)
## progress bar
Sys.sleep(0.25)
####UpdateProgress
if (is.function(updateProgress)) {
text <- paste0("Number of remaining steps is ", TIME - tS)
updateProgress(detail = text)
}
tS <- tS + 1
Horiz <- Horiz - ROS
}
# Create table
Ca <- Ca %>%
select(tS, repId, tempS, tempA, tempB, tempC, tempD, tempE,
moistureA, moistureB, moistureC, moistureD, moistureE)%>%
mutate(scar = ifelse(tempE>=necT, 1, 0))
return(Ca)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.