From 7fe02cf010a94d36c22dde274b1201a4c8bd5e32 Mon Sep 17 00:00:00 2001 From: james <81617086+je-cook@users.noreply.github.com> Date: Fri, 2 Feb 2024 16:34:29 +0000 Subject: [PATCH 1/5] unify costing interface --- process/caller.py | 9 +- process/costs.py | 1312 +++++++++++++++++++--------------------- process/costs_2015.py | 17 +- process/ife.py | 5 +- process/main.py | 41 +- process/output.py | 10 +- process/stellarator.py | 5 +- 7 files changed, 653 insertions(+), 746 deletions(-) diff --git a/process/caller.py b/process/caller.py index d0be83720a..d4ac6287b8 100644 --- a/process/caller.py +++ b/process/caller.py @@ -153,13 +153,8 @@ def call_models(self, xc): ---- | ------ 0 | 1990 costs model 1 | 2015 Kovari model - 2 | 2019 STEP model + 2 | Custom model """ - if ft.cost_variables.cost_model == 0: - self.models.costs.run(output=False) - elif ft.cost_variables.cost_model == 1: - self.models.costs_2015.run(output=False) - elif ft.cost_variables.cost_model == 2: - self.models.costs_step.run() + self.models.costs.run() # FISPACT and LOCA model (not used)- removed diff --git a/process/costs.py b/process/costs.py index e5de3b3b85..ed5b96c4a9 100644 --- a/process/costs.py +++ b/process/costs.py @@ -46,111 +46,30 @@ def __init__(self): float, 0.0, docstring="ccont account cost", units="M$" ) - # Account 226 - Heat transport system - self.c226 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2261 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2262 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2263 = AnnotatedVariable(float, 0.0, docstring="", units="") - - # Account 227 - Fuel handling - self.c227 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2271 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2272 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2273 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2274 = AnnotatedVariable(float, 0.0, docstring="", units="") - - # Account 24 - electrical plant equipment - self.c24 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c241 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c242 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c243 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c244 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c245 = AnnotatedVariable(float, 0.0, docstring="", units="") - - # Module Variables - self.c21 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c211 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c212 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c213 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c214 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2141 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2142 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c215 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c216 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c217 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2171 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2172 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2173 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2174 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2211 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2212 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22121 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22122 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22123 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22124 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22125 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22126 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22127 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2213 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22131 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22132 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2214 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2215 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2221 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22211 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22212 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22213 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22214 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22215 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2222 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22221 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22222 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22223 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22224 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2223 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c223 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2231 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2232 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2233 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2234 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c224 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2241 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2242 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2243 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2244 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2245 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2246 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c225 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2251 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22511 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22512 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22513 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22514 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22515 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2252 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22521 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22522 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22523 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22524 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22525 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22526 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22527 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c2253 = AnnotatedVariable(float, 0.0, docstring="", units="") - self.chx = AnnotatedVariable(float, 0.0, docstring="", units="") - self.cpp = AnnotatedVariable(float, 0.0, docstring="", units="") - self.cppa = AnnotatedVariable(float, 0.0, docstring="", units="") - self.c22128 = AnnotatedVariable(float, 0.0, docstring="", units="") - - def run(self, output: bool = False): - self.costs(output) - - def costs(self, output: bool): + for names in ( + (f"c226{no}" for no in ("", 1, 2, 3)), # Accnt 226: Heat transport system + (f"c227{no}" for no in ("", 1, 2, 3, 4)), # Accnt 227: Fuel handling + (f"c24{no}" for no in ("", 1, 2, 3, 4, 5)), # Accnt 24: elec equipment + (f"c21{no}" for no in ("", 1, 2, 3, 4, 41, 42, 5, 6, 7, 71, 72, 73, 74)), + ("c22",), + (f"c221{no}" for no in (1, 2, 21, 22, 23, 24, 25, 26, 27, 3, 31, 32, 4, 5)), + (f"c222{no}" for no in (1, 11, 12, 13, 14, 15, 2, 21, 22, 23, 24, 3)), + (f"c223{no}" for no in ("", 1, 2, 3, 4)), + (f"c224{no}" for no in ("", 1, 2, 3, 4, 5, 6)), + ( + f"c225{no}" + for no in ("", 1, 11, 12, 13, 14, 15, 2, 21, 22, 23, 24, 25, 26, 27, 3) + ), + ("chx", "cpp", "cppa", "c22128"), + ): + for i in names: + setattr(self, i, AnnotatedVariable(float, 0.0, docstring="", units="")) + + def run(self): """ Cost accounting for a fusion power plant author: P J Knight, CCFE, Culham Science Centre - outfile : input integer : output file unit - iprint : input integer : switch for writing to output file (1=yes) + This routine performs the cost accounting for a fusion power plant. The direct costs are calculated based on parameters input from other sections of the code. @@ -196,636 +115,736 @@ def costs(self, output: bool): # Cost of electricity if (cost_variables.ireactor == 1) and (cost_variables.ipnet == 0): - self.coelc(output) + self.coelc() - if output and cost_variables.output_costs == 1: + def output(self): + if cost_variables.output_costs == 0: + return - po.oheadr(self.outfile, "Detailed Costings (1990 US$)") - po.ovarre( - self.outfile, - "Acc.22 multiplier for Nth of a kind", - "(fkind)", - cost_variables.fkind, - ) - po.ovarin( - self.outfile, "Level of Safety Assurance", "(lsa)", cost_variables.lsa - ) - po.oblnkl(self.outfile) - po.oshead(self.outfile, "Structures and Site Facilities") - po.ocosts( - self.outfile, - "(c211)", - "Site improvements, facilities, land (M$)", - self.c211, - ) - po.ocosts(self.outfile, "(c212)", "Reactor building cost (M$)", self.c212) - po.ocosts(self.outfile, "(c213)", "Turbine building cost (M$)", self.c213) - po.ocosts( - self.outfile, - "(c2141)", - "Reactor maintenance building cost (M$)", - self.c2141, - ) - po.ocosts(self.outfile, "(c2142)", "Warm shop cost (M$)", self.c2142) - po.ocosts(self.outfile, "(c215)", "Tritium building cost (M$)", self.c215) - po.ocosts( - self.outfile, - "(c216)", - "Electrical equipment building cost (M$)", - self.c216, - ) - po.ocosts( - self.outfile, - "(c2171)", - "Additional buildings cost (M$)", - self.c2171, - ) - po.ocosts( + po.oheadr(self.outfile, "Power Reactor Costs (1990 US$)") + + po.ovarrf( + self.outfile, + "First wall / blanket life (years)", + "(fwbllife)", + fwbs_variables.bktlife, + ) + + if ife_variables.ife != 1: + po.ovarrf( self.outfile, - "(c2172)", - "Control room buildings cost (M$)", - self.c2172, + "Divertor life (years)", + "(divlife.)", + cost_variables.divlife, ) - po.ocosts( + if physics_variables.itart == 1: + po.ovarrf( + self.outfile, + "Centrepost life (years)", + "(cplife.)", + cost_variables.cplife, + ) + + po.ovarrf( + self.outfile, "Cost of electricity (m$/kWh)", "(coe)", cost_variables.coe + ) + + po.osubhd(self.outfile, "Power Generation Costs :") + # TODO: Convert fortran format to Python + # if ((annfwbl != annfwbl) or (annfwbl > 1.0e10) or (annfwbl < 0.0e0)) : + # write(outfile,*)'Problem with annfwbl' + # write(outfile,*)'fwallcst=', fwallcst, ' blkcst=', cost_variables.blkcst + # write(outfile,*)'crffwbl=', crffwbl, ' fcap0cp=', cost_variables.fcap0cp + # write(outfile,*)'feffwbl=', feffwbl, ' fwbllife=', fwbllife + + # write(outfile,200) # anncap,coecap, # annoam,coeoam, # anndecom,coedecom, # annfwbl,coefwbl, # anndiv,coediv, # anncp,coecp, # anncdr,coecdr, # annfuel,coefuel, # annwst,coewst, # annfuelt,coefuelt, # anntot,coe + + # 200 format( # t76,'Annual Costs, M$ COE, m$/kWh'// # 1x,'Capital Investment',t80,f10.2,10x,f10.2/ # 1x,'Operation & Maintenance',t80,f10.2,10x,f10.2/ # 1x,'Decommissioning Fund',t80,f10.2,10x,f10.2/ # 1x,'Fuel Charge Breakdown'// # 5x,'Blanket & first wall',t72,f10.2,10x,f10.2/ # 5x,'Divertors',t72,f10.2,10x,f10.2/ # 5x,'Centrepost (TART only)',t72,f10.2,10x,f10.2/ # 5x,'Auxiliary Heating',t72,f10.2,10x,f10.2/ # 5x,'Actual Fuel',t72,f10.2,10x,f10.2/ # 5x,'Waste Disposal',t72,f10.2,10x,f10.2/ # 1x,'Total Fuel Cost',t80,f10.2,10x,f10.2// # 1x,'Total Cost',t80,f10.2,10x,f10.2 ) + + if cost_variables.ifueltyp == 1: + po.oshead(self.outfile, "Replaceable Components Direct Capital Cost") + po.ovarrf( self.outfile, - "(c2173)", - "Shop and warehouses cost (M$)", - self.c2173, + "First wall direct capital cost (M$)", + "(fwallcst)", + cost_variables.fwallcst, ) - po.ocosts( + po.ovarrf( self.outfile, - "(c2174)", - "Cryogenic building cost (M$)", - self.c2174, + "Blanket direct capital cost (M$)", + "(blkcst)", + cost_variables.blkcst, ) - po.oblnkl(self.outfile) - po.ocosts(self.outfile, "(c21)", "Total account 21 cost (M$)", self.c21) - - po.oshead(self.outfile, "Reactor Systems") - po.ocosts(self.outfile, "(c2211)", "First wall cost (M$)", self.c2211) if ife_variables.ife != 1: - if fwbs_variables.iblanket == 4: - po.ocosts( - self.outfile, - "(c22121)", - "Blanket lithium-lead cost (M$)", - self.c22121, - ) - po.ocosts( - self.outfile, - "(c22122)", - "Blanket lithium cost (M$)", - self.c22122, - ) - else: - po.ocosts( - self.outfile, - "(c22121)", - "Blanket beryllium cost (M$)", - self.c22121, - ) - po.ocosts( + po.ovarrf( + self.outfile, + "Divertor direct capital cost (M$)", + "(divcst)", + cost_variables.divcst, + ) + if physics_variables.itart == 1: + po.ovarrf( self.outfile, - "(c22122)", - "Blanket breeder material cost (M$)", - self.c22122, + "Centrepost direct capital cost (M$)", + "(cpstcst)", + cost_variables.cpstcst, ) - po.ocosts( - self.outfile, - "(c22123)", - "Blanket stainless steel cost (M$)", - self.c22123, - ) - po.ocosts( - self.outfile, - "(c22124)", - "Blanket vanadium cost (M$)", - self.c22124, - ) - else: # IFE - po.ocosts( + po.ovarrf( self.outfile, - "(c22121)", - "Blanket beryllium cost (M$)", - self.c22121, + "Plasma heating/CD system cap cost (M$)", + "", + cost_variables.cdcost + * cost_variables.fcdfuel + / (1.0e0 - cost_variables.fcdfuel), ) - po.ocosts( + po.ovarrf( self.outfile, - "(c22122)", - "Blanket lithium oxide cost (M$)", - self.c22122, + "Fraction of CD cost --> fuel cost", + "(fcdfuel)", + cost_variables.fcdfuel, ) - po.ocosts( + else: + po.ovarrf( self.outfile, - "(c22123)", - "Blanket stainless steel cost (M$)", - self.c22123, + "IFE driver system direct cap cost (M$)", + "", + cost_variables.cdcost + * cost_variables.fcdfuel + / (1.0e0 - cost_variables.fcdfuel), ) - po.ocosts( + po.ovarrf( self.outfile, - "(c22124)", - "Blanket vanadium cost (M$)", - self.c22124, + "Fraction of driver cost --> fuel cost", + "(fcdfuel)", + cost_variables.fcdfuel, ) + + po.oheadr(self.outfile, "Detailed Costings (1990 US$)") + po.ovarre( + self.outfile, + "Acc.22 multiplier for Nth of a kind", + "(fkind)", + cost_variables.fkind, + ) + po.ovarin( + self.outfile, "Level of Safety Assurance", "(lsa)", cost_variables.lsa + ) + po.oblnkl(self.outfile) + po.oshead(self.outfile, "Structures and Site Facilities") + po.ocosts( + self.outfile, + "(c211)", + "Site improvements, facilities, land (M$)", + self.c211, + ) + po.ocosts(self.outfile, "(c212)", "Reactor building cost (M$)", self.c212) + po.ocosts(self.outfile, "(c213)", "Turbine building cost (M$)", self.c213) + po.ocosts( + self.outfile, + "(c2141)", + "Reactor maintenance building cost (M$)", + self.c2141, + ) + po.ocosts(self.outfile, "(c2142)", "Warm shop cost (M$)", self.c2142) + po.ocosts(self.outfile, "(c215)", "Tritium building cost (M$)", self.c215) + po.ocosts( + self.outfile, + "(c216)", + "Electrical equipment building cost (M$)", + self.c216, + ) + po.ocosts( + self.outfile, + "(c2171)", + "Additional buildings cost (M$)", + self.c2171, + ) + po.ocosts( + self.outfile, + "(c2172)", + "Control room buildings cost (M$)", + self.c2172, + ) + po.ocosts( + self.outfile, + "(c2173)", + "Shop and warehouses cost (M$)", + self.c2173, + ) + po.ocosts( + self.outfile, + "(c2174)", + "Cryogenic building cost (M$)", + self.c2174, + ) + po.oblnkl(self.outfile) + po.ocosts(self.outfile, "(c21)", "Total account 21 cost (M$)", self.c21) + + po.oshead(self.outfile, "Reactor Systems") + po.ocosts(self.outfile, "(c2211)", "First wall cost (M$)", self.c2211) + if ife_variables.ife != 1: + if fwbs_variables.iblanket == 4: po.ocosts( self.outfile, - "(c22125)", - "Blanket carbon cloth cost (M$)", - self.c22125, + "(c22121)", + "Blanket lithium-lead cost (M$)", + self.c22121, ) po.ocosts( self.outfile, - "(c22126)", - "Blanket concrete cost (M$)", - self.c22126, + "(c22122)", + "Blanket lithium cost (M$)", + self.c22122, ) + else: po.ocosts( self.outfile, - "(c22127)", - "Blanket FLiBe cost (M$)", - self.c22127, + "(c22121)", + "Blanket beryllium cost (M$)", + self.c22121, ) po.ocosts( self.outfile, - "(c22128)", - "Blanket lithium cost (M$)", - self.c22128, + "(c22122)", + "Blanket breeder material cost (M$)", + self.c22122, ) - po.ocosts(self.outfile, "(c2212)", "Blanket total cost (M$)", self.c2212) - po.ocosts(self.outfile, "(c22131)", "Bulk shield cost (M$)", self.c22131) po.ocosts( self.outfile, - "(c22132)", - "Penetration shielding cost (M$)", - self.c22132, + "(c22123)", + "Blanket stainless steel cost (M$)", + self.c22123, ) - po.ocosts(self.outfile, "(c2213)", "Total shield cost (M$)", self.c2213) po.ocosts( self.outfile, - "(c2214)", - "Total support structure cost (M$)", - self.c2214, + "(c22124)", + "Blanket vanadium cost (M$)", + self.c22124, ) - po.ocosts(self.outfile, "(c2215)", "Divertor cost (M$)", self.c2215) - # TODO: Convert fortran format to Python - # if (cost_variables.ifueltyp == 1) : - # po.oblnkl(self.outfile) - # write(self.outfile,20) - # 20 format(t2, 'First wall, total blanket and divertor direct costs',/, t2,'are zero as they are assumed to be fuel costs.') - # elif (cost_variables.ifueltyp == 2) : - # po.oblnkl(self.outfile) - # write(self.outfile,31) - # 21 format(t2, 'Initial First wall, total blanket and divertor direct costs',/, t2,'are in capital and replacemnet are in cost of electricity') - - po.oblnkl(self.outfile) + else: # IFE po.ocosts( self.outfile, - "(c221)", - "Total account 221 cost (M$)", - cost_variables.c221, + "(c22121)", + "Blanket beryllium cost (M$)", + self.c22121, ) + po.ocosts( + self.outfile, + "(c22122)", + "Blanket lithium oxide cost (M$)", + self.c22122, + ) + po.ocosts( + self.outfile, + "(c22123)", + "Blanket stainless steel cost (M$)", + self.c22123, + ) + po.ocosts( + self.outfile, + "(c22124)", + "Blanket vanadium cost (M$)", + self.c22124, + ) + po.ocosts( + self.outfile, + "(c22125)", + "Blanket carbon cloth cost (M$)", + self.c22125, + ) + po.ocosts( + self.outfile, + "(c22126)", + "Blanket concrete cost (M$)", + self.c22126, + ) + po.ocosts( + self.outfile, + "(c22127)", + "Blanket FLiBe cost (M$)", + self.c22127, + ) + po.ocosts( + self.outfile, + "(c22128)", + "Blanket lithium cost (M$)", + self.c22128, + ) + + po.ocosts(self.outfile, "(c2212)", "Blanket total cost (M$)", self.c2212) + po.ocosts(self.outfile, "(c22131)", "Bulk shield cost (M$)", self.c22131) + po.ocosts( + self.outfile, + "(c22132)", + "Penetration shielding cost (M$)", + self.c22132, + ) + po.ocosts(self.outfile, "(c2213)", "Total shield cost (M$)", self.c2213) + po.ocosts( + self.outfile, + "(c2214)", + "Total support structure cost (M$)", + self.c2214, + ) + po.ocosts(self.outfile, "(c2215)", "Divertor cost (M$)", self.c2215) + # TODO: Convert fortran format to Python + # if (cost_variables.ifueltyp == 1) : + # po.oblnkl(self.outfile) + # write(self.outfile,20) + # 20 format(t2, 'First wall, total blanket and divertor direct costs',/, t2,'are zero as they are assumed to be fuel costs.') + # elif (cost_variables.ifueltyp == 2) : + # po.oblnkl(self.outfile) + # write(self.outfile,31) + # 21 format(t2, 'Initial First wall, total blanket and divertor direct costs',/, t2,'are in capital and replacemnet are in cost of electricity') + + po.oblnkl(self.outfile) + po.ocosts( + self.outfile, + "(c221)", + "Total account 221 cost (M$)", + cost_variables.c221, + ) - if ife_variables.ife != 1: - - po.oshead(self.outfile, "Magnets") - - if tfcoil_variables.i_tf_sup != 1: # Resistive TF coils - if physics_variables.itart == 1: - po.ocosts( - self.outfile, - "(c22211)", - "Centrepost costs (M$)", - self.c22211, - ) - else: - po.ocosts( - self.outfile, - "(c22211)", - "Inboard leg cost (M$)", - self.c22211, - ) + if ife_variables.ife != 1: + po.oshead(self.outfile, "Magnets") - po.ocosts( - self.outfile, - "(c22212)", - "Outboard leg cost (M$)", - self.c22212, - ) - po.ocosts( - self.outfile, - "(c2221)", - "TF magnet assemblies cost (M$)", - self.c2221, - ) - else: # Superconducting TF coils + if tfcoil_variables.i_tf_sup != 1: # Resistive TF coils + if physics_variables.itart == 1: po.ocosts( self.outfile, "(c22211)", - "TF coil conductor cost (M$)", + "Centrepost costs (M$)", self.c22211, ) + else: po.ocosts( self.outfile, - "(c22212)", - "TF coil winding cost (M$)", - self.c22212, - ) - po.ocosts( - self.outfile, - "(c22213)", - "TF coil case cost (M$)", - self.c22213, - ) - po.ocosts( - self.outfile, - "(c22214)", - "TF intercoil structure cost (M$)", - self.c22214, - ) - po.ocosts( - self.outfile, - "(c22215)", - "TF coil gravity support structure (M$)", - self.c22215, - ) - po.ocosts( - self.outfile, - "(c2221)", - "TF magnet assemblies cost (M$)", - self.c2221, + "(c22211)", + "Inboard leg cost (M$)", + self.c22211, ) po.ocosts( self.outfile, - "(c22221)", - "PF coil conductor cost (M$)", - self.c22221, - ) - po.ocosts( - self.outfile, - "(c22222)", - "PF coil winding cost (M$)", - self.c22222, + "(c22212)", + "Outboard leg cost (M$)", + self.c22212, ) po.ocosts( self.outfile, - "(c22223)", - "PF coil case cost (M$)", - self.c22223, + "(c2221)", + "TF magnet assemblies cost (M$)", + self.c2221, ) + else: # Superconducting TF coils po.ocosts( self.outfile, - "(c22224)", - "PF coil support structure cost (M$)", - self.c22224, + "(c22211)", + "TF coil conductor cost (M$)", + self.c22211, ) po.ocosts( self.outfile, - "(c2222)", - "PF magnet assemblies cost (M$)", - self.c2222, + "(c22212)", + "TF coil winding cost (M$)", + self.c22212, ) po.ocosts( self.outfile, - "(c2223)", - "Vacuum vessel assembly cost (M$)", - self.c2223, + "(c22213)", + "TF coil case cost (M$)", + self.c22213, ) - # TODO: Convert fortran format to Python - # if ((physics_variables.itart == 1)and(cost_variables.ifueltyp == 1)) : - # po.oblnkl(self.outfile) - # write(self.outfile,30) - # 30 format(t2, 'Centrepost direct cost is zero, as it ', 'is assumed to be a fuel cost.') - # elif ((physics_variables.itart == 1)and(cost_variables.ifueltyp == 2)) : - # po.oblnkl(self.outfile) - # write(self.outfile,31) - # 31 format(t2, 'Initial centrepost direct cost in included in capital ', 'cost and replacements are assumed to be a fuel cost.') - - po.oblnkl(self.outfile) po.ocosts( self.outfile, - "(c222)", - "Total account 222 cost (M$)", - cost_variables.c222, + "(c22214)", + "TF intercoil structure cost (M$)", + self.c22214, ) - - po.oshead(self.outfile, "Power Injection") - - if ife_variables.ife == 1: po.ocosts( self.outfile, - "(c2231)", - "IFE driver system cost (M$)", - self.c2231, + "(c22215)", + "TF coil gravity support structure (M$)", + self.c22215, ) - else: - po.ocosts(self.outfile, "(c2231)", "ECH system cost (M$)", self.c2231) po.ocosts( self.outfile, - "(c2232)", - "Lower hybrid system cost (M$)", - self.c2232, + "(c2221)", + "TF magnet assemblies cost (M$)", + self.c2221, ) - po.ocosts( - self.outfile, - "(c2233)", - "Neutral beam system cost (M$)", - self.c2233, - ) - - po.oblnkl(self.outfile) - po.ocosts(self.outfile, "(c223)", "Total account 223 cost (M$)", self.c223) - po.oshead(self.outfile, "Vacuum Systems") po.ocosts( self.outfile, - "(c2241)", - "High vacuum pumps cost (M$)", - self.c2241, - ) - po.ocosts(self.outfile, "(c2242)", "Backing pumps cost (M$)", self.c2242) - po.ocosts(self.outfile, "(c2243)", "Vacuum duct cost (M$)", self.c2243) - po.ocosts(self.outfile, "(c2244)", "Valves cost (M$)", self.c2244) - po.ocosts(self.outfile, "(c2245)", "Duct shielding cost (M$)", self.c2245) - po.ocosts(self.outfile, "(c2246)", "Instrumentation cost (M$)", self.c2246) - po.oblnkl(self.outfile) - po.ocosts(self.outfile, "(c224)", "Total account 224 cost (M$)", self.c224) - - if ife_variables.ife != 1: - po.oshead(self.outfile, "Power Conditioning") - po.ocosts( - self.outfile, - "(c22511)", - "TF coil power supplies cost (M$)", - self.c22511, - ) - po.ocosts( - self.outfile, - "(c22512)", - "TF coil breakers cost (M$)", - self.c22512, - ) - po.ocosts( - self.outfile, - "(c22513)", - "TF coil dump resistors cost (M$)", - self.c22513, - ) - po.ocosts( - self.outfile, - "(c22514)", - "TF coil instrumentation and control (M$)", - self.c22514, - ) - po.ocosts( - self.outfile, - "(c22515)", - "TF coil bussing cost (M$)", - self.c22515, - ) - po.ocosts( - self.outfile, - "(c2251)", - "Total, TF coil power costs (M$)", - self.c2251, - ) - po.ocosts( - self.outfile, - "(c22521)", - "PF coil power supplies cost (M$)", - self.c22521, - ) - po.ocosts( - self.outfile, - "(c22522)", - "PF coil instrumentation and control (M$)", - self.c22522, - ) - po.ocosts( - self.outfile, - "(c22523)", - "PF coil bussing cost (M$)", - self.c22523, - ) - po.ocosts( - self.outfile, - "(c22524)", - "PF coil burn power supplies cost (M$)", - self.c22524, - ) - po.ocosts( - self.outfile, - "(c22525)", - "PF coil breakers cost (M$)", - self.c22525, - ) - po.ocosts( - self.outfile, - "(c22526)", - "PF coil dump resistors cost (M$)", - self.c22526, - ) - po.ocosts( - self.outfile, - "(c22527)", - "PF coil ac breakers cost (M$)", - self.c22527, - ) - po.ocosts( - self.outfile, - "(c2252)", - "Total, PF coil power costs (M$)", - self.c2252, - ) - po.ocosts( - self.outfile, - "(c2253)", - "Total, energy storage cost (M$)", - self.c2253, - ) - po.oblnkl(self.outfile) - po.ocosts( - self.outfile, - "(c225)", - "Total account 225 cost (M$)", - self.c225, - ) - - po.oshead(self.outfile, "Heat Transport System") + "(c22221)", + "PF coil conductor cost (M$)", + self.c22221, + ) po.ocosts( self.outfile, - "(cpp)", - "Pumps and piping system cost (M$)", - self.cpp, + "(c22222)", + "PF coil winding cost (M$)", + self.c22222, ) po.ocosts( self.outfile, - "(chx)", - "Primary heat exchanger cost (M$)", - self.chx, + "(c22223)", + "PF coil case cost (M$)", + self.c22223, ) po.ocosts( self.outfile, - "(c2261)", - "Total, reactor cooling system cost (M$)", - self.c2261, + "(c22224)", + "PF coil support structure cost (M$)", + self.c22224, ) - po.ocosts(self.outfile, "(cppa)", "Pumps, piping cost (M$)", self.cppa) po.ocosts( self.outfile, - "(c2262)", - "Total, auxiliary cooling system cost (M$)", - self.c2262, + "(c2222)", + "PF magnet assemblies cost (M$)", + self.c2222, ) po.ocosts( self.outfile, - "(c2263)", - "Total, cryogenic system cost (M$)", - self.c2263, + "(c2223)", + "Vacuum vessel assembly cost (M$)", + self.c2223, ) + # TODO: Convert fortran format to Python + # if ((physics_variables.itart == 1)and(cost_variables.ifueltyp == 1)) : + # po.oblnkl(self.outfile) + # write(self.outfile,30) + # 30 format(t2, 'Centrepost direct cost is zero, as it ', 'is assumed to be a fuel cost.') + # elif ((physics_variables.itart == 1)and(cost_variables.ifueltyp == 2)) : + # po.oblnkl(self.outfile) + # write(self.outfile,31) + # 31 format(t2, 'Initial centrepost direct cost in included in capital ', 'cost and replacements are assumed to be a fuel cost.') + po.oblnkl(self.outfile) - po.ocosts(self.outfile, "(c226)", "Total account 226 cost (M$)", self.c226) + po.ocosts( + self.outfile, + "(c222)", + "Total account 222 cost (M$)", + cost_variables.c222, + ) + + po.oshead(self.outfile, "Power Injection") - po.oshead(self.outfile, "Fuel Handling System") - po.ocosts(self.outfile, "(c2271)", "Fuelling system cost (M$)", self.c2271) + if ife_variables.ife == 1: po.ocosts( self.outfile, - "(c2272)", - "Fuel processing and purification cost (M$)", - self.c2272, + "(c2231)", + "IFE driver system cost (M$)", + self.c2231, ) + else: + po.ocosts(self.outfile, "(c2231)", "ECH system cost (M$)", self.c2231) po.ocosts( self.outfile, - "(c2273)", - "Atmospheric recovery systems cost (M$)", - self.c2273, + "(c2232)", + "Lower hybrid system cost (M$)", + self.c2232, ) po.ocosts( self.outfile, - "(c2274)", - "Nuclear building ventilation cost (M$)", - self.c2274, + "(c2233)", + "Neutral beam system cost (M$)", + self.c2233, ) - po.oblnkl(self.outfile) - po.ocosts(self.outfile, "(c227)", "Total account 227 cost (M$)", self.c227) - po.oshead(self.outfile, "Instrumentation and Control") + po.oblnkl(self.outfile) + po.ocosts(self.outfile, "(c223)", "Total account 223 cost (M$)", self.c223) + + po.oshead(self.outfile, "Vacuum Systems") + po.ocosts( + self.outfile, + "(c2241)", + "High vacuum pumps cost (M$)", + self.c2241, + ) + po.ocosts(self.outfile, "(c2242)", "Backing pumps cost (M$)", self.c2242) + po.ocosts(self.outfile, "(c2243)", "Vacuum duct cost (M$)", self.c2243) + po.ocosts(self.outfile, "(c2244)", "Valves cost (M$)", self.c2244) + po.ocosts(self.outfile, "(c2245)", "Duct shielding cost (M$)", self.c2245) + po.ocosts(self.outfile, "(c2246)", "Instrumentation cost (M$)", self.c2246) + po.oblnkl(self.outfile) + po.ocosts(self.outfile, "(c224)", "Total account 224 cost (M$)", self.c224) + + if ife_variables.ife != 1: + po.oshead(self.outfile, "Power Conditioning") po.ocosts( self.outfile, - "(c228)", - "Instrumentation and control cost (M$)", - self.c228, + "(c22511)", + "TF coil power supplies cost (M$)", + self.c22511, ) - - po.oshead(self.outfile, "Maintenance Equipment") po.ocosts( self.outfile, - "(c229)", - "Maintenance equipment cost (M$)", - self.c229, + "(c22512)", + "TF coil breakers cost (M$)", + self.c22512, ) - - po.oshead(self.outfile, "Total Account 22 Cost") - po.ocosts(self.outfile, "(c22)", "Total account 22 cost (M$)", self.c22) - - po.oshead(self.outfile, "Turbine Plant Equipment") po.ocosts( self.outfile, - "(c23)", - "Turbine plant equipment cost (M$)", - self.c23, + "(c22513)", + "TF coil dump resistors cost (M$)", + self.c22513, ) - - po.oshead(self.outfile, "Electric Plant Equipment") po.ocosts( self.outfile, - "(c241)", - "Switchyard equipment cost (M$)", - self.c241, + "(c22514)", + "TF coil instrumentation and control (M$)", + self.c22514, ) - po.ocosts(self.outfile, "(c242)", "Transformers cost (M$)", self.c242) po.ocosts( self.outfile, - "(c243)", - "Low voltage equipment cost (M$)", - self.c243, + "(c22515)", + "TF coil bussing cost (M$)", + self.c22515, ) po.ocosts( self.outfile, - "(c244)", - "Diesel backup equipment cost (M$)", - self.c244, + "(c2251)", + "Total, TF coil power costs (M$)", + self.c2251, ) po.ocosts( self.outfile, - "(c245)", - "Auxiliary facilities cost (M$)", - self.c245, + "(c22521)", + "PF coil power supplies cost (M$)", + self.c22521, ) - po.oblnkl(self.outfile) - po.ocosts(self.outfile, "(c24)", "Total account 24 cost (M$)", self.c24) - - po.oshead(self.outfile, "Miscellaneous Plant Equipment") po.ocosts( self.outfile, - "(c25)", - "Miscellaneous plant equipment cost (M$)", - self.c25, + "(c22522)", + "PF coil instrumentation and control (M$)", + self.c22522, ) - - po.oshead(self.outfile, "Heat Rejection System") po.ocosts( self.outfile, - "(c26)", - "Heat rejection system cost (M$)", - self.c26, + "(c22523)", + "PF coil bussing cost (M$)", + self.c22523, ) - - po.oshead(self.outfile, "Plant Direct Cost") po.ocosts( - self.outfile, "(cdirt)", "Plant direct cost (M$)", cost_variables.cdirt + self.outfile, + "(c22524)", + "PF coil burn power supplies cost (M$)", + self.c22524, + ) + po.ocosts( + self.outfile, + "(c22525)", + "PF coil breakers cost (M$)", + self.c22525, + ) + po.ocosts( + self.outfile, + "(c22526)", + "PF coil dump resistors cost (M$)", + self.c22526, + ) + po.ocosts( + self.outfile, + "(c22527)", + "PF coil ac breakers cost (M$)", + self.c22527, + ) + po.ocosts( + self.outfile, + "(c2252)", + "Total, PF coil power costs (M$)", + self.c2252, ) - - po.oshead(self.outfile, "Reactor Core Cost") po.ocosts( self.outfile, - "(crctcore)", - "Reactor core cost (M$)", - cost_variables.crctcore, + "(c2253)", + "Total, energy storage cost (M$)", + self.c2253, ) + po.oblnkl(self.outfile) + po.ocosts( + self.outfile, + "(c225)", + "Total account 225 cost (M$)", + self.c225, + ) + + po.oshead(self.outfile, "Heat Transport System") + po.ocosts( + self.outfile, + "(cpp)", + "Pumps and piping system cost (M$)", + self.cpp, + ) + po.ocosts( + self.outfile, + "(chx)", + "Primary heat exchanger cost (M$)", + self.chx, + ) + po.ocosts( + self.outfile, + "(c2261)", + "Total, reactor cooling system cost (M$)", + self.c2261, + ) + po.ocosts(self.outfile, "(cppa)", "Pumps, piping cost (M$)", self.cppa) + po.ocosts( + self.outfile, + "(c2262)", + "Total, auxiliary cooling system cost (M$)", + self.c2262, + ) + po.ocosts( + self.outfile, + "(c2263)", + "Total, cryogenic system cost (M$)", + self.c2263, + ) + po.oblnkl(self.outfile) + po.ocosts(self.outfile, "(c226)", "Total account 226 cost (M$)", self.c226) + + po.oshead(self.outfile, "Fuel Handling System") + po.ocosts(self.outfile, "(c2271)", "Fuelling system cost (M$)", self.c2271) + po.ocosts( + self.outfile, + "(c2272)", + "Fuel processing and purification cost (M$)", + self.c2272, + ) + po.ocosts( + self.outfile, + "(c2273)", + "Atmospheric recovery systems cost (M$)", + self.c2273, + ) + po.ocosts( + self.outfile, + "(c2274)", + "Nuclear building ventilation cost (M$)", + self.c2274, + ) + po.oblnkl(self.outfile) + po.ocosts(self.outfile, "(c227)", "Total account 227 cost (M$)", self.c227) + + po.oshead(self.outfile, "Instrumentation and Control") + po.ocosts( + self.outfile, + "(c228)", + "Instrumentation and control cost (M$)", + self.c228, + ) - po.oshead(self.outfile, "Indirect Cost") - po.ocosts(self.outfile, "(c9)", "Indirect cost (M$)", self.cindrt) + po.oshead(self.outfile, "Maintenance Equipment") + po.ocosts( + self.outfile, + "(c229)", + "Maintenance equipment cost (M$)", + self.c229, + ) + + po.oshead(self.outfile, "Total Account 22 Cost") + po.ocosts(self.outfile, "(c22)", "Total account 22 cost (M$)", self.c22) + + po.oshead(self.outfile, "Turbine Plant Equipment") + po.ocosts( + self.outfile, + "(c23)", + "Turbine plant equipment cost (M$)", + self.c23, + ) - po.oshead(self.outfile, "Total Contingency") - po.ocosts(self.outfile, "(ccont)", "Total contingency (M$)", self.ccont) + po.oshead(self.outfile, "Electric Plant Equipment") + po.ocosts( + self.outfile, + "(c241)", + "Switchyard equipment cost (M$)", + self.c241, + ) + po.ocosts(self.outfile, "(c242)", "Transformers cost (M$)", self.c242) + po.ocosts( + self.outfile, + "(c243)", + "Low voltage equipment cost (M$)", + self.c243, + ) + po.ocosts( + self.outfile, + "(c244)", + "Diesel backup equipment cost (M$)", + self.c244, + ) + po.ocosts( + self.outfile, + "(c245)", + "Auxiliary facilities cost (M$)", + self.c245, + ) + po.oblnkl(self.outfile) + po.ocosts(self.outfile, "(c24)", "Total account 24 cost (M$)", self.c24) + + po.oshead(self.outfile, "Miscellaneous Plant Equipment") + po.ocosts( + self.outfile, + "(c25)", + "Miscellaneous plant equipment cost (M$)", + self.c25, + ) + + po.oshead(self.outfile, "Heat Rejection System") + po.ocosts( + self.outfile, + "(c26)", + "Heat rejection system cost (M$)", + self.c26, + ) + + po.oshead(self.outfile, "Plant Direct Cost") + po.ocosts( + self.outfile, "(cdirt)", "Plant direct cost (M$)", cost_variables.cdirt + ) + + po.oshead(self.outfile, "Reactor Core Cost") + po.ocosts( + self.outfile, + "(crctcore)", + "Reactor core cost (M$)", + cost_variables.crctcore, + ) - po.oshead(self.outfile, "Constructed Cost") + po.oshead(self.outfile, "Indirect Cost") + po.ocosts(self.outfile, "(c9)", "Indirect cost (M$)", self.cindrt) + + po.oshead(self.outfile, "Total Contingency") + po.ocosts(self.outfile, "(ccont)", "Total contingency (M$)", self.ccont) + + po.oshead(self.outfile, "Constructed Cost") + po.ocosts( + self.outfile, + "(concost)", + "Constructed cost (M$)", + cost_variables.concost, + ) + + if cost_variables.ireactor == 1: + po.oshead(self.outfile, "Interest during Construction") po.ocosts( self.outfile, - "(concost)", - "Constructed cost (M$)", - cost_variables.concost, + "(moneyint)", + "Interest during construction (M$)", + cost_variables.moneyint, ) - if cost_variables.ireactor == 1: - po.oshead(self.outfile, "Interest during Construction") - po.ocosts( - self.outfile, - "(moneyint)", - "Interest during construction (M$)", - cost_variables.moneyint, - ) - - po.oshead(self.outfile, "Total Capital Investment") - po.ocosts( - self.outfile, - "(capcost)", - "Total capital investment (M$)", - cost_variables.capcost, - ) + po.oshead(self.outfile, "Total Capital Investment") + po.ocosts( + self.outfile, + "(capcost)", + "Total capital investment (M$)", + cost_variables.capcost, + ) def acc22(self): """ @@ -963,7 +982,6 @@ def acc225(self): if ife_variables.ife == 1: self.c225 = 0.0e0 else: - # Account 225.1 : TF coil power conditioning self.acc2251() @@ -1179,7 +1197,6 @@ def acc2212(self): cmlsa = [0.5000e0, 0.7500e0, 0.8750e0, 1.0000e0] if ife_variables.ife != 1: - # iblanket=4 is used for KIT HCLL model. iblanket<4 are all # HCPB (CCFE, KIT and CCFE + Shimwell TBR calculation). @@ -1208,7 +1225,6 @@ def acc2212(self): self.c22127 = 0.0e0 else: - # IFE blanket; materials present are Li2O, steel, carbon, concrete, # FLiBe and lithium @@ -1398,7 +1414,6 @@ def acc2221(self): cmlsa = [0.6900e0, 0.8450e0, 0.9225e0, 1.0000e0] if tfcoil_variables.i_tf_sup != 1: # Resistive TF coils - # Account 222.1.1 : Inboard TF coil legs self.c22211 = ( @@ -1431,7 +1446,6 @@ def acc2221(self): self.c2221 = self.c22211 + self.c22212 else: # Superconducting TF coils - # Account 222.1.1 : Conductor # Superconductor ($/m) @@ -1563,7 +1577,6 @@ def acc2222(self): self.c22221 = 0.0e0 for i in range(0, npf): - # Superconductor ($/m) if pfcoil_variables.ipfres == 0: costpfsc = ( @@ -1620,7 +1633,6 @@ def acc2222(self): # Central Solenoid if build_variables.iohcl == 1: - # Superconductor ($/m) # Issue #328 Use CS conductor cross-sectional area (m2) if pfcoil_variables.ipfres == 0: @@ -1727,7 +1739,6 @@ def acc223(self): exprf = 1.0e0 if ife_variables.ife != 1: - # Account 223.1 : ECH self.c2231 = ( @@ -1775,7 +1786,6 @@ def acc223(self): self.c2233 = cost_variables.fkind * self.c2233 else: - # IFE driver costs (depends on driver type) # Assume offset linear form for generic and SOMBRERO types, # or one of two offset linear forms for OSIRIS type @@ -2477,9 +2487,7 @@ def acc2253(self): # See F/MPE/MOD/CAG/PROCESS/PULSE/0008 and 0014 if pulse_variables.lpulse == 1: - if pulse_variables.istore == 1: - # Option 1 from ELECTROWATT report # Pulsed Fusion Reactor Study : AEA FUS 205 @@ -2502,7 +2510,6 @@ def acc2253(self): self.c2253 = self.c2253 + 29.0e0 elif pulse_variables.istore == 2: - # Option 2 from ELECTROWATT report # Pulsed Fusion Reactor Study : AEA FUS 205 @@ -2532,7 +2539,6 @@ def acc2253(self): self.c2253 = self.c2253 + 18.0e0 elif pulse_variables.istore == 3: - # Simplistic approach that assumes that a large stainless steel # block acts as the thermal storage medium. No account is taken # of the cost of the piping within the block, etc. @@ -2555,7 +2561,6 @@ def acc2253(self): error_handling.report_error(125) if pulse_variables.istore < 3: - # Scale self.c2253 with net electric power self.c2253 = self.c2253 * heat_transport_variables.pnetelmw / 1200.0e0 @@ -2568,12 +2573,12 @@ def acc2253(self): self.c2253 = cost_variables.fkind * self.c2253 - def coelc(self, iprint): + def coelc(self): """ Routine to calculate the cost of electricity for a fusion power plant author: P J Knight, CCFE, Culham Science Centre outfile : input integer : output file unit - iprint : input integer : switch for writing to output file (1=yes) + This routine performs the calculation of the cost of electricity for a fusion power plant.
Annual costs are in megadollars/year, electricity costs are in
@@ -2663,7 +2668,6 @@ def coelc(self, iprint):
anndiv = 0.0e0
coediv = 0.0e0
else:
-
# Compound interest factor
fefdiv = (1.0e0 + cost_variables.discount_rate) ** cost_variables.divlife
@@ -2694,7 +2698,6 @@ def coelc(self, iprint):
# ===============================
if (physics_variables.itart == 1) and (ife_variables.ife != 1):
-
# Compound interest factor
fefcp = (1.0e0 + cost_variables.discount_rate) ** cost_variables.cplife
@@ -2880,104 +2883,3 @@ def coelc(self, iprint):
+ cost_variables.coeoam
+ coedecom
)
-
- if (iprint == 0) or (cost_variables.output_costs == 0):
- return
-
- # Output section
-
- po.oheadr(self.outfile, "Power Reactor Costs (1990 US$)")
-
- po.ovarrf(
- self.outfile, "First wall / blanket life (years)", "(fwbllife)", fwbllife
- )
-
- if ife_variables.ife != 1:
- po.ovarrf(
- self.outfile,
- "Divertor life (years)",
- "(divlife.)",
- cost_variables.divlife,
- )
- if physics_variables.itart == 1:
- po.ovarrf(
- self.outfile,
- "Centrepost life (years)",
- "(cplife.)",
- cost_variables.cplife,
- )
-
- po.ovarrf(
- self.outfile, "Cost of electricity (m$/kWh)", "(coe)", cost_variables.coe
- )
-
- po.osubhd(self.outfile, "Power Generation Costs :")
- # TODO: Convert fortran format to Python
- # if ((annfwbl != annfwbl) or (annfwbl > 1.0e10) or (annfwbl < 0.0e0)) :
- # write(outfile,*)'Problem with annfwbl'
- # write(outfile,*)'fwallcst=', fwallcst, ' blkcst=', cost_variables.blkcst
- # write(outfile,*)'crffwbl=', crffwbl, ' fcap0cp=', cost_variables.fcap0cp
- # write(outfile,*)'feffwbl=', feffwbl, ' fwbllife=', fwbllife
-
- # write(outfile,200) # anncap,coecap, # annoam,coeoam, # anndecom,coedecom, # annfwbl,coefwbl, # anndiv,coediv, # anncp,coecp, # anncdr,coecdr, # annfuel,coefuel, # annwst,coewst, # annfuelt,coefuelt, # anntot,coe
-
- # 200 format( # t76,'Annual Costs, M$ COE, m$/kWh'// # 1x,'Capital Investment',t80,f10.2,10x,f10.2/ # 1x,'Operation & Maintenance',t80,f10.2,10x,f10.2/ # 1x,'Decommissioning Fund',t80,f10.2,10x,f10.2/ # 1x,'Fuel Charge Breakdown'// # 5x,'Blanket & first wall',t72,f10.2,10x,f10.2/ # 5x,'Divertors',t72,f10.2,10x,f10.2/ # 5x,'Centrepost (TART only)',t72,f10.2,10x,f10.2/ # 5x,'Auxiliary Heating',t72,f10.2,10x,f10.2/ # 5x,'Actual Fuel',t72,f10.2,10x,f10.2/ # 5x,'Waste Disposal',t72,f10.2,10x,f10.2/ # 1x,'Total Fuel Cost',t80,f10.2,10x,f10.2// # 1x,'Total Cost',t80,f10.2,10x,f10.2 )
-
- if cost_variables.ifueltyp == 1:
- po.oshead(self.outfile, "Replaceable Components Direct Capital Cost")
- po.ovarrf(
- self.outfile,
- "First wall direct capital cost (M$)",
- "(fwallcst)",
- cost_variables.fwallcst,
- )
- po.ovarrf(
- self.outfile,
- "Blanket direct capital cost (M$)",
- "(blkcst)",
- cost_variables.blkcst,
- )
- if ife_variables.ife != 1:
- po.ovarrf(
- self.outfile,
- "Divertor direct capital cost (M$)",
- "(divcst)",
- cost_variables.divcst,
- )
- if physics_variables.itart == 1:
- po.ovarrf(
- self.outfile,
- "Centrepost direct capital cost (M$)",
- "(cpstcst)",
- cost_variables.cpstcst,
- )
-
- po.ovarrf(
- self.outfile,
- "Plasma heating/CD system cap cost (M$)",
- "",
- cost_variables.cdcost
- * cost_variables.fcdfuel
- / (1.0e0 - cost_variables.fcdfuel),
- )
- po.ovarrf(
- self.outfile,
- "Fraction of CD cost --> fuel cost",
- "(fcdfuel)",
- cost_variables.fcdfuel,
- )
- else:
- po.ovarrf(
- self.outfile,
- "IFE driver system direct cap cost (M$)",
- "",
- cost_variables.cdcost
- * cost_variables.fcdfuel
- / (1.0e0 - cost_variables.fcdfuel),
- )
- po.ovarrf(
- self.outfile,
- "Fraction of driver cost --> fuel cost",
- "(fcdfuel)",
- cost_variables.fcdfuel,
- )
diff --git a/process/costs_2015.py b/process/costs_2015.py
index 2a47dbc2d3..ce62516a4a 100644
--- a/process/costs_2015.py
+++ b/process/costs_2015.py
@@ -23,7 +23,6 @@ def __init__(self):
self.outfile = constants.nout
# Initialise module variables
- self.ip = AnnotatedVariable(float, 0.0, docstring="", units="")
self.ofile = AnnotatedVariable(float, 0.0, docstring="", units="")
self.total_costs = AnnotatedVariable(float, 0.0, docstring="", units="")
self.mean_electric_output = AnnotatedVariable(
@@ -33,7 +32,6 @@ def __init__(self):
float, 0.0, docstring="", units=""
)
self.maintenance = AnnotatedVariable(float, 0.0, docstring="", units="")
- self.ip = AnnotatedVariable(float, 0.0, docstring="", units="")
self.ofile = AnnotatedVariable(float, 0.0, docstring="", units="")
self.total_costs = AnnotatedVariable(float, 0.0, docstring="", units="")
@@ -85,7 +83,7 @@ def __init__(self):
units="",
)
- def run(self, output: bool):
+ def run(self):
"""
Cost accounting for a fusion power plant
author: J Morris, CCFE, Culham Science Centre
@@ -94,7 +92,6 @@ def run(self, output: bool):
This routine performs the cost accounting for a fusion power plant.
PROCESS Costs Paper (M. Kovari, J. Morris)
"""
- self.ip = int(output)
self.outfile = self.outfile
# ###############################################
@@ -196,14 +193,6 @@ def run(self, output: bool):
return
- # Output costs #
- # ###############
-
- if (self.ip == 0) or (cost_variables.output_costs == 0):
- return
-
- self.write_costs_to_output()
-
def calc_fwbs_costs(self):
"""
Function to calculate the cost of the first wall, blanket and shield
@@ -232,7 +221,7 @@ def calc_fwbs_costs(self):
tail_li6 = feed_li6 * 0.75e0
# Built-in test
- if (self.ip == 1) and (global_variables.run_tests == 1):
+ if global_variables.run_tests == 1:
product_li6 = 0.3
feed_to_product_mass_ratio = (product_li6 - tail_li6) / (
feed_li6 - tail_li6
@@ -383,7 +372,7 @@ def calc_fwbs_costs(self):
for j in range(21, 26):
self.s_cost[26] = self.s_cost[26] + self.s_cost[j]
- def write_costs_to_output(self):
+ def output(self):
"""
Function to output the costs calculations
author: J Morris, CCFE, Culham Science Centre
diff --git a/process/ife.py b/process/ife.py
index 31d9d1cea4..c442f81b71 100644
--- a/process/ife.py
+++ b/process/ife.py
@@ -45,7 +45,8 @@ def run(self, output: bool):
# write to output file
if output:
# Costs
- self.costs.costs(output=True)
+ self.costs.run()
+ self.costs.output()
# Plant availability
self.availability.avail(output=True)
@@ -118,4 +119,4 @@ def run(self, output: bool):
self.availability.avail(output=False)
# Costs
- self.costs.costs(output=False)
+ self.costs.run()
diff --git a/process/main.py b/process/main.py
index daeb38f89c..b282c26afe 100644
--- a/process/main.py
+++ b/process/main.py
@@ -41,6 +41,8 @@
Box file F/MI/PJK/PROCESS and F/PL/PJK/PROCESS (15/01/96 to 24/01/12)
Box file T&M/PKNIGHT/PROCESS (from 24/01/12)
"""
+
+from typing import Protocol
from process import fortran
from process.buildings import Buildings
from process.costs import Costs
@@ -92,7 +94,6 @@
from process.water_use import WaterUse
from process.sctfcoil import Sctfcoil
-from process.fortran import cost_variables
os.environ["PYTHON_PROCESS_ROOT"] = os.path.join(os.path.dirname(__file__))
@@ -545,11 +546,18 @@ def validate_user_model(self):
Ensures that the corresponding model variable in Models is defined
and that any relevant switches are set correctly.
"""
+ # try and get costs model
+ self.models.costs
- if cost_variables.cost_model == 2 and self.models.costs_step is None:
- raise NotImplementedError(
- f"cost_model = {cost_variables.cost_model} and costs_step = {self.models.costs_step}. Please provide cost model or change switch value."
- )
+
+class CostsProtocol(Protocol):
+ """Protocol layout for costs models"""
+
+ def run(self):
+ """Run the model"""
+
+ def output(self):
+ """write model output"""
class Models:
@@ -564,7 +572,7 @@ def __init__(self):
This also initialises module variables in the Fortran for that module.
"""
- self.costs_step = None
+ self._costs_custom = None
self.cs_fatigue = CsFatigue()
self.pfcoil = PFCoil(cs_fatigue=self.cs_fatigue)
self.power = Power()
@@ -579,7 +587,7 @@ def __init__(self):
self.vacuum = Vacuum()
self.water_use = WaterUse()
self.pulse = Pulse()
- self.costs = Costs()
+ self._costs_old = Costs()
self.ife = IFE(availability=self.availability, costs=self.costs)
self.plasma_profile = PlasmaProfile()
self.fw = Fw()
@@ -596,12 +604,29 @@ def __init__(self):
hcpb=self.ccfe_hcpb,
current_drive=self.current_drive,
)
- self.costs_2015 = Costs2015()
+ self._costs_2015 = Costs2015()
self.physics = Physics(
plasma_profile=self.plasma_profile, current_drive=self.current_drive
)
self.dcll = DCLL(blanket_library=self.blanket_library)
+ @property
+ def costs(self) -> CostsProtocol:
+ if fortran.cost_variables.cost_model == 0:
+ return self._costs_old
+ if fortran.cost_variables.cost_model == 1:
+ return self._costs_2015
+ if fortran.cost_variables.cost_model == 2:
+ if self._costs_custom is not None:
+ return self._costs_custom
+ raise ValueError("Custom costs model not initialised")
+ # Probably overkill but makes typing happy
+ raise ValueError("Unknown costs model")
+
+ @costs.setter
+ def costs(self, value: CostsProtocol):
+ self._costs_custom = value
+
def main(args=None):
"""Run Process.
diff --git a/process/output.py b/process/output.py
index 46cdbabd2b..8214e7cc17 100644
--- a/process/output.py
+++ b/process/output.py
@@ -33,14 +33,8 @@ def write(models, outfile):
# ---- | ------
# 0 | 1990 costs model
# 1 | 2015 Kovari model
- # 2 | 2019 STEP model
-
- if ft.cost_variables.cost_model == 0:
- models.costs.run(output=True)
- elif ft.cost_variables.cost_model == 1:
- models.costs_2015.run(output=True)
- elif ft.cost_variables.cost_model == 2:
- models.costs_step.output()
+ # 2 | Custom model
+ models.costs.output()
# Availability model
models.availability.run(output=True)
diff --git a/process/stellarator.py b/process/stellarator.py
index 2cbfa5ade9..263bcf5dfe 100644
--- a/process/stellarator.py
+++ b/process/stellarator.py
@@ -107,7 +107,8 @@ def run(self, output: bool):
"""
if output:
- self.costs.costs(output=True)
+ self.costs.run()
+ self.costs.output()
self.availability.run(output=True)
ph.outplas(self.outfile)
self.stigma()
@@ -154,7 +155,7 @@ def run(self, output: bool):
# TODO: should availability.run be called
# rather than availability.avail?
self.availability.avail(output=False)
- self.costs.costs(output=False)
+ self.costs.run()
if any(numerics.icc == 91):
# This call is comparably time consuming..
From 1131b8f40632ab70cdca5339f14373da8c4525fe Mon Sep 17 00:00:00 2001
From: james <81617086+je-cook@users.noreply.github.com>
Date: Fri, 2 Feb 2024 16:57:31 +0000
Subject: [PATCH 2/5] fix tests
---
process/main.py | 4 ++--
tests/unit/test_costs_1990.py | 44 ++---------------------------------
tests/unit/test_costs_2015.py | 21 +----------------
3 files changed, 5 insertions(+), 64 deletions(-)
diff --git a/process/main.py b/process/main.py
index b282c26afe..f1f532fd25 100644
--- a/process/main.py
+++ b/process/main.py
@@ -573,6 +573,8 @@ def __init__(self):
This also initialises module variables in the Fortran for that module.
"""
self._costs_custom = None
+ self._costs_old = Costs()
+ self._costs_2015 = Costs2015()
self.cs_fatigue = CsFatigue()
self.pfcoil = PFCoil(cs_fatigue=self.cs_fatigue)
self.power = Power()
@@ -587,7 +589,6 @@ def __init__(self):
self.vacuum = Vacuum()
self.water_use = WaterUse()
self.pulse = Pulse()
- self._costs_old = Costs()
self.ife = IFE(availability=self.availability, costs=self.costs)
self.plasma_profile = PlasmaProfile()
self.fw = Fw()
@@ -604,7 +605,6 @@ def __init__(self):
hcpb=self.ccfe_hcpb,
current_drive=self.current_drive,
)
- self._costs_2015 = Costs2015()
self.physics = Physics(
plasma_profile=self.plasma_profile, current_drive=self.current_drive
)
diff --git a/tests/unit/test_costs_1990.py b/tests/unit/test_costs_1990.py
index 30edc9f65a..f3a55ad0d7 100644
--- a/tests/unit/test_costs_1990.py
+++ b/tests/unit/test_costs_1990.py
@@ -1,4 +1,5 @@
"""Unit tests for costs.f90."""
+
from process.fortran import cost_variables
from process.fortran import fwbs_variables as fv
from process.fortran import heat_transport_variables as htv
@@ -706,7 +707,6 @@ def test_acc9(monkeypatch, costs):
class Acc21Param(NamedTuple):
-
shovol: Any = None
triv: Any = None
@@ -992,7 +992,6 @@ def test_acc21(acc21param, monkeypatch, costs):
class Acc2211Param(NamedTuple):
-
fwarea: Any = None
ucblss: Any = None
@@ -1130,7 +1129,6 @@ def test_acc2211(acc2211param, monkeypatch, costs):
class Acc2212Param(NamedTuple):
-
ucblss: Any = None
ucblbreed: Any = None
@@ -1418,7 +1416,6 @@ def test_acc2212(acc2212param, monkeypatch, costs):
class Acc2213Param(NamedTuple):
-
ucpens: Any = None
ucshld: Any = None
@@ -1580,7 +1577,6 @@ def test_acc2213(acc2213param, monkeypatch, costs):
class Acc2214Param(NamedTuple):
-
fkind: Any = None
lsa: Any = None
@@ -1644,7 +1640,6 @@ def test_acc2214(acc2214param, monkeypatch, costs):
class Acc2215Param(NamedTuple):
-
ifueltyp: Any = None
divcst: Any = None
@@ -1726,7 +1721,6 @@ def test_acc2215(acc2215param, monkeypatch, costs):
class Acc2221Param(NamedTuple):
-
uccpclb: Any = None
uccase: Any = None
@@ -1964,7 +1958,6 @@ def test_acc2221(acc2221param, monkeypatch, costs):
class Acc2222Param(NamedTuple):
-
iohcl: Any = None
uccase: Any = None
@@ -2522,7 +2515,6 @@ def test_acc2222(acc2222param, monkeypatch, costs):
class Acc2223Param(NamedTuple):
-
uccryo: Any = None
lsa: Any = None
@@ -2592,7 +2584,6 @@ def test_acc2223(acc2223param, monkeypatch, costs):
class Acc223Param(NamedTuple):
-
ucich: Any = None
fkind: Any = None
@@ -2818,7 +2809,6 @@ def test_acc223(acc223param, monkeypatch, costs):
class Acc224Param(NamedTuple):
-
fkind: Any = None
dlscal: Any = None
@@ -2972,7 +2962,6 @@ def test_acc224(acc224param, monkeypatch, costs):
class Acc2251Param(NamedTuple):
-
uctfsw: Any = None
fkind: Any = None
@@ -3174,7 +3163,6 @@ def test_acc2251(acc2251param, monkeypatch, costs):
class Acc2252Param(NamedTuple):
-
ucpfcb: Any = None
ucpfbk: Any = None
@@ -3376,7 +3364,6 @@ def test_acc2252(acc2252param, monkeypatch, costs):
class Acc2253Param(NamedTuple):
-
ucblss: Any = None
fkind: Any = None
@@ -3476,7 +3463,6 @@ def test_acc2253(acc2253param, monkeypatch, costs):
class Acc226Param(NamedTuple):
-
c226: Any = None
c2261: Any = None
@@ -3540,7 +3526,6 @@ def test_acc226(acc226param, monkeypatch, costs):
class Acc2261Param(NamedTuple):
-
uchts: Any = None
lsa: Any = None
@@ -3676,7 +3661,6 @@ def test_acc2261_rut(acc2261param, monkeypatch, costs):
class Acc2262Param(NamedTuple):
-
lsa: Any = None
fkind: Any = None
@@ -3806,7 +3790,6 @@ def test_acc2262_rut(acc2262param, monkeypatch, costs):
class Acc2263Param(NamedTuple):
-
uccry: Any = None
lsa: Any = None
@@ -3888,7 +3871,6 @@ def test_acc2263_rut(acc2263param, monkeypatch, costs):
class Acc227Param(NamedTuple):
-
c227: Any = None
c2271: Any = None
@@ -3958,7 +3940,6 @@ def test_acc227(acc227param, monkeypatch, costs):
class Acc2271Param(NamedTuple):
-
ucf1: Any = None
fkind: Any = None
@@ -4022,7 +4003,6 @@ def test_acc2271_rut(acc2271param, monkeypatch, costs):
class Acc2272Param(NamedTuple):
-
fkind: Any = None
fburn: Any = None
@@ -4134,7 +4114,6 @@ def test_acc2272_rut(acc2272param, monkeypatch, costs):
class Acc2273Param(NamedTuple):
-
wsvol: Any = None
volrci: Any = None
@@ -4210,7 +4189,6 @@ def test_acc2273_rut(acc2273param, monkeypatch, costs):
class Acc2274Param(NamedTuple):
-
wsvol: Any = None
volrci: Any = None
@@ -4280,7 +4258,6 @@ def test_acc2274_rut(acc2274param, monkeypatch, costs):
class Acc228Param(NamedTuple):
-
uciac: Any = None
fkind: Any = None
@@ -4338,7 +4315,6 @@ def test_acc228_rut(acc228param, monkeypatch, costs):
class Acc229Param(NamedTuple):
-
ucme: Any = None
fkind: Any = None
@@ -4396,7 +4372,6 @@ def test_acc229_rut(acc229param, monkeypatch, costs):
class Acc23Param(NamedTuple):
-
ucturb: Any = None
ireactor: Any = None
@@ -4464,7 +4439,6 @@ def test_acc23_rut(acc23param, monkeypatch, costs):
class Acc24Param(NamedTuple):
-
c24: Any = None
c241: Any = None
@@ -4534,7 +4508,6 @@ def test_acc24(acc24param, monkeypatch, costs):
class Acc241Param(NamedTuple):
-
lsa: Any = None
c24: Any = None
@@ -4586,7 +4559,6 @@ def test_acc241_rut(acc241param, monkeypatch, costs):
class Acc242Param(NamedTuple):
-
lsa: Any = None
pacpmw: Any = None
@@ -4656,7 +4628,6 @@ def test_acc242_rut(acc242param, monkeypatch, costs):
class Acc243Param(NamedTuple):
-
lsa: Any = None
tlvpmw: Any = None
@@ -4714,7 +4685,6 @@ def test_acc243_rut(acc243param, monkeypatch, costs):
class Acc244Param(NamedTuple):
-
lsa: Any = None
c24: Any = None
@@ -4766,7 +4736,6 @@ def test_acc244_rut(acc244param, monkeypatch, costs):
class Acc245Param(NamedTuple):
-
lsa: Any = None
c24: Any = None
@@ -4818,7 +4787,6 @@ def test_acc245_rut(acc245param, monkeypatch, costs):
class Acc25Param(NamedTuple):
-
ucmisc: Any = None
lsa: Any = None
@@ -4870,7 +4838,6 @@ def test_acc25_rut(acc25param, monkeypatch, costs):
class Acc26Param(NamedTuple):
-
ireactor: Any = None
uchrs: Any = None
@@ -4958,7 +4925,6 @@ def test_acc26_rut(acc26param, monkeypatch, costs):
class Acc9Param(NamedTuple):
-
fcontng: Any = None
lsa: Any = None
@@ -5062,7 +5028,6 @@ def test_acc9_rut(acc9param, monkeypatch, costs):
class Acc2253Param(NamedTuple):
-
ucblss: Any = None
fkind: Any = None
@@ -5162,7 +5127,6 @@ def test_acc2253_urt(acc2253param, monkeypatch, costs, initialise_error_module):
class CoelcParam(NamedTuple):
-
fcdfuel: Any = None
uche3: Any = None
@@ -5249,8 +5213,6 @@ class CoelcParam(NamedTuple):
tburn: Any = None
- iprint: Any = None
-
outfile: Any = None
expected_coeoam: Any = None
@@ -5341,7 +5303,6 @@ class CoelcParam(NamedTuple):
fhe3=0,
tcycle=10864.426139387357,
tburn=0,
- iprint=0,
outfile=11,
expected_coeoam=4.4099029328740929e20,
expected_coecap=4.9891775218979061e21,
@@ -5422,7 +5383,6 @@ class CoelcParam(NamedTuple):
fhe3=0,
tcycle=864.42613938735622,
tburn=10230.533336387549,
- iprint=0,
outfile=11,
expected_coeoam=1.2419424614419636,
expected_coecap=15.547404530833255,
@@ -5532,7 +5492,7 @@ def test_coelc(coelcparam, monkeypatch, costs):
monkeypatch.setattr(times_variables, "tburn", coelcparam.tburn)
- costs.coelc(iprint=coelcparam.iprint)
+ costs.coelc()
assert cost_variables.coeoam == pytest.approx(coelcparam.expected_coeoam)
diff --git a/tests/unit/test_costs_2015.py b/tests/unit/test_costs_2015.py
index 0c4235e5d5..9934b94666 100644
--- a/tests/unit/test_costs_2015.py
+++ b/tests/unit/test_costs_2015.py
@@ -1,4 +1,5 @@
"""Unit tests for costs_2015.f90."""
+
import pytest
import numpy
from typing import NamedTuple, Any
@@ -26,7 +27,6 @@ def costs2015():
class CalcBuildingCostsParam(NamedTuple):
-
pwpnb: Any = None
pfrmax: Any = None
@@ -2359,7 +2359,6 @@ def test_calc_building_costs(calcbuildingcostsparam, monkeypatch, costs2015):
class CalcLandCostsParam(NamedTuple):
-
dr_tf_inner_bore: Any = None
dh_tf_inner_bore: Any = None
@@ -4631,7 +4630,6 @@ def test_calc_land_costs(calclandcostsparam, monkeypatch, costs2015):
class CalcTfCoilCostsParam(NamedTuple):
-
n_tf: Any = None
tfleng: Any = None
@@ -6907,7 +6905,6 @@ def test_calc_tf_coil_costs(calctfcoilcostsparam, monkeypatch, costs2015):
class CalcRemoteHandlingCostsParam(NamedTuple):
-
armour_fw_bl_mass: Any = None
cost_factor_rh: Any = None
@@ -6916,8 +6913,6 @@ class CalcRemoteHandlingCostsParam(NamedTuple):
num_rh_systems: Any = None
- ip: Any = None
-
s_kref: Any = None
s_k: Any = None
@@ -6947,7 +6942,6 @@ class CalcRemoteHandlingCostsParam(NamedTuple):
cost_factor_rh=1,
costexp=0.80000000000000004,
num_rh_systems=4,
- ip=0,
s_kref=numpy.array(
numpy.array(
(
@@ -8034,7 +8028,6 @@ class CalcRemoteHandlingCostsParam(NamedTuple):
cost_factor_rh=1,
costexp=0.80000000000000004,
num_rh_systems=4,
- ip=0,
s_kref=numpy.array(
numpy.array(
(
@@ -9149,8 +9142,6 @@ def test_calc_remote_handling_costs(
cost_variables, "num_rh_systems", calcremotehandlingcostsparam.num_rh_systems
)
- monkeypatch.setattr(costs2015, "ip", calcremotehandlingcostsparam.ip)
-
monkeypatch.setattr(costs2015, "s_kref", calcremotehandlingcostsparam.s_kref)
monkeypatch.setattr(costs2015, "s_k", calcremotehandlingcostsparam.s_k)
@@ -9185,7 +9176,6 @@ def test_calc_remote_handling_costs(
class CalcNPlantAndVvCostsParam(NamedTuple):
-
rsldo: Any = None
d_vv_out: Any = None
@@ -11451,7 +11441,6 @@ def test_calc_n_plant_and_vv_costs(calcnplantandvvcostsparam, monkeypatch, costs
class CalcEnergyConversionSystemParam(NamedTuple):
-
pgrossmw: Any = None
cost_factor_bop: Any = None
@@ -13719,7 +13708,6 @@ def test_calc_energy_conversion_system(
class CalcRemainingSubsystemsParam(NamedTuple):
-
pinjmw: Any = None
pdivt: Any = None
@@ -13748,8 +13736,6 @@ class CalcRemainingSubsystemsParam(NamedTuple):
costexp: Any = None
- ip: Any = None
-
s_kref: Any = None
s_k: Any = None
@@ -13789,7 +13775,6 @@ class CalcRemainingSubsystemsParam(NamedTuple):
zdewex=15.118436894660423,
cost_factor_misc=1,
costexp=0.80000000000000004,
- ip=0,
s_kref=numpy.array(
numpy.array(
(
@@ -14886,7 +14871,6 @@ class CalcRemainingSubsystemsParam(NamedTuple):
zdewex=15.165858901796364,
cost_factor_misc=1,
costexp=0.80000000000000004,
- ip=0,
s_kref=numpy.array(
numpy.array(
(
@@ -16033,8 +16017,6 @@ def test_calc_remaining_subsystems(
monkeypatch.setattr(cost_variables, "costexp", calcremainingsubsystemsparam.costexp)
- monkeypatch.setattr(costs2015, "ip", calcremainingsubsystemsparam.ip)
-
monkeypatch.setattr(costs2015, "s_kref", calcremainingsubsystemsparam.s_kref)
monkeypatch.setattr(costs2015, "s_k", calcremainingsubsystemsparam.s_k)
@@ -16069,7 +16051,6 @@ def test_calc_remaining_subsystems(
class ValueFunctionParam(NamedTuple):
-
x: Any = None
expected_v: Any = None
From 18c7bbc0fd0b324272ac84a92f0fc5549d581e8e Mon Sep 17 00:00:00 2001
From: james <81617086+je-cook@users.noreply.github.com>
Date: Mon, 5 Feb 2024 08:28:35 +0000
Subject: [PATCH 3/5] rename and respect cost model is rerun before _every_
output command
---
process/costs_2015.py | 2 +-
process/main.py | 4 ++--
process/output.py | 1 +
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/process/costs_2015.py b/process/costs_2015.py
index ce62516a4a..ccb1a5d47a 100644
--- a/process/costs_2015.py
+++ b/process/costs_2015.py
@@ -173,7 +173,7 @@ def run(self):
if (abs(cost_variables.concost) > 9.99e99) or (
cost_variables.concost != cost_variables.concost
):
- self.write_costs_to_output()
+ self.output()
for i in range(100):
# noqa: E741
diff --git a/process/main.py b/process/main.py
index f1f532fd25..506e5dfb03 100644
--- a/process/main.py
+++ b/process/main.py
@@ -573,7 +573,7 @@ def __init__(self):
This also initialises module variables in the Fortran for that module.
"""
self._costs_custom = None
- self._costs_old = Costs()
+ self._costs_1990 = Costs()
self._costs_2015 = Costs2015()
self.cs_fatigue = CsFatigue()
self.pfcoil = PFCoil(cs_fatigue=self.cs_fatigue)
@@ -613,7 +613,7 @@ def __init__(self):
@property
def costs(self) -> CostsProtocol:
if fortran.cost_variables.cost_model == 0:
- return self._costs_old
+ return self._costs_1990
if fortran.cost_variables.cost_model == 1:
return self._costs_2015
if fortran.cost_variables.cost_model == 2:
diff --git a/process/output.py b/process/output.py
index 8214e7cc17..71f60f9d1a 100644
--- a/process/output.py
+++ b/process/output.py
@@ -34,6 +34,7 @@ def write(models, outfile):
# 0 | 1990 costs model
# 1 | 2015 Kovari model
# 2 | Custom model
+ models.costs.run()
models.costs.output()
# Availability model
From 90b809d209db4fe495cfd3b04674cb11c3867c0f Mon Sep 17 00:00:00 2001
From: james <81617086+je-cook@users.noreply.github.com>
Date: Mon, 5 Feb 2024 08:30:17 +0000
Subject: [PATCH 4/5] WIP injection of model into run, unify SingleRun and
VaryRun run
---
process/main.py | 10 ++++------
tests/unit/test_main.py | 1 +
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/process/main.py b/process/main.py
index 506e5dfb03..51f50e841e 100644
--- a/process/main.py
+++ b/process/main.py
@@ -201,7 +201,7 @@ def run_mode(self):
self.run = VaryRun(self.args.varyiterparamsconfig, self.args.solver)
else:
self.run = SingleRun(self.args.input, self.args.solver)
- self.run.run()
+ self.run.run()
def post_process(self):
"""Perform post-run actions, like plotting the mfile."""
@@ -253,13 +253,11 @@ def __init__(self, config_file, solver="vmcon"):
# Store the absolute path to the config file immediately: various
# dir changes happen in old run_process code
self.config_file = Path(config_file).resolve()
- self.run(solver)
+ self.solver = solver
- def run(self, solver):
+ def run(self):
"""Perform a VaryRun by running multiple SingleRuns.
- :param solver: which solver to use, as specified in solver.py
- :type solver: str
:raises FileNotFoundError: if input file doesn't exist
"""
# The input path for the varied input file
@@ -301,7 +299,7 @@ def run(self, solver):
# TODO Don't do this; remove stop statements from Fortran and
# handle error codes
# Run process on an IN.DAT file
- config.run_process(input_path, solver)
+ config.run_process(input_path, self.solver)
check_input_error(wdir=wdir)
diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py
index c910d61eab..d584f4fc46 100644
--- a/tests/unit/test_main.py
+++ b/tests/unit/test_main.py
@@ -108,6 +108,7 @@ def test_run_mode(process_obj, monkeypatch):
# Mock VaryRun() (don't want it to actually run), then assert run type is
# VaryRun
monkeypatch.setattr(VaryRun, "__init__", mock_init)
+ monkeypatch.setattr(VaryRun, "run", mock_run)
process_obj.run_mode()
assert isinstance(process_obj.run, VaryRun)
From 3e52e95d03fb749c4f50e5849c45ab1522b11f86 Mon Sep 17 00:00:00 2001
From: Jack Foster \n
",
"iscz": "",
- "ishape": "switch for plasma cross-sectional shape calculation:\n\n
",
+ "ishape": "switch for plasma cross-sectional shape calculation:\n\n
",
"istell": "Switch for stellarator option (set via `device.dat`):\n\n
",
"isthtr": "Switch for stellarator auxiliary heating method:\n\n
",
"istore": "Switch for thermal storage method:\n\n
",
@@ -10679,19 +10666,6 @@
"startuppwr": "cost associated with additional HCD system power required on start-up ($)",
"startupratio": "ratio of additional HCD power for start-up to flat-top operational requirements",
"stcl": "clearance above crane to roof (m)",
- "step20": "M$",
- "step21": "M$",
- "step22": "M$",
- "step23": "M$",
- "step24": "M$",
- "step25": "M$",
- "step27": "M$",
- "step91": "M$",
- "step91_per": "Percentage of cdirt used in calculating step91 (3.0D-1 = 30%)",
- "step92": "M$",
- "step92_per": "Percentage of cdirt used in calculating step92 (3.0D-1 = 30%)",
- "step93": "M$",
- "step93_per": "Percentage of cdirt used in calculating step93 (3.0D-1 = 30%)",
"str_cs_con_res": "Residual manufacturing strain in CS superconductor material",
"str_pf_con_res": "Residual manufacturing strain in PF superconductor material",
"str_tf_con_res": "Residual manufacturing strain in TF superconductor material\n If `i_str_wp == 0`, used to compute the critical surface.\n Otherwise, the self-consistent winding pack `str_wp` is used.",
@@ -14376,18 +14350,6 @@
"lb": 0.0,
"ub": 10.0
},
- "step91_per": {
- "lb": 1.0,
- "ub": 100.0
- },
- "step92_per": {
- "lb": 1.0,
- "ub": 100.0
- },
- "step93_per": {
- "lb": 1.0,
- "ub": 100.0
- },
"str_cs_con_res": {
"lb": -0.02,
"ub": 0.02
@@ -17616,9 +17578,6 @@
"discount_rate",
"startupratio",
"startuppwr",
- "step91_per",
- "step92_per",
- "step93_per",
"tlife",
"ucad",
"ucaf",
@@ -17819,24 +17778,6 @@
"cppa",
"c22128"
],
- "costs_step": [
- "pth",
- "ptherm_star",
- "rmajor_star",
- "rminor_star",
- "step20",
- "step21",
- "step22",
- "step23",
- "step24",
- "step25",
- "step27",
- "step91",
- "step92",
- "step93",
- "vfi",
- "vfi_star"
- ],
"current_drive_module": [],
"current_drive_variables": [
"beamwd",
@@ -20794,9 +20735,6 @@
"staff_buildings_h": "real_variable",
"startupratio": "real_variable",
"stcl": "real_variable",
- "step91_per": "real_variable",
- "step92_per": "real_variable",
- "step93_per": "real_variable",
"str_cs_con_res": "real_variable",
"str_pf_con_res": "real_variable",
"str_tf_con_res": "real_variable",
diff --git a/utilities/costs_bar.py b/utilities/costs_bar.py
index ef13702ec0..edb17acacf 100644
--- a/utilities/costs_bar.py
+++ b/utilities/costs_bar.py
@@ -220,126 +220,6 @@ def comp_new():
plt.show()
-def comp_step():
- """
-
- Plot bar chart for the STEP cost model.
- Two plots produced: (1) Breakdown of the direct costs and (2) Direct, indirect, etc.
-
- """
- # Setup figures
- labels = [
- "Site and\n Buildings",
- "Blanket and\n First Wall",
- "Shield",
- "Magnets",
- "Other Reactor\n Equipment",
- "Heat Transfer\n System",
- "Other Reactor\n Plant Equipment",
- "Turbine Plant\n Equipment",
- "Electric Plant\n Equipment",
- "Miscellaneous\n Plant Equipment",
- ]
- labels2 = [
- "Plant Direct\n Cost",
- "Construction Facilities,\n Equipment and\n Services",
- "Engineering and\n Costruction Management\n Services",
- "Other Costs",
- "Interest during\n Construction",
- ]
- index = np.arange(len(labels))
- index2 = np.arange(len(labels2))
- bar_width = 0.7 / len(mfile_list)
- fig, ax = plt.subplots()
- fig2, ax2 = plt.subplots()
-
- # Read cost data
- for id, item in enumerate(mfile_list):
- cost = np.zeros(19)
- cost[0] = item.data["step20"].get_scan(-1) # Land and Rights
- cost[1] = item.data["step21"].get_scan(
- -1
- ) # Building and Site Service Infrastructure
- cost[2] = item.data["step2201"].get_scan(-1) # Reactor Equipment
- cost[3] = item.data["step220101"].get_scan(-1) # Blanket and First Wall
- cost[4] = item.data["step220102"].get_scan(-1) # Shield
- cost[5] = item.data["step22010301"].get_scan(-1) # TF Coils
- cost[6] = item.data["step22010302"].get_scan(-1) # PF Coils
- cost[7] = item.data["step22010303"].get_scan(-1) # Central Solenoid
- cost[8] = item.data["step22010304"].get_scan(-1) # Control Coils
- cost[9] = item.data["step2202"].get_scan(-1) # Heat Transfer System
- cost[10] = item.data["step22"].get_scan(-1) # Reactor Plant Equipment
- cost[11] = item.data["step23"].get_scan(-1) # Turbine Plant Equipment
- cost[12] = item.data["step24"].get_scan(-1) # Electric Plant Equipment
- cost[13] = item.data["step25"].get_scan(-1) # Miscellaneous Plant Equipment
- cost[14] = item.data["cdirt"].get_scan(-1) # Plant Direct Cost
- cost[15] = item.data["step91"].get_scan(
- -1
- ) # Construction Facilities, Equipment and Services
- cost[16] = item.data["step92"].get_scan(
- -1
- ) # Engineering and Costruction Management Services
- cost[17] = item.data["step93"].get_scan(-1) # Other Costs
- cost[18] = item.data["moneyint"].get_scan(-1) # Interest during Construction
-
- # Explain why moneyint is missing
- if "moneyint" not in item.data.keys():
- print(
- "Interest during construction (moneyint) is only calculated for ireactor = 1"
- )
-
- # Inflate costs using value parsed if specified
- if args.inf:
- cost = inflate * cost
-
- # Simplify grouping
- sizes = [
- cost[0] + cost[1],
- cost[3],
- cost[4],
- cost[5] + cost[6] + cost[7] + cost[8],
- cost[2] - cost[3] - cost[4] - cost[5] - cost[6] - cost[7] - cost[8],
- cost[9],
- cost[10] - cost[2] - cost[9],
- cost[11],
- cost[12],
- cost[13],
- ]
-
- # Direct, indirect costs etc. for second plot
- sizes2 = [cost[14], cost[15], cost[16], cost[17], cost[18]]
-
- # Plot bar charts
- ax.bar(index + id * bar_width, sizes, bar_width, label=args.f[id])
- ax2.bar(index2 + id * bar_width, sizes2, bar_width, label=args.f[id])
-
- # Plot labels
- ax.set_xticks(index + (len(mfile_list) - 1) * 0.5 * bar_width)
- ax2.set_xticks(index2 + (len(mfile_list) - 1) * 0.5 * bar_width)
- ax.set_xticklabels(labels, rotation=90)
- ax2.set_xticklabels(labels2, rotation=90)
- ax.legend()
- ax2.legend()
-
- # Adjust axis label depending on if inflation factor is used
- if args.inf:
- ax.set_ylabel("%.2f x (1980 M$)" % inflate)
- ax2.set_ylabel("%.2f x (1980 M$)" % inflate)
- else:
- ax.set_ylabel("1980 M$")
- ax2.set_ylabel("1980 M$")
-
- fig.tight_layout()
- fig2.tight_layout()
-
- # Save plots if option selected
- if args.save:
- fig.savefig("direct_cost_bar.pdf")
- fig2.savefig("cost_bar.pdf")
-
- plt.show()
-
-
# Main code
if __name__ == "__main__":
# Setup command line arguments
@@ -385,13 +265,5 @@ def comp_step():
comp_new()
- elif "step20" in mfile_list[0].data.keys():
- # Check all MFILEs use new cost model
- for item in mfile_list:
- if "step20" not in item.data.keys():
- sys.exit("ERROR: Inconsistent cost models used between MFILEs!")
-
- comp_step()
-
else:
print("ERROR: Failed to identify cost data, check MFILE!")
diff --git a/utilities/costs_pie.py b/utilities/costs_pie.py
index 3984ccaa53..994b103d06 100644
--- a/utilities/costs_pie.py
+++ b/utilities/costs_pie.py
@@ -186,106 +186,6 @@ def new_cost_model():
plt.show()
-def step_cost_model():
- """
-
- Plot pie chart for the STEP cost model.
- Two plots produced: (1) Breakdown of the direct costs and (2) Direct, indirect, etc.
-
- """
- # Read Cost Values
- step20 = m_file.data["step20"].get_scan(-1) # Land and Rights
- step21 = m_file.data["step21"].get_scan(
- -1
- ) # Building and Site Service Infrastructure
- step2201 = m_file.data["step2201"].get_scan(-1) # Reactor Equipment
- step220101 = m_file.data["step220101"].get_scan(-1) # Blanket and First Wall
- step220102 = m_file.data["step220102"].get_scan(-1) # Shield
- step22010301 = m_file.data["step22010301"].get_scan(-1) # TF Coils
- step22010302 = m_file.data["step22010302"].get_scan(-1) # PF Coils
- step22010303 = m_file.data["step22010303"].get_scan(-1) # Central Solenoid
- step22010304 = m_file.data["step22010304"].get_scan(-1) # Control Coils
- step220103 = step22010301 + step22010302 + step22010303 + step22010304 # Magnets
- step2202 = m_file.data["step2202"].get_scan(-1) # Heat Transfer System
- step22 = m_file.data["step22"].get_scan(-1) # Reactor Plant Equipment
- step23 = m_file.data["step23"].get_scan(-1) # Turbine Plant Equipment
- step24 = m_file.data["step24"].get_scan(-1) # Electric Plant Equipment
- step25 = m_file.data["step25"].get_scan(-1) # Miscellaneous Plant Equipment
-
- cdirt = m_file.data["cdirt"].get_scan(-1) # Plant Direct Cost
- step91 = m_file.data["step91"].get_scan(
- -1
- ) # Construction Facilities, Equipment and Services
- step92 = m_file.data["step92"].get_scan(
- -1
- ) # Engineering and Costruction Management Services
- step93 = m_file.data["step93"].get_scan(-1) # Other Costs
-
- # Interest during construction is linked to ireactor = 1
- if "moneyint" in m_file.data.keys():
- moneyint = m_file.data["moneyint"].get_scan(-1) # Interest during Construction
- labels2 = [
- "Plant Direct Cost",
- "Construction Facilities,\n Equipment and\n Services",
- "Engineering and\n Costruction Management\n Services",
- "Other Costs",
- "Interest during Construction",
- ]
- sizes2 = [cdirt, step91, step92, step93, moneyint]
- else:
- labels2 = [
- "Plant Direct Cost",
- "Construction Facilities,\n Equipment and\n Services",
- "Engineering and\n Costruction Management\n Services",
- "Other Costs",
- ]
- sizes2 = [cdirt, step91, step92, step93]
-
- # Direct Cost Breakdown
- labels = [
- "Site and Buildings",
- "Blanket and First Wall",
- "Shield",
- "Magnets",
- "Other Reactor Equipment",
- "Heat Transfer System",
- "Other Reactor Plant Equipment",
- "Turbine Plant Equipment",
- "Electric Plant Equipment",
- "Miscellaneous Plant Equipment",
- ]
-
- sizes = [
- step20 + step21,
- step220101,
- step220102,
- step220103,
- step2201 - step220101 - step220102 - step220103,
- step2202,
- step22 - step2201 - step2202,
- step23,
- step24,
- step25,
- ]
-
- # Setup figures
- # Plot direct cost items
- fig1, ax1 = plt.subplots(figsize=(9, 5))
- ax1.pie(sizes, labels=labels, autopct="%1.1f%%")
- ax1.axis("equal") # Equal aspect ratio ensures that pie is drawn as a circle.
-
- # Plot overall breakdown
- fig2, ax2 = plt.subplots(figsize=(8, 5))
- ax2.pie(sizes2, labels=labels2, autopct="%1.1f%%")
- ax2.axis("equal") # Equal aspect ratio ensures that pie is drawn as a circle.
-
- # Save figures if option selected
- if args.save:
- fig1.savefig("direct_cost_pie.pdf")
- fig2.savefig("cost_pie.pdf")
- plt.show()
-
-
# Main code
if __name__ == "__main__":
# Setup command line arguments
@@ -313,7 +213,5 @@ def step_cost_model():
orig_cost_model()
elif "s01" in m_file.data.keys():
new_cost_model()
- elif "step20" in m_file.data.keys():
- step_cost_model()
else:
print("ERROR: Cannot identify cost data, check MFILE!")