Skip to content

Commit

Permalink
Supercritical co2 example (#69)
Browse files Browse the repository at this point in the history
* Updated the HDA example exercise and solution

* Adding supercritical CO2 example

* Encorporated changes

* Cleaned up pdf plots and filenames

* Removed HDA examples

* Revert "Updated the HDA example exercise and solution"

This reverts commit 87fa04d.

* Revert "Removed HDA examples"

This reverts commit 9a62890.

* Trying with replacing files from latest clone.

* Revert "Trying with replacing files from latest clone."

This reverts commit 33909f8.

* Changing HDA files to forked version

* New notebook SCO2_alamo_surrogate in directory docs/surrogates/alamo

* New notebook supercritical_CO2_flowsheet in directory docs/surrogates/alamo

* New notebook supercritical_CO2_surrogate in directory docs/surrogates/alamo

* New notebook supercritical_CO2_surrogate in directory docs/surrogates/omlt

* New notebook supercritical_CO2_surrogate in directory docs/surrogates/pysmo

* Incorporate review suggestions

* Add new notebooks to TOC

* Missed some references, add those as links

* Missed file endings in _toc file

* Add files generated by build and run tests

* Fix test failures from misnamed references to StateBlock

* Fix test failure by improving heater initializations

* Force check-in missing saved model files

* Skip notebooks requiring ALAMO

* Fix indent

* Fix typos

* Try using actual notebooks from only ones that call training

* updated _toc.yml

* Skipping ALAMO files for testing

* Resolving conflict in _toc.yml

* Skipping using paths-ignore

* Resolving _toc conflict

* Fixed typo in _toc

* fixed paths in _toc

* Reverting to previous version of _ toc

* Reverting to previous core.yml

* Skipping ALAMO files

* Updating core.yml

* Trying to resolve test failure

* Updating the _toc.yml

* Skipping files with -k flag

* Updating the _toc.yml

* Trying with ignore blob

* Adding metadata

* Fixing .pb file

* Adding .gitattributes

* Create .gitattributes

* Removing .txt file

* Cleaning the comments

* Adding the changes

* Fixing notebook name

* fixing image path

* Fixing path for image

* Fixing path in all notebooks

* Fixing surrogate paths for pysmo

* Trying to fix path

* fixing paths

* fixing paths

* Reorganizing the files

* fixing paths

* Attempting to fix paths

* fixing pysmo path

* fixing path

* adding dummy file to add folder

* Adding sco2_keras_surr folder

* Adding pysmo_poly_surrogate.json

* fixing omlt path

* Adding files to sco2_keras_surr

* fixing paths

* Create dummy_file

* Adding variables folder

* fixing reference paths

* fixing reference paths

* adding changes

* clean up

---------

Co-authored-by: JavalVyas2000 <[email protected]>
Co-authored-by: Brandon Paul <[email protected]>
Co-authored-by: Brandon Paul <[email protected]>
Co-authored-by: Ludovico Bianchi <[email protected]>
  • Loading branch information
5 people authored Feb 19, 2024
1 parent 3ceb3ba commit 104e3cb
Show file tree
Hide file tree
Showing 65 changed files with 28,743 additions and 3 deletions.
10 changes: 10 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -text: do not apply line ending normalization
# -merge: do not try to merge
# `binary` can also be used corresponding to `-text -merge -diff`
variables.data-* -text -merge
variables.index -text -merge
*.pb -text -merge
*.pkl -text -merge
*.srw -text -merge
*.npy -text -merge
*.png -text -merge
2 changes: 1 addition & 1 deletion .github/workflows/core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ jobs:
run: |
pwd
ls idaes_examples
pytest -v idaes_examples
pytest -v idaes_examples --ignore=idaes_examples/notebooks/docs/surrogates/sco2/alamo/
- name: Upload pytest-xdist worker logs
if: success() || failure()
uses: actions/upload-artifact@v3
Expand Down
18 changes: 16 additions & 2 deletions idaes_examples/notebooks/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ parts:
- file: docs/surrogates/omlt/index
sections:
- file: docs/surrogates/omlt/keras_flowsheet_optimization_doc
- file: docs/surrogates/sco2/alamo/index
sections:
- file: docs/surrogates/sco2/alamo/alamo_training_doc
- file: docs/surrogates/sco2/alamo/surrogate_embedding_doc
- file: docs/surrogates/sco2/alamo/flowsheet_optimization_doc
- file: docs/surrogates/sco2/omlt/index
sections:
- file: docs/surrogates/sco2/omlt/keras_training_doc
- file: docs/surrogates/sco2/omlt/surrogate_embedding_doc
- file: docs/surrogates/sco2/omlt/flowsheet_optimization_doc
- file: docs/surrogates/sco2/pysmo/index
sections:
- file: docs/surrogates/sco2/pysmo/pysmo_training_doc
- file: docs/surrogates/sco2/pysmo/surrogate_embedding_doc
- file: docs/surrogates/sco2/pysmo/flowsheet_optimization_doc
- caption: Power generation
chapters:
- file: docs/power_gen/supercritical/index
Expand All @@ -98,5 +113,4 @@ parts:
# Moved this one to 'held'
# - file: active/power_gen/ngcc/ngcc_soec_doc
- file: active/power_gen/ngcc/ngcc_doc
root: index

root: index
501 changes: 501 additions & 0 deletions idaes_examples/notebooks/docs/surrogates/sco2/500_Points_DataSet.csv

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
Empty file.
94 changes: 94 additions & 0 deletions idaes_examples/notebooks/docs/surrogates/sco2/alamo/alamo_run.trc

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"surrogate": {"CO2SM_CO2_Enthalpy": " CO2SM_CO2_Enthalpy == 142.00232605043254352495 * CO2SM_Temperature + 2.5280649736985938424993 * CO2SM_Pressure**2 - 0.13788428202598035365867 * CO2SM_Temperature**2 + 0.66186633129257225506559E-004 * CO2SM_Temperature**3 - 114667.63130721540073864 * CO2SM_Pressure/CO2SM_Temperature - 428949.09007398976245895", "CO2SM_CO2_Entropy": " CO2SM_CO2_Entropy == - 3.9179528198356607937569 * CO2SM_Pressure + 0.51570723686001085361852 * CO2SM_Temperature + 0.17222545182333473534619 * CO2SM_Pressure**2 - 0.55969916790357242958320E-003 * CO2SM_Temperature**2 - 0.21077870265129327632947E-002 * CO2SM_Pressure**3 + 0.24061231665087056461711E-006 * CO2SM_Temperature**3 - 0.10420555302271612869991E-002 * CO2SM_Pressure*CO2SM_Temperature - 363.27314562306145262482 * CO2SM_Pressure/CO2SM_Temperature - 0.20456756625658267800816 * CO2SM_Temperature/CO2SM_Pressure - 116.67325766759245198045"}, "input_labels": ["CO2SM_Pressure", "CO2SM_Temperature"], "output_labels": ["CO2SM_CO2_Enthalpy", "CO2SM_CO2_Entropy"], "input_bounds": {"CO2SM_Pressure": [7.460891, 34.993814], "CO2SM_Temperature": [306.215965, 999.971989]}}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
###############################################################################
# The Institute for the Design of Advanced Energy Systems Integrated Platform
# Framework (IDAES IP) was produced under the DOE Institute for the
# Design of Advanced Energy Systems (IDAES).
#
# Copyright (c) 2018-2023 by the software owners: The Regents of the
# University of California, through Lawrence Berkeley National Laboratory,
# National Technology & Engineering Solutions of Sandia, LLC, Carnegie Mellon
# University, West Virginia University Research Corporation, et al.
# All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md
# for full copyright and license information.
###############################################################################

'''
Maintainer: Javal Vyas
Author: Javal Vyas
Updated: 2024-01-24
'''

"""
SCO2 baseline cycle from the NETL baseline report
Case Baseline620 - Turbine inlet temperature 893.15 K (620 C).
Case Basleine760 - Turbine inlet temperature 1033.15 K (760 C).
"""
from pyomo.environ import (ConcreteModel,
Block,
Var,
Param,
Constraint,
SolverFactory,
TransformationFactory, TerminationCondition,
value, Expression, minimize, units)
from pyomo.network import Arc, SequentialDecomposition

# Import IDAES libraries
from idaes.core import FlowsheetBlock, UnitModelBlockData
from idaes.models.unit_models import (Mixer, MomentumMixingType,
PressureChanger, Heater,
Separator, HeatExchanger)
from idaes.models.unit_models.pressure_changer import ThermodynamicAssumption
from idaes.core.util.model_statistics import degrees_of_freedom
from idaes.core.util.initialization import propagate_state
from properties import SCO2ParameterBlock
import idaes.logger as idaeslog

def main():
# Setup solver and options
solver = SolverFactory('ipopt')
outlvl = 0
tee = True

# Set up concrete model
m = ConcreteModel()

# Create a flowsheet block
m.fs = FlowsheetBlock(dynamic=False)

# Create the properties param block
m.fs.properties = SCO2ParameterBlock()

# Add unit models to the flowsheet
m.fs.boiler = Heater(dynamic=False,property_package= m.fs.properties,has_pressure_change=True)

m.fs.turbine = PressureChanger(dynamic=False,
property_package= m.fs.properties,
compressor=False,
thermodynamic_assumption=ThermodynamicAssumption.isentropic)

m.fs.HTR_pseudo_shell = Heater(dynamic= False,
property_package= m.fs.properties,
has_pressure_change= True)

m.fs.HTR_pseudo_tube = Heater(dynamic=False,
property_package= m.fs.properties,
has_pressure_change= True)

m.fs.LTR_pseudo_shell = Heater(dynamic= False,
property_package= m.fs.properties,
has_pressure_change=True)

m.fs.LTR_pseudo_tube = Heater(dynamic= False,
property_package= m.fs.properties,
has_pressure_change=True)

m.fs.splitter_1 = Separator(property_package= m.fs.properties,
outlet_list= ["bypass", "to_cooler"])

m.fs.co2_cooler = Heater(dynamic= False,
property_package=m.fs.properties,
has_pressure_change= True)

m.fs.main_compressor = PressureChanger(dynamic= False,
property_package= m.fs.properties,
compressor= True,
thermodynamic_assumption= ThermodynamicAssumption.isentropic)

m.fs.bypass_compressor = PressureChanger(dynamic= False,
property_package= m.fs.properties,
compressor= True,
thermodynamic_assumption= ThermodynamicAssumption.isentropic)

m.fs.splitter_2 = Separator(property_package= m.fs.properties,
ideal_separation= False,
outlet_list= ["to_FG_cooler",
"to_LTR"])

m.fs.FG_cooler = Heater(dynamic= False,
property_package= m.fs.properties,
has_pressure_change= True)

m.fs.mixer = Mixer(property_package= m.fs.properties,
inlet_list=["FG_out", "LTR_out", "bypass"])

# # Connect the flowsheet
m.fs.s01 = Arc(source=m.fs.boiler.outlet,
destination=m.fs.turbine.inlet)
m.fs.s02 = Arc(source=m.fs.turbine.outlet,
destination=m.fs.HTR_pseudo_shell.inlet)
m.fs.s03 = Arc(source=m.fs.HTR_pseudo_shell.outlet,
destination=m.fs.LTR_pseudo_shell.inlet)
m.fs.s04 = Arc(source=m.fs.LTR_pseudo_shell.outlet,
destination=m.fs.splitter_1.inlet)
m.fs.s05 = Arc(source=m.fs.splitter_1.to_cooler,
destination=m.fs.co2_cooler.inlet)
m.fs.s06 = Arc(source=m.fs.splitter_1.bypass,
destination=m.fs.bypass_compressor.inlet)
m.fs.s07 = Arc(source=m.fs.co2_cooler.outlet,
destination=m.fs.main_compressor.inlet)
m.fs.s08 = Arc(source=m.fs.bypass_compressor.outlet,
destination=m.fs.mixer.bypass)
m.fs.s09 = Arc(source=m.fs.main_compressor.outlet,
destination=m.fs.splitter_2.inlet)
m.fs.s10 = Arc(source=m.fs.splitter_2.to_FG_cooler,
destination=m.fs.FG_cooler.inlet)
m.fs.s11 = Arc(source=m.fs.splitter_2.to_LTR,
destination=m.fs.LTR_pseudo_tube.inlet)
m.fs.s12 = Arc(source=m.fs.LTR_pseudo_tube.outlet,
destination=m.fs.mixer.LTR_out)
m.fs.s13 = Arc(source=m.fs.FG_cooler.outlet,
destination=m.fs.mixer.FG_out)
m.fs.s14 = Arc(source=m.fs.mixer.outlet,
destination=m.fs.HTR_pseudo_tube.inlet)

# NETL Baseline
m.fs.boiler.inlet.flow_mol.fix(121.1)
m.fs.boiler.inlet.temperature.fix(685.15)
m.fs.boiler.inlet.pressure.fix(34.51)

m.fs.boiler.outlet.temperature.fix(893.15) # Turbine inlet T = 620 C
m.fs.boiler.deltaP.fix(-0.21)

m.fs.boiler.initialize(outlvl=outlvl)

propagate_state(m.fs.s01)

m.fs.turbine.ratioP.fix(1/3.68)
m.fs.turbine.efficiency_isentropic.fix(0.927)
m.fs.turbine.initialize(outlvl=outlvl)

propagate_state(m.fs.s02)
m.fs.HTR_pseudo_shell.outlet.temperature.fix(489.15)
m.fs.HTR_pseudo_shell.deltaP.fix(-0.07)

m.fs.HTR_pseudo_shell.initialize(outlvl=outlvl)


propagate_state(m.fs.s03)

m.fs.LTR_pseudo_shell.outlet.temperature.fix(354.15)
m.fs.LTR_pseudo_shell.deltaP.fix(-0.07)
m.fs.LTR_pseudo_shell.initialize(outlvl=outlvl)


propagate_state(m.fs.s04)
m.fs.splitter_1.split_fraction[0, "bypass"].fix(0.25)

m.fs.splitter_1.initialize(outlvl=outlvl)

propagate_state(m.fs.s05)
m.fs.co2_cooler.outlet.temperature.fix(308.15)
m.fs.co2_cooler.deltaP.fix(-0.07)
m.fs.co2_cooler.initialize(outlvl=outlvl)


propagate_state(m.fs.s06)
m.fs.bypass_compressor.efficiency_isentropic.fix(0.85)
m.fs.bypass_compressor.ratioP.fix(3.8)
m.fs.bypass_compressor.initialize(outlvl=outlvl)

propagate_state(m.fs.s07)
m.fs.main_compressor.efficiency_isentropic.fix(0.85)
m.fs.main_compressor.ratioP.fix(3.8)
m.fs.main_compressor.initialize(outlvl=outlvl)

propagate_state(m.fs.s09)

m.fs.splitter_2.split_fraction[0, "to_FG_cooler"].fix(0.046)
m.fs.splitter_2.initialize(outlvl=outlvl)

propagate_state(m.fs.s10)
m.fs.FG_cooler.outlet.temperature.fix(483.15)
m.fs.FG_cooler.deltaP.fix(-0.06)
m.fs.FG_cooler.initialize(outlvl=outlvl)


propagate_state(m.fs.s11)

m.fs.LTR_pseudo_tube.deltaP.fix(0)
m.fs.LTR_pseudo_tube.heat_duty[0].\
fix(-value(m.fs.LTR_pseudo_shell.heat_duty[0]))
m.fs.LTR_pseudo_tube.initialize(outlvl=outlvl)

# Add constraint heats of the LTR_pseudo shell and tube
m.fs.LTR_pseudo_tube.heat_duty[0].unfix()
m.fs.c1 = Constraint(expr=m.fs.LTR_pseudo_shell.heat_duty[0] ==
-m.fs.LTR_pseudo_tube.heat_duty[0])

propagate_state(m.fs.s08)
propagate_state(m.fs.s12)
propagate_state(m.fs.s13)

m.fs.mixer.initialize(outlvl=outlvl)

propagate_state(m.fs.s14)

m.fs.HTR_pseudo_tube.heat_duty[0].\
fix(-value(m.fs.HTR_pseudo_shell.heat_duty[0]))
m.fs.HTR_pseudo_tube.deltaP.fix(-0.07)
m.fs.HTR_pseudo_tube.initialize(outlvl=outlvl)

m.fs.HTR_pseudo_tube.heat_duty[0].unfix()
m.fs.c2 = Constraint(expr=m.fs.HTR_pseudo_shell.heat_duty[0] ==
-m.fs.HTR_pseudo_tube.heat_duty[0])

TransformationFactory("network.expand_arcs").apply_to(m.fs)

print("--------------------------------------------------------------------")
print("The degrees of freedom for the flowsheet is ", degrees_of_freedom(m))
print("--------------------------------------------------------------------")

solver.solve(m, tee=tee)

#
from idaes.core.util.units_of_measurement import convert_quantity_to_reporting_units,report_quantity
# Print reports
for i in m.fs.component_objects(Block):
if isinstance(i, UnitModelBlockData):
i.report()

# Converting units for readability
print(-1*value(units.convert(m.fs.turbine.work_mechanical[0],units.kW))\
-1*value(units.convert(m.fs.main_compressor.work_mechanical[0],units.kW))\
-1*value(units.convert(m.fs.bypass_compressor.work_mechanical[0],units.kW)),units.kW)
return m

if __name__ == "__main__":
m = main()

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Supercritical CO2 ALAMO Surrogates
Loading

0 comments on commit 104e3cb

Please sign in to comment.