Supercritical Power Plant Flowsheet Example#

Maintainer: Andrew Lee
Author: John Eslick

1. Introduction#

This example is to demonstrate a supercritical pulverized coal power plant model. The power plant consists of two major sub-systems (or flowsheets), a boiler heat exchanger network and a steam cycle. This jupyter notebook provides the workflow to import the steam cycle flowsheet, import the boiler heat exchanger network, connect and run both the flowsheets, and display the main results.

2. Model Description#

The case study demonstrated here is for a ~620MW gross power output. The process flow diagram is shown in section 3 of this jupyter notebook. Figure 1 shows the boiler heat exchanger network, while, figure 2 shows the steam cycle system.

The streams connecting both the flowsheets are:
  a) The main steam: that connects the boiler attemperator to the throttle valves of the high pressure turbine   b) The cold reheat: that connects the final stage of the high pressure turbine to the boiler reheater
  c) The hot reheat: that connects the boiler reheater to the intermediate pressure turbine
  d) The main feed water: that connects the last feed water heater to the boiler economizer

To get a more detailed description of the power plant flowsheet, review the SCPC_full_plant.py file. For details in terms of specific power plant units (for example dimensions, parameters, and variables), more information can be found at supercritical_steam_cycle.py and boiler_subflowsheet.py.

3. Process Flow Diagram (PFD)#

from IPython.display import SVG, display

display(
    "Boiler subsystem PFD",
    SVG(filename="Boiler_scpc_PFD.svg"),
    "Steam Cycle subsystem PFD",
    SVG(filename="supercritical_steam_cycle.svg"),
)
'Boiler subsystem PFD'
../../../_images/5dd82c79f6aa969c6c6335d4f3aeed4ea81a66a514dc617255541c25b053995a.svg
'Steam Cycle subsystem PFD'
../../../_images/ffa7ad7b99d4bb609ab7442bf5a3c75113cb024844500ca0d004c0296404e941.svg

4. Run power plant model example#

This example runs the main SCPC_full_plant.py script, which, imports two flowsheets (steam cycle and boiler heat exchanger network), builds arcs to connect both flowsheets, and run the full power plant model.

# import SCPC power plant
# initialize steam cycle, initialize boiler heat exchanger network, connect both flowsheets,
# and run SCPC plant.
from idaes.models_extra.power_generation.flowsheets.supercritical_power_plant.SCPC_full_plant import (
    main,
)

m, res = main()
2024-05-09 18:34:33 [ERROR] idaes.core.base.process_block: Failure in build: fs.prop_water
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/core/base/process_block.py", line 41, in _rule_default
    b.build()
  File "/home/docs/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/general_helmholtz/helmholtz_functions.py", line 1441, in build
    raise RuntimeError("Helmholtz EoS external functions not available")
RuntimeError: Helmholtz EoS external functions not available
ERROR: Constructing component 'fs.prop_water' from data=None failed:
        RuntimeError: Helmholtz EoS external functions not available
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[2], line 8
      1 # import SCPC power plant
      2 # initialize steam cycle, initialize boiler heat exchanger network, connect both flowsheets,
      3 # and run SCPC plant.
      4 from idaes.models_extra.power_generation.flowsheets.supercritical_power_plant.SCPC_full_plant import (
      5     main,
      6 )
----> 8 m, res = main()

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models_extra/power_generation/flowsheets/supercritical_power_plant/SCPC_full_plant.py:95, in main()
     93 def main():
     94     # import steam cycle and build concrete model
---> 95     m, solver = import_steam_cycle()
     96     print(degrees_of_freedom(m))
     97     # at this point we have a flowsheet with "steam cycle" that solves
     98     # correctly, with 0 degrees of freedom.
     99 
   (...)
    104     # model "m" has been created a few lines above
    105     # pylint: disable-next=import-outside-toplevel

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models_extra/power_generation/flowsheets/supercritical_power_plant/SCPC_full_plant.py:89, in import_steam_cycle()
     83 def import_steam_cycle():
     84     # build concrete model
     85     # import steam cycle model and initialize flowsheet (only if needed)
     86     # pylint: disable-next=import-outside-toplevel
     87     import idaes.models_extra.power_generation.flowsheets.supercritical_steam_cycle.supercritical_steam_cycle as steam_cycle
---> 89     m, solver = steam_cycle.main()
     90     return m, solver

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models_extra/power_generation/flowsheets/supercritical_steam_cycle/supercritical_steam_cycle.py:980, in main(initialize_from_file, store_initialization)
    971 def main(initialize_from_file=None, store_initialization=None):
    972     """Create and initialize a model and solver
    973 
    974     Args:
   (...)
    978         A tuple of a model and solver
    979     """
--> 980     m = create_model()
    981     _stream_dict(m)
    982     set_model_input(m)

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models_extra/power_generation/flowsheets/supercritical_steam_cycle/supercritical_steam_cycle.py:88, in create_model()
     83 m.fs = FlowsheetBlock(dynamic=False)  # Add steady state flowsheet
     85 # A physical property parameter block for IAPWS-95 with pressure and enthalpy
     86 # (PH) state variables.  Usually pressure and enthalpy state variables are
     87 # more robust especially when the phases are unknown.
---> 88 m.fs.prop_water = iapws95.Iapws95ParameterBlock(
     89     phase_presentation=iapws95.PhaseType.MIX
     90 )
     92 # A physical property parameter block with temperature, pressure and vapor
     93 # fraction (TPx) state variables. There are a few instances where the vapor
     94 # fraction is known and the temperature and pressure state variables are
     95 # preferable.
     96 m.fs.prop_water_tpx = iapws95.Iapws95ParameterBlock(
     97     phase_presentation=iapws95.PhaseType.LG, state_vars=iapws95.StateVars.TPX
     98 )

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py:571, in BlockData.__setattr__(self, name, val)
    566 if name not in self.__dict__:
    567     if isinstance(val, Component):
    568         #
    569         # Pyomo components are added with the add_component method.
    570         #
--> 571         self.add_component(name, val)
    572     else:
    573         #
    574         # Other Python objects are added with the standard __setattr__
    575         # method.
    576         #
    577         super(BlockData, self).__setattr__(name, val)

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py:1129, in BlockData.add_component(self, name, val)
   1121     logger.debug(
   1122         "Constructing %s '%s' on %s from data=%s",
   1123         val.__class__.__name__,
   (...)
   1126         str(data),
   1127     )
   1128 try:
-> 1129     val.construct(data)
   1130 except:
   1131     err = sys.exc_info()[1]

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py:2186, in Block.construct(self, data)
   2184                     obj.construct(data.get(name, None))
   2185         # Trigger the (normal) initialization of the block
-> 2186         self._getitem_when_not_present(_idx)
   2187 finally:
   2188     # We must allow that id(self) may no longer be in
   2189     # _BlockConstruction.data, as _getitem_when_not_present will
   2190     # have already removed the entry for scalar blocks (as the
   2191     # BlockData and the Block component are the same object)
   2192     if data is not None:

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/block.py:2101, in Block._getitem_when_not_present(self, idx)
   2098     data = None
   2100 try:
-> 2101     obj = self._rule(_block, idx)
   2102     # If the user returns a block, transfer over everything
   2103     # they defined into the empty one we created.  We do
   2104     # this inside the try block so that any abstract
   2105     # components declared by the rule have the opportunity
   2106     # to be initialized with data from
   2107     # _BlockConstruction.data as they are transferred over.
   2108     if obj is not _block and isinstance(obj, BlockData):

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/pyomo/core/base/initializer.py:316, in IndexedCallInitializer.__call__(self, parent, idx)
    314     return self._fcn(parent, *idx)
    315 else:
--> 316     return self._fcn(parent, idx)

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/core/base/process_block.py:41, in _rule_default(b, *args)
     35 """
     36 Default rule for ProcessBlock, which calls build(). A different rule can
     37 be specified to add additional build steps, or to not call build at all
     38 using the normal rule argument to ProcessBlock init.
     39 """
     40 try:
---> 41     b.build()
     42 except Exception:
     43     logging.getLogger(__name__).exception(f"Failure in build: {b}")

File ~/checkouts/readthedocs.org/user_builds/idaes-examples/envs/latest/lib/python3.8/site-packages/idaes/models/properties/general_helmholtz/helmholtz_functions.py:1441, in HelmholtzParameterBlockData.build(self)
   1439 """Populate the parameter block"""
   1440 if not self.available():
-> 1441     raise RuntimeError("Helmholtz EoS external functions not available")
   1442 super().build()
   1443 # Check if the specified component is supported

RuntimeError: Helmholtz EoS external functions not available

5. Creating a PFD with results and a stream table#

The steam cycle results can be displayed on the PFD and as a stream table, by running the following cells.

import pkg_resources
import pyomo.environ as pyo
from idaes.models_extra.power_generation.flowsheets.supercritical_steam_cycle import (
    pfd_result,
)
from idaes.core.util.tables import create_stream_table_dataframe

# Create stream results as Pandas dataframe
df = create_stream_table_dataframe(streams=m._streams, orient="index")
# Create a new PFD with simulation results
init_pfd = pkg_resources.resource_string(
    "idaes.models_extra.power_generation.flowsheets.supercritical_steam_cycle",
    "supercritical_steam_cycle.svg",
)
res_pfd = pfd_result(m, df, svg=init_pfd)
# Display PFD with results.
display(SVG(res_pfd))
C:\Users\dkgun\AppData\Local\Temp\ipykernel_35844\2286906919.py:1: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
  import pkg_resources
../../../_images/f7b5e7f8c55e0283ae93187f401fde135a7f5e10b4721045cdc75e823e221998.svg
# Display the stream table.
df
Molar Flow Mass Flow T P Vapor Fraction Molar Enthalpy
Units mole / second kilogram / second kelvin pascal dimensionless joule / mole
COND_01 17282.47115 311.348349 301.579977 3878.882993 0.0 2146.889145
COND_02 17282.47015 311.348331 301.579976 3878.882993 0.0 2146.889125
COND_03 17282.47015 311.348331 301.661032 1003878.882993 0.0 2169.492072
CW01 2500000 45038.17 295.536861 500000 0.0 1700
CW02 2500000.0 45038.17 299.435142 500000.0 0.0 1993.588144
EXHST_BFPT 1546.859656 27.867091 301.579977 3878.882993 0.995438 45787.761725
EXHST_MAIN 15735.611494 283.481258 301.579977 3878.882993 0.966082 44500.759915
EXTR_BFPT_A 1546.859656 27.867091 543.606798 338388.603252 1.0 54195.400951
EXTR_HP4 1862.001605 33.544458 697.961788 8629988.197215 1.0 57580.163942
EXTR_HP7 1286.07555 23.168996 604.326829 4418553.956974 1.0 54662.948278
EXTR_IP10 859.693419 15.487607 543.606798 338388.603252 1.0 54195.400951
EXTR_IP5 807.135567 14.540764 702.023585 1172040.757229 1.0 59876.246946
EXTR_LP10 144.712851 2.607041 335.037184 21754.627463 0.969922 45782.945673
EXTR_LP11 403.947628 7.277225 329.150793 16533.516872 0.959113 45129.193587
EXTR_LP4 273.642832 4.929749 430.323422 112893.801381 1.0 50261.606682
EXTR_LP8 139.830327 2.519081 347.567123 37663.82871 0.992883 47147.58101
FW01A 17282.47015 311.348331 314.29081 1003878.882993 0.0 3119.909089
FW01B 18244.603789 328.681427 315.083398 1003878.882993 0.0 3179.556729
FW02 18244.603789 328.681427 319.712364 1003878.882993 0.0 3527.957688
FW03 18244.603789 328.681427 324.210585 1003878.882993 0.0 3866.605104
FW04 18244.603789 328.681427 333.071657 1003878.882993 0.0 4534.062165
FW05A 23059.50993 415.423251 377.816168 1003878.882993 0.0 7918.042589
FW05B 23059.50993 415.423251 381.030295 25055327.334945 0.0 8482.037139
FW06 23059.50993 415.423251 412.67792 25055327.334945 0.0 10871.356834
FW07 23059.50993 415.423251 442.071525 25055327.334945 0.0 13119.091039
FW08 23059.50993 415.423251 478.52766 25055327.334945 0.0 15965.747919
FWH1_DRN1 962.133639 17.333095 329.150793 16533.516872 0.0 4223.563659
FWH1_DRN2 962.133639 17.333095 329.271314 1216533.516872 0.0 4250.986427
FWH2_DRN 558.186011 10.055871 326.815736 21754.627463 0.0 4047.675227
FWH3_DRN 413.473159 7.44883 336.976168 37663.82871 0.0 4813.885705
FWH4_DRN 273.642832 4.929749 349.497349 112893.801381 0.0 5760.204873
FWH6_DRN 3955.212722 71.254217 449.625486 1172040.757229 0.0 13468.955565
FWH7_DRN 3148.077155 56.713454 517.546178 4418553.956974 0.0 19072.238124
FWH8_DRN 1862.001605 33.544458 553.839275 8629988.197215 0.0 22326.428163
MAKEUP_01 -0.001 -0.000018 306.248085 101325 0.0 2500
RHT_COLD 19911.433775 358.709816 604.326829 4418553.956974 1.0 54662.948278
RHT_HOT 19911.433775 358.709816 896.029914 4059473.408394 1.0 67143.632291
STEAM_LP 16697.745133 300.814354 543.606798 338388.603252 1.0 54195.400951
STEAM_MAIN 23059.51093 415.423269 866.481887 24230000.0 0.0 62710.01
THRTL1 5764.877732 103.855817 863.036545 23161159.682041 0.0 62710.01
THRTL2 5764.877732 103.855817 863.036545 23161159.682041 0.0 62710.01
THRTL3 5764.877732 103.855817 863.036545 23161159.682041 0.0 62710.01
THRTL4 5764.877732 103.855817 863.036545 23161159.682041 0.0 62710.01
condenser_mix_to_condenser 17282.47115 311.348349 301.579977 3878.882993 0.968709 44615.952422