Assigning some numbers:

electricityCost<-0.0477 #$/kWh
span<-20 #yr
componentcosts<-"C:\\Users\\craw038\\Documents\\CarbonCaptureCellCosts.xlsx"%>%
  read_excel()

rownames(componentcosts)<-componentcosts$Component

aspectratio<-1
membraneX<-0.038#m extra length for membrane
frameXW<-0.14 #m extra length for pvc frame
frameXL<-0.05 #m extra length for pvc frame
cdepth<-0.002 #m
cwidth<-0.005 #m


CO2MassRate<-600*24 #kg/day
MMCarbon<-12+16*2 #g/mol CO2
CO2MolarRate<-CO2MassRate*1000/MMCarbon #mol/day
CaptEff<-0.75

Faraday<-26.8 #Ah/mol
CurrentRequired<-CO2MolarRate/24*Faraday/CaptEff #A

CO3Concentration<-2.5/1000 #mol/L
Utilisation<-1


flow<-1/(Faraday*CO3Concentration/1000)/60/Utilisation #ml/min-A
visc<-9e-4 #Pa-s

Voltage<-0.62 #V
j<-(50/1000)/(5/100/100) #A/m^2

Defining Cost function

findCost<-function(Cells,Stacks){
area<-CurrentRequired/Cells/Stacks/j #m^2

q<-CurrentRequired/Cells/Stacks*flow*1e-6/60 #m^3/s

Loss<-function(area,q,Vd){
  
  Dsp<-0.009 #m
  Lsp<-0.1 #m
    Dmp<-1.75*2.54/100 #m
    k<-0.0015/1000 #m roughness
  
  resistivity<-1/5 #S/m
  length<-sqrt(area/aspectratio)
  carea<-Dsp^2*pi/4
  Rs<-resistivity*Lsp/carea
  Rm<-resistivity*Dsp/((Dmp)^2*3.14/4) 
  Ik<-Vd/Rm
  r <- sqrt(Rs/Rm)
  data.frame(cellno=(-(Cells-2)/2):((Cells-2)/2))%>%
    mutate(im=Ik*(1-(cosh(cellno/r)/cosh(0.5*Cells/r))),
           is=(Ik/r)*(sinh(cellno/r)/cosh(0.5*Cells/r)),
           powerLoss=4*Rm*im^2+4*Rs*is^2)%>%
    .$powerLoss%>%mean->shuntLoss
  
  if(visc==0){return(shuntLoss)}
  
  width = sqrt(area*aspectratio)
  height = width/aspectratio
  #Dh=2*cdepth*cwidth/(cdepth+cwidth)
  #carea=cdepth*cwidth
  K = 3.982E-10# m^2
  thickness = 0.001 #m
  #segments <- width/channelsep
  
  rho<-1000 #kg/m^3
  
  ReSP<-q/(Dsp^2*pi/4)*Dsp*rho/visc
  
  froot<-function(f){
    
    if(f<=0){return(NA)}
    1/sqrt(f)+2*log10(k/Dsp/3.7+2.51/ReSP/sqrt(f))
  }
  
  fsp<-uniroot(froot,c(100,1e-10))$root
  
  Lmp<-7 #m
  ReMP<-Cells*q/(Dmp^2*pi/4)*Dmp*rho/visc/2
  
  froot<-function(f){
    
    if(f<=0){return(NA)}
    1/sqrt(f)+2*log10(k/Dmp/3.7+2.51/ReMP/sqrt(f))
  }
  
  fmp<-uniroot(froot,c(100,1e-10))$root
  
  
  DhCell<-2*thickness*width/(thickness+width)
  
  Pdrop<-32*height*q*visc/(thickness*width*DhCell*DhCell)+
    2*fsp*rho*(q/(Dsp^2*pi/4))^2/Dsp/2*Lsp+
    2*fmp*rho*(q*Cells/2/(Dmp^2*pi/4))^2/Dmp/2*Lmp
  
  PEff<-0.67
  powerLoss<-2*Pdrop*q/PEff
  
  return(powerLoss+shuntLoss)
  
}

PowerRequired<-Loss(area,q,Voltage)+area*j*Voltage #W


EnergyCost<-data.frame(Component=c("Electricity","Electricity Loss"),
                       Cost=c(area*j*Voltage,Loss(area,q,Voltage))*Cells*Stacks/1000*electricityCost/(CO2MassRate/24))

length<-sqrt(area*aspectratio)
width<-sqrt(area/aspectratio)

q<-CurrentRequired*flow #ml/min
GPM<-q/3785.41
PumpLoss<-(PowerRequired-area*j*Voltage)*Cells*Stacks/1000/2
#print(PumpLoss)

FeltCost<-componentcosts["Carbon Cloth",]%>%
  mutate(Cost=Cost*area*2*Cells*Stacks)

NfCost<-componentcosts["Membrane",]%>%
  mutate(Cost=2*Cost*(length+membraneX)*(membraneX+width)*Cells*Stacks)


PtCost<-componentcosts["Pt",]%>%
  mutate(Cost=1*Cost*area*Cells*Stacks)

BipolarCost<-componentcosts["Carbon Plate",]%>%
  mutate(Cost=Cost*area*Cells*Stacks)

PVCCost<-componentcosts["PVC Frame",]%>%
  mutate(Cost=Cost*(length+frameXW)*(width+frameXL)*2*Cells*Stacks)

PumpCost<-componentcosts["Pump Cost per GPM",]%>%
  mutate(Component="Pumps",
         Cost=(Cost*GPM*2+componentcosts["Pump Base Cost",]$Cost*2))

PumpCost<-componentcosts["Pump Cost per kW",]%>%
  mutate(Component="Pumps",
         Cost=(Cost*PumpLoss*2+componentcosts["Pump Base Cost2",]$Cost*2))

PCSCost<-componentcosts["PCS",]%>%
  mutate(Cost=Cost*PowerRequired*Cells*Stacks)

AlCosts<-componentcosts["Al Endplate",]%>%
  mutate(Cost=Cost*2*Stacks)

bind_rows(EnergyCost,
          PtCost,
          FeltCost,
          NfCost,
          BipolarCost,
          PVCCost,
          PumpCost,
          PCSCost,
          AlCosts)%>%
  return
}

Levelised Cost Multipliers:

"C:\\Users\\craw038\\Documents\\LevelisedCost.csv"%>%
  read.csv(row.names = NULL)->X

X%>%lm(data=.,`ï..Levelised.Cost`~.+0)%>%summary%>%coef%>%.[,"Estimate"]->LCOEMult

LCOEMultiplier<-bind_rows(data.frame(Component=c("Electricity",
                             "Electricity Loss"),
                           Mult=CO2MassRate*365.25*LCOEMult["Electricity"]),
                          data.frame(Component=c("PVC Frame",
                                                 "Pumps",
                                                 "PCS",
                                                 "AI Endplate"),
                                     Mult=LCOEMult["Capital"]),
                          data.frame(Component=c("Membrane",
                                                 "Pt",
                                                 "Carbon Cloth",
                                                 "Carbon Plate"),
                                     Mult=LCOEMult["CapitalReplace"]))

Check various electrochemical performance scenarios:

ElectroChemScenarios<-data.frame(V=c(0.62,0.88,0.62,0.93),
                                 j=c(5,10,10,50)*100*100/1000)

ElectroChemScenarios<-bind_rows(ElectroChemScenarios%>%mutate(Pumped=TRUE),
                                ElectroChemScenarios%>%mutate(Pumped=FALSE))

ElectroChemResults<-NULL
for(i in 1:nrow(ElectroChemScenarios)){
  
  Voltage<-ElectroChemScenarios$V[i] #V
  j<-ElectroChemScenarios$j[i] #A/m^2
  visc <- 0.9E-03*ElectroChemScenarios$Pumped[i] # p
  
  CO2MassRate<-24*ifelse(ElectroChemScenarios$Pumped[i],750,450) #kg/day
  MMCarbon<-12+16*2 #g/mol CO2
  CO2MolarRate<-CO2MassRate*1000/MMCarbon #mol/day
  CaptEff<-0.75
  
  Faraday<-26.8 #Ah/mol
  CurrentRequired<-CO2MolarRate/24*Faraday/CaptEff #A
  
  CO3Concentration<-2.5/1000 #mol/L
  Utilisation<-1
  electricityCost<-0.0477 #$/kWh
  
  flow<-1/(Faraday*CO3Concentration/1000)/60/Utilisation #ml/min-A
  
  
  findCost(15,800)%>%
    mutate(V=Voltage,
           j=j,
           Pumped=ElectroChemScenarios$Pumped[i],
           Scenario=paste0(Voltage," V\n", j/10, " mA/cm^2"),
           CO2perHour=CO2MassRate/24)%>%
    bind_rows(ElectroChemResults)->ElectroChemResults
  
}

ElectroChemResults%>%
  filter(!(Component=="Pumps" & !Pumped))%>%
  merge(LCOEMultiplier)%>%
  mutate(LevlisedCost=Cost*Mult*ifelse(!grepl("Electricity",Component),600/CO2perHour,1),
         Scenario2=ifelse(Pumped,"Pumped","Effulent"),
         Component=factor(Component, levels(factor(Component))[rev(c(5,1,2,6:9,3,4))]))%>%
    select(-Cost)%>%
  arrange(Pumped,Scenario,Component)%T>%write.csv("CarbonCaptureCostBase.csv")%>%
  ggplot(aes(x=Scenario,y=LevlisedCost,fill=Component))+
  geom_bar(stat="identity", colour="black",size=1)+theme_bw()+ylab("Levelized Cost $/kg")+facet_wrap(.~Scenario2)+scale_fill_brewer(palette = "Set1")+
    theme(strip.background = element_blank(),
          axis.title = element_text(face="bold",size=16),
          axis.text = element_text(face="bold",size=10,colour="black"),
          strip.text =  element_text(face="bold",size=16,colour="black"),
          legend.text =   element_text(face="bold",size=14,colour="black"),
          legend.title =  element_text(face="bold",size=14,colour="black"))+
    scale_y_continuous(expand = expand_scale(mult = c(0,0.05), add = 0), limits = c(0, NA))

ElectroChemResults%>%
  filter(!(Component=="Pumps" & !Pumped))%>%
  merge(LCOEMultiplier)%>%
  mutate(LevlisedCost=Cost*Mult*ifelse(!grepl("Electricity",Component),600/CO2perHour,1),
         Scenario2=ifelse(Pumped,"Pumped","Effulent"),
         Component=factor(Component, levels(factor(Component))[rev(c(5,1,2,6:9,3,4))]))%>%
  filter(!grepl("Electricity",Component))%>%
    select(-LevlisedCost)%>%
  arrange(Pumped,Scenario,Cost)%T>%write.csv("CarbonCaptureCostBaseCapital.csv")%>%
  ggplot(aes(x=Scenario,y=Cost,fill=Component))+
  geom_bar(stat="identity", colour="black",size=1)+theme_bw()+ylab("Levelized Cost $/kg")+facet_wrap(.~Scenario2)+scale_fill_brewer(palette = "Set1")+
    theme(strip.background = element_blank(),
          axis.title = element_text(face="bold",size=16),
          axis.text = element_text(face="bold",size=10,colour="black"),
          strip.text =  element_text(face="bold",size=16,colour="black"),
          legend.text =   element_text(face="bold",size=14,colour="black"),
          legend.title =  element_text(face="bold",size=14,colour="black"))+
    scale_y_continuous(expand = expand_scale(mult = c(0,0.05), add = 0), limits = c(0, NA))

Load in electricity price data:

MarketData<-read_feather("C:\\Users\\craw038\\Documents\\RedoxCellCost\\RegionalElectricityPrice.feather")

Scenarios2<-NULL
for(i in 1:24){
  
  MarketData%>%
    arrange(Region,Day,Cost)%>%
    group_by(Region,Day)%>%
    mutate(Rank=seq_along(Cost),
           Count=n(),
           Cost=Cost/1000)%>%
    filter(Count==24,
           Rank<=i)%>%
    group_by(Region)%>%
    summarise(MeanCost=mean(Cost))%>%
    mutate(Hours=i)%>%
    bind_rows(Scenarios2)->Scenarios2
}

Scenarios2<-bind_rows(Scenarios2%>%mutate(Pumped=TRUE),Scenarios2%>%mutate(Pumped=FALSE))

Scenarios2%>%ggplot(aes(x=Hours,y=MeanCost,colour=Region))+geom_line(size=1.2)+
  theme_bw()+
  xlab("Hours per Day Operated")+
  ylab("Electricity Cost ($/kWh)")+
  scale_color_brewer(palette="Set1")+
    theme(strip.background = element_blank(),
          axis.title = element_text(face="bold",size=16),
          axis.text = element_text(face="bold",size=10,colour="black"),
          strip.text =  element_text(face="bold",size=16,colour="black"),
          legend.text =   element_text(face="bold",size=14,colour="black"),
          legend.title =  element_text(face="bold",size=14,colour="black"))+
    scale_y_continuous(expand = expand_scale(mult = c(0,0.05), add = 0), limits = c(0, NA))

Check various electricity price scenarios:

Costs2<-NULL
for(i in 1:nrow(Scenarios2)){
  
  
Voltage<-0.62 #V
j<-(50/1000)/(5/100/100) #A/m^2
  
  CO2MassRate<-ifelse(Scenarios2$Pumped[i],750,450)*24*(24/Scenarios2$Hours[i]) #kg/day
  MMCarbon<-12+16*2 #g/mol CO2
  CO2MolarRate<-CO2MassRate*1000/MMCarbon #mol/day
  CaptEff<-0.75
  
  Faraday<-26.8 #Ah/mol
  CurrentRequired<-CO2MolarRate/24*Faraday/CaptEff #A
  
  CO3Concentration<-2.5/1000 #mol/L
  Utilisation<-1

  flow<-1/(Faraday*CO3Concentration/1000)/60/Utilisation #ml/min-A

  electricityCost<-Scenarios2$MeanCost[i]
  
  
Costs<-findCost(15,800)

Costs2<-Costs%>%mutate(Region=Scenarios2$Region[i],
                       Hours=Scenarios2$Hours[i],
                       Pumped=Scenarios2$Pumped[i],
                        CO2perHour=ifelse(Scenarios2$Pumped[i],750,450))%>%bind_rows(Costs2)

}

Costs2%>%
  filter(!(Component=="Pumps" & !Pumped))%>%
  merge(LCOEMultiplier)%>%
  mutate(LevlisedCost=Cost*Mult*ifelse(!grepl("Electricity",Component),600/CO2perHour,1),
         Scenario2=ifelse(Pumped,"Pumped","Effulent"),
         Component=factor(Component, levels(factor(Component))[rev(c(5,1,2,6:9,3,4))]))%>%
  select(-Cost)%>%
  arrange(Region,Scenario2,Hours,Component)%T>%write.csv("CarbonCaptureCostsbyRegion.csv")%>%
  group_by(Region,Scenario2,Hours)%>%
  mutate(TotalCost=sum(LevlisedCost))%>%
  group_by(Region,Scenario2)%>%#filter(Scenario2=="Pumped",Region=="PNW")%>%
  filter(Hours==24 | TotalCost==min(TotalCost))%>%
  mutate(Scenario=ifelse(Hours==24 & !((Hours%>%unique%>%sum)==24),"Non-Opt","Opt"))%>%
  #mutate(Cost=Cost/ifelse(grepl("Electricity",Component),1,CO2MassRate*365.25*20))%>%
  ggplot(aes(x=Scenario,y=LevlisedCost,fill=Component))+
  geom_bar(stat="identity", colour="black",size=1)+theme_bw()+ylab("Levelized Cost $/kg")+facet_grid(Scenario2~Region)+scale_fill_brewer(palette = "Set1")+
    theme(strip.background = element_blank(),
          axis.title = element_text(face="bold",size=16),
          axis.text = element_text(face="bold",size=10,colour="black"),
          strip.text =  element_text(face="bold",size=16,colour="black"),
          legend.text =   element_text(face="bold",size=14,colour="black"),
          legend.title =  element_text(face="bold",size=14,colour="black"))+
    scale_y_continuous(expand = expand_scale(mult = c(0,0.05), add = 0), limits = c(0, NA))

Using NF212 and 10x Pt cost:

ElectroChemScenarios<-data.frame(V=c(0.62,0.88,0.62,0.93),
                                 j=c(5,10,10,50)*100*100/1000)

ElectroChemScenarios<-bind_rows(ElectroChemScenarios%>%mutate(Pumped=TRUE),
                                ElectroChemScenarios%>%mutate(Pumped=FALSE))

ElectroChemResults<-NULL
for(i in 1:nrow(ElectroChemScenarios)){
  
  Voltage<-ElectroChemScenarios$V[i] #V
  j<-ElectroChemScenarios$j[i] #A/m^2
  visc <- 0.9E-03*ElectroChemScenarios$Pumped[i] # p
  
  CO2MassRate<-24*ifelse(ElectroChemScenarios$Pumped[i],750,450) #kg/day
  MMCarbon<-12+16*2 #g/mol CO2
  CO2MolarRate<-CO2MassRate*1000/MMCarbon #mol/day
  CaptEff<-0.75
  
  Faraday<-26.8 #Ah/mol
  CurrentRequired<-CO2MolarRate/24*Faraday/CaptEff #A
  
  CO3Concentration<-2.5/1000 #mol/L
  Utilisation<-1
  electricityCost<-0.0477 #$/kWh
  
  flow<-1/(Faraday*CO3Concentration/1000)/60/Utilisation #ml/min-A
  
  
  findCost(15,800)%>%
    mutate(V=Voltage,
           j=j,
           Pumped=ElectroChemScenarios$Pumped[i],
           Scenario=paste0(Voltage," V\n", j/10, " mA/cm²"),
           CO2perHour=CO2MassRate/24)%>%
    bind_rows(ElectroChemResults)->ElectroChemResults
  
}

(ElectroChemResults%>%
  filter(!(Component=="Pumps" & !Pumped))%>%
  merge(LCOEMultiplier)%>%
  mutate(Cost=Cost*ifelse(Component=="Membrane",95/32,1),
         Cost=Cost*ifelse(Component=="Pt",10,1))%>%
  mutate(LevlisedCost=Cost*Mult*ifelse(!grepl("Electricity",Component),600/CO2perHour,1),
         Scenario2=ifelse(Pumped,"Pumped","Effulent"),
         Component=factor(Component, levels(factor(Component))[rev(c(5,1,2,6:9,3,4))]))%>%
    select(-Cost)%>%
  arrange(Pumped,Scenario,Component)%T>%write.csv("CarbonCaptureCostNf212Pt10x.csv")%>%
  ggplot(aes(x=Scenario,y=LevlisedCost,fill=Component))+
  geom_bar(stat="identity", colour="black",size=1)+theme_bw()+ylab("Levelized Cost $/kg")+facet_wrap(.~Scenario2)+scale_fill_brewer(palette = "Set1")+
    theme(strip.background = element_blank(),
          axis.title = element_text(face="bold",size=16),
          axis.text = element_text(face="bold",size=10,colour="black"),
          strip.text =  element_text(face="bold",size=16,colour="black"),
          legend.text =   element_text(face="bold",size=14,colour="black"),
          legend.title =  element_text(face="bold",size=14,colour="black"))+
    scale_y_continuous(expand = expand_scale(mult = c(0,0.05), add = 0), limits = c(0, NA)))%>%print

ElectroChemResults%>%
  filter(!(Component=="Pumps" & !Pumped))%>%
  merge(LCOEMultiplier)%>%
  mutate(LevlisedCost=Cost*Mult*ifelse(!grepl("Electricity",Component),600/CO2perHour,1),
         Scenario2=ifelse(Pumped,"Pumped","Effulent"),
         Component=factor(Component, levels(factor(Component))[rev(c(5,1,2,6:9,3,4))]))%>%
   mutate(Cost=Cost*ifelse(Component=="Membrane",95/32,1),
         Cost=Cost*ifelse(Component=="Pt",10,1))%>%
  filter(!grepl("Electricity",Component))%>%
    select(-LevlisedCost)%>%
  arrange(Pumped,Scenario,Cost)%T>%write.csv("CarbonCaptureCostNf212Pt10xCapital.csv")%>%
  ggplot(aes(x=Scenario,y=Cost,fill=Component))+
  geom_bar(stat="identity", colour="black",size=1)+theme_bw()+ylab("Capital Cost $")+facet_wrap(.~Scenario2)+scale_fill_brewer(palette = "Set1")+
    theme(strip.background = element_blank(),
          axis.title = element_text(face="bold",size=16),
          axis.text = element_text(face="bold",size=10,colour="black"),
          strip.text =  element_text(face="bold",size=16,colour="black"),
          legend.text =   element_text(face="bold",size=14,colour="black"),
          legend.title =  element_text(face="bold",size=14,colour="black"))+
    scale_y_continuous(expand = expand_scale(mult = c(0,0.05), add = 0), limits = c(0, NA))

Costs2<-NULL
for(i in 1:nrow(Scenarios2)){
  
  
Voltage<-0.62 #V
j<-(50/1000)/(5/100/100) #A/m^2
  
  CO2MassRate<-ifelse(Scenarios2$Pumped[i],750,450)*24*(24/Scenarios2$Hours[i]) #kg/day
  MMCarbon<-12+16*2 #g/mol CO2
  CO2MolarRate<-CO2MassRate*1000/MMCarbon #mol/day
  CaptEff<-0.75
  
  Faraday<-26.8 #Ah/mol
  CurrentRequired<-CO2MolarRate/24*Faraday/CaptEff #A
  
  CO3Concentration<-2.5/1000 #mol/L
  Utilisation<-1

  flow<-1/(Faraday*CO3Concentration/1000)/60/Utilisation #ml/min-A

  electricityCost<-Scenarios2$MeanCost[i]
  
  
Costs<-findCost(15,800)

Costs2<-Costs%>%mutate(Region=Scenarios2$Region[i],
                       Hours=Scenarios2$Hours[i],
                       Pumped=Scenarios2$Pumped[i],
                        CO2perHour=ifelse(Scenarios2$Pumped[i],750,450))%>%bind_rows(Costs2)

}

Costs2%>%
  filter(!(Component=="Pumps" & !Pumped))%>%
  merge(LCOEMultiplier)%>%
    mutate(Cost=Cost*ifelse(Component=="Membrane",95/32,1),
         Cost=Cost*ifelse(Component=="Pt",10,1))%>%
  mutate(LevlisedCost=Cost*Mult*ifelse(!grepl("Electricity",Component),600/CO2perHour,1),
         Scenario2=ifelse(Pumped,"Pumped","Effulent"),
         Component=factor(Component, levels(factor(Component))[rev(c(5,1,2,6:9,3,4))]))%>%
  select(-Cost)%>%
  arrange(Region,Scenario2,Hours,Component)%T>%write.csv("CarbonCaptureCostsbyRegionNf212Pt10x.csv")%>%
  group_by(Region,Scenario2,Hours)%>%
  mutate(TotalCost=sum(LevlisedCost))%>%
  group_by(Region,Scenario2)%>%#filter(Scenario2=="Pumped",Region=="PNW")%>%
  filter(Hours==24 | TotalCost==min(TotalCost))%>%
  mutate(Scenario=ifelse(Hours==24 & !((Hours%>%unique%>%sum)==24),"Non-Opt","Opt"))%>%
  #mutate(Cost=Cost/ifelse(grepl("Electricity",Component),1,CO2MassRate*365.25*20))%>%
  ggplot(aes(x=Scenario,y=LevlisedCost,fill=Component))+
  geom_bar(stat="identity", colour="black",size=1)+theme_bw()+ylab("Levelized Cost $/kg")+facet_grid(Scenario2~Region)+scale_fill_brewer(palette = "Set1")+
    theme(strip.background = element_blank(),
          axis.title = element_text(face="bold",size=16),
          axis.text = element_text(face="bold",size=10,colour="black"),
          strip.text =  element_text(face="bold",size=16,colour="black"),
          legend.text =   element_text(face="bold",size=14,colour="black"),
          legend.title =  element_text(face="bold",size=14,colour="black"))+
    scale_y_continuous(expand = expand_scale(mult = c(0,0.05), add = 0), limits = c(0, NA))