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'
'Steam Cycle subsystem PFD'
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
# 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 |