Institute for the Design of Advanced Energy Systems (IDAES)

Project Goals

The Institute for the Design of Advanced Energy Systems (IDAES) will be the world’s premier resource for the development and analysis of innovative advanced energy systems through the use of process systems engineering tools and approaches. IDAES and its capabilities will be applicable to the development of the full range of advanced fossil energy systems, including chemical looping and other transformational CO2 capture technologies, as well as integration with other new technologies such as supercritical CO2. In addition, the tools and capabilities will be applicable to renewable energy development, such as biofuels, green chemistry, Nuclear and Environmental Management, such as the design of complex, integrated waste treatment facilities.

Collaborating institutions

The IDAES team is comprised of collaborators from the following institutions:

  • National Energy Technology Laboratory (Lead)
  • Sandia National Laboratory
  • Lawrence Berkeley National Laboratory
  • Carnegie-Mellon University (subcontract to LBNL)
  • West Virginia University (subcontract to LBNL)

Contact, contributions and more information

General, background and overview information is available at the IDAES main website. Framework development happens at our GitHub repo where you can report issues/bugs or make contributions. For further enquiries, send an email to: <idaes-support@idaes.org>

Contents

Installation

Minimal installation

To make it easier to use basic functionality and try the IDAES PSE Toolkit, we have compiled these “minimal” instructions, that only allow one to use the free IPOPT solver with MUMPS. This will not be appropriate for some models. We are working on an easy installer with better solvers, but for now you will need to use the full install instructions in the next sections if this is not sufficient for your needs.

Minimal install with IPOPT/MUMPS for Windows

Install Miniconda [2]

  1. Download: https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe
  2. Install anaconda from the downloaded file in (1).
  3. Open the Anaconda powershell (Start -> “Anaconda Powershell Prompt”).
  4. In the Anaconda Powershell, follow the Generic minimal install with IPOPT/MUMPS instructions.
Minimal install with IPOPT/MUMPS for Linux

Install Miniconda [2]

  1. Download: https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
  2. For the next steps, open a terminal window
  3. Run the script you downloaded in (1).
  4. Follow the Generic minimal install with IPOPT/MUMPS instructions.
[2](1, 2) Miniconda is a product from Anaconda that contains their package manager, “Conda” (and not much else). This is the package manager we will use here for setting up the software development environment and installing IDAES’ software (package) dependencies.
Generic minimal install with IPOPT/MUMPS

Once you have Conda installed, the remaining steps, performed in either the Anaconda Powershell (Prompt) or a Linux terminal, are the same.

Isolate the IDAES installation (from other Python packages)

  1. Create an environment with Python = 3.6 or above:

    conda create -n myenv "python>=3.6"
    
  2. Activate the environment you created:

    conda activate myenv
    

Install a git client

  1. Install the git client:

    conda install -c anaconda git
    

Install IPOPT

  1. Install IPOPT from “conda-forge”:

    conda install -c conda-forge ipopt
    
  2. Check if the installation worked by checking for the ipopt version:

    ipopt -v
    

Download IDAES source code and install required packages

  1. Go to the idaes-pse releases page, https://github.com/IDAES/idaes-pse/releases/, and look at the most recent release. Under the section labeled “Assets” there will be a zip file. Download that file and extract the contents in any location of your choice.

  2. In the Linux terminal or Anaconda Powershell, navigate to the folder you created in the previous step.

  3. Install the packages required for IDAES using the following command:

    pip install -r requirements.txt
    

Install IDAES

  1. In the folder where the idaes source code was downloaded, run the setup.py file:

    python setup.py develop
    
  2. Run tests on unit models:

    pytest idaes/unit_models
    
  3. You should see the tests run and all should pass to ensure the installation worked. You can report problems on the Github issues page (Please try to be specific about the command and the offending output.)

  4. Launch the Jupyter Notebook

    1. Navigate to examples and run Jupyter notebook:

      cd examples
      jupyter notebook
      
    2. Open a web browser to the URL that is printed from the previous command.

Linux installation

This section has the instructions for a “full” Linux installation. If you want to just try a few examples and find these instructions difficult to follow, you may try the Minimal install with IPOPT/MUMPS for Linux.

System Requirements

The IDAES toolkit can be installed on Linux, Windows, or MacOSX. The officially supported platform, and the one we use for our automated testing, is Linux. Therefore it is recommended that for maximum stability you use this platform. However we realize many users have Windows or Mac OSX environments. We include best-effort instructions, that we have gotten to work for us, for those platforms as well.

  • Linux operating system
  • Python 3.6 or above (Python 2 is no longer supported)
  • Basic GNU/C compilation tools: make, gcc/g++
  • wget (for downloading software)
  • git (for getting the IDAES source code)
  • Access to the Internet

Things you must know how to do:

  • Get root permissions via sudo.
  • Install packages using the package manager.
Installation steps
sudo apt-get install gcc g++ make libboost-dev

We use a Python packaging system called Conda. Below are instructions for installing a minimal version of Conda, called Miniconda. The full version installs a large number of scientific analysis and visualization libraries that are not required by the IDAES framework.

wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh

Create and activate a conda environment (along with its own copy of pip) for the new IDAES installation (you will need to conda activate idaes when you open a fresh terminal window and wish to use IDAES):

conda create -n idaes pip
conda activate idaes

Obtain the source code for IDAES from GitHub:

git clone https://github.com/IDAES/idaes-pse.git

Download and compile the AMPL Solver Library (ASL) and compile external property functions; this is required for steam properties and cubic equations of state. This step is optional, but highly recommended.

cd <Location to keep the ASL>
wget https://ampl.com/netlib/ampl/solvers.tgz
tar -xf solvers.tgz
cd solvers
./configure
make
export ASL_BUILD=`pwd`/sys.`uname -m`.`uname -s`
cd <IDAES source main directory>
make

Note

If you get an error about funcadd.h not being found, either ASL_BUILD is not set correctly or the ASL did not compile properly.

Install the required Python packages:

pip install -r requirements.txt
python setup.py develop  # or "install"

Install ipopt. If you have an HSL license, you may prefer to compile ipopt with HSL support. Please see the ipopt documentation in that case. Otherwise ipopt can be installed with conda.

conda install -c conda-forge ipopt

At this point, you should be able to launch the Jupyter Notebook server and successfully run examples from the examples folder:

jupyter notebook
Solvers

Some of the model code depends on external solvers. The installation instructions above include the free IPOPT solver. Most of the examples can run with this solver, but a significant number of more advanced problems will not be handled well. Some other solvers you can install that may improve (or make possible) solutions for these models are:

  • CPLEX: a linear optimization package from IBM.
  • Gurobi: LP/MILP/MIQP, etc., solvers from Gurobi.
ASL and AMPL

In some cases, IDAES uses AMPL user-defined functions written in C for property models. Compiling these functions is optional, but some models may not work without them.

The AMPL solver library (ASL) is required, and can be downloaded from from https://ampl.com/netlib/ampl/solvers.tgz. Documentation is available at https://ampl.com/resources/hooking-your-solver-to-ampl/.

Windows Installation

Note

Windows is not officially supported at this time.

This is a complete guide to installing the IDAES framework on Windows. The Extras section includes additional information which may be useful. This guide includes compiling C++ components. In the future precompiled versions of these libraries will be made available, simplifying the installation process.

Tools

Before installing the IDAES software there are a few development tools that need to be installed. There are alternatives, but an attempt was made to provide the easiest path here.

  1. Install a git client from https://git-scm.com/download/win. A git client is not necessary for all users, but if you are a developer or advanced user, you will likely want it.

  2. Install MSYS2. MSYS2 provides a shell which will allow use of Linux style build tools. It also provides a convenient package manager (pacman) which allows for easy installation of build tools.

    1. Go to https://www.msys2.org/

    2. Download the x86_64 installer

    3. Run the installer (the default options should be okay)

    4. Open the MSYS2 MinGW 64-bit terminal (go to: start menu/MSYS2 64Bit/MSYS2 MinGW 64Bit).

    5. Update the MSYS2 software:

      pacman -Syu
      
    6. Repeat the previous step until there are no more updates.

    7. Install the build tools and libraries. Some packages installed are group packages, and pacman will prompt to select which packages you would like to install. Press “enter” for the default, which is all.:

      pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-boost unzip patch make
      
    8. While MinGW does produce Windows native binaries, depending on linking options, some DLLs may be required. Add the MinWG/MSYS2 DLLs to your path. For example if MSYS2 was installed in the default location you would probably want to add C:\msys64\mingw64\bin. See Modifying the Path Environment Variable.

Note

In the MSYS2 terminal the directory structure looks different than the regular Windows directory structure. The Windows C: drive is located at /c.

Install Miniconda
  1. Download Miniconda (https://docs.conda.io/en/latest/miniconda.html)
  2. Run the Miniconda installer (default options should be fine)
Get IDAES

The two main options for getting IDAES are to download the files or to clone the repository. Cloning the repository requires a git client. For core IDAES developers or users who need to track the latest developments and have access to the idaes-dev repo, replace “idaes-pse” with “idaes-dev.”

Option 1: Download from Github

Most users can download the release files from https://github.com/IDAES/idaes-pse/releases. The latest development version can be downloaded by going to https://github.com/IDAES/idaes-pse and clicking the “Clone or Download” button then clicking on “Download Zip.” Unzip the files to a convenient location.

Option 2: Fork and Clone the Repository

For people who are not IDAES core developers but potentially would like to make contributions to the IDAES project or closely follow IDAES development, the best way to get the IDAES files is to fork the IDAES repo on Github, then clone the new fork. To fork the repository sign into your Github account, and go to https://github.com/IDAES/idaes-pse. Then, click the “Fork” button in the upper righthand corner of the page.

To clone a repository:

  1. Open a command window.

  2. Go to the directory where you want to create the local repo.

  3. Enter the command (replace “Github_Account” with the Github account of the fork you wish to clone):

    git clone https://github.com/Githhub_Account/idaes-pse
    
  4. The clone command should create a new idaes-pse subdirectory with a local repository.

IDAES Location

In the instructions that follow idaes_dir will refer to the directory containing the IDAES files.

Compiling ASL

The AMPL Solver Library (ASL) is required to compile some user-defined functions used in parts of the IDAES framework (mainly some property packages).

  1. Open the MSYS2 MinGW 64-bit terminal (go to: start menu/MSYS2 64Bit/MSYS2 MinGW 64Bit).

  2. Create a directory for complied source code in a convenient location, which will be referred to as src in these instructions. For example (obviously change the user name and /c is the location of the C: drive in Windows) mkdir /c/Users/jeslick/src.

  3. Go to the source directory (again replace src with the actual directory):

    cd src
    
  4. Download the ASL and compile the ASL:

    wget https://ampl.com/netlib/ampl/solvers.tgz
    tar -zxvf solvers.tgz
    cd solvers
    ./configure
    make
    
Compiling IDAES AMPL Function Extensions

IDAES uses some additional user defined AMPL functions for various purposes, but mainly for physical properties. Before installing IDAES these functions must be compiled.

  1. Open the MSYS2 MinGW 64-bit terminal.

  2. Set the ASL_BUILD environment variable (the directory may differ depending on the architecture and replace .../src with the actual location of your src directory):

    export ASL_BUILD=/c/.../src/solvers/sys.`uname -m`.`uname -s`
    
  3. Go to the IDAES directory (replace /c/idaes_dir with the location of the IDAES files):

    cd /c/idaes_dir/idaes_pse/
    
  4. Run: make

If the compile finishes without errors you can proceed to installing IDAES.

Install IDAES
  1. Open the Anaconda Command prompt

  2. Create an idaes environment and activate it (optional):

    conda create -n idaes "python>=3.6" pip
    conda activate idaes
    

Note

If you are using a version of conda older than 4.4 the command on Windows to activate a conda environment (for example idaes) is activate idaes.

  1. Install requirements:

    pip install -r requirements.txt
    
  2. Install IDAES:

    python setup.py develop
    
  3. (Optional) Install IPOPT:

    conda install -c conda-forge ipopt
    
Extras
Building Documentation

Most users do not need to build this documentation, but if necessary you can. The instructions here use make from the MSYS2 installed above.

  1. Open the Anaconda Command prompt, and activate the IDAES environment

  2. Go to the IDAES directory

  3. Go to the docs subdirectory

  4. Add the MSYS2 bin directory to your path temporarily. For example, if MSYS2 is installed in the default location:

    set Path=%Path%;C:\msys64\usr\bin
    
  5. Run make (from MSYS2):

    make html
    

The HTML documentation will be in the “build” subdirectory.

Compiling IPOPT

It’s not required to compile IPOPT yourself, and these are pretty much the standard IPOPT compile instructions. If you have set up MSYS2 as above, you should be able to follow these instructions to compile IPOPT for Windows.

  1. Download IPOPT from https://www.coin-or.org/download/source/Ipopt/, and put the zip file in the src directory created above. The Ipopt source is also available from other locations, but source code from other locations may not include the scripts to download third-party libraries.

  2. Open the MSYS2 MinGW 64-bit terminal (go to: start menu/MSYS2 64Bit/MSYS2 MinGW 64Bit).

  3. Unzip Ipopt (the * here represents the portion of the file name with the Ipopt version information):

    unzip Ipopt*.zip
    cd Ipopt*
    
  4. Get third party libraries:

    cd ThirdParty/ASL
    ./get.ASL
    cd ../Blas
    ./get.Blas
    # and so on for all the other subdirectories except HSL.
    
  5. (Optional) Get the HSL source code from https://www.hsl.ac.uk/ipopt. You will need to fill out a request from and be emailed a download link. Extract the files. Depending on how you extract the files there may be an extra directory level. Find the directory containing the HSL files and rename it “coinhsl.” Copy the renamed directory to the HSL subdirectory of the Ipop ThirdParty directory. The results of the configure script below should show that the HSL was found. Refer to the Ipopt documentation if necessary.

  6. Go to the IPOPT directory (replace $IPOPT_DIR with the IPOPT directory):

    cd $IPOPT_DIR
    ./configure
    make
    
  7. The IPOPT AMPL executable will be in ./Ipopt/src/Apps/AmplSolver/ipopt.exe, you can move the executable to a location in the path (environment variable). See Modifying the Path Environment Variable.

Modifying the Path Environment Variable

The Windows Path environment variable provides a search path for executable code and dynamically linked libraries (DLLs). You can temporarily modify the path in a command window session or permanently modify it for the whole system.

Changing Path Via the Control Panel

This method will modify the path for the whole system. Running programs especially open command windows will need to be restarted for this change to take effect.

  1. Any version of Windows

    1. Press the “Windows Key.”
    2. Start to type “Control Panel”
    3. Click on “Control Panel” in the start menu.
    4. Click “System and Security.”
    5. Click “System.”
    6. Click “Advanced system settings.”
    7. Click “Environment Variables.”
  2. In Windows 10

    1. Press the “Windows Key.”
    2. Start to type “Environment”
    3. Click on “Edit the system environment” in the start menu.
    4. Click “Environment Variables.”

Temporary Change in Command Window

This method temporarily changes the path in just the active command window. Once the command window is closed the change will be lost.

Set the Path variable to include any additional directories you want to add to the path. Replace “added_directory” with the directory you want to add:

set Path=%Path%;added_directory

Installation using Docker

One way to install the IDAES PSE Framework is by using the pre-built Docker image.

A Docker image is essentially an embedded instance of Linux (even if you are using Windows or Mac OSX) that has all the code for the IDAES PSE framework pre-installed. You can run commands and Jupyter Notebooks in that image. This section describes how to set up your system, get the Docker image, and interact with it.

Install Docker on your system
  1. Install the community edition (CE) of Docker (website: https://docker.io).

  2. Start the Docker daemon. How to do this will depend on your operating system.

    OS X

    You should install Docker Desktop for Mac. Docker should have been installed to your Applications directory. Browse to it and click on it from there. You will see a small icon in your toolbar that indicates that the daemon is running.

    Linux

    Install Docker using the package manager for your OS. Then start the daemon. If you are using Ubuntu or a Debian-based Linux distro, the Docker daemon will start automatically once Docker is installed. For CentOS, start Docker manually, e.g., run sudo systemctl start docker.

    Windows

    You should install Docker Desktop for Windows. Docker will be started automatically.

Get the IDAES Docker image

You need to get the ready made Docker image containing the source code and solvers for the IDAES PSE framework. This image is available for download at a URL like “https://s3.amazonaws.com/idaes/idaes-pse/idaes-pse-docker-VERSION.tgz”, where VERSION is the release version. See the Releases page on GitHub for information about what is different about each version.

If you want the latest version, simply use the tag “latest” as the version number. Thus, clicking on this link will start a download of the latest version: https://s3.amazonaws.com/idaes/idaes-pse/idaes-pse-docker-latest.tgz.

Load the IDAES Docker image

The image you downloaded needs to be loaded into your local Docker Installation using the Docker load command, which from the command-line looks like this:

docker load < idaes-pse-docker-latest.tgz
Run the IDAES Docker image

To start the Docker image, use a graphical user interface or a console or shell command-line interface.

From the command-line, if you want to start up the Jupyter Notebook server, e.g. to view and run the examples and tutorials, then run this command:

$ docker run -p 8888:8888 -it idaes/idaes_pse
... <debugging output from Jupyter>
...
Copy/paste this URL into your browser when you connect for the first time,
to login with a token:
    http://(305491ce063a or 127.0.0.1):8888/?token=812a290619211bef9177b0e8c0fd7e4d1f673d29909ac254

Copy and paste the URL provided at the end of the output into a browser window and you should get a working Jupyter Notebook. You can browse to the examples directory under /home/idaes/examples and click on the Jupyter Notebooks to open them.

To interact with the image directly from the command-line (console), you can run the following command:

$ docker run -p 8888:8888 -it idaes/idaes_pse /bin/bash
jovyan@10c11ca29008:~$ cd /home/idaes
...

To install the IDAES PSE framework, follow the set of instructions below that are appropriate for your needs and operating system.

If you get stuck, please contact idaes-support@idaes.org.

The minimal installation only installs IDAES and the free IPOPT solver with MUMPS. The full installation is recommended for access to more advanced solvers. The Docker installation works on any platform that supports Docker, but of course requires installation of, and some understanding of, Docker itself to operate.

Type of installation Operating System Section
Minimal IPOPT/MUMPS Linux Minimal install with IPOPT/MUMPS for Linux
  Windows Minimal install with IPOPT/MUMPS for Windows
  Mac OSX not supported [1]
Full Linux Linux installation
  Windows Windows Installation
  Mac OSX not supported [1]
Docker-based Windows, Linux OSX Installation using Docker
[1](1, 2) For advanced users, Mac OSX installation may be performed with some small changes to the Linux installation instructions.

Note

These installation procedures are only fully tested on Debian-based Linux distributions.

IDAES Modeling Standards

Model Formatting and General Standards

The section describes the recommended formatting used within the IDAES framework. Users are strongly encouraged to follow these standards in developing their models in order to improve readability of their code.

Headers and Meta-data

Model developers are encouraged to include some documentation in the header of their model files which provides a brief description of the purpose of the model and how it was developed. Some suggested information to include is:

  • Model name,
  • Model publication date,
  • Model author
  • Any necessary licensing and disclaimer information (see below).
  • Any additional information the modeler feels should be included.
Coding Standard

All code developed as part of IDAES should conform to the PEP-8 standard.

Model Organization

Whilst the overall IDAES modeling framework enforces a hierarchical structure on models, model developers are still encouraged to arrange their models in a logical fashion to aid other users in understanding the model. Model constraints should be grouped with similar constraints, and each grouping of constraints should be clearly commented.

For property packages, it is recommended that all the equations necessary for calculating a given property be grouped together, clearly separated and identified by using comments.

Additionally, model developers are encouraged to consider breaking their model up into a number of smaller methods where this makes sense. This can facilitate modification of the code by allowing future users to inherit from the base model and selectively overload sub-methods where desired.

Commenting

To help other modelers and users understand the how a model works, model builders are strongly encouraged to comment their code. It is suggested that every constraint should be commented with a description of the purpose of the constraint, and if possible/necessary a reference to a source or more detailed explanation. Any deviations from standard units or formatting should be clearly identified here. Any initialization procedures, or other procedures required to get the model to converge should be clearly commented and explained where they appear in the code. Additionally, modelers are strongly encouraged to add additional comments explaining how their model works to aid others in understanding the model.

Units of Measurement and Reference States

Due to the flexibility provided by the IDAES modeling framework, there is no standard set of units of measurement or standard reference state that should be used in models. This places the onus on the user to understand the units of measurement being used within their models and to ensure that they are consistent.

The IDAES developers have generally used SI units without prefixes (i.e. Pa, not kPa) within models developed by the institute, with a default thermodynamic reference state of 298.15 K and 101325 Pa. Supercritical fluids have been consider to be part of the liquid phase, as they will be handled via pumps rather than compressors.

Standard Variable Names

In order for different models to communicate information effectively, it is necessary to have a standard naming convention for any variable that may need to be shared between different models. Within the IDAES modeling framework, this occurs most frequently with information regarding the state and properties of the material within the system, which is calculated in specialized property blocks, and then used in others parts of the model. This section of the documentation discusses the standard naming conventions used within the IDAES modeling framework.

Standard Naming Format

There are a wide range of different variables which may be of interest to modelers, and a number of different ways in which these quantities can be expressed. In order to facilitate communication between different parts of models, a naming convention has been established to standardize the naming of variables across models. Variable names within IDAES follow to the format below:

{property_name}_{basis}_{state}_{condition}

Here, property_name is the name of the quantity in question, and should be drawn from the list of standard variable names given later in this document. If a particular quantity is not included in the list of standard names, users are encouraged to contact the IDAES developers so that it can be included in a future release. This is followed by a number of qualifiers which further indicate the specific conditions under which the quantity is being calculated. These qualifiers are described below, and some examples are given at the end of this document.

Basis Qualifier

Many properties of interest to modelers are most conveniently represented on an intensive basis, that is quantity per unit amount of material. There are a number of different bases that can be used when expressing intensive quantities, and a list of standard basis qualifiers are given below.

Basis Standard Name
Mass Basis mass
Molar Basis mol
Volume Basis vol
State Qualifier

Many quantities can be calculated either for the whole or a part of a mixture. In these cases, a qualifier is added to the quantity to indicate which part of the mixture the quantity applies to. In these cases, quantities may also be indexed by a Pyomo Set.

Basis Standard Name Comments
Component comp Indexed by component list
Phase phase Indexed by phase list
Phase & Component phase_comp Indexed by phase and component list
Total Mixture   No state qualifier
Phase Standard Name
Supercritical Fluid liq
Ionic Species ion
Liquid Phase liq
Solid Phase sol
Vapor Phase vap
Multiple Phases e.g. liq1
Condition Qualifier

There are also cases where a modeler may want to calculate a quantity at some state other than the actual state of the system (e.g. at the critical point, or at equilibrium).

Basis Standard Name
Critical Point crit
Equilibrium State equil
Ideal Gas ideal
Reduced Properties red
Reference State ref
Constants
Constant Standard Name
Gas Constant gas_const
Thermophysical and Transport Properties

Below is a list of all the thermophysical properties which currently have a standard name associated with them in the IDAES framework.

Variable Standard Name
Activity act
Activity Coefficient act_coeff
Bubble Pressure pressure_bubble
Bubble Temperature temperature_bubble
Compressibility Factor compress_fact
Concentration conc
Density dens
Dew Pressure pressure_dew
Dew Temperature temperature_dew
Diffusivity diffus
Diffusion Coefficient (binary) diffus_binary
Enthalpy enth
Entropy entr
Fugacity fug
Fugacity Coefficient fug_coeff
Gibbs Energy energy_gibbs
Heat Capacity (const. P) cp
Heat Capacity (const. V) cv
Heat Capacity Ratio heat_capacity_ratio
Helmholtz Energy energy_helmholtz
Henry’s Constant henry
Mass Fraction mass_frac
Material Flow flow
Molecular Weight mw
Mole Fraction mole_frac
pH pH
Pressure pressure
Speed of Sound speed_sound
Surface Tension surf_tens
Temperature temperature
Thermal Conductivity therm_cond
Vapor Pressure pressure_sat
Viscosity (dynamic) visc_d
Viscosity (kinematic) visc_k
Vapor Fraction vap_frac
Volume Fraction vol_frac
Reaction Properties

Below is a list of all the reaction properties which currently have a standard name associated with them in the IDAES framework.

Variable Standard Name
Activation Energy energy_activation
Arrhenius Coefficient arrhenius
Heat of Reaction dh_rxn
Entropy of Reaction ds_rxn
Equilibrium Constant k_eq
Reaction Rate reaction_rate
Rate constant k_rxn
Solubility Constant k_sol
Solid Properties

Below is a list of all the properties of solid materials which currently have a standard name associated with them in the IDAES framework.

Variable Standard Name
Min. Fluidization Velocity velocity_mf
Min. Fluidization Voidage voidage_mf
Particle Size particle_dia
Pore Size pore_dia
Porosity particle_porosity
Specific Surface Area area_{basis}
Sphericity sphericity
Tortuosity tort
Voidage bulk_voidage
Naming Examples

Below are some examples of the IDAES naming convention in use.

Variable Name Meaning
enth Specific enthalpy of the entire mixture (across all phases)
flow_comp[“H2O”] Total flow of H2O (across all phases)
entr_phase[“liq”] Specific entropy of the liquid phase mixture
conc_phase_comp[“liq”, “H2O”] Concentration of H2O in the liquid phase
temperature_red Reduced temperature
pressure_crit Critical pressure

Core Library

Core Contents

IDAES Framework Configuration

The IDAES framework can be configured with configuration files in TOML format. Supplying a configuration file is optional. Currently this file sets logging configuration and modules that should be searched for plugins. The configuration is done when first importing any idaes.* module. The IDAES framework will first attempt to read a user-level configuration file at %LOCALAPPDATA%\idaes\idaes.conf on Windows or $HOME/.idaes/idaes.conf on other operating systems (e.g. Linux or Mac). Next if an idaes.conf file exists in the working directory it will be read. Configuration files in the working directory will override settings in the user-level configuration file. The user level configuration file will override default settings. Not all setting need to be set in a configuration file.

An example configuration file is given below with the default settings.

[plugins]
  required = []
  optional = []
[logging]
  version = 1
  disable_existing_loggers = false
  [logging.formatters.f1]
    format = "%(asctime)s - %(levelname)s - %(name)s - %(message)s"
    datefmt = "%Y-%m-%d %H:%M:%S"
  [logging.handlers.console]
    class = "logging.StreamHandler"
    formatter = "f1"
    stream = "ext://sys.stderr"
  [logging.loggers.idaes]
    level = "INFO"
    handlers = ["console"]

The Python dictConfig method is used to set up the logger. The required and optional elements under plugins are string lists of modules to search for Pyomo style plugins. Any failure to import plugins in the required modules will raise an exception, while any failure to import optional plugins will only result in the exception being logged and execution continuing.

Process Blocks
Example

ProcessBlock is used to simplify inheritance of Pyomo’s Block. The code below provides an example of how a new ProcessBlock class can be implemented. The new ProcessBlock class has a ConfigBlock that allows each element of the block to be passed configuration options that affect how a block is built. ProcessBlocks have a rule set by default that calls the build method of the contained ProcessBlockData class.

from pyomo.environ import *
from pyomo.common.config import ConfigValue
from idaes.core import ProcessBlockData, declare_process_block_class

@declare_process_block_class("MyBlock")
class MyBlockData(ProcessBlockData):
    CONFIG = ProcessBlockData.CONFIG()
    CONFIG.declare("xinit", ConfigValue(default=1001, domain=float))
    CONFIG.declare("yinit", ConfigValue(default=1002, domain=float))
    def build(self):
        super(MyBlockData, self).build()
        self.x = Var(initialize=self.config.xinit)
        self.y = Var(initialize=self.config.yinit)

The following example demonstrates creating a scalar instance of the new class. The default key word argument is used to pass information on the the MyBlockData ConfigBlock.

m = ConcreteModel()
m.b = MyBlock(default={"xinit":1, "yinit":2})

The next example creates an indexed MyBlock instance. In this case, each block is configured the same, using the default argument.

m = ConcreteModel()
m.b = MyBlock([0,1,2,3,4], default={"xinit":1, "yinit":2})

The next example uses the initialize argument to override the configuration of the first block. Initialize is a dictionary of dictionaries where the key of the top level dictionary is the block index and the second level dictionary is arguments for the config block.

m = ConcreteModel()
m.b = MyBlock([0,1,2,3,4], default={"xinit":1, "yinit":2},
              initialize={0:{"xinit":1, "yinit":2}})

The next example shows a more complicated configuration where there are three configurations, one for the first block, one for the last block, and one for the interior blocks. This is accomplished by providing the idx_map argument to MyBlock, which is a function that maps a block index to a index in the initialize dictionary. In this case 0 is mapped to 0, 4 is mapped to 4, and all elements between 0 and 4 are mapped to 1. A lambda function is used to convert the block index to the correct index in initialize.

m = ConcreteModel()
m.b = MyBlock(
    [0,1,2,3,4],
    idx_map = lambda i: 1 if i > 0 and i < 4 else i,
    initialize={0:{"xinit":2001, "yinit":2002},
                1:{"xinit":5001, "yinit":5002},
                4:{"xinit":7001, "yinit":7002}})
The build method

The core part of any IDAES Block is the build method, which contains the instructions on how to construct the variables, constraints and other components that make up the model. The build method serves as the default rule for constructing an instance of an IDAES Block, and is triggered automatically whenever an instance of an IDAES Block is created unless a custom rule is provided by the user.

ProcessBlock Class
idaes.core.process_block.declare_process_block_class(name, block_class=<class 'idaes.core.process_block.ProcessBlock'>, doc='')[source]

Declare a new ProcessBlock subclass.

This is a decorator function for a class definition, where the class is derived from Pyomo’s _BlockData. It creates a ProcessBlock subclass to contain the decorated class. The only requirment is that the subclass of _BlockData contain a build() method. The purpose of this decorator is to simplify subclassing Pyomo’s block class.

Parameters:
  • name – name of class to create
  • block_class – ProcessBlock or a subclass of ProcessBlock, this allows you to use a subclass of ProcessBlock if needed. The typical use case for Subclassing ProcessBlock is to impliment methods that operate on elements of an indexed block.
  • doc – Documentation for the class. This should play nice with sphinx.
Returns:

Decorator function

class idaes.core.process_block.ProcessBlock(*args, **kwargs)[source]

ProcessBlock is a Pyomo Block that is part of a system to make Pyomo Block easier to subclass. The main difference between a Pyomo Block and ProcessBlock from the user perspective is that a ProcessBlock has a rule assigned by default that calls the build() method for the contained ProcessBlockData objects. The default rule can be overridden, but the new rule should always call build() for the ProcessBlockData object.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) – Default ProcessBlockData config
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(ProcessBlock) New instance

classmethod base_class_module()[source]

Return module of the associated ProcessBase class.

Returns:(str) Module of the class.
Raises:AttributeError, if no base class module was set, e.g. this class – was not wrapped by the declare_process_block_class decorator.
classmethod base_class_name()[source]

Name given by the user to the ProcessBase class.

Returns:(str) Name of the class.
Raises:AttributeError, if no base class name was set, e.g. this class – was not wrapped by the declare_process_block_class decorator.
class idaes.core.process_base.ProcessBlockData(component)[source]

Base class for most IDAES process models and classes.

The primary purpose of this class is to create the local config block to handle arguments provided by the user when constructing an object and to ensure that these arguments are stored in the config block.

Additionally, this class contains a number of methods common to all IDAES classes.

build()[source]

The build method is called by the default ProcessBlock rule. If a rule is sepecified other than the default it is important to call ProcessBlockData’s build method to put information from the “default” and “initialize” arguments to a ProcessBlock derived class into the BlockData object’s ConfigBlock.

The the build method should usually be overloaded in a subclass derived from ProcessBlockData. This method would generally add Pyomo components such as variables, expressions, and constraints to the object. It is important for build() methods implimented in derived classes to call build() from the super class.

Parameters:None
Returns:None
fix_initial_conditions(state='steady-state')[source]

This method fixes the initial conditions for dynamic models.

Parameters:state – initial state to use for simulation (default = ‘steady-state’)
Returns :
None
flowsheet()[source]

This method returns the components parent flowsheet object, i.e. the flowsheet component to which the model is attached. If the component has no parent flowsheet, the method returns None.

Parameters:None
Returns:Flowsheet object or None
unfix_initial_conditions()[source]

This method unfixed the initial conditions for dynamic models.

Parameters:None
Returns :
None
IDAES Modeling Concepts
Introduction

The purpose of this section of the documentation is to explain the different parts of the IDAES modeling framework, and what components belong in each part for the hierarchy. Each component is described in greater detail later in the documentation, however this section provides a general introduction to different types of components.

Time Domain

Before starting on the different types of models present in the IDAES framework, it is important to discuss how time is handled by the framework. When a user first declares a Flowsheet model a time domain is created, the form of which depends on whether the Flowsheet is declared to be dynamic or steady-state (see FlowsheetBlock documentation). In situations where the user makes use of nested flowsheets, each sub-flowsheet refers to its parent flowsheet for the time domain.

Different models may handle the time domain differently, but in general all IDAES models refer to the time domain of their parent flowsheet. The only exception to this are blocks associated with Property calculations. PropertyBlocks represent the state of the material at a single point in space and time, and thus do not contain the time domain. Instead, PropertyBlocks are indexed by time (and space where applicable) - i.e. there is a separate PropertyBlock for each point in time. The user should keep this in mind when working with IDAES models, as it is important for understanding where the time index appears within a model.

In order to facilitate referencing of the time domain, all Flowsheet objects have a time configuration argument which is a reference to the time domain for that flowsheet. All IDAES models contain a flowsheet method which returns the parent flowsheet object, thus a reference to the time domain can always be found using the following code: flowsheet().config.time.

Another important thing to note is that steady-state models do contain a time domain, however this is generally a single point at time = 0.0. However, models still contain a reference to the time domain, and any components are still indexed by time even in a steady-state model (e.g. PropertyBlocks).

Flowsheets

The top level of the IDAES modeling framework is the Flowsheet model. Flowsheet models represent traditional process flowsheets, containing a number of Unit models representing process unit operations connected together into a flow network. Flowsheets generally contain three types of components:

  1. Unit models, representing unit operations,
  2. Arcs, representing connections between Unit models, and,
  3. Property Parameter blocks, representing the parameters associated with different materials present within the flowsheet.

Flowsheet models may also contain additional constraints relating to how different Unit models behave and interact, such as control and operational constraints. Generally speaking, if a Constraint is purely internal to a single unit, and does not depend on information from other units in the flowsheet, then the Constraint should be placed inside the relevant Unit model. Otherwise, the Constraint should be placed at the Flowsheet level.

Unit Models

Unit models generally represent individual pieces of equipment present within a process which perform a specific task. Unit models in turn are generally composed of two main types of components:

  1. Control Volume Blocks, which represent volume of material over which we wish to perform material, energy and/or momentum balances, and,
  2. StateBlocks and ReactionBlocks, which represent the thermophysical, transport and reaction properties of the material at a specific point in space and time.
  3. Inlets and Outlets, which allow Unit models to connect to other Unit models.

Unit models will also contain Constraints describing the performance of the unit, which will relate terms in the balance equations to different phenomena.

Control Volumes

A key feature of the IDAES modeling framework is the use of Control Volume Blocks. As mentioned above, Control Volumes represent a volume of material over which material, energy and/or momentum balances can be performed. Control Volume Blocks contain methods to automate the task of writing common forms of these balance equations. Control Volume Blocks can also automate the creation of StateBlocks and ReactionBlocks associated with the control volume.

Property Blocks

Property blocks represent the state of a material at a given point in space and time within the process flowsheet, and contain the state variables, thermophysical, transport and reaction properties of a material (which are functions solely of the local state of the material). Within the IDAES process modeling framework, properties are divided into two types:

  • Physical properties (StateBlocks), including thermophysical and transport properties, and
  • Reaction properties (ReactionBlocks), which include all properties associated with chemical reactions.

Additionally, StateBlocks contain information on the extensive flow of material at that point in space and time, which is a departure from how engineers generally think about properties. This is required to facilitate the flexible formulation of the IDAES Framework by allowing the property package to dictate what form the balance equations will take, which requires the StateBlock to know the extensive flow information.

The calculations involved in property blocks of both types generally require a set of parameters which are constant across all instances of that type of property block. Rather than each property block containing its own copy of each of these parameters (thus duplicating parameters between blocks), each type of property block is associated with a Property Parameter Block (PhysicalParameterBlock or ReactionParameterBlock). Property Parameter Blocks serve as a centralized location for the constant parameters involved in property calculations, and all property blocks of the associated type link to the parameters contained in the parameter block.

Component References

There are many situations in the IDAES modeling framework where a developer may want to make use of a modeling component (e.g. a variable or parameter) from one Block in another Block. The time domain is a good example of this - almost all Blocks within an IDAES model need to make use of the time domain, however the time domain exists only at the top level of the flowsheet structure. In order to make use of the time domain in other parts of the framework, references to the time domain are used instead. By convention, all references within the IDAES modeling framework are indicated by the suffix “_ref” attached to the name of the reference. E.g. all references to the time domain within the framework are called “time_ref”.

What Belongs in Each Type of Block?

A common question with the hierarchical structure of the IDAES framework is where does a specific variable or constraint belong (or conversely, where can I find a specific variable or constraint). In general, variables and constraints are divided based on the following guidelines:

  1. Property Parameter Blocks - any parameter or quantity that is consistent across all instances of a Property Block belongs in the Property Parameter Block. This includes:

    • component lists,
    • lists of valid phases,
    • universal constants (e.g. R, \(\pi\)),
    • constants used in calculating properties (e.g. coefficients for calculating \(c_p\),
    • reference states (e.g. \(P_{ref}\) and \(T_{ref}\)),
    • lists of reaction identifiers,
    • reaction stoichiometry.
  2. Property Blocks - all state variables (including extensive flow information) and any quantity that is a function only of state variables plus the constraints required to calculate these. These include:

    • flow rates (can be of different forms, e.g. mass or molar flow, on a total or component basis),
    • temperature,
    • pressure,
    • intensive and extensive state functions (e.g. enthalpy); both variables and constraints.
  3. Control Volume Blocks - material, energy and momentum balances and the associated terms. These include:

    • balance equations,
    • holdup volume,
    • material and energy holdups; both variables and constraints,
    • material and energy accumulation terms (Pyomo.dae handles the creation of the associated derivative constraints),
    • material generation terms (kinetic reactions, chemical and phase equilibrium, mass transfer),
    • extent of reaction terms and constraints relating these to the equivalent generation terms,
    • phase fraction within the holdup volume and constrain on the sum of phase fractions,
    • heat and work transfer terms,
    • pressure change term
    • diffusion and conduction terms (where applicable) and associated constraints,
    • Mixer and Splitter blocks for handling multiple inlets/outlets.
  4. Unit Model - any unit performance constraints and associated variables, such as:

    • constraints relating balance terms to physical phenomena or properties (e.g. relating extent of reaction to reaction rate and volume),
    • constraints describing flow of material into or out of unit (e.g. pressure driven flow constraints),
    • unit level efficiency constraints (e.g. relating mechanical work to fluid work).
  5. Flowsheet Model - any constraints related to interaction of unit models and associated variables. Examples include:

    • control constraints relating behavior between different units (e.g. a constraint on valve opening based on the level in another unit).
Flowsheet Model Class

Flowsheet models make up the top level of the IDAES modeling framework, and represent the flow of material and energy through a process. Flowsheets will generally contain a number of UnitModels to represent unit operations within the process, and will contain one or more Property Packages which represent the thermophysical and transport properties of material within the process.

Flowsheet models are responsible for establishing and maintaining the time domain of the model, including declaring whether the process model will be dynamic or steady-state. This time domain is passed on to all models attached to the flowsheet (such as Unit Models and sub-Flowsheets). The Flowsheet model also serves as a centralized location for organizing property packages, and can set one property package to use as a default throughout the flowsheet.

Flowsheet Blocks may contain other Flowsheet Blocks in order to create nested flowsheets and to better organize large, complex process configurations. In these cases, the top-level Flowsheet Block creates the time domain, and each sub-flowsheet creates a reference this time domain. Sub-flowsheets may make use of any property package declared at a higher level, or declare new property package for use within itself - any of these may be set as the default property package for a sub-Flowsheet.

Default Property Packages

Flowsheet Blocks may assign a property package to use as a default for all UnitModels within the Flowsheet. If a specific property package is not provided as an argument when constructing a UnitModel, the UnitModel will search up the model tree until it finds a default property package declared. The UnitModel will use the first default property package it finds during the search, and will return an error if no default is found.

Flowsheet Configuration Arguments

Flowsheet blocks have three configuration arguments which are stored within a Config block (flowsheet.config). These arguments can be set by passing arguments when instantiating the class, and are described below:

  • dynamic - indicates whether the flowsheet should be dynamic or steady-state. If dynamic = True, the flowsheet is declared to be a dynamic flowsheet, and the time domain will be a Pyomo ContunuousSet. If dynamic = False, the flowsheet is declared to be steady-state, and the time domain will be an ordered Pyomo Set. For top level Flowsheets, dynamic defaults to False if not provided. For lower level Flowsheets, the dynamic will take the same value as that of the parent model if not provided. It is possible to declare steady-state sub-Flowsheets as part of dynamic Flowsheets if desired, however the reverse is not true (cannot have dynamic Flowsheets within steady-state Flowsheets).
  • time - a reference to the time domain for the flowsheet. During flowsheet creation, users may provide a Set or ContinuousSet that the flowsheet should use as the time domain. If not provided, then the flowsheet will look for a parent flowsheet and set this equal to the parent’s time domain, otherwise a new time domain will be created and assigned here.
  • time_set - used to initialize the time domain in top-level Flowsheets. When constructing the time domain in top-level Flowsheets, time_set is used to initialize the ContinuousSet or Set created. This can be used to set start and end times, and to establish points of interest in time (e.g. times when disturbances will occur). If dynamic = True, time_set defaults to [0.0, 1.0] if not provided, if dynamic = False time_set defaults to [0.0]. time_set is not used in sub-Flowsheets and will be ignored.
  • default_property_package - can be used to assign the default property package for a Flowsheet. Defaults to None if not provided.
Flowsheet Classes
class idaes.core.flowsheet_model.FlowsheetBlockData(component)[source]

The FlowsheetBlockData Class forms the base class for all IDAES process flowsheet models. The main purpose of this class is to automate the tasks common to all flowsheet models and ensure that the necessary attributes of a flowsheet model are present.

The most signfiicant role of the FlowsheetBlockData class is to automatically create the time domain for the flowsheet.

build()[source]

General build method for FlowsheetBlockData. This method calls a number of sub-methods which automate the construction of expected attributes of flowsheets.

Inheriting models should call super().build.

Parameters:None
Returns:None
is_flowsheet()[source]

Method which returns True to indicate that this component is a flowsheet.

Parameters:None
Returns:True
model_check()[source]

This method runs model checks on all unit models in a flowsheet.

This method searches for objects which inherit from UnitModelBlockData and executes the model_check method if it exists.

Parameters:None
Returns:None
class idaes.core.flowsheet_model.FlowsheetBlock(*args, **kwargs)

FlowsheetBlock is a specialized Pyomo block for IDAES flowsheet models, and contains instances of FlowsheetBlockData.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic, default - useDefault. Valid values: { useDefault - get flag from parent or False, True - set as a dynamic model, False - set as a steady-state model.}
    time
    Pointer to the time domain for the flowsheet. Users may provide an existing time domain from another flowsheet, otherwise the flowsheet will search for a parent with a time domain or create a new time domain and reference it here.
    time_set
    Set of points for initializing time domain. This should be a list of floating point numbers, default - [0].
    default_property_package
    Indicates the default property package to be used by models within this flowsheet if not otherwise specified, default - None. Valid values: { None - no default property package, a ParameterBlock object.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(FlowsheetBlock) New instance

Property Packages
Physical Property Package Classes

Physical property packages represent a collection of calculations necessary to determine the state properties of a given material. Property calculations form a critical part of any process model, and thus property packages form the core of the IDAES modeling framework.

Physical property packages consist of two parts:

  • PhysicalParameterBlocks, which contain a set of parameters associated with the specific material(s) being modeled, and
  • StateBlocks, which contain the actual calculations of the state variables and functions.
Physical Parameter Blocks

Physical Parameter blocks serve as a central location for linking to a property package, and contain all the parameters and indexing sets used by a given property package.

PhysicalParameterBlock Class

The role of the PhysicalParameterBlock class is to set up the references required by the rest of the IDAES framework for constructing instances of StateBlocks and attaching these to the PhysicalParameter block for ease of use. This allows other models to be pointed to the PhysicalParameter block in order to collect the necessary information and to construct the necessary StateBlocks without the need for the user to do this manually.

Physical property packages form the core of any process model in the IDAES modeling framework, and are used by all of the other modeling components to inform them of what needs to be constructed. In order to do this, the IDAES modeling framework looks for a number of attributes in the PhysicalParameter block which are used to inform the construction of other components.

  • state_block_class - a pointer to the associated class that should be called when constructing StateBlocks.
  • phase_list - a Pyomo Set object defining the valid phases of the mixture of interest.
  • component_list - a Pyomo Set defining the names of the chemical species present in the mixture.
  • element_list - (optional) a Pyomo Set defining the names of the chemical elements that make up the species within the mixture. This is used when doing elemental material balances.
  • element_comp - (optional) a dict-like object which defines the elemental composition of each species in component_list. Form: component: {element_1: value, element_2: value, …}.
  • supported properties metadata - a list of supported physical properties that the property package supports, along with instruction to the framework on how to construct the associated variables and constraints, and the units of measurement used for the property. This information is set using the add_properties attribute of the define_metadata class method.
Physical Parameter Configuration Arguments

Physical Parameter blocks have one standard configuration argument:

  • default_arguments - this allows the user to provide a set of default values for construction arguments in associated StateBlocks, which will be passed to all StateBlocks when they are constructed.
class idaes.core.property_base.PhysicalParameterBlock(component)[source]

This is the base class for thermophysical parameter blocks. These are blocks that contain a set of parameters associated with a specific thermophysical property package, and are linked to by all instances of that property package.

build()[source]

General build method for PropertyParameterBlocks. Inheriting models should call super().build.

Parameters:None
Returns:None
State Blocks

State Blocks are used within all IDAES Unit models (generally within ControlVolume Blocks) in order to calculate physical properties given the state of the material. State Blocks are notably different to other types of Blocks within IDAES as they are always indexed by time (and possibly space as well). There are two base Classes associated with State Blocks:

  • StateBlockData forms the base class for all StateBlockData objects, which contain the instructions on how to construct each instance of a State Block.
  • StateBlock is used for building classes which contain methods to be applied to sets of Indexed State Blocks (or to a subset of these). See the documentation on declare_process_block_class and the IDAES tutorials and examples for more information.
State Block Construction Arguments

State Blocks have the following construction arguments:

  • parameters - a reference to the associated Physical Parameter block which will be used to make references to all necessary parameters.
  • defined_state - this argument indicates whether the State Block should expect the material state to be fully defined by another part of the flowsheet (such as by an upstream unit operation). This argument is used to determine whether constraints such as sums of mole fractions should be enforced.
  • has_phase_equilibrium - indicates whether the associated Control Volume or Unit model expects phase equilibrium to be enforced (if applicable).
StateBlockData Class

StateBlockData contains the code necessary for implementing the as needed construction of variables and constraints.

class idaes.core.property_base.StateBlockData(component)[source]

This is the base class for state block data objects. These are blocks that contain the Pyomo components associated with calculating a set of thermophysical and transport properties for a given material.

build()[source]

General build method for StateBlockDatas.

Parameters:None
Returns:None
calculate_bubble_point_pressure(*args, **kwargs)[source]

Method which computes the bubble point pressure for a multi- component mixture given a temperature and mole fraction.

calculate_bubble_point_temperature(*args, **kwargs)[source]

Method which computes the bubble point temperature for a multi- component mixture given a pressure and mole fraction.

calculate_dew_point_pressure(*args, **kwargs)[source]

Method which computes the dew point pressure for a multi- component mixture given a temperature and mole fraction.

calculate_dew_point_temperature(*args, **kwargs)[source]

Method which computes the dew point temperature for a multi- component mixture given a pressure and mole fraction.

define_port_members()[source]

Method used to specific components to populate Ports with. Defaults to define_state_vars, and developers should overload as required.

define_state_vars()[source]

Method that returns a dictionary of state variables used in property package. Implement a placeholder method which returns an Exception to force users to overload this.

get_energy_diffusion_terms(*args, **kwargs)[source]

Method which returns a valid expression for energy diffusion to use in the energy balances.

get_enthalpy_density_terms(*args, **kwargs)[source]

Method which returns a valid expression for enthalpy density to use in the energy balances.

get_enthalpy_flow_terms(*args, **kwargs)[source]

Method which returns a valid expression for enthalpy flow to use in the energy balances.

get_material_density_terms(*args, **kwargs)[source]

Method which returns a valid expression for material density to use in the material balances .

get_material_diffusion_terms(*args, **kwargs)[source]

Method which returns a valid expression for material diffusion to use in the material balances.

get_material_flow_basis(*args, **kwargs)[source]

Method which returns an Enum indicating the basis of the material flow term.

get_material_flow_terms(*args, **kwargs)[source]

Method which returns a valid expression for material flow to use in the material balances.

StateBlock Class
class idaes.core.property_base.StateBlock(*args, **kwargs)[source]

This is the base class for state block objects. These are used when constructing the SimpleBlock or IndexedBlock which will contain the PropertyData objects, and contains methods that can be applied to multiple StateBlockData objects simultaneously.

initialize(*args, **kwargs)[source]

This is a default initialization routine for StateBlocks to ensure that a routine is present. All StateBlockData classes should overload this method with one suited to the particular property package

Parameters:None
Returns:None
Reaction Property Package Classes

Reaction property packages represent a collection of calculations necessary to determine the reaction behavior of a mixture at a given state. Reaction properties depend upon the state and physical properties of the material, and thus must be linked to a StateBlock which provides the necessary state and physical property information.

Reaction property packages consist of two parts:

  • ReactionParameterBlocks, which contain a set of parameters associated with the specific reaction(s) being modeled, and
  • ReactionBlocks, which contain the actual calculations of the reaction behavior.
Reaction Parameter Blocks

Reaction Parameter blocks serve as a central location for linking to a reaction property package, and contain all the parameters and indexing sets used by a given reaction package.

ReactionParameterBlock Class

The role of the ReactionParameterBlock class is to set up the references required by the rest of the IDAES framework for constructing instances of ReactionBlocks and attaching these to the ReactionParameter block for ease of use. This allows other models to be pointed to the ReactionParameter block in order to collect the necessary information and to construct the necessary ReactionBlocks without the need for the user to do this manually.

Reaction property packages are used by all of the other modeling components to inform them of what needs to be constructed when dealing with chemical reactions. In order to do this, the IDAES modeling framework looks for a number of attributes in the ReactionParameter block which are used to inform the construction of other components.

  • reaction_block_class - a pointer to the associated class that should be called when constructing ReactionBlocks.
  • phase_list - a Pyomo Set object defining the valid phases of the mixture of interest.
  • component_list - a Pyomo Set defining the names of the chemical species present in the mixture.
  • rate_reaction_idx - a Pyomo Set defining a list of names for the kinetically controlled reactions of interest.
  • rate_reaction_stoichiometry - a dict-like object defining the stoichiometry of the kinetically controlled reactions. Keys should be tuples of (rate_reaction_idx, phase_list, component_list) and values equal to the stoichiometric coefficient for that index.
  • equilibrium_reaction_idx - a Pyomo Set defining a list of names for the equilibrium controlled reactions of interest.
  • equilibrium_reaction_stoichiometry - a dict-like object defining the stoichiometry of the equilibrium controlled reactions. Keys should be tuples of (equilibrium_reaction_idx, phase_list, component_list) and values equal to the stoichiometric coefficient for that index.
  • supported properties metadata - a list of supported reaction properties that the property package supports, along with instruction to the framework on how to construct the associated variables and constraints, and the units of measurement used for the property. This information is set using the add_properties attribute of the define_metadata class method.
  • required properties metadata - a list of physical properties that the reaction property calculations depend upon, and must be supported by the associated StateBlock. This information is set using the add_required_properties attribute of the define_metadata class method.
Reaction Parameter Configuration Arguments

Reaction Parameter blocks have two standard configuration arguments:

  • property_package - a pointer to a PhysicalParameterBlock which will be used to construct the StateBlocks to which associated ReactionBlocks will be linked. Reaction property packages must be tied to a single Physical property package, and this is used to validate the connections made later when constructing ReactionBlocks.
  • default_arguments - this allows the user to provide a set of default values for construction arguments in associated ReactionBlocks, which will be passed to all ReactionBlocks when they are constructed.
class idaes.core.reaction_base.ReactionParameterBlock(component)[source]

This is the base class for reaction parameter blocks. These are blocks that contain a set of parameters associated with a specific reaction package, and are linked to by all instances of that reaction package.

build()[source]

General build method for ReactionParameterBlocks. Inheriting models should call super().build.

Parameters:None
Returns:None
Reaction Blocks

Reaction Blocks are used within IDAES Unit models (generally within ControlVolume Blocks) in order to calculate reaction properties given the state of the material (provided by an associated StateBlock). Reaction Blocks are notably different to other types of Blocks within IDAES as they are always indexed by time (and possibly space as well), and are also not fully self contained (in that they depend upon the associated state block for certain variables). There are two bases Classes associated with Reaction Blocks:

  • ReactionBlockDataBase forms the base class for all ReactionBlockData objects, which contain the instructions on how to construct each instance of a Reaction Block.
  • ReactionBlockBase is used for building classes which contain methods to be applied to sets of Indexed Reaction Blocks (or to a subset of these). See the documentation on declare_process_block_class and the IDAES tutorials and examples for more information.
Reaction Block Construction Arguments

Reaction Blocks have the following construction arguments:

  • parameters - a reference to the associated Reaction Parameter block which will be used to make references to all necessary parameters.
  • state_block - a reference to the associated StateBlock which will provide the necessary state and physical property information.
  • has_equilibrium - indicates whether the associated Control Volume or Unit model expects chemical equilibrium to be enforced (if applicable).
ReactionBlockDataBase Class

ReactionBlockDataBase contains the code necessary for implementing the as needed construction of variables and constraints.

class idaes.core.reaction_base.ReactionBlockDataBase(component)[source]

This is the base class for reaction block data objects. These are blocks that contain the Pyomo components associated with calculating a set of reacion properties for a given material.

build()[source]

General build method for PropertyBlockDatas. Inheriting models should call super().build.

Parameters:None
Returns:None
get_reaction_rate_basis()[source]

Method which returns an Enum indicating the basis of the reaction rate term.

ReactionBlockBase Class
class idaes.core.reaction_base.ReactionBlockBase(*args, **kwargs)[source]

This is the base class for reaction block objects. These are used when constructing the SimpleBlock or IndexedBlock which will contain the PropertyData objects, and contains methods that can be applied to multiple ReactionBlockData objects simultaneously.

initialize(*args)[source]

This is a default initialization routine for ReactionBlocks to ensure that a routine is present. All ReactionBlockData classes should overload this method with one suited to the particular reaction package

Parameters:None
Returns:None
IDAES Property Packages

The IDAES process modeling framework divides property calculations into two parts;

  • physical and transport properties
  • chemical reaction properties

Defining the calculations to be used when calculating properties is done via “property packages”, which contain a set of related calculations for a number of properties of interest. Property packages may be general in purpose, such as ideal gas equations, or specific to a certain application.

As Needed Properties

Process flow sheets often require a large number of properties to be calculate, but not all of these are required in every unit operation. Calculating additional properties that are not required is undesirable, as it leads to larger problem sizes and unnecessary complexity of the resulting model.

To address this, the IDAES modeling framework supports “as needed” construction of properties, where the variables and constraints required to calculate a given quantity are not added to a model unless the model calls for this quantity. To designate a property as an “as needed” quantity, a method can be declared in the associated property BlockData class (StateBlockData or ReactionBlockData) which contains the instructions for constructing the variables and constraints associated with the quantity (rather than declaring these within the BlockData’s build method). The name of this method can then be associated with the property via the add_properties metadata in the property packages ParameterBlock, which indicates to the framework that when this property is called for, the associated method should be run.

The add_properties metadata can also indicate that a property should always be present (i.e. constructed in the BlockData’s build method) by setting the method to None, or that it is not supported by setting the method to False.

Unit Model Class

The UnitModelBlock is class is designed to form the basis of all IDAES Unit Models, and contains a number of methods which are common to all Unit Models.

UnitModelBlock Construction Arguments

The UnitModelBlock class by default has only one construction argument, which is listed below. However, most models inheriting from UnitModelBlock should declare their own set of configuration arguments which contain more information on how the model should be constructed.

  • dynamic - indicates whether the Unit model should be dynamic or steady-state, and if dynamic = True, the unit is declared to be a dynamic model. dynamic defaults to useDefault if not provided when instantiating the Unit model (see below for more details). It is possible to declare steady-state Unit models as part of dynamic Flowsheets if desired, however the reverse is not true (cannot have dynamic Unit models within steady-state Flowsheets).
Collecting Time Domain

The next task of the UnitModelBlock class is to establish the time domain for the unit by collecting the necessary information from the parent Flowsheet model. If the dynamic construction argument is set to useDefault then the Unit model looks to its parent model for the dynamic argument, otherwise the value provided at construction is used.

Finally, if the Unit model has a construction argument named “has_holdup” (not part of the base class), then this is checked to ensure that if dynamic = True then has_holdup is also True. If this check fails then a ConfigurationError exception will be thrown.

Modeling Support Methods

The UnitModelBlock class also contains a number of methods designed to facilitate the construction of common components of a model, and these are described below.

Build Inlets Method

All (or almost all) Unit Models will have inlets and outlets which allow material to flow in and out of the unit being modeled. In order to save the model developer from having to write the code for each inlet themselves, UnitModelBlock contains a method named build_inlet_port which can automatically create an inlet to a specified ControlVolume block (or linked to a specified StateBlock). The build_inlet_port method is described in more detail in the documentation below.

Build Outlets Method

Similar to build_inlet_port, UnitModelBlock also has a method named build_outlet_port for constructing outlets from Unit models. The build_outlets method is described in more detail in the documentation below.

Model Check Method

In order to support the IDAES Model Check tools, UnitModelBlock contains a simple model_check method which assumes a single Holdup block and calls the model_check method on this block. Model developers are encouraged to create their own model_check methods for their particular applications.

Initialization Routine

All Unit Models need to have an initialization routine, which should be customized for each Unit model, In order to ensure that all Unit models have at least a basic initialization routine, UnitModelBlock contains a generic initialization procedure which may be sufficient for simple models with only one Holdup Block. Model developers are strongly encouraged to write their own initialization routines rather than relying on the default method.

UnitModelBlock Classes
class idaes.core.unit_model.UnitModelBlockData(component)[source]

This is the class for process unit operations models. These are models that would generally appear in a process flowsheet or superstructure.

add_inlet_port(name=None, block=None, doc=None)[source]

This is a method to build inlet Port objects in a unit model and connect these to a specified control volume or state block.

The name and block arguments are optional, but must be used together. i.e. either both arguments are provided or neither.

Keyword Arguments:
 
  • = name to use for Port object (name) –
  • = an instance of a ControlVolume or StateBlock to use as the (block) – source to populate the Port object. If a ControlVolume is provided, the method will use the inlet state block as defined by the ControlVolume. If not provided, method will attempt to default to an object named control_volume.
  • = doc string for Port object (doc) –
Returns:

A Pyomo Port object and associated components.

add_outlet_port(name=None, block=None, doc=None)[source]

This is a method to build outlet Port objects in a unit model and connect these to a specified control volume or state block.

The name and block arguments are optional, but must be used together. i.e. either both arguments are provided or neither.

Keyword Arguments:
 
  • = name to use for Port object (name) –
  • = an instance of a ControlVolume or StateBlock to use as the (block) – source to populate the Port object. If a ControlVolume is provided, the method will use the outlet state block as defined by the ControlVolume. If not provided, method will attempt to default to an object named control_volume.
  • = doc string for Port object (doc) –
Returns:

A Pyomo Port object and associated components.

add_port(name=None, block=None, doc=None)[source]

This is a method to build Port objects in a unit model and connect these to a specified StateBlock. :keyword name = name to use for Port object.: :keyword block = an instance of a StateBlock to use as the source to: populate the Port object :keyword doc = doc string for Port object:

Returns:A Pyomo Port object and associated components.
build()[source]

General build method for UnitModelBlockData. This method calls a number of sub-methods which automate the construction of expected attributes of unit models.

Inheriting models should call super().build.

Parameters:None
Returns:None
initialize(state_args=None, outlvl=0, solver='ipopt', optarg={'tol': 1e-06})[source]

This is a general purpose initialization routine for simple unit models. This method assumes a single ControlVolume block called controlVolume, and first initializes this and then attempts to solve the entire unit.

More complex models should overload this method with their own initialization routines,

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating which solver to use during initialization (default = ‘ipopt’)
Returns:

None

model_check()[source]

This is a general purpose initialization routine for simple unit models. This method assumes a single ControlVolume block called controlVolume and tries to call the model_check method of the controlVolume block. If an AttributeError is raised, the check is passed.

More complex models should overload this method with a model_check suited to the particular application, especially if there are multiple ControlVolume blocks present.

Parameters:None
Returns:None
class idaes.core.unit_model.UnitModelBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(UnitModelBlock) New instance

Control Volume Classes
0D Control Volume Class

The ControlVolume0DBlock block is the most commonly used Control Volume class, and is used for systems where there is a well-mixed volume of fluid, or where variations in spatial domains are considered to be negligible. ControlVolume0DBlock blocks generally contain two StateBlocks - one for the incoming material and one for the material within and leaving the volume - and one StateBlocks.

class idaes.core.control_volume0d.ControlVolume0DBlock(*args, **kwargs)

ControlVolume0DBlock is a specialized Pyomo block for IDAES non-discretized control volume blocks, and contains instances of ControlVolume0DBlockData.

ControlVolume0DBlock should be used for any control volume with a defined volume and distinct inlets and outlets which does not require spatial discretization. This encompases most basic unit models used in process modeling.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic, default - useDefault. Valid values: { useDefault - get flag from parent, True - set as a dynamic model, False - set as a steady-state model}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    reaction_package
    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}
    reaction_package_args
    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}
    auto_construct
    If set to True, this argument will trigger the auto_construct method which will attempt to construct a set of material, energy and momentum balance equations based on the parent unit’s config block. The parent unit must have a config block which derives from CONFIG_Base, default - False. Valid values: { True - use automatic construction, False - do not use automatic construciton.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(ControlVolume0DBlock) New instance

class idaes.core.control_volume0d.ControlVolume0DBlockData(component)[source]

0-Dimensional (Non-Discretised) ControlVolume Class

This class forms the core of all non-discretized IDAES models. It provides methods to build property and reaction blocks, and add mass, energy and momentum balances. The form of the terms used in these constraints is specified in the chosen property package.

add_geometry()[source]

Method to create volume Var in ControlVolume.

Parameters:None
Returns:None
add_phase_component_balances(has_rate_reactions=False, has_equilibrium_reactions=False, has_phase_equilibrium=False, has_mass_transfer=False, custom_molar_term=None, custom_mass_term=None)[source]

This method constructs a set of 0D material balances indexed by time, phase and component.

Parameters:
  • has_rate_reactions – whether default generation terms for rate reactions should be included in material balances
  • has_equilibrium_reactions – whether generation terms should for chemical equilibrium reactions should be included in material balances
  • has_phase_equilibrium – whether generation terms should for phase equilibrium behaviour should be included in material balances
  • has_mass_transfer – whether generic mass transfer terms should be included in material balances
  • custom_molar_term – a Pyomo Expression representing custom terms to be included in material balances on a molar basis. Expression must be indexed by time, phase list and component list
  • custom_mass_term – a Pyomo Expression representing custom terms to be included in material balances on a mass basis. Expression must be indexed by time, phase list and component list
Returns:

Constraint object representing material balances

add_phase_energy_balances(*args, **kwargs)[source]

Method for adding energy balances (including kinetic energy) indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_enthalpy_balances(*args, **kwargs)[source]

Method for adding enthalpy balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_momentum_balances(*args, **kwargs)[source]

Method for adding momentum balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_pressure_balances(*args, **kwargs)[source]

Method for adding pressure balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_reaction_blocks(has_equilibrium=None)[source]

This method constructs the reaction block for the control volume.

Parameters:
  • has_equilibrium – indicates whether equilibrium calculations will be required in reaction block
  • package_arguments – dict-like object of arguments to be passed to reaction block as construction arguments
Returns:

None

add_state_blocks(information_flow=<FlowDirection.forward: 1>, has_phase_equilibrium=None)[source]

This method constructs the inlet and outlet state blocks for the control volume.

Parameters:
  • information_flow – a FlowDirection Enum indicating whether information flows from inlet-to-outlet or outlet-to-inlet
  • has_phase_equilibrium – indicates whether equilibrium calculations will be required in state blocks
  • package_arguments – dict-like object of arguments to be passed to state blocks as construction arguments
Returns:

None

add_total_component_balances(has_rate_reactions=False, has_equilibrium_reactions=False, has_phase_equilibrium=False, has_mass_transfer=False, custom_molar_term=None, custom_mass_term=None)[source]

This method constructs a set of 0D material balances indexed by time and component.

Parameters:
  • - whether default generation terms for rate (has_rate_reactions) – reactions should be included in material balances
  • - whether generation terms should for (has_equilibrium_reactions) – chemical equilibrium reactions should be included in material balances
  • - whether generation terms should for phase (has_phase_equilibrium) – equilibrium behaviour should be included in material balances
  • - whether generic mass transfer terms should be (has_mass_transfer) – included in material balances
  • - a Pyomo Expression representing custom terms to (custom_mass_term) – be included in material balances on a molar basis. Expression must be indexed by time, phase list and component list
  • - a Pyomo Expression representing custom terms to – be included in material balances on a mass basis. Expression must be indexed by time, phase list and component list
Returns:

Constraint object representing material balances

add_total_element_balances(has_rate_reactions=False, has_equilibrium_reactions=False, has_phase_equilibrium=False, has_mass_transfer=False, custom_elemental_term=None)[source]

This method constructs a set of 0D element balances indexed by time.

Parameters:
  • - whether default generation terms for rate (has_rate_reactions) – reactions should be included in material balances
  • - whether generation terms should for (has_equilibrium_reactions) – chemical equilibrium reactions should be included in material balances
  • - whether generation terms should for phase (has_phase_equilibrium) – equilibrium behaviour should be included in material balances
  • - whether generic mass transfer terms should be (has_mass_transfer) – included in material balances
  • - a Pyomo Expression representing custom (custom_elemental_term) – terms to be included in material balances on a molar elemental basis. Expression must be indexed by time and element list
Returns:

Constraint object representing material balances

add_total_energy_balances(*args, **kwargs)[source]

Method for adding a total energy balance (including kinetic energy) to the control volume.

See specific control volume documentation for details.

add_total_enthalpy_balances(has_heat_of_reaction=False, has_heat_transfer=False, has_work_transfer=False, custom_term=None)[source]

This method constructs a set of 0D enthalpy balances indexed by time and phase.

Parameters:
  • - whether terms for heat of reaction should (has_heat_of_reaction) – be included in enthalpy balance
  • - whether terms for heat transfer should be (has_heat_transfer) – included in enthalpy balances
  • - whether terms for work transfer should be (has_work_transfer) – included in enthalpy balances
  • - a Pyomo Expression representing custom terms to (custom_term) – be included in enthalpy balances. Expression must be indexed by time and phase list
Returns:

Constraint object representing enthalpy balances

add_total_material_balances(*args, **kwargs)[source]

Method for adding a total material balance to the control volume.

See specific control volume documentation for details.

add_total_momentum_balances(*args, **kwargs)[source]

Method for adding a total momentum balance to the control volume.

See specific control volume documentation for details.

add_total_pressure_balances(has_pressure_change=False, custom_term=None)[source]

This method constructs a set of 0D pressure balances indexed by time.

Parameters:
  • - whether terms for pressure change should be (has_pressure_change) – included in enthalpy balances
  • - a Pyomo Expression representing custom terms to (custom_term) – be included in pressure balances. Expression must be indexed by time
Returns:

Constraint object representing pressure balances

build()[source]

Build method for ControlVolume0DBlock blocks.

Returns:None
initialize(state_args=None, outlvl=0, optarg=None, solver='ipopt', hold_state=True)[source]

Initialisation routine for 0D control volume (default solver ipopt)

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl – sets output level of initialisation routine. Valid values: 0 - no output (default), 1 - return solver state for each step in routine, 2 - include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default=None)
  • solver – str indicating whcih solver to use during initialization (default = ‘ipopt’)
  • hold_state – flag indicating whether the initialization routine should unfix any state variables fixed during initialization, default - True. Valid values: True - states variables are not unfixed, and a dict of returned containing flags for which states were fixed during initialization, False - state variables are unfixed after initialization by calling the release_state method.
Returns:

If hold_states is True, returns a dict containing flags for which states were fixed during initialization.

model_check()[source]

This method executes the model_check methods on the associated state blocks (if they exist). This method is generally called by a unit model as part of the unit’s model_check method.

Parameters:None
Returns:None
release_state(flags, outlvl=0)[source]

Method to release state variables fixed during initialisation.

Keyword Arguments:
 
  • flags – dict containing information of which state variables were fixed during initialization, and should now be unfixed. This dict is returned by initialize if hold_state = True.
  • outlvl – sets output level of logging
Returns:

None

ControlVolume0DBlock Equations

This section documents the variables and constraints created by each of the methods provided by the ControlVolume0DBlock class.

  • \(t\) indicates time index
  • \(p\) indicates phase index
  • \(j\) indicates component index
  • \(e\) indicates element index
  • \(r\) indicates reaction name index
add_geometry

The add_geometry method creates a single variable within the control volume named volume indexed by time (allowing for varying volume over time). A number of other methods depend on this variable being present, thus this method should generally be called first.

Variables

Variable Name Symbol Indices Conditions
volume \(V_t\) t None

Constraints

No additional constraints

add_phase_component_balances

Material balances are written for each component in each phase (e.g. separate balances for liquid water and steam). Physical property packages may include information to indicate that certain species do not appear in all phases, and material balances will not be written in these cases (if has_holdup is True holdup terms will still appear for these species, however these will be set to 0).

Variables

Variable Name Symbol Indices Conditions
material_holdup \(M_{t,p,j}\) t, p, j has_holdup = True
phase_fraction \(\phi_{t,p}\) t, p has_holdup = True
material_accumulation \(\frac{\partial M_{t,p,j}}{\partial t}\) t, p, j dynamic = True
rate_reaction_generation \(N_{kinetic,t,p,j}\) t, p ,j has_rate_reactions = True
rate_reaction_extent \(X_{kinetic,t,r}\) t, r has_rate_reactions = True
equilibrium_reaction_generation \(N_{equilibrium,t,p,j}\) t, p ,j has_equilibrium_reactions = True
equilibrium_reaction_extent \(X_{equilibrium,t,r}\) t, r has_equilibrium_reactions = True
phase_equilibrium_generation \(N_{pe,t,p,j}\) t, p ,j has_phase_equilibrium = True
mass_transfer_term \(N_{transfer,t,p,j}\) t, p ,j has_mass_transfer = True

Constraints

material_balances(t, p, j):

\[\frac{\partial M_{t, p, j}}{\partial t} = F_{in, t, p, j} - F_{out, t, p, j} + N_{kinetic, t, p, j} + N_{equilibrium, t, p, j} + N_{pe, t, p, j} + N_{transfer, t, p, j} + N_{custom, t, p, j}\]

The \(N_{custom, t, p, j}\) term allows the user to provide custom terms (variables or expressions) in both mass and molar basis which will be added into the material balances, which will be converted as necessary to the same basis as the material balance (by multiplying or dividing by the component molecular weight). The basis of the material balance is determined by the physical property package, and if undefined (or not mass or mole basis), an Exception will be returned.

If has_holdup is True, material_holdup_calculation(t, p, j):

\[M_{t, p, j} = \rho_{t, p, j} \times V_{t} \times \phi_{t, p}\]

where \(\rho_{t, p ,j}\) is the density of component \(j\) in phase \(p\) at time \(t\)

If dynamic is True:

Numerical discretization of the derivative terms, \(\frac{\partial M_{t,p,j}}{\partial t}\), will be performed by Pyomo.DAE.

If has_rate_reactions is True, rate_reaction_stoichiometry_constraint(t, p, j):

\[N_{kinetic, t, p, j} = \alpha_{r, p, j} \times X_{kinetic, t, r}\]

where \(\alpha_{r, p. j}\) is the stoichiometric coefficient of component \(j\) in phase \(p\) for reaction \(r\) (as defined in the PhysicalParameterBlock).

If has_equilibrium_reactions argument is True, equilibrium_reaction_stoichiometry_constraint(t, p, j):

\[N_{equilibrium, t, p, j} = \alpha_{r, p, j} \times X_{equilibrium, t, r}\]

where \(\alpha_{r, p. j}\) is the stoichiometric coefficient of component \(j\) in phase \(p\) for reaction \(r\) (as defined in the PhysicalParameterBlock).

add_total_component_balances

Material balances are written for each component across all phases (e.g. one balance for both liquid water and steam). Most terms in the balance equations are still indexed by both phase and component however. Physical property packages may include information to indicate that certain species do not appear in all phases, and material balances will not be written in these cases (if has_holdup is True holdup terms will still appear for these species, however these will be set to 0).

Variables

Variable Name Symbol Indices Conditions
material_holdup \(M_{t,p,j}\) t, p, j has_holdup = True
phase_fraction \(\phi_{t,p}\) t, p has_holdup = True
material_accumulation \(\frac{\partial M_{t,p,j}}{\partial t}\) t, p, j dynamic = True
rate_reaction_generation \(N_{kinetic,t,p,j}\) t, p ,j has_rate_reactions = True
rate_reaction_extent \(X_{kinetic,t,r}\) t, r has_rate_reactions = True
equilibrium_reaction_generation \(N_{equilibrium,t,p,j}\) t, p ,j has_equilibrium_reactions = True
equilibrium_reaction_extent \(X_{equilibrium,t,r}\) t, r has_equilibrium_reactions = True
mass_transfer_term \(N_{transfer,t,p,j}\) t, p ,j has_mass_transfer = True

Constraints

material_balances(t, j):

\[\sum_p{\frac{\partial M_{t, p, j}}{\partial t}} = \sum_p{F_{in, t, p, j}} - \sum_p{F_{out, t, p, j}} + \sum_p{N_{kinetic, t, p, j}} + \sum_p{N_{equilibrium, t, p, j}} + \sum_p{N_{pe, t, p, j}} + \sum_p{N_{transfer, t, p, j}} + N_{custom, t, j}\]

The \(N_{custom, t, j}\) term allows the user to provide custom terms (variables or expressions) in both mass and molar basis which will be added into the material balances, which will be converted as necessary to the same basis as the material balance (by multiplying or dividing by the component molecular weight). The basis of the material balance is determined by the physical property package, and if undefined (or not mass or mole basis), an Exception will be returned.

If has_holdup is True, material_holdup_calculation(t, p, j):

\[M_{t, p, j} = \rho_{t, p, j} \times V_{t} \times \phi_{t, p}\]

where \(\rho_{t, p ,j}\) is the density of component \(j\) in phase \(p\) at time \(t\)

If dynamic is True:

Numerical discretization of the derivative terms, \(\frac{\partial M_{t,p,j}}{\partial t}\), will be performed by Pyomo.DAE.

If has_rate_reactions is True,, rate_reaction_stoichiometry_constraint(t, p, j):

\[N_{kinetic, t, p, j} = \alpha_{r, p, j} \times X_{kinetic, t, r}\]

where \(\alpha_{r, p. j}\) is the stoichiometric coefficient of component \(j\) in phase \(p\) for reaction \(r\) (as defined in the PhysicalParameterBlock).

If has_equilibrium_reactions argument is True, equilibrium_reaction_stoichiometry_constraint(t, p, j):

\[N_{equilibrium, t, p, j} = \alpha_{r, p, j} \times X_{equilibrium, t, r}\]

where \(\alpha_{r, p. j}\) is the stoichiometric coefficient of component \(j\) in phase \(p\) for reaction \(r\) (as defined in the PhysicalParameterBlock).

add_total_element_balances

Material balances are written for each element in the mixture.

Variables

Variable Name Symbol Indices Conditions
element_holdup \(M_{t,e}\) t, e has_holdup = True
phase_fraction \(\phi_{t,p}\) t, p has_holdup = True
element_accumulation \(\frac{\partial M_{t,e}}{\partial t}\) t, e dynamic = True
elemental_mass_transfer_term \(N_{transfer,t,e}\) t, e has_mass_transfer = True

Expressions

elemental_flow_in(t, p, e):

\[F_{in,t,p,e} = \sum_j{F_{in, t, p, j}} \times n_{j, e}\]

elemental_flow_out(t, p, e):

\[F_{out,t,p,e} = \sum_j{F_{out, t, p, j}} \times n_{j, e}\]

where \(n_{j, e}\) is the number of moles of element \(e\) in component \(j\).

Constraints

element_balances(t, e):

\[\frac{\partial M_{t, e}}{\partial t} = \sum_p{F_{in, t, p, e}} - \sum_p{F_{out, t, p, e}} + \sum_p{N_{transfer, t, e}} + N_{custom, t, e}\]

The \(N_{custom, t, e}\) term allows the user to provide custom terms (variables or expressions) which will be added into the material balances.

If has_holdup is True, elemental_holdup_calculation(t, e):

\[M_{t, e} = V_{t} \times \sum_{p, j}{\phi_{t, p} \times \rho_{t, p, j} \times n_{j, e}}\]

where \(\rho_{t, p ,j}\) is the density of component \(j\) in phase \(p\) at time \(t\)

If dynamic is True:

Numerical discretization of the derivative terms, \(\frac{\partial M_{t,e}}{\partial t}\), will be performed by Pyomo.DAE.

add_total_enthalpy_balances

A single enthalpy balance is written for the entire mixture.

Variables

Variable Name Symbol Indices Conditions
enthalpy_holdup \(E_{t,p}\) t, p has_holdup = True
phase_fraction \(\phi_{t,p}\) t, p has_holdup = True
enthalpy_accumulation \(\frac{\partial E_{t,p}}{\partial t}\) t, p dynamic = True
heat \(Q_{t}\) t has_heat_transfer = True
work \(W_{t}\) t has_work_transfer = True

Expressions

heat_of_reaction(t):

\[Q_{rxn, t} = sum_r{X_{kinetic, t, r} \times \Delta H_{rxn, r}} + sum_r{X_{equilibrium, t, r} \times \Delta H_{rxn, r}}\]

where \(Q_{rxn, t}\) is the total enthalpy released by both kinetic and equilibrium reactions, and \(\Delta H_{rxn, r}\) is the specific heat of reaction for reaction \(r\).

Parameters

Parameter Name Symbol Default Value
scaling_factor_energy \(s_{energy}\) 1E-6

Constraints

enthalpy_balance(t):

\[s_{energy} \times \sum_p{\frac{\partial E_{t, p}}{\partial t}} = s_{energy} \times \sum_p{H_{in, t, p}} - s_{energy} \times \sum_p{H_{out, t, p}} + s_{energy} \times Q_t + s_{energy} \times W_t + s_{energy} \times Q_{rxn, t} + s_{energy} \times E_{custom, t}\]

The \(E_{custom, t}\) term allows the user to provide custom terms which will be added into the energy balance.

If has_holdup is True, enthalpy_holdup_calculation(t, p):

\[E_{t, p} = h_{t, p} \times V_{t} \times \phi_{t, p}\]

where \(h_{t, p}\) is the enthalpy density (specific enthalpy) of phase \(p\) at time \(t\)

If dynamic is True:

Numerical discretization of the derivative terms, \(\frac{\partial E_{t,p}}{\partial t}\), will be performed by Pyomo.DAE.

add_total_pressure_balances

A single pressure balance is written for the entire mixture.

Variables

Variable Name Symbol Indices Conditions
deltaP \(\Delta P_{t}\) t has_pressure_change = True

Parameters

Parameter Name Symbol Default Value
scaling_factor_pressure \(s_{pressure}\) 1E-4

Constraints

pressure_balance(t):

\[0 = s_{pressure} \times P_{in, t} - s_{pressure} \times P_{out, t} + s_{pressure} \times \Delta P_t + s_{pressure} \times \Delta P_{custom, t}\]

The \(\Delta P_{custom, t}\) term allows the user to provide custom terms which will be added into the pressure balance.

1D Control Volume Class

The ControlVolume1DBlock block is used for systems with one spatial dimension where material flows parallel to the spatial domain. Examples of these types of unit operations include plug flow reactors and pipes. ControlVolume1DBlock blocks are discretized along the length domain and contain one StateBlock and one ReactionBlock (if applicable) at each point in the domain (including the inlet and outlet).

class idaes.core.control_volume1d.ControlVolume1DBlock(*args, **kwargs)

ControlVolume1DBlock is a specialized Pyomo block for IDAES control volume blocks discretized in one spatial direction, and contains instances of ControlVolume1DBlockData.

ControlVolume1DBlock should be used for any control volume with a defined volume and distinct inlets and outlets where there is a single spatial domain parallel to the material flow direction. This encompases unit operations such as plug flow reactors and pipes.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic, default - useDefault. Valid values: { useDefault - get flag from parent, True - set as a dynamic model, False - set as a steady-state model}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    reaction_package
    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}
    reaction_package_args
    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}
    auto_construct
    If set to True, this argument will trigger the auto_construct method which will attempt to construct a set of material, energy and momentum balance equations based on the parent unit’s config block. The parent unit must have a config block which derives from CONFIG_Base, default - False. Valid values: { True - use automatic construction, False - do not use automatic construciton.}
    area_definition
    Argument defining whether area variable should be spatially variant or not. default - DistributedVars.uniform. Valid values: { DistributedVars.uniform - area does not vary across spatial domian, DistributedVars.variant - area can vary over the domain and is indexed by time and space.}
    transformation_method
    Method to use to transform domain. Must be a method recognised by the Pyomo TransformationFactory.
    transformation_scheme
    Scheme to use when transformating domain. See Pyomo documentation for supported schemes.
    finite_elements
    Number of finite elements to use in transformation (equivalent to Pyomo nfe argument).
    collocation_points
    Number of collocation points to use (equivalent to Pyomo ncp argument).
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(ControlVolume1DBlock) New instance

class idaes.core.control_volume1d.ControlVolume1DBlockData(component)[source]

1-Dimensional ControlVolume Class

This class forms the core of all 1-D IDAES models. It provides methods to build property and reaction blocks, and add mass, energy and momentum balances. The form of the terms used in these constraints is specified in the chosen property package.

add_geometry(length_domain=None, length_domain_set=[0.0, 1.0], flow_direction=<FlowDirection.forward: 1>)[source]

Method to create spatial domain and volume Var in ControlVolume.

Parameters:
  • - (length_domain_set) – domain for the ControlVolume. If not provided, a new ContinuousSet will be created (default=None). ContinuousSet should be normalized to run between 0 and 1.
  • - – a new ContinuousSet if length_domain is not provided (default = [0.0, 1.0]).
  • - argument indicating direction of material flow (flow_direction) –
    relative to length domain. Valid values:
    • FlowDirection.forward (default), flow goes from 0 to 1.
    • FlowDirection.backward, flow goes from 1 to 0
Returns:

None

add_phase_component_balances(has_rate_reactions=False, has_equilibrium_reactions=False, has_phase_equilibrium=False, has_mass_transfer=False, custom_molar_term=None, custom_mass_term=None)[source]

This method constructs a set of 1D material balances indexed by time, length, phase and component.

Parameters:
  • has_rate_reactions – whether default generation terms for rate reactions should be included in material balances
  • has_equilibrium_reactions – whether generation terms should for chemical equilibrium reactions should be included in material balances
  • has_phase_equilibrium – whether generation terms should for phase equilibrium behaviour should be included in material balances
  • has_mass_transfer – whether generic mass transfer terms should be included in material balances
  • custom_molar_term – a Pyomo Expression representing custom terms to be included in material balances on a molar basis. Expression must be indexed by time, length domain, phase list and component list
  • custom_mass_term – a Pyomo Expression representing custom terms to be included in material balances on a mass basis. Expression must be indexed by time, length domain, phase list and component list
Returns:

Constraint object representing material balances

add_phase_energy_balances(*args, **kwargs)[source]

Method for adding energy balances (including kinetic energy) indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_enthalpy_balances(*args, **kwargs)[source]

Method for adding enthalpy balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_momentum_balances(*args, **kwargs)[source]

Method for adding momentum balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_pressure_balances(*args, **kwargs)[source]

Method for adding pressure balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_reaction_blocks(has_equilibrium=None)[source]

This method constructs the reaction block for the control volume.

Parameters:
  • has_equilibrium – indicates whether equilibrium calculations will be required in reaction block
  • package_arguments – dict-like object of arguments to be passed to reaction block as construction arguments
Returns:

None

add_state_blocks(information_flow=<FlowDirection.forward: 1>, has_phase_equilibrium=None)[source]

This method constructs the state blocks for the control volume.

Parameters:
  • information_flow – a FlowDirection Enum indicating whether information flows from inlet-to-outlet or outlet-to-inlet
  • has_phase_equilibrium – indicates whether equilibrium calculations will be required in state blocks
  • package_arguments – dict-like object of arguments to be passed to state blocks as construction arguments
Returns:

None

add_total_component_balances(has_rate_reactions=False, has_equilibrium_reactions=False, has_phase_equilibrium=False, has_mass_transfer=False, custom_molar_term=None, custom_mass_term=None)[source]

This method constructs a set of 1D material balances indexed by time length and component.

Parameters:
  • has_rate_reactions – whether default generation terms for rate reactions should be included in material balances
  • has_equilibrium_reactions – whether generation terms should for chemical equilibrium reactions should be included in material balances
  • has_phase_equilibrium – whether generation terms should for phase equilibrium behaviour should be included in material balances
  • has_mass_transfer – whether generic mass transfer terms should be included in material balances
  • custom_molar_term – a Pyomo Expression representing custom terms to be included in material balances on a molar basis. Expression must be indexed by time, length domain and component list
  • custom_mass_term – a Pyomo Expression representing custom terms to be included in material balances on a mass basis. Expression must be indexed by time, length domain and component list
Returns:

Constraint object representing material balances

add_total_element_balances(has_rate_reactions=False, has_equilibrium_reactions=False, has_phase_equilibrium=False, has_mass_transfer=False, custom_elemental_term=None)[source]

This method constructs a set of 1D element balances indexed by time and length.

Parameters:
  • - whether default generation terms for rate (has_rate_reactions) – reactions should be included in material balances
  • - whether generation terms should for (has_equilibrium_reactions) – chemical equilibrium reactions should be included in material balances
  • - whether generation terms should for phase (has_phase_equilibrium) – equilibrium behaviour should be included in material balances
  • - whether generic mass transfer terms should be (has_mass_transfer) – included in material balances
  • - a Pyomo Expression representing custom (custom_elemental_term) – terms to be included in material balances on a molar elemental basis. Expression must be indexed by time, length and element list
Returns:

Constraint object representing material balances

add_total_energy_balances(*args, **kwargs)[source]

Method for adding a total energy balance (including kinetic energy) to the control volume.

See specific control volume documentation for details.

add_total_enthalpy_balances(has_heat_of_reaction=False, has_heat_transfer=False, has_work_transfer=False, custom_term=None)[source]

This method constructs a set of 1D enthalpy balances indexed by time and phase.

Parameters:
  • - whether terms for heat of reaction should (has_heat_of_reaction) – be included in enthalpy balance
  • - whether terms for heat transfer should be (has_heat_transfer) – included in enthalpy balances
  • - whether terms for work transfer should be (has_work_transfer) – included in enthalpy balances
  • - a Pyomo Expression representing custom terms to (custom_term) – be included in enthalpy balances. Expression must be indexed by time, length and phase list
Returns:

Constraint object representing enthalpy balances

add_total_material_balances(*args, **kwargs)[source]

Method for adding a total material balance to the control volume.

See specific control volume documentation for details.

add_total_momentum_balances(*args, **kwargs)[source]

Method for adding a total momentum balance to the control volume.

See specific control volume documentation for details.

add_total_pressure_balances(has_pressure_change=False, custom_term=None)[source]

This method constructs a set of 1D pressure balances indexed by time.

Parameters:
  • - whether terms for pressure change should be (has_pressure_change) – included in enthalpy balances
  • - a Pyomo Expression representing custom terms to (custom_term) – be included in pressure balances. Expression must be indexed by time and length domain
Returns:

Constraint object representing pressure balances

apply_transformation()[source]

Method to apply DAE transformation to the Control Volume length domain. Transformation applied will be based on the Control Volume configuration arguments.

build()[source]

Build method for ControlVolume1DBlock blocks.

Returns:None
initialize(state_args=None, outlvl=0, optarg=None, solver='ipopt', hold_state=True)[source]

Initialisation routine for 1D control volume (default solver ipopt)

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl – sets output level of initialisation routine. Valid values: 0 - no output (default), 1 - return solver state for each step in routine, 2 - include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default=None)
  • solver – str indicating whcih solver to use during initialization (default = ‘ipopt’)
  • hold_state – flag indicating whether the initialization routine should unfix any state variables fixed during initialization, default - True. Valid values: True - states variables are not unfixed, and a dict of returned containing flags for which states were fixed during initialization, False - state variables are unfixed after initialization by calling the release_state method.
Returns:

If hold_states is True, returns a dict containing flags for which states were fixed during initialization else the release state is triggered.

model_check()[source]

This method executes the model_check methods on the associated state blocks (if they exist). This method is generally called by a unit model as part of the unit’s model_check method.

Parameters:None
Returns:None
release_state(flags, outlvl=0)[source]

Method to release state variables fixed during initialisation.

Keyword Arguments:
 
  • flags – dict containing information of which state variables were fixed during initialization, and should now be unfixed. This dict is returned by initialize if hold_state = True.
  • outlvl – sets output level of logging
Returns:

None

ControlVolume1DBlock Equations

This section documents the variables and constraints created by each of the methods provided by the ControlVolume0DBlock class.

  • \(t\) indicates time index
  • \(x\) indicates spatial (length) index
  • \(p\) indicates phase index
  • \(j\) indicates component index
  • \(e\) indicates element index
  • \(r\) indicates reaction name index

Most terms within the balance equations written by ControlVolume1DBlock are on a basis of per unit length (e.g. \(mol/m \cdot s\)).

add_geometry

The add_geometry method creates the normalized length domain for the control volume (or a reference to an external domain). All constraints in ControlVolume1DBlock assume a normalized length domain, with values between 0 and 1.

This method also adds variables and constraints to describe the geometry of the control volume. ControlVolume1DBlock does not support varying dimensions of the control volume with time at this stage.

Variables

Variable Name Symbol Indices Conditions
length_domain \(x\) None None
volume \(V\) None None
area \(A\) None None
length \(L\) None None

Constraints

geometry_constraint:

\[V = A \times L\]
add_phase_component_balances

Material balances are written for each component in each phase (e.g. separate balances for liquid water and steam). Physical property packages may include information to indicate that certain species do not appear in all phases, and material balances will not be written in these cases (if has_holdup is True holdup terms will still appear for these species, however these will be set to 0).

Variables

Variable Name Symbol Indices Conditions
material_holdup \(M_{t,x,p,j}\) t, x, p, j has_holdup = True
phase_fraction \(\phi_{t,x,p}\) t, x, p has_holdup = True
material_accumulation \(\frac{\partial M_{t,x,p,j}}{\partial t}\) t, x, p, j dynamic = True
_flow_terms \(F_{t, x, p, j}\) t, x, p, j None
material_flow_dx \(\frac{\partial F_{t,x,p,j}}{\partial x}\) t, x, p, j None
rate_reaction_generation \(N_{kinetic,t,x,p,j}\) t, x, p ,j has_rate_reactions = True
rate_reaction_extent \(X_{kinetic,t,x,r}\) t, x, r has_rate_reactions = True
equilibrium_reaction_generation \(N_{equilibrium,t,x,p,j}\) t, x, p ,j has_equilibrium_reactions = True
equilibrium_reaction_extent \(X_{equilibrium,t,x,r}\) t, x, r has_equilibrium_reactions = True
phase_equilibrium_generation \(N_{pe,t,x,p,j}\) t, x, p ,j has_phase_equilibrium = True
mass_transfer_term \(N_{transfer,t,x,p,j}\) t, x, p ,j has_mass_transfer = True

Constraints

material_balances(t, x, p, j):

\[L \times \frac{\partial M_{t, x, p, j}}{\partial t} = fd \times \frac{\partial F_{t, x, p, j}}{\partial x} + L \times N_{kinetic, t, x, p, j} + L \times N_{equilibrium, t, x, p, j} + L \times N_{pe, t, x, p, j} + L \times N_{transfer, t, x, p, j} + L \times N_{custom, t, x, p, j}\]

\(fd\) is a flow direction term, which allows for material flow to be defined in either direction. If material flow is defined as forward, \(fd = -1\), otherwise \(fd = 1\).

The \(N_{custom, t, x, p, j}\) term allows the user to provide custom terms (variables or expressions) in both mass and molar basis which will be added into the material balances, which will be converted as necessary to the same basis as the material balance (by multiplying or dividing by the component molecular weight). The basis of the material balance is determined by the physical property package, and if undefined (or not mass or mole basis), an Exception will be returned.

material_flow_linking_constraints(t, x, p, j):

This constraint is an internal constraint used to link the extensive material flow terms in the StateBlocks into a single indexed variable. This is required as Pyomo.DAE requires a single indexed variable to create the associated DerivativeVars and their numerical expansions.

If has_holdup is True, material_holdup_calculation(t, x, p, j):

\[M_{t, x, p, j} = \rho_{t, x, p, j} \times A \times \phi_{t, x, p}\]

where \(\rho_{t, x, p ,j}\) is the density of component \(j\) in phase \(p\) at time \(t\) and location \(x\).

If dynamic is True:

Numerical discretization of the derivative terms, \(\frac{\partial M_{t,x,p,j}}{\partial t}\), will be performed by Pyomo.DAE.

If has_rate_reactions is True, rate_reaction_stoichiometry_constraint(t, x, p, j):

\[N_{kinetic, t, x, p, j} = \alpha_{r, p, j} \times X_{kinetic, t, x, r}\]

where \(\alpha_{r, p. j}\) is the stoichiometric coefficient of component \(j\) in phase \(p\) for reaction \(r\) (as defined in the PhysicalParameterBlock).

If has_equilibrium_reactions argument is True, equilibrium_reaction_stoichiometry_constraint(t, x, p, j):

\[N_{equilibrium, t, x, p, j} = \alpha_{r, p, j} \times X_{equilibrium, t, x, r}\]

where \(\alpha_{r, p. j}\) is the stoichiometric coefficient of component \(j\) in phase \(p\) for reaction \(r\) (as defined in the PhysicalParameterBlock).

add_total_component_balances

Material balances are written for each component across all phases (e.g. one balance for both liquid water and steam). Physical property packages may include information to indicate that certain species do not appear in all phases, and material balances will not be written in these cases (if has_holdup is True holdup terms will still appear for these species, however these will be set to 0).

Variables

Variable Name Symbol Indices Conditions
material_holdup \(M_{t,x,p,j}\) t, x, p, j has_holdup = True
phase_fraction \(\phi_{t,x,p}\) t, x, p has_holdup = True
material_accumulation \(\frac{\partial M_{t,x,p,j}}{\partial t}\) t, x, p, j dynamic = True
_flow_terms \(F_{t, x, p, j}\) t, x, p, j None
material_flow_dx \(\frac{\partial F_{t,x,p,j}}{\partial x}\) t, x, p, j None
rate_reaction_generation \(N_{kinetic,t,x,p,j}\) t, x, p ,j has_rate_reactions = True
rate_reaction_extent \(X_{kinetic,t,x,r}\) t, x, r has_rate_reactions = True
equilibrium_reaction_generation \(N_{equilibrium,t,x,p,j}\) t, x, p ,j has_equilibrium_reactions = True
equilibrium_reaction_extent \(X_{equilibrium,t,x,r}\) t, x, r has_equilibrium_reactions = True
mass_transfer_term \(N_{transfer,t,x,p,j}\) t, x, p ,j has_mass_transfer = True

Constraints

material_balances(t, x, p, j):

\[L \times \sum_p{\frac{\partial M_{t, x, p, j}}{\partial t}} = fd \times \sum{\frac{\partial F_{t, x, p, j}}{\partial x}} + L \times \sum_p{N_{kinetic, t, x, p, j}} + L \times \sum_p{N_{equilibrium, t, x, p, j}} + L \times \sum_p{N_{transfer, t, x, p, j}} + L \times N_{custom, t, x, j}\]

\(fd\) is a flow direction term, which allows for material flow to be defined in either direction. If material flow is defined as forward, \(fd = -1\), otherwise \(fd = 1\).

The \(N_{custom, t, x, j}\) term allows the user to provide custom terms (variables or expressions) in both mass and molar basis which will be added into the material balances, which will be converted as necessary to the same basis as the material balance (by multiplying or dividing by the component molecular weight). The basis of the material balance is determined by the physical property package, and if undefined (or not mass or mole basis), an Exception will be returned.

material_flow_linking_constraints(t, x, p, j):

This constraint is an internal constraint used to link the extensive material flow terms in the StateBlocks into a single indexed variable. This is required as Pyomo.DAE requires a single indexed variable to create the associated DerivativeVars and their numerical expansions.

If has_holdup is True, material_holdup_calculation(t, x, p, j):

\[M_{t, x, p, j} = \rho_{t, x, p, j} \times A \times \phi_{t, x, p}\]

where \(\rho_{t, x, p ,j}\) is the density of component \(j\) in phase \(p\) at time \(t\) and location \(x\).

If dynamic is True:

Numerical discretization of the derivative terms, \(\frac{\partial M_{t,x,p,j}}{\partial t}\), will be performed by Pyomo.DAE.

If has_rate_reactions is True, rate_reaction_stoichiometry_constraint(t, x, p, j):

\[N_{kinetic, t, x, p, j} = \alpha_{r, p, j} \times X_{kinetic, t, x, r}\]

where \(\alpha_{r, p. j}\) is the stoichiometric coefficient of component \(j\) in phase \(p\) for reaction \(r\) (as defined in the PhysicalParameterBlock).

If has_equilibrium_reactions argument is True, equilibrium_reaction_stoichiometry_constraint(t, x, p, j):

\[N_{equilibrium, t, x, p, j} = \alpha_{r, p, j} \times X_{equilibrium, t, x, r}\]

where \(\alpha_{r, p. j}\) is the stoichiometric coefficient of component \(j\) in phase \(p\) for reaction \(r\) (as defined in the PhysicalParameterBlock).

add_total_element_balances

Material balances are written for each element in the mixture.

Variables

Variable Name Symbol Indices Conditions
element_holdup \(M_{t,x,e}\) t, x, e has_holdup = True
phase_fraction \(\phi_{t,x,p}\) t, x, p has_holdup = True
element_accumulation \(\frac{\partial M_{t,x,e}}{\partial t}\) t, x, e dynamic = True
elemental_mass_transfer_term \(N_{transfer,t,x,e}\) t, x, e has_mass_transfer = True
elemental_flow_term \(F_{t,x,e}\) t, x, e None

Constraints

elemental_flow_constraint(t, x, e):

\[F_{t,x,e} = \sum_p{\sum_j{F_{t,x,p,j} \times n_{j, e}}}\]

where \(n_{j, e}\) is the number of moles of element \(e\) in component \(j\).

element_balances(t, x, e):

\[L \times \frac{\partial M_{t, x, e}}{\partial t} = fd \times \frac{\partial F_{t, x, e}}{\partial x} + L \times N_{transfer, t, p, j} + L \times N_{custom, t, e}\]

\(fd\) is a flow direction term, which allows for material flow to be defined in either direction. If material flow is defined as forward, \(fd = -1\), otherwise \(fd = 1\).

The \(N_{custom, t, x, e}\) term allows the user to provide custom terms (variables or expressions) which will be added into the material balances.

If has_holdup is True, elemental_holdup_calculation(t, x, e):

\[M_{t, x, e} = \rho_{t, x, p, j} \times A \times \phi_{t, x, p}\]

where \(\rho_{t, x, p ,j}\) is the density of component \(j\) in phase \(p\) at time \(t\) and location \(x\).

If dynamic is True:

Numerical discretization of the derivative terms, \(\frac{\partial M_{t,x,p,j}}{\partial t}\), will be performed by Pyomo.DAE.

add_total_enthalpy_balances

A single enthalpy balance is written for the entire mixture at each point in the spatial domain.

Variables

Variable Name Symbol Indices Conditions
enthalpy_holdup \(E_{t,x,p}\) t, x, p has_holdup = True
phase_fraction \(\phi_{t,x,p}\) t, x, p has_holdup = True
enthalpy_accumulation \(\frac{\partial E_{t,x,p}}{\partial t}\) t, x, p dynamic = True
_enthalpy_flow \(H_{t,x,p}\) t, x, p None
enthalpy_flow_dx \(\frac{\partial H_{t,x,p}}{\partial x}\) t, x, p None
heat \(Q_{t,x}\) t, x has_heat_transfer = True
work \(W_{t,x}\) t, x has_work_transfer = True

Expressions

heat_of_reaction(t, x):

\[Q_{rxn, t, x} = sum_r{X_{kinetic, t, x, r} \times \Delta H_{rxn, r}} + sum_r{X_{equilibrium, t, x, r} \times \Delta H_{rxn, r}}\]

where \(Q_{rxn, t, x}\) is the total enthalpy released by both kinetic and equilibrium reactions, and \(\Delta H_{rxn, r}\) is the specific heat of reaction for reaction \(r\).

Parameters

Parameter Name Symbol Default Value
scaling_factor_energy \(s_{energy}\) 1E-6

Constraints

enthalpy_balance(t):

\[s_{energy} \times L \times \sum_p{\frac{\partial E_{t, x, p}}{\partial t}} = s_{energy} \times fd \ times \sum_p{\frac{\partial H_{t, x, p}}{\partial x}} + s_{energy} \times L \times Q_{t,x} + s_{energy} \times L \times W_{t,x} + s_{energy} \times L \times Q_{rxn, t, x} + s_{energy} \times L \times E_{custom, t, x}\]

\(fd\) is a flow direction term, which allows for material flow to be defined in either direction. If material flow is defined as forward, \(fd = -1\), otherwise \(fd = 1\).

The \(E_{custom, t, x}\) term allows the user to provide custom terms which will be added into the energy balance.

enthalpy_flow_linking_constraints(t, x, p):

This constraint is an internal constraint used to link the extensive enthalpy flow terms in the StateBlocks into a single indexed variable. This is required as Pyomo.DAE requires a single indexed variable to create the associated DerivativeVars and their numerical expansions.

If has_holdup is True, enthalpy_holdup_calculation(t, x, p):

\[E_{t, x, p} = h_{t, x, p} \times A \times \phi_{t, x, p}\]

where \(h_{t, x, p}\) is the enthalpy density (specific enthalpy) of phase \(p\) at time \(t\) and location \(x\).

If dynamic is True:

Numerical discretization of the derivative terms, \(\frac{\partial E_{t,x,p}}{\partial t}\), will be performed by Pyomo.DAE.

add_total_pressure_balances

A single pressure balance is written for the entire mixture at all points in the spatial domain.

Variables

Variable Name Symbol Indices Conditions
pressure \(P_{t,x}\) t, x None
pressure_dx \(\frac{\partial P_{t,x}}{\partial x}\) t, x None
deltaP \(\Delta P_{t,x}\) t, x has_pressure_change = True

Parameters

Parameter Name Symbol Default Value
scaling_factor_pressure \(s_{pressure}\) 1E-4

Constraints

pressure_balance(t, x):

\[0 = s_{pressure} \times fd \times \frac{\partial P_{t,x}}{\partial x} + s_{pressure} \times L \times \Delta P_{t,x} + s_{pressure} \times L \times \Delta P_{custom, t, x}\]

\(fd\) is a flow direction term, which allows for material flow to be defined in either direction. If material flow is defined as forward, \(fd = -1\), otherwise \(fd = 1\).

The \(\Delta P_{custom, t, x}\) term allows the user to provide custom terms which will be added into the pressure balance.

pressure_linking_constraint(t, x):

This constraint is an internal constraint used to link the pressure terms in the StateBlocks into a single indexed variable. This is required as Pyomo.DAE requires a single indexed variable to create the associated DerivativeVars and their numerical expansions.

Control Volumes are the center of the IDAES process modeling framework, and serve as the fundamental building block of all unit operations. Control Volumes represent a single, well-defined volume of material over which material, energy and/or momentum balances will be performed.

The IDAES Control Volume classes are designed to facilitate the construction of these balance equations by providing the model developer with a set of pre-built methods to perform the most common tasks in developing models of unit operations. The Control Volume classes contain methods for creating and linking the necessary property calculations and writing common forms of the balance equations so that the model developer can focus their time on the aspects that make each unit model unique.

The IDAES process modeling framework currently supports two types of Control Volume:

  • ControlVolume0DBlock represents a single well-mixed volume of material with a single inlet and a single outlet. This type of control volume is sufficient to model most inlet-outlet type unit operations which do not require spatial discretization.
  • ControlVolume1DBlock represents a volume with spatial variation in one dimension parallel to the material flow. This type of control volume is useful for representing flow in pipes and simple 1D flow reactors.
Common Control Volume Tasks

All of the IDAES Control Volume classes are built on a common core (ControlVolumeBlockData) which defines a set of common tasks required for all Control Volumes. The more specific Control Volume classes then build upon these common tasks to provide tools appropriate for their specific application.

All Control Volume classes begin with the following tasks:

  • Determine if the ControlVolume should be steady-state or dynamic.
  • Get the time domain.
  • Determine whether material and energy holdups should be calculated.
  • Collect information necessary for creating StateBlocks and ReactionBlocks.
  • Create references to phase_list and component_list Sets in the PhysicalParameterBlock.

More details on these steps is provided later.

Setting up the time domain

The first common task the Control Volume block performs is to determine if it should be dynamic or steady-state and to collect the time domain from the UnitModel. Control Volume blocks have an argument dynamic which can be provided during construction which specifies if the Control Volume should be dynamic (dynamic=True) or steady-state (dynamic=False). If the argument is not provided, the Control Volume block will inherit this argument from its parent UnitModel.

Finally, the Control Volume checks that the has_holdup argument is consistent with the dynamic argument, and raises a ConfigurationError if it is not.

Getting Property Package Information

If a reference to a property package was not provided by the UnitModel as an argument, the Control Volume first checks to see if the UnitModel has a property_package argument set, and uses this if present. Otherwise, the Control Volume block begins searching up the model tree looking for an argument named default_property_package and uses the first of these that it finds. If no default_property_package is found, a ConfigurationError is returned.

Collecting Indexing Sets for Property Package

The final common step for all Control Volumes is to collect any required indexing sets from the physical property package (for example component and phase lists). These are used by the Control Volume for determining what balance equations need to be written, and what terms to create.

The indexing sets the Control Volume looks for are:

  • component_list - used to determine what components are present, and thus what material balances are required
  • phase_list - used to determine what phases are present, and thus what balance equations are required
ControlVolume and ControlVolumeBlockData Classes

A key purpose of Control Volumes is to automate as much of the task of writing a unit model as possible. For this purpose, Control Volumes support a number of methods for common tasks model developers may want to perform. The specifics of these methods will be different between different types of Control Volumes, and certain methods may not be applicable to some types of Control Volumes (in which case a NotImplementedError will be returned). A full list of potential methods is provided here, however users should check the documentation for the specific Control Volume they are using for more details on what methods are supported in that specific Control Volume.

class idaes.core.control_volume_base.ControlVolume(*args, **kwargs)

This class is not usually used directly. Use ControlVolume0DBlock or ControlVolume1DBlock instead.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic, default - useDefault. Valid values: { useDefault - get flag from parent, True - set as a dynamic model, False - set as a steady-state model}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    reaction_package
    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}
    reaction_package_args
    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}
    auto_construct
    If set to True, this argument will trigger the auto_construct method which will attempt to construct a set of material, energy and momentum balance equations based on the parent unit’s config block. The parent unit must have a config block which derives from CONFIG_Base, default - False. Valid values: { True - use automatic construction, False - do not use automatic construciton.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(ControlVolume) New instance

class idaes.core.control_volume_base.ControlVolumeBlockData(component)[source]

The ControlVolumeBlockData Class forms the base class for all IDAES ControlVolume models. The purpose of this class is to automate the tasks common to all control volume blockss and ensure that the necessary attributes of a control volume block are present.

The most signfiicant role of the ControlVolumeBlockData class is to set up the construction arguments for the control volume block, automatically link to the time domain of the parent block, and to get the information about the property and reaction packages.

add_energy_balances(balance_type=<EnergyBalanceType.enthalpyPhase: 1>, **kwargs)[source]

General method for adding energy balances to a control volume. This method makes calls to specialised sub-methods for each type of energy balance.

Parameters:
  • balance_type (EnergyBalanceType) – Enum indicating which type of energy balance should be constructed.
  • has_heat_of_reaction (bool) – whether terms for heat of reaction should be included in energy balance
  • has_heat_transfer (bool) – whether generic heat transfer terms should be included in energy balances
  • has_work_transfer (bool) – whether generic mass transfer terms should be included in energy balances
  • custom_term (Expression) – a Pyomo Expression representing custom terms to be included in energy balances
Returns:

Constraint objects constructed by sub-method

add_geometry(*args, **kwargs)[source]

Method for defining the geometry of the control volume.

See specific control volume documentation for details.

add_material_balances(balance_type=<MaterialBalanceType.componentPhase: 1>, **kwargs)[source]

General method for adding material balances to a control volume. This method makes calls to specialised sub-methods for each type of material balance.

Parameters:
  • - MaterialBalanceType Enum indicating which type of (balance_type) – material balance should be constructed.
  • - whether default generation terms for rate (has_rate_reactions) – reactions should be included in material balances
  • - whether generation terms should for (has_equilibrium_reactions) – chemical equilibrium reactions should be included in material balances
  • - whether generation terms should for phase (has_phase_equilibrium) – equilibrium behaviour should be included in material balances
  • - whether generic mass transfer terms should be (has_mass_transfer) – included in material balances
  • - a Pyomo Expression representing custom terms to (custom_mass_term) – be included in material balances on a molar basis.
  • - a Pyomo Expression representing custom terms to – be included in material balances on a mass basis.
Returns:

Constraint objects constructed by sub-method

add_momentum_balances(balance_type=<MomentumBalanceType.pressureTotal: 1>, **kwargs)[source]

General method for adding momentum balances to a control volume. This method makes calls to specialised sub-methods for each type of momentum balance.

Parameters:
  • balance_type (MomentumBalanceType) – Enum indicating which type of momentum balance should be constructed.
  • has_pressure_change (bool) – whether default generation terms for pressure change should be included in momentum balances
  • custom_term (Expression) – a Pyomo Expression representing custom terms to be included in momentum balances
Returns:

Constraint objects constructed by sub-method

add_phase_component_balances(*args, **kwargs)[source]

Method for adding material balances indexed by phase and component to the control volume.

See specific control volume documentation for details.

add_phase_energy_balances(*args, **kwargs)[source]

Method for adding energy balances (including kinetic energy) indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_enthalpy_balances(*args, **kwargs)[source]

Method for adding enthalpy balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_momentum_balances(*args, **kwargs)[source]

Method for adding momentum balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_pressure_balances(*args, **kwargs)[source]

Method for adding pressure balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_reaction_blocks(*args, **kwargs)[source]

Method for adding ReactionBlocks to the control volume.

See specific control volume documentation for details.

add_state_blocks(*args, **kwargs)[source]

Method for adding StateBlocks to the control volume.

See specific control volume documentation for details.

add_total_component_balances(*args, **kwargs)[source]

Method for adding material balances indexed by component to the control volume.

See specific control volume documentation for details.

add_total_element_balances(*args, **kwargs)[source]

Method for adding total elemental material balances indexed to the control volume.

See specific control volume documentation for details.

add_total_energy_balances(*args, **kwargs)[source]

Method for adding a total energy balance (including kinetic energy) to the control volume.

See specific control volume documentation for details.

add_total_enthalpy_balances(*args, **kwargs)[source]

Method for adding a total enthalpy balance to the control volume.

See specific control volume documentation for details.

add_total_material_balances(*args, **kwargs)[source]

Method for adding a total material balance to the control volume.

See specific control volume documentation for details.

add_total_momentum_balances(*args, **kwargs)[source]

Method for adding a total momentum balance to the control volume.

See specific control volume documentation for details.

add_total_pressure_balances(*args, **kwargs)[source]

Method for adding a total pressure balance to the control volume.

See specific control volume documentation for details.

build()[source]

General build method for Control Volumes blocks. This method calls a number of sub-methods which automate the construction of expected attributes of all ControlVolume blocks.

Inheriting models should call super().build.

Parameters:None
Returns:None
Auto-Construct Method

To reduce the demands on unit model developers even further, Control Volumes have an optional auto-construct feature that will attempt to populate the Control Volume based on a set of instructions provided at the Unit Model level. If the auto_construct configuration argument is set to True, the following methods are called automatically in the following order when instantiating the Control Volume.

  1. add_geometry
  2. add_state_blocks
  3. add_reaction_blocks
  4. add_material_balances
  5. add_energy_balances
  6. add_momentum_balances
  7. apply_transformation

To determine what terms are required for the balance equations, the Control Volume expects the Unit Model to have the following configuration arguments, which are used as arguments to the methods above.

  • dynamic
  • has_holdup
  • material_balance_type
  • energy_balance_type
  • momentum_balance_type
  • has_rate_reactions
  • has_equilibrium_reactions
  • has_phase_equilibrium
  • has_mass_transfer
  • has_heat_of_reaction
  • has_heat_transfer
  • has_work_transfer
  • has_pressure_change
  • property_package
  • property_package_args
  • reaction_package
  • reaction_package_args

For convenience, a template ConfigBlock (named CONFIG_Template) is available in the control_volume_base.py module which contains all the necessary arguments which can be inherited by unit models wishing to use the auto-construct feature.

Utility Methods
Model State Serialization

The IDAES framework has some utility functions for serializing the state of a Pyomo model. These functions can save and load attributes of Pyomo components, but cannot reconstruct the Pyomo objects (it is not a replacement for pickle). It does have some advantages over pickle though. Not all Pyomo models are picklable. Serialization and deserialization of the model state to/from json is more secure in that it only deals with data and not executable code. It should be safe to use the from_json() function with data from untrusted sources, while, unpickling an object from an untrusted source is not secure. Storing a model state using these functions is also probably more robust against Python and Python package version changes, and possibly more suitable for long-term storage of results.

Below are a few example use cases for this module.

  • Some models are very complex and may take minutes to initialize. Once a model is initialized it’s state can be saved. For future runs, the initialized state can be reloaded instead of rerunning the initialization procedure.
  • Results can be stored for later evaluation without needing to rerun the model. These results can be archived in a data management system if needed later.
  • These functions may be useful in writing initialization procedures. For example, a model may be constructed and ready to run but first it may need to be initialized. Which components are active and which variables are fixed can be stored. The initialization can change which variables are fixed and which components are active. The original state can be read back after initialization, but where only values of variables that were originally fixed are read back in. This is an easy way to ensure that whatever the initialization procedure may do, the result is exactly the same problem (with only better initial values for unfixed variables).
  • These functions can be used to send and receive model data to/from JavaScript user interface components.
Examples

This section provides a few very simple examples of how to use these functions.

Example Models

This section provides some boilerplate and functions to create a couple simple test models. The second model is a little more complicated and includes suffixes.

from pyomo.environ import *
from idaes.core.util import to_json, from_json, StoreSpec

def setup_model01():
    model = ConcreteModel()
    model.b = Block([1,2,3])
    a = model.b[1].a = Var(bounds=(-100, 100), initialize=2)
    b = model.b[1].b = Var(bounds=(-100, 100), initialize=20)
    model.b[1].c = Constraint(expr=b==10*a)
    a.fix(2)
    return model

def setup_model02():
    model = ConcreteModel()
    a = model.a = Param(default=1, mutable=True)
    b = model.b = Param(default=2, mutable=True)
    c = model.c = Param(initialize=4)
    x = model.x = Var([1,2], initialize={1:1.5, 2:2.5}, bounds=(-10,10))
    model.f = Objective(expr=(x[1] - a)**2 + (x[2] - b)**2)
    model.g = Constraint(expr=x[1] + x[2] - c >= 0)
    model.dual = Suffix(direction=Suffix.IMPORT)
    model.ipopt_zL_out = Suffix(direction=Suffix.IMPORT)
    model.ipopt_zU_out = Suffix(direction=Suffix.IMPORT)
    return model
Serialization

These examples can be appended to the boilerplate code above.

The first example creates a model, saves the state, changes a value, then reads back the initial state.

model = setup_model01()
to_json(model, fname="ex.json.gz", gz=True, human_read=True)
model.b[1].a = 3000.4
from_json(model, fname="ex.json.gz", gz=True)
print(value(model.b[1].a))
2

This next example show how to save only suffixes.

model = setup_model02()
# Suffixes here are read back from solver, so to have suffix data,
# need to solve first
solver = SolverFactory("ipopt")
solver.solve(model)
store_spec = StoreSpec.suffix()
to_json(model, fname="ex.json", wts=store_spec)
# Do something and now I want my suffixes back
from_json(model, fname="ex.json", wts=store_spec)
to_json

Despite the name of the to_json function it is capable of creating Python dictionaries, json files, gzipped json files, and json strings. The function documentation is below. A StoreSpec object provides the function with details on what to store and how to handle special cases of Pyomo component attributes.

idaes.core.util.model_serializer.to_json(o, fname=None, human_read=False, wts=None, metadata={}, gz=False, return_dict=False, return_json_string=False)[source]

Save the state of a model to a Python dictionary, and optionally dump it to a json file. To load a model state, a model with the same structure must exist. The model itself cannot be recreated from this.

Parameters:
  • o – The Pyomo component object to save. Usually a Pyomo model, but could also be a subcomponent of a model (usually a sub-block).
  • fname – json file name to save model state, if None only create python dict
  • gz – If fname is given and gv is True gzip the json file. The default is False.
  • human_read – if True, add indents and spacing to make the json file more readable, if false cut out whitespace and make as compact as possilbe
  • metadata – A dictionary of addtional metadata to add.
  • wts – is What To Save, this is a StoreSpec object that specifies what object types and attributes to save. If None, the default is used which saves the state of the compelte model state.
  • metadata – addtional metadata to save beyond the standard format_version, date, and time.
  • return_dict – default is False if true returns a dictionary representation
  • return_json_string – default is False returns a json string
Returns:

If return_dict is True returns a dictionary serialization of the Pyomo component. If return_dict is False and return_json_string is True returns a json string dump of the dict. If fname is given the dictionary is also written to a json file. If gz is True and fname is given, writes a gzipped json file.

from_json

The from_json function puts data from Python dictionaries, json files, gzipped json files, and json strings back into a Pyomo model. The function documentation is below. A StoreSpec object provides the function with details on what to read and how to handle special cases of Pyomo component attributes.

idaes.core.util.model_serializer.from_json(o, sd=None, fname=None, s=None, wts=None, gz=False)[source]

Load the state of a Pyomo component state from a dictionary, json file, or json string. Must only specify one of sd, fname, or s as a non-None value. This works by going through the model and loading the state of each sub-compoent of o. If the saved state contains extra information, it is ignored. If the save state doesn’t contain an enetry for a model component that is to be loaded an error will be raised, unless ignore_missing = True.

Parameters:
  • o – Pyomo component to for which to load state
  • sd – State dictionary to load, if None, check fname and s
  • fname – JSON file to load, only used if sd is None
  • s – JSON string to load only used if both sd and fname are None
  • wts – StoreSpec object specifying what to load
  • gz – If True assume the file specified by fname is gzipped. The default is False.
Returns:

Dictionary with some perfomance information. The keys are “etime_load_file”, how long in seconds it took to load the json file “etime_read_dict”, how long in seconds it took to read models state “etime_read_suffixes”, how long in seconds it took to read suffixes

StoreSpec

StoreSpec is a class for objects that tell the to_json() and from_json() functions how to read and write Pyomo component attributes. The default initialization provides an object that would load and save attributes usually needed to save a model state. There are several other class methods that provide canned objects for specific uses. Through initialization arguments, the behavior is highly customizable. Attributes can be read or written using callback functions to handle attributes that can not be directly read or written (e.g. a variable lower bound is set by calling setlb()). See the class documentation below.

class idaes.core.util.model_serializer.StoreSpec(classes=((<class 'pyomo.core.base.param.Param'>, ('_mutable', )), (<class 'pyomo.core.base.var.Var'>, ()), (<class 'pyomo.core.base.component.Component'>, ('active', ))), data_classes=((<class 'pyomo.core.base.var._VarData'>, ('fixed', 'stale', 'value', 'lb', 'ub')), (<class 'pyomo.core.base.param._ParamData'>, ('value', )), (<class 'int'>, ('value', )), (<class 'float'>, ('value', )), (<class 'pyomo.core.base.component.ComponentData'>, ('active', ))), skip_classes=(<class 'pyomo.core.base.external.ExternalFunction'>, <class 'pyomo.core.base.sets.Set'>, <class 'pyomo.network.port.Port'>, <class 'pyomo.core.base.expression.Expression'>, <class 'pyomo.core.base.rangeset.RangeSet'>), ignore_missing=True, suffix=True, suffix_filter=None)[source]

A StoreSpec object tells the serializer functions what to read or write. The default settings will produce a StoreSpec configured to load/save the typical attributes required to load/save a model state.

Parameters:
  • classes – A list of classes to save. Each class is represented by a list (or tupple) containing the following elements: (1) class (compared using isinstance) (2) attribute list or None, an emptry list store the object, but none of its attributes, None will not store objects of this class type (3) optional load filter function. The load filter function returns a list of attributes to read based on the state of an object and its saved state. The allows, for example, loading values for unfixed variables, or only loading values whoes current value is less than one. The filter function only applies to load not save. Filter functions take two arguments (a) the object (current state) and (b) the dictionary containing the saved state of an object. More specific classes should come before more general classes. For example if an obejct is a HeatExchanger and a UnitModel, and HeatExchanger is listed first, it will follow the HeatExchanger settings. If UnitModel is listed first in the classes list, it will follow the UnitModel settings.
  • data_classes – This takes the same form as the classes argument. This is for component data classes.
  • skip_classes – This is a list of classes to skip. If a class appears in the skip list, but also appears in the classes argument, the classes argument will override skip_classes. The use for this is to specifically exclude certain classes that would get caught by more general classes (e.g. UnitModel is in the class list, but you want to exclude HeatExchanger which is derived from UnitModel).
  • ignore_missing – If True will ignore a component or attribute that exists in the model, but not in the stored state. If false an excpetion will be raised for things in the model that should be loaded but aren’t in the stored state. Extra items in the stored state will not raise an exception regaurdless of this argument.
  • suffix – If True store suffixes and component ids. If false, don’t store suffixes.
  • suffix_filter – None to store all siffixes if suffix=True, or a list of suffixes to store if suffix=True
classmethod bound()[source]

Returns a StoreSpec object to store variable bounds only.

get_class_attr_list(o)[source]

Look up what attributes to save/load for an Component object. :param o: Object to look up attribute list for.

Returns:A list of attributes and a filter function for object type
get_data_class_attr_list(o)[source]

Look up what attributes to save/load for an ComponentData object. :param o: Object to look up attribute list for.

Returns:A list of attributes and a filter function for object type
classmethod isfixed()[source]

Returns a StoreSpec object to store if variables are fixed.

set_read_callback(attr, cb=None)[source]

Set a callback to set an attribute, when reading from json or dict.

set_write_callback(attr, cb=None)[source]

Set a callback to get an attribute, when writing to json or dict.

classmethod value()[source]

Returns a StoreSpec object to store variable values only.

classmethod value_isfixed(only_fixed)[source]

Return a StoreSpec object to store variable values and if fixed.

Parameters:only_fixed – Only load fixed variable values
classmethod value_isfixed_isactive(only_fixed)[source]

Retur a StoreSpec object to store variable values, if variables are fixed and if components are active.

Parameters:only_fixed – Only load fixed variable values
Structure

Python dictionaries, json strings, or json files are generated, in any case the structure of the data is the same. The current data structure version is 3.

The example json below shows the top-level structure. The "top_level_component" would be the name of the Pyomo component that is being serialized. The top level component is the only place were the component name does not matter when reading the serialized data.

{
    "__metadata__": {
        "format_version": 3,
        "date": "2018-12-21",
        "time": "11:34:39.714323",
        "other": {
        },
        "__performance__": {
            "n_components": 219,
            "etime_make_dict": 0.003}
    },
    "top_level_component":{
      "...": "..."
    },
}

The data structure of a Pyomo component is shown below. Here "attribute_1" and "attribute_2" are just examples the actual attributes saved depend on the “wts” argument to to_json(). Scalar and indexed components have the same structure. Scalar components have one entry in "data" with an index of "None". Only components derived from Pyomo’s _BlockData have a "__pyomo_components__" field, and components appearing there are keyed by thier name. The data structure duplicates the hierarchical structure of the Pyomo model.

Suffixes store extra attributes for Pyomo components that are not stored on the components themselves. Suffixes are a Pyomo structure that comes from the AMPL solver interface. If a component is a suffix, keys in the data section are the serial integer component IDs generated by to_json(), and the value is the value of the suffix for the corresponding component.

{
    "__type__": "<class 'some.class'>",
    "__id__": 0,
    "data":{
      "index_1":{
          "__type__":"<usually a component class but for params could be float, int, ...>",
          "__id__": 1,
          "__pyomo_components__":{
            "child_component_1": {
              "...": "..."
            }
          },
          "attribute_1": "... could be any number of attributes like 'value': 1.0,",
          "attribute_2": "..."
      }
    },
    "attribute_1": "... could be any number of attributes like 'active': true,",
    "attribute_2": "..."
}

As a more concrete example, here is the json generated for example model 2 in Examples. This code can be appended to the example boilerplate above. To generate the example json shown.

model = setup_model02()
solver = SolverFactory("ipopt")
solver.solve(model)
to_json(model, fname="ex.json")

The resulting json is shown below. The top-level component in this case is given as “unknown,” because the model was not given a name. The top level object name is not needed when reading back data, since the top level object is specified in the call to from_json(). Types are not used when reading back data, they may have some future application, but at this point they just provide a little extra information.

{
  "__metadata__":{
    "format_version":3,
    "date":"2019-01-02",
    "time":"10:22:25.833501",
    "other":{
    },
    "__performance__":{
      "n_components":18,
      "etime_make_dict":0.0009555816650390625
    }
  },
  "unknown":{
    "__type__":"<class 'pyomo.core.base.PyomoModel.ConcreteModel'>",
    "__id__":0,
    "active":true,
    "data":{
      "None":{
        "__type__":"<class 'pyomo.core.base.PyomoModel.ConcreteModel'>",
        "__id__":1,
        "active":true,
        "__pyomo_components__":{
          "a":{
            "__type__":"<class 'pyomo.core.base.param.SimpleParam'>",
            "__id__":2,
            "_mutable":true,
            "data":{
              "None":{
                "__type__":"<class 'pyomo.core.base.param.SimpleParam'>",
                "__id__":3,
                "value":1
              }
            }
          },
          "b":{
            "__type__":"<class 'pyomo.core.base.param.SimpleParam'>",
            "__id__":4,
            "_mutable":true,
            "data":{
              "None":{
                "__type__":"<class 'pyomo.core.base.param.SimpleParam'>",
                "__id__":5,
                "value":2
              }
            }
          },
          "c":{
            "__type__":"<class 'pyomo.core.base.param.SimpleParam'>",
            "__id__":6,
            "_mutable":false,
            "data":{
              "None":{
                "__type__":"<class 'pyomo.core.base.param.SimpleParam'>",
                "__id__":7,
                "value":4
              }
            }
          },
          "x":{
            "__type__":"<class 'pyomo.core.base.var.IndexedVar'>",
            "__id__":8,
            "data":{
              "1":{
                "__type__":"<class 'pyomo.core.base.var._GeneralVarData'>",
                "__id__":9,
                "fixed":false,
                "stale":false,
                "value":1.5,
                "lb":-10,
                "ub":10
              },
              "2":{
                "__type__":"<class 'pyomo.core.base.var._GeneralVarData'>",
                "__id__":10,
                "fixed":false,
                "stale":false,
                "value":2.5,
                "lb":-10,
                "ub":10
              }
            }
          },
          "f":{
            "__type__":"<class 'pyomo.core.base.objective.SimpleObjective'>",
            "__id__":11,
            "active":true,
            "data":{
              "None":{"__type__":"<class 'pyomo.core.base.objective.SimpleObjective'>",
              "__id__":12,
              "active":true
              }
            }
          },
          "g":{
            "__type__":"<class 'pyomo.core.base.constraint.SimpleConstraint'>",
            "__id__":13,
            "active":true,
            "data":{
              "None":{
                "__type__":"<class 'pyomo.core.base.constraint.SimpleConstraint'>",
                "__id__":14,
                "active":true
              }
            }
          },
          "dual":{
            "__type__":"<class 'pyomo.core.base.suffix.Suffix'>",
            "__id__":15,
            "active":true,
            "data":{
              "14":0.9999999626149493
            }
          },
          "ipopt_zL_out":{
            "__type__":"<class 'pyomo.core.base.suffix.Suffix'>",
            "__id__":16,
            "active":true,
            "data":{
              "9":2.1791814146763388e-10,
              "10":2.004834508495852e-10
            }
          },
          "ipopt_zU_out":{
            "__type__":"<class 'pyomo.core.base.suffix.Suffix'>",
            "__id__":17,
            "active":true,
            "data":{
              "9":-2.947875485096964e-10,
              "10":-3.3408951850535573e-10
            }
          }
        }
      }
    }
  }
}

Core Overview

All components of the IDAES process modeling framework are built of Pyomo Block components (see Pyomo documentation).

The ProcessBlock class is the base class of IDAES models, and provides the common foundation for all other components.

FlowsheetModel objects represent the top level of the IDAES modeling hierarchy, and contain connected networks of unit models, or even contain other flowsheet models, which are connected by Pyomo Arcs.

Physical property packages supply information about a material’s state including physical properties and flow rates. Reaction property packages are used in systems where chemical reactions may take place, and supply information on reaction rates and stoichiometry, based on a material’s state.

Equipment models are derived from UnitModel. Unit models contain control volumes and have ports which can be used to connect material and energy flows between unit models. On top of the balance equations usually contained in control volumes unit models contain additional performance equations that may calculate things like heat and mass transfer or efficiency curves.

ControlVolumes are the basic building block used to construct unit models that contain material and energy holdup and flows in and out. These blocks contain energy, mass, and momentum balances, as well as state and reaction blocks associated with the material within the control volume.

More detail on the different types of modeling objects is available in the Modeling Concepts section.

Unit Model Library

Continuous Stirred Tank Reactor

The IDAES CSTR model represents a unit operation where a material stream undergoes some chemical reaction(s) in a well-mixed vessel.

Degrees of Freedom

CSTRs generally have one degree of freedom. Typically, the fixed variable is reactor volume.

Model Structure

The core CSTR unit model consists of a single ControlVolume0D (named control_volume) with one Inlet Port (named inlet) and one Outlet Port (named outlet).

Additional Constraints

CSTR units write the following additional Constraints beyond those written by the ControlVolume Block.

\[X_{t,r} = V_t \times r_{t,r}\]

where \(X_{t,r}\) is the extent of reaction of reaction \(r\) at time \(t\), \(V_t\) is the volume of the reacting material at time \(t\) (allows for varying reactor volume with time) and \(r_{t,r}\) is the volumetric rate of reaction of reaction \(r\) at time \(t\) (from the outlet property package).

Variables

CSTR units add the following additional Variables beyond those created by the ControlVolume Block.

Variable Name Notes
\(V_t\) volume If has_holdup = True this is a reference to control_volume.volume, otherwise a Var attached to the Unit Model
\(Q_t\) heat Only if has_heat_transfer = True, reference to control_volume.heat
CSTR Class
class idaes.unit_models.cstr.CSTR(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of material balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_heat_transfer
    Indicates whether terms for heat transfer should be constructed, default - False. Valid values: { True - include heat transfer terms, False - exclude heat transfer terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    has_equilibrium_reactions
    Indicates whether terms for equilibrium controlled reactions should be constructed, default - True. Valid values: { True - include equilibrium reaction terms, False - exclude equilibrium reaction terms.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    has_heat_of_reaction
    Indicates whether terms for heat of reaction terms should be constructed, default - False. Valid values: { True - include heat of reaction terms, False - exclude heat of reaction terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PhysicalParameterObject - a PhysicalParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    reaction_package
    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}
    reaction_package_args
    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(CSTR) New instance

CSTRData Class
class idaes.unit_models.cstr.CSTRData(component)[source]

Standard CSTR Unit Model Class

build()[source]

Begin building model (pre-DAE transformation). :param None:

Returns:None

Equilibrium Reactor

The IDAES Equilibrium reactor model represents a unit operation where a material stream undergoes some chemical reaction(s) to reach an equilibrium state. This model is for systems with reaction with equilibrium coefficients - for Gibbs energy minimization see Gibbs reactor documentation.

Degrees of Freedom

Equilibrium reactors generally have 1 degree of freedom.

Typical fixed variables are:

  • reactor heat duty (has_heat_transfer = True only).
Model Structure

The core Equilibrium reactor unit model consists of a single ControlVolume0D (named control_volume) with one Inlet Port (named inlet) and one Outlet Port (named outlet).

Additional Constraints

Equilibrium reactors units write the following additional Constraints beyond those written by the Control Volume if rate controlled reactions are present.

\[r_{t,r} = 0\]

where \(r_{t,r}\) is the rate of reaction for reaction \(r\) at time \(t\). This enforces equilibrium in any reversible rate controlled reactions which are present. Any non-reversible reaction that may be present will proceed to completion.

Variables

Equilibrium reactor units add the following additional Variables beyond those created by the Control Volume.

Variable Name Notes
\(V_t\) volume If has_holdup = True this is a reference to control_volume.volume, otherwise a Var attached to the Unit Model
\(Q_t\) heat Only if has_heat_transfer = True, reference to control_volume.heat
EquilibriumReactor Class
class idaes.unit_models.equilibrium_reactor.EquilibriumReactor(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = False. Equilibrium Reactors do not support dynamic behavior.
    has_holdup
    Indicates whether holdup terms should be constructed or not. default - False. Equilibrium reactors do not have defined volume, thus this must be False.
    material_balance_type
    Indicates what type of material balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_rate_reactions
    Indicates whether terms for rate controlled reactions should be constructed, along with constraints equating these to zero, default - True. Valid values: { True - include rate reaction terms, False - exclude rate reaction terms.}
    has_equilibrium_reactions
    Indicates whether terms for equilibrium controlled reactions should be constructed, default - True. Valid values: { True - include equilibrium reaction terms, False - exclude equilibrium reaction terms.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default - True. Valid values: { True - include phase equilibrium term, False - exclude phase equlibirum terms.}
    has_heat_transfer
    Indicates whether terms for heat transfer should be constructed, default - False. Valid values: { True - include heat transfer terms, False - exclude heat transfer terms.}
    has_heat_of_reaction
    Indicates whether terms for heat of reaction terms should be constructed, default - False. Valid values: { True - include heat of reaction terms, False - exclude heat of reaction terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PhysicalParameterObject - a PhysicalParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    reaction_package
    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}
    reaction_package_args
    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(EquilibriumReactor) New instance

EquilibriumReactorData Class
class idaes.unit_models.equilibrium_reactor.EquilibriumReactorData(component)[source]

Standard Equilibrium Reactor Unit Model Class

build()[source]

Begin building model.

Parameters:None
Returns:None

Feed Block

Feed Blocks are used to represent sources of material in Flowsheets. Feed blocks do not calculate phase equilibrium of the feed stream, and the composition of the material in the outlet stream will be exactly as specified in the input. For applications where the users wishes the outlet stream to be in phase equilibrium, see the Feed_Flash unit model.

Degrees of Freedom

The degrees of freedom of Feed blocks depends on the property package being used and the number of state variables necessary to fully define the system. Users should refer to documentation on the property package they are using.

Model Structure

Feed Blocks consists of a single StateBlock (named properties), each with one Outlet Port (named outlet). Feed Blocks also contain References to the state variables defined within the StateBlock

Additional Constraints

Feed Blocks write no additional constraints to the model.

Variables

Feed blocks add no additional Variables.

Feed Class
class idaes.unit_models.feed.Feed(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = False. Feed blocks are always steady-state.
    has_holdup
    Feed blocks do not contain holdup, thus this must be False.
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PhysicalParameterObject - a PhysicalParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Feed) New instance

FeedData Class
class idaes.unit_models.feed.FeedData(component)[source]

Standard Feed Block Class

build()[source]

Begin building model.

Parameters:None
Returns:None
initialize(state_args={}, outlvl=0, solver='ipopt', optarg={'tol': 1e-06})[source]

This method calls the initialization method of the state block.

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating which solver to use during initialization (default = ‘ipopt’)
Returns:

None

Feed Block with Flash

Feed Blocks are used to represent sources of material in Flowsheets. In some cases, users may have a situation where a feed stream may be in a multi-phase state, but may not know the full details of the equilibrium state. The IDAES Feed Block with Flash (FeedFlash) allows users to define a feed block where the outlet is in phase equilibrium based on calculations from the chosen property package and a sufficient set of state variables prior to being passed to the first unit operation. The phase equilibrium is performed assuming an isobaric and isothermal flash operation.

A Feed Block with Flash is only required in cases where the feed may be in phase equilibrium AND the chosen property package uses a state definition that includes phase separations. Some property packages support phase equilibrium, but use a state definition that involves only total flows - in these cases a flash calculation is performed at the inlet of every unit and thus it is not necessary to perform a flash calculation at the feed block.

Degrees of Freedom

The degrees of freedom of FeedFlash blocks depends on the property package being used and the number of state variables necessary to fully define the system. Users should refer to documentation on the property package they are using.

Model Structure

FeedFlash Blocks contain a single ControlVolume0D (named control_volume) with one Outlet Port (named outlet). FeedFlash Blocks also contain References to the state variables defined within the inlet StateBlock of the ControlVolume (representing the unflashed state of the feed).

FeedFlash Blocks do not write a set of energy balances within the Control Volume - instead a constraint is written which enforces an isothermal flash.

Additional Constraints

The FeedFlash Block writes one additional constraint to enforce isothermal behavior.

\[T_{in, t} = T_{out, t}\]

where \(T_{in, t}\) and \(T_{out, t}\) are the temperatures of the material before and after the flash operation.

Variables

FeedFlash blocks add no additional Variables.

FeedFlash Class
class idaes.unit_models.feed_flash.FeedFlash(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Feed units do not support dynamic behavior.
    has_holdup
    Feed units do not have defined volume, thus this must be False.
    material_balance_type
    Indicates what type of material balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PhysicalParameterObject - a PhysicalParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(FeedFlash) New instance

FeedFlashData Class
class idaes.unit_models.feed_flash.FeedFlashData(component)[source]

Standard Feed block with phase equilibrium

build()[source]

Begin building model.

Parameters:None
Returns:None

Flash Unit

The IDAES Flash model represents a unit operation where a single stream undergoes a flash separation into two phases. The Flash model supports mutile types of flash operations, including pressure changes and addition or removal of heat.

Degrees of Freedom

Flash units generally have 2 degrees of freedom.

Typical fixed variables are:

  • heat duty or outlet temperature (see note),
  • pressure change or outlet pressure.

Note: When setting the outlet temeprature of a Flash unit, it is best to set control_volume.properties_out[t].temperature. Setting the temperature in one of the outlet streams directly results in a much harder problme ot solve, and may be degenerate in some cases.

Model Structure

The core Flash unit model consists of a single ControlVolume0DBlock (named control_volume) with one Inlet Port (named inlet) and one Outlet Port (named outlet, default with two indexes (‘vap_outlet’ and ‘liq_outlet’)). The Flash model utilizes the separator unit model in IDAES to split the outlets by phase flows to the liquid and vapor outlets respectively.

The state variables used by the assoicated property package should meet specific requirements in order that the Flash model can find the necessary information for splitting the outlet flows. To support direct splitting, the property package must use one of a specified set of state variables and support a certain set of property calacuations, as outlined in the table below.

State Variables Required Properties
Material flow and composition
flow_mol & mole_frac flow_mol_phase & mole_frac_phase
flow_mol_phase & mole_frac_phase flow_mol_phase & mole_frac_phase
flow_mol_comp flow_mol_phase_comp
flow_mol_phase_comp flow_mol_phase_comp
flow_mass & mass_frac flow_mass_phase & mass_frac_phase
flow_mass_phase & mass_frac_phase flow_mass_phase & mass_frac_phase
flow_mass_comp flow_mass_phase_comp
flow_mass_phase_comp flow_mass_phase_comp
Energy state
temperature temperature
enth_mol enth_mol_phase
enth_mol_phase enth_mol_phase
enth_mass enth_mass_phase
enth_mass_phase enth_mass_phase
Pressure state
pressure pressure
Construction Arguments

Flash units have the following construction arguments:

  • property_package - property package to use when constructing Property Blocks (default = ‘use_parent_value’). This is provided as a Property Parameter Block by the Flowsheet when creating the model. If a value is not provided, the Holdup Block will try to use the default property package if one is defined.
  • property_package_args - set of arguments to be passed to the Property Blocks when they are created.

Additionally, Flash units have the following construction arguments which are passed to the Holdup Block for determining which terms to construct in the balance equations.

Argument Default Value
dynamic False
include_holdup False
material_balance_type MaterialBalanceType.componentPhase
energy_balance_type EnergyBalanceType.enthalpyTotal
momentum_balance_type MomentumBalanceType.pressureTotal
has_phase_equilibrium True
has_heat_transfer True
has_pressure_change True
Additional Constraints

Flash units write no additional Constraints beyond those written by the ControlVolume0DBlock and the Separator block.

Variables
Name Notes
heat_duty Reference to control_volume.heat
deltaP Reference to control_volume.deltaP
Flash Class
class idaes.unit_models.flash.Flash(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = False. Flash units do not support dynamic behavior.
    has_holdup
    Indicates whether holdup terms should be constructed or not. default - False. Flash units do not have defined volume, thus this must be False.
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_heat_transfer
    Indicates whether terms for heat transfer should be constructed, default - False. Valid values: { True - include heat transfer terms, False - exclude heat transfer terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - True. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Flash) New instance

FlashData Class
class idaes.unit_models.flash.FlashData(component)[source]

Standard Flash Unit Model Class

build()[source]

Begin building model (pre-DAE transformation).

Parameters:None
Returns:None

Gibbs Reactor

The IDAES Gibbs reactor model represents a unit operation where a material stream undergoes some set of reactions such that the Gibbs energy of the resulting mixture is minimized. Gibbs reactors rely on conservation of individual elements within the system, and thus require element balances, and make use of Lagrange multipliers to find the minimum Gibbs energy state of the system.

Degrees of Freedom

Gibbs reactors generally have between 0 and 2 degrees of freedom, depending on construction arguments.

Typical fixed variables are:

  • reactor heat duty (has_heat_transfer = True only).
  • reactor pressure change (has_pressure_change = True only).
Model Structure

The core Gibbs reactor unit model consists of a single ControlVolume0DBlock (named control_volume) with one Inlet Port (named inlet) and one Outlet Port (named outlet).

Variables

Gibbs reactor units add the following additional Variables beyond those created by the Control Volume Block.

Variable Name Symbol Notes
lagrange_mult \(L_{t,e}\) Lagrange multipliers
heat_duty \(Q_t\) Only if has_heat_transfer = True, reference
deltaP \(\Delta P_t\) Only if has_pressure_change = True, reference
Constraints

Gibbs reactor models write the following additional constraints to calculate the state that corresponds to the minimum Gibbs energy of the system.

gibbs_minimization(time, phase, component):

\[0 = g_{partial,t,j} + \sum_e{L_{t,e} \times \alpha_{j,e}})\]

where \(g_{partial,t,j}\) is the partial molar Gibbs energy of component \(j\) at time \(t\), \(L_{t,e}\) is the Lagrange multiplier for element \(e\) at time \(t\) and \(\alpha_{j,e}\) is the number of moles of element \(e\) in one mole of component \(j\). \(g_{partial,t,j}\) and \(\alpha_{j,e}\) come from the outlet StateBlock.

GibbsReactor Class
class idaes.unit_models.gibbs_reactor.GibbsReactor(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Gibbs reactors do not support dynamic models, thus this must be False.
    has_holdup
    Gibbs reactors do not have defined volume, thus this must be False.
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_heat_transfer
    Indicates whether terms for heat transfer should be constructed, default - False. Valid values: { True - include heat transfer terms, False - exclude heat transfer terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(GibbsReactor) New instance

GibbsReactorData Class
class idaes.unit_models.gibbs_reactor.GibbsReactorData(component)[source]

Standard Gibbs Reactor Unit Model Class

This model assume all possible reactions reach equilibrium such that the system partial molar Gibbs free energy is minimized. Since some species mole flow rate might be very small, the natural log of the species molar flow rate is used. Instead of specifying the system Gibbs free energy as an objective function, the equations for zero partial derivatives of the grand function with Lagrangian multiple terms with repect to product species mole flow rates and the multiples are specified as constraints.

build()[source]

Begin building model (pre-DAE transformation).

Parameters:None
Returns:None

Heater

The Heater model is a simple 0D model that adds or removes heat from a material stream.

Example
import pyomo.environ as pe # Pyomo environment
from idaes.core import FlowsheetBlock, StateBlock
from idaes.unit_models import Heater
from idaes.property_models import iapws95_ph

# Create an empty flowsheet and steam property parameter block.
model = pe.ConcreteModel()
model.fs = FlowsheetBlock(default={"dynamic": False})
model.fs.properties = iapws95_ph.Iapws95ParameterBlock()

# Add a Heater model to the flowsheet.
model.fs.heater = Heater(default={"property_package": model.fs.properties})

# Setup the heater model by fixing the inputs and heat duty
model.fs.heater.inlet[:].enth_mol.fix(4000)
model.fs.heater.inlet[:].flow_mol.fix(100)
model.fs.heater.inlet[:].pressure.fix(101325)
model.fs.heater.heat_duty[:].fix(100*20000)

# Initialize the model.
model.fs.heater.initialize()
Degrees of Freedom

Aside from the inlet conditions, a heater model usually has one degree of freedom, which is the heat duty.

Model Structure

A heater model contains one ControlVolume0DBlock block.

Variables

The heat_duty variable is a reference to control_volume.heat.

Constraints

A heater model contains no additional constraints beyond what are contained in a ControlVolume0DBlock model.

Heater Class
class idaes.unit_models.heat_exchanger.Heater(*args, **kwargs)

Simple 0D heater/cooler model.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Heater) New instance

HeaterData Class
class idaes.unit_models.heat_exchanger.HeaterData(component)[source]

Simple 0D heater unit. Unit model to add or remove heat from a material.

build()[source]

Building model :param None:

Returns:None

HeatExchanger (0D)

The HeatExchanger model can be imported from idaes.unit_models, while additional rules and utility functions can be imported from idaes.unit_models.heat_exchanger.

Example

The example below demonstrates how to initialize the HeatExchanger model, and override the default temperature difference calculation.

import pyomo.environ as pe # Pyomo environment
from idaes.core import FlowsheetBlock, StateBlock
from idaes.unit_models import HeatExchanger
from idaes.unit_models.heat_exchanger import delta_temperature_amtd_rule
from idaes.property_models import iapws95_ph

# Create an empty flowsheet and steam property parameter block.
model = pe.ConcreteModel()
model.fs = FlowsheetBlock(default={"dynamic": False})
model.fs.properties = iapws95_ph.Iapws95ParameterBlock()

# Add a Heater model to the flowsheet.
model.fs.heat_exchanger = HeatExchanger(default={
        "delta_temperature_rule":delta_temperature_amtd_rule,
        "side_1":{"property_package": model.fs.properties},
        "side_2":{"property_package": model.fs.properties}})

model.fs.heat_exchanger.area.fix(1000)
model.fs.heat_exchanger.overall_heat_transfer_coefficient[0].fix(100)
model.fs.heat_exchanger.inlet_1.flow_mol.fix(100)
model.fs.heat_exchanger.inlet_1.pressure.fix(101325)
model.fs.heat_exchanger.inlet_1.enth_mol.fix(4000)
model.fs.heat_exchanger.inlet_2.flow_mol.fix(100)
model.fs.heat_exchanger.inlet_2.pressure.fix(101325)
model.fs.heat_exchanger.inlet_2.enth_mol.fix(3000)

# Initialize the model
model.fs.heat_exchanger.initialize()
Degrees of Freedom

Aside from the inlet conditions, a heat exchanger model usually has two degrees of freedom, which can be fixed for it to be fully specified:

  • heat transfer area
  • heat transfer coefficient.

The user may also provide constants to calculate the heat transfer coefficient.

Model Structure

The HeatExchanger model contains two ControlVolume0DBlock blocks (side_1 and side_2), which are configured the same as the ControlVolume0DBlock in the Heater model. The HeatExchanger model contains additional constraints that calculate the amount of heat transferred from side_1 to side_2.

The HeatExchanger has two inlet ports inlet_1 (inlet for side_1) and inlet_2 (outlet for side_2), and two outlet ports inlet ports inlet_1 (outlet for side_1) and outlet_2 (outlet for side_2).

If the \(\Delta T\) calculation method requires one side to be hotter than the other, side_1 is assumed to be the hot side.

Variables
Variable Symbol Index Sets Doc
heat_duty \(Q\) t Heat transferred from side_1 to side_2 a reference to side_2.heat
area \(A\) None Heat transfer area
heat_transfer_coefficient \(U\) t Heat transfer coefficient
delta_temperature \(\Delta T\) t Temperature difference for heat transfer calculations defaults to LMTD
Constraints

The default constants can be overridden by providing alternative rules for the heat transfer equation, temperature difference, and heat transfer coefficient. The section describes the default constraints.

Heat transfer from side_1 to side_2:

\[Q = UA\Delta T\]

Temperature difference is an expression:

\[\Delta T = \frac{\Delta T_1 - \Delta T_2}{\log_e \Delta T_1 - \log_e \Delta T_2}\]

The heat transfer coefficient is a variable with no associated constraints by default.

HeatExchanger Class
class idaes.unit_models.heat_exchanger.HeatExchanger(*args, **kwargs)

Simple 0D heat exchanger model.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    side_1
    A config block used to construct the side_1 control volume.
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    side_2
    A config block used to construct the side_2 control volume.
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    delta_temperature_rule
    Rule for equation for temperature difference
    flow_pattern
    Heat exchanger flow pattern, default - HeatExchangerFlowPattern.countercurrent. Valid values: { HeatExchangerFlowPattern.countercurrent - countercurrent flow, HeatExchangerFlowPattern.cocurrent - cocurrent flow, HeatExchangerFlowPattern.crossflow - cross flow, factor times countercurrent temperature difference.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(HeatExchanger) New instance

HeatExchangerData Class
class idaes.unit_models.heat_exchanger.HeatExchangerData(component)[source]

Simple 0D heat exchange unit. Unit model to transfer heat from one material to another.

build()[source]

Building model

Parameters:None
Returns:None
initialize(state_args_1=None, state_args_2=None, outlvl=0, solver='ipopt', optarg={'tol': 1e-06}, duty=1000)[source]

Heat exchanger initialization method.

Parameters:
  • state_args_1 – a dict of arguments to be passed to the property initialization for side_1 (see documentation of the specific property package) (default = {}).
  • state_args_2 – a dict of arguments to be passed to the property initialization for side_2 (see documentation of the specific property package) (default = {}).
  • outlvl – sets output level of initialisation routine * 0 = no output (default) * 1 = return solver state for each step in routine * 2 = return solver state for each step in subroutines * 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating which solver to use during initialization (default = ‘ipopt’)
  • duty – an initial guess for the amount of heat transfered (default = 10000)
Returns:

None

set_scaling_factor_energy(f)[source]

This function sets scaling_factor_energy for both side_1 and side_2. This factor multiplies the energy balance and heat transfer equations in the heat exchnager. The value of this factor should be about 1/(expected heat duty).

Parameters:f – Energy balance scaling factor
Rules

A selection of functions for Pyomo rules are provided in the idaes.unit_models.heat_exchanger module, which provide options for different calculation methods. Users can also provide their own rule functions. See the source code for the rules below for examples.

Rules for the delta_temperature_rule Option

These rules provide expressions for the temperature difference used in the heat transfer equations.

idaes.unit_models.heat_exchanger.delta_temperature_lmtd_rule(b, t)[source]

This is a rule for a temperaure difference expression to calculate \(\Delta T\) in the heat exchanger model using log-mean temperature difference (LMTD). It can be supplied to “delta_temperature_rule” HeatExchanger configuration option.

idaes.unit_models.heat_exchanger.delta_temperature_amtd_rule(b, t)[source]

This is a rule for a temperaure difference expression to calculate \(\Delta T\) in the heat exchanger model using arithmetic-mean temperature difference (AMTD). It can be supplied to “delta_temperature_rule” HeatExchanger configuration option.

Rules for the heat_transfer_rule Option

These rules provide constraints for the heat transfer rate.

idaes.unit_models.heat_exchanger._heat_transfer_rule(b, t)[source]

This is the default rule used by the HeatExchanger model to calculate heat transfer (\(Q = UA\Delta T\)).

Rules for the heat_transfer_coefficient_rule Option

There are currently no rules provided for heat transfer coefficient calculation. When the rule is set to None, heat_transfer_coefficient is a fixed Var. User provided heat transfer coefficient rules should return a constraint.

Heat Exchangers (1D)

Heat Exchanger models represents a unit operation with two material streams which exchange heat. The IDAES 1-D Heat Exchanger model is used for detailed modeling of heat exchanger units with variations in one spatial dimension. For a simpler representation of a heat exchanger unit see Heat Exchanger (0-D).

Degrees of Freedom

1-D Heat Exchangers generally have 7 degrees of freedom.

Typical fixed variables are:

  • shell length and diameter,
  • tube length and diameter,
  • number of tubes,
  • heat transfer coefficients (at all spatial points) for both shell and tube sides.
Model Structure

The core 1-D Heat Exchanger Model unit model consists of two ControlVolume1DBlock Blocks (named shell and tube), each with one Inlet Port (named shell_inlet and tube_inlet) and one Outlet Port (named shell_outlet and tube_outlet).

Construction Arguments

1-D Heat Exchanger units have construction arguments specific to the shell side, tube side and for the unit as a whole.

Arguments that are applicable to the heat exchanger unit are as follows:

  • flow_type - indicates the flow arrangement within the unit to be modeled. Options are:

    • ‘co-current’ - (default) shell and tube both flow in the same direction (from x=0 to x=1)
    • ‘counter-current’ - shell and tube flow in opposite directions (shell from x=0 to x=1 and tube from x=1 to x=0).
  • finite_elements - sets the number of finite elements to use when discretizing the spatial domains (default = 20). This is used for both shell and tube side domains.

  • collocation_points - sets the number of collocation points to use when discretizing the spatial domains (default = 5, collocation methods only). This is used for both shell and tube side domains.

  • has_wall_conduction - option to enable a model for heat conduction across the tube wall:
    • ‘none’ - 0D wall model
    • ‘1D’ - 1D heat conduction equation along the thickness of the tube wall
    • ‘2D’ - 2D heat conduction equation along the length and thickness of the tube wall

Arguments that are applicable to the shell side:

  • property_package - property package to use when constructing shell side Property Blocks (default = ‘use_parent_value’). This is provided as a Physical Parameter Block by the Flowsheet when creating the model. If a value is not provided, the ControlVolume Block will try to use the default property package if one is defined.
  • property_package_args - set of arguments to be passed to the shell side Property Blocks when they are created.
  • transformation_method - argument to specify the DAE transformation method for the shell side; should be compatible with the Pyomo DAE TransformationFactory
  • transformation_scheme - argument to specify the scheme to use for the selected DAE transformation method; should be compatible with the Pyomo DAE TransformationFactory

Arguments that are applicable to the tube side:

  • property_package - property package to use when constructing tube side Property Blocks (default = ‘use_parent_value’). This is provided as a Property Parameter Block by the Flowsheet when creating the model. If a value is not provided, the ControlVolume Block will try to use the default property package if one is defined.
  • property_package_args - set of arguments to be passed to the tube side Property Blocks when they are created.
  • transformation_method - argument to specify the DAE transformation method for the tube side; should be compatible with the Pyomo DAE TransformationFactory
  • transformation_scheme - argument to specify the scheme to use for the selected DAE transformation method; should be compatible with the Pyomo DAE TransformationFactory

Additionally, 1-D Heat Exchanger units have the following construction arguments which are passed to the ControlVolume1DBlock Block for determining which terms to construct in the balance equations for the shell and tube side.

Argument Default Value
dynamic useDefault
has_holdup False
material_balance_type ‘componentTotal’
energy_balance_type ‘enthalpyTotal’
momentum_balance_type ‘pressureTotal’
has_phase_equilibrium False
has_heat_transfer True
has_pressure_change False
Additional Constraints

1-D Heat Exchanger models write the following additional Constraints to describe the heat transfer between the two sides of the heat exchanger. Firstly, the shell- and tube-side heat transfer is calculated as:

\[Q_{shell,t,x} = - N_{tubes} \times (\pi \times U_{shell,t,x} \times D_{tube,outer} \times (T_{shell,t,x}-T_{wall,t,x}))\]

where \(Q_{shell,t,x}\) is the shell-side heat duty at point \(x\) and time \(t\), \(N_{tubes}\) \(D_{tube}\) are the number of and diameter of the tubes in the heat exchanger, \(U_{shell,t,x}\) is the shell-side heat transfer coefficient, and \(T_{shell,t,x}\) and \(T_{wall,t,x}\) are the shell-side and tube wall temperatures respectively.

\[Q_{tube,t,x} = N_{tubes} \times (\pi \times U_{tube,t,x} \times D_{tube,inner} \times (T_{wall,t,x}-T_{tube,t,x}))\]

where \(Q_{tube,t,x}\) is the tube-side heat duty at point \(x\) and time \(t\), \(U_{tube,t,x}\) is the tube-side heat transfer coefficient and \(T_{tube,t,x}\) is the tube-side temperature.

If a OD wall model is used for the tube wall conduction, the following constraint is implemented to connect the heat terms on the shell and tube side:

\[N_{tubes} \times Q_{tube,t,x} = - Q_{shell,t,x}\]

Finally, the following Constraints are written to describe the unit geometry:

\[4 \times A_{tube} = \pi \times D_{tube}^2\]
\[4 \times A_{shell} = \pi \times (D_{shell}^2 - N_{tubes} \times D_{tube}^2)\]

where \(A_{shell}\) and \(A_{tube}\) are the shell and tube areas respectively and \(D_{shell}\) and \(D_{tube}\) are the shell and tube diameters.

Variables

1-D Heat Exchanger units add the following additional Variables beyond those created by the ControlVolume1DBlock Block.

Variable Name Notes
\(L_{shell}\) shell_length Reference to shell.length
\(A_{shell}\) shell_area Reference to shell.area
\(D_{shell}\) d_shell  
\(L_{tube}\) tube_length Reference to tube.length
\(A_{tube}\) tube_area Reference to tube.area
\(D_{tube}\) d_tube  
\(N_{tubes}\) N_tubes  
\(T_{wall,t,x}\) temperature_wall  
\(U_{shell,t,x}\) shell_heat_transfer_coefficient  
\(U_{tube,t,x}\) tube_heat_transfer_coefficient  
HeatExchanger1dClass
class idaes.unit_models.heat_exchanger_1D.HeatExchanger1D(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    shell_side
    shell side config arguments
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentTotal. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    has_phase_equilibrium
    Argument to enable phase equilibrium on the shell side. - True - include phase equilibrium term - False - do not include phase equilinrium term
    property_package
    Property parameter object used to define property calculations (default = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a ParameterBlock object
    property_package_args
    A dict of arguments to be passed to the PropertyBlockData and used when constructing these (default = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a dict (see property package for documentation)
    transformation_method
    Discretization method to use for DAE transformation. See Pyomo documentation for supported transformations.
    transformation_scheme
    Discretization scheme to use when transformating domain. See Pyomo documentation for supported schemes.
    tube_side
    tube side config arguments
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentTotal. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    has_phase_equilibrium
    Argument to enable phase equilibrium on the shell side. - True - include phase equilibrium term - False - do not include phase equilinrium term
    property_package
    Property parameter object used to define property calculations (default = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a ParameterBlock object
    property_package_args
    A dict of arguments to be passed to the PropertyBlockData and used when constructing these (default = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a dict (see property package for documentation)
    transformation_method
    Discretization method to use for DAE transformation. See Pyomo documentation for supported transformations.
    transformation_scheme
    Discretization scheme to use when transformating domain. See Pyomo documentation for supported schemes.
    finite_elements
    Number of finite elements to use when discretizing length domain (default=20)
    collocation_points
    Number of collocation points to use per finite element when discretizing length domain (default=3)
    flow_type
    Flow configuration of heat exchanger - HeatExchangerFlowPattern.cocurrent: shell and tube flows from 0 to 1 - HeatExchangerFlowPattern.countercurrent: shell side flows from 0 to 1 tube side flows from 1 to 0
    has_wall_conduction
    Argument to enable type of wall heat conduction model. - WallConductionType.zero_dimensional - 0D wall model, - WallConductionType.one_dimensional - 1D wall model along the thickness of the tube, - WallConductionType.two_dimensional - 2D wall model along the lenghth and thickness of the tube
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(HeatExchanger1D) New instance

HeatExchanger1dDataClass
class idaes.unit_models.heat_exchanger_1D.HeatExchanger1DData(component)[source]

Standard Heat Exchanger 1D Unit Model Class.

build()[source]

Begin building model (pre-DAE transformation).

Parameters:None
Returns:None
initialize(shell_state_args=None, tube_state_args=None, outlvl=1, solver='ipopt', optarg={'tol': 1e-06})[source]

Initialisation routine for the unit (default solver ipopt).

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating whcih solver to use during initialization (default = ‘ipopt’)
Returns:

None

Mixer

The IDAES Mixer unit model represents operations where multiple streams of material are combined into a single flow. The Mixer class can be used to create either a stand-alone mixer unit, or as part of a unit model where multiple streams need to be mixed.

Degrees of Freedom

Mixer units have zero degrees of freedom.

Model Structure

The IDAES Mixer unit model does not use ControlVolumes, and instead writes a set of material, energy and momentum balances to combine the inlet streams into a single mixed stream. Mixer models have a user-defined number of inlet Ports (by default named inlet_1, inlet_2, etc.) and one outlet Port (named outlet).

Mixed State Block

If a mixed state block is provided in the construction arguments, the Mixer model will use this as the StateBlock for the mixed stream in the resulting balance equations. This allows a Mixer unit to be used as part of a larger unit operation by linking multiple inlet streams to a single existing StateBlock.

Variables

Mixer units have the following variables (\(i\) indicates index by inlet):

Variable Name Symbol Notes
phase_equilibrium_generation \(X_{eq, t, r}\) Only if has_phase_equilibrium = True, Generation term for phase equilibrium
minimum_pressure \(P_{min, t, i}\) Only if momentum_mixing_type = MomemntumMixingType.minimize
Parameters

Mixer units have the following parameters:

Variable Name Symbol Notes
eps_pressure \(\epsilon\) Only if momentum_mixing_type = MomemntumMixingType.minimize, smooth minimum parameter
Constraints

The constraints written by the Mixer model depend upon the construction arguments chosen.

If material_mixing_type is extensive:

material_mixing_equations(t, p, j):

\[0 = \sum_i{F_{in, i, p, j}} - F_{out, p, j} + \sum_r {n_{r, p, j} \times X_{eq, t, r}}\]

where \(n_{r, p, j}\) is the stoichiometric coefficient of component \(j\) in phase \(p\) in reaction \(r\).

If ‘energy_mixing_type` is extensive:

enthalpy_mixing_equations(t):

\[0 = \sum_i{\sum_p{H_{in, i, p}}} - \sum_p{H_{out, p}}\]

If ‘momentum_mixing_type` is minimize, a series of smooth minimum operations are performed:

minimum_pressure_constraint(t, i):

For the first inlet:

\[P_{min, t, i} = P_{t, i}\]

Otherwise:

\[P_{min, t, i} = smin(P_{min, t, i-1}, P_{t, i}, eps)\]

Here, \(P_{t, i}\) is the pressure in inlet \(i\) at time \(t\), \(P_{min, t, i}\) is the minimum pressure in all inlets up to inlet \(i\), and \(smin\) is the smooth minimum operator (see IDAES Utility Function documentation).

The minimum pressure in all inlets is then:

mixture_pressure(t):

\[P_{mix, t} = P_{min, t, i=last}\]

If momentum_mixing_type is equality, the pressure in all inlets and the outlet are equated.

Note

This may result in an over-specified problem if the user is not careful.

pressure_equality_constraints(t, i):

\[P_{mix, t} = P_{t, i}\]

Often the minimum inlet pressure constraint is useful for sequential modular type initialization, but the equal pressure constants are required for pressure-driven flow models. In these cases it may be convenient to use the minimum pressure constraint for some initialization steps, them deactivate it and use the equal pressure constraints. The momentum_mixing_type is minimum_and_equality this will create the constraints for both with the minimum pressure constraint being active.

The mixture_pressure(t) and pressure_equality_constraints(t, i) can be directly activated and deactivated, but only one set of constraints should be active at a time. The use_minimum_inlet_pressure_constraint() and use_equal_pressure_constraint() methods are also provided to switch between constant sets.

Mixer Class
class idaes.unit_models.mixer.Mixer(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = False. Mixer blocks are always steady-state.
    has_holdup
    Mixer blocks do not contain holdup, thus this must be False.
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    inlet_list
    A list containing names of inlets, default - None. Valid values: { None - use num_inlets argument, list - a list of names to use for inlets.}
    num_inlets
    Argument indicating number (int) of inlets to construct, not used if inlet_list arg is provided, default - None. Valid values: { None - use inlet_list arg instead, or default to 2 if neither argument provided, int - number of inlets to create (will be named with sequential integers from 1 to num_inlets).}
    has_phase_equilibrium
    Argument indicating whether phase equilibrium should be calculated for the resulting mixed stream, default - False. Valid values: { True - calculate phase equilibrium in mixed stream, False - do not calculate equilibrium in mixed stream.}
    material_mixing_type
    Argument indicating what method to use when mixing material flows of incoming streams, default - MixingType.extensive. Valid values: { MixingType.none - do not include material mixing equations, MixingType.extensive - mix total flows of each phase-component pair.}
    energy_mixing_type
    Argument indicating what method to use when mixing energy flows of incoming streams, default - MixingType.extensive. Valid values: { MixingType.none - do not include energy mixing equations, MixingType.extensive - mix total enthalpy flows of each phase.}
    momentum_mixing_type
    Argument indicating what method to use when mixing momentum/ pressure of incoming streams, default - MomentumMixingType.minimize. Valid values: { MomentumMixingType.none - do not include momentum mixing equations, MomentumMixingType.minimize - mixed stream has pressure equal to the minimimum pressure of the incoming streams (uses smoothMin operator), MomentumMixingType.equality - enforces equality of pressure in mixed and all incoming streams., MomentumMixingType.minimize_and_equality - add constraints for pressure equal to the minimum pressure of the inlets and constraints for equality of pressure in mixed and all incoming streams. When the model is initially built, the equality constraints are deactivated. This option is useful for switching between flow and pressure driven simulations.}
    mixed_state_block
    An existing state block to use as the outlet stream from the Mixer block, default - None. Valid values: { None - create a new StateBlock for the mixed stream, StateBlock - a StateBock to use as the destination for the mixed stream.}
    construct_ports
    Argument indicating whether model should construct Port objects linked to all inlet states and the mixed state, default - True. Valid values: { True - construct Ports for all states, False - do not construct Ports.
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Mixer) New instance

MixerData Class
class idaes.unit_models.mixer.MixerData(component)[source]

This is a general purpose model for a Mixer block with the IDAES modeling framework. This block can be used either as a stand-alone Mixer unit operation, or as a sub-model within another unit operation.

This model creates a number of StateBlocks to represent the incoming streams, then writes a set of phase-component material balances, an overall enthalpy balance and a momentum balance (2 options) linked to a mixed-state StateBlock. The mixed-state StateBlock can either be specified by the user (allowing use as a sub-model), or created by the Mixer.

When being used as a sub-model, Mixer should only be used when a set of new StateBlocks are required for the streams to be mixed. It should not be used to mix streams from mutiple ControlVolumes in a single unit model - in these cases the unit model developer should write their own mixing equations.

add_energy_mixing_equations(inlet_blocks, mixed_block)[source]

Add energy mixing equations (total enthalpy balance).

add_inlet_state_blocks(inlet_list)[source]

Construct StateBlocks for all inlet streams.

Parameters:of strings to use as StateBlock names (list) –
Returns:list of StateBlocks
add_material_mixing_equations(inlet_blocks, mixed_block)[source]

Add material mixing equations (phase-component balances).

add_mixed_state_block()[source]

Constructs StateBlock to represent mixed stream.

Returns:New StateBlock object
add_port_objects(inlet_list, inlet_blocks, mixed_block)[source]

Adds Port objects if required.

Parameters:
  • list of inlet StateBlock objects (a) –
  • mixed state StateBlock object (a) –
Returns:

None

add_pressure_equality_equations(inlet_blocks, mixed_block)[source]

Add pressure equality equations. Note that this writes a number of constraints equal to the number of inlets, enforcing equality between all inlets and the mixed stream.

add_pressure_minimization_equations(inlet_blocks, mixed_block)[source]

Add pressure minimization equations. This is done by sequential comparisons of each inlet to the minimum pressure so far, using the IDAES smooth minimum fuction.

build()[source]

General build method for MixerData. This method calls a number of sub-methods which automate the construction of expected attributes of unit models.

Inheriting models should call super().build.

Parameters:None
Returns:None
create_inlet_list()[source]

Create list of inlet stream names based on config arguments.

Returns:list of strings
get_mixed_state_block()[source]

Validates StateBlock provided in user arguments for mixed stream.

Returns:The user-provided StateBlock or an Exception
initialize(outlvl=0, optarg={}, solver='ipopt', hold_state=False)[source]

Initialisation routine for mixer (default solver ipopt)

Keyword Arguments:
 
  • outlvl – sets output level of initialisation routine. Valid values: 0 - no output (default), 1 - return solver state for each step in routine, 2 - include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={})
  • solver – str indicating whcih solver to use during initialization (default = ‘ipopt’)
  • hold_state – flag indicating whether the initialization routine should unfix any state variables fixed during initialization, default - False. Valid values: True - states variables are not unfixed, and a dict of returned containing flags for which states were fixed during initialization, False - state variables are unfixed after initialization by calling the release_state method.
Returns:

If hold_states is True, returns a dict containing flags for which states were fixed during initialization.

model_check()[source]

This method executes the model_check methods on the associated state blocks (if they exist). This method is generally called by a unit model as part of the unit’s model_check method.

Parameters:None
Returns:None
release_state(flags, outlvl=0)[source]

Method to release state variables fixed during initialisation.

Keyword Arguments:
 
  • flags – dict containing information of which state variables were fixed during initialization, and should now be unfixed. This dict is returned by initialize if hold_state = True.
  • outlvl – sets output level of logging
Returns:

None

use_equal_pressure_constraint()[source]

Deactivate the mixer pressure = mimimum inlet pressure constraint and activate the mixer pressure and all inlet pressures are equal constraints. This should only be used when momentum_mixing_type == MomentumMixingType.minimize_and_equality.

use_minimum_inlet_pressure_constraint()[source]

Activate the mixer pressure = mimimum inlet pressure constraint and deactivate the mixer pressure and all inlet pressures are equal constraints. This should only be used when momentum_mixing_type == MomentumMixingType.minimize_and_equality.

Plug Flow Reactor

The IDAES Plug Flow Reactor (PFR) model represents a unit operation where a material stream passes through a linear reactor vessel whilst undergoing some chemical reaction(s). This model requires modeling the system in one spatial dimension.

Degrees of Freedom

PFRs generally have at least 2 degrees of freedom.

Typical fixed variables are:

  • 2 of reactor length, area and volume.
Model Structure

The core PFR unit model consists of a single ControlVolume1DBlock (named control_volume) with one Inlet Port (named inlet) and one Outlet Port (named outlet).

Variables

PFR units add the following additional Variables:

Variable Name Notes
\(L\) length Reference to control_volume.length
\(A\) area Reference to control_volume.area
\(V\) volume Reference to control_volume.volume
\(Q_{t,x}\) heat Only if has_heat_transfer = True, reference to holdup.heat
\(\Delta P_{t,x}\) deltaP Only if has_pressure_change = True, reference to holdup.deltaP
Constraints

PFR units write the following additional Constraints at all points in the spatial domain:

\[X_{t,x,r} = A \times r_{t,x,r}\]

where \(X_{t,x,r}\) is the extent of reaction of reaction \(r\) at point \(x\) and time \(t\), \(A\) is the cross-sectional area of the reactor and \(r_{t,r}\) is the volumetric rate of reaction of reaction \(r\) at point \(x\) and time \(t\) (from the outlet StateBlock).

PFR Class
class idaes.unit_models.plug_flow_reactor.PFR(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_equilibrium_reactions
    Indicates whether terms for equilibrium controlled reactions should be constructed, default - True. Valid values: { True - include equilibrium reaction terms, False - exclude equilibrium reaction terms.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    has_heat_of_reaction
    Indicates whether terms for heat of reaction terms should be constructed, default - False. Valid values: { True - include heat of reaction terms, False - exclude heat of reaction terms.}
    has_heat_transfer
    Indicates whether terms for heat transfer should be constructed, default - False. Valid values: { True - include heat transfer terms, False - exclude heat transfer terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    reaction_package
    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}
    reaction_package_args
    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}
    length_domain_set
    A list of values to be used when constructing the length domain of the reactor. Point must lie between 0.0 and 1.0, default - [0.0, 1.0]. Valid values: { a list of floats}
    transformation_method
    Method to use to transform domain. Must be a method recognised by the Pyomo TransformationFactory, default - “dae.finite_difference”.
    transformation_scheme
    Scheme to use when transformating domain. See Pyomo documentation for supported schemes, default - “BACKWARD”.
    finite_elements
    Number of finite elements to use when transforming length domain, default - 20.
    collocation_points
    Number of collocation points to use when transforming length domain, default - 3.
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(PFR) New instance

PFRData Class
class idaes.unit_models.plug_flow_reactor.PFRData(component)[source]

Standard Plug Flow Reactor Unit Model Class

build()[source]

Begin building model (pre-DAE transformation).

Parameters:None
Returns:None

Pressure Changer

The IDAES Pressure Changer model represents a unit operation with a single stream of material which undergoes a change in pressure due to the application of a work. The Pressure Changer model contains support for a number of different thermodynamic assumptions regarding the working fluid.

Degrees of Freedom

Pressure Changer units generally have one or more degrees of freedom, depending on the thermodynamic assumption used.

Typical fixed variables are:

  • outlet pressure, \(P_{ratio}\) or \(\Delta P\),
  • unit efficiency (isentropic or pump assumption).
Model Structure

The core Pressure Changer unit model consists of a single control volume (named ControlVolume0DBlock), a state block, containing the states, one Inlet Port (named inlet) and one Outlet Port (named outlet).

Variables

Pressure Changers contain the following Variables (not including those contained within the control volume Block):

Variable Name Notes
\(P_{ratio}\) ratioP  
\(V_t\) volume Only if has_rate_reactions = True, reference to control_volume.rate_reaction_extent
\(W_{mechanical,t}\) work_mechanical Reference to control_volume.work
\(W_{fluid,t}\) work_fluid Pump assumption only
\(\eta_{pump,t}\) efficiency_pump Pump assumption only
\(W_{isentropic,t}\) work_isentropic Isentropic assumption only
\(\eta_{isentropic,t}\) efficiency_isentropic Isentropic assumption only

Isentropic Pressure Changers also have an additional Property Block named properties_isentropic (attached to the Unit Model).

Constraints

In addition to the Constraints written by the Control Volume block, Pressure Changer writes additional Constraints which depend on the thermodynamic assumption chosen. All Pressure Changers add the following Constraint to calculate the pressure ratio:

\[P_{ratio,t} \times P_{in,t} = P_{out,t}\]
Isothermal Assumption

The isothermal assumption writes one additional Constraint:

\[T_{out} = T_{in}\]
Adiabatic Assumption

The isothermal assumption writes one additional Constraint:

\[H_{out} = H_{in}\]
Isentropic Assumption

The isentropic assumption creates an additional set of Property Blocks (indexed by time) for the isentropic fluid calculations (named properties_isentropic). This requires a set of balance equations relating the inlet state to the isentropic conditions, which are shown below:

\[F_{in,t,p,j} = F_{out,t,p,j}\]
\[s_{in,t} = s_{isentropic,t}\]
\[P_{in,t} \times P_{ratio,t} = P_{isentropic,t}\]

where \(F_{t,p,j}\) is the flow of component \(j\) in phase \(p\) at time \(t\) and \(s\) is the specific entropy of the fluid at time \(t\).

Next, the isentropic work is calculated as follows:

\[W_{isentropic,t} = \sum_p{H_{isentropic,t,p}} - \sum_p{H_{in,t,p}}\]

where \(H_{t,p}\) is the total energy flow of phase \(p\) at time \(t\). Finally, a constraint which relates the fluid work to the actual mechanical work via an efficiency term \(\eta\).

If compressor is True, \(W_{isentropic,t} = W_{mechanical,t} \times \eta_t\)

If compressor is False, \(W_{isentropic,t} \times \eta_t = W_{mechanical,t}\)

Pump (Incompressible Fluid) Assumption

The incompressible fluid assumption writes two additional constraints. Firstly, a Constraint is written which relates fluid work to the pressure change of the fluid.

\[W_{fluid,t} = (P_{out,t}-P_{in,t})\times F_{vol,t}\]

where \(F_{vol,t}\) is the total volumetric flowrate of material at time \(t\) (from the outlet Property Block). Secondly, a constraint which relates the fluid work to the actual mechanical work via an efficiency term \(\eta\).

If compressor is True, \(W_{fluid,t} = W_{mechanical,t} \times \eta_t\)

If compressor is False, \(W_{fluid,t} \times \eta_t = W_{mechanical,t}\)

PressureChanger Class
class idaes.unit_models.pressure_changer.PressureChanger(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    compressor
    Indicates whether this unit should be considered a compressor (True (default), pressure increase) or an expander (False, pressure decrease).
    thermodynamic_assumption
    Flag to set the thermodynamic assumption to use for the unit. - ThermodynamicAssumption.isothermal (default) - ThermodynamicAssumption.isentropic - ThermodynamicAssumption.pump - ThermodynamicAssumption.adiabatic
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(PressureChanger) New instance

PressureChangerData Class
class idaes.unit_models.pressure_changer.PressureChangerData(component)[source]

Standard Compressor/Expander Unit Model Class

add_adiabatic()[source]

Add constraints for adiabatic assumption.

Parameters:None
Returns:None
add_isentropic()[source]

Add constraints for isentropic assumption.

Parameters:None
Returns:None
add_isothermal()[source]

Add constraints for isothermal assumption.

Parameters:None
Returns:None
add_performance()[source]

Define constraints which describe the behaviour of the unit model.

Parameters:None
Returns:None
add_pump()[source]

Add constraints for the incompressible fluid assumption

Parameters:None
Returns:None
build()[source]
Parameters:None
Returns:None
init_isentropic(state_args, outlvl, solver, optarg)[source]

Initialisation routine for unit (default solver ipopt)

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating whcih solver to use during initialization (default = ‘ipopt’)
Returns:

None

initialize(state_args={}, routine=None, outlvl=0, solver='ipopt', optarg={'tol': 1e-06})[source]

General wrapper for pressure changer initialisation routines

Keyword Arguments:
 
  • routine – str stating which initialization routine to execute * None - use routine matching thermodynamic_assumption * ‘isentropic’ - use isentropic initialization routine * ‘isothermal’ - use isothermal initialization routine
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating whcih solver to use during initialization (default = ‘ipopt’)
Returns:

None

model_check()[source]

Check that pressure change matches with compressor argument (i.e. if compressor = True, pressure should increase or work should be positive)

Parameters:None
Returns:None
set_geometry()[source]

Define the geometry of the unit as necessary, and link to control volume

Parameters:None
Returns:None

Product Block

Product Blocks are used to represent sinks of material in Flowsheets. These can be used as a conventient way to mark the final destination of a material stream and to view the state of that material.

Degrees of Freedom

Product blocks generally have zero degrees of freedom.

Model Structure

Product Blocks consists of a single StateBlock (named properties), each with one Inlet Port (named inlet). Product Blocks also contain References to the state variables defined within the StateBlock

Additional Constraints

Product Blocks write no additional constraints to the model.

Variables

Product blocks add no additional Variables.

Product Class
class idaes.unit_models.product.Product(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = False. Product blocks are always steady- state.
    has_holdup
    Product blocks do not contain holdup, thus this must be False.
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PhysicalParameterObject - a PhysicalParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Product) New instance

ProductData Class
class idaes.unit_models.product.ProductData(component)[source]

Standard Product Block Class

build()[source]

Begin building model.

Parameters:None
Returns:None
initialize(state_args={}, outlvl=0, solver='ipopt', optarg={'tol': 1e-06})[source]

This method calls the initialization method of the state block.

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating which solver to use during initialization (default = ‘ipopt’)
Returns:

None

Separator

The IDAES Separator unit model represents operations where a single stream is split into multiple flows. The Separator model supports separation using split fractions, or by ideal separation of flows. The Separator class can be used to create either a stand-alone separator unit, or as part of a unit model where a flow needs to be separated.

Degrees of Freedom

Separator units have a number of degrees of freedom based on the separation type chosen.

  • If split_basis = ‘phaseFlow’, degrees of freedom are generally \((no. outlets-1) \times no. phases\)
  • If split_basis = ‘componentFlow’, degrees of freedom are generally \((no. outlets-1) \times no. components\)
  • If split_basis = ‘phaseComponentFlow’, degrees of freedom are generally \((no. outlets-1) \times no. phases \times no. components\)
  • If split_basis = ‘totalFlow’, degrees of freedom are generally \((no. outlets-1) \times no. phases \times no. components\)

Typical fixed variables are:

  • split fractions.
Model Structure

The IDAES Separator unit model does not use ControlVolumes, and instead writes a set of material, energy and momentum balances to split the inlet stream into a number of outlet streams. Separator models have a single inlet Port (named inlet) and a user-defined number of outlet Ports (by default named outlet_1, outlet_2, etc.).

Mixed State Block

If a mixed state block is provided in the construction arguments, the Mixer model will use this as the StateBlock for the mixed stream in the resulting balance equations. This allows a Mixer unit to be used as part of a larger unit operation by linking to an existing StateBlock.

Ideal Separation

The IDAES Separator model supports ideal separations, where all of a given subset of the mixed stream is sent to a single outlet (i.e. split fractions are equal to zero or one). In these cases, no Constraints are necessary for performing the separation, as the mixed stream states can be directly partitioned to the outlets.

Ideal separations will not work for all choices of state variables, and thus will not work for all property packages. To use ideal separations, the user must provide a map of what part of the mixed flow should be partitioned to each outlet. The ideal_split_map should be a dict-like object with keys as tuples matching the split_basis argument and values indicating which outlet this subset should be partitioned to.

Variables

Separator units have the following variables (\(o\) indicates index by outlet):

Variable Name Symbol Notes
split_fraction \(\phi_{t, o, *}\) Indexing sets depend upon split_basis
Constraints

Separator units have the following Constraints, unless ideal_separation is True.

material_splitting_eqn(t, o, p, j):

\[F_{in, t, p, j} = \phi_{t, p, *} \times F_{t, o, p, j}\]

temperature_equality_eqn(t, o):

\[T_{in, t} = T_{t, o}\]

pressure_equality_eqn(t, o):

\[P_{in, t} = P_{t, o}\]
Separator Class
class idaes.unit_models.separator.Separator(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = False. Product blocks are always steady- state.
    has_holdup
    Product blocks do not contain holdup, thus this must be False.
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    outlet_list
    A list containing names of outlets, default - None. Valid values: { None - use num_outlets argument, list - a list of names to use for outlets.}
    num_outlets
    Argument indicating number (int) of outlets to construct, not used if outlet_list arg is provided, default - None. Valid values: { None - use outlet_list arg instead, or default to 2 if neither argument provided, int - number of outlets to create (will be named with sequential integers from 1 to num_outlets).}
    split_basis
    Argument indicating basis to use for splitting mixed stream, default - SplittingType.totalFlow. Valid values: { SplittingType.totalFlow - split based on total flow (split fraction indexed only by time and outlet), SplittingType.phaseFlow - split based on phase flows (split fraction indexed by time, outlet and phase), SplittingType.componentFlow - split based on component flows (split fraction indexed by time, outlet and components), SplittingType.phaseComponentFlow - split based on phase-component flows ( split fraction indexed by both time, outlet, phase and components).}
    energy_split_basis
    Argument indicating basis to use for splitting energy this is not used for when ideal_separation == True. default - EnergySplittingType.equal_temperature. Valid values: { EnergySplittingType.equal_temperature - outlet temperatures equal inlet EnergySplittingType.equal_molar_enthalpy - oulet molar enthalpies equal inlet}
    ideal_separation
    Argument indicating whether ideal splitting should be used. Ideal splitting assumes perfect spearation of material, and attempts to avoid duplication of StateBlocks by directly partitioning outlet flows to ports, default - True. Valid values: { True - use ideal splitting methods, False - use explicit splitting equations with split fractions.}
    ideal_split_map
    Dictionary containing information on how extensive variables should be partitioned when using ideal splitting (ideal_separation = True). default - None. Valid values: { dict with keys of indexing set members and values indicating which outlet this combination of keys should be partitioned to. E.g. {(“Vap”, “H2”): “outlet_1”}}
    mixed_state_block
    An existing state block to use as the source stream from the Separator block, default - None. Valid values: { None - create a new StateBlock for the mixed stream, StateBlock - a StateBock to use as the source for the mixed stream.}
    construct_ports
    Argument indicating whether model should construct Port objects linked the mixed state and all outlet states, default - True. Valid values: { True - construct Ports for all states, False - do not construct Ports.
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Separator) New instance

SeparatorData Class
class idaes.unit_models.separator.SeparatorData(component)[source]

This is a general purpose model for a Separator block with the IDAES modeling framework. This block can be used either as a stand-alone Separator unit operation, or as a sub-model within another unit operation.

This model creates a number of StateBlocks to represent the outgoing streams, then writes a set of phase-component material balances, an overall enthalpy balance (2 options), and a momentum balance (2 options) linked to a mixed-state StateBlock. The mixed-state StateBlock can either be specified by the user (allowing use as a sub-model), or created by the Separator.

When being used as a sub-model, Separator should only be used when a set of new StateBlocks are required for the streams to be separated. It should not be used to separate streams to go to mutiple ControlVolumes in a single unit model - in these cases the unit model developer should write their own splitting equations.

add_energy_splitting_constraints(mixed_block)[source]

Creates constraints for splitting the energy flows - done by equating temperatures in outlets.

add_inlet_port_objects(mixed_block)[source]

Adds inlet Port object if required.

Parameters:mixed state StateBlock object (a) –
Returns:None
add_material_splitting_constraints(mixed_block)[source]

Creates constraints for splitting the material flows

add_mixed_state_block()[source]

Constructs StateBlock to represent mixed stream.

Returns:New StateBlock object
add_momentum_splitting_constraints(mixed_block)[source]

Creates constraints for splitting the momentum flows - done by equating pressures in outlets.

add_outlet_port_objects(outlet_list, outlet_blocks)[source]

Adds outlet Port objects if required.

Parameters:list of outlet StateBlock objects (a) –
Returns:None
add_outlet_state_blocks(outlet_list)[source]

Construct StateBlocks for all outlet streams.

Parameters:of strings to use as StateBlock names (list) –
Returns:list of StateBlocks
add_split_fractions(outlet_list)[source]

Creates outlet Port objects and tries to partiton mixed stream flows between these

Parameters:
  • representing the mixed flow to be split (StateBlock) –
  • list of names for outlets (a) –
Returns:

None

build()[source]

General build method for SeparatorData. This method calls a number of sub-methods which automate the construction of expected attributes of unit models.

Inheriting models should call super().build.

Parameters:None
Returns:None
create_outlet_list()[source]

Create list of outlet stream names based on config arguments.

Returns:list of strings
get_mixed_state_block()[source]

Validates StateBlock provided in user arguments for mixed stream.

Returns:The user-provided StateBlock or an Exception
initialize(outlvl=0, optarg={}, solver='ipopt', hold_state=False)[source]

Initialisation routine for separator (default solver ipopt)

Keyword Arguments:
 
  • outlvl – sets output level of initialisation routine. Valid values: 0 - no output (default), 1 - return solver state for each step in routine, 2 - include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default=None)
  • solver – str indicating whcih solver to use during initialization (default = ‘ipopt’)
  • hold_state – flag indicating whether the initialization routine should unfix any state variables fixed during initialization, default - False. Valid values: True - states variables are not unfixed, and a dict of returned containing flags for which states were fixed during initialization, False - state variables are unfixed after initialization by calling the release_state method.
Returns:

If hold_states is True, returns a dict containing flags for which states were fixed during initialization.

model_check()[source]

This method executes the model_check methods on the associated state blocks (if they exist). This method is generally called by a unit model as part of the unit’s model_check method.

Parameters:None
Returns:None
partition_outlet_flows(mb, outlet_list)[source]

Creates outlet Port objects and tries to partiton mixed stream flows between these

Parameters:
  • representing the mixed flow to be split (StateBlock) –
  • list of names for outlets (a) –
Returns:

None

release_state(flags, outlvl=0)[source]

Method to release state variables fixed during initialisation.

Keyword Arguments:
 
  • flags – dict containing information of which state variables were fixed during initialization, and should now be unfixed. This dict is returned by initialize if hold_state = True.
  • outlvl – sets output level of logging
Returns:

None

StateJunction Block

The IDAES StateJunction block represents a pass-through unit or simple pipe with no holdup. The primary use for this unit is in conceptual design applications for linking Arcs to/from different process alternatives.

Degrees of Freedom

StateJunctions have no degrees of freedom.

Model Structure

A StateJunction consists of a single StateBlock with two Ports (inlet and outlet), where the state variables in the state block are simultaneously connected to both Ports.

Additional Constraints

StateJunctions write no additional constraints beyond those in the StateBlock.

Variables

StateJunctions have no additional variables.

StateJunction Class
class idaes.unit_models.statejunction.StateJunction(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this unit will be dynamic or not, default = False.
    has_holdup
    Indicates whether holdup terms should be constructed or not. default - False. StateJunctions do not have defined volume, thus this must be False.
    property_package
    Property parameter object used to define property state block, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PhysicalParameterObject - a PhysicalParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(StateJunction) New instance

StateJunctionData Class
class idaes.unit_models.statejunction.StateJunctionData(component)[source]

Standard StateJunction Unit Model Class

build()[source]

Begin building model. :param None:

Returns:None
initialize(state_args={}, outlvl=0, solver='ipopt', optarg={'tol': 1e-06})[source]

This method initializes the StateJunction block by calling the initialize method on the property block.

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating which solver to use during initialization (default = ‘ipopt’)
Returns:

None

Stoichiometric (Yield) Reactor

The IDAES Stoichiometric reactor model represents a unit operation where a single material stream undergoes some chemical reaction(s) subject to a set of extent or yield specifications.

Degrees of Freedom

Stoichiometric reactors generally have degrees of freedom equal to the number of reactions + 1.

Typical fixed variables are:

  • reaction extents or yields (1 per reaction),
  • reactor heat duty (has_heat_transfer = True only).
Model Structure

The core Stoichiometric reactor unit model consists of a single ControlVolume0DBlock (named control_volume) with one Inlet Port (named inlet) and one Outlet Port (named outlet).

Variables

Stoichiometric reactors units add the following variables:

Variable Name Notes
\(Q_t\) heat Only if has_heat_transfer = True, reference to control_volume.heat
\(deltaP_t\) pressure change Only if has_pressure_change = True, reference to control_volume.deltaP
Constraints

Stoichiometric reactor units write no additional Constraints beyond those written by the control_volume Block.

StoichiometricReactor Class
class idaes.unit_models.stoichiometric_reactor.StoichiometricReactor(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_heat_of_reaction
    Indicates whether terms for heat of reaction terms should be constructed, default - False. Valid values: { True - include heat of reaction terms, False - exclude heat of reaction terms.}
    has_heat_transfer
    Indicates whether terms for heat transfer should be constructed, default - False. Valid values: { True - include heat transfer terms, False - exclude heat transfer terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    reaction_package
    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}
    reaction_package_args
    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(StoichiometricReactor) New instance

StoichiometricReactorData Class
class idaes.unit_models.stoichiometric_reactor.StoichiometricReactorData(component)[source]

Standard Stoichiometric Reactor Unit Model Class This model assumes that all given reactions are irreversible, and that each reaction has a fixed rate_reaction extent which has to be specified by the user.

build()[source]

Begin building model (pre-DAE transformation). :param None:

Returns:None

Translator Block

Translator blocks are used in complex flowsheets where the user desires to use different property packages for different parts of the flowsheet. In order to link two streams using different property packages, a translator block is required.

The core translator block provides a general framework for constructing Translator Blocks, however users need to add constraints to map the incoming states to the outgoing states as required by their specific application.

Degrees of Freedom

The degrees of freedom of Translator blocks depends on the property packages being used, and the user should write a sufficient number of constraints mapping inlet states to outlet states to satisfy these degrees of freedom.

Model Structure

The core Translator Block consists of two State Blocks, names properties_in and properties_out, which are linked to two Ports names inlet and outlet respectively.

Additional Constraints

The core Translator Block writes no additional constraints. Users should add constraints to their instances as required.

Variables

Translator blocks add no additional Variables.

Translator Class
class idaes.unit_models.translator.Translator(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Translator blocks are always steady-state.
    has_holdup
    Translator blocks do not contain holdup.
    outlet_state_defined
    Indicates whether unit model will fully define outlet state. If False, the outlet property package will enforce constraints such as sum of mole fractions and phase equilibrium. default - True. Valid values: { True - outlet state will be fully defined, False - outlet property package should enforce sumation and equilibrium constraints.}
    has_phase_equilibrium
    Indicates whether outlet property package should enforce phase equilibrium constraints. default - False. Valid values: { True - outlet property package should calculate phase equilibrium, False - outlet property package should notcalculate phase equilibrium.}
    inlet_property_package
    Property parameter object used to define property calculations for the incoming stream, default - None. Valid values: { PhysicalParameterObject - a PhysicalParameterBlock object.}
    inlet_property_package_args
    A ConfigBlock with arguments to be passed to the property block associated with the incoming stream, default - None. Valid values: { see property package for documentation.}
    outlet_property_package
    Property parameter object used to define property calculations for the outgoing stream, default - None. Valid values: { PhysicalParameterObject - a PhysicalParameterBlock object.}
    outlet_property_package_args
    A ConfigBlock with arguments to be passed to the property block associated with the outgoing stream, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Translator) New instance

TranslatorData Class
class idaes.unit_models.translator.TranslatorData(component)[source]

Standard Translator Block Class

build()[source]

Begin building model.

Parameters:None
Returns:None
initialize(state_args_in={}, state_args_out={}, outlvl=0, solver='ipopt', optarg={'tol': 1e-06})[source]

This method calls the initialization method of the state blocks.

Keyword Arguments:
 
  • state_args_in – a dict of arguments to be passed to the inlet property package (to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • state_args_out – a dict of arguments to be passed to the outlet property package (to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating which solver to use during initialization (default = ‘ipopt’)
Returns:

None

Power Generation Models

Feedwater Heater (0D)

The FWH0D model is a 0D feedwater heater model suitable for steady state modeling. It is intended to be used primarily used with the IAWPS95 property package. The feedwater heater is split into three sections the condensing section is required while the desuperheating and drain cooling sections are optional. There is also an optional mixer for adding a drain stream from another feedwater heater to the condensing section. The figure below shows the layout of the feedwater heater. All but the condensing section are optional.

_images/feedwater_heater_0D.svg

Feedwater Heater

Example

The example below shows how to setup a feedwater heater with all tree sections. The feedwater flow rate, steam conditions, heat transfer coefficients and areas are not necessarily realistic.

import pyomo.environ as pyo
from idaes.core import FlowsheetBlock
from idaes.unit_models.heat_exchanger import (delta_temperature_underwood2_rule,
    delta_temperature_underwood_rule, delta_temperature_lmtd_rule)
from idaes.property_models import Iapws95ParameterBlock
from idaes.unit_models.power_generation import FWH0D

def make_fwh_model():
    model = pyo.ConcreteModel()
    model.fs = FlowsheetBlock(default={
        "dynamic": False,
        "default_property_package": Iapws95ParameterBlock()})
    model.fs.properties = model.fs.config.default_property_package
    model.fs.fwh = FWH0D(default={
        "has_desuperheat":True,
        "has_drain_cooling":True,
        "has_drain_mixer":True,
        "property_package":model.fs.properties})

    model.fs.fwh.desuperheat.inlet_1.flow_mol.fix(100)
    model.fs.fwh.desuperheat.inlet_1.flow_mol.unfix()
    model.fs.fwh.desuperheat.inlet_1.pressure.fix(201325)
    model.fs.fwh.desuperheat.inlet_1.enth_mol.fix(60000)
    model.fs.fwh.drain_mix.drain.flow_mol.fix(1)
    model.fs.fwh.drain_mix.drain.pressure.fix(201325)
    model.fs.fwh.drain_mix.drain.enth_mol.fix(20000)
    model.fs.fwh.cooling.inlet_2.flow_mol.fix(400)
    model.fs.fwh.cooling.inlet_2.pressure.fix(101325)
    model.fs.fwh.cooling.inlet_2.enth_mol.fix(3000)
    model.fs.fwh.condense.area.fix(1000)
    model.fs.fwh.condense.overall_heat_transfer_coefficient.fix(100)
    model.fs.fwh.desuperheat.area.fix(1000)
    model.fs.fwh.desuperheat.overall_heat_transfer_coefficient.fix(10)
    model.fs.fwh.cooling.area.fix(1000)
    model.fs.fwh.cooling.overall_heat_transfer_coefficient.fix(10)

    model.fs.fwh.initialize()
    return(model)

# create a feedwater heater model with all optional units and initialize
model = make_fwh_model()
Model Structure

The condensing section uses the FWHCondensing0D model to calculate a steam flow rate such that all steam is condensed in the condensing section. This allows turbine steam extraction rates to be calculated. The other sections are regular HeatExchanger models. The table below shows the unit models which make up the feedwater heater, and the option to include or exclude them.

Unit Option Doc
condense Condensing section (FWHCondensing0D)
desuperheat has_desuperheat Desuperheating section (HeatExchanger)
cooling has_drain_cooling Drain cooling section (HeatExchanger)
drain_mix has_drain_mixer Mixer for steam and other FWH drain (Mixer)
Degrees of Freedom

The area and overall_heat_transfer_coefficient should be fixed or constraints should be provided to calculate overall_heat_transfer_coefficient. If the inlets are also fixed except for the inlet steam flow rate (inlet_1.flow_mol), the model will have 0 degrees of freedom.

FWH0D Class
class idaes.unit_models.power_generation.feedwater_heater_0D.FWH0D(*args, **kwargs)

Feedwater Heater Model This is a 0D feedwater heater model. The model may contain three 0D heat exchanger models representing the desuperheat, condensing and drain cooling sections of the feedwater heater. Only the condensing section must be included. A drain mixer can also be optionally included, which mixes the drain outlet of another feedwater heater with the steam fed into the condensing section.

Args:

rule (function): A rule function or None. Default rule calls build(). concrete (bool): If True, make this a toplevel model. Default - False. ctype (str): Pyomo ctype of the block. Default - “Block” default (dict): Default ProcessBlockData config

Keys
dynamic
Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
has_holdup
Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
has_drain_mixer
Add a mixer to the inlet of the condensing section to add water from the drain of another feedwaterheater to the steam, if True
has_desuperheat
Add a mixer desuperheat section to the heat exchanger
has_drain_cooling
Add a section after condensing section to cool condensate.
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
condense

ProcessBlockData

dynamic
Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
has_holdup
Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
side_1

A config block used to construct the side_1 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
side_2

A config block used to construct the side_2 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
delta_temperature_rule
Rule for equation for temperature difference
flow_pattern
Heat exchanger flow pattern, default - HeatExchangerFlowPattern.countercurrent. Valid values: { HeatExchangerFlowPattern.countercurrent - countercurrent flow, HeatExchangerFlowPattern.cocurrent - cocurrent flow, HeatExchangerFlowPattern.crossflow - cross flow, factor times countercurrent temperature difference.}
desuperheat

ProcessBlockData

dynamic
Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
has_holdup
Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
side_1

A config block used to construct the side_1 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
side_2

A config block used to construct the side_2 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
delta_temperature_rule
Rule for equation for temperature difference
flow_pattern
Heat exchanger flow pattern, default - HeatExchangerFlowPattern.countercurrent. Valid values: { HeatExchangerFlowPattern.countercurrent - countercurrent flow, HeatExchangerFlowPattern.cocurrent - cocurrent flow, HeatExchangerFlowPattern.crossflow - cross flow, factor times countercurrent temperature difference.}
cooling

ProcessBlockData

dynamic
Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
has_holdup
Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
side_1

A config block used to construct the side_1 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
side_2

A config block used to construct the side_2 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
delta_temperature_rule
Rule for equation for temperature difference
flow_pattern
Heat exchanger flow pattern, default - HeatExchangerFlowPattern.countercurrent. Valid values: { HeatExchangerFlowPattern.countercurrent - countercurrent flow, HeatExchangerFlowPattern.cocurrent - cocurrent flow, HeatExchangerFlowPattern.crossflow - cross flow, factor times countercurrent temperature difference.}
initialize (dict): ProcessBlockData config for individual elements. Keys
are BlockData indexes and values are dictionaries described under the “default” argument above.
idx_map (function): Function to take the index of a BlockData element and
return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:
(FWH0D) New instance
FWH0DData Class
class idaes.unit_models.power_generation.feedwater_heater_0D.FWH0DData(component)[source]
build()[source]

General build method for UnitModelBlockData. This method calls a number of sub-methods which automate the construction of expected attributes of unit models.

Inheriting models should call super().build.

Parameters:None
Returns:None
initialize(*args, **kwargs)[source]

This is a general purpose initialization routine for simple unit models. This method assumes a single ControlVolume block called controlVolume, and first initializes this and then attempts to solve the entire unit.

More complex models should overload this method with their own initialization routines,

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating which solver to use during initialization (default = ‘ipopt’)
Returns:

None

Feedwater Heater (Condensing Section 0D)

The condensing feedwater heater is the same as the HeatExchanger model with one additional constraint to calculate the inlet flow rate such that all the entering steam is condensed. This model is suitable for steady state modeling, and is intended to be used with the IAWPS95 property package. For dynamic modeling, the 1D feedwater heater models should be used (not yet publicly available).

Degrees of Freedom

Usually area and overall_heat_transfer_coefficient are fixed or constraints are provided to calculate overall_heat_transfer_coefficient. If the inlets are also fixed except for the inlet steam flow rate (inlet_1.flow_mol), the model will have 0 degrees of freedom.

Variables

The variables are the same as HeatExchanger.

Constraints

In addition to the HeatExchanger constraints, there is one additional constraint to calculate the inlet steam flow such that all steam condenses. The constraint is called extraction_rate_constraint, and is defined below.

\[h_{steam, out} = h_{sat, liquid}(P)\]

Where \(h\) is molar enthalpy, and the saturated liquid enthalpy is a function of pressure.

FWHCondensing0D Class
class idaes.unit_models.power_generation.feedwater_heater_0D.FWHCondensing0D(*args, **kwargs)

Feedwater Heater Condensing Section The feedwater heater condensing section model is a normal 0D heat exchanger model with an added constraint to calculate the steam flow such that the outlet of side_1 is a saturated liquid.

Args:

rule (function): A rule function or None. Default rule calls build(). concrete (bool): If True, make this a toplevel model. Default - False. ctype (str): Pyomo ctype of the block. Default - “Block” default (dict): Default ProcessBlockData config

Keys
dynamic
Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
has_holdup
Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
side_1

A config block used to construct the side_1 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
side_2

A config block used to construct the side_2 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
delta_temperature_rule
Rule for equation for temperature difference
flow_pattern
Heat exchanger flow pattern, default - HeatExchangerFlowPattern.countercurrent. Valid values: { HeatExchangerFlowPattern.countercurrent - countercurrent flow, HeatExchangerFlowPattern.cocurrent - cocurrent flow, HeatExchangerFlowPattern.crossflow - cross flow, factor times countercurrent temperature difference.}
initialize (dict): ProcessBlockData config for individual elements. Keys
are BlockData indexes and values are dictionaries described under the “default” argument above.
idx_map (function): Function to take the index of a BlockData element and
return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:
(FWHCondensing0D) New instance
FWHCondensing0DData Class
class idaes.unit_models.power_generation.feedwater_heater_0D.FWHCondensing0DData(component)[source]
build()[source]

Building model

Parameters:None
Returns:None
initialize(*args, **kwargs)[source]

Use the regular heat exchanger initilization, with the extraction rate constraint deactivated; then it activates the constraint and calculates a steam inlet flow rate.

Turbine (Inlet Stage)

This is a steam power generation turbine model for the inlet stage. The turbine inlet model is based on:

Liese, (2014). “Modeling of a Steam Turbine Including Partial Arc Admission for Use in a Process Simulation Software Environment.” Journal of Engineering for Gas Turbines and Power. v136.

Example
from pyomo.environ import ConcreteModel, SolverFactory, TransformationFactory
from idaes.core import FlowsheetBlock
from idaes.unit_models.power_generation import TurbineInletStage
from idaes.property_models import iapws95_ph
from idaes.ui.report import degrees_of_freedom

m = ConcreteModel()
m.fs = FlowsheetBlock(default={"dynamic": False})
m.fs.properties = iapws95_ph.Iapws95ParameterBlock()
m.fs.turb = TurbineInletStage(default={"property_package": m.fs.properties})
hin = iapws95_ph.htpx(T=880, P=2.4233e7)
# set inlet
m.fs.turb.inlet[:].enth_mol.fix(hin)
m.fs.turb.inlet[:].flow_mol.fix(26000/4.0)
m.fs.turb.inlet[:].pressure.fix(2.4233e7)
m.fs.turb.eff_nozzle.fix(0.95)
m.fs.turb.blade_reaction.fix(0.9)
m.fs.turb.flow_coeff.fix(1.053/3600.0)
m.fs.turb.blade_velocity.fix(110.0)
m.fs.turb.efficiency_mech.fix(0.98)

m.fs.turb.initialize()
Degrees of Freedom

Usually the inlet stream, or the inlet stream minus flow rate plus discharge pressure are fixed. There are also a few variables which are turbine parameters and are usually fixed. See the variables section for more information.

Model Structure

The turbine inlet stage model contains one ControlVolume0DBlock block called control_volume and inherits the PressureChanger model using the isentropic option.

Variables

The variables below are defined in the TurbineInletStage model. Additional variables are inherited from the PressureChanger model model.

Variable Symbol Index Sets Doc
blade_reaction \(R\) None Blade reaction
eff_nozzle \(\eta_{nozzle}\) None Nozzle efficiency
efficiency_mech \(\eta_{mech}\) None Mechanical Efficiency (accounts for losses in bearings…)
flow_coeff \(C_{flow}\) None Turbine stage flow coefficient [kg*C^0.5/Pa/s]
blade_velocity \(V_{rbl}\) None Turbine blade velocity (should be constant while running) [m/s]
delta_enth_isentropic \(\Delta h_{isen}\) time Isentropic enthalpy change through stage [J/mol]

The table below shows important variables inherited from the pressure changer model.

Variable Symbol Index Sets Doc
efficiency_isentropic \(\eta_{isen}\) time Isentropic efficiency
deltaP \(\Delta P\) time Pressure change (\(P_{out} - P_{in}\)) [Pa]
ratioP \(P_{ratio}\) time Ratio of discharge pressure to inlet pressure \(\left(\frac{P_{out}}{P_{in}}\right)\)
Expressions
Variable Symbol Index Sets Doc
power_thermo \(\dot{w}_{thermo}\) time Turbine stage power output not including mechanical loss [W]
power_shaft \(\dot{w}_{shaft}\) time Turbine stage power output including mechanical loss (bearings…) [W]
steam_entering_velocity \(V_0\) time Steam velocity entering stage [m/s]

The expression defined below provides a calculation for steam velocity entering the stage, which is used in the efficiency calculation.

\[V_0 = 1.414\sqrt{\frac{-(1 - R)\Delta h_{isen}}{WT_{in}\eta_{nozzel}}}\]
Constraints

In addition to the constraints inherited from the PressureChanger model with the isentropic options, this model contains two more constraints, one to estimate efficiency and one pressure-flow relation. From the isentropic pressure changer model, these constraints eliminate the need to specify efficiency and either inlet flow or outlet pressure.

The isentropic efficiency is given by:

\[\eta_{isen} = 2 \frac{V_{rbl}}{V_0}\left[\left(\sqrt{1 - R} - \frac{V_{rbl}}{V_0}\right) + \sqrt{\left(\sqrt{1 - R} - \frac{V_{rbl}}{V_0}\right)^2 + R}\right]\]

The pressure-flow relation is given by:

\[\dot{m} = C_{flow}\frac{P_{in}}{\sqrt{T_{in}-273.15}}\sqrt{\frac{\gamma}{\gamma-1} \left[ \left(\frac{P_{out}}{P_{in}}\right)^{\frac{2}{\gamma}} - \left(\frac{P_{out}}{P_{in}}\right)^{\frac{\gamma+1}{\gamma}} \right]}\]
Initialization

The initialization method for this model will save the current state of the model before commencing initialization and reloads it afterwards. The state of the model will be the same after initialization, only the initial guesses for unfixed variables will be changed. To initialize this model, provide a starting value for the inlet port variables. Then provide a guess for one of: discharge pressure, deltaP, or ratioP.

The model should initialize readily, but it is possible to provide a flow coefficient that is incompatible with the given flow rate resulting in an infeasible problem.

TurbineInletStage Class
class idaes.unit_models.power_generation.turbine_inlet.TurbineInletStage(*args, **kwargs)

Inlet stage steam turbine model

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    compressor
    Indicates whether this unit should be considered a compressor (True (default), pressure increase) or an expander (False, pressure decrease).
    thermodynamic_assumption
    Flag to set the thermodynamic assumption to use for the unit. - ThermodynamicAssumption.isothermal (default) - ThermodynamicAssumption.isentropic - ThermodynamicAssumption.pump - ThermodynamicAssumption.adiabatic
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(TurbineInletStage) New instance

TurbineInletStageData Class
class idaes.unit_models.power_generation.turbine_inlet.TurbineInletStageData(component)[source]
build()[source]
Parameters:None
Returns:None
initialize(state_args={}, outlvl=0, solver='ipopt', optarg={'max_iter': 30, 'tol': 1e-06})[source]

Initialize the inlet turbine stage model. This deactivates the specialized constraints, then does the isentropic turbine initialization, then reactivates the constraints and solves.

Parameters:
  • state_args (dict) – Initial state for property initialization
  • outlvl (int) – Amount of output (0 to 3) 0 is lowest
  • solver (str) – Solver to use for initialization
  • optarg (dict) – Solver arguments dictionary
Turbine (Outlet Stage)

This is a steam power generation turbine model for the outlet stage. The turbine outlet model is based on:

Liese, (2014). “Modeling of a Steam Turbine Including Partial Arc Admission for Use in a Process Simulation Software Environment.” Journal of Engineering for Gas Turbines and Power. v136.

Example
from pyomo.environ import ConcreteModel, SolverFactory
from idaes.core import FlowsheetBlock
from idaes.unit_models.power_generation import TurbineOutletStage
from idaes.property_models import iapws95_ph
from idaes.ui.report import degrees_of_freedom

m = ConcreteModel()
m.fs = FlowsheetBlock(default={"dynamic": False})
m.fs.properties = iapws95_ph.Iapws95ParameterBlock()
m.fs.turb = TurbineOutletStage(default={"property_package": m.fs.properties})
# set inlet
m.fs.turb.inlet[:].enth_mol.fix(47115)
m.fs.turb.inlet[:].flow_mol.fix(15000)
m.fs.turb.inlet[:].pressure.fix(8e4)

m.fs.turb.initialize()
Degrees of Freedom

Usually the inlet stream, or the inlet stream minus flow rate plus discharge pressure are fixed. There are also a few variables which are turbine parameters and are usually fixed. See the variables section for more information.

Model Structure

The turbine outlet stage model contains one ControlVolume0DBlock block called control_volume and inherits the PressureChanger model using the isentropic option.

Variables

The variables below are defined int the TurbineInletStage model. Additional variables are in inherited from the PressureChanger model model.

Variable Symbol Index Sets Doc
eff_dry \(\eta_{dry}\) None Turbine efficiency when no liquid is present.
efficiency_mech \(\eta_{mech}\) None Mechanical Efficiency (accounts for losses in bearings…)
flow_coeff \(C_{flow}\) None Turbine stage flow coefficient [kg*C^0.5/Pa/s]
design_exhaust_flow_vol \(V_{des,exhaust}\) None Design volumetric flow out of stage [m^3/s]

The table below shows important variables inherited from the pressure changer model.

Variable Symbol Index Sets Doc
efficiency_isentropic \(\eta_{isen}\) time Isentropic efficiency
deltaP \(\Delta P\) time Pressure change (\(P_{out} - P_{in}\)) [Pa]
ratioP \(P_{ratio}\) time Ratio of discharge pressure to inlet pressure \(\left(\frac{P_{out}}{P_{in}}\right)\)
Expressions
Variable Symbol Index Sets Doc
power_thermo \(\dot{w}_{thermo}\) time Turbine stage power output not including mechanical loss [W]
power_shaft \(\dot{w}_{shaft}\) time Turbine stage power output including mechanical loss (bearings…) [W]
tel \(\text{TEL}\) time Total exhaust loss [J/mol]

The expression defined below provides a total exhaust loss.

\[\text{TEL} = 1\times 10^6*\left(-0.0035f^5 + 0.022f^4 - 0.0542f^3 + 0.0638f^2 - 0.0328f + 0.0064\right)\]

Where \(f\) is the total volumetric flow of the exhaust divided by the design flow.

Constraints

In addition to the constraints inherited from the PressureChanger model with the isentropic options, this model contains two more constraints, one to estimate efficiency and one pressure-flow relation. From the isentropic pressure changer model, these constraints eliminate the need to specify efficiency and either inlet flow or outlet pressure.

The isentropic efficiency is given by:

\[\eta_{isen} = \eta_{dry}x\left(1 - 0.65(1 - x)\right)*\left(1 + \frac{\text{TEL}}{\Delta h_{isen}}\right)\]

Where \(x\) is the steam quality (vapor fraction).

The pressure-flow relation is given by the Stodola Equation:

\[\dot{m}\sqrt{Tin - 273.15} = C_{flow}P_{in}\sqrt{1 - Pr^2}\]
Initialization

The initialization method for this model will save the current state of the model before commencing initialization and reloads it afterwards. The state of the model will be the same after initialization, only the initial guesses for unfixed variables will be changed. To initialize this model, provide a starting value for the inlet port variables. Then provide a guess for one of: discharge pressure, deltaP, or ratioP.

The model should initialize readily, but it is possible to provide a flow coefficient that is incompatible with the given flow rate resulting in an infeasible problem.

TurbineOutletStage Class
class idaes.unit_models.power_generation.turbine_outlet.TurbineOutletStage(*args, **kwargs)

Outlet stage steam turbine model

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    compressor
    Indicates whether this unit should be considered a compressor (True (default), pressure increase) or an expander (False, pressure decrease).
    thermodynamic_assumption
    Flag to set the thermodynamic assumption to use for the unit. - ThermodynamicAssumption.isothermal (default) - ThermodynamicAssumption.isentropic - ThermodynamicAssumption.pump - ThermodynamicAssumption.adiabatic
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(TurbineOutletStage) New instance

TurbineOutletStageData Class
class idaes.unit_models.power_generation.turbine_outlet.TurbineOutletStageData(component)[source]
build()[source]
Parameters:None
Returns:None
initialize(state_args={}, outlvl=0, solver='ipopt', optarg={'max_iter': 30, 'tol': 1e-06})[source]

Initialize the outlet turbine stage model. This deactivates the specialized constraints, then does the isentropic turbine initialization, then reactivates the constraints and solves.

Parameters:
  • state_args (dict) – Initial state for property initialization
  • outlvl (int) – Amount of output (0 to 3) 0 is lowest
  • solver (str) – Solver to use for initialization
  • optarg (dict) – Solver arguments dictionary
Turbine (Stage)

This is a steam power generation turbine model for the stages between the inlet and outlet. This model inherits the PressureChanger model with the isentropic options. The initialization scheme is the same as the TurbineInletStage model.

Example
from pyomo.environ import ConcreteModel, SolverFactory

from idaes.core import FlowsheetBlock
from idaes.unit_models.power_generation import TurbineStage
from idaes.property_models import iapws95_ph

m = ConcreteModel()
m.fs = FlowsheetBlock(default={"dynamic": False})
m.fs.properties = iapws95_ph.Iapws95ParameterBlock()
m.fs.turb = TurbineStage(default={"property_package": m.fs.properties})
# set inlet
m.fs.turb.inlet[:].enth_mol.fix(70000)
m.fs.turb.inlet[:].flow_mol.fix(15000)
m.fs.turb.inlet[:].pressure.fix(8e6)
m.fs.turb.efficiency_isentropic[:].fix(0.8)
m.fs.turb.ratioP[:].fix(0.7)
m.fs.turb.initialize()
Variables

This model adds a variable to the base PressureChanger model to account for mechanical efficiency .

Variable Symbol Index Sets Doc
efficiency_mech \(\eta_{mech}\) None Mechanical Efficiency (accounts for losses in bearings…)

The table below shows important variables inherited from the pressure changer model.

Variable Symbol Index Sets Doc
efficiency_isentropic \(\eta_{isen}\) time Isentropic efficiency
deltaP \(\Delta P\) time Pressure change (\(P_{out} - P_{in}\)) [Pa]
ratioP \(P_{ratio}\) time Ratio of discharge pressure to inlet pressure \(\left(\frac{P_{out}}{P_{in}}\right)\)

\(\eta_{isentropic,t}\) efficiency_isentropic Isentropic assumption only

Expressions

This model provides two expressions that are not available in the pressure changer model.

Variable Symbol Index Sets Doc
power_thermo \(\dot{w}_{thermo}\) time Turbine stage power output not including mechanical loss [W]
power_shaft \(\dot{w}_{shaft}\) time Turbine stage power output including mechanical loss (bearings…) [W]
Constraints

There are no additional constraints.

Initialization

This just calls the initialization routine from PressureChanger, but it is wrapped in a function to ensure the state after initialization is the same as before initialization. The arguments to the initialization method are the same as PressureChanger.

TurbineStage Class
class idaes.unit_models.power_generation.turbine_stage.TurbineStage(*args, **kwargs)

Basic steam turbine model

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    compressor
    Indicates whether this unit should be considered a compressor (True (default), pressure increase) or an expander (False, pressure decrease).
    thermodynamic_assumption
    Flag to set the thermodynamic assumption to use for the unit. - ThermodynamicAssumption.isothermal (default) - ThermodynamicAssumption.isentropic - ThermodynamicAssumption.pump - ThermodynamicAssumption.adiabatic
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(TurbineStage) New instance

TurbineStageData Class
class idaes.unit_models.power_generation.turbine_stage.TurbineStageData(component)[source]
build()[source]
Parameters:None
Returns:None
initialize(state_args={}, outlvl=0, solver='ipopt', optarg={'max_iter': 30, 'tol': 1e-06})[source]

Initialize the turbine stage model. This deactivates the specialized constraints, then does the isentropic turbine initialization, then reactivates the constraints and solves.

Parameters:
  • state_args (dict) – Initial state for property initialization
  • outlvl (int) – Amount of output (0 to 3) 0 is lowest
  • solver (str) – Solver to use for initialization
  • optarg (dict) – Solver arguments dictionary
Turbine (Multistage)

This is a composite model for a power plant turbine with high, intermediate and low pressure sections. This model contains an inlet stage with throttle valves for partial arc admission and optional splitters for steam extraction.

The figure below shows the layout of the mutistage turbine model. Optional splitters provide for steam extraction. The splitters can have two or more outlets (one being the main steam outlet). The streams that connect one stage to the next can also be omitted. This allows for connecting additional unit models (usually reheaters) between stages.

_images/turbine_multistage.svg

MultiStage Turbine Model

Example

This example sets up a turbine multistage turbine model similar to what could be found in a power plant steam cycle. There are 7 high-pressure stages, 14 intermediate-pressure stages, and 11 low-pressure stages. Steam extractions are provided after stages hp4, hp7, ip5, ip14, lp4, lp7, lp9, lp11. The extraction at ip14 uses a splitter with three outlets, one for the main steam, one for the boiler feed pump, and one for a feedwater heater. There is a disconnection between the HP and IP sections so that steam can be sent to a reheater. In this example, a heater block is a stand-in for a reheater model.

from pyomo.environ import (ConcreteModel, SolverFactory, TransformationFactory,
                           Constraint, value)
from pyomo.network import Arc

from idaes.core import FlowsheetBlock
from idaes.unit_models import Heater
from idaes.unit_models.power_generation import (
    TurbineMultistage, TurbineStage, TurbineInletStage, TurbineOutletStage)
from idaes.property_models import iapws95_ph

solver = SolverFactory('ipopt')
solver.options = {'tol': 1e-6}

m = ConcreteModel()
m.fs = FlowsheetBlock(default={"dynamic": False})
m.fs.properties = iapws95_ph.Iapws95ParameterBlock()
m.fs.turb = TurbineMultistage(default={
    "property_package": m.fs.properties,
    "num_hp": 7,
    "num_ip": 14,
    "num_lp": 11,
    "hp_split_locations": [4,7],
    "ip_split_locations": [5, 14],
    "lp_split_locations": [4,7,9,11],
    "hp_disconnect": [7], # 7 is last stage in hp so disconnect hp from ip
    "ip_split_num_outlets": {14:3}})
# Add reheater (for example using a simple heater block)
m.fs.reheat = Heater(default={"property_package": m.fs.properties})
# Add Arcs (streams) to connect the HP and IP sections through reheater
m.fs.hp_to_reheat = Arc(source=m.fs.turb.hp_split[7].outlet_1,
                        destination=m.fs.reheat.inlet)
m.fs.reheat_to_ip = Arc(source=m.fs.reheat.outlet,
                        destination=m.fs.turb.ip_stages[1].inlet)
# Set the turbine inlet conditions and an initial flow guess
p = 2.4233e7
hin = iapws95_ph.htpx(T=880, P=p)
m.fs.turb.inlet_split.inlet.enth_mol[0].fix(hin)
m.fs.turb.inlet_split.inlet.flow_mol[0].fix(26000)
m.fs.turb.inlet_split.inlet.pressure[0].fix(p)

# Set the inlet of the ip section for initialization, since it is disconnected
p = 7.802e+06
hin = iapws95_ph.htpx(T=880, P=p)
m.fs.turb.ip_stages[1].inlet.enth_mol[0].value = hin
m.fs.turb.ip_stages[1].inlet.flow_mol[0].value = 25220.0
m.fs.turb.ip_stages[1].inlet.pressure[0].value = p
# Set the efficency and pressure ratios of stages other than inlet and outlet
for i, s in turb.hp_stages.items():
    s.ratioP[:] = 0.88
    s.efficiency_isentropic[:] = 0.9
for i, s in turb.ip_stages.items():
    s.ratioP[:] = 0.85
    s.efficiency_isentropic[:] = 0.9
for i, s in turb.lp_stages.items():
    s.ratioP[:] = 0.82
    s.efficiency_isentropic[:] = 0.9
# Usually these fractions would be determined by the boiler feed water heater
# network. Since this example doesn't include them, just fix split fractions
turb.hp_split[4].split_fraction[0,"outlet_2"].fix(0.03)
turb.hp_split[7].split_fraction[0,"outlet_2"].fix(0.03)
turb.ip_split[5].split_fraction[0,"outlet_2"].fix(0.04)
turb.ip_split[14].split_fraction[0,"outlet_2"].fix(0.04)
turb.ip_split[14].split_fraction[0,"outlet_3"].fix(0.15)
turb.lp_split[4].split_fraction[0,"outlet_2"].fix(0.04)
turb.lp_split[7].split_fraction[0,"outlet_2"].fix(0.04)
turb.lp_split[9].split_fraction[0,"outlet_2"].fix(0.04)
turb.lp_split[11].split_fraction[0,"outlet_2"].fix(0.04)
# unfix inlet flow for pressure driven simulation
turb.inlet_split.inlet.flow_mol.unfix()
# Set the inlet steam mixer to use the constraints that the pressures of all
# inlet streams are equal
turb.inlet_mix.use_equal_pressure_constraint()
# Initialize turbine
turb.initialize(outlvl=1)
# Copy conditions out of turbine to initialize the reheater
for t in m.fs.time:
    m.fs.reheat.inlet.flow_mol[t].value = \
        value(turb.hp_split[7].outlet_1_state[t].flow_mol)
    m.fs.reheat.inlet.enth_mol[t].value = \
        value(turb.hp_split[7].outlet_1_state[t].enth_mol)
    m.fs.reheat.inlet.pressure[t].value = \
        value(turb.hp_split[7].outlet_1_state[t].pressure)
# initialize the reheater
m.fs.reheat.initialize(outlvl=4)
# Add constraint to the reheater to result in 880K outlet temperature
def reheat_T_rule(b, t):
    return m.fs.reheat.control_volume.properties_out[t].temperature == 880
m.fs.reheat.temperature_out_equation = Constraint(m.fs.reheat.time_ref,
    rule=reheat_T_rule)
# Expand the Arcs connecting the turbine to the reheater
TransformationFactory("network.expand_arcs").apply_to(m)
# Fix the outlet pressure (usually determined by condenser)
m.fs.turb.outlet_stage.control_volume.properties_out[0].pressure.fix()

# Solve the pressure driven flow model with reheat
solver.solve(m, tee=True)
Unit Models

The multistage turbine model contains the models in the table below. The splitters for steam extraction are not present if a turbine section contains no steam extractions.

Unit Index Sets Doc
inlet_split None Splitter to split the main steam feed into steams for each arc (Separator)
throttle_valve Admission Arcs Throttle valves for each admission arc (SteamValve)
inlet_stage Admission Arcs Parallel inlet turbine stages that represent admission arcs (TurbineInlet)
inlet_mix None Mixer to combine the streams from each arc back to one stream (Mixer)
hp_stages HP stages Turbine stages in the high-pressure section (TurbineStage)
ip_stages IP stages Turbine stages in the intermediate-pressure section (TurbineStage)
lp_stages LP stages Turbine stages in the low-pressure section (TurbineStage)
hp_splits subset of HP stages Extraction splitters in the high-pressure section (Separator)
ip_splits subset of IP stages Extraction splitters in the high-pressure section (Separator)
lp_splits subset of LP stages Extraction splitters in the high-pressure section (Separator)
outlet_stage None The final stage in the turbine, which calculates exhaust losses (TurbineOutlet)
Initialization

The initialization approach is to sequentially initialize each sub-unit using the outlet of the previous model. Before initializing the model, the inlet of the turbine, and any stage that is disconnected should be given a reasonable guess. The efficiency and pressure ration of the stages in the HP, IP and LP sections should be specified. For the inlet and outlet stages the flow coefficient should be specified. Valve coefficients should also be specified. A reasonable guess for split fractions should also be given for any extraction splitters present. The most likely cause of initialization failure is flow coefficients in inlet stage, outlet stage, or valves that do not pair well with the specified flow rates.

TurbineMultistage Class
class idaes.unit_models.power_generation.turbine_multistage.TurbineMultistage(*args, **kwargs)

Multistage steam turbine with optional reheat and extraction

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether the model is dynamic.
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    has_phase_equilibrium
    Argument indicating whether phase equilibrium should be calculated for the resulting mixed stream, default - False. Valid values: { True - calculate phase equilibrium in mixed stream, False - do not calculate equilibrium in mixed stream.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    num_parallel_inlet_stages
    Number of parallel inlet stages to simulate partial arc admission. Default=4
    num_hp
    Number of high pressure stages not including inlet stage
    num_ip
    Number of intermediate pressure stages
    num_lp
    Number of low pressure stages not including outlet stage
    hp_split_locations
    A list of index locations of splitters in the HP section. The indexes indicate after which stage to include splitters. 0 is between the inlet stage and the first regular HP stage.
    ip_split_locations
    A list of index locations of splitters in the IP section. The indexes indicate after which stage to include splitters.
    lp_split_locations
    A list of index locations of splitters in the LP section. The indexes indicate after which stage to include splitters.
    hp_disconnect
    HP Turbine stages to not connect to next with an arc. This is usually used to insert addtional units between stages on a flowsheet, such as a reheater
    ip_disconnect
    IP Turbine stages to not connect to next with an arc. This is usually used to insert addtional units between stages on a flowsheet, such as a reheater
    lp_disconnect
    LP Turbine stages to not connect to next with an arc. This is usually used to insert addtional units between stages on a flowsheet, such as a reheater
    hp_split_num_outlets
    Dict, hp split index: number of splitter outlets, if not 2
    ip_split_num_outlets
    Dict, ip split index: number of splitter outlets, if not 2
    lp_split_num_outlets
    Dict, lp split index: number of splitter outlets, if not 2
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(TurbineMultistage) New instance

TurbineMultistageData Class
class idaes.unit_models.power_generation.turbine_multistage.TurbineMultistageData(component)[source]
build()[source]

General build method for UnitModelBlockData. This method calls a number of sub-methods which automate the construction of expected attributes of unit models.

Inheriting models should call super().build.

Parameters:None
Returns:None
initialize(outlvl=0, solver='ipopt', optarg={'max_iter': 35, 'tol': 1e-06})[source]

Initialize

throttle_cv_fix(value)[source]

Fix the thottle valve coefficients. These are generally the same for each of the parallel stages so this provides a convenient way to set them.

Parameters:value – The value to fix the turbine inlet flow coefficients at
turbine_inlet_cf_fix(value)[source]

Fix the inlet turbine stage flow coefficient. These are generally the same for each of the parallel stages so this provides a convenient way to set them.

Parameters:value – The value to fix the turbine inlet flow coefficients at
turbine_outlet_cf_fix(value)[source]

Fix the inlet turbine stage flow coefficient. These are generally the same for each of the parallel stages so this provides a convenient way to set them.

Parameters:value – The value to fix the turbine inlet flow coefficients at
Steam/Water Valve

This is a steam power generation turbine model for the stages between the inlet and outlet. This model inherits the PressureChanger model with the adiabatic options. Beyond the base pressure changer model this provides a pressure flow relation as a function of the valve opening fraction.

Example
from pyomo.environ import ConcreteModel, SolverFactory, TransformationFactory

from idaes.core import FlowsheetBlock
from idaes.unit_models.power_generation import SteamValve
from idaes.property_models import iapws95_ph
from idaes.ui.report import degrees_of_freedom, active_equalities

solver = SolverFactory('ipopt')
solver.options = {'tol': 1e-6}

m = ConcreteModel()
m.fs = FlowsheetBlock(default={"dynamic": False})
m.fs.properties = iapws95_ph.Iapws95ParameterBlock()
m.fs.valve = SteamValve(default={"property_package": m.fs.properties})

hin = iapws95_ph.htpx(T=880, P=2.4233e7)
# set inlet
m.fs.valve.inlet.enth_mol[0].fix(hin)
m.fs.valve.inlet.flow_mol[0].fix(26000/4.0)
m.fs.valve.inlet.pressure[0].fix(2.5e7)
m.fs.valve.Cv.fix(0.01)
m.fs.valve.valve_opening.fix(0.5)
m.fs.valve.initialize(outlvl=1)
Parameters
Expression Symbol Index Sets Doc
flow_scale \(s_f\) None Factor for scaling the pressure-flow equation, should be same magnitude as expected flow rate
Variables

This model adds a variable to account for mechanical efficiency to the base PressureChanger model.

Variable Symbol Index Sets Doc
Cv \(C_v\) None Valve coefficient for liquid [mol/s/Pa^0.5] for vapor [mol/s/Pa]
valve_opening \(x\) time The fraction that the valve is open from 0 to 1
Expressions

Currently this model provides two additional expressions, with are not available in the pressure changer model.

Expression Symbol Index Sets Doc
valve_function \(f(x)\) time This is a valve function that describes how the fraction open affects flow.
Constraints

The pressure flow relation is added to the inherited constraints from the PressureChanger model.

If the phase option is set to "Liq" the following equation describes the pressure-flow relation.

\[\frac{1}{s_f^2}F^2 = \frac{1}{s_f^2}C_v^2\left(P_{in} - P_{out}\right)f(x)^2\]

If the phase option is set to "Vap" the following equation describes the pressure-flow relation.

\[\frac{1}{s_f^2}F^2 = \frac{1}{s_f^2}C_v^2\left(P_{in}^2 - P_{out}^2\right)f(x)^2\]
Initialization

This just calls the initialization routine from PressureChanger, but it is wrapped in a function to ensure the state after initialization is the same as before initialization. The arguments to the initialization method are the same as PressureChanger.

SteamValve Class
class idaes.unit_models.power_generation.valve_steam.SteamValve(*args, **kwargs)

Basic steam valve models

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    compressor
    Indicates whether this unit should be considered a compressor (True (default), pressure increase) or an expander (False, pressure decrease).
    thermodynamic_assumption
    Flag to set the thermodynamic assumption to use for the unit. - ThermodynamicAssumption.isothermal (default) - ThermodynamicAssumption.isentropic - ThermodynamicAssumption.pump - ThermodynamicAssumption.adiabatic
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    valve_function
    The type of valve function, if custom provide an expression rule with the valve_function_rule argument. default - ValveFunctionType.linear Valid values - { ValveFunctionType.linear, ValveFunctionType.quick_opening, ValveFunctionType.equal_percentage, ValveFunctionType.custom}
    valve_function_rule
    This is a rule that returns a time indexed valve function expression. This is required only if valve_function==ValveFunctionType.custom
    phase
    Expected phase of fluid in valve in {“Liq”, “Vap”}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(SteamValve) New instance

SteamValveData Class
class idaes.unit_models.power_generation.valve_steam.SteamValveData(component)[source]
build()[source]
Parameters:None
Returns:None
initialize(state_args={}, outlvl=0, solver='ipopt', optarg={'max_iter': 30, 'tol': 1e-06})[source]

Initialize the turbine stage model. This deactivates the specialized constraints, then does the isentropic turbine initialization, then reactivates the constraints and solves.

Parameters:
  • state_args (dict) – Initial state for property initialization
  • outlvl (int) – Amount of output (0 to 3) 0 is lowest
  • solver (str) – Solver to use for initialization
  • optarg (dict) – Solver arguments dictionary

Property Model Library

Cubic Equations of State

Coming Soon.

Ideal Gas

Water/Steam

Two property modules are available for pure water and steam properties. The property modules use the same calculations and yield consistent results, but one uses pressure and molar enthalpy as state variables and the other uses temperature, pressure, and vapor fraction as the state variables.

Theses modules can be imported as:

from idaes.property_models import iapws95_ph
Example

The Heater unit model example, provides a simple example for using water properties.

Since all properties except the state variables are Pyomo Expressions in the water properties module, after solving the problem any property can be calculated in any state block after the problem is solved. To get the viscosity of the water at the heater outlet, for example the line below could be added.

import pyomo.environ as pe
mu_l = pe.value(model.fs.heater.control_volume.properties_out[0].visc_d_phase["Liq"])
mu_v = pe.value(model.fs.heater.control_volume.properties_out[0].visc_d_phase["Vap"])

For more information about how StateBlocks and PropertyParameterBlocks work see the StateBlock documentation.

Units

The water property modules are in SI units (m, kg, s, mol). Temperature is in K.

Methods

These methods use the IAPWS-95 formulation for scientific use for thermodynamic properties (Wagner and Pruss, 2002; IAPWS, 2016). To solve the phase equilibrium, the method of Akasaka (2008) was used. For solving these equations, some relations from the IAPWS-97 formulation for industrial use are used as initial values (Wagner et al., 2002). The industrial formulation is slightly discontinuous between different regions, so it may not be suitable for optimization. In addition to thermodynamic quantities, viscosity and thermal conductivity are calculated (IAPWS, 2008; IAPWS, 2011).

External Functions

The IAPWS-95 formulation uses density and temperature as state variables. For most applications those sate variables are not the most convenient choices. Using other state variables requires solving an equation or two to get density and temperature from the chosen state variables. This can have numerous solutions only one of which is physically meaningful. Rather than solve these equations as part of the full process simulation, external functions were developed that can solve the equations required to change state variables and guarantee the correct roots.

The external property functions are written in C++ and complied such that they can be called by AMPL solvers. See the Installation page for information about compiling these functions. The external functions provide both first and second derivatives for all property function calls, however at phase transitions some of these functions may be non-smooth.

IDAES Framework Wrappers

Wrappers for these function are provided for compatibility with the IDAES framework. Some methods for dealing with non-smoothness may also be included in the IDAES wrappers. The wrappers provide most properties in the form of Pyomo Expressions, with only the chosen set of state variables being Pyomo Vars. The expressions pass the state variables to the external functions and do unit conversion to put the results in SI units. This means that only the state variables can be fixed and other quantities cannot be fixed, but constraints can be added to set them to a specific value.

Since state variables are calculated when solving a model, and the rest of the properties are Expressions, any property available can be easily calculated after the model is solved, whether is was needed in the model or not.

Although not generally used the wrappers provide direct access to the ExternalFunctions also. For more information see section ExternalFunctions

Pressure-Enthalpy

Although Expressions for properties of different phases are available, the pressure-enthalpy formulation treats the fluid as a single mixed phase with a vapor fraction. This bypasses some of the IDAES framework phase equilibrium mechanisms and phase equilibrium is always calculated.

The advantage of this choice of state variables is that it is very robust when phase changes occur, and is especially useful when it is not known if a phase change will occur. The disadvantage of this choice of state variables is that for equations like heat transfer equations that are highly dependent on temperature, a model could be harder to solve near regions with phase change. Temperature is a non-smooth function with a zero derivative with respect to enthalpy in the two-phase region.

The variables for this form are flow_mol (mol/s), pressure (Pa), and enth_mol (J/mol).

Since temperature and vapor fraction are not state variables in this formulation, they are provided by expressions, and cannot be fixed. For example, to set a temperature to a specific value, a constraint could be added which says the temperature expression equals a fixed value.

These expressions are specific to the P-H formulation:

temperature
Expression that calculates temperature by calling an ExternalFunction of enthalpy and pressure. This expression is non-smooth in the transition from single-phase to two-phase and has a zero derivative with respect to enthalpy in the two-phase region.
vapor_frac
Expression that calculates vapor fraction by calling an ExternalFunction of enthalpy and pressure. This expression is non-smooth in the transition from single-phase to two-phase and has a zero derivative with respect to enthalpy in the single-phase region, where the value is 0 (liquid) or 1 (vapor).
Temperature-Pressure-Vapor Fraction

Coming soon.

Expressions

Unless otherwise noted above, the property expressions are common to both the T-P-x and P-H formulations. For phase specific properties, valid phase indexes are "Liq" and "Vap"

Expression Description
mw Molecular weight (kg/mol)
tau Critical temperature divided by temperature (unitless)
temperature_red Reduced temperature, temperature divided by critical temperature (unitless)
temperature_sat Saturation temperature (K)
tau_sat Critical temperature divided by saturation temperature (unitless)
pressure_sat Saturation pressure (Pa)
dens_mass_phase[phase] Density phase (kg/m3)
dens_phase_red[phase] Phase reduced density (\(\delta\)), mass density divided by critical density (unitless)
dens_mass Total mixed phase mass density (kg/m3)
dens_mol Total mixed phase mole density (kg/m3)
flow_vol Total volumetric flow rate (m3/s)
enth_mass Mass enthalpy (kJ/kg)
enth_mol_sat_phase[phase] Saturation enthalpy of phase, enthalpy at P and Tsat (kJ/mol)
enth_mol_phase[phase] Molar enthalpy of phase (kJ/mol)
entr_mol_phase Molar entropy of phase (kJ/mol/K)
entr_mol Total mixed phase entropy (kJ/mol/K)
cp_mol_phase[phase] Constant pressure molar heat capacity of phase (kJ/mol/K)
cv_mol_phase[phase] Constant pressure volume heat capacity of phase (kJ/mol/K)
cp_mol Total mixed phase constant pressure heat capacity (kJ/mol/K)
cv_mol Total mixed phase constant volume heat capacity (kJ/mol/K)
heat_capacity_ratio cp_mol/cv_mol
speed_sound_phase[phase] Speed of sound in phase (m/s)
dens_mol_phase[phase] Mole density of phase (mol/m3)
therm_cond_phase[phase] Thermal conductivity of phase (W/K/m)
visc_d_phase[phase] Viscosity of phase (Pa/s)
visc_k_phase[phase] Kinimatic viscosity of phase (m2/s)
phase_frac[phase] Phase fraction
flow_mol_comp["H2O"] Same as total flow since only water (mol/s)
ExternalFunctions

This provides a list of ExternalFuctions available in the wrappers. These functions do not use SI units and are not usually called directly. If these functions are needed, they should be used with caution. Some of these are used in the property expressions, some are just provided to allow easier testing with a Python framework.

All of these functions provide first and second derivative and are generally suited to optimization. Some functions may have non-smoothness at phase transitions. The delta_vap and delta_liq functions return the same values in the critical region. They will also return real values when a phase doesn’t exist, but those values do not necessarily have physical meaning.

There are a few variables that are common to a lot of these functions, so they are summarized here \(tau\) is the critical temperature divided by the temperature \(\frac{T_c}{T}\), \(\delta\) is density divided by the critical density \(\frac{\rho}{\rho_c}\), and \(\phi\) is Helmholtz free energy divided by the ideal gas constant and temperature \(\frac{f}{RT}\).

Pyomo Function C Function Returns Arguments
func_p p pressure (kPa) \(\delta, \tau\)
func_u u internal energy (kJ/kg) \(\delta, \tau\)
func_s s entropy (kJ/K/kg) \(\delta, \tau\)
func_h h enthalpy (kJ/kg) \(\delta, \tau\)
func_hvpt hvpt vapor enthalpy (kJ/kg) P (kPa), \(\tau\)
func_hlpt hlpt liquid enthalpy (kJ/kg) P (kPa), \(\tau\)
func_tau tau \(\tau\) (unitless) h (kJ/kg), P (kPa)
func_vf vf vapor fraction (unitless) h (kJ/kg), P (kPa)
func_g g Gibbs free energy (kJ/kg) \(\delta, \tau\)
func_f f Helmholtz free energy (kJ/kg) \(\delta, \tau\)
func_cv cv const. volume heat capacity (kJ/K/kg) \(\delta, \tau\)
func_cp cp const. pressure heat capacity (kJ/K/kg) \(\delta, \tau\)
func_w w speed of sound (m/s) \(\delta, \tau\)
func_delta_liq delta_liq liquid \(\delta\) (unitless) P (kPa), \(\tau\)
func_delta_vap delta_vap vapor \(\delta\) (unitless) P (kPa), \(\tau\)
func_delta_sat_l delta_sat_l sat. liquid \(\delta\) (unitless) \(\tau\)
func_delta_sat_v delta_sat_v sat. vapor \(\delta\) (unitless) \(\tau\)
func_p_sat p_sat sat. pressure (kPa) \(\tau\)
func_tau_sat tau_sat sat. \(\tau\) (unitless) P (kPa)
func_phi0 phi0 \(\phi\) idaes gas part (unitless) \(\delta, \tau\)
func_phi0_delta phi0_delta \(\frac{\partial \phi_0}{\partial \delta}\) \(\delta\)
func_phi0_delta2 phi0_delta2 \(\frac{\partial^2 \phi_0}{\partial \delta^2}\) \(\delta\)
func_phi0_tau phi0_tau \(\frac{\partial \phi_0}{\partial \tau}\) \(\tau\)
func_phi0_tau2 phi0_tau2 \(\frac{\partial^2 \phi_0}{\partial \tau^2}\) \(\tau\)
func_phir phir \(\phi\) real gas part (unitless) \(\delta, \tau\)
func_phir_delta phir_delta \(\frac{\partial \phi_r}{\partial \delta}\) \(\delta, \tau\)
func_phir_delta2 phir_delta2 \(\frac{\partial^2 \phi_r}{\partial \delta^2}\) \(\delta, \tau\)
func_phir_tau phir_tau \(\frac{\partial \phi_r}{\partial \tau}\) \(\delta, \tau\)
func_phir_tau2 phir_tau2 \(\frac{\partial^2 \phi_r}{\partial \tau^2}\) \(\delta, \tau\)
func_phir_delta_tau phir_delta_tau \(\frac{\partial^2 \phi_r}{\partial \delta \partial \tau}\) \(\delta, \tau\)
Initialization

The IAPWS-95 property functions do provide initilaization functions for general compatibility with the IDAES framework, but as long as the state variables are specified to some resonalbe value, initialization is not required. All required solves are handled by external functions.

References

International Association for the Properties of Water and Steam (2016). IAPWS R6-95 (2016), “Revised Release on the IAPWS Formulation 1995 for the Properties of Ordinary Water Substance for General Scientific Use,” URL: http://iapws.org/relguide/IAPWS95-2016.pdf

Wagner, W., A. Pruss (2002). “The IAPWS Formulation 1995 for the Thermodynamic Properties of Ordinary Water Substance for General and Scientific Use.” J. Phys. Chem. Ref. Data, 31, 387-535.

Wagner, W. et al. (2000). “The IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of Water and Steam,” ASME J. Eng. Gas Turbines and Power, 122, 150-182.

Akasaka, R. (2008). “A Reliable and Useful Method to Determine the Saturation State from Helmholtz Energy Equations of State.” Journal of Thermal Science and Technology, 3(3), 442-451.

International Association for the Properties of Water and Steam (2011). IAPWS R15-11, “Release on the IAPWS Formulation 2011 for the Thermal Conductivity of Ordinary Water Substance,” URL: http://iapws.org/relguide/ThCond.pdf.

International Association for the Properties of Water and Steam (2008). IAPWS R12-08, “Release on the IAPWS Formulation 2008 for the Viscosity of Ordinary Water Substance,” URL: http://iapws.org/relguide/visc.pdf.

Convenience Functions
idaes.property_models.iapws95.iapws95_wrap_ph.htpx(T, P=None, x=None)[source]

Conveneince function to calculate steam enthalpy from temperature and either pressure or vapor fraction. This function can be used for inlet streams and initialization where temperature is known instread of enthalpy. :param T: Temperature [K] :param P: Pressure [Pa], None if saturated steam :param x: Vapor fraction [mol vapor/mol total], None if superheated or subcooled

Returns:Molar enthalpy [J/mol].
Iapws95StateBlock Class
class idaes.property_models.iapws95.iapws95_wrap_ph.Iapws95StateBlock(*args, **kwargs)

This is some placeholder doc.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    parameters
    A reference to an instance of the Property Parameter Block associated with this property package.
    defined_state
    Flag indicating whether the state should be considered fully defined, and thus whether constraints such as sum of mass/mole fractions should be included, default - False. Valid values: { True - state variables will be fully defined, False - state variables will not be fully defined.}
    has_phase_equilibrium
    Flag indicating whether phase equilibrium constraints should be constructed in this state block, default - True. Valid values: { True - StateBlock should calculate phase equilibrium, False - StateBlock should not calculate phase equilibrium.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Iapws95StateBlock) New instance

Iapws95StateBlockData Class
class idaes.property_models.iapws95.iapws95_wrap_ph.Iapws95StateBlockData(component)[source]

This is a property package for calcuating thermophysical properties of water

build(*args)[source]

Callable method for Block construction

define_state_vars()[source]

Method that returns a dictionary of state variables used in property package. Implement a placeholder method which returns an Exception to force users to overload this.

get_enthalpy_density_terms(p)[source]

Method which returns a valid expression for enthalpy density to use in the energy balances.

get_enthalpy_flow_terms(p)[source]

Method which returns a valid expression for enthalpy flow to use in the energy balances.

get_material_density_terms(p, j)[source]

Method which returns a valid expression for material density to use in the material balances .

get_material_flow_terms(p, j)[source]

Method which returns a valid expression for material flow to use in the material balances.

Iapws95ParameterBlock Class
class idaes.property_models.iapws95.iapws95_wrap_ph.Iapws95ParameterBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    default_arguments
    Default arguments to use with Property Package
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Iapws95ParameterBlock) New instance

Iapws95ParameterBlockData Class
class idaes.property_models.iapws95.iapws95_wrap_ph.Iapws95ParameterBlockData(component)[source]
build()[source]

General build method for PropertyParameterBlocks. Inheriting models should call super().build.

Parameters:None
Returns:None
classmethod define_metadata(obj)[source]

Set all the metadata for properties and units.

This method should be implemented by subclasses. In the implementation, they should set information into the object provided as an argument.

Parameters:pcm (PropertyClassMetadata) – Add metadata to this object.
Returns:None

Visualization

Contents

Drawing heat exchanger network diagrams

The following example demonstrates how to generate a heat exchanger network diagram.

In the code below, different streams are defined in the streams list. For each stream, we expect a name (name), a list of temperatures (temps) and a type field specifying if this is a hot stream (HENStreamType.hot) or a cold one (HENStreamType.cold).

The exchangers list defines the heat exchangers. Each exchanger is defined by its hot/cold stream (hot, cold) which must match one of the streams in the streams list above. We also require for each exchanger the area (A),the amount of heat transferred from one stream to another (Q), annual cost (annual_cost) and stage (stg). If the utility_type key is passed and it’s set to HENStreamType.cold_utility then we draw the cold stream of the exchanger as water. If the utility_type key is passed and it’s set to HENStreamType.hot_utility then we draw the hot stream of the exchanger as steam.

The color-codes of each stage are picked randomly in the final diagram.

from bokeh.io import output_notebook
from bokeh.plotting import show
from idaes.vis.plot import Plot
from idaes.vis.plot_utils import HENStreamType

exchangers = [
    {'hot': 'H2', 'cold': 'C1', 'Q': 1400, 'A': 159, 'annual_cost': 28358, 'stg': 2},
    {'hot': 'H1', 'cold': 'C1', 'Q': 667, 'A': 50, 'annual_cost': 10979, 'stg': 3},
    {'hot': 'H1', 'cold': 'C1', 'Q': 233, 'A': 10, 'annual_cost': 4180, 'stg': 1},
    {'hot': 'H1', 'cold': 'C2', 'Q': 2400, 'A': 355, 'annual_cost': 35727, 'stg': 2},
    {'hot': 'H2', 'cold': 'W', 'Q': 400, 'A': 50, 'annual_cost': 10979, 'stg': 3, 'utility_type': HENStreamType.cold_utility},
    {'hot': 'S', 'cold': 'C2', 'Q': 450, 'A': 50, 'annual_cost': 0, 'stg': 1, 'utility_type': HENStreamType.hot_utility}
]

streams = [
    {'name':'H2', 'temps': [423, 423, 330, 303], 'type': HENStreamType.hot},
    {'name':'H1', 'temps': [443, 435, 355, 333], 'type': HENStreamType.hot},
    {'name':'C1', 'temps': [408, 396, 326, 293], 'type': HENStreamType.cold},
    {'name':'C2', 'temps': [413, 413, 353, 353], 'type': HENStreamType.cold}
]
plot_obj = Plot.heat_exchanger_network(exchangers, streams,
    mark_temperatures_with_tooltips=True)
plot_obj.show()
Bokeh Application

By default tooltips are used to mark stream temperatures. We can disable those and add labels instead as seen below. They can be a bit crowded and for now you can just zoom in to decipher crowded labels (but we’re working on that!)

plot_obj = Plot.heat_exchanger_network(exchangers, streams,
    mark_temperatures_with_tooltips=False)
plot_obj.show()
Bokeh Application

In case a stream exchanges with multiple streams in the same stage, this is handled through a stage split. We also currently support describing modules for each exchanger that are added as tooltips to the area label on each exchanger. The example below demonstrates this functionality:

exchangers = [
    {'hot': 'H1', 'cold': 'C2', 'Q': 2400, 'A': 355, 'annual_cost': 35727, 'stg': 2},
    {'hot': 'H2', 'cold': 'C2', 'Q': 1700, 'A': 159, 'annual_cost': 28358, 'stg': 2},


    {'hot': 'H1', 'cold': 'C2', 'Q': 1700, 'A': 159, 'annual_cost': 28358, 'stg': 3},
    {'hot': 'H1', 'cold': 'C1', 'Q': 667, 'A': 50, 'annual_cost': 10979, 'stg': 3, 'modules': {10: 1, 20: 2}},
    {'hot': 'H2', 'cold': 'C3', 'Q': 1700, 'A': 159, 'annual_cost': 28358, 'stg': 3},
    {'hot': 'H2', 'cold': 'C2', 'Q': 1700, 'A': 159, 'annual_cost': 28358, 'stg': 3, 'modules': {10: 1, 20: 2}},
    {'hot': 'H3', 'cold': 'C2', 'Q': 1700, 'A': 159, 'annual_cost': 28358, 'stg': 3},

    {'hot': 'H2', 'cold': 'W', 'Q': 400, 'A': 50, 'annual_cost': 10979, 'stg': 3, 'utility_type': HENStreamType.cold_utility},
    {'hot': 'S', 'cold': 'C2', 'Q': 450, 'A': 50, 'annual_cost': 0, 'stg': 1, 'utility_type': HENStreamType.hot_utility}
]

streams = [
    {'name':'H3', 'temps': [423, 423, 330, 303], 'type': HENStreamType.hot},
    {'name':'H2', 'temps': [423, 423, 330, 303], 'type': HENStreamType.hot},
    {'name':'H1', 'temps': [443, 435, 355, 333], 'type': HENStreamType.hot},
    {'name':'C1', 'temps': [408, 396, 326, 293], 'type': HENStreamType.cold},
    {'name':'C2', 'temps': [413, 413, 353, 353], 'type': HENStreamType.cold},
    {'name':'C3', 'temps': [413, 413, 353, 353], 'type': HENStreamType.cold}
]
plot_obj = Plot.heat_exchanger_network(exchangers, streams,
    mark_temperatures_with_tooltips=True,
    mark_modules_with_tooltips=True,
    stage_width=2,
    y_stream_step=1)
plot_obj.show()
Bokeh Application
Plotting profile plots from the MEA example

Warning

The following has not been tested recently and should be considered a work in progress.

The following examples demonstrate the resize, annotation and saving functionalities.

In the following example, we being by preparing a data frame from our flowsheet variables.

# Absorber CO2 Levels
from pandas import DataFrame
import os
tmp = fs.absorb.make_profile(t=0)
tmp = fs.regen.make_profile(t=0)

plot_dict = {'z':fs.absorb.profile_1['z'],
             'y1':fs.absorb.profile_1.y_vap_CO2*101325.0,
             'y2':fs.absorb.profile_1.P_star_CO2}
plot_data_frame = DataFrame(data=plot_dict)

We can then plot the data frame we just made, show it, resize it and save it.

absorber_co2_plot = Plot.profile(plot_data_frame,
                                 x = 'z',
                                 y = ['y1','y2'],
                                 title = 'Absorber CO2 Levels',
                                 xlab = 'Axial distance from top (m)',
                                 ylab = 'Partial Pressure CO2 (Pa)',
                                 legend = ['Bulk vapor','Equilibrium'])

absorber_co2_plot.show()
absorber_co2_plot.save('/home/jovyan/model_contrib/absorber_co2_plot.html')
assert(os.path.isfile('/home/jovyan/model_contrib/absorber_co2_plot.html'))
Bokeh Application
absorber_co2_plot.resize(height=400,width=600)
absorber_co2_plot.show()
absorber_co2_plot.save('/home/jovyan/model_contrib/absorber_co2_plot_resized.html')
assert(os.path.isfile('/home/jovyan/model_contrib/absorber_co2_plot_resized.html'))
Bokeh Application

The following demonstrates the annotate functionality by plotting a second plot from the same flowsheet.

from IPython.core.display import display,HTML
stripper_co2_plot = Plot.profile(plot_data_frame,
                                 x = 'z',
                                 y = ['y1','y2'],
                                 title = 'Stripper CO2 Levels',
                                 xlab = 'Axial distance from top (m)',
                                 ylab = 'Partial Pressure CO2 (Pa)',
                                 legend = ['Bulk vapor','Equilibrium'])
stripper_co2_plot.show()
stripper_co2_plot.save('/home/jovyan/model_contrib/stripper_co2_plot.html')
assert(os.path.isfile('/home/jovyan/model_contrib/stripper_co2_plot.html'))
Bokeh Application

We can then annotate the “Reboiler vapor” point as shown below:

stripper_co2_plot.annotate(rloc,rco2p,'Reboiler vapor')
stripper_co2_plot.show()
stripper_co2_plot.save('/home/jovyan/model_contrib/stripper_co2_plot_annotated.html')
Bokeh Application

Warning

The visualization library is still in active development and we hope to improve on it in future releases. Please use its functionality at your own discretion.

Overview

The idaes.vis subpackage contains the framework and implementation of plots that are expected to be of general utility within the IDAES framework.

For users, an entry point is provided for IDAES classes to produce plots with the idaes.vis.plotbase.PlotRegistry singleton.

Plots will inherit from the interface in idaes.vis.plotbase.PlotBase, which provides some basic methods.

The current implementations all use the Python “bokeh” package, and can be found in idaes.vis.bokeh_plots.

Data Management Framework

DMF Command-line Interface

This page lists the commands and options for the DMF command-line interface, which is a Python program called dmf. There are several usage examples for each sub-command. These examples assume the UNIX bash shell.

dmf

Data management framework command wrapper. This base command has some options for verbosity that can be applied to any sub-command.

dmf options
-v
--verbose

Increase verbosity. Show warnings if given once, then info, and then debugging messages.

-q
--quiet

Increase quietness. If given once, only show critical messages. If given twice, show no messages.

dmf usage

Run sub-command with logging at level “error”:

$ dmf <sub-command>

Run sub-command and log warnings:

$ dmf <sub-command>

Run sub-command and log informational / warning messages:

$ dmf -vv <sub-command>

Run sub-command only logging fatal errors:

$ dmf -q <sub-command>

Run sub-command with no logging at all:

$ dmf -qq <sub-command>
dmf subcommands

The subcommands are listed alphabetically below. For each, keep in mind that any unique prefix of that command will be accepted. For example, for dmf init, the user may also type dmf ini. However, dmf in will not work because that would also be a valid prefix for dmf info.

In addition, there are some aliases for some of the sub-commands:

  • dmf info => dmf resource or dmf show
  • dmf ls => dmf list
  • dmf register => dmf add
  • dmf related => dmf graph
  • dmf rm => dmf delete
  • dmf status => dmf describe
usage overview

To give a feel for the context in which you might actually run these commands, below is a simple example that uses each command:

# create a new workspace
$ dmf init ws --name workspace --desc "my workspace" --create
Configuration in '/home/dang/src/idaes/dangunter/idaes-dev/docs/ws/config.yaml

# view status of the workspace
$ dmf status
settings:
  workspace: /home/myuser/ws
workspace:
  location: /home/myuser/ws
  name: workspace
  description: my workspace
  created: 2019-04-20 08:32:59
  modified: 2019-04-20 08:32:59

# add some resources from files
$ echo "one" > oldfile ; echo "two" > newfile
$ dmf register oldfile --version 0.0.1
2792c0ceb0734ed4b302c44884f2d404
$ dmf register newfile --version 0.0.2 --prev 2792c0ceb0734ed4b302c44884f2d404
6ddee9bb2bb3420ab10aaf4c74d186f6

# list the current workspace contents
$ dmf ls
id   type desc    modified
2792 data oldfile 2019-04-20 15:33:11
6dde data newfile 2019-04-20 15:33:23

# look at one one resource (newfile)
$ dmf info 6dde
                            Resource 6ddee9bb2bb3420ab10aaf4c74d186f6
  created
     '2019-04-20 15:33:23'
  creator
     name: dang
  datafiles
     - desc: newfile
       is_copy: true
       path: newfile
       sha1: 7bbef45b3bc70855010e02460717643125c3beca
  datafiles_dir
     /home/myuser/ws/files/8027bf92628f41a0b146a5167d147e9d
  desc
     newfile
  doc_id
     2
  id_
     6ddee9bb2bb3420ab10aaf4c74d186f6
  modified
     '2019-04-20 15:33:23'
  relations
     - 2792c0ceb0734ed4b302c44884f2d404 --[version]--> ME
  type
     data
  version
     0.0.2 @ 2019-04-20 15:33:23

# see relations
$ dmf related 2792
2792 data

    └──┤version├─▶ 6dde data -

# remove the "old" file
$ dmf rm 2792
id                               type desc    modified
2792c0ceb0734ed4b302c44884f2d404 data oldfile 2019-04-20 15:33:11
Remove this resource [y/N]? y
resource removed

$ dmf ls
id   type desc    modified
6dde data newfile 2019-04-20 15:33:23
_images/blue-white-band.png
dmf find

Search for resources by a combination of their fields. Several convenient fields are provided. At this time, a comprehensive capability to search on any field is not available.

dmf find options

In addition to the options below, this command also accepts all the dmf ls options, although the --color/--no-color option is ignored for JSON output.

--output value

Output style/format. Possible values:

list
(Default) Show results as a listing, as from the ls subcommand.
info
Show results as individual records, as from the info subcommand.
json
Show results are JSON objects
--by value

Look for “value” in the value of the creator.name field.

--created value

Use “value” as a date or date range and filter on records that have a created date in that range. Dates should be in a form that is accepted by the Pendulum parse function. The special token .. is used to indicate date ranges, as in:

  • 2012-03-19: On March 19, 2012
  • 2012-03-19..2012-03-22: From March 19 to March 22, 2012
  • 2012-03-19..: After March 19, 2012
  • ..2012-03-19: Before March 19, 2012

Note that times may also be part of the date strings.

--file value

Look for “value” in the value of the desc field in one of the datafiles.

--modified value

Use “value” as a date or date range and filter on records that have a modified date in that range. See --created for details on the date format.

--name value

Look for “value” as one of the values of the alias field.

--type value

Look for “value” as the value of the type field.

dmf find usage

By default, find will essentially provide a filtered listing of resources. If used without options, it is basically an alias for ls.

$ dmf ls
id   type desc      modified
2517 data file1.txt 2019-04-29 17:29:00
344c data file2.txt 2019-04-29 17:29:01
5d98 data A         2019-04-29 17:28:41
602a data B         2019-04-29 17:28:56
8c55 data C         2019-04-29 17:28:58
9cbe data D         2019-04-29 17:28:59
$ dmf find
id   type desc      modified
2517 data file1.txt 2019-04-29 17:29:00
344c data file2.txt 2019-04-29 17:29:01
5d98 data A         2019-04-29 17:28:41
602a data B         2019-04-29 17:28:56
8c55 data C         2019-04-29 17:28:58
9cbe data D         2019-04-29 17:28:59

The find-specific options add filters. In the example below, the find filters for files that were modified after the given date and time.

$ dmf  find --modified 2019-04-29T17:29:00..
id   type desc      modified
2517 data file1.txt 2019-04-29 17:29:00
344c data file2.txt 2019-04-29 17:29:01
_images/blue-white-band.png
dmf info

Show detailed information about a resource. This command may also be referred to as dmf show.

dmf info options
identifier

Identifier, or unique prefix thereof, of the resource. Any unique prefix of the identifier will work, but if that prefix matches multiple identifiers, you need to add --multiple to allow multiple records in the output.

--multiple

Allow multiple records in the output (see identifier)

-f,--format value

Output format. Accepts the following values:

term
Terminal output (colored, if the terminal supports it), with values that are empty left out and some values simplified for easy reading.
json
Raw JSON value for the resource, with newlines and indents for readability.
jsonc
Raw JSON value for the resource, “compact” version with no extra whitespace added.
dmf info usage

The default is to show, with some terminal colors, a summary of the resource:

$ dmf info 0b62

                          Resource 0b62d999f0c44b678980d6a5e4f5d37d
  created
     '2019-03-23 17:49:35'
  creator
     name: dang
  datafiles
     - desc: foo13
       is_copy: true
       path: foo13
       sha1: feee44ad365b6b1ec75c5621a0ad067371102854
  datafiles_dir
     /home/dang/src/idaes/dangunter/idaes-dev/ws2/files/71d101327d224302aa8875802ed2af52
  desc
     foo13
  doc_id
     4
  id_
     0b62d999f0c44b678980d6a5e4f5d37d
  modified
     '2019-03-23 17:49:35'
  relations
     - 1e41e6ae882b4622ba9043f4135f2143 --[derived]--> ME
  type
     data
  version
     0.0.0 @ 2019-03-23 17:49:35

The same resource in JSON format:

$ dmf info --format json 0b62
{
  "id_": "0b62d999f0c44b678980d6a5e4f5d37d",
  "type": "data",
  "aliases": [],
  "codes": [],
  "collaborators": [],
  "created": 1553363375.817961,
  "modified": 1553363375.817961,
  "creator": {
    "name": "dang"
  },
  "data": {},
  "datafiles": [
    {
      "desc": "foo13",
      "path": "foo13",
      "sha1": "feee44ad365b6b1ec75c5621a0ad067371102854",
      "is_copy": true
    }
  ],
  "datafiles_dir": "/home/dang/src/idaes/dangunter/idaes-dev/ws2/files/71d101327d224302aa8875802ed2af52",
  "desc": "foo13",
  "relations": [
    {
      "predicate": "derived",
      "identifier": "1e41e6ae882b4622ba9043f4135f2143",
      "role": "object"
    }
  ],
  "sources": [],
  "tags": [],
  "version_info": {
    "created": 1553363375.817961,
    "version": [
      0,
      0,
      0,
      ""
    ],
    "name": ""
  },
  "doc_id": 4
}

And one more time, in “compact” JSON:

$ dmf info --format jsonc 0b62
{"id_": "0b62d999f0c44b678980d6a5e4f5d37d", "type": "data", "aliases": [], "codes": [], "collaborators": [], "created": 1553363375.817961, "modified": 1553363375.817961, "creator": {"name": "dang"}, "data": {}, "datafiles": [{"desc": "foo13", "path": "foo13", "sha1": "feee44ad365b6b1ec75c5621a0ad067371102854", "is_copy": true}], "datafiles_dir": "/home/dang/src/idaes/dangunter/idaes-dev/ws2/files/71d101327d224302aa8875802ed2af52", "desc": "foo13", "relations": [{"predicate": "derived", "identifier": "1e41e6ae882b4622ba9043f4135f2143", "role": "object"}], "sources": [], "tags": [], "version_info": {"created": 1553363375.817961, "version": [0, 0, 0, ""], "name": ""}, "doc_id": 4}
_images/blue-white-band.png
dmf init

Initialize the current workspace. Optionally, create a new workspace.

dmf init options
path

Use the provided path as the workspace path. This is required.

--create

Create a new workspace at location provided by path. Use the --name and --desc options to set the workspace name and description, respectively. If these are not given, they will be prompted for interactively.

--name

Workspace name, used by --create

--desc

Workspace description, used by --create

dmf init usage

Note

In the following examples, the current working directory is set to /home/myuser.

This command sets a value in the user-global configuration file in .dmf, in the user’s home directory, so that all other dmf commands know which workspace to use. With the --create option, a new empty workspace can be created.

Create new workspace in sub-directory ws, with given name and description:

$ dmf init ws --create --name "foo" --desc "foo workspace description"
Configuration in '/home/myuser/ws/config.yaml

Create new workspace in sub-directory ws, providing the name and description interactively:

$ dmf init  ws --create
New workspace name: foo
New workspace description: foo workspace description
Configuration in '/home/myuser/ws/config.yaml

Switch to workspace ws2:

$ dmf init  ws2

If you try to switch to a non-existent workspace, you will get an error message:

$ dmf init doesnotexist
Existing workspace not found at path='doesnotexist'
Add --create flag to create a workspace.
$ mkdir some_random_directory
$ dmf init some_random_directory
Workspace configuration not found at path='some_random_directory/'

If the workspace exists, you cannot create it:

$ dmf init ws --create --name "foo" --desc "foo workspace description"
Configuration in '/home/myuser/ws/config.yaml
$ dmf init ws --create
Cannot create workspace: path 'ws' already exists

And, of course, you can’t create workspaces anywhere you don’t have permissions to create directories:

$ mkdir forbidden
$ chmod 000 forbidden
$ dmf init forbidden/ws --create
Cannot create workspace: path 'forbidden/ws' not accessible
_images/blue-white-band.png
dmf ls

This command lists resources in the current workspace.

dmf ls options
--color

Allow (if terminal supports it) colored terminal output. This is the default.

--no-color

Disallow, even if terminal supports it, colored terminal output.

-s,--show

Pick field to show in output table. This option can be repeated to show any known subset of fields. Also the option value can have commas in it to hold multiple fields. Default fields, if this option is not specified at all, are “type”, “desc”, and “modified”. The resource identifier field is always shown first.

codes
List name of code(s) in resource. May be shortened with ellipses.
created
Date created.
desc
Description of resource.
files
List names of file(s) in resource. May be shortened with ellipses.
modified
Date modified.
type
Name of the type of resource.
version
Resource version.

You can specify other fields from the schema, as long as they are not arrays of objects, i.e. you can say --show tags or --show version_info.version, but --show sources is too complicated for a tabular listing. To see detailed values in a record use the dmf info command.

-S,--sort

Sort by given field; if repeated, combine to make a compound sort key. These fields are a subset of those in -s,--show, with the addition of id for sorting by the identifier: “id”, “type”, “desc”, “created”, “modified”, and/or “version”.

--no-prefix

By default, shown identifier is the shortest unique prefix, but if you don’t want the identifier shortened, this option will force showing it in full.

-r,--reverse

Reverse the order of the sorting given by (or implied by absence of) the -S,--sort option.

dmf ls usage

Note

In the following examples, the current working directory is set to /home/myuser and the workspace is named ws.

Without arguments, show the resources in an arbitrary (though consistent) order:

$ dmf ls
id   type desc  modified
0b62 data foo13 2019-03-23 17:49:35
1e41 data foo10 2019-03-23 17:47:53
6c9a data foo14 2019-03-23 17:51:59
d3d5 data bar1  2019-03-26 13:07:02
e780 data foo11 2019-03-23 17:48:11
eb60 data foo12 2019-03-23 17:49:08

Add a sort key to sort by, e.g. modified date

$ dmf ls -S modified
id   type desc  modified
1e41 data foo10 2019-03-23 17:47:53
e780 data foo11 2019-03-23 17:48:11
eb60 data foo12 2019-03-23 17:49:08
0b62 data foo13 2019-03-23 17:49:35
6c9a data foo14 2019-03-23 17:51:59
d3d5 data bar1  2019-03-26 13:07:02

Especially for resources of type “data”, showing the first (possibly only) file that is referred to by the resource is useful:

$ dmf ls -S modified -s type -s modified -s files
id   type modified            files
1e41 data 2019-03-23 17:47:53 foo10
e780 data 2019-03-23 17:48:11 foo11
eb60 data 2019-03-23 17:49:08 foo12
0b62 data 2019-03-23 17:49:35 foo13
6c9a data 2019-03-23 17:51:59 foo14
d3d5 data 2019-03-26 13:07:02 bar1

Note that you don’t actually have to show a field to sort by it (compare sort order with results from command above):

$ dmf ls -S modified -s type -s files
id   type files
1e41 data foo10
e780 data foo11
eb60 data foo12
0b62 data foo13
6c9a data foo14
d3d5 data bar1

Add --no-prefix to show the full identifier:

$ dmf ls -S modified -s type -s files --no-prefix
id                               type files
1e41e6ae882b4622ba9043f4135f2143 data foo10
e7809d25b390453487998e1f1ef0e937 data foo11
eb606172dde74aa79eea027e7eb6a1b6 data foo12
0b62d999f0c44b678980d6a5e4f5d37d data foo13
6c9a85629cb24e9796a2d123e9b03601 data foo14
d3d5981106ce4d9d8cccd4e86c2cd184 data bar1
_images/blue-white-band.png
dmf register

Register a new resource with the DMF, using a file as an input. An alias for this command is dmf add.

dmf register options
--no-copy

Do not copy the file, instead remember path to current location. Default is to copy the file under the workspace directory.

-t,--type

Explicitly specify the type of resource. If this is not given, then try to infer the resource type from the file. The default will be ‘data’. The full list of resource types is in idaes.dmf.resource.RESOURCE_TYPES

--strict

If inferring the type fails, report an error. With --no-strict, or no option, if inferring the type fails, fall back to importing as a generic file.

--no-unique

Allow duplicate files. The default is --unique, which will stop and print an error if another resource has a file matching this file’s name and contents.

--contained resource

Add a ‘contained in’ relation to the given resource.

--derived resource

Add a ‘derived from’ relation to the given resource.

--used resource

Add a ‘used by’ relation to the given resource.

--prev resource

Add a ‘version of previous’ relation to the given resource.

--is-subject

If given, reverse the sense of any relation(s) added to the resource so that the newly created resource is the subject and the existing resource is the object. Otherwise, the new resource is the object of the relation.

--version

Set the semantic version of the resource. From 1 to 4 part semantic versions are allowed, e.g.

  • 1
  • 1.0
  • 1.0.1
  • 1.0.1-alpha

See http://semver.org and the function idaes.dmf.resource.version_list() for more details.

dmf register usage

Note

In the following examples, the current working directory is set to /home/myuser and the workspace is named ws.

Register a new file, which is a CSV data file, and use the --info option to show the created resource.

  $ printf "index,time,value\n1,0.1,1.0\n2,0.2,1.3\n" > file.csv
  $ dmf reg file.csv --info
                        Resource 117a42287aec4c5ca333e0ff3ac89639
created
   '2019-04-11 03:58:52'
creator
   name: dang
datafiles
   - desc: file.csv
     is_copy: true
     path: file.csv
     sha1: f1171a6442bd6ce22a718a0e6127866740c9b52c
datafiles_dir
   /home/myuser/ws/files/4db42d92baf3431ab31d4f91ab1a673b
desc
   file.csv
doc_id
   1
id_
   117a42287aec4c5ca333e0ff3ac89639
modified
   '2019-04-11 03:58:52'
type
   data
version
   0.0.0 @ 2019-04-11 03:58:52

If you try to register (add) the same file twice, it will be an error by default. You need to add the --no-unique option to allow it.

$ printf "index,time,value\n1,0.1,1.0\n2,0.2,1.3\n" > timeseries.csv
$ dmf add timeseries.csv
2315bea239c147e4bc6d2e1838e4101f
$ dmf add timeseries.csv
This file is already in 1 resource(s): 2315bea239c147e4bc6d2e1838e4101f
$ dmf add --no-unique timeseries.csv
3f95851e4931491b995726f410998491

If you register a file ending in “.json”, it will be parsed (unless it is over 1MB) and, if it passes, registered as type JSON. If the parse fails, it will be registerd as a generic file unless the --strict option is given (with this option, failure to parse will be an error):

$ echo "totally bogus" > notreally.json
$ dmf reg notreally.json
2019-04-12 06:06:47,003 [WARNING] idaes.dmf.resource: File ending in '.json' is not valid JSON: treating as generic file
d22727c678a1499ab2c5224e2d83d9df
$ dmf reg --strict notreally.json
Failed to infer resource: File ending in '.json' is not valid JSON

You can explicitly specify the type of the resource with the -t,--type option. In that case, any failure to validate will be an error. For example, if you say the resource is a Jupyter Notebook file, and it is not, it will fail. But the same file with type “data” will be fine:

$ echo "Ceci n'est pas une notebook" > my.ipynb
$ dmf reg -t notebook my.ipynb
Failed to load resource: resource type 'notebook': not valid JSON
$ dmf reg -t data my.ipynb
0197a82abab44ecf980d6e42e299b258

You can add links to existing resources with the options --contained, --derived, --used, and --prev. For all of these, the new resource being registered is the target of the relation and the option argument is the identifier of an existing resource that is the subject of the relation.

For example, here we add a “shoebox” resource and then some “shoes” that are contained in it:

$ touch shoebox.txt shoes.txt closet.txt
$ dmf add shoebox.txt
755374b6503a47a09870dfbdc572e561
$ dmf add shoes.txt --contained 755374b6503a47a09870dfbdc572e561
dba0a5dc7d194040ac646bf18ab5eb50
$ dmf info 7553  # the "shoebox" contains the "shoes"
                            Resource 755374b6503a47a09870dfbdc572e561
  created
     '2019-04-11 20:16:50'
  creator
     name: dang
  datafiles
     - desc: shoebox.txt
       is_copy: true
       path: shoebox.txt
       sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709
  datafiles_dir
     /home/dang/src/idaes/dangunter/idaes-dev/docs/ws/files/7f3ff820676b41689bb32bc325fd2d1b
  desc
     shoebox.txt
  doc_id
     9
  id_
     755374b6503a47a09870dfbdc572e561
  modified
     '2019-04-11 20:16:50'
  relations
     - dba0a5dc7d194040ac646bf18ab5eb50 <--[contains]-- ME
  type
     data
  version
     0.0.0 @ 2019-04-11 20:16:50

$ dmf info dba0  # the "shoes" are in the "shoebox"
                            Resource dba0a5dc7d194040ac646bf18ab5eb50
  created
     '2019-04-11 20:17:28'
  creator
     name: dang
  datafiles
     - desc: shoes.txt
       is_copy: true
       path: shoes.txt
       sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709
  datafiles_dir
     /home/dang/src/idaes/dangunter/idaes-dev/docs/ws/files/a27f98c24d1848eaba1b26e5ef87be88
  desc
     shoes.txt
  doc_id
     10
  id_
     dba0a5dc7d194040ac646bf18ab5eb50
  modified
     '2019-04-11 20:17:28'
  relations
     - 755374b6503a47a09870dfbdc572e561 --[contains]--> ME
  type
     data
  version
     0.0.0 @ 2019-04-11 20:17:28

To reverse the sense of the relation, add the --is-subject flag. For example, we now add a “closet” resource that contains the existing “shoebox”. This means the shoebox now has two different “contains” type of relations.

$ dmf add closet.txt --is-subject --contained 755374b6503a47a09870dfbdc572e561
22ace0f8ed914fa3ac3e7582748924e4
$ dmf info 7553
                            Resource 755374b6503a47a09870dfbdc572e561
  created
     '2019-04-11 20:16:50'
  creator
     name: dang
  datafiles
     - desc: shoebox.txt
       is_copy: true
       path: shoebox.txt
       sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709
  datafiles_dir
     /home/dang/src/idaes/dangunter/idaes-dev/docs/ws/files/7f3ff820676b41689bb32bc325fd2d1b
  desc
     shoebox.txt
  doc_id
     9
  id_
     755374b6503a47a09870dfbdc572e561
  modified
     '2019-04-11 20:16:50'
  relations
     - dba0a5dc7d194040ac646bf18ab5eb50 <--[contains]-- ME
     - 22ace0f8ed914fa3ac3e7582748924e4 --[contains]--> ME
  type
     data
  version
     0.0.0 @ 2019-04-11 20:16:50

You can give your new resource a version with the --version option. You can use this together with the --prev option to link between multiple versions of the same underlying data:

# note: following command stores the output of "dmf reg", which is the
#       id of the new resource, in the shell variable "oldid"
$ oldid=$( dmf reg oldfile.py --type code --version 0.0.1 )
$ dmf reg newfile.py --type code --version 0.0.2 --prev $oldid
ef2d801ca29a4a0a8c6f79ee71d3fe07
$ dmf ls --show type --show version --show codes --sort version
id   type version codes
44e7 code 0.0.1   oldfile.py
ef2d code 0.0.2   newfile.py
$ dmf related $oldid
44e7 code

    └──┤version├─▶ ef2d code -
_images/blue-white-band.png
dmf rm

Remove one or more resources. This also removes relations (links) to other resources.

dmf rm options
identifier

The identifier, or identifier prefix, of the resource(s) to remove

--list,--no-list

With the –list option, which is the default, the resources to remove, or removed, will be listed as if by the dmf ls command. With –no-list, then do not produce this output.

-y,--yes

If given, do not confirm removal of the resource(s) with a prompt. This is useful for scripts that do not want to bother with input, or people with lots of confidence.

--multiple

If given, allow multiple resources to be selected by an identifier prefix. Otherwise, if the given identifier matches more than one resource, the program will print a message and stop.

dmf rm usage

Note

In the following examples, there are 5 text files named “file1.txt”, “file2.txt”, .., “file5.txt”, in the workspace. The identifiers for these files may be different in each example.

Remove one resource, by its full identifier:

$ dmf ls --no-prefix
id                               type desc      modified
096aa2491e234c4b941f32b537dd3017 data file5.txt 2019-04-16 02:51:30
821fc8f8e54e4c65b481f483be7f5a2d data file4.txt 2019-04-16 02:51:29
c20f3a6e338a40ee8a3a4972544adb74 data file1.txt 2019-04-16 02:51:25
c8f2b5cb80824e649008c414db5287f7 data file3.txt 2019-04-16 02:51:28
cd62e3bcb9a4459c9f2f5405ca442961 data file2.txt 2019-04-16 02:51:26
$ dmf rm c20f3a6e338a40ee8a3a4972544adb74
id                               type desc      modified
c20f3a6e338a40ee8a3a4972544adb74 data file1.txt 2019-04-16 02:51:25
Remove this resource [y/N]? y
resource removed
[dmfcli-167 !?]idaes-dev$ dmf ls --no-prefix
id                               type desc      modified
096aa2491e234c4b941f32b537dd3017 data file5.txt 2019-04-16 02:51:30
821fc8f8e54e4c65b481f483be7f5a2d data file4.txt 2019-04-16 02:51:29
c8f2b5cb80824e649008c414db5287f7 data file3.txt 2019-04-16 02:51:28
cd62e3bcb9a4459c9f2f5405ca442961 data file2.txt 2019-04-16 02:51:26

Remove a single resource by its prefix:

$ dmf ls
id   type desc      modified
6dd5 data file2.txt 2019-04-16 18:51:10
7953 data file3.txt 2019-04-16 18:51:12
7a06 data file4.txt 2019-04-16 18:51:13
e5d7 data file1.txt 2019-04-16 18:51:08
fe0c data file5.txt 2019-04-16 18:51:15
$ dmf rm 6d
id                               type desc      modified
6dd57ecc50a24efb824a66109dda0956 data file2.txt 2019-04-16 18:51:10
Remove this resource [y/N]? y
resource removed
$ dmf ls
id   type desc      modified
7953 data file3.txt 2019-04-16 18:51:12
7a06 data file4.txt 2019-04-16 18:51:13
e5d7 data file1.txt 2019-04-16 18:51:08
fe0c data file5.txt 2019-04-16 18:51:15

Remove multiple resources that share a common prefix. In this case, use the -y,--yes option to remove without prompting.

$ dmf ls
id   type desc      modified
7953 data file3.txt 2019-04-16 18:51:12
7a06 data file4.txt 2019-04-16 18:51:13
e5d7 data file1.txt 2019-04-16 18:51:08
fe0c data file5.txt 2019-04-16 18:51:15
$ dmf rm --multiple --yes 7
id                               type desc      modified
7953e67db4a543419b9988c52c820b68 data file3.txt 2019-04-16 18:51:12
7a06435c39b54890a3d01a9eab114314 data file4.txt 2019-04-16 18:51:13
2 resources removed
$ dmf ls
id   type desc      modified
e5d7 data file1.txt 2019-04-16 18:51:08
fe0c data file5.txt 2019-04-16 18:51:15
_images/blue-white-band.png
dmf status

This command shows basic information about the current active workspace and, optionally, some additional details. It does not (yet) give any way to modify the workspace configuration. To do that, you need to edit the config.yaml file in the workspace root directory. See Configuration.

dmf status options
--color

Allow (if terminal supports it) colored terminal output. This is the default.

--no-color

Disallow, even if terminal supports it, colored terminal output. UNIX output streams to pipes should be detected and have color disabled, but this option can force that behavior if detection is failing.

-s,--show info

Show one of the following types of information:

files
Count and total size of files in workspace
htmldocs
Configured paths to the HTML documentation (for “%dmf help” magic in the Jupyter Notebook)
logging
Configuration for logging
all
Show all items above
-a,--all

This option is just an alias for “–show all”.

dmf status usage

Note

In the following examples, the current working directory is set to /home/myuser and the workspace is named ws.

Also note that the output shown below is plain (black) text. This is due to our limited understanding of how to do colored text in our documentation tool (Sphinx). In a color-capable terminal, the output will be more colorful.

Show basic workspace status:

$ dmf status
settings:
  workspace: /home/myuser/ws
workspace:
  location: /home/myuser/ws
  name: myws
  description: my workspace
  created: 2019-04-09 12:46:40
  modified: 2019-04-09 12:46:40

Add the file information:

$ dmf status --show files
settings:
  workspace: /home/myuser/ws
workspace:
  location: /home/myuser/ws
  name: myws
  description: my workspace
  created: 2019-04-09 12:52:49
  modified: 2019-04-09 12:52:49
  files:
    count: 3
    total_size: 1.3 MB

You can repeat the -s,--show option to add more things:

$ dmf status --show files --show htmldocs
settings:
  workspace: /home/myuser/ws
workspace:
  location: /home/myuser/ws
  name: myws
  description: my workspace
  created: 2019-04-09 12:54:10
  modified: 2019-04-09 12:54:10
  files:
    count: 3
    total_size: 1.3 MB
  html_documentation_paths:
    -: /home/myuser/idaes/docs/build

However, showing everything is less typing, and not overwhelming:

$ dmf status -a
settings:
  workspace: /home/myuser/ws
workspace:
  location: /home/myuser/ws
  name: myws
  description: my workspace
  created: 2019-04-09 12:55:05
  modified: 2019-04-09 12:55:05
  files:
    count: 3
    total_size: 1.3 MB
  html_documentation_paths:
    -: /home/myuser/idaes/docs/build
  logging:
    not configured

Overview

The Data Management Framework (DMF) is used to manage all the data needed by the IDAES framework, including flowsheets, models, and results. It stores metadata and data in persistent storage. It does not require that the user run a server or connect to a remote service. The DMF can be accessed through its Python API or command-line interfaces. There is work in progress on adding graphical interfaces for Jupyter Notebooks and stand-alone desktop apps.

The DMF is designed to allow multiple separate threads of work. These are organized in workspaces. Inside a given workspace, all the information is represented by containers called resources. A resource describes some data in the system in a standard way, so it can be searched and manipulated by the rest of the IDAES framework. Resources can be connected to each other with relations such as “derived”, “contains”, “uses”, and “version”.

Below is an illustration of these components.

_images/dmf-workspace-resource.png

Configuration

The DMF is configured with an optional global configuration file and a required per-workspace configuration file. By default the global file is looked for as .dmf in the user’s home directory. Its main function at the moment is to set the default workspace directory with the workspace keyword. For example:

# global DMF configuration
workspace: ~/data/workspaces/workspace1

The per-workspace configuration has more options. See the documentation in the Workspace class for details. The configuration file is in YAML (or JSON) format. Here is an example file, with some description in comments:

settings:                               # Global settings
  workspace: /home/myuser/ws            # Path to current workspace
workspace:                              # Per-workspace settings
  location: /home/myuser/ws             # Path to this workspace
  name: myws                            # Name of this workspace
  description: my workspace             # Description (if any) of this workspace
  created: 2019-04-09 12:55:05          # Date workspace was created
  modified: 2019-04-09 12:55:05         # Date workspace was modified
  files:                                # Basic information about data files
    count: 3                            # How many files
    total_size: 1.3 MB                  # Total size of the files
  html_documentation_paths:             # List of paths for HTML documentation
    -: /home/myuser/idaes/docs/build
  logging:                              # Logging configuration
    idaes.dmf:                          # Name of the logger
        level: DEBUG                    # Log level (Python logging constant)
        output: /tmp/debug.log          # File path or "_stdout_" or "_stderr_"

This configuration file is used whether you use the DMF from the command-line, Jupyter notebook, or in a Python program. For details see the DMF package documentation.

Jupyter notebook usage

In the Jupyter Notebook, there are some “magics” defined that make initializing the DMF pretty easy. For example:

from idaes.dmf import magics
%dmf init path/to/workspace

The code above loads the “%dmf” line magic in the first line, then uses it to initialize the DMF with the workspace at “path/to/workspace”.

From there, other “line magics” will operate in the context of that DMF workspace.

  • %dmf help - Provide help on IDAES objects and classes. See dmf-help.
  • %dmf info - Provide information about DMF current state for whatever ‘topics’ are provided
  • %dmf list - List resources in the current workspace
  • %dmf workspaces - List DMF workspaces; you can do this before %dmf init
DMF help

The IDAES Python interfaces are documented with Sphinx. This includes automatic translation of the comments and structure of the code into formatted and hyperlinked HTML pages. The %dmf help command lets you easily pull up this documentation for an IDAES module, class, or object. Below are a couple of examples:

# Initialize the DMF first
from idaes.dmf import magics
%dmf init path/to/workspace create

# Get help on a module (imported)
from idaes.core import control_volume1d
%dmf help control_volume1d

# Get help on a module (by name, no import)
%dmf help idaes.core.control_volume0d

# Get help on a class
from idaes.core.control_volume1d import ControlVolume1DBlock
%dmf help ControlVolume1DBlock

# Get help on a class (by name, no import)
%dmf help idaes.core.control_volume1d.ControlVolume1DBlock

# Get help on an object (will show help for the object's class)
# This will end up showing the same help as the previous two examples
obj = control_volume1d.ControlVolume1DBlock()
%dmf help obj

The help pages will open in a new window. The location of the built documentation that they use is configured in the per-workspace DMF configuration under the htmldocs keyword (a default value is filled in when the DMF is first initialized).

Sharing

The contents of a DMF workspace can be shared quite simply because the data is all contained within a directory in the local file system. So, some ways to share (with one or many people) include:

  • Put the workspace directory in a cloud/shared drive like Dropbox , Box , Google Drive , or OneDrive .
  • Put the workspace directory under version control like Git and share that versioned data using Git commands and a service like Github , BitBucket or Gitlab.
  • Package up the directory with a standard archiving utility like “zip” or “tar” and share it like any other file (e.g. attach it to an email).

Note

These modes of sharing allow users to see the same data, but are not designed for real-time collaboration (reading and writing) of the same data. That mode of operation requires a proper database server to mediate operations on the same data. This is in the roadmap for the DMF, but not currently implemented.

Reference

See the idaes.dmf package documentation that is generated automatically from the source code.

IDAES Versioning

The IDAES Python package is versioned according to the general guidelines of semantic versioning, following the recommendations of PEP 440 with respect to extended versioning descriptors (alpha, beta, release candidate, etc.).

Basic usage

You can see the version of the package at any time interactively by printing out the __version__ variable in the top-level package:

import idaes
print(idaes.__version__)
# prints a version like "1.2.3"

Advanced usage

This section describes the module’s variables and classes.

Overview

The API in this module is mostly for internal use, e.g. from ‘setup.py’ to get the version of the package. But Version has been written to be usable as a general versioning interface.

Example of using the class directly:

>>> from idaes.ver import Version
>>> my_version = Version(1, 2, 3)
>>> print(my_version)
1.2.3
>>> tuple(my_version)
(1, 2, 3)
>>> my_version = Version(1, 2, 3, 'alpha')
>>> print(my_version)
1.2.3a
>>> tuple(my_version)
(1, 2, 3, 'alpha')
>>> my_version = Version(1, 2, 3, 'candidate', 1)
>>> print(my_version)
1.2.3rc1
>>> tuple(my_version)
(1, 2, 3, 'candidate', 1)

If you want to add a version to a class, e.g. a model, then simply inherit from HasVersion and initialize it with the same arguments you would give the Version constructor:

>>> from idaes.ver import HasVersion
>>> class MyClass(HasVersion):
...     def __init__(self):
...         super(MyClass, self).__init__(1, 2, 3, 'alpha')
...
>>> obj = MyClass()
>>> print(obj.version)
1.2.3a
idaes.ver.package_version = <idaes.ver.Version object>

Package’s version as an object

idaes.ver.__version__ = '1.1.1'

Package’s version as a simple string

Version class

The versioning semantics are encapsulated in a class called Version.

class idaes.ver.Version(major, minor, micro, releaselevel='final', serial=None)[source]

This class attempts to be compliant with a subset of PEP 440.

Note: If you actually happen to read the PEP, you will notice that pre- and post- releases, as well as “release epochs”, are not supported.

__init__(major, minor, micro, releaselevel='final', serial=None)[source]

Create new version object.

Provided arguments are stored in public class attributes by the same name.

Parameters:
  • major (int) – Major version
  • minor (int) – Minor version
  • micro (int) – Micro (aka patchlevel) version
  • releaselevel (str) – Optional PEP 440 specifier
  • serial (int) – Optional number associated with releaselevel
__iter__()[source]

Return version information as a sequence.

__str__()[source]

Return version information as a string.

HasVersion class

For adding versions to other classes in a simple and standard way, you can use the HasVersion mixin class.

class idaes.ver.HasVersion(*args)[source]

Interface for a versioned class.

__init__(*args)[source]

Constructor creates a version attribute that is an instance of Version initialized with the provided args.

Parameters:*args – Arguments to be passed to Version constructor.

Tutorials

The tutorials linked below are Jupyter Notebooks, which create and run IDAES models. They provide a thorough introduction to the capabilities of the IDAES PSE framework. They were originally presented at a stakeholder meeting in May of 2019. Each tutorial presents the creation of models, etc., as a series of steps with extensive context and information. Each tutorial builds on information from the prior one, so it is recommended that the new user view them in order.

Module 0 Welcome Solution:

Module_0_Welcome_Solution

Welcome to the IDAES Stakeholder Workshop

Welcome and thank you for taking the time to attend today's workshop. Today we will introduce you to the fundamentals of working with the IDAES process modeling toolset, and we will demonstrate how these tools can be applied for optimization applications.

Today's workshop will be conducted using Jupyter Notebooks which provide an online, interactive Python environment for you to use (without the need for installing anything).

Before we get started on some actual examples, let's make sure that everything is working correctly. The cell below contains a command to run a simple test script that will test that everything we will need for today is working properly.

You can execute a cell by pressing Shift+Enter.

In [1]:
run "notebook_test_script.py"
Pyomo Import Checks:        Passed
IDAES Import Checks:        Passed
Solver Availability Check:  Passed
Simple Model Check:         Passed

All Good!

If everything worked properly, you should see a message saying All good! and a summary of all the checks that were run. If you don't see this, please contact someone for assistance.

Outline of Workshop

Today's workshop is divided into four modules which will take you through the steps of setting up a flowsheet within the IDAES framework.

Welcome Module (this one):

  • Introduction to Jupyter notebooks and Python
  • Introduction to Pyomo

Module 1 will cover:

  • how to import models from the core IDAES model library,
  • how to create a model for a single unit operation,
  • how to define feed and operating conditions,
  • how to initialize and a single unit model,
  • some ways we can manipulate the model and examine the results.

Module 2 will demonstrate:

  • how to combine unit models together to form flowsheets,
  • tools to initialize and solve flowsheets with recycle loops,
  • how to optimize process operating conditions to meet product specifications.

Module 3 will demonstrate:

  • how to build new unit models using the IDAES tools,
  • how to include new unit models into flowsheets.

Introduction to Jupyter Notebooks and Python

In this short notebook, we will briefly describe the uses of Jupyter notebooks like this one, and provide you with the necessary background in Python for this workshop. We will cover if statements, looping, array-like containers called lists and dictionaries, as well as the use of some external packages for working with data.

There are many additional tutorials online to learn more about the Python syntax.

In Python, variables do not need to be declared before they are used. You can simply define a new variable using x = 5.

Inline Exercise: In the cell below, assign a value of 5 to the variable x. Don't forget to type Shift+Enter to execute the line.
In [2]:
x = 5

You can easily see the value of a variable using the built-in print function. For example, to print the value of x use print(x).

Inline Exercise: Write the code to print the value of x. Don't forget to hit Shift+Enter to execute the cell.
In [3]:
print(x)
5
Inline Exercise: Now change the value of the x variable to 8 and execute the cell.
In [4]:
x = 8

Jupyter notebooks and execution order

Note: When using Jupyter notebooks, it is very important to know that the cells can be executed out of order (intentionally or not). The state of the environment (e.g., values of variables, imports, etc.) is defined by the execution order.
Inline Exercise: To see this concept, select the cell above that contained the print statement and execute the cell again using Shift+Enter.

You should see that the value 8 is now printed. This may seem problematic if you are used to programming in environments where the state is linked to the order of the commands as written, not as executed.

Again, notice that the state of the environment is determined by the execution order.

Note also that the square brackets to the left of the cell show the order that cells were executed. If you scroll to the top, you should see that the code cells show an execution order of [1], [2], [5], and [4], indicating the actual execution order.

There are some useful menu commands at the top of the Jupyter notebook to help with these problems and make sure you retain the execution order as expected.

Some important commands to remember:

  • You can clear the current state with the menu item Kernel | Restart & Clear Output
  • It is often useful to clear the state using the menu command just described, and then execute all the lines above the currently selected cell using Cell | Run All Above.
  • You can clear all the state and re-run the entire notebook using Kernel | Restart & Run All.

To show the use of these commands, complete the following.

Inline Exercise:
  • Clear the current state (using Kernel | Restart & Clear Output). You should notice that the square brackets that listed the execution order are all now empty.
  • Select the cell immediately below this text
  • Re-run all the code up to this point (Cell | Run All Above). You should now see that the square brackets indicate the expected execution order.
  • Print the value of x again using the print function. You should see the value 8 printed, while the earlier cell printing x shows the value of 5 as expected.
In [5]:
print(x)
8

Python if statements

In the code below, we show an example of an if statement in Python.

temp = 325
# some other code
if temp > 320:
    print('temperature is too high')
elif x < 290:
    print('temperature is too low')
else:
    print('temperature is just right')
Note: You will notice that there are no braces to separate blocks in the if-else tree. In Python, indentation is used to delineate blocks of code throughout Python (e.g., if statements, for loops, functions, etc.). The indentation in the above example is not only to improve legibility of the code. It is necessary for the code to run correctly. As well, the number of spaces required to define the indentation is arbitrary, but it must be consistent throughout the code. For example, we could use 3 spaces (instead of the 4 used in the example above, but we could not use 3 for one of the blocks and 4 for another).

Using the syntax above for the if statement, write the following code.

Inline Exercise:
  • set the value of the variable T_degC to 20
  • convert this from degrees Celsius to degrees Fahrenheit (use variable name T_degF)
  • write an `if` statement that prints a message if the degrees Fahrenheit are below 70
In [6]:
T_degC = 20
# some other code
T_degF = (T_degC * 9.0/5.0) + 32.0

# Todo: put the if statement here
if T_degF < 70:
    print('The room is too cold.')
The room is too cold.

Python list containers

Now we will illustrate the use of lists in Python. Lists are similar to vectors or arrays in other languages. A list in Python is indexed by integers from 0 up to the length of the array minus 1. The list can contain standard types (int, float, string), or other objects.

In the next inline exercise, we will create a list that contains the values from 0 to 50 by steps of 5 using a for loop. Note that the python function range(n) can be used to iterate from 0 to (n-1) in a for loop. Also note that lists have an append method which adds an entry to the end of the list (e.g., if the list l currently has 5 elements, then l.append('temp') will add the string "temp" as the sixth element). Print the new list after the for loop. If this is done correctly, you should see: [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50] printed after the cell.

Inline Exercise: Complete the code block below to create the desired list and print the result.
In [7]:
# Create a list with the values 0 to 50 with steps of 5.
xlist = list()
for i in range(11):
    # Todo: use the append method of list to append the correct value
    xlist.append(i*5)

print(xlist) # Todo: print the value of xlist to verify the results
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50]

Python provides a short-hand notation for building lists called list comprehensions. An example of a list comprehension that creates all even numbers from 0 to 40 is:

values = [q*2 for q in range(21)]

Note also that list comprehensions can include if clauses. For example, we could also implement the above example with the following code:

values = [q for q in range(41) if q % 2 == 0]

Note that % is the modulus operator (it returns the remainder of the division). Therefore, in the above code, q % 2 returns 0 if the value in q is exactly divisible by 2 (i.e., an even number).

Inline Exercise: In the cell below, create the same xlist that we created previously, but use the list comprehension notation. Verify that this result is correct by printing it.
In [8]:
# Todo: define the list comprehension
xlist = [i*5 for i in range(11)] 
print(xlist)
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50]

You can easily check the length of a list using the python len(l) function.

Inline Exercise: Print the length of `xlist`. It should be 11.
In [9]:
print(len(xlist)) # Todo: print the len of the list
11

If you have a list of values or objects, it is easy to iterate through that list in a for loop. In the next inline exercise, we will create another list, ylist where each of the values is equal to the corresponding value in xlist squared. That is, $y_i = x_i^2$.

Inline Exercise: Modify the code below to create ylist as described above. Print the values in ylist to check the result.
In [10]:
ylist = list()

# Todo: define the for loop to add elements to ylist using the values in xlist
for x in xlist:
    ylist.append(x**2)

print(ylist)
[0, 25, 100, 225, 400, 625, 900, 1225, 1600, 2025, 2500]

This same task could have been done with a list comprehension (using much less code).

Inline Exercise: Write the list comprehension to compute the values of ylist. Print the values in ylist to check the result.
In [11]:
# Todo: create ylist using a list comprehension and print the result
ylist = [x**2 for x in xlist]
print(ylist)
[0, 25, 100, 225, 400, 625, 900, 1225, 1600, 2025, 2500]

Python dictionary containers

Another valuable data structure in Python are dictionaries. Dictionaries are an associative array; that is, a map from keys to values or objects. The keys can be almost anything, including floats, integers, and strings. The code below shows an example of creating a dictionary (here, to store the areas of some of the states).

Inline Exercise: Execute the lines below to see the areas dictionary.
In [12]:
areas = dict()
areas['South Dakota'] = 199742               
areas['Oklahoma'] = 181035
print(areas)
{'South Dakota': 199742, 'Oklahoma': 181035}

Dictionaries can contain mixed types (i.e., it is valid to add areas['Texas'] = 'Really big!') but this may lead to unpredictable behavior if the different types are unexpected in other parts of the code.

You can loop through dictionaries in different ways. For example,

d = {'A': 2, 'B': 4, 'D': 16}
for k in d.keys():
    # loop through the keys in the dictionary
    # access the value with d[k]
    print('key=', k, 'value=', d[k])

for v in d.values():
    # loop through the values in the dictionary, ignoring the keys
    print('value=', v)

for k,v in d.items():
    # loop through the entries in the dictionary, retrieving both
    # the key and the value
    print('key=', k, 'value=', v)
Inline Exercise: The areas listed above for the two states are in square kilometers. Modify the loop below to create a new dictionary that contains the areas in square miles. Print the new dictionary to verify the correct behavior. Note that 1 kilometer is equal to 0.62137 miles.
In [13]:
areas_mi = dict()
for state_name, area in areas.items():
    # Todo: convert the area to sq. mi and assign to the areas_mi dict.
    areas_mi[state_name] = area*(0.62137**2)
print(areas_mi)
{'South Dakota': 77120.5214053598, 'Oklahoma': 69897.7360425915}

Python also supports dictionary comprehensions much like list comprehensions. For example:

d = {'A': 2, 'B': 4, 'D': 16}
d2 = {k:v**2 for k,v in d.items()}
Inline Exercise: Redo the conversion from square kilometers to square miles using a dictionary comprehension.
In [14]:
# Todo: define areas_mi using a dictionary comprehension and print the result
areas_mi = {k:v*(0.62137**2) for k,v in areas.items()}
print(areas_mi)
{'South Dakota': 77120.5214053598, 'Oklahoma': 69897.7360425915}

Matplotlib for generating figures

We will now briefly explore the use of the matplotlib package to generate figures. Before we do this, we will introduce some other helpful tools.

Another effective way to create a list of evenly spaced numbers (e.g., for plotting or other computation) is to use the linspace function from the numpy package. Let's import the numpy package and use linspace function to create a list of 15 evenly spaced intervals (that is, 16 points) from 0 to 50 and store this in xlist. We will also create the ylist that corresponds to the square of the values in xlist. Note, we must first import the numpy package.

Inline Exercise: Execute the next two cells to see the output.
In [15]:
import numpy as np
In [16]:
xlist = list(np.linspace(0,50,16))
ylist = [x**2 for x in xlist]
print(xlist)
print(ylist)
[0.0, 3.3333333333333335, 6.666666666666667, 10.0, 13.333333333333334, 16.666666666666668, 20.0, 23.333333333333336, 26.666666666666668, 30.0, 33.333333333333336, 36.66666666666667, 40.0, 43.333333333333336, 46.66666666666667, 50.0]
[0.0, 11.111111111111112, 44.44444444444445, 100.0, 177.7777777777778, 277.7777777777778, 400.0, 544.4444444444446, 711.1111111111112, 900.0, 1111.1111111111113, 1344.4444444444448, 1600.0, 1877.777777777778, 2177.7777777777783, 2500.0]

This printed output is not a very effective way to communicate these results. Let's use matplotlib to create a figure of x versus y. A full treatment of the matplotlib package is beyond the scope of this tutorial. For now, we will import the plotting capability and show how to generate a straightforward figure. You can consult the documentation for matplotlib for further details.

Inline Exercise: Execute the next two cells to see the output.
In [17]:
import matplotlib.pyplot as plt
In [18]:
plt.plot(xlist, ylist)
plt.title('Embedded x vs y figure')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(['data'])
plt.show()

Next, we will use what you have learned so far to create a plot of sin(x) for x from 0 to $2 \pi$ with 100 points. Note, you can get the sin function and the value for $\pi$ from the math package.

Inline Exercise: Execute the import statement in the next cell, and then complete the missing code in the following cell to create the figure discussed above.
In [19]:
import math
In [20]:
x = list(np.linspace(0,2*math.pi, 100))

# Todo: create the list for y
y = [math.sin(xv) for xv in x] 

# Todo: Generate the figure
plt.plot(x, y)
plt.title('Trig: sin function')
plt.xlabel('x in radians')
plt.ylabel('sin(x)')
plt.show()

Importing and exporting data using Pandas

Often, it is useful to output the data in a general format so it can be imported into other tools or presented in a familiar application. Python makes this easy with many great packages already available. The next code shows how to use the pandas package to create a dataframe and export the data to a csv file that we can import to excel. You could also consult pandas documentation to see how to export the data directly to excel.

Inline Exercise: Execute the code below that shows how to import some data into a DataFrame from the Pandas package and then export this data to a csv file.
In [21]:
import pandas as pd
df_sin = pd.DataFrame({'x': x, 'sin(x) (radians)': y})
print(df_sin)
df_sin.to_csv('sin_data.csv')
           x  sin(x) (radians)
0   0.000000      0.000000e+00
1   0.063467      6.342392e-02
2   0.126933      1.265925e-01
3   0.190400      1.892512e-01
4   0.253866      2.511480e-01
5   0.317333      3.120334e-01
6   0.380799      3.716625e-01
7   0.444266      4.297949e-01
8   0.507732      4.861967e-01
9   0.571199      5.406408e-01
10  0.634665      5.929079e-01
11  0.698132      6.427876e-01
12  0.761598      6.900790e-01
13  0.825065      7.345917e-01
14  0.888531      7.761465e-01
15  0.951998      8.145760e-01
16  1.015464      8.497254e-01
17  1.078931      8.814534e-01
18  1.142397      9.096320e-01
19  1.205864      9.341479e-01
20  1.269330      9.549022e-01
21  1.332797      9.718116e-01
22  1.396263      9.848078e-01
23  1.459730      9.938385e-01
24  1.523196      9.988673e-01
25  1.586663      9.998741e-01
26  1.650129      9.968548e-01
27  1.713596      9.898214e-01
28  1.777063      9.788024e-01
29  1.840529      9.638422e-01
..       ...               ...
70  4.442656     -9.638422e-01
71  4.506123     -9.788024e-01
72  4.569589     -9.898214e-01
73  4.633056     -9.968548e-01
74  4.696522     -9.998741e-01
75  4.759989     -9.988673e-01
76  4.823455     -9.938385e-01
77  4.886922     -9.848078e-01
78  4.950388     -9.718116e-01
79  5.013855     -9.549022e-01
80  5.077321     -9.341479e-01
81  5.140788     -9.096320e-01
82  5.204254     -8.814534e-01
83  5.267721     -8.497254e-01
84  5.331188     -8.145760e-01
85  5.394654     -7.761465e-01
86  5.458121     -7.345917e-01
87  5.521587     -6.900790e-01
88  5.585054     -6.427876e-01
89  5.648520     -5.929079e-01
90  5.711987     -5.406408e-01
91  5.775453     -4.861967e-01
92  5.838920     -4.297949e-01
93  5.902386     -3.716625e-01
94  5.965853     -3.120334e-01
95  6.029319     -2.511480e-01
96  6.092786     -1.892512e-01
97  6.156252     -1.265925e-01
98  6.219719     -6.342392e-02
99  6.283185     -2.449294e-16

[100 rows x 2 columns]

If you go back to the browser tab that showed all the Jupyter notebook files and refresh, you will now see that there is a csv file with the x and y data. You can consult the Pandas documentation do learn about the many data analysis and statistical features of the pandas package.

Introduction to Pyomo

Pyomo is an object-oriented, python-based package for equation-oriented (or algebraic) modeling and optimization. The IDAES framework is built upon the Pyomo package. IDAES extends the Pyomo package and defines a class heirarchy for flowsheet based modeling, including definition of property packages, unit models, and flowsheets.

The use of IDAES does not require extensive knowledge about Pyomo, however, it can be beneficial to have some familiarity with the Pyomo package for certain tasks:

  • IDAES models are open, and you can interrogating the underlying Pyomo model to view the variables, constraints, and objective functions defined in the model.
  • You can use Pyomo components to define your objective function or to create additional constraints.
  • Since IDAES models are Pyomo models, any advanced meta-algorithms or analysis tools that can be developed and/or used on a Pyomo model can also be used on an IDAES model.

A full tutorial on Pyomo is beyond the scope of this workshop, however, in this section, we will briefly cover the commands required to specify an objective function or add a constraint to an existing model.

In the next cell, we will create a Pyomo model, and add a couple of variables to that model. When using IDAES, you will define a flowsheet and the addition of variables and model equations will be handled by the IDAES framework.

Inline Exercise: Execute the following cell to create a Pyomo model with some variables that will be used later.
In [22]:
from pyomo.environ import ConcreteModel, Var
model = ConcreteModel()
model.x = Var()
model.y = Var()

The Pyomo syntax to define a scalar objective function is shown below. This defines the objective function as $x^2$. By default Pyomo models (and IDAES models) seek to minimize the objective function.

model.obj = Objective(expr=model.x**2)

To maximize a quantity, include the keyword argument sense=maximize as in the following:

model.obj = Objective(expr=model.y, sense=maximize)

Note that Objective and maximize would need to be imported from pyomo.environ.

The Pyomo syntax to define a scalar constraint is shown below. This code defines the equality constraint $x^2 + y^2 = 1$.

model.on_unit_circle_con = Constraint(expr=model.x**2 + model.y**2 == 1)

Pyomo also supports inequalities. For example, the code for the inequality constraint $x^2 + y^2 \le 1$ is given as the following.

model.inside_unit_circle_con = Constraint(expr=model.x**2 + model.y**2 <= 1)

Note that, as before, we would need to include the appropriate imports. In this case Constraint would need to be imported from pyomo.environ.

Using the syntax shown above, we will now add the objective function: $\min x^2 + y^2$ and the constraint $x + y = 1$.

Inline Exercise: Complete the missing code in the cell below. If this is done correctly, after executing the cell, you should see the log output from the solver and the printed solution should show that x, y, and the objective value are all equal to 0.5.
In [23]:
from pyomo.environ import Objective, Constraint, value

# Todo: add the objective function here
model.obj = Objective(expr=model.x**2 + model.y**2)

# Todo: add the constraint here
model.con = Constraint(expr=model.x + model.y == 1)

# now solve the problem
status = SolverFactory('ipopt').solve(model, tee=True) # tee=True shows the solver log

# print the values of x, y, and the objective function at the solution
# Note that the results are automatically stored in the model variables
print('x =', value(model.x))
print('y =', value(model.y))
print('obj =', value(model.obj))
Ipopt 3.12.12: 

******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
 Ipopt is released as open source code under the Eclipse Public License (EPL).
         For more information visit http://projects.coin-or.org/Ipopt
******************************************************************************

This is Ipopt version 3.12.12, running with linear solver mumps.
NOTE: Other linear solvers might be more efficient (see Ipopt documentation).

Number of nonzeros in equality constraint Jacobian...:        2
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:        2

Total number of variables............................:        2
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        0
                     variables with only upper bounds:        0
Total number of equality constraints.................:        1
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  0.0000000e+00 1.00e+00 0.00e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  5.0000000e-01 0.00e+00 0.00e+00  -1.7 5.00e-01    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 1

                                   (scaled)                 (unscaled)
Objective...............:   5.0000000000000000e-01    5.0000000000000000e-01
Dual infeasibility......:   0.0000000000000000e+00    0.0000000000000000e+00
Constraint violation....:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   0.0000000000000000e+00    0.0000000000000000e+00
Overall NLP error.......:   0.0000000000000000e+00    0.0000000000000000e+00


Number of objective function evaluations             = 2
Number of objective gradient evaluations             = 2
Number of equality constraint evaluations            = 2
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 2
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 1
Total CPU secs in IPOPT (w/o function evaluations)   =      0.012
Total CPU secs in NLP function evaluations           =      0.000

EXIT: Optimal Solution Found.
x = 0.5
y = 0.5
obj = 0.5

Notice that the code above also imported the value function. This is a Pyomo function that should be used to retrieve the value of variables in Pyomo (or IDAES) models. Note that you can display the complete list of all variables, objectives, and constraints (with their expressions) using model.pprint(). The display method is similar to the pprint method except that is shows the values of the constraints and objectives instead of the underlying expressions. The pprint and display methods can also be used on individual components.

Inline Exercise: Execute the lines of code below to see the output from pprint and display for a Pyomo model.
In [24]:
print('*** Output from model.pprint():')
model.pprint()

print()
print('*** Output from model.display():')
model.display()
*** Output from model.pprint():
2 Var Declarations
    x : Size=1, Index=None
        Key  : Lower : Value : Upper : Fixed : Stale : Domain
        None :  None :   0.5 :  None : False : False :  Reals
    y : Size=1, Index=None
        Key  : Lower : Value : Upper : Fixed : Stale : Domain
        None :  None :   0.5 :  None : False : False :  Reals

1 Objective Declarations
    obj : Size=1, Index=None, Active=True
        Key  : Active : Sense    : Expression
        None :   True : minimize : x**2 + y**2

1 Constraint Declarations
    con : Size=1, Index=None, Active=True
        Key  : Lower : Body  : Upper : Active
        None :   1.0 : x + y :   1.0 :   True

4 Declarations: x y obj con

*** Output from model.display():
Model unknown

  Variables:
    x : Size=1, Index=None
        Key  : Lower : Value : Upper : Fixed : Stale : Domain
        None :  None :   0.5 :  None : False : False :  Reals
    y : Size=1, Index=None
        Key  : Lower : Value : Upper : Fixed : Stale : Domain
        None :  None :   0.5 :  None : False : False :  Reals

  Objectives:
    obj : Size=1, Index=None, Active=True
        Key  : Active : Value
        None :   True :   0.5

  Constraints:
    con : Size=1
        Key  : Lower : Body : Upper
        None :   1.0 :  1.0 :   1.0
In [ ]:
 

Module 1 Flash Unit Solution:

Module_1_Flash_Unit_Solution

Module 1: Flash Unit

In this module, we will familiarize ourselves with the IDAES framework by creating and working with a flowsheet that contains a single flash tank. The flash tank will be used to perform separation of Benzene and Toluene. The inlet specifications for this flash tank are:

Inlet Specifications:

  • Mole fraction (Benzene) = 0.5
  • Mole fraction (Toluene) = 0.5
  • Pressure = 101325 Pa
  • Temperature = 368 K

We will complete the following tasks:

  • Create the model and the IDAES Flowsheet object
  • Import the appropriate property packages
  • Create the flash unit and set the operating conditions
  • Initialize the model and simulate the system
  • Demonstrate analyses on this model through some examples and exercises

Create the Model and the IDAES Flowsheet

In the next cell, we will perform the necessary imports to get us started. From pyomo.environ (a standard import for the Pyomo package), we are importing ConcreteModel (to create the Pyomo model that will contain the IDAES flowsheet) and SolverFactory (to create the object we will use to solve the equations). We will also import Constraint as we will be adding a constraint to the model later in the module. Lastly, we also import value from Pyomo. This is a function that can be used to return the current numerical value for variables and parameters in the model. These are all part of Pyomo.

We will also import the main FlowsheetBlock from IDAES. The flowsheet block will contain our unit model.

Inline Exercise: Execute the cell below to perform the imports. Let a workshop organizer know if you see any errors.
In [1]:
from pyomo.environ import ConcreteModel, SolverFactory, Constraint, value
from idaes.core import FlowsheetBlock

In the next cell, we will create the ConcreteModel and the FlowsheetBlock, and attach the flowsheet block to the Pyomo model.

Inline Exercise: Execute the cell below to create the objects
In [2]:
m = ConcreteModel()
m.fs = FlowsheetBlock(default={"dynamic": False})

At this point, we have a single Pyomo model that contains an (almost) empty flowsheet block.

Inline Exercise: Use the pprint method on the model, i.e. m.pprint(), to see what is currently contained in the model.
In [3]:
# Todo: call pprint on the model
m.pprint()
1 Block Declarations
    1 Set Declarations
        time : Dim=0, Dimen=1, Size=1, Domain=None, Ordered=Insertion, Bounds=(0.0, 0.0)
            [0.0]

    1 Declarations: time

1 Declarations: fs

Define Properties

We need to define the property package for our flowsheet. In this example, we have created a property package based on ideal VLE that contains the necessary components.

IDAES supports creation of your own property packages that allow for specification of the fluid using any set of valid state variables (e.g., component molar flows vs overall flow and mole fractions). This flexibility is designed to support advanced modeling needs that may rely on specific formulations. As well, the IDAES team has completed some general property packages (and is currently working on more). To learn about creating your own property package, please consult the online documentation at: https://idaes-pse.readthedocs.io/en/latest/core/properties.html and look at examples within IDAES

For this workshop, we will import the BTX_idea_VLE property package and create a properties block for the flowsheet. This properties block will be passed to our unit model to define the appropriate state variables and equations for performing thermodynamic calculations.

Inline Exercise: Execute the following two cells to import and create the properties block.
In [4]:
import BTX_ideal_VLE as ideal_props
In [5]:
m.fs.properties = ideal_props.BTXParameterBlock()

Adding Flash Unit

Now that we have the flowsheet and the properties defined, we can create the flash unit and add it to the flowsheet.

The Unit Model Library within IDAES includes a large set of common unit operations (see the online documentation for details: https://idaes-pse.readthedocs.io/en/latest/models/index.html

IDAES also fully supports the development of customized unit models (which we will see in a later module).

Some of the IDAES pre-written unit models:

  • Mixer / Splitter
  • Heater / Cooler
  • Heat Exchangers (simple and 1D discretized)
  • Flash
  • Reactors (kinetic, equilibrium, gibbs, stoichiometric conversion)
  • Pressure changing equipment (compressors, expanders, pumps)
  • Feed and Product (source / sink) components

In this module, we will import the Flash unit model from idaes.unit_models and create an instance of the flash unit, attaching it to the flowsheet. Each IDAES unit model has several configurable options to customize the model behavior, but also includes defaults for these options. In this example, we will specify that the property package to be used with the Flash is the one we created earlier.

Inline Exercise: Execute the following two cells to import the Flash and create an instance of the unit model, attaching it to the flowsheet object.
In [6]:
from idaes.unit_models import Flash
In [7]:
m.fs.flash = Flash(default={"property_package": m.fs.properties})

At this point, we have created a flowsheet and a properties block. We have also created a flash unit and added it to the flowsheet. Under the hood, IDAES has created the required state variables and model equations. Everything is open. You can see these variables and equations by calling the Pyomo method pprint on the model, flowsheet, or flash tank objects. Note that this output is very exhaustive, and is not intended to provide any summary information about the model, but rather a complete picture of all of the variables and equations in the model.

Set Operating Conditions

Now that we have created our unit model, we can specify the necessary operating conditions. It is often very useful to determine the degrees of freedom before we specify any conditions.

The idaes.ui.report package has a function degrees_of_freedom. To see how to use this function, we can make use of the Python function help(func). This function prints the appropriate documentation string for the function.

Inline Exercise: Import the degrees_of_freedom function and print the help for the function by calling the Python help function.
In [8]:
# Todo: import the degrees_of_freedom function from the idaes.ui.report package
from idaes.ui.report import degrees_of_freedom

# Todo: Call the python help on the degrees_of_freedom function
help(degrees_of_freedom)
Help on function degrees_of_freedom in module idaes.ui.report:

degrees_of_freedom(blk)
    Return the degrees of freedom.

Inline Exercise: Now print the degrees of freedom for your model. The result should be 7.
In [9]:
# Todo: print the degrees of freedom for your model
print("Degrees of Freedom =", degrees_of_freedom(m))
Degrees of Freedom = 7

To satisfy our degrees of freedom, we will first specify the inlet conditions. We can specify these values through the inlet port of the flash unit.

To see the list of naming conventions for variables within the IDAES framework, consult the online documentation at: https://idaes-pse.readthedocs.io/en/latest/standards.html#standard-naming-format

As an example, to fix the molar flow of the inlet to be 1.0, you can use the following notation:

m.fs.flash.inlet.flow_mol.fix(1.0)

To specify variables that are indexed by components, you can use the following notation:

m.fs.flash.inlet.mole_frac[0, "benzene"].fix(0.5)
Note: The "0" in the indexing of the component mole fraction is present because IDAES models support both dynamic and steady state simulation, and the "0" refers to a timestep. Dynamic modeling is beyond the scope of this workshop. Since we are performing steady state modeling, there is only a single timestep in the model.

In the next cell, we will specify the inlet conditions. To satisfy the remaining degrees of freedom, we will make two additional specifications on the flash tank itself. The names of the key variables within the Flash unit model can also be found in the online documentation: https://idaes-pse.readthedocs.io/en/latest/models/flash.html#variables.

To specify the value of a variable on the unit itself, use the following notation.

m.fs.flash.heat_duty.fix(0)

For this module, we will use the following specifications:

  • inlet overall molar flow = 1.0 (flow_mol)
  • inlet temperature = 368 K (temperature)
  • inlet pressure = 101325 Pa (pressure)
  • inlet mole fraction (benzene) = 0.5 (mole_frac[0, "benzene"])
  • inlet mole fraction (toluene) = 0.5 (mole_frac[0, "toluene"])
  • The heat duty on the flash set to zero (heat_duty)
  • The pressure drop across the flash tank set to 0 (deltaP)
Inline Exercise: Write the code below to specify the inlet conditions and unit specifications described above
In [10]:
# Inlet specifications given above
m.fs.flash.inlet.flow_mol.fix(1)
m.fs.flash.inlet.temperature.fix(368)
m.fs.flash.inlet.pressure.fix(101325)
m.fs.flash.inlet.mole_frac[0, "benzene"].fix(0.5)
m.fs.flash.inlet.mole_frac[0, "toluene"].fix(0.5)

# Todo: add code for the 2 flash unit specifications given above
m.fs.flash.heat_duty.fix(0)
m.fs.flash.deltaP.fix(0)
Inline Exercise: Check the degrees of freedom again to ensure that the system is now square. You should see that the degrees of freedom is now 0.
In [11]:
# Todo: print the degrees of freedom for your model
print("Degrees of Freedom =", degrees_of_freedom(m))
Degrees of Freedom = 0

Initializing the Model

IDAES includes pre-written initialization routines for all unit models. You can call this initialize method on the units. In the next module, we will demonstrate the use of a sequential modular solve cycle to initialize flowsheets.

Inline Exercise: Call the initialize method on the flash unit to initialize the model.
In [12]:
# Todo: initialize the flash unit
m.fs.flash.initialize()

Now that the model has been defined and intialized, we can solve the model.

Inline Exercise: Using the notation described in the previous model, create an instance of the "ipopt" solver and use it to solve the model. Set the tee option to True to see the log output.
In [13]:
# Todo: create the ipopt solver
solver = SolverFactory('ipopt')

# Todo: solve the model
status = solver.solve(m, tee=True)
Ipopt 3.12.12: 

******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
 Ipopt is released as open source code under the Eclipse Public License (EPL).
         For more information visit http://projects.coin-or.org/Ipopt
******************************************************************************

This is Ipopt version 3.12.12, running with linear solver mumps.
NOTE: Other linear solvers might be more efficient (see Ipopt documentation).

Number of nonzeros in equality constraint Jacobian...:      139
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       53

Total number of variables............................:       43
                     variables with only lower bounds:        3
                variables with lower and upper bounds:       10
                     variables with only upper bounds:        0
Total number of equality constraints.................:       43
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  0.0000000e+00 7.45e-09 1.00e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0

Number of Iterations....: 0

                                   (scaled)                 (unscaled)
Objective...............:   0.0000000000000000e+00    0.0000000000000000e+00
Dual infeasibility......:   0.0000000000000000e+00    0.0000000000000000e+00
Constraint violation....:   4.8319287785642854e-12    7.4505805969238281e-09
Complementarity.........:   0.0000000000000000e+00    0.0000000000000000e+00
Overall NLP error.......:   4.8319287785642854e-12    7.4505805969238281e-09


Number of objective function evaluations             = 1
Number of objective gradient evaluations             = 1
Number of equality constraint evaluations            = 1
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 1
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 0
Total CPU secs in IPOPT (w/o function evaluations)   =      0.008
Total CPU secs in NLP function evaluations           =      0.000

EXIT: Optimal Solution Found.

Viewing the Results

Once a model is solved, the values returned by the solver are loaded into the model object itself. We can access the value of any variable in the model with the value function. For example:

print('Vap. Outlet Temperature = ', print(value(m.fs.flash.vap_outlet.temperature[0])))

You can also find more information about a variable or an entire port using the display method from Pyomo:

m.fs.flash.vap_outlet.temperature.display()
m.fs.flash.vap_outlet.display()
Inline Exercise: Execute the cells below to show the current value of the flash vapor outlet pressure. This cell also shows use of the display function to see the values of the variables in the vap_outlet and the liq_outlet.
In [14]:
# Print the pressure of the flash vapor outlet
print('Pressure =', value(m.fs.flash.vap_outlet.pressure[0]))

print()
print('Output from display:')
# Call display on vap_outlet and liq_outlet of the flash
m.fs.flash.vap_outlet.display()
m.fs.flash.liq_outlet.display()
Pressure = 101325.0

Output from display:
vap_outlet : Size=1
    Key  : Name        : Value
    None :    flow_mol : {0.0: 0.3546244301390874}
         :   mole_frac : {(0.0, 'benzene'): 0.6429364285519159, (0.0, 'toluene'): 0.35706357144808404}
         :    pressure : {0.0: 101325.0}
         : temperature : {0.0: 368.0}
liq_outlet : Size=1
    Key  : Name        : Value
    None :    flow_mol : {0.0: 0.6453755698609127}
         :   mole_frac : {(0.0, 'benzene'): 0.4214585244801508, (0.0, 'toluene'): 0.5785414755198491}
         :    pressure : {0.0: 101325.0}
         : temperature : {0.0: 368.0}

The output from display is quite exhaustive and not really intended to provide quick summary information. Because Pyomo is built on Python, there are opportunities to format the output any way we like. The IDAES team is working on several potential solutions for effective viewing of model results.

To help with this workshop, we created a short module called workshoptools that contains a few helpful functions. Here, we will import the print_ports_summary function from the workshoptools module and use it to view our results.

Inline Exercise: Execute the cell below which uses the function above to print a summary of the key variables in the inlet, the vapor, and the liquid ports of the flash.
In [15]:
from workshoptools import print_ports_summary
print_ports_summary([m.fs.flash.inlet, m.fs.flash.vap_outlet, m.fs.flash.liq_outlet])
                   Variable	fs.flash.inlet	fs.flash.vap_outlet	fs.flash.liq_outlet	
---------------------------	--------------	-------------------	-------------------	
              flow_mol[0.0]	      1.000000	           0.354624	           0.645376	
mole_frac[(0.0, 'benzene')]	      0.500000	           0.642936	           0.421459	
mole_frac[(0.0, 'toluene')]	      0.500000	           0.357064	           0.578541	
           temperature[0.0]	    368.000000	         368.000000	         368.000000	
              pressure[0.0]	 101325.000000	      101325.000000	      101325.000000	

Studying Purity as a Function of Heat Duty

Since the entire modeling framework is built upon Python, it includes a complete programming environment for whatever analysis we may want to perform. In this next exercise, we will make use of what we learned in this and the previous module to generate a figure showing some output variables as a function of the heat duty in the flash tank.

First, let's import the matplotlib package for plotting as we did in the previous module.

Inline Exercise: Execute the cell below to import matplotlib appropriately.
In [16]:
import matplotlib.pyplot as plt

Exercise specifications:

  • Generate a figure showing the flash tank heat duty (m.fs.flash.heat_duty[0]) vs. the vapor flowrate (m.fs.flash.vap_outlet.mol_flow[0])
  • Specify the heat duty from -17000 to 25000 over 20 steps
Inline Exercise: Using what you have learned so far, fill in the missing code below to generate the figure specified above. (Hint: import numpy and use the linspace function from the previous module)
In [17]:
# import the solve_successful checking function from workshop tools
from workshoptools import solve_successful

# Todo: import numpy
import numpy as np

# create the empty lists to store the results that will be plotted
Q = []
V = []

# create the solver
solver = SolverFactory('ipopt')

# Todo: Write the for loop specification using numpy's linspace
for duty in np.linspace(-17000, 25000, 20):
    # fix the heat duty
    m.fs.flash.heat_duty.fix(duty)
    
    # append the value of the duty to the Q list
    Q.append(duty)
    
    # print the current simulation
    print("Simulating with Q = ", value(m.fs.flash.heat_duty[0]))

    # Solve the model
    status = solver.solve(m)
    
    # append the value for vapor fraction if the solve was successful
    if solve_successful(status):
        V.append(value(m.fs.flash.vap_outlet.flow_mol[0]))
        print('... solve successful.')
    else:
        V.append(0.0)
        print('... solve failed.')
    
# Create and show the figure
plt.figure("Vapor Fraction")
plt.plot(Q, V)
plt.grid()
plt.xlabel("Heat Duty [J]")
plt.ylabel("Vapor Fraction [-]")
plt.show()
Simulating with Q =  -17000.0
... solve successful.
Simulating with Q =  -14789.473684210527
... solve successful.
Simulating with Q =  -12578.947368421053
... solve successful.
Simulating with Q =  -10368.421052631578
... solve successful.
Simulating with Q =  -8157.894736842105
... solve successful.
Simulating with Q =  -5947.368421052632
... solve successful.
Simulating with Q =  -3736.8421052631566
... solve successful.
Simulating with Q =  -1526.3157894736833
... solve successful.
Simulating with Q =  684.21052631579
... solve successful.
Simulating with Q =  2894.7368421052633
... solve successful.
Simulating with Q =  5105.263157894737
... solve successful.
Simulating with Q =  7315.78947368421
... solve successful.
Simulating with Q =  9526.315789473687
... solve successful.
Simulating with Q =  11736.84210526316
... solve successful.
Simulating with Q =  13947.368421052633
... solve successful.
Simulating with Q =  16157.894736842107
... solve successful.
Simulating with Q =  18368.42105263158
... solve successful.
Simulating with Q =  20578.947368421053
... solve successful.
Simulating with Q =  22789.473684210527
... solve successful.
Simulating with Q =  25000.0
... solve successful.
Inline Exercise: Repeate the exercise above, but create a figure showing the heat duty vs. the mole fraction of Benzene in the vapor outlet. Remove any unnecessary printing to create cleaner results.
In [18]:
# Todo: generate a figure of heat duty vs. mole fraction of Benzene in the vapor
Q = []
V = []

for duty in np.linspace(-17000, 25000, 20):
    # fix the heat duty
    m.fs.flash.heat_duty.fix(duty)
    
    # append the value of the duty to the Q list
    Q.append(duty)
    
    # solve the model
    status = solver.solve(m)
    
    # append the value for vapor fraction if the solve was successful
    if solve_successful(status):
        V.append(value(m.fs.flash.vap_outlet.mole_frac[0, "benzene"]))
    else:
        V.append(0.0)
        print('... solve failed.')
    
plt.figure("Purity")
plt.plot(Q, V)
plt.grid()
plt.xlabel("Heat Duty [J]")
plt.ylabel("Vapor Benzene Mole Fraction [-]")
plt.show()

Recall that the IDAES framework is an equation-oriented modeling environment. This means that we can specify "design" problems natively. That is, there is no need to have our specifications on the inlet alone. We can put specifications on the outlet as long as we retain a well-posed, square system of equations.

For example, we can remove the specification on heat duty and instead specify that we want the mole fraction of Benzene in the vapor outlet to be equal to 0.6. The mole fraction is not a native variable in the property block, so we cannot use "fix". We can, however, add a constraint to the model.

Note that we have been executing a number of solves on the problem, and may not be sure of the current state. To help convergence, therefore, we will first call initialize, then add the new constraint and solve the problem. Note that the reference for the mole fraction of Benzene in the vapor outlet is m.fs.flash.vap_outlet.mole_frac[0, "benzene"].

Inline Exercise: Fill in the missing code below and add a constraint on the mole fraction of Benzene (to a value of 0.6) to find the required heat duty.
In [19]:
# unfix the heat duty
m.fs.flash.heat_duty.unfix()

# re-initialize the model - this may or may not be required depending on current state
m.fs.flash.initialize()

# Todo: Add a new constraint (benzene mole fraction to 0.6)
m.benz_purity_con = Constraint(expr= m.fs.flash.vap_outlet.mole_frac[0, "benzene"] == 0.6)

# solve the problem
status = solver.solve(m, tee=True)

# print the value of the heat duty
print('Q =', value(m.fs.flash.heat_duty[0]))
Ipopt 3.12.12: 

******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
 Ipopt is released as open source code under the Eclipse Public License (EPL).
         For more information visit http://projects.coin-or.org/Ipopt
******************************************************************************

This is Ipopt version 3.12.12, running with linear solver mumps.
NOTE: Other linear solvers might be more efficient (see Ipopt documentation).

Number of nonzeros in equality constraint Jacobian...:      141
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:       53

Total number of variables............................:       44
                     variables with only lower bounds:        3
                variables with lower and upper bounds:       10
                     variables with only upper bounds:        0
Total number of equality constraints.................:       44
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  0.0000000e+00 6.88e-03 1.00e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  0.0000000e+00 5.39e-02 1.03e-02  -1.0 1.02e+03    -  9.90e-01 1.00e+00H  1
   2  0.0000000e+00 5.53e-10 2.30e-04  -1.0 2.01e-01    -  9.90e-01 1.00e+00h  1

Number of Iterations....: 2

                                   (scaled)                 (unscaled)
Objective...............:   0.0000000000000000e+00    0.0000000000000000e+00
Dual infeasibility......:   0.0000000000000000e+00    0.0000000000000000e+00
Constraint violation....:   3.5152540356996045e-12    5.5297277867794037e-10
Complementarity.........:   0.0000000000000000e+00    0.0000000000000000e+00
Overall NLP error.......:   3.5152540356996045e-12    5.5297277867794037e-10


Number of objective function evaluations             = 4
Number of objective gradient evaluations             = 3
Number of equality constraint evaluations            = 4
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 3
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 2
Total CPU secs in IPOPT (w/o function evaluations)   =      0.017
Total CPU secs in NLP function evaluations           =      0.001

EXIT: Optimal Solution Found.
Q = 6455.280946055264
In [ ]:
 

Module 2 Flowsheet Solution:

Module_2_Flowsheet_Solution

Learning outcomes

  • Construct a steady-state flowsheet using the IDAES unit model library
  • Connecting unit models in a flowsheet using Arcs
  • Using the SequentialDecomposition tool to initialize a flowsheet with recycle
  • Fomulate and solve an optimization problem
    • Defining an objective function
    • Setting variable bounds
    • Adding additional constraints

Problem Statement

Hydrodealkylation is a chemical reaction that often involves reacting an aromatic hydrocarbon in the presence of hydrogen gas to form a simpler aromatic hydrocarbon devoid of functional groups,. In this example, toluene will be reacted with hydrogen gas at high temperatures to form benzene via the following reaction:

C6H5CH3 + H2 → C6H6 + CH4

This reaction is often accompanied by an equilibrium side reaction which forms diphenyl, which we will neglect for this example.

This example is based on the 1967 AIChE Student Contest problem as present by Douglas, J.M., Chemical Design of Chemical Processes, 1988, McGraw-Hill.

The flowsheet that we will be using for this module is shown below with the stream conditions. We will be processing toluene and hydrogen to produce at least 370 TPY of benzene. As shown in the flowsheet, there are two flash tanks, F101 to separate out the non-condensibles and F102 to further separate the benzene-toluene mixture to improve the benzene purity. Note that typically a distillation column is required to obtain high purity benzene but that is beyond the scope of this workshop. The non-condensibles separated out in F101 will be partially recycled back to M101 and the rest will be either purged or combusted for power generation.We will assume ideal gas for this flowsheet. The properties required for this module is available in the same directory:

  • hda_ideal_VLE.py
  • hda_reaction.py

The state variables chosen for the property package are flows of component by phase, temperature and pressure. The components considered are: toluene, hydrogen, benzene and methane. Therefore, every stream has 8 flow variables, 1 temperature and 1 pressure variable.

Importing required pyomo and idaes components

To construct a flowsheet, we will need several components from the pyomo and idaes package. Let us first import the following components from Pyomo:

  • Constraint (to write constraints)
  • Var (to declare variables)
  • ConcreteModel (to create the concrete model object)
  • Expression (to evaluate values as a function of variables defined in the model)
  • Objective (to define an objective function for optimization)
  • SolverFactory (to solve the problem)
  • TransformationFactory (to apply certain transformations)
  • Arc (to connect two unit models)
  • SequentialDecomposition (to initialize the flowsheet in a sequential mode)

For further details on these components, please refer to the pyomo documentation: https://pyomo.readthedocs.io/en/latest/

In [1]:
from pyomo.environ import (Constraint,
                           Var,
                           ConcreteModel,
                           Expression,
                           Objective,
                           SolverFactory,
                           TransformationFactory,
                           value)
from pyomo.network import Arc, SequentialDecomposition

From idaes, we will be needing the FlowsheetBlock and the following unit models:

  • Mixer
  • Heater
  • StoichiometricReactor
  • **Flash**
  • Separator (splitter)
  • PressureChanger
In [2]:
from idaes.core import FlowsheetBlock
In [3]:
from idaes.unit_models import (PressureChanger,
                               Mixer,
                               Separator as Splitter,
                               Heater,
                               StoichiometricReactor)
Inline Exercise: Now, import the remaining unit models highlighted in blue above and run the cell using `Shift+Enter` after typing in the code.
In [4]:
from idaes.unit_models import Flash

We will also be needing some utility tools to put together the flowsheet and calculate the degrees of freedom.

In [5]:
from idaes.unit_models.pressure_changer import ThermodynamicAssumption
from idaes.ui.report import degrees_of_freedom

Importing required thermo and reaction package

The final set of imports are to import the thermo and reaction package for the HDA process. We have created a custom thermo package that assumes Ideal Gas with support for VLE.

The reaction package here is very simple as we will be using only a StochiometricReactor and the reaction package consists the stochiometric coefficients for the reaction and the parameter for the heat of reaction.

Let us import the following modules and they are in the same directory as this jupyter notebook:

  • hda_ideal_VLE as thermo_props
  • hda_reaction as reaction_props
</div>
In [6]:
import hda_ideal_VLE as thermo_props
import hda_reaction as reaction_props

Constructing the Flowsheet

We have now imported all the components, unit models, and property modules we need to construct a flowsheet. Let us create a ConcreteModel and add the flowsheet block as we did in module 1.

In [7]:
m = ConcreteModel()
m.fs = FlowsheetBlock(default={"dynamic": False})

We now need to add the property packages to the flowsheet. Unlike Module 1, where we only had a thermo property package, for this flowsheet we will also need to add a reaction property package.

In [8]:
m.fs.thermo_params = thermo_props.HDAParameterBlock()
m.fs.reaction_params = reaction_props.HDAReactionParameterBlock(
        default={"property_package": m.fs.thermo_params})

Adding Unit Models

Let us start adding the unit models we have imported to the flowsheet. Here, we are adding the Mixer (assigned a name M101) and a Heater (assigned a name H101). Note that, all unit models need to be given a property package argument. In addition to that, there are several arguments depending on the unit model, please refer to the documentation for more details (https://idaes-pse.readthedocs.io/en/latest/models/index.html). For example, the Mixer unit model here is given a list consisting of names to the three inlets.

In [9]:
m.fs.M101 = Mixer(default={"property_package": m.fs.thermo_params,
                           "inlet_list": ["toluene_feed", "hydrogen_feed", "vapor_recycle"]})

m.fs.H101 = Heater(default={"property_package": m.fs.thermo_params,
                            "has_pressure_change": False,
                            "has_phase_equilibrium": True})
Inline Exercise: Let us now add the StoichiometricReactor(assign the name R101) and pass the following arguments:
  • "property_package": m.fs.thermo_params
  • "reaction_package": m.fs.reaction_params
  • "has_heat_of_reaction": True
  • "has_heat_transfer": True
  • "has_pressure_change": False
In [10]:
m.fs.R101 = StoichiometricReactor(
            default={"property_package": m.fs.thermo_params,
                     "reaction_package": m.fs.reaction_params,
                     "has_heat_of_reaction": True,
                     "has_heat_transfer": True,
                     "has_pressure_change": False})

Let us now add the Flash(assign the name F101) and pass the following arguments:

  • "property_package": m.fs.thermo_params
  • "has_heat_transfer": True
  • "has_pressure_change": False
In [11]:
m.fs.F101 = Flash(default={"property_package": m.fs.thermo_params,
                               "has_heat_transfer": True,
                               "has_pressure_change": True})

Let us now add the Splitter(S101), PressureChanger(C101) and the second Flash(F102).

In [12]:
m.fs.S101 = Splitter(default={"property_package": m.fs.thermo_params,
                               "ideal_separation": False,
                               "outlet_list": ["purge", "recycle"]})
    

m.fs.C101 = PressureChanger(default={
            "property_package": m.fs.thermo_params,
            "compressor": True,
            "thermodynamic_assumption": ThermodynamicAssumption.isothermal})
    
m.fs.F102 = Flash(default={"property_package": m.fs.thermo_params,
                           "has_heat_transfer": True,
                           "has_pressure_change": True})

Connecting Unit Models using Arcs

We have now added all the unit models we need to the flowsheet. However, we have not yet specifed how the units are to be connected. To do this, we will be using the Arc which is a pyomo component that takes in two arguments: source and destination. Let us connect the outlet of the mixer(M101) to the inlet of the heater(H101).

In [13]:
m.fs.s03 = Arc(source=m.fs.M101.outlet, destination=m.fs.H101.inlet)

Inline Exercise: Now, connect the H101 outlet to the R101 inlet using the cell above as a guide.
In [14]:
m.fs.s04 = Arc(source=m.fs.H101.outlet, destination=m.fs.R101.inlet)

We will now be connecting the rest of the flowsheet as shown below. Notice how the outlet names are different for the flash tanks F101 and F102 as they have a vapor and a liquid outlet.

In [15]:
m.fs.s05 = Arc(source=m.fs.R101.outlet, destination=m.fs.F101.inlet)
m.fs.s06 = Arc(source=m.fs.F101.vap_outlet, destination=m.fs.S101.inlet)
m.fs.s08 = Arc(source=m.fs.S101.recycle, destination=m.fs.C101.inlet)
m.fs.s09 = Arc(source=m.fs.C101.outlet,
               destination=m.fs.M101.vapor_recycle)
m.fs.s10 = Arc(source=m.fs.F101.liq_outlet, destination=m.fs.F102.inlet)

We have now connected the unit model block using the arcs. However, each of these arcs link to ports on the two unit models that are connected. In this case, the ports consist of the state variables that need to be linked between the unit models. Pyomo provides a convenient method to write these equality constraints for us between two ports and this is done as follows:

In [16]:
TransformationFactory("network.expand_arcs").apply_to(m)

Adding expressions to compute purity and operating costs

In this section, we will add a few Expressions that allows us to evaluate the performance. Expressions provide a convenient way of calculating certain values that are a function of the variables defined in the model. For more details on Expressions, please refer to: https://pyomo.readthedocs.io/en/latest/pyomo_modeling_components/Expressions.html

For this flowsheet, we are interested in computing the purity of the product Benzene stream (i.e. the mole fraction) and the operating cost which is a sum of the cooling and heating cost.

Let us first add an Expression to compute the mole fraction of benzene in the vap_outlet of F102 which is our product stream. Please note that the var flow_mol_phase_comp has the index - [time, phase, component]. As this is a steady-state flowsheet, the time index by default is 0. The valid phases are ["Liq", "Vap"]. Similarly the valid component list is ["benzene", "toluene", "hydrogen", "methane"].

In [17]:
m.fs.purity = Expression(
        expr=m.fs.F102.vap_outlet.flow_mol_phase_comp[0, "Vap", "benzene"] /
        (m.fs.F102.vap_outlet.flow_mol_phase_comp[0, "Vap", "benzene"]
         + m.fs.F102.vap_outlet.flow_mol_phase_comp[0, "Vap", "toluene"]))

Now, let us add an expression to compute the cooling cost assuming a cost of 0.212E-4 $/kW. Note that cooling utility is required for the reactor (R101) and the first flash (F101).

In [18]:
m.fs.cooling_cost = Expression(expr=0.212e-7 * (-m.fs.F101.heat_duty[0]) +
                                   0.212e-7 * (-m.fs.R101.heat_duty[0]))

Now, let us add an expression to compute the heating cost assuming the utility cost as follows:

  • 2.2E-4 dollars/kW for H101
  • 1.9E-4 dollars/kW for F102
Note that the heat duty is in units of watt (J/s).
In [19]:
m.fs.heating_cost = Expression(expr=2.2e-7 * m.fs.H101.heat_duty[0] +
                                   1.9e-7 * m.fs.F102.heat_duty[0])

Let us now add an expression to compute the total operating cost per year which is basically the sum of the cooling and heating cost we defined above.

In [20]:
m.fs.operating_cost = Expression(expr=(3600 * 24 * 365 *
                                           (m.fs.heating_cost +
                                            m.fs.cooling_cost)))

Fixing feed conditions

Let us first check how many degrees of freedom exist for this flowsheet using the degrees_of_freedom tool we imported earlier.

In [21]:
print(degrees_of_freedom(m))
29

We will now be fixing the toluene feed stream to the conditions shown in the flowsheet above. Please note that though this is a pure toluene feed, the remaining components are still assigned a very small non-zero value to help with convergence and initializing.

In [22]:
m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Vap", "benzene"].fix(1e-5)
m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Vap", "toluene"].fix(1e-5)
m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Vap", "hydrogen"].fix(1e-5)
m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Vap", "methane"].fix(1e-5)
m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Liq", "benzene"].fix(1e-5)
m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Liq", "toluene"].fix(0.30)
m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Liq", "hydrogen"].fix(1e-5)
m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Liq", "methane"].fix(1e-5)
m.fs.M101.toluene_feed.temperature.fix(303.2)
m.fs.M101.toluene_feed.pressure.fix(350000)

Similarly, let us fix the hydrogen feed to the following conditions in the next cell:

  • FH2 = 0.30 mol/s
  • FCH4 = 0.02 mol/s
  • Remaining components = 1e-5 mol/s
  • T = 303.2 K
  • P = 350000 Pa
In [23]:
m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Vap", "benzene"].fix(1e-5)
m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Vap", "toluene"].fix(1e-5)
m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Vap", "hydrogen"].fix(0.30)
m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Vap", "methane"].fix(0.02)
m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Liq", "benzene"].fix(1e-5)
m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Liq", "toluene"].fix(1e-5)
m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Liq", "hydrogen"].fix(1e-5)
m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Liq", "methane"].fix(1e-5)
m.fs.M101.hydrogen_feed.temperature.fix(303.2)
m.fs.M101.hydrogen_feed.pressure.fix(350000)

Fixing unit model specifications

Now that we have fixed our inlet feed conditions, we will now be fixing the operating conditions for the unit models in the flowsheet. Let us set set the H101 outlet temperature to 600 K.

In [24]:
m.fs.H101.outlet.temperature.fix(600)

For the StoichiometricReactor, we have to define the conversion in terms of toluene. This requires us to create a new variable for specifying the conversion and adding a Constraint that defines the conversion with respect to toluene. The second degree of freedom for the reactor is to define the heat duty. In this case, let us assume the reactor to be adiabatic i.e. Q = 0.

In [25]:
m.fs.R101.conversion = Var(initialize=0.75, bounds=(0, 1))

m.fs.R101.conv_constraint = Constraint(
    expr=m.fs.R101.conversion*m.fs.R101.inlet.
    flow_mol_phase_comp[0, "Vap", "toluene"] ==
    (m.fs.R101.inlet.flow_mol_phase_comp[0, "Vap", "toluene"] -
     m.fs.R101.outlet.flow_mol_phase_comp[0, "Vap", "toluene"]))

m.fs.R101.conversion.fix(0.75)
m.fs.R101.heat_duty.fix(0)

The Flash conditions for F101 can be set as follows.

In [26]:
m.fs.F101.vap_outlet.temperature.fix(325.0)
m.fs.F101.deltaP.fix(0)
Inline Exercise: Set the conditions for Flash F102 to the following conditions:
  • T = 375 K
  • deltaP = -200000
Use Shift+Enter to run the cell once you have typed in your code.
In [27]:
m.fs.F102.vap_outlet.temperature.fix(375)
m.fs.F102.deltaP.fix(-200000)

Let us fix the purge split fraction to 20% and the outlet pressure of the compressor is set to 350000 Pa.

In [28]:
m.fs.S101.split_fraction[0, "purge"].fix(0.2)
m.fs.C101.outlet.pressure.fix(350000)
Inline Exercise: We have now defined all the feed conditions and the inputs required for the unit models. The system should now have 0 degrees of freedom i.e. should be a square problem. Please check that the degrees of freedom is 0. Use Shift+Enter to run the cell once you have typed in your code.
In [29]:
print(degrees_of_freedom(m))
0

Initialization

This section will demonstrate how to use the built-in sequential decomposition tool to initialize our flowsheet.

Let us first create an object for the SequentialDecomposition and specify our options for this.

In [30]:
seq = SequentialDecomposition()
seq.options.select_tear_method = "heuristic"
seq.options.tear_method = "Wegstein"
seq.options.iterLim = 5

# Using the SD tool
G = seq.create_graph(m)
heuristic_tear_set = seq.tear_set_arcs(G, method="heuristic")
order = seq.calculation_order(G)

Which is the tear stream? Display tear set and order

In [31]:
for o in heuristic_tear_set:
    print(o.name)
fs.s03

What sequence did the SD tool determine to solve this flowsheet with the least number of tears?

In [32]:
for o in order:
    print(o[0].name)
fs.H101
fs.R101
fs.F101
fs.S101
fs.C101
fs.M101

The SequentialDecomposition tool has determined that the tear stream is the mixer outlet. We will need to provide a reasonable guess for this.

In [33]:
tear_guesses = {
        "flow_mol_phase_comp": {
                (0, "Vap", "benzene"): 1e-5,
                (0, "Vap", "toluene"): 1e-5,
                (0, "Vap", "hydrogen"): 0.30,
                (0, "Vap", "methane"): 0.02,
                (0, "Liq", "benzene"): 1e-5,
                (0, "Liq", "toluene"): 0.30,
                (0, "Liq", "hydrogen"): 1e-5,
                (0, "Liq", "methane"): 1e-5},
        "temperature": {0: 303},
        "pressure": {0: 350000}}

# Pass the tear_guess to the SD tool
seq.set_guesses_for(m.fs.H101.inlet, tear_guesses)

Next, we need to tell the tool how to initialize a particular unit. We will be writing a python function which takes in a "unit" and calls the initialize method on that unit.

In [34]:
def function(unit):
        unit.initialize(outlvl=1)

We are now ready to initialize our flowsheet in a sequential mode. Note that we specifically set the iteration limit to be 5 as we are trying to use this tool only to get a good set of initial values such that IPOPT can then take over and solve this flowsheet for us.

In [35]:
seq.run(m, function)
2019-05-22 16:38:46 - INFO - idaes.core.unit_model - fs.H101 Initialisation Step 1 Complete.
2019-05-22 16:38:46 - INFO - idaes.core.unit_model - fs.H101 Initialisation Step 2 Complete.
2019-05-22 16:38:46 - INFO - idaes.core.unit_model - fs.H101 Initialisation Complete.
2019-05-22 16:38:46 - INFO - idaes.core.unit_model - fs.R101 Initialisation Step 1 Complete.
2019-05-22 16:38:46 - INFO - idaes.core.unit_model - fs.R101 Initialisation Step 2 Complete.
2019-05-22 16:38:46 - INFO - idaes.core.unit_model - fs.R101 Initialisation Complete.
2019-05-22 16:38:46 - INFO - idaes.core.unit_model - fs.F101 Initialisation Step 1 Complete.
2019-05-22 16:38:46 - INFO - idaes.core.unit_model - fs.F101 Initialisation Step 2 Complete.
2019-05-22 16:38:46 - INFO - idaes.core.unit_model - fs.F101 Initialisation Complete.
2019-05-22 16:38:46 - INFO - idaes.unit_models.separator - fs.S101 Initialisation Complete.
2019-05-22 16:38:46 - INFO - idaes.core.unit_model - fs.F102 Initialisation Step 1 Complete.
2019-05-22 16:38:46 - INFO - idaes.core.unit_model - fs.F102 Initialisation Step 2 Complete.
2019-05-22 16:38:46 - INFO - idaes.core.unit_model - fs.F102 Initialisation Complete.
2019-05-22 16:38:46 - INFO - idaes.core.unit_model - fs.C101 Initialisation Step 1 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.C101 Initialisation Step 2 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.C101 Initialisation Complete.
2019-05-22 16:38:47 - INFO - idaes.unit_models.mixer - fs.M101 Initialisation Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.H101 Initialisation Step 1 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.H101 Initialisation Step 2 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.H101 Initialisation Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.R101 Initialisation Step 1 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.R101 Initialisation Step 2 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.R101 Initialisation Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.F101 Initialisation Step 1 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.F101 Initialisation Step 2 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.F101 Initialisation Complete.
2019-05-22 16:38:47 - INFO - idaes.unit_models.separator - fs.S101 Initialisation Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.C101 Initialisation Step 1 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.C101 Initialisation Step 2 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.C101 Initialisation Complete.
2019-05-22 16:38:47 - INFO - idaes.unit_models.mixer - fs.M101 Initialisation Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.H101 Initialisation Step 1 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.H101 Initialisation Step 2 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.H101 Initialisation Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.R101 Initialisation Step 1 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.R101 Initialisation Step 2 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.R101 Initialisation Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.F101 Initialisation Step 1 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.F101 Initialisation Step 2 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.F101 Initialisation Complete.
2019-05-22 16:38:47 - INFO - idaes.unit_models.separator - fs.S101 Initialisation Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.C101 Initialisation Step 1 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.C101 Initialisation Step 2 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.C101 Initialisation Complete.
2019-05-22 16:38:47 - INFO - idaes.unit_models.mixer - fs.M101 Initialisation Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.H101 Initialisation Step 1 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.H101 Initialisation Step 2 Complete.
2019-05-22 16:38:47 - INFO - idaes.core.unit_model - fs.H101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.R101 Initialisation Step 1 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.R101 Initialisation Step 2 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.R101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.F101 Initialisation Step 1 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.F101 Initialisation Step 2 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.F101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.unit_models.separator - fs.S101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.C101 Initialisation Step 1 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.C101 Initialisation Step 2 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.C101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.unit_models.mixer - fs.M101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.H101 Initialisation Step 1 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.H101 Initialisation Step 2 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.H101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.R101 Initialisation Step 1 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.R101 Initialisation Step 2 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.R101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.F101 Initialisation Step 1 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.F101 Initialisation Step 2 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.F101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.unit_models.separator - fs.S101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.C101 Initialisation Step 1 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.C101 Initialisation Step 2 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.C101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.unit_models.mixer - fs.M101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.H101 Initialisation Step 1 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.H101 Initialisation Step 2 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.H101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.R101 Initialisation Step 1 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.R101 Initialisation Step 2 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.R101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.F101 Initialisation Step 1 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.F101 Initialisation Step 2 Complete.
2019-05-22 16:38:48 - INFO - idaes.core.unit_model - fs.F101 Initialisation Complete.
2019-05-22 16:38:48 - INFO - idaes.unit_models.separator - fs.S101 Initialisation Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.C101 Initialisation Step 1 Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.C101 Initialisation Step 2 Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.C101 Initialisation Complete.
2019-05-22 16:38:49 - INFO - idaes.unit_models.mixer - fs.M101 Initialisation Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.H101 Initialisation Step 1 Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.H101 Initialisation Step 2 Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.H101 Initialisation Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.R101 Initialisation Step 1 Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.R101 Initialisation Step 2 Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.R101 Initialisation Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.F101 Initialisation Step 1 Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.F101 Initialisation Step 2 Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.F101 Initialisation Complete.
2019-05-22 16:38:49 - INFO - idaes.unit_models.separator - fs.S101 Initialisation Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.C101 Initialisation Step 1 Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.C101 Initialisation Step 2 Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.C101 Initialisation Complete.
2019-05-22 16:38:49 - INFO - idaes.unit_models.mixer - fs.M101 Initialisation Complete.
WARNING: Wegstein failed to converge in 5 iterations
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.F102 Initialisation Step 1 Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.F102 Initialisation Step 2 Complete.
2019-05-22 16:38:49 - INFO - idaes.core.unit_model - fs.F102 Initialisation Complete.
Inline Exercise: We have now initialized the flowsheet. Let us run the flowsheet in a simulation mode to look at the results. To do this, complete the last line of code where we pass the model to the solver. You will need to type the following: results = solver.solve(m, tee=True) Use Shift+Enter to run the cell once you have typed in your code.
In [36]:
# Create the solver object
solver = SolverFactory('ipopt')
solver.options = {'tol': 1e-6, 'max_iter': 5000}

# Solve the model
results = solver.solve(m, tee=True)
Ipopt 3.12: tol=1e-06
max_iter=5000


******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
 Ipopt is released as open source code under the Eclipse Public License (EPL).
         For more information visit http://projects.coin-or.org/Ipopt
******************************************************************************

This is Ipopt version 3.12, running with linear solver ma27.

Number of nonzeros in equality constraint Jacobian...:     1022
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:      898

Total number of variables............................:      338
                     variables with only lower bounds:        0
                variables with lower and upper bounds:      146
                     variables with only upper bounds:        0
Total number of equality constraints.................:      338
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  0.0000000e+00 6.35e+04 0.00e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  0.0000000e+00 8.71e+03 1.40e+03  -1.0 3.82e+04    -  9.72e-01 4.62e-01H  1
   2  0.0000000e+00 3.05e+03 1.57e+03  -1.0 6.07e+03    -  9.79e-01 4.89e-01h  1
   3  0.0000000e+00 1.59e+03 1.48e+05  -1.0 9.04e+03    -  9.91e-01 4.94e-01h  1
   4  0.0000000e+00 7.62e+02 1.90e+07  -1.0 5.97e+03    -  1.00e+00 5.26e-01h  1
   5  0.0000000e+00 1.35e+02 1.61e+11  -1.0 3.18e+03    -  1.00e+00 9.78e-01h  1
   6  0.0000000e+00 6.48e+01 5.26e+08  -1.0 1.71e+02    -  1.00e+00 5.22e-01h  1
   7  0.0000000e+00 2.53e+00 4.53e+11  -1.0 8.17e+01    -  1.00e+00 9.90e-01h  1
   8  0.0000000e+00 1.44e-01 1.91e+10  -1.0 8.01e-01    -  1.00e+00 1.00e+00h  1
   9  0.0000000e+00 7.58e-08 8.27e+04  -1.0 7.71e-07    -  1.00e+00 1.00e+00f  1
Cannot recompute multipliers for feasibility problem.  Error in eq_mult_calculator

Number of Iterations....: 9

                                   (scaled)                 (unscaled)
Objective...............:   0.0000000000000000e+00    0.0000000000000000e+00
Dual infeasibility......:   1.0837353154983716e+11    1.0837353154983716e+11
Constraint violation....:   2.9103830456733704e-11    7.5779098551720381e-08
Complementarity.........:   0.0000000000000000e+00    0.0000000000000000e+00
Overall NLP error.......:   2.9103830456733704e-11    1.0837353154983716e+11


Number of objective function evaluations             = 11
Number of objective gradient evaluations             = 10
Number of equality constraint evaluations            = 11
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 10
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 9
Total CPU secs in IPOPT (w/o function evaluations)   =      0.007
Total CPU secs in NLP function evaluations           =      0.001

EXIT: Optimal Solution Found.

Analyze the results of the square problem

What is the total operating cost?

In [37]:
print('operating cost = $', value(m.fs.operating_cost))
operating cost = $ 419122.3387677938

For this operating cost, what is the amount of benzene we are able to produce and what purity we are able to achieve?

In [38]:
from workshoptools import print_ports_summary

print_ports_summary([m.fs.F102.vap_outlet])

print()
print('benzene purity = ', value(m.fs.purity))
                                     Variable	fs.F102.vap_outlet	
---------------------------------------------	------------------	
 flow_mol_phase_comp[(0.0, 'Liq', 'benzene')]	          0.000000	
 flow_mol_phase_comp[(0.0, 'Liq', 'toluene')]	          0.000000	
flow_mol_phase_comp[(0.0, 'Liq', 'hydrogen')]	          0.000000	
 flow_mol_phase_comp[(0.0, 'Liq', 'methane')]	          0.000000	
 flow_mol_phase_comp[(0.0, 'Vap', 'benzene')]	          0.141979	
 flow_mol_phase_comp[(0.0, 'Vap', 'toluene')]	          0.030264	
flow_mol_phase_comp[(0.0, 'Vap', 'hydrogen')]	          0.000000	
 flow_mol_phase_comp[(0.0, 'Vap', 'methane')]	          0.000000	
                             temperature[0.0]	        375.000000	
                                pressure[0.0]	     149999.999191	

benzene purity =  0.8242962943918922
Inline Exercise: How much benzene are we loosing in the F101 vapor outlet stream? Use Shift+Enter to run the cell once you have typed in your code.
In [39]:
print_ports_summary([m.fs.R101.outlet, m.fs.F101.vap_outlet])
                                     Variable	fs.R101.outlet	fs.F101.vap_outlet	
---------------------------------------------	--------------	------------------	
 flow_mol_phase_comp[(0.0, 'Liq', 'benzene')]	      0.000000	          0.000000	
 flow_mol_phase_comp[(0.0, 'Liq', 'toluene')]	      0.000001	          0.000000	
flow_mol_phase_comp[(0.0, 'Liq', 'hydrogen')]	      0.000000	          0.000000	
 flow_mol_phase_comp[(0.0, 'Liq', 'methane')]	      0.000000	          0.000000	
 flow_mol_phase_comp[(0.0, 'Vap', 'benzene')]	      0.353744	          0.149145	
 flow_mol_phase_comp[(0.0, 'Vap', 'toluene')]	      0.078129	          0.015610	
flow_mol_phase_comp[(0.0, 'Vap', 'hydrogen')]	      0.328211	          0.328211	
 flow_mol_phase_comp[(0.0, 'Vap', 'methane')]	      1.272087	          1.272087	
                             temperature[0.0]	    771.845857	        325.000000	
                                pressure[0.0]	 349999.999191	     349999.999191	
Inline Exercise: You can querry additional variables here if you like. Use Shift+Enter to run the cell once you have typed in your code.

Optimization

We saw from the results above that the total operating cost for the base case was $419,122 per year. We are producing 0.142 mol/s of benzene at a purity of 82\%. However, we are losing around 42\% of benzene in F101 vapor outlet stream.

Let us try to minimize this cost such that:

  • we are producing at least 0.15 mol/s of benzene in F102 vapor outlet i.e. our product stream
  • purity of benzne i.e. the mole fraction of benzene in F102 vapor outlet is at least 80%
  • restricting the benzene loss in F101 vapor outlet to less than 20%

For this problem, our decision variables are as follows:

  • H101 outlet temperature
  • R101 cooling duty provided
  • F101 outlet temperature
  • F102 outlet temperature
  • F102 deltaP in the flash tank

Let us declare our objective function for this problem.

In [40]:
m.fs.objective = Objective(expr=m.fs.operating_cost)

Now, we need to unfix the decision variables as we had solved a square problem (degrees of freedom = 0) until now.

In [41]:
m.fs.H101.outlet.temperature.unfix()
m.fs.R101.heat_duty.unfix()
m.fs.F101.vap_outlet.temperature.unfix()
m.fs.F102.vap_outlet.temperature.unfix()
Inline Exercise: Let us now unfix the remaining variable which is F102 pressure drop (F102.deltaP) Use Shift+Enter to run the cell once you have typed in your code.
In [42]:
m.fs.F102.deltaP.unfix()

Next, we need to set bounds on these decision variables to values shown below:

  • H101 outlet temperature [500, 600] K
  • R101 outlet temperature [600, 800] K
  • F101 outlet temperature [298, 450] K
  • F102 outlet temperature [298, 450] K
  • F102 outlet pressure [105000, 110000] Pa

Let us first set the variable bound for the H101 outlet temperature as shown below:

In [43]:
m.fs.H101.outlet.temperature[0].setlb(500)
m.fs.H101.outlet.temperature[0].setub(600)
Inline Exercise: Now, set the variable bound for the R101 outlet temperature. Use Shift+Enter to run the cell once you have typed in your code.
In [44]:
m.fs.R101.outlet.temperature[0].setlb(600)
m.fs.R101.outlet.temperature[0].setub(800)

Let us fix the bounds for the rest of the decision variables.

In [45]:
m.fs.F101.vap_outlet.temperature[0].setlb(298.0)
m.fs.F101.vap_outlet.temperature[0].setub(450.0)
m.fs.F102.vap_outlet.temperature[0].setlb(298.0)
m.fs.F102.vap_outlet.temperature[0].setub(450.0)
m.fs.F102.vap_outlet.pressure[0].setlb(105000)
m.fs.F102.vap_outlet.pressure[0].setub(110000)

Now, the only things left to define are our constraints on overhead loss in F101, product flow rate and purity in F102. Let us first look at defining a constraint for the overhead loss in F101 where we are restricting the benzene leaving the vapor stream to less than 20 \% of the benzene available in the reactor outlet.

In [46]:
m.fs.overhead_loss = Constraint(
        expr=m.fs.F101.vap_outlet.flow_mol_phase_comp[0, "Vap", "benzene"] <=
        0.20 * m.fs.R101.outlet.flow_mol_phase_comp[0, "Vap", "benzene"])
Inline Exercise: Now, add the constraint such that we are producing at least 0.15 mol/s of benzene in the product stream which is the vapor outlet of F102. Let us name this constraint as m.fs.product_flow. Use Shift+Enter to run the cell once you have typed in your code.
In [47]:
m.fs.product_flow = Constraint(
        expr=m.fs.F102.vap_outlet.flow_mol_phase_comp[0, "Vap", "benzene"] >=
        0.15)

Let us add the final constraint on product purity or the mole fraction of benzene in the product stream such that it is at least greater than 80%.

In [48]:
m.fs.product_purity = Constraint(expr=m.fs.purity >= 0.80)

We have now defined the optimization problem and we are now ready to solve this problem.

In [49]:
results = solver.solve(m, tee=True)
Ipopt 3.12: tol=1e-06
max_iter=5000


******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
 Ipopt is released as open source code under the Eclipse Public License (EPL).
         For more information visit http://projects.coin-or.org/Ipopt
******************************************************************************

This is Ipopt version 3.12, running with linear solver ma27.

Number of nonzeros in equality constraint Jacobian...:     1048
Number of nonzeros in inequality constraint Jacobian.:        5
Number of nonzeros in Lagrangian Hessian.............:      901

Total number of variables............................:      343
                     variables with only lower bounds:        0
                variables with lower and upper bounds:      149
                     variables with only upper bounds:        0
Total number of equality constraints.................:      338
Total number of inequality constraints...............:        3
        inequality constraints with only lower bounds:        2
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        1

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  4.1912234e+05 2.99e+05 6.94e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  4.1628396e+05 2.99e+05 6.94e+00  -1.0 4.82e+09    -  1.80e-05 5.83e-06f  1
   2  4.1616769e+05 2.99e+05 1.60e+02  -1.0 1.45e+09    -  5.86e-04 1.47e-05f  1
   3  4.0783429e+05 2.94e+05 4.85e+02  -1.0 1.35e+09    -  2.61e-04 9.35e-04f  1
   4  2.9670827e+05 2.83e+06 6.94e+02  -1.0 4.75e+08    -  7.35e-05 1.50e-03f  1
   5  2.9557701e+05 2.82e+06 4.95e+04  -1.0 1.90e+08    -  1.88e-01 1.04e-03f  1
   6  2.9452502e+05 2.72e+06 4.63e+05  -1.0 4.40e+07    -  1.88e-01 3.46e-02f  1
   7  2.9632753e+05 2.13e+06 4.47e+05  -1.0 1.47e+07    -  7.61e-02 2.19e-01h  1
   8  2.9636923e+05 2.12e+06 4.45e+05  -1.0 5.86e+06    -  6.38e-01 3.38e-03h  1
   9  2.9647019e+05 2.10e+06 4.42e+05  -1.0 6.53e+06    -  7.25e-01 7.18e-03h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  2.9958737e+05 1.63e+06 4.17e+05  -1.0 6.56e+06    -  3.55e-02 2.24e-01h  1
  11  3.0436334e+05 9.49e+05 6.96e+05  -1.0 5.55e+06    -  9.46e-01 4.19e-01h  1
  12  3.0792618e+05 5.00e+05 4.56e+06  -1.0 4.03e+06    -  9.90e-01 4.73e-01h  1
  13  3.0931998e+05 3.46e+05 1.59e+08  -1.0 2.67e+06    -  1.00e+00 3.08e-01h  2
  14  3.1261432e+05 5.80e+05 1.20e+11  -1.0 2.00e+06    -  1.00e+00 9.78e-01H  1
  15  3.1271509e+05 2.42e+05 8.71e+08  -1.0 1.43e+05    -  1.00e+00 5.84e-01h  1
  16  3.1278603e+05 2.73e+03 3.26e+11  -1.0 5.97e+04    -  1.00e+00 9.90e-01h  1
  17  3.1278674e+05 1.79e-01 3.96e+09  -1.0 6.18e+02    -  1.00e+00 1.00e+00h  1
  18  3.1278674e+05 1.91e-06 3.15e+05  -1.0 5.18e-03    -  1.00e+00 1.00e+00h  1
  19  3.1278634e+05 3.47e-05 1.62e+06  -3.8 2.02e+02    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20  3.1278634e+05 7.45e-09 6.26e-04  -3.8 1.71e-01    -  1.00e+00 1.00e+00h  1
  21  3.1278634e+05 7.45e-09 4.35e+00  -7.0 3.04e-01    -  1.00e+00 1.00e+00f  1
  22  3.1278634e+05 7.45e-09 2.21e-05  -7.0 3.92e-07    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 22

                                   (scaled)                 (unscaled)
Objective...............:   3.1278633834102692e+05    3.1278633834102692e+05
Dual infeasibility......:   2.2104556086546602e-05    2.2104556086546602e-05
Constraint violation....:   2.9103830456733704e-11    7.4505805969238281e-09
Complementarity.........:   9.0926527280252903e-08    9.0926527280252903e-08
Overall NLP error.......:   2.0798568647064281e-09    2.2104556086546602e-05


Number of objective function evaluations             = 26
Number of objective gradient evaluations             = 23
Number of equality constraint evaluations            = 26
Number of inequality constraint evaluations          = 26
Number of equality constraint Jacobian evaluations   = 23
Number of inequality constraint Jacobian evaluations = 23
Number of Lagrangian Hessian evaluations             = 22
Total CPU secs in IPOPT (w/o function evaluations)   =      0.015
Total CPU secs in NLP function evaluations           =      0.002

EXIT: Optimal Solution Found.

Optimization Results

Display the results and product specifications

In [50]:
print('operating cost = $', value(m.fs.operating_cost))

print()
print('Product flow rate and purity in F102')

print_ports_summary([m.fs.F102.vap_outlet])

print()
print('benzene purity = ', value(m.fs.purity))

print()
print('Overhead loss in F101')
print_ports_summary([m.fs.F101.vap_outlet])
operating cost = $ 312786.3383410269

Product flow rate and purity in F102
                                     Variable	fs.F102.vap_outlet	
---------------------------------------------	------------------	
 flow_mol_phase_comp[(0.0, 'Liq', 'benzene')]	          0.000000	
 flow_mol_phase_comp[(0.0, 'Liq', 'toluene')]	          0.000000	
flow_mol_phase_comp[(0.0, 'Liq', 'hydrogen')]	          0.000000	
 flow_mol_phase_comp[(0.0, 'Liq', 'methane')]	          0.000000	
 flow_mol_phase_comp[(0.0, 'Vap', 'benzene')]	          0.150000	
 flow_mol_phase_comp[(0.0, 'Vap', 'toluene')]	          0.033189	
flow_mol_phase_comp[(0.0, 'Vap', 'hydrogen')]	          0.000000	
 flow_mol_phase_comp[(0.0, 'Vap', 'methane')]	          0.000000	
                             temperature[0.0]	        362.934768	
                                pressure[0.0]	     105000.000000	

benzene purity =  0.8188276578112287

Overhead loss in F101
                                     Variable	fs.F101.vap_outlet	
---------------------------------------------	------------------	
 flow_mol_phase_comp[(0.0, 'Liq', 'benzene')]	          0.000000	
 flow_mol_phase_comp[(0.0, 'Liq', 'toluene')]	          0.000000	
flow_mol_phase_comp[(0.0, 'Liq', 'hydrogen')]	          0.000000	
 flow_mol_phase_comp[(0.0, 'Liq', 'methane')]	          0.000000	
 flow_mol_phase_comp[(0.0, 'Vap', 'benzene')]	          0.054356	
 flow_mol_phase_comp[(0.0, 'Vap', 'toluene')]	          0.005391	
flow_mol_phase_comp[(0.0, 'Vap', 'hydrogen')]	          0.358867	
 flow_mol_phase_comp[(0.0, 'Vap', 'methane')]	          1.241431	
                             temperature[0.0]	        301.878476	
                                pressure[0.0]	     349999.999191	

Display optimal values for the decision variables

In [51]:
print('Optimal Values')
print()

print('H101 outlet temperature = ', value(m.fs.H101.outlet.temperature[0]), 'K')

print()
print('R101 outlet temperature = ', value(m.fs.R101.outlet.temperature[0]), 'K')

print()
print('F101 outlet temperature = ', value(m.fs.F101.vap_outlet.temperature[0]), 'K')

print()
print('F102 outlet temperature = ', value(m.fs.F102.vap_outlet.temperature[0]), 'K')
print('F102 outlet pressure = ', value(m.fs.F102.vap_outlet.pressure[0]), 'Pa')
Optimal Values

H101 outlet temperature =  500.0 K

R101 outlet temperature =  696.1161004637527 K

F101 outlet temperature =  301.8784760569282 K

F102 outlet temperature =  362.93476830548974 K
F102 outlet pressure =  105000.0 Pa
In [ ]:
 

Module 3 Exercise 1 Solution:

Module_3_Exercise_1_Solution

Create a Heater

In [1]:
import pyomo.environ as pe
from pyomo.common.config import ConfigBlock, ConfigValue, In
from idaes.core import (ControlVolume0DBlock,
                        declare_process_block_class,
                        EnergyBalanceType,
                        MomentumBalanceType,
                        MaterialBalanceType,
                        UnitModelBlockData,
                        useDefault,
                        FlowsheetBlock)
from idaes.core.util.config import is_physical_parameter_block
from methanol_param_VLE import PhysicalParameterBlock
from idaes.core.util.misc import add_object_reference
In [2]:
def make_control_volume(unit, name, config):
    if config.dynamic is not False:
        raise ValueError('IdealGasIsentropcCompressor does not support dynamics')
    if config.has_holdup is not False:
        raise ValueError('IdealGasIsentropcCompressor does not support holdup')

    control_volume = ControlVolume0DBlock(default={"property_package": config.property_package,
                                                   "property_package_args": config.property_package_args})

    setattr(unit, name, control_volume)

    control_volume.add_state_blocks(has_phase_equilibrium=config.has_phase_equilibrium)
    control_volume.add_material_balances(balance_type=config.material_balance_type,
                                         has_phase_equilibrium=config.has_phase_equilibrium)
    control_volume.add_total_enthalpy_balances(has_heat_of_reaction=False, 
                                               has_heat_transfer=True, 
                                               has_work_transfer=False)
    control_volume.add_total_pressure_balances(has_pressure_change=False)
In [3]:
def make_config_block(config):
    config.declare("material_balance_type",
        ConfigValue(default=MaterialBalanceType.componentPhase, domain=In(MaterialBalanceType)))
    config.declare("energy_balance_type",
        ConfigValue(default=EnergyBalanceType.enthalpyTotal, domain=In([EnergyBalanceType.enthalpyTotal])))
    config.declare("momentum_balance_type",
        ConfigValue(default=MomentumBalanceType.pressureTotal, domain=In([MomentumBalanceType.pressureTotal])))
    config.declare("has_phase_equilibrium",
        ConfigValue(default=False, domain=In([False])))
    config.declare("has_pressure_change",
        ConfigValue(default=False, domain=In([False])))
    config.declare("property_package",
        ConfigValue(default=useDefault, domain=is_physical_parameter_block))
    config.declare("property_package_args",
        ConfigBlock(implicit=True))
In [4]:
@declare_process_block_class("Heater")
class HeaterData(UnitModelBlockData):
    CONFIG = UnitModelBlockData.CONFIG()
    make_config_block(CONFIG)

    def build(self):
        super(HeaterData, self).build()

        make_control_volume(self, "control_volume", self.config)

        self.add_inlet_port()
        self.add_outlet_port()
        
        add_object_reference(self, 'heat', self.control_volume.heat[0.0])
In [5]:
m = pe.ConcreteModel()
m.fs = fs = FlowsheetBlock(default={"dynamic": False})
fs.properties = props = PhysicalParameterBlock(default={'Cp': 0.038056, 'valid_phase': 'Vap'})

fs.heater = Heater(default={"property_package": props, 'has_phase_equilibrium': False})
fs.heater.inlet.flow_mol.fix(1)
fs.heater.inlet.mole_frac[0, 'CH3OH'].fix(0.25)
fs.heater.inlet.mole_frac[0, 'CH4'].fix(0.25)
fs.heater.inlet.mole_frac[0, 'H2'].fix(0.25)
fs.heater.inlet.mole_frac[0, 'CO'].fix(0.25)
fs.heater.inlet.pressure.fix(0.1)
fs.heater.inlet.temperature.fix(3)
fs.heater.heat.fix(5)

opt = pe.SolverFactory('ipopt')
opt.options['linear_solver'] = 'mumps'
res = opt.solve(m, tee=False)
print(res.solver.termination_condition)
fs.heater.outlet.display()
optimal
outlet : Size=1
    Key  : Name        : Value
    None :    flow_mol : {0.0: 1.0}
         :   mole_frac : {(0.0, 'CH3OH'): 0.25, (0.0, 'CH4'): 0.25, (0.0, 'CO'): 0.25, (0.0, 'H2'): 0.25}
         :    pressure : {0.0: 0.1}
         : temperature : {0.0: 4.313853268866933}
In [ ]:
 

If you want to run these Jupyter notebooks yourself, you need to download the source code for the IDAES toolkit and then navigate to examples/workshops and its subdirectories. You would load a given tutorial with the command:

jupyter notebook <notebook-file-name.ipynb>

Then, in the Jupyter interface, you could select “Run all” to see the tutorial executed in front of you.

Developer Documentation

This section of the documentation is intended for developers, and much of it is targeted at the IDAES internal team. Hopefully many of the principles and ideas are also applicable to external contributors.

Developer Contents

Developer introductory material

This section gives terms and information targeted at people who are new to collaborative software development. It serves as background for understanding the collaborative development procedures. However, this is a quick start and there are many more useful things to learn about git and Github. For more information, please refer to the excellent Atlassian Github tutorials and the online Git documentation and Github help.

Terminology
Git
A “version control system”, for keeping track of changes in a set of files
Github
A hosting service for Git repositories that adds many other features that are useful for collaborative software development.
branch
A name for a series of commits. See Branches.
fork
Copy of a repository in Github. See Forks.
pull request (PR)
A request to compare and merge code in a Github repository. See Pull Requests.
Git commands

The Git tool has many different commands, but there are several really important ones that tend to get used as verbs in software development conversations, and therefore are good to know:

add
Put a file onto the list of “things I want to commit” (see “commit”), called “staging” the file.
commit
Save the changes in “staged” files into Git (since the last time you did this), along with a user-provided description of what the changes mean (called the “commit message”).
push
Move local committed changes to the Github-hosted “remote” repository by “pushing” them across the network.
pull
Update your local files with changes from the Github-hosted “remote” repository by “pulling” them across the network.

Note that the push and pull commands require Github (or some other service that can host a remote copy of the repository).

Branches

There is a good description of what git branches are and how they work here. Understanding this takes a little study, but this pays off by making git’s behavior much less mysterious. The short, practical version is that a branch is a name for a series of commits that you want to group together, and keep separable from other series of commits. From git’s perspective, the branch is just a name for the first commit in that series.

It is recommended that you create new branches on which to develop your work, and reserve the “master” branch for merging in work that has been completed and approved on Github. One way to do this is to create branches that correspond directly to issues on Github, and include the issue number in the branch name.

Forks

A fork is a copy of a repository, in the Github shared space (a copy of a repository from Github down to your local disk is called a “clone”). In this context, that means a copy of the “idaes-dev” repository from the IDAES organization (https://github.com/IDAES/idaes-dev) to your own user space, e.g., https://github.com/myname/idaes-dev). The mechanics of creating and using forks on Github are given here.

Pull Requests

A fundamental procedure in the development lifecycle is what is called a “pull request”. Understanding what these are, and do, is important for participating fully in the software development process. First, understand that pull requests are for collaborative development (Github) and not part of the core revision control functionality that is offered by Git. The official Github description of pull requests is here. However, it gets technical rather quickly, so a higher-level explanation may be helpful:

Pull requests are a mechanism that Github provides to look at what the code on some branch from your fork of the repository would be like if it were merged with the master branch in the main (e.g., idaes/idaes-dev) repository. You can think of it as a staging area where the code is merged and all the tests are run, without changing the target repository. Everyone on the team can see a pull request, comment on it, and review it.

Github repository overview

This section describes the layout of the Github repositories. Later sections will give guidelines for contributing code to these repositories.

Repositories
Repository name Public? Description
idaes-pse Yes Main public repository, including core framework and integrated tools
idaes-dev No Main private repository, where code is contributed before being “mirrored” to the public ideas-pse repository
workspace No Repository for code that does not belong to any particular CRADA or NDA, but also is never intended to be released open-source

The URL for an IDAES repository, e.g. “some-repo”, will be https://github.com/IDAES/some-repo.

Public vs. Private

All these repositories except for “idaes-pse” will only be visible on Github, on the web, for people who have been added to the IDAES developer team in the IDAES “organization” (See About Github organizations). If you are a member of the IDAES team and not in the IDAES Github organization, please contact one of the core developers. The idaes-pse repository will be visible to anyone, even people without a Github account.

Collaborative software development

This page gives guidance for all developers on the project.

Note

Many details here are targeted at members of the IDAES project team. However, we strongly believe in the importance of transparency in the project’s software practices and approaches. Also, understanding how we develop the software internally should be generally useful to understand the review process to expect for external contributors.

Although the main focus of this project is developing open source software (OSS), it is also true that some of the software may be developed internally or in coordination with industry under a CRADA or NDA.

It is the developer’s responsibility, for a given development effort, to keep in mind what role you must assume and thus which set of procedures must be followed.

CRADA/NDA
If you are developing software covered by a CRADA, NDA, or other legal agreement that does not explicitly allow the data and/or code to be released as open-source under the IDAES license, then you must follow procedures under Developing Software with Proprietary Content.
Internal
If you are developing non-CRADA/NDA software, which is not intended to be part of the core framework or (ever) released as open-source then follow procedures under Developing Software for Internal Use.
Core/open-source
If you are developing software with no proprietary data or code, which is intended to be released as open-source with the core framework, then follow procedures under Developing software for Open-source Release.
Developing Software with Proprietary Content

Proprietary content is not currently being kept on Github, or any other collaborative version control platform. When this changes, this section will be updated.

Developing Software for Internal Use

Software for internal use should be developed in the workspace repository of the IDAES github organization. The requirements for reviews and testing of this code are not as strict as for the idaes-dev repository, but otherwise the procedures are the same as outlined for open-source development.

Developing software for Open-source Release

We can break the software development process into five distinct phases, illustrated in Figure 1 and summarized below:

1. Setup: Prepare your local system for collaborative development
2. Initiate: Notify collaborators of intent to make some changes
3. Develop: Make local changes
4. Collaborate: Push the changes to Github, get feedback and merge
_images/sw-overview-workflow.png

Figure 1. Overview of software development workflow

The rest of this page describes the what and how of each of these phases.

1. Setup

Before you can start developing software collaboratively, you need to make sure you are set up in Github and set up your local development environment.

Github setup

To work within the project, you need to create a login on Github. You also need to make sure that this login has been added to the IDAES organization by contacting one of the core developers.

If these steps are successful, you should be able to login to Github, visit the IDAES Github organization, and see “Private” repositories such as idaes-dev and workspace.

Fork the repo

You use a “fork” of a repository (or “repo” for short) to create a space where you can save changes without directly affecting the main repository. Then, as we will see, you request that these changes be incorporated (after review).

This section assumes that the repository in question is idaes-dev, but the idea is the same for any other repo.

You should first visit the repo on Github by pointing your browser to https://github.com/IDAES/idaes-dev/. Then you should fork the repo into a repo of the same name under your name.

_images/github-fork-repo.png

Figure 2. Screenshot showing where to click to fork the Github repo

Clone your fork

A “clone” is a copy of a Github repository on your local machine. This is what you need to do in order to actually edit and change the files. To make a clone of the fork you created in the previous step, change to a directory where you want to put the source code and run the command:

git clone git@github.com:MYNAME/idaes-dev.git
cd idaes-dev

Of course, replace MYNAME with your login name. This will download all the files in the latest version of the repository onto your local disk.

Note

After the git clone, subsequent git commands should be performed from the “idaes-dev” directory.

Add upstream remote

In order to guarantee that your fork can be synchronized with the “main” idaes-dev repo in the Github IDAES organization, you need to add a pointer to that repository as a remote. This repository is called upstream (changes made there by the whole team flow down to your fork), so we will use that name for it in our command:

git remote add upstream git@github.com:IDAES/idaes-dev.git
Create the Python environment

Once you have the repo cloned, you can change into that directory (by default, it will be called “idaes-dev” like the repo) and install the Python packages.

But before you do that, you need to get the Python package manager fully up and running. We use a Python packaging system called Conda. Below are instructions for installing a minimal version of Conda, called Miniconda. The full version installs a large number of scientific analysis and visualization libraries that are not required by the IDAES framework.

wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh

Create and activate a conda environment (along with its own copy of pip) for the new IDAES installation (you will need to conda activate idaes when you open a fresh terminal window and wish to use IDAES):

conda create -n idaes pip
conda activate idaes

Now that conda and pip are installed, and you are in the “idaes” conda environment, you can run the standard steps for installing a Python package in development mode:

pip install -r requirements.txt
python setup.py develop

You can test that everything is installed properly by running the tests with Pytest:

pytest
2. Initiate

We will call a set of changes that belong together, e.g. because they depend on each other to work, a “topic”. This section describes how to start work on a new topic. The workflow for initiating a topic is shown in Figure 3 below.

_images/sw-init-workflow.png

Figure 3. Initiate topic workflow

Create an issue on Github

To create an issue on Github, simply navigate to the repository page and click on the “Issues” tab. Then click on the “Issues” button and fill in a title and brief description of the issue. You do not need to list details about sub-steps required for the issue, as this sort of information is better put in the (related) pull request that you will create later. Assign the issue to the appropriate people, which is often yourself.

There is one more important step to take, that will allow the rest of the project to easily notice your issue: add the issue to the “Priorities” project. The screenshot below shows where you need to click to do this.

_images/github-issue-priority.png

Figure 4. Screenshot for creating an issue on Github

Create a branch on your fork

It is certainly possible to do your work on your fork in the “master” branch. The problem that can arise here is if you need to do two unrelated things at the same time, for example working on a new feature and fixing a bug in the current code. This can be quite tricky to manage as a single set of changes, but very easy to handle by putting each new set of changes in its own branch, which we call a topic branch. When all the changes in the branch are done and merged, you can delete it both locally and in your fork so you don’t end up with a bunch of old branches cluttering up your git history.

The command for doing this is simple:

git checkout -b <BRANCH-NAME>

The branch name should be one word, with dashes or underscores as needed. One convention for the name that can be helpful is to include the Issue number at the end, e.g. git co -b mytopic-issue42. This is especially useful later when you are cleaning up old branches, and you can quickly see which branches are related to issues that are completed.

Make local edits and push changes

A new branch, while it feels like a change, is not really a change in the eyes of Git or Github, and by itself will not allow you to start a new pull request (which is the goal of this whole phase). The easiest thing to do is a special “empty” commit:

git commit --allow-empty -m 'Empty commit so I can open a PR'

Since this is your first “push” to this branch, you are going to need to set an upstream branch on the remote that should receive the changes. If this sounds complicated, it’s OK because git actually gives you cut-and-paste instructions. Just run the git push command with no other arguments:

$ git push
fatal: The current branch mybranch-issue3000 has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin mybranch-issue3000

Cut and paste the suggested command, and you’re ready to go. Subsequent calls to “push” will not require any additional arguments to work.

Start a new Pull Request on Github

Finally, you are ready to initiate the pull request. Right after you perform the push command above, head to the repository URL in Github (https://github.com/IDAES/idaes-dev) and you should see a highlighted bar below the tabs, as in Figure 5 below, asking if you want to start a pull-request.

_images/github-start-pullrequest.png

Figure 5. Screenshot for starting a Pull Request on Github

Click on this and fill in the requested information. Remember to link to the issue you created earlier.

Depending on the Github plan, there may be a pull-down menu for creating the pull request that lets you create a “draft” pull request. If that is not present, you can signal this the old-fashioned way by adding “[WIP]” (for Work-in-Progress) at the beginning of the pull request title.

Either way, create the pull request. Do not assign reviewers until you are done making your changes (which is probably not now). This way the assigning of reviewers becomes an unambiguous signal that the PR is actually ready for review.

Note

Avoid having pull requests that take months to complete. It is better to divide up the work, even artificially, into a piece that can be reviewed and merged into the main repository within a week or two.

3. Develop

The development process is a loop of adding code, testing and debugging, and committing and pushing to Github. You may go through many (many!) iterations of this loop before the code is ready for review. This workflow is illustrated in Figure 6.

_images/sw-dev-workflow.png

Figure 6. Software development workflow

Running tests

After significant edits, you should make sure you have tests for the new/changed functionality. This involves writing Unit tests as well as running the test suite and examining the results of the Code coverage.

This project uses Pytest to help with running the unit tests. From the top-level directory of the working tree, type:

pytest

Alternatively users of an IDE like PyCharm can run the tests from within the IDE.

Commit changes

The commands: git add, git status, and git commit are all used in combination to save a snapshot of a Git project’s current state. [1].

The commit command is the equivalent of “saving” your changes. But unlike editing a document, the set of changes may cover multiple files, including newly created files. To allow the user flexibility in specifying exactly which changes to save with each commit, the add command is used first to indicate files to “stage” for the next commit command. The status command is used to show the current status of the working tree.

A typical workflow goes like this:

$ ls
file1  file2
$ echo 'a' > file1 # edit existing file
$ echo '1' > file3 # create new file
$ git status --short # shows changed/unstaged and unknown file
 M file1
?? file3
$ git add file1 file3 # stage file1, file3 for commit
$ git status --short # M=modified, A=added
M  file1
A  file3
$ git commit -m "made some changes"
[master 067c16e] made some changes
2 files changed, 2 insertions(+)
create mode 100644 file3

Of course, in most IDEs you could use built-in commands for committing and adding files. The basic flow would be the same.

Synchronize with upstream changes

Hopefully you are not the only one on the team doing work, and therefore you should expect that the main repository may have new and changed content while you are in the process of working. To synchronize with the latest content from the “upstream” (IDAES organization) repository, you should periodically run one of the two following commands:

git pull
# OR -- explicit
git fetch --all
git merge upstream/master

You’ll notice that this merge command is using the name of the “upstream” remote that you created earlier.

Push changes to Github

Once changes are tested and committed, they need to be synchronized up to Github. This is done with the git push command, which typically takes no options (assuming you have set up your fork, etc., as described so far):

git push

The output of this command on the console should be an informative, if slightly cryptic, statement of how many changes were pushed and, at the bottom, the name of your remote fork and the local/remote branches (which should be the same). For example:

Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 528 bytes | 528.00 KiB/s, done.
Total 5 (delta 4), reused 0 (delta 0)
remote: Resolving deltas: 100% (4/4), completed with 4 local objects.
To github.com:dangunter/idaes-dev.git
   d535552..fe61fcc  devdocs-issue65 -> devdocs-issue65
4. Collaborate

The collaboration phase of our journey, shown in Figure 7, is mostly about communicating what you did to the other developers. Through the Github “review” mechanism, people will be able to suggest changes and improvements. You can make changes to the code (other people can also make changes, see Shared forks), and then push those changes up into the same Pull Request. When you get enough approving reviews, the code is merged into the master repository. At this point, you can delete the “topic branch” used for the pull request, and go back to initiate your next set of changes.

_images/sw-collaborate-workflow.png

Figure 7. Collaborate phase workflow

Request review

To request review of a pull request, navigate to the pull request in the main (e.g., “idaes-dev”) repository and select some names in the “Reviewers” pull-down on the right-hand side. You need to have two approving reviews. The reviewers should get an email, but you can also “@” people in a comment in the pull request to give them a little extra nudge.

See the full code review procedure for more details.

Make changes

You need to keep track of the comments and reviews, and make changes accordingly. Think of a pull request as a discussion. Normally, the person who made the pull request will make any requested edits. Occasionally, it may make sense for one or more other developers to jump in and make edits too, so how to do this is covered in the sub-section below.

Changes made while the code is being reviewed use the normal Develop workflow.

Shared forks

Other developers can also make changes in your fork. All they need to do is git clone your fork (not the main repository), switch to the correct topic branch, and then git push work directly to that branch. Note since this does not use the whole pull-request mechanism, all developers working on the same branch this way need to make sure the git pull to synchronize with updates from the other developers.

For example, if Jack wants to make some edits on Rose’s fork, on a topic branch called “changes-issue51” he could do the following:

$ git clone https://github.com/rose/idaes-dev # clone Rose's fork
$ git checkout changes-issue51  # checkout the topic branch
$ echo "Hello" >> README.txt  # make some important changes
$ pytest # always run tests!!
$ git add README.txt ; git commit -m "important changes"
$ git push # push changes to the fork

Hopefully it also is obvious that developers working this way have less safeguards for overwriting each other’s work, and thus should make an effort to communicate clearly and in a timely manner.

Merge

Once all the tests pass and you have enough approving reviews, it’s time to merge the code! This is the easy part: go to the bottom of the Pull Request and hit the big green “merge” button.

Before you close the laptop and go down to the pub, you should tidy up. First, delete your local branch (you can also delete that branch on Github):

git checkout master # switch back to master branch
git branch -d mychanges-issue3000

Next, you should make sure your master reflects the current state of the main master branch, i.e. go back and synchronize with the upstream remote, i.e. run git pull.

Now you can go and enjoy a tasty beverage. Cheers!

_images/beer-coffee-cheers-small.png

Footnotes

[1]Git has an additional saving mechanism called ‘the stash’. The stash is an ephemeral storage area for changes that are not ready to be committed. The stash operates on the working directory and has extensive usage options.* See the documentation for git stash for more information.
Testing

Testing is essential to the process of creating software. “If it isn’t tested, it doesn’t work” is a good rule of thumb.

There are different kinds of tests: functional, acceptance, performance, usability. We will primarily concern ourselves with functional testing here, i.e. whether the thing being tested produces correct outputs for expected inputs, and gracefully handles everything else. Within functional testing, we can classify the testing according to the axes of time, i.e. how long the test takes to run, and scope, i.e. the amount of the total functionality being tested. Along these two axes we will pick out just two points, as depicted in Figure 1. The main tests you will write are “unit tests”, which run very quickly and test a focused amount of functionality. But sometimes you need something more involved (e.g. running solvers, using data on disk), and here we will label that kind of test “integration tests”.

_images/testing-conceptual.png

Figure 1. Conceptual space of functional testing

Unit tests

Testing individual pieces of functionality, including the ability to report the correct kind of errors from bad inputs. Unit tests must always run quickly. If it takes more than 10 seconds, it is not a unit test, and it is expected that most unit tests take well under 1 second. The reason for this is that the entire unit test suite is run on every change in a Pull Request, and should also be run relatively frequently on local developer machines. If this suite of hundreds of tests takes more than a couple of minutes to run, it will introduce a significant bottleneck in the development workflow.

For Python code, we use the pytest testing framework. This is compatible with the built-in Python unittest framework, but has many nice features that make it easier and more powerful.

The best way to learn how to use pytest is to look at existing unit tests, e.g. the file “idaes/core/tests/test_process_block.py”. Test files are found in a directory named “test/” in every Python package (directory with an “__init__.py”). The tests are named “test_{something}.py”; this naming convention is important so pytest can automatically find all the tests.

When writing your own tests, make sure to remember to keep each test focused on a single piece of functionality. If a unit test fails, it should be obvious which code is causing the problem.

Mocking

Mocking is a common, but important, technique for avoiding dependencies that make your tests slow, fragile, and harder to understand. The basic idea is to replace dependencies with fake, or “mock”, versions of them that will provide just enough realism for the test. Python provides a library, unittest.mock, to help with this process by providing objects that can report how they were used, and easily pretend to have certain functionality (returning, for example, fixed values). To make this all more concrete, consider a simple problem where you want to test a function that makes a system call (in this case, os.remove):

# file: mymodule.py
import os
def rm(filename):
    os.remove(filename)

Normally, to test this you would create a temporary file, and then see if it got removed. However, with mocking you can take a different approach entirely:

# file: test_mymodule.py
from mymodule import rm
from unittest import mock

@mock.patch('mymodule.os')
def test_rm(mock_os):
    rm("any path")
    # test that rm called os.remove with the right parameters
    mock_os.remove.assert_called_with("any path")

Here, we have “patched” the os module that got imported into “mymodule” (note: had to do mymodule.os instead of simply os, or the one mymodule uses would not get patched) so that when rm calls os.remove, it is really calling a fake method in mock_os that does nothing but record how it was called. The patched module is passed in to the test as an argument so you can examine it. So, now, you are not doing any OS operations at all! You can imagine how this is very useful with large files or external services.

Integration tests

Integration tests exercise an end-to-end slice of the overall functionality. At this time, the integration tests are all housed in Jupyter Notebooks, which serve double-duty as examples and tutorials for end users. We execute these notebooks and verify that they run correctly to completion at least once before each new release of the software.

Code coverage

The “coverage” of the code refers to what percentage of the code (“lines covered” divided by total lines) is executed by the automated tests. This is important because passing automated tests is only meaningful if the automated tests cover the majority of the code’s behavior. This is not a perfect measure, of course, since simply executing a line of code under one condition does not mean it would execute correctly under all conditions. The code coverage is evaluated locally and then integrated with Github through a tool called Coveralls.

Code Review

“It’s a simple 3-step process. Step one: Fix! Step two: It! Step three: Fix it!” – Oscar Rogers (Kenan Thompson), Saturday Night Live, 2/2009

Code review is the last line of defense between a mistake that the IDAES team will see and a mistake the whole world will see. In the case of that mistake being a leak of proprietary information, the entire project is jeopardized, so we need to take this process seriously.

Summary

Warning

This section is an incomplete set of notes

Every piece of code must be reviewed by at least two people.

In every case, one of those people will be a designated “gatekeeper” and the one or more others will be “technical reviewers”.

The technical reviewers are expected to consider various aspects of the proposed changes (details below), and engage the author in a discussion on any aspects that are deemed lacking or missing.

The gatekeeper is expected to make sure all criteria have been met, and actually merge the PR.

Assigning Roles

The gatekeeper is a designated person, who will always be added to review a Pull Request (PR)

Gatekeeper is a role that will be one (?) person for some period like a week or two weeks

The role should rotate around the team, it’s expected to be a fair amount of work and should be aligned with availability and paper deadlines, etc.

The originator of the PR will add as reviewers the gatekeeper and 1+ technical reviewers.

Originator responsibilities

The originator of the PR should include in the PR itself information about where to find:

Changes to code/data

Tests of the changes

Documentation of the changes

The originator should be responsive to the reviewers

Technical reviewer responsibilities

The technical reviewer(s) should look at the proposed changes for

Technical correctness (runs properly, good style, internal code documentation, etc.)

Tests

Documentation

No proprietary / sensitive information

Until they approve, the conversation in the PR is between the technical reviewers and the originator (the gatekeeper is not required to participate, assuming they have many PRs to worry about)

Gatekeeper responsibilities

The gatekeeper does not need to engage until there is at least one approving technical review.

Once there is, they should verify that:

Changes do not contain proprietary data

Tests are adequate and do not fail

Documentation is adequate

Once everything is verified, the gatekeeper merges the PR

Automated Checks

The first level of code review is a set of automated checks that must pass before the code is ready for people to review it. These checks will run on the initiation of a pull request and on every new commit to that pull request that is pushed to Github (thus the name “continuous integration”).

The “continuous integration” of the code is hosted by an online service – we use CircleCI – that can automatically rerun the tests after every change (in this case, every new Pull Request or update to the code in an existing Pull Request) and report the results back to Github for display in the web pages. This status information can then be used as an automatic gatekeeper on whether the code can be merged into the master branch – if tests fail, then no merge is allowed. Following this procedure, it is not possible for the master branch to ever be failing its own tests.

Docker container

This page documents information needed by developers for working with the IDAES docker container.

As is expected by Docker, the main file for creating the Docker image is the “Dockerfile” in the top-level directory.

docker-idaes script

You can build new Docker images using the create option to the docker-idaes script. For example:

./docker-idaes create

You need to have the IDAES installation activated. The script will automatically find the current version and attempt to build a Docker image with the same version. If it detects an existing image, it will skip the image build. Next, the script will try to use docker save to save the image as a compressed archive. This will also be skipped if an existing image file, with the same version as the “idaes” Python package, is detected.

Pushing an image to S3

The Docker images are stored on Amazon S3. Before you can upload a new image, you need to be part of the “IDAES-admin” group that is part of Amazon’s IAM (Identity Access Management) system. Please contact one of the core developers to learn how to join this IAM group.

Once you have the IAM keys, you need to create a file ~/.aws/credentials that has the access key id and key from the IAM account. It will look like this:

[default]
aws_access_key_id = IDGOESHERE
aws_secret_access_key = accesskeygoeshere

The values for the ID and Access key are available from the AWS “IAM” service console.

Next you need to use the AWS command-line tools to copy the local image up to Amazon S3. For example, if the image was version “1.0.1”, you would use the following command:

aws s3 cp idaes-pse-docker-1.0.1.tgz \
       s3://idaes/idaes-pse/idaes-pse-docker-1.0.1.tgz

If the new image should be the latest, you also need to do an S3 -> S3 copy to create a new latest image:

aws s3 cp s3://idaes/idaes-pse/idaes-pse-docker-1.0.1.tgz \
          s3://idaes/idaes-pse/idaes-pse-docker-latest.tgz

idaes

idaes package

__init__.py for idaes module

Set up logging for the idaes module, and import plugins.

Subpackages
idaes.core package
Subpackages
idaes.core.util package
Subpackages
idaes.core.util.convergence package
Submodules
idaes.core.util.convergence.convergence module

This module is a command-line script for executing convergence evaluation testing on IDAES models.

Convergence evaluation testing is used to verify reliable convergence of a model over a range of conditions for inputs and parameters. The developer of the test must create a ConvergenceEvaluation class prior to executing any convergence testing (see convergence_base.py for documentation).

Convergence evaluation testing is a two step process. In the first step, a json file is created that contains a set of points sampled from the provided inputs. This step only needs to be done once - up front. The second step, which should be executed any time there is a major code change that could impact the model, takes that set of sampled points and solves the model at each of the points, collecting convergence statistics (success/failure, iterations, and solution time).

To find help on convergence.py:

$ python convergence.py --help

You will see that there are some subcommands. To find help on a particular subcommand:

$ python convergence.py  <subcommand> --help

To create a sample file, you can use a command-line like the following (this should be done once by the model developer for a few different sample sizes):

$ python ../../../core/util/convergence/convergence.py create-sample-file
      -s PressureChanger-10.json
      -N 10 --seed=42
      -e idaes.models.convergence.pressure_changer.
          pressure_changer_conv_eval.PressureChangerConvergenceEvaluation

More commonly, to run the convergence evaluation:

$ python ../../../core/util/convergence/convergence.py run-eval
      -s PressureChanger-10.json

Note that the convergence evaluation can also be run in parallel if you have installed MPI and mpi4py using a command line like the following:

$ mpirun -np 4 python ../../../core/util/convergence/convergence.py run-eval
      -s PressureChanger-10.json
idaes.core.util.convergence.convergence_base module

This module provides the base classes and methods for running convergence evaluations on IDAES models. The convergence evaluation runs a given model over a set of sample points to ensure reliable convergence over the parameter space.

The module requires the user to provide:
  • a set of inputs along with their lower bound, upper bound, mean,
and standard deviation.
  • an initialized Pyomo model
  • a Pyomo solver with appropriate options

The module executes convergence evaluation in two steps. In the first step, a json file is created that containsa set of points sampled from the provided inputs. This step only needs to be done once - up front. The second step, which should be executed any time there is a major code change that could impact the model, takes that set of sampled points and solves the model at each of the points, collecting convergence statistics (success/failure, iterations, and solution time).

This can be used as a tool to evaluate model convergence reliability over the defined input space, or to verify that convergence performance is not decreasing with framework and/or model changes.

In order to write a convergence evaluation for your model, you must inherit a class from ConvergenceEvaluation, and implement three methods:

  • get_specification: This method should create and return a
    ConvergenceEvaluationSpecification object. There are methods on ConvergenceEvaluationSpecification to add inputs. These inputs contain a string that identifies a Pyomo Param or Var object, the lower and upper bounds, and the mean and standard deviation to be used for sampling. When samples are generated, they are drawn from a normal distribution, and then truncated by the lower or upper bounds.
  • get_initialized_model: This method should create and return a Pyomo model
    object that is already initialized and ready to be solved. This model will be modified according to the sampled inputs, and then it will be solved.
  • get_solver: This method should return an instance of the Pyomo solver that
    will be used for the analysis.

There are methods to create the sample points file (on ConvergenceEvaluationSpecification), to run a convergence evaluation (run_convergence_evaluation), and print the results in table form (print_convergence_statistics).

However, this package can also be executed using the command-line interface. See the documentation in convergence.py for more information.

idaes.core.util.convergence.convergence_base.print_convergence_statistics(inputs, results, s)[source]

Print the statistics returned from run_convergence_evaluation in a set of tables

Parameters:
  • inputs (dict) – The inputs dictionary returned by run_convergence_evaluation
  • results (dict) – The results dictionary returned by run_convergence_evaluation
Returns:

Return type:

N/A

idaes.core.util.convergence.convergence_base.run_convergence_evaluation(sample_file_dict, conv_eval)[source]

Run convergence evaluation and generate the statistics based on information in the sample_file.

Parameters:
  • sample_file_dict (dict) – Dictionary created by ConvergenceEvaluationSpecification that contains the input and sample point information
  • conv_eval (ConvergenceEvaluation) – The ConvergenceEvaluation object that should be used
Returns:

Return type:

N/A

idaes.core.util.convergence.convergence_base.save_results_to_dmf(dmf, inputs, results, stats)[source]

Save results of run, along with stats, to DMF.

Parameters:
  • dmf (DMF) – Data management framework object
  • inputs (dict) – Run inputs
  • results (dict) – Run results
  • stats (Stats) – Calculated result statistics
Returns:

None

idaes.core.util.convergence.convergence_base.write_sample_file(eval_spec, filename, convergence_evaluation_class_str, n_points, seed=None)[source]

Samples the space of the inputs defined in the eval_spec, and creates a json file with all the points to be used in executing a convergence evaluation

Parameters:
  • filename (str) – The filename for the json file that will be created containing all the points to be run
  • eval_spec (ConvergenceEvaluationSpecification) – The convergence evaluation specification object that we would like to sample
  • convergence_evaluation_class_str (str) – Python string that identifies the convergence evaluation class for this specific evaluation. This is usually in the form of module.class_name.
  • n_points (int) – The total number of points that should be created
  • seed (int or None) – The seed to be used when generating samples. If set to None, then the seed is not set
Returns:

Return type:

N/A

idaes.core.util.convergence.mpi_utils module
Submodules
idaes.core.util.config module

This module contains utility functions useful for validating arguments to IDAES modeling classes. These functions are primarily designed to be used as the domain argument in ConfigBlocks.

idaes.core.util.config.is_physical_parameter_block(val)[source]

Domain validator for property package attributes

Parameters:val – value to be checked
Returns:ConfigurationError if val is not an instance of PhysicalParameterBlock or useDefault
idaes.core.util.config.is_port(arg)[source]

Domain validator for ports

Parameters:arg – argument to be checked as a Port
Returns:Port object or Exception
idaes.core.util.config.is_reaction_parameter_block(val)[source]

Domain validator for reaction package attributes

Parameters:val – value to be checked
Returns:ConfigurationError if val is not an instance of ReactionParameterBlock
idaes.core.util.config.is_state_block(val)[source]

Domain validator for state block as an argument

Parameters:val – value to be checked
Returns:ConfigurationError if val is not an instance of StateBlock or None
idaes.core.util.config.is_time_domain(arg)[source]

Domain validator for time domains

Parameters:
  • arg – argument to be checked as a time domain (i.e. Set or
  • ContinuousSet)
Returns:

Set, ContinuousSet or Exception

idaes.core.util.config.is_transformation_method(arg)[source]

Domain validator for transformation methods

Parameters:arg – argument to be checked for membership in recognized strings
Returns:Recognised string or Exception
idaes.core.util.config.is_transformation_scheme(arg)[source]

Domain validator for transformation scheme

Parameters:arg – argument to be checked for membership in recognized strings
Returns:Recognised string or Exception
idaes.core.util.config.list_of_floats(arg)[source]

Domain validator for lists of floats

Parameters:arg – argument to be cast to list of floats and validated
Returns:List of strings
idaes.core.util.config.list_of_strings(arg)[source]

Domain validator for lists of strings

Parameters:arg – argument to be cast to list of strings and validated
Returns:List of strings
idaes.core.util.exceptions module

This module contains custom IDAES exceptions.

exception idaes.core.util.exceptions.BalanceTypeNotSupportedError[source]

IDAES exception to be used when a control volumedoes not support a given type of balance equation.

exception idaes.core.util.exceptions.BurntToast[source]

General exception for when something breaks badly in the core.

exception idaes.core.util.exceptions.ConfigurationError[source]

IDAES exception to be used when configuration arguments are incorrect or inconsistent.

exception idaes.core.util.exceptions.DynamicError[source]

IDAES exception for cases where settings associated with dynamic models are incorrect.

exception idaes.core.util.exceptions.PropertyNotSupportedError[source]

IDAES exception for cases when a models calls for a property which is not supported by the chosen property package.

Needs to inherit from AttributeError for Pyomo interactions.

exception idaes.core.util.exceptions.PropertyPackageError[source]

IDAES exception for generic errors arising from property packages.

Needs to inherit from AttributeError for Pyomo interactions.

idaes.core.util.expr_doc module
class idaes.core.util.expr_doc.Pyomo2SympyVisitor(object_map)[source]

This is based on the class of the same name in pyomo.core.base.symbolic, but it catches ExternalFunctions and does not decend into named expressions.

class idaes.core.util.expr_doc.PyomoSympyBimap[source]

This is based on the class of the same name in pyomo.core.base.symbolic, but it adds mapping latex symbols to the sympy symbols. This will get you pretty equations when using sympy’s LaTeX writer.

idaes.core.util.expr_doc.deduplicate_symbol(x, v, used)[source]

Check if x is a duplicated LaTeX symbol if so add incrementing Di subscript

Parameters:
  • x – symbol string
  • v – pyomo object
  • used – dictionary of pyomo objects with symbols as keys
Returns:

Returns a unique symbol. If x was not in used keys, returns x, otherwise adds exponents to make it unique.

idaes.core.util.expr_doc.document_constraints(comp, doc=True, descend_into=True)[source]

Provides nicely formatted constraint documetntation in markdown format, assuming the $$latex math$$ and $latex math$ syntax is supported.

Parameters:
  • comp – A Pyomo component to document in {_ConstraintData, _ExpressionData, _BlockData}.
  • doc – True adds a documentation table for each constraint or expression. Due to the way symbols are semi-automatiaclly generated, the exact symbol definitions may be unique to each constraint or expression, if unique LaTeX symbols were not provided everywhere in a block.
  • descend_into – If True, look in subblocks for constraints.
Returns:

A string in markdown format with equations in LaTeX form.

idaes.core.util.expr_doc.ipython_document_constraints(comp, doc=True, descend_into=True)[source]

See document_constraints, this just directly displays the markdown instead of returning a string.

idaes.core.util.expr_doc.sympify_expression(expr)[source]

Converts Pyomo expressions to sympy expressions. This is based on the function of the same name in pyomo.core.base.symbolic. The difference between this and the Pymomo is that this one checks if the expr argument is a named expression and expands it anyway. This allows named expressions to only be expanded if they are the top level object.

idaes.core.util.expr_doc.to_latex(expr)[source]

Return a sympy expression for the given Pyomo expression

Parameters:expr (Expression) – Pyomo expression
Returns:
keys: sympy_expr, a sympy expression; where, markdown string
with documentation table; latex_expr, a LaTeX string representation of the expression.
Return type:(dict)
idaes.core.util.initialization module

This module contains utility functions for initialization of IDAES models.

idaes.core.util.initialization.solve_indexed_blocks(solver, blocks, **kwds)[source]

This method allows for solving of Indexed Block components as if they were a single Block. A temporary Block object is created which is populated with the contents of the objects in the blocks argument and then solved.

Parameters:
  • solve – a Pyomo solver object to use when solving the Indexed Block
  • blocks – an object which inherits from Block, or a list of Blocks
  • kwds – a dict of argumnets to be passed to the solver
Returns:

A Pyomo solver results object

idaes.core.util.math module

This module contains utility functions for mathematical operators of use in equation oriented models.

idaes.core.util.math.smooth_abs(a, eps=0.0001)[source]

General function for creating an expression for a smooth minimum or maximum.

\[|a| = sqrt(a^2 + eps^2)\]
Parameters:
  • a – term to get absolute value from (Pyomo component, float or int)
  • eps – smoothing parameter (Param, float or int) (default=1e-4)
Returns:

An expression for the smoothed absolute value operation.

idaes.core.util.math.smooth_max(a, b, eps=0.0001)[source]

Smooth maximum operator, using smooth_abs operator.

\[max(a, b) = 0.5*(a+b + |a-b|)\]
Parameters:
  • a – first term in max function
  • b – second term in max function
  • eps – smoothing parameter (Param or float, default = 1e-4)
Returns:

An expression for the smoothed maximum operation.

idaes.core.util.math.smooth_min(a, b, eps=0.0001)[source]

Smooth minimum operator, using smooth_abs operator.

\[max(a, b) = 0.5*(a+b - |a-b|)\]
Parameters:
  • a – first term in min function
  • b – second term in min function
  • eps – smoothing parameter (Param or float, default = 1e-4)
Returns:

An expression for the smoothed minimum operation.

idaes.core.util.math.smooth_minmax(a, b, eps=0.0001, sense='max')[source]

General function for creating an expression for a smooth minimum or maximum. Uses the smooth_abs operator.

\[minmax(a, b) = 0.5*(a+b +- |a-b|)\]
Parameters:
  • a – first term in mix or max function (Pyomo component, float or int)
  • b – second term in min or max function (Pyomo component, float or int)
  • eps – smoothing parameter (Param, float or int) (default=1e-4)
  • sense – ‘mim’ or ‘max’ (default = ‘max’)
Returns:

An expression for the smoothed minimum or maximum operation.

idaes.core.util.misc module

This module contains miscellaneous utility functions for use in IDAES models.

idaes.core.util.misc.TagReference(s, description='')[source]

Create a Pyomo reference with an added description string attribute to describe the reference. The intended use for these references is to create a time-indexed reference to variables in a model corresponding to plant measurment tags.

Parameters:
  • s – Pyomo time slice of a variable or expression
  • description (str) – A description the measurment
Returns:

A Pyomo Reference object with an added doc attribute

idaes.core.util.misc.add_object_reference(self, local_name, remote_object)[source]

Method to create a reference in the local model to a remote Pyomo object. This method should only be used where Pyomo Reference objects are not suitable (such as for referencing scalar Pyomo objects where the None index is undesirable).

Parameters:
  • local_name – name to use for local reference (str)
  • remote_object – object to make a reference to
Returns:

None

idaes.core.util.misc.copy_port_values(destination, source)[source]

Copy the variable values in the source port to the destination port. The ports must containt the same variables.

Parameters:
  • (pyomo.Port) – Copy values from this port
  • (pyomo.Port) – Copy values to this port
Returns:

None

idaes.core.util.misc.extract_data(data_dict)[source]

General method that returns a rule to extract data from a python dictionary. This method allows the param block to have a database for a parameter but extract a subset of this data to initialize a Pyomo param object.

idaes.core.util.misc.svg_tag(tags, svg, outfile=None, idx=None, tag_map=None, show_tags=False)[source]

Replace text in a SVG with tag values for the model. This works by looking for text elements in the SVG with IDs that match the tags or are in tag_map.

Parameters:
  • tags – A dictionary where the key is the tag and the value is a Pyomo Refernce. The refernce could be indexed. In yypical IDAES applications the references would be indexed by time.
  • svg – a file pointer or a string continaing svg contents
  • outfile – a file name to save the results, if None don’t save
  • idx – if None not indexed, otherwise an index in the indexing set of the reference
  • tag_map – dictionary with svg id keys and tag values, to map svg ids to tags
  • show_tags – Put tag labels of the diagram instead of numbers
Returns:

String for SVG

idaes.core.util.model_serializer module

Functions for saving and loading Pyomo objects to json

class idaes.core.util.model_serializer.Counter[source]

This is a counter object, which is an easy way to pass an interger pointer around between methods.

class idaes.core.util.model_serializer.StoreSpec(classes=((<class 'pyomo.core.base.param.Param'>, ('_mutable', )), (<class 'pyomo.core.base.var.Var'>, ()), (<class 'pyomo.core.base.component.Component'>, ('active', ))), data_classes=((<class 'pyomo.core.base.var._VarData'>, ('fixed', 'stale', 'value', 'lb', 'ub')), (<class 'pyomo.core.base.param._ParamData'>, ('value', )), (<class 'int'>, ('value', )), (<class 'float'>, ('value', )), (<class 'pyomo.core.base.component.ComponentData'>, ('active', ))), skip_classes=(<class 'pyomo.core.base.external.ExternalFunction'>, <class 'pyomo.core.base.sets.Set'>, <class 'pyomo.network.port.Port'>, <class 'pyomo.core.base.expression.Expression'>, <class 'pyomo.core.base.rangeset.RangeSet'>), ignore_missing=True, suffix=True, suffix_filter=None)[source]

A StoreSpec object tells the serializer functions what to read or write. The default settings will produce a StoreSpec configured to load/save the typical attributes required to load/save a model state.

Parameters:
  • classes – A list of classes to save. Each class is represented by a list (or tupple) containing the following elements: (1) class (compared using isinstance) (2) attribute list or None, an emptry list store the object, but none of its attributes, None will not store objects of this class type (3) optional load filter function. The load filter function returns a list of attributes to read based on the state of an object and its saved state. The allows, for example, loading values for unfixed variables, or only loading values whoes current value is less than one. The filter function only applies to load not save. Filter functions take two arguments (a) the object (current state) and (b) the dictionary containing the saved state of an object. More specific classes should come before more general classes. For example if an obejct is a HeatExchanger and a UnitModel, and HeatExchanger is listed first, it will follow the HeatExchanger settings. If UnitModel is listed first in the classes list, it will follow the UnitModel settings.
  • data_classes – This takes the same form as the classes argument. This is for component data classes.
  • skip_classes – This is a list of classes to skip. If a class appears in the skip list, but also appears in the classes argument, the classes argument will override skip_classes. The use for this is to specifically exclude certain classes that would get caught by more general classes (e.g. UnitModel is in the class list, but you want to exclude HeatExchanger which is derived from UnitModel).
  • ignore_missing – If True will ignore a component or attribute that exists in the model, but not in the stored state. If false an excpetion will be raised for things in the model that should be loaded but aren’t in the stored state. Extra items in the stored state will not raise an exception regaurdless of this argument.
  • suffix – If True store suffixes and component ids. If false, don’t store suffixes.
  • suffix_filter – None to store all siffixes if suffix=True, or a list of suffixes to store if suffix=True
classmethod bound()[source]

Returns a StoreSpec object to store variable bounds only.

get_class_attr_list(o)[source]

Look up what attributes to save/load for an Component object. :param o: Object to look up attribute list for.

Returns:A list of attributes and a filter function for object type
get_data_class_attr_list(o)[source]

Look up what attributes to save/load for an ComponentData object. :param o: Object to look up attribute list for.

Returns:A list of attributes and a filter function for object type
classmethod isfixed()[source]

Returns a StoreSpec object to store if variables are fixed.

set_read_callback(attr, cb=None)[source]

Set a callback to set an attribute, when reading from json or dict.

set_write_callback(attr, cb=None)[source]

Set a callback to get an attribute, when writing to json or dict.

classmethod value()[source]

Returns a StoreSpec object to store variable values only.

classmethod value_isfixed(only_fixed)[source]

Return a StoreSpec object to store variable values and if fixed.

Parameters:only_fixed – Only load fixed variable values
classmethod value_isfixed_isactive(only_fixed)[source]

Retur a StoreSpec object to store variable values, if variables are fixed and if components are active.

Parameters:only_fixed – Only load fixed variable values
idaes.core.util.model_serializer.component_data_from_dict(sd, o, wts)[source]

Component data to a dict.

idaes.core.util.model_serializer.component_data_to_dict(o, wts)[source]

Component data to a dict.

idaes.core.util.model_serializer.from_json(o, sd=None, fname=None, s=None, wts=None, gz=False)[source]

Load the state of a Pyomo component state from a dictionary, json file, or json string. Must only specify one of sd, fname, or s as a non-None value. This works by going through the model and loading the state of each sub-compoent of o. If the saved state contains extra information, it is ignored. If the save state doesn’t contain an enetry for a model component that is to be loaded an error will be raised, unless ignore_missing = True.

Parameters:
  • o – Pyomo component to for which to load state
  • sd – State dictionary to load, if None, check fname and s
  • fname – JSON file to load, only used if sd is None
  • s – JSON string to load only used if both sd and fname are None
  • wts – StoreSpec object specifying what to load
  • gz – If True assume the file specified by fname is gzipped. The default is False.
Returns:

Dictionary with some perfomance information. The keys are “etime_load_file”, how long in seconds it took to load the json file “etime_read_dict”, how long in seconds it took to read models state “etime_read_suffixes”, how long in seconds it took to read suffixes

idaes.core.util.model_serializer.to_json(o, fname=None, human_read=False, wts=None, metadata={}, gz=False, return_dict=False, return_json_string=False)[source]

Save the state of a model to a Python dictionary, and optionally dump it to a json file. To load a model state, a model with the same structure must exist. The model itself cannot be recreated from this.

Parameters:
  • o – The Pyomo component object to save. Usually a Pyomo model, but could also be a subcomponent of a model (usually a sub-block).
  • fname – json file name to save model state, if None only create python dict
  • gz – If fname is given and gv is True gzip the json file. The default is False.
  • human_read – if True, add indents and spacing to make the json file more readable, if false cut out whitespace and make as compact as possilbe
  • metadata – A dictionary of addtional metadata to add.
  • wts – is What To Save, this is a StoreSpec object that specifies what object types and attributes to save. If None, the default is used which saves the state of the compelte model state.
  • metadata – addtional metadata to save beyond the standard format_version, date, and time.
  • return_dict – default is False if true returns a dictionary representation
  • return_json_string – default is False returns a json string
Returns:

If return_dict is True returns a dictionary serialization of the Pyomo component. If return_dict is False and return_json_string is True returns a json string dump of the dict. If fname is given the dictionary is also written to a json file. If gz is True and fname is given, writes a gzipped json file.

idaes.core.util.tables module
idaes.core.util.tables.state_table(m, attributes, heading=None)[source]

Create a Pandas dataframe that shows the material state in every state block.

Parameters:
  • m (Block) – Pyomo model or block from which to create a state block table
  • attributes (list or tuple of strings) – Attributes to report from a StateBlock, can be a Var, Param, or Expression. If an attribute doesn’t exist or doesn’t have a valid value, it will be treated as missing data.
  • heading (list or tuple of srings) – A list of strings that will be used as column headings. If None the attribute names will be used.
Returns:

A Pandas DataFrame with a StateBlock table

Return type:

(DataFrame)

idaes.core.util.tables.stream_table(streams, attributes, heading=None)[source]

Create a Pandas DataFrame that shows the material state in streams.

Parameters:
  • streams (dict) – A dictionary with stream name keys and StateBlockData objects for values. The stream names do not need to correspond to Arcs in the flowhseet. Any name can be associated with a state block. Use an OrderedDict to show the streams in a specific order, otherwise the dataframe can be sorted later.
  • attributes (list or tuple of strings) – Attributes to report from a StateBlock, can be a Var, Param, or Expression. If an attribute doesn’t exist or doesn’t have a valid value, it will be treated as missing data.
  • heading (list or tuple of srings) – A list of strings that will be used as column headings. If None the attribute names will be used.
Returns:

A Pandas dataframe containing a stream table

Return type:

(DataFrame)

Submodules
idaes.core.control_volume0d module

Base class for control volumes

class idaes.core.control_volume0d.ControlVolume0DBlock(*args, **kwargs)

ControlVolume0DBlock is a specialized Pyomo block for IDAES non-discretized control volume blocks, and contains instances of ControlVolume0DBlockData.

ControlVolume0DBlock should be used for any control volume with a defined volume and distinct inlets and outlets which does not require spatial discretization. This encompases most basic unit models used in process modeling.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic, default - useDefault. Valid values: { useDefault - get flag from parent, True - set as a dynamic model, False - set as a steady-state model}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    reaction_package
    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}
    reaction_package_args
    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}
    auto_construct
    If set to True, this argument will trigger the auto_construct method which will attempt to construct a set of material, energy and momentum balance equations based on the parent unit’s config block. The parent unit must have a config block which derives from CONFIG_Base, default - False. Valid values: { True - use automatic construction, False - do not use automatic construciton.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(ControlVolume0DBlock) New instance

class idaes.core.control_volume0d.ControlVolume0DBlockData(component)[source]

0-Dimensional (Non-Discretised) ControlVolume Class

This class forms the core of all non-discretized IDAES models. It provides methods to build property and reaction blocks, and add mass, energy and momentum balances. The form of the terms used in these constraints is specified in the chosen property package.

add_geometry()[source]

Method to create volume Var in ControlVolume.

Parameters:None
Returns:None
add_phase_component_balances(has_rate_reactions=False, has_equilibrium_reactions=False, has_phase_equilibrium=False, has_mass_transfer=False, custom_molar_term=None, custom_mass_term=None)[source]

This method constructs a set of 0D material balances indexed by time, phase and component.

Parameters:
  • has_rate_reactions – whether default generation terms for rate reactions should be included in material balances
  • has_equilibrium_reactions – whether generation terms should for chemical equilibrium reactions should be included in material balances
  • has_phase_equilibrium – whether generation terms should for phase equilibrium behaviour should be included in material balances
  • has_mass_transfer – whether generic mass transfer terms should be included in material balances
  • custom_molar_term – a Pyomo Expression representing custom terms to be included in material balances on a molar basis. Expression must be indexed by time, phase list and component list
  • custom_mass_term – a Pyomo Expression representing custom terms to be included in material balances on a mass basis. Expression must be indexed by time, phase list and component list
Returns:

Constraint object representing material balances

add_phase_energy_balances(*args, **kwargs)[source]

Method for adding energy balances (including kinetic energy) indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_enthalpy_balances(*args, **kwargs)[source]

Method for adding enthalpy balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_momentum_balances(*args, **kwargs)[source]

Method for adding momentum balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_pressure_balances(*args, **kwargs)[source]

Method for adding pressure balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_reaction_blocks(has_equilibrium=None)[source]

This method constructs the reaction block for the control volume.

Parameters:
  • has_equilibrium – indicates whether equilibrium calculations will be required in reaction block
  • package_arguments – dict-like object of arguments to be passed to reaction block as construction arguments
Returns:

None

add_state_blocks(information_flow=<FlowDirection.forward: 1>, has_phase_equilibrium=None)[source]

This method constructs the inlet and outlet state blocks for the control volume.

Parameters:
  • information_flow – a FlowDirection Enum indicating whether information flows from inlet-to-outlet or outlet-to-inlet
  • has_phase_equilibrium – indicates whether equilibrium calculations will be required in state blocks
  • package_arguments – dict-like object of arguments to be passed to state blocks as construction arguments
Returns:

None

add_total_component_balances(has_rate_reactions=False, has_equilibrium_reactions=False, has_phase_equilibrium=False, has_mass_transfer=False, custom_molar_term=None, custom_mass_term=None)[source]

This method constructs a set of 0D material balances indexed by time and component.

Parameters:
  • - whether default generation terms for rate (has_rate_reactions) – reactions should be included in material balances
  • - whether generation terms should for (has_equilibrium_reactions) – chemical equilibrium reactions should be included in material balances
  • - whether generation terms should for phase (has_phase_equilibrium) – equilibrium behaviour should be included in material balances
  • - whether generic mass transfer terms should be (has_mass_transfer) – included in material balances
  • - a Pyomo Expression representing custom terms to (custom_mass_term) – be included in material balances on a molar basis. Expression must be indexed by time, phase list and component list
  • - a Pyomo Expression representing custom terms to – be included in material balances on a mass basis. Expression must be indexed by time, phase list and component list
Returns:

Constraint object representing material balances

add_total_element_balances(has_rate_reactions=False, has_equilibrium_reactions=False, has_phase_equilibrium=False, has_mass_transfer=False, custom_elemental_term=None)[source]

This method constructs a set of 0D element balances indexed by time.

Parameters:
  • - whether default generation terms for rate (has_rate_reactions) – reactions should be included in material balances
  • - whether generation terms should for (has_equilibrium_reactions) – chemical equilibrium reactions should be included in material balances
  • - whether generation terms should for phase (has_phase_equilibrium) – equilibrium behaviour should be included in material balances
  • - whether generic mass transfer terms should be (has_mass_transfer) – included in material balances
  • - a Pyomo Expression representing custom (custom_elemental_term) – terms to be included in material balances on a molar elemental basis. Expression must be indexed by time and element list
Returns:

Constraint object representing material balances

add_total_energy_balances(*args, **kwargs)[source]

Method for adding a total energy balance (including kinetic energy) to the control volume.

See specific control volume documentation for details.

add_total_enthalpy_balances(has_heat_of_reaction=False, has_heat_transfer=False, has_work_transfer=False, custom_term=None)[source]

This method constructs a set of 0D enthalpy balances indexed by time and phase.

Parameters:
  • - whether terms for heat of reaction should (has_heat_of_reaction) – be included in enthalpy balance
  • - whether terms for heat transfer should be (has_heat_transfer) – included in enthalpy balances
  • - whether terms for work transfer should be (has_work_transfer) – included in enthalpy balances
  • - a Pyomo Expression representing custom terms to (custom_term) – be included in enthalpy balances. Expression must be indexed by time and phase list
Returns:

Constraint object representing enthalpy balances

add_total_material_balances(*args, **kwargs)[source]

Method for adding a total material balance to the control volume.

See specific control volume documentation for details.

add_total_momentum_balances(*args, **kwargs)[source]

Method for adding a total momentum balance to the control volume.

See specific control volume documentation for details.

add_total_pressure_balances(has_pressure_change=False, custom_term=None)[source]

This method constructs a set of 0D pressure balances indexed by time.

Parameters:
  • - whether terms for pressure change should be (has_pressure_change) – included in enthalpy balances
  • - a Pyomo Expression representing custom terms to (custom_term) – be included in pressure balances. Expression must be indexed by time
Returns:

Constraint object representing pressure balances

build()[source]

Build method for ControlVolume0DBlock blocks.

Returns:None
initialize(state_args=None, outlvl=0, optarg=None, solver='ipopt', hold_state=True)[source]

Initialisation routine for 0D control volume (default solver ipopt)

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl – sets output level of initialisation routine. Valid values: 0 - no output (default), 1 - return solver state for each step in routine, 2 - include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default=None)
  • solver – str indicating whcih solver to use during initialization (default = ‘ipopt’)
  • hold_state – flag indicating whether the initialization routine should unfix any state variables fixed during initialization, default - True. Valid values: True - states variables are not unfixed, and a dict of returned containing flags for which states were fixed during initialization, False - state variables are unfixed after initialization by calling the release_state method.
Returns:

If hold_states is True, returns a dict containing flags for which states were fixed during initialization.

model_check()[source]

This method executes the model_check methods on the associated state blocks (if they exist). This method is generally called by a unit model as part of the unit’s model_check method.

Parameters:None
Returns:None
release_state(flags, outlvl=0)[source]

Method to release state variables fixed during initialisation.

Keyword Arguments:
 
  • flags – dict containing information of which state variables were fixed during initialization, and should now be unfixed. This dict is returned by initialize if hold_state = True.
  • outlvl – sets output level of logging
Returns:

None

idaes.core.control_volume1d module

Base class for control volumes

class idaes.core.control_volume1d.ControlVolume1DBlock(*args, **kwargs)

ControlVolume1DBlock is a specialized Pyomo block for IDAES control volume blocks discretized in one spatial direction, and contains instances of ControlVolume1DBlockData.

ControlVolume1DBlock should be used for any control volume with a defined volume and distinct inlets and outlets where there is a single spatial domain parallel to the material flow direction. This encompases unit operations such as plug flow reactors and pipes.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic, default - useDefault. Valid values: { useDefault - get flag from parent, True - set as a dynamic model, False - set as a steady-state model}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    reaction_package
    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}
    reaction_package_args
    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}
    auto_construct
    If set to True, this argument will trigger the auto_construct method which will attempt to construct a set of material, energy and momentum balance equations based on the parent unit’s config block. The parent unit must have a config block which derives from CONFIG_Base, default - False. Valid values: { True - use automatic construction, False - do not use automatic construciton.}
    area_definition
    Argument defining whether area variable should be spatially variant or not. default - DistributedVars.uniform. Valid values: { DistributedVars.uniform - area does not vary across spatial domian, DistributedVars.variant - area can vary over the domain and is indexed by time and space.}
    transformation_method
    Method to use to transform domain. Must be a method recognised by the Pyomo TransformationFactory.
    transformation_scheme
    Scheme to use when transformating domain. See Pyomo documentation for supported schemes.
    finite_elements
    Number of finite elements to use in transformation (equivalent to Pyomo nfe argument).
    collocation_points
    Number of collocation points to use (equivalent to Pyomo ncp argument).
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(ControlVolume1DBlock) New instance

class idaes.core.control_volume1d.ControlVolume1DBlockData(component)[source]

1-Dimensional ControlVolume Class

This class forms the core of all 1-D IDAES models. It provides methods to build property and reaction blocks, and add mass, energy and momentum balances. The form of the terms used in these constraints is specified in the chosen property package.

add_geometry(length_domain=None, length_domain_set=[0.0, 1.0], flow_direction=<FlowDirection.forward: 1>)[source]

Method to create spatial domain and volume Var in ControlVolume.

Parameters:
  • - (length_domain_set) – domain for the ControlVolume. If not provided, a new ContinuousSet will be created (default=None). ContinuousSet should be normalized to run between 0 and 1.
  • - – a new ContinuousSet if length_domain is not provided (default = [0.0, 1.0]).
  • - argument indicating direction of material flow (flow_direction) –
    relative to length domain. Valid values:
    • FlowDirection.forward (default), flow goes from 0 to 1.
    • FlowDirection.backward, flow goes from 1 to 0
Returns:

None

add_phase_component_balances(has_rate_reactions=False, has_equilibrium_reactions=False, has_phase_equilibrium=False, has_mass_transfer=False, custom_molar_term=None, custom_mass_term=None)[source]

This method constructs a set of 1D material balances indexed by time, length, phase and component.

Parameters:
  • has_rate_reactions – whether default generation terms for rate reactions should be included in material balances
  • has_equilibrium_reactions – whether generation terms should for chemical equilibrium reactions should be included in material balances
  • has_phase_equilibrium – whether generation terms should for phase equilibrium behaviour should be included in material balances
  • has_mass_transfer – whether generic mass transfer terms should be included in material balances
  • custom_molar_term – a Pyomo Expression representing custom terms to be included in material balances on a molar basis. Expression must be indexed by time, length domain, phase list and component list
  • custom_mass_term – a Pyomo Expression representing custom terms to be included in material balances on a mass basis. Expression must be indexed by time, length domain, phase list and component list
Returns:

Constraint object representing material balances

add_phase_energy_balances(*args, **kwargs)[source]

Method for adding energy balances (including kinetic energy) indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_enthalpy_balances(*args, **kwargs)[source]

Method for adding enthalpy balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_momentum_balances(*args, **kwargs)[source]

Method for adding momentum balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_pressure_balances(*args, **kwargs)[source]

Method for adding pressure balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_reaction_blocks(has_equilibrium=None)[source]

This method constructs the reaction block for the control volume.

Parameters:
  • has_equilibrium – indicates whether equilibrium calculations will be required in reaction block
  • package_arguments – dict-like object of arguments to be passed to reaction block as construction arguments
Returns:

None

add_state_blocks(information_flow=<FlowDirection.forward: 1>, has_phase_equilibrium=None)[source]

This method constructs the state blocks for the control volume.

Parameters:
  • information_flow – a FlowDirection Enum indicating whether information flows from inlet-to-outlet or outlet-to-inlet
  • has_phase_equilibrium – indicates whether equilibrium calculations will be required in state blocks
  • package_arguments – dict-like object of arguments to be passed to state blocks as construction arguments
Returns:

None

add_total_component_balances(has_rate_reactions=False, has_equilibrium_reactions=False, has_phase_equilibrium=False, has_mass_transfer=False, custom_molar_term=None, custom_mass_term=None)[source]

This method constructs a set of 1D material balances indexed by time length and component.

Parameters:
  • has_rate_reactions – whether default generation terms for rate reactions should be included in material balances
  • has_equilibrium_reactions – whether generation terms should for chemical equilibrium reactions should be included in material balances
  • has_phase_equilibrium – whether generation terms should for phase equilibrium behaviour should be included in material balances
  • has_mass_transfer – whether generic mass transfer terms should be included in material balances
  • custom_molar_term – a Pyomo Expression representing custom terms to be included in material balances on a molar basis. Expression must be indexed by time, length domain and component list
  • custom_mass_term – a Pyomo Expression representing custom terms to be included in material balances on a mass basis. Expression must be indexed by time, length domain and component list
Returns:

Constraint object representing material balances

add_total_element_balances(has_rate_reactions=False, has_equilibrium_reactions=False, has_phase_equilibrium=False, has_mass_transfer=False, custom_elemental_term=None)[source]

This method constructs a set of 1D element balances indexed by time and length.

Parameters:
  • - whether default generation terms for rate (has_rate_reactions) – reactions should be included in material balances
  • - whether generation terms should for (has_equilibrium_reactions) – chemical equilibrium reactions should be included in material balances
  • - whether generation terms should for phase (has_phase_equilibrium) – equilibrium behaviour should be included in material balances
  • - whether generic mass transfer terms should be (has_mass_transfer) – included in material balances
  • - a Pyomo Expression representing custom (custom_elemental_term) – terms to be included in material balances on a molar elemental basis. Expression must be indexed by time, length and element list
Returns:

Constraint object representing material balances

add_total_energy_balances(*args, **kwargs)[source]

Method for adding a total energy balance (including kinetic energy) to the control volume.

See specific control volume documentation for details.

add_total_enthalpy_balances(has_heat_of_reaction=False, has_heat_transfer=False, has_work_transfer=False, custom_term=None)[source]

This method constructs a set of 1D enthalpy balances indexed by time and phase.

Parameters:
  • - whether terms for heat of reaction should (has_heat_of_reaction) – be included in enthalpy balance
  • - whether terms for heat transfer should be (has_heat_transfer) – included in enthalpy balances
  • - whether terms for work transfer should be (has_work_transfer) – included in enthalpy balances
  • - a Pyomo Expression representing custom terms to (custom_term) – be included in enthalpy balances. Expression must be indexed by time, length and phase list
Returns:

Constraint object representing enthalpy balances

add_total_material_balances(*args, **kwargs)[source]

Method for adding a total material balance to the control volume.

See specific control volume documentation for details.

add_total_momentum_balances(*args, **kwargs)[source]

Method for adding a total momentum balance to the control volume.

See specific control volume documentation for details.

add_total_pressure_balances(has_pressure_change=False, custom_term=None)[source]

This method constructs a set of 1D pressure balances indexed by time.

Parameters:
  • - whether terms for pressure change should be (has_pressure_change) – included in enthalpy balances
  • - a Pyomo Expression representing custom terms to (custom_term) – be included in pressure balances. Expression must be indexed by time and length domain
Returns:

Constraint object representing pressure balances

apply_transformation()[source]

Method to apply DAE transformation to the Control Volume length domain. Transformation applied will be based on the Control Volume configuration arguments.

build()[source]

Build method for ControlVolume1DBlock blocks.

Returns:None
initialize(state_args=None, outlvl=0, optarg=None, solver='ipopt', hold_state=True)[source]

Initialisation routine for 1D control volume (default solver ipopt)

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl – sets output level of initialisation routine. Valid values: 0 - no output (default), 1 - return solver state for each step in routine, 2 - include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default=None)
  • solver – str indicating whcih solver to use during initialization (default = ‘ipopt’)
  • hold_state – flag indicating whether the initialization routine should unfix any state variables fixed during initialization, default - True. Valid values: True - states variables are not unfixed, and a dict of returned containing flags for which states were fixed during initialization, False - state variables are unfixed after initialization by calling the release_state method.
Returns:

If hold_states is True, returns a dict containing flags for which states were fixed during initialization else the release state is triggered.

model_check()[source]

This method executes the model_check methods on the associated state blocks (if they exist). This method is generally called by a unit model as part of the unit’s model_check method.

Parameters:None
Returns:None
release_state(flags, outlvl=0)[source]

Method to release state variables fixed during initialisation.

Keyword Arguments:
 
  • flags – dict containing information of which state variables were fixed during initialization, and should now be unfixed. This dict is returned by initialize if hold_state = True.
  • outlvl – sets output level of logging
Returns:

None

idaes.core.control_volume_base module

Base class for control volumes

class idaes.core.control_volume_base.ControlVolume(*args, **kwargs)

This class is not usually used directly. Use ControlVolume0DBlock or ControlVolume1DBlock instead.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic, default - useDefault. Valid values: { useDefault - get flag from parent, True - set as a dynamic model, False - set as a steady-state model}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    reaction_package
    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}
    reaction_package_args
    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}
    auto_construct
    If set to True, this argument will trigger the auto_construct method which will attempt to construct a set of material, energy and momentum balance equations based on the parent unit’s config block. The parent unit must have a config block which derives from CONFIG_Base, default - False. Valid values: { True - use automatic construction, False - do not use automatic construciton.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(ControlVolume) New instance

class idaes.core.control_volume_base.ControlVolumeBlockData(component)[source]

The ControlVolumeBlockData Class forms the base class for all IDAES ControlVolume models. The purpose of this class is to automate the tasks common to all control volume blockss and ensure that the necessary attributes of a control volume block are present.

The most signfiicant role of the ControlVolumeBlockData class is to set up the construction arguments for the control volume block, automatically link to the time domain of the parent block, and to get the information about the property and reaction packages.

add_energy_balances(balance_type=<EnergyBalanceType.enthalpyPhase: 1>, **kwargs)[source]

General method for adding energy balances to a control volume. This method makes calls to specialised sub-methods for each type of energy balance.

Parameters:
  • balance_type (EnergyBalanceType) – Enum indicating which type of energy balance should be constructed.
  • has_heat_of_reaction (bool) – whether terms for heat of reaction should be included in energy balance
  • has_heat_transfer (bool) – whether generic heat transfer terms should be included in energy balances
  • has_work_transfer (bool) – whether generic mass transfer terms should be included in energy balances
  • custom_term (Expression) – a Pyomo Expression representing custom terms to be included in energy balances
Returns:

Constraint objects constructed by sub-method

add_geometry(*args, **kwargs)[source]

Method for defining the geometry of the control volume.

See specific control volume documentation for details.

add_material_balances(balance_type=<MaterialBalanceType.componentPhase: 1>, **kwargs)[source]

General method for adding material balances to a control volume. This method makes calls to specialised sub-methods for each type of material balance.

Parameters:
  • - MaterialBalanceType Enum indicating which type of (balance_type) – material balance should be constructed.
  • - whether default generation terms for rate (has_rate_reactions) – reactions should be included in material balances
  • - whether generation terms should for (has_equilibrium_reactions) – chemical equilibrium reactions should be included in material balances
  • - whether generation terms should for phase (has_phase_equilibrium) – equilibrium behaviour should be included in material balances
  • - whether generic mass transfer terms should be (has_mass_transfer) – included in material balances
  • - a Pyomo Expression representing custom terms to (custom_mass_term) – be included in material balances on a molar basis.
  • - a Pyomo Expression representing custom terms to – be included in material balances on a mass basis.
Returns:

Constraint objects constructed by sub-method

add_momentum_balances(balance_type=<MomentumBalanceType.pressureTotal: 1>, **kwargs)[source]

General method for adding momentum balances to a control volume. This method makes calls to specialised sub-methods for each type of momentum balance.

Parameters:
  • balance_type (MomentumBalanceType) – Enum indicating which type of momentum balance should be constructed.
  • has_pressure_change (bool) – whether default generation terms for pressure change should be included in momentum balances
  • custom_term (Expression) – a Pyomo Expression representing custom terms to be included in momentum balances
Returns:

Constraint objects constructed by sub-method

add_phase_component_balances(*args, **kwargs)[source]

Method for adding material balances indexed by phase and component to the control volume.

See specific control volume documentation for details.

add_phase_energy_balances(*args, **kwargs)[source]

Method for adding energy balances (including kinetic energy) indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_enthalpy_balances(*args, **kwargs)[source]

Method for adding enthalpy balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_momentum_balances(*args, **kwargs)[source]

Method for adding momentum balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_phase_pressure_balances(*args, **kwargs)[source]

Method for adding pressure balances indexed by phase to the control volume.

See specific control volume documentation for details.

add_reaction_blocks(*args, **kwargs)[source]

Method for adding ReactionBlocks to the control volume.

See specific control volume documentation for details.

add_state_blocks(*args, **kwargs)[source]

Method for adding StateBlocks to the control volume.

See specific control volume documentation for details.

add_total_component_balances(*args, **kwargs)[source]

Method for adding material balances indexed by component to the control volume.

See specific control volume documentation for details.

add_total_element_balances(*args, **kwargs)[source]

Method for adding total elemental material balances indexed to the control volume.

See specific control volume documentation for details.

add_total_energy_balances(*args, **kwargs)[source]

Method for adding a total energy balance (including kinetic energy) to the control volume.

See specific control volume documentation for details.

add_total_enthalpy_balances(*args, **kwargs)[source]

Method for adding a total enthalpy balance to the control volume.

See specific control volume documentation for details.

add_total_material_balances(*args, **kwargs)[source]

Method for adding a total material balance to the control volume.

See specific control volume documentation for details.

add_total_momentum_balances(*args, **kwargs)[source]

Method for adding a total momentum balance to the control volume.

See specific control volume documentation for details.

add_total_pressure_balances(*args, **kwargs)[source]

Method for adding a total pressure balance to the control volume.

See specific control volume documentation for details.

build()[source]

General build method for Control Volumes blocks. This method calls a number of sub-methods which automate the construction of expected attributes of all ControlVolume blocks.

Inheriting models should call super().build.

Parameters:None
Returns:None
class idaes.core.control_volume_base.EnergyBalanceType[source]

An enumeration.

class idaes.core.control_volume_base.FlowDirection[source]

An enumeration.

class idaes.core.control_volume_base.MaterialBalanceType[source]

An enumeration.

class idaes.core.control_volume_base.MomentumBalanceType[source]

An enumeration.

idaes.core.flowsheet_model module

This module contains the base class for constructing flowsheet models in the IDAES modeling framework.

class idaes.core.flowsheet_model.FlowsheetBlock(*args, **kwargs)

FlowsheetBlock is a specialized Pyomo block for IDAES flowsheet models, and contains instances of FlowsheetBlockData.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic, default - useDefault. Valid values: { useDefault - get flag from parent or False, True - set as a dynamic model, False - set as a steady-state model.}
    time
    Pointer to the time domain for the flowsheet. Users may provide an existing time domain from another flowsheet, otherwise the flowsheet will search for a parent with a time domain or create a new time domain and reference it here.
    time_set
    Set of points for initializing time domain. This should be a list of floating point numbers, default - [0].
    default_property_package
    Indicates the default property package to be used by models within this flowsheet if not otherwise specified, default - None. Valid values: { None - no default property package, a ParameterBlock object.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(FlowsheetBlock) New instance

class idaes.core.flowsheet_model.FlowsheetBlockData(component)[source]

The FlowsheetBlockData Class forms the base class for all IDAES process flowsheet models. The main purpose of this class is to automate the tasks common to all flowsheet models and ensure that the necessary attributes of a flowsheet model are present.

The most signfiicant role of the FlowsheetBlockData class is to automatically create the time domain for the flowsheet.

build()[source]

General build method for FlowsheetBlockData. This method calls a number of sub-methods which automate the construction of expected attributes of flowsheets.

Inheriting models should call super().build.

Parameters:None
Returns:None
is_flowsheet()[source]

Method which returns True to indicate that this component is a flowsheet.

Parameters:None
Returns:True
model_check()[source]

This method runs model checks on all unit models in a flowsheet.

This method searches for objects which inherit from UnitModelBlockData and executes the model_check method if it exists.

Parameters:None
Returns:None
idaes.core.process_base module

Base for IDAES process model objects.

class idaes.core.process_base.ProcessBaseBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys

  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(ProcessBaseBlock) New instance

class idaes.core.process_base.ProcessBlockData(component)[source]

Base class for most IDAES process models and classes.

The primary purpose of this class is to create the local config block to handle arguments provided by the user when constructing an object and to ensure that these arguments are stored in the config block.

Additionally, this class contains a number of methods common to all IDAES classes.

build()[source]

The build method is called by the default ProcessBlock rule. If a rule is sepecified other than the default it is important to call ProcessBlockData’s build method to put information from the “default” and “initialize” arguments to a ProcessBlock derived class into the BlockData object’s ConfigBlock.

The the build method should usually be overloaded in a subclass derived from ProcessBlockData. This method would generally add Pyomo components such as variables, expressions, and constraints to the object. It is important for build() methods implimented in derived classes to call build() from the super class.

Parameters:None
Returns:None
fix_initial_conditions(state='steady-state')[source]

This method fixes the initial conditions for dynamic models.

Parameters:state – initial state to use for simulation (default = ‘steady-state’)
Returns :
None
flowsheet()[source]

This method returns the components parent flowsheet object, i.e. the flowsheet component to which the model is attached. If the component has no parent flowsheet, the method returns None.

Parameters:None
Returns:Flowsheet object or None
unfix_initial_conditions()[source]

This method unfixed the initial conditions for dynamic models.

Parameters:None
Returns :
None
idaes.core.process_block module

The process_block module simplifies inheritance of Pyomo blocks. The main reason to subclass a Pyomo block is to create a block that comes with pre-defined model equations. This is used in the IDAES modeling framework to create modular process model blocks.

class idaes.core.process_block.ProcessBlock(*args, **kwargs)[source]

ProcessBlock is a Pyomo Block that is part of a system to make Pyomo Block easier to subclass. The main difference between a Pyomo Block and ProcessBlock from the user perspective is that a ProcessBlock has a rule assigned by default that calls the build() method for the contained ProcessBlockData objects. The default rule can be overridden, but the new rule should always call build() for the ProcessBlockData object.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) – Default ProcessBlockData config
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(ProcessBlock) New instance

classmethod base_class_module()[source]

Return module of the associated ProcessBase class.

Returns:(str) Module of the class.
Raises:AttributeError, if no base class module was set, e.g. this class – was not wrapped by the declare_process_block_class decorator.
classmethod base_class_name()[source]

Name given by the user to the ProcessBase class.

Returns:(str) Name of the class.
Raises:AttributeError, if no base class name was set, e.g. this class – was not wrapped by the declare_process_block_class decorator.
idaes.core.process_block.declare_process_block_class(name, block_class=<class 'idaes.core.process_block.ProcessBlock'>, doc='')[source]

Declare a new ProcessBlock subclass.

This is a decorator function for a class definition, where the class is derived from Pyomo’s _BlockData. It creates a ProcessBlock subclass to contain the decorated class. The only requirment is that the subclass of _BlockData contain a build() method. The purpose of this decorator is to simplify subclassing Pyomo’s block class.

Parameters:
  • name – name of class to create
  • block_class – ProcessBlock or a subclass of ProcessBlock, this allows you to use a subclass of ProcessBlock if needed. The typical use case for Subclassing ProcessBlock is to impliment methods that operate on elements of an indexed block.
  • doc – Documentation for the class. This should play nice with sphinx.
Returns:

Decorator function

idaes.core.property_base module

This module contains classes for property blocks and property parameter blocks.

class idaes.core.property_base.PhysicalParameterBlock(component)[source]

This is the base class for thermophysical parameter blocks. These are blocks that contain a set of parameters associated with a specific thermophysical property package, and are linked to by all instances of that property package.

build()[source]

General build method for PropertyParameterBlocks. Inheriting models should call super().build.

Parameters:None
Returns:None
class idaes.core.property_base.StateBlock(*args, **kwargs)[source]

This is the base class for state block objects. These are used when constructing the SimpleBlock or IndexedBlock which will contain the PropertyData objects, and contains methods that can be applied to multiple StateBlockData objects simultaneously.

initialize(*args, **kwargs)[source]

This is a default initialization routine for StateBlocks to ensure that a routine is present. All StateBlockData classes should overload this method with one suited to the particular property package

Parameters:None
Returns:None
class idaes.core.property_base.StateBlockData(component)[source]

This is the base class for state block data objects. These are blocks that contain the Pyomo components associated with calculating a set of thermophysical and transport properties for a given material.

build()[source]

General build method for StateBlockDatas.

Parameters:None
Returns:None
calculate_bubble_point_pressure(*args, **kwargs)[source]

Method which computes the bubble point pressure for a multi- component mixture given a temperature and mole fraction.

calculate_bubble_point_temperature(*args, **kwargs)[source]

Method which computes the bubble point temperature for a multi- component mixture given a pressure and mole fraction.

calculate_dew_point_pressure(*args, **kwargs)[source]

Method which computes the dew point pressure for a multi- component mixture given a temperature and mole fraction.

calculate_dew_point_temperature(*args, **kwargs)[source]

Method which computes the dew point temperature for a multi- component mixture given a pressure and mole fraction.

define_port_members()[source]

Method used to specific components to populate Ports with. Defaults to define_state_vars, and developers should overload as required.

define_state_vars()[source]

Method that returns a dictionary of state variables used in property package. Implement a placeholder method which returns an Exception to force users to overload this.

get_energy_diffusion_terms(*args, **kwargs)[source]

Method which returns a valid expression for energy diffusion to use in the energy balances.

get_enthalpy_density_terms(*args, **kwargs)[source]

Method which returns a valid expression for enthalpy density to use in the energy balances.

get_enthalpy_flow_terms(*args, **kwargs)[source]

Method which returns a valid expression for enthalpy flow to use in the energy balances.

get_material_density_terms(*args, **kwargs)[source]

Method which returns a valid expression for material density to use in the material balances .

get_material_diffusion_terms(*args, **kwargs)[source]

Method which returns a valid expression for material diffusion to use in the material balances.

get_material_flow_basis(*args, **kwargs)[source]

Method which returns an Enum indicating the basis of the material flow term.

get_material_flow_terms(*args, **kwargs)[source]

Method which returns a valid expression for material flow to use in the material balances.

idaes.core.property_meta module

These classes handle the metadata aspects of classes representing property packages.

Implementors of property packages need to do the following:

  1. Create a new class that inherits from idaes.core.property_base.PhysicalParameterBlock, which in turn inherits from HasPropertyClassMetadata, in this module.
  2. In that class, implement the define_metadata() method, inherited from HasPropertyClassMetadata. This method is called automatically, once, when the get_metadata() method is first invoked. An empty metadata object (an instance of PropertyClassMetadata) will be passed in, which the method should populate with information about properties and default units.

Example:

from idaes.core.property_base import PhysicalParameterBlock

class MyPropParams(PhysicalParameterBlock):

    @classmethod
    def define_metadata(cls, meta):
        meta.add_default_units({foo.U.TIME: 'fortnights',
                               foo.U.MASS: 'stones'})
        meta.add_properties({'under_sea': {'units': 'leagues'},
                            'tentacle_size': {'units': 'yards'}})
        meta.add_required_properties({'under_sea': 'leagues',
                            'tentacle_size': 'yards'})

    # Also, of course, implement the non-metadata methods that
    # do the work of the class.
class idaes.core.property_meta.HasPropertyClassMetadata[source]

Interface for classes that have PropertyClassMetadata.

classmethod define_metadata(pcm)[source]

Set all the metadata for properties and units.

This method should be implemented by subclasses. In the implementation, they should set information into the object provided as an argument.

Parameters:pcm (PropertyClassMetadata) – Add metadata to this object.
Returns:None
classmethod get_metadata()[source]

Get property parameter metadata.

If the metadata is not defined, this will instantiate a new metadata object and call define_metadata() to set it up.

If the metadata is already defined, it will be simply returned.

Returns:The metadata
Return type:PropertyClassMetadata
class idaes.core.property_meta.PropertyClassMetadata[source]
Container for metadata about the property class, which includes
default units and properties.

Example usage:

foo = PropertyClassMetadata()
foo.add_default_units({foo.U.TIME: 'fortnights',
                       foo.U.MASS: 'stones'})
foo.add_properties({'under_sea': {'units': 'leagues'},
                    'tentacle_size': {'units': 'yards'}})
foo.add_required_properties({'under_sea': 'leagues',
                            'tentacle_size': 'yards'})
U

Alias for class enumerating supported/known unit types

alias of UnitNames

add_default_units(u)[source]

Add a dict with keys for the quantities used in the property package (as strings) and values of their default units as strings.

The quantities used by the framework are in constants defined in UnitNames, aliased here in the class attribute U.

Parameters:u (dict) – Key=property, Value=units
Returns:None
add_properties(p)[source]

Add properties to the metadata.

For each property, the value should be another dict which may contain the following keys:

  • ‘method’: (required) the name of a method to construct the
    property as a str, or None if the property will be constructed by default.
  • ‘units’: (optional) units of measurement for the property.
Parameters:p (dict) – Key=property, Value=PropertyMetadata or equiv. dict
Returns:None
add_required_properties(p)[source]

Add required properties to the metadata.

For each property, the value should be the expected units of measurement for the property.

Parameters:p (dict) – Key=property, Value=units
Returns:None
class idaes.core.property_meta.PropertyMetadata(name=None, method=None, units=None)[source]

Container for property parameter metadata.

Instances of this class are exactly dictionaries, with the only difference being some guidance on the values expected in the dictionary from the constructor.

class idaes.core.property_meta.UnitNames[source]

Names for recognized units.

idaes.core.reaction_base module

This module contains classes for reaction blocks and reaction parameter blocks.

class idaes.core.reaction_base.ReactionBlockBase(*args, **kwargs)[source]

This is the base class for reaction block objects. These are used when constructing the SimpleBlock or IndexedBlock which will contain the PropertyData objects, and contains methods that can be applied to multiple ReactionBlockData objects simultaneously.

initialize(*args)[source]

This is a default initialization routine for ReactionBlocks to ensure that a routine is present. All ReactionBlockData classes should overload this method with one suited to the particular reaction package

Parameters:None
Returns:None
class idaes.core.reaction_base.ReactionBlockDataBase(component)[source]

This is the base class for reaction block data objects. These are blocks that contain the Pyomo components associated with calculating a set of reacion properties for a given material.

build()[source]

General build method for PropertyBlockDatas. Inheriting models should call super().build.

Parameters:None
Returns:None
get_reaction_rate_basis()[source]

Method which returns an Enum indicating the basis of the reaction rate term.

class idaes.core.reaction_base.ReactionParameterBlock(component)[source]

This is the base class for reaction parameter blocks. These are blocks that contain a set of parameters associated with a specific reaction package, and are linked to by all instances of that reaction package.

build()[source]

General build method for ReactionParameterBlocks. Inheriting models should call super().build.

Parameters:None
Returns:None
idaes.core.unit_model module

Base class for unit models

class idaes.core.unit_model.UnitModelBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(UnitModelBlock) New instance

class idaes.core.unit_model.UnitModelBlockData(component)[source]

This is the class for process unit operations models. These are models that would generally appear in a process flowsheet or superstructure.

add_inlet_port(name=None, block=None, doc=None)[source]

This is a method to build inlet Port objects in a unit model and connect these to a specified control volume or state block.

The name and block arguments are optional, but must be used together. i.e. either both arguments are provided or neither.

Keyword Arguments:
 
  • = name to use for Port object (name) –
  • = an instance of a ControlVolume or StateBlock to use as the (block) – source to populate the Port object. If a ControlVolume is provided, the method will use the inlet state block as defined by the ControlVolume. If not provided, method will attempt to default to an object named control_volume.
  • = doc string for Port object (doc) –
Returns:

A Pyomo Port object and associated components.

add_outlet_port(name=None, block=None, doc=None)[source]

This is a method to build outlet Port objects in a unit model and connect these to a specified control volume or state block.

The name and block arguments are optional, but must be used together. i.e. either both arguments are provided or neither.

Keyword Arguments:
 
  • = name to use for Port object (name) –
  • = an instance of a ControlVolume or StateBlock to use as the (block) – source to populate the Port object. If a ControlVolume is provided, the method will use the outlet state block as defined by the ControlVolume. If not provided, method will attempt to default to an object named control_volume.
  • = doc string for Port object (doc) –
Returns:

A Pyomo Port object and associated components.

add_port(name=None, block=None, doc=None)[source]

This is a method to build Port objects in a unit model and connect these to a specified StateBlock. :keyword name = name to use for Port object.: :keyword block = an instance of a StateBlock to use as the source to: populate the Port object :keyword doc = doc string for Port object:

Returns:A Pyomo Port object and associated components.
build()[source]

General build method for UnitModelBlockData. This method calls a number of sub-methods which automate the construction of expected attributes of unit models.

Inheriting models should call super().build.

Parameters:None
Returns:None
initialize(state_args=None, outlvl=0, solver='ipopt', optarg={'tol': 1e-06})[source]

This is a general purpose initialization routine for simple unit models. This method assumes a single ControlVolume block called controlVolume, and first initializes this and then attempts to solve the entire unit.

More complex models should overload this method with their own initialization routines,

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating which solver to use during initialization (default = ‘ipopt’)
Returns:

None

model_check()[source]

This is a general purpose initialization routine for simple unit models. This method assumes a single ControlVolume block called controlVolume and tries to call the model_check method of the controlVolume block. If an AttributeError is raised, the check is passed.

More complex models should overload this method with a model_check suited to the particular application, especially if there are multiple ControlVolume blocks present.

Parameters:None
Returns:None
idaes.dmf package

IDAES Data Management Framework (DMF)

The DMF lets you save, search, and retrieve provenance related to your models.

Submodules
idaes.dmf.cli module

Command Line Interface for IDAES DMF.

Uses “Click” to handle command-line parsing and dispatch.

class idaes.dmf.cli.AliasedGroup(aliases=None, **attrs)[source]

Improved click.Group that will accept unique prefixes for the commands, as well as a set of aliases.

For example, the following code will create mycommand as a group, and alias the subcommand “info” to invoke the subcommand “status”. Any unique prefix of “info” (not conflicting with other subcommands or aliases) or “status” will work, e.g. “inf” or “stat”:

@click.group(cls=AliasedGroup, aliases={"info": "status"})
def mycommand():
    pass
get_command(ctx, cmd_name)[source]

Given a context and a command name, this returns a Command object if it exists or returns None.

class idaes.dmf.cli.Code[source]

Return codes from the CLI.

class idaes.dmf.cli.URLType[source]

Click type for URLs.

convert(value, param, ctx)[source]

Converts the value. This is not invoked for values that are None (the missing value).

idaes.dmf.codesearch module

Search through the code and index static information in the DMF.

class idaes.dmf.codesearch.ModuleClassWalker(from_path=None, from_pkg=None, class_expr=None, parent_class=None, suppress_warnings=False, exclude_testdirs=True, exclude_tests=True, exclude_init=True, exclude_setup=True, exclude_dirs=None)[source]

Walk modules from a given root (e.g. ‘idaes’), and visit all classes in those modules whose name matches a given pattern.

Example usage:

walker = ModuleClassWalker(from_pkg=idaes,
                           class_expr='_PropertyParameter.*')

walker.walk(PrintMetadataVisitor())  # see below
walk(visitor)[source]

Interface for walkers.

Parameters:visitor (Visitor) – Class whose visit method will be called for each item.
Returns:None
class idaes.dmf.codesearch.PrintPropertyMetadataVisitor[source]
visit_metadata(obj, meta)[source]

Print the module and class of the object, and then the metadata dict, to standard output.

class idaes.dmf.codesearch.PropertyMetadataVisitor[source]

Visit something implementing HasPropertyClassMetadata and pass that metadata, as a dict, to the visit_metadata() method, which should be implemented by the subclass.

visit(obj)[source]

Visit one object.

Parameters:obj (idaes.core.property_base.HasPropertyClassMetadata) – The object
Returns:True if visit succeeded, else False
visit_metadata(obj, meta)[source]

Do something with the metadata.

Parameters:
  • obj (object) – Object from which metadata was pulled, for context.
  • meta (idaes.core.property_base.PropertyClassMetadata) – The metadata
Returns:

None

class idaes.dmf.codesearch.Visitor[source]

Interface for the ‘visitor’ class passed to Walker subclasses’ walk() method.

visit(obj)[source]

Visit one object.

Parameters:obj (object) – Some object to operate on.
Returns:True if visit succeeded, else False
idaes.dmf.commands module

Perform all logic, input, output of commands that is particular to the CLI.

Call functions defined in ‘api’ module to handle logic that is common to the API and CLI.

idaes.dmf.commands.init_conf(workspace)[source]

Initialize the workspace.

idaes.dmf.commands.list_resources(path, long_format=None, relations=False)[source]

List resources in a given DMF workspace.

Parameters:
  • path (str) – Path to the workspace
  • long_format (bool) – List in long format flag
  • relations (bool) – Show relationships, in long format
Returns:

None

idaes.dmf.commands.list_workspaces(root, stream=None)[source]

List workspaces found from a given root path.

Parameters:
  • root – root path
  • stream – Output stream (must have .write() method)
idaes.dmf.commands.workspace_import(path, patterns, exit_on_error)[source]

Import files into workspace.

Parameters:
  • path (str) – Target workspace directory
  • patterns (list) – List of Unix-style glob for files to import. Files are expected to be resource JSON or a Jupyter Notebook.
  • exit_on_error (bool) – If False, continue trying to import resources even if one or more fail.
Returns:

Number of things imported

Return type:

int

Raises:

BadResourceError, if there is a problem

idaes.dmf.commands.workspace_init(dirname, metadata)[source]

Initialize from root at dirname, set environment variable for other commands, and parse config file.

idaes.dmf.dmfbase module

Data Management Framework

class idaes.dmf.dmfbase.DMF(path='', name=None, desc=None, create=False, save_path=False, **ws_kwargs)[source]

Data Management Framework (DMF).

Expected usage is to instantiate this class, once, and then use it for storing, searching, and retrieving resources that are required for the given analysis.

For details on the configuration files used by the DMF, see documentation for DMFConfig (global configuration) and idaes.dmf.workspace.Workspace.

add(rsrc)[source]

Add a resource and associated files.

If the resource has ‘datafiles’, there are some special values that cause those files to be copied and possibly the original removed at this point. There are attributes do_copy and is_tmp on the resource, and also potentially keys of the same name in the datafiles themselves. If present, the datafile key/value pairs will override the attributes in the resource. For do_copy, the original file will be copied into the DMF workspace. If do_copy is True, then if is_tmp is also True the original file will be removed (after the copy is made, of course).

Parameters:rsrc (resource.Resource) – The resource
Returns:(str) Resource ID
Raises:DMFError, DuplicateResourceError
fetch_one(rid, id_only=False)[source]

Fetch one resource, from its identifier.

Parameters:
  • rid (str) – Resource identifier
  • id_only (bool) – If true, return only the identifier of each resource; otherwise a Resource object is returned.
Returns:

(resource.Resource) The found resource, or None if no match

find(filter_dict=None, id_only=False, re_flags=0)[source]

Find and return resources matching the filter.

The filter syntax is a subset of the MongoDB filter syntax. This means that it is represented as a dictionary, where each key is an attribute or nested attribute name, and each value is the value against which to match. There are six possible types of values:

  1. scalar string or number (int, float): Match resources that have this exact value for the given attribute.

  2. special scalars “@<value>”:

    • “@true”/”@false”: boolean (bare True/False will test existence)
  3. date, as datetime.datetime or pendulum.Pendulum instance: Match resources that have this exact date for the given attribute.

  4. list: Match resources that have a list value for this attribute, and for which any of the values in the provided list are in the resource’s corresponding value. If a ‘!’ is appended to the key name, then this will be interpreted as a directive to only match resources for which all values in the provided list are present.

  5. dict: This is an inequality, with one or more key/value pairs. The key is the type of inequality and the value is the numeric value for that range. All keys begin with ‘$’. The possible inequalities are:

    • “$lt”: Less than (<)
    • “$le”: Less than or equal (<=)
    • “$gt”: Greater than (>)
    • “$ge”: Greater than or equal (>=)
    • “$ne”: Not equal to (!=)
  6. Boolean True means does the field exist, and False means does it not exist.

  7. Regular expression, string “~<expr>” and re_flags for flags (understood: re.IGNORECASE)

Parameters:
  • filter_dict (dict) – Search filter.
  • id_only (bool) – If true, return only the identifier of each resource; otherwise a Resource object is returned.
  • re_flags (int) – Flags for regex filters
Returns:

(list of int|Resource) Depending on the value of id_only.

find_by_id(identifier: str, id_only=False) → Generator[T_co, T_contra, V_co][source]

Find resources by their identifier or identifier prefix.

Find related resources.

Parameters:
  • rsrc (resource.Resource) – Resource starting point
  • filter_dict (dict) – See parameter of same name in find().
  • maxdepth (int) – Maximum depth of search (starts at 1)
  • meta (List[str]) – Metadata fields to extract for meta part
  • outgoing (bool) – If True, look at outgoing relations. Otherwise look at incoming relations. e.g. if A ‘uses’ B and if True, would find B starting from A. If False, would find A starting from B.
Returns:

Generates triples (depth, Triple, meta), where the depth is an integer (starting at 1), the Triple is a simple namedtuple wrapping (subject, object, predicate), and meta is a dict of metadata for the endpoint of the relation (the object if outgoing=True, the subject if outgoing=False) for the fields provided in the meta parameter.

Raises:

NoSuchResourceError – if the starting resource is not found

remove(identifier=None, filter_dict=None, update_relations=True)[source]

Remove one or more resources, from its identifier or a filter. Unless told otherwise, this method will scan the DB and remove all relations that involve this resource.

Parameters:
  • identifier (str) – Identifier for a resource.
  • filter_dict (dict) – Filter to use instead of identifier
  • update_relations (bool) – If True (the default), scan the DB and remove all relations that involve this identifier.
update(rsrc, sync_relations=False, upsert=False)[source]

Update/insert stored resource.

Parameters:
  • rsrc (resource.Resource) – Resource instance
  • sync_relations (bool) – If True, and if resource exists in the DB, then the “relations” attribute of the provided resource will be changed to the stored value.
  • upsert (bool) – If true, and the resource is not in the DMF, then insert it. If false, and the resource is not in the DMF, then do nothing.
Returns:

True if the resource was updated or added, False if nothing

was done.

Return type:

bool

Raises:

errors.DMFError – If the input resource was invalid.

class idaes.dmf.dmfbase.DMFConfig(defaults=None)[source]

Global DMF configuration.

Every time you create an instance of the DMF or run a dmf command on the command-line, the library opens the global DMF configuration file to figure out the default workspace (and, eventually, other values).

The default location for this configuration file is “~/.dmf”, i.e. the file named “.dmf” in the user’s home directory. This can be modified programmatically by changing the “filename” attribute of this class.

The contents of the configuration are formatted as YAML with the following keys defined:

workspace
Path to the default workspace directory.
idaes.dmf.errors module

Exception classes.

exception idaes.dmf.errors.AlamoDisabledError[source]
exception idaes.dmf.errors.AlamoError(msg)[source]
exception idaes.dmf.errors.BadResourceError[source]
exception idaes.dmf.errors.CommandError(command, operation, details)[source]
exception idaes.dmf.errors.DMFError(detailed_error='No details')[source]
exception idaes.dmf.errors.DataFormatError(dtype, err)[source]
exception idaes.dmf.errors.DmfError[source]
exception idaes.dmf.errors.DuplicateResourceError(op, id_)[source]
exception idaes.dmf.errors.FileError[source]
exception idaes.dmf.errors.InvalidRelationError(subj, pred, obj)[source]
exception idaes.dmf.errors.ModuleFormatError(module_name, type_, what)[source]
exception idaes.dmf.errors.NoSuchResourceError(name=None, id_=None)[source]
exception idaes.dmf.errors.ParseError[source]
exception idaes.dmf.errors.ResourceError[source]
exception idaes.dmf.errors.SearchError(spec, problem)[source]
exception idaes.dmf.errors.WorkspaceCannotCreateError(path)[source]
exception idaes.dmf.errors.WorkspaceConfMissingField(path, name, desc)[source]
exception idaes.dmf.errors.WorkspaceConfNotFoundError(path)[source]
exception idaes.dmf.errors.WorkspaceError(detailed_error='No details')[source]
exception idaes.dmf.errors.WorkspaceNotFoundError(from_dir)[source]
idaes.dmf.experiment module

The ‘experiment’ is a root container for a coherent set of ‘resources’.

class idaes.dmf.experiment.Experiment(dmf, **kwargs)[source]

An experiment is a way of grouping resources in a way that makes sense to the user.

It is also a useful unit for passing as an argument to functions, since it has a standard ‘slot’ for the DMF instance that created it.

add(rsrc)[source]

Add a resource to an experiment.

This does two things:

  1. Establishes an “experiment” type of relationship between the new resource and the experiment.
  2. Adds the resource to the DMF
Parameters:rsrc (resource.Resource) – The resource to add.
Returns:Added (input) resource, for chaining calls.
Return type:resource.Resource
copy(new_id=True, **kwargs)[source]

Get a copy of this experiment. The returned object will have been added to the DMF.

Parameters:
  • new_id (bool) – If True, generate a new unique ID for the copy.
  • kwargs – Values to set in new instance after copying.
Returns:

A (mostly deep) copy.

Note that the DMF instance is just a reference to the same object as in the original, and they will share state.

Return type:

Experiment

Add and update relation triple in DMF.

Parameters:
Returns:

None

remove()[source]

Remove this experiment from the associated DMF instance.

update()[source]

Update experiment to current values.

idaes.dmf.help module

Find documentation for modules and classes in the generated Sphinx documentation and return its location.

idaes.dmf.help.find_html_docs(dmf, obj=None, obj_name=None, **kw)[source]

Get one or more files with HTML documentation for the given object, in paths referred to by the dmf instance.

idaes.dmf.magics module

Jupyter magics for the DMF.

exception idaes.dmf.magics.DMFMagicError(errmsg, usermsg=None)[source]
class idaes.dmf.magics.DmfMagics(shell)[source]

Implement “magic” commands in Jupyter/IPython for interacting with the DMF and IDAES more generally.

In order to allow easier testing, the functionality is broken into two classes. This class has the decorated method(s) for invoking the ‘magics’, and DmfMagicsImpl has the state and functionality.

dmf(line)[source]

DMF outer command.

Example:

%dmf <subcommand> [subcommand args..]
class idaes.dmf.magics.DmfMagicsImpl(shell)[source]

State and implementation called by DmfMagics.

On failure of any method, a DMFMagicError is raised, that should be handled by the line or cell magic that invoked it.

dmf(line)[source]

DMF outer command

dmf_help(*names)[source]

Provide help on IDAES objects and classes. Invoking with no arguments gives general help. Invoking with one argument looks for help in the docs on the given object or class. Arguments: [name].

dmf_info(*topics)[source]

Provide information about DMF current state. Arguments: none

Parameters:topics ((List[str])) – List of topics
Returns:None
dmf_init(path, *extra)[source]

Initialize DMF (do this before most other commands). Arguments: path [“create”]

Parameters:
  • path (str) – Full path to DMF home
  • extra (str) – Extra tokens. If ‘create’, then try to create the path if it is not found.
dmf_list()[source]

List resources in the current workspace. Arguments: none.

dmf_workspaces(*paths)[source]

List DMF workspaces. Optionally takes one or more paths to use as a starting point. By default, start from current directory. Arguments: [paths..]

Parameters:paths (List[str]) – Paths to search, use “.” by default
idaes.dmf.magics.register()[source]

Register with IPython on import (once).

idaes.dmf.propdata module

Property data types.

Ability to import, etc. from text files is part of the methods in the type.

Import property database from textfile(s): * See PropertyData.from_csv(), for the expected format for data. * See PropertyMetadata() for the expected format for metadata.

exception idaes.dmf.propdata.AddedCSVColumnError(names, how_bad, column_type='')[source]

Error for :meth:PropertyData.add_csv()

class idaes.dmf.propdata.Fields[source]

Constants for fields.

class idaes.dmf.propdata.PropertyColumn(name, data)[source]

Data column for a property.

class idaes.dmf.propdata.PropertyData(data)[source]

Class representing property data that knows how to construct itself from a CSV file.

You can build objects from multiple CSV files as well. See the property database section of the API docs for details, or read the code in add_csv() and the tests in idaes_dmf.propdb.tests.test_mergecsv.

add_csv(file_or_path, strict=False)[source]

Add to existing object from a new CSV file.

Depending on the value of the strict argument (see below), the new file may or may not have the same properties as the object – but it always needs to have the same number of state columns, and in the same order.

Note

Data that is “missing” because of property columns in one CSV and not the other will be filled with float(nan) values.

Parameters:
  • file_or_path (file or str) – Input file. This should be in exactly the same format as expected by :meth:from_csv().
  • strict (bool) – If true, require that the columns in the input CSV match columns in this object. Otherwise, only require that state columns in input CSV match columns in this object. New property columns are added, and matches to existing property columns will append the data.
Raises:

AddedCSVColumnError – If the new CSV column headers are not the same as the ones in this object.

Returns:

(int) Number of added rows

as_arr(states=True)[source]

Export property data as arrays.

Parameters:states (bool) – If False, exclude “state” data, e.g. the ambient temperature, and only include measured property values.
Returns:(values[M,N], errors[M,N]) Two arrays of floats, each with M columns having N values.
Raises:ValueError if the columns are not all the same length
errors_dataframe(states=False)[source]

Get errors as a dataframe.

Parameters:states (bool) – If False, exclude state data. This is the default, because states do not normally have associated error information.
Returns:Pandas dataframe for values.
Return type:pd.DataFrame
Raises:ImportError – If pandas or numpy were never successfully imported.
static from_csv(file_or_path, nstates=0)[source]

Import the CSV data.

Expected format of the files is a header plus data rows.

Header: Index-column, Column-name(1), Error-column(1), Column-name(2), Error-column(2), .. Data: <index>, <val>, <errval>, <val>, <errval>, ..

Column-name is in the format “Name (units)”

Error-column is in the format “<type> Error”, where “<type>” is the error type.

Parameters:
  • file_or_path (file-like or str) – Input file
  • nstates (int) – Number of state columns, appearing first before property columns.
Returns:

New properties instance

Return type:

PropertyData

is_property_column(index)[source]

Whether given column is a property. See is_state_column().

is_state_column(index)[source]

Whether given column is state.

Parameters:index (int) – Index of column
Returns:(bool) State or property and the column number.
Raises:IndexError – No column at that index.
names(states=True, properties=True)[source]

Get column names.

Parameters:
  • states (bool) – If False, exclude “state” data, e.g. the ambient temperature, and only include measured property values.
  • properties (bool) – If False, excluse property data
Returns:

List of column names.

Return type:

list[str]

values_dataframe(states=True)[source]

Get values as a dataframe.

Parameters:states (bool) – see names().
Returns:(pd.DataFrame) Pandas dataframe for values.
Raises:ImportError – If pandas or numpy were never successfully imported.
class idaes.dmf.propdata.PropertyMetadata(values=None)[source]

Class to import property metadata.

class idaes.dmf.propdata.PropertyTable(data=None, **kwargs)[source]

Property data and metadata together (at last!)

classmethod load(file_or_path, validate=True)[source]

Create PropertyTable from JSON input.

Parameters:
  • file_or_path (file or str) – Filename or file object from which to read the JSON-formatted data.
  • validate (bool) – If true, apply validation to input JSON data.

Example input:

{
    "meta": [
        {"datatype": "MEA",
         "info": "J. Chem. Eng. Data, 2009, Vol 54, pg. 306-310",
         "notes": "r is MEA weight fraction in aqueous soln.",
         "authors": "Amundsen, T.G., Lars, E.O., Eimer, D.A.",
         "title": "Density and Viscosity of ..."}
    ],
    "data": [
        {"name": "Viscosity Value",
         "units": "mPa-s",
         "values": [2.6, 6.2],
         "error_type": "absolute",
         "errors": [0.06, 0.004],
         "type": "property"},
        {"name": "r",
         "units": "",
         "values": [0.2, 1000],
         "type": "state"}
    ]
}
class idaes.dmf.propdata.StateColumn(name, data)[source]

Data column for a state.

idaes.dmf.propindex module

Index Property metadata

class idaes.dmf.propindex.DMFVisitor(dmf, default_version=None)[source]
INDEXED_PROPERTY_TAG = 'indexed-property'

Added to resource ‘tags’, so easier to find later

visit_metadata(obj, meta)[source]
Called for each property class encountered during the “walk”
initiated by index_property_metadata().
Parameters:
  • obj (property_base.PropertyParameterBase) – Property class instance
  • meta (property_base.PropertyClassMetadata) – Associated metadata
Returns:

None

Raises:

AttributeError – if

idaes.dmf.propindex.index_property_metadata(dmf, pkg=<module 'idaes' from '/home/docs/checkouts/readthedocs.org/user_builds/idaes-pse/checkouts/1.1.1/idaes/__init__.py'>, expr='_PropertyMetadata.*', default_version='0.0.1', **kwargs)[source]

Index all the PropertyMetadata classes in this package.

Usually the defaults will be correct, but you can modify the package explored and set of classes indexed.

When you re-index the same class (in the same module), whether or not that is a “duplicate” will depend on the version found in the containing module. If there is no version in the containing module, the default version is used (so it is always the same). If it is a duplicate, nothing is done, this is not considered an error. If a new version is added, it will be explicitly connected to the highest version of the same module/code. So, for example,

  1. Starting with (a.module.ClassName version=0.1.2)

  2. If you then find a new version (a.module.ClassName version=1.2.3) There will be 2 resources, and you will have the relation:

    a.module.ClassName/1.2.3 --version---> a.module.ClassName/0.1.2
    
  3. If you add another version (a.module.ClassName version=1.2.4), you will have two relations:

    a.module.ClassName/1.2.3 --version---> a.module.ClassName/0.1.2
    a.module.ClassName/1.2.4 --version---> a.module.ClassName/1.2.3
    
Parameters:
  • dmf (idaes.dmf.DMF) – Data Management Framework instance in which to record the found metadata.
  • pkg (module) – Root module (i.e. package root) from which to find the classes containing metadata.
  • expr (str) – Regular expression pattern for the names of the classes in which to look for metadata.
  • default_version (str) – Default version to use for modules with no explicit version.
  • kwargs – Other keyword arguments passed to codesearch.ModuleClassWalker.
Returns:

Class that walked through the modules.

You can call .get_indexed_classes() to see the list of classes walked, or .walk() to walk the modules again.

Return type:

codesearch.ModuleClassWalker

Raises:
  • This instantiated a DMFVisitor and calls its walk() method to
  • walk/visit each found class, so any exception raised by the constructor
  • or DMFVisitor.visit_metadata().
idaes.dmf.resource module

Resource representaitons.

class idaes.dmf.resource.CodeImporter(path, language, **kwargs)[source]
class idaes.dmf.resource.Dict(*args, **kwargs)[source]

Subclass of dict that has a ‘dirty’ bit.

class idaes.dmf.resource.FileImporter(path: pathlib.Path, do_copy: bool = None)[source]
class idaes.dmf.resource.JsonFileImporter(path: pathlib.Path, do_copy: bool = None)[source]
class idaes.dmf.resource.JupyterNotebookImporter(path: pathlib.Path, do_copy: bool = None)[source]
idaes.dmf.resource.PR_DERIVED = 'derived'

Constants for relation predicates

class idaes.dmf.resource.ProgLangExt[source]

Helper class to map from file extensions to names of the programming language.

idaes.dmf.resource.RESOURCE_TYPES = {'code', 'data', 'experiment', 'flowsheet', 'json', 'notebook', 'other', 'propertydb', 'resource_json', 'surrogate_model', 'tabular_data'}

Constants for resource ‘types’

class idaes.dmf.resource.Resource(value: dict = None, type_: str = None)[source]

Core object for the Data Management Framework.

ID_FIELD = 'id_'

Identifier field name constant

ID_LENGTH = 32

Full-length of identifier

exception InferResourceTypeError[source]
exception LoadResourceError(inferred_type, msg)[source]
TYPE_FIELD = 'type'

Resource type field name constant

data

Get JSON data for this resource.

classmethod from_file(path: str, as_type: str = None, strict: bool = True, do_copy: bool = True) → idaes.dmf.resource.Resource[source]

Import resource from a file.

Parameters:
  • path – File path
  • as_type – Resource type. If None/empty, then inferred from path.
  • strict – If True, fail when file extension and contents don’t match. If False, always fall through to generic resource.
  • do_copy – If True (the default), copy the files; else do not
Raises:
get_datafiles(mode='r')[source]

Generate readable file objects for ‘datafiles’ in resource.

Parameters:mode (str) – Mode for open()
Returns:Generates file objects.
Return type:generator
id

Get resource identifier.

name

Get resource name (first alias).

type

Get resource type.

class idaes.dmf.resource.ResourceImporter(path: pathlib.Path, do_copy: bool = None)[source]

Base class for Resource importers.

create() → idaes.dmf.resource.Resource[source]

Factory method.

class idaes.dmf.resource.SerializedResourceImporter(path, parsed, **kwargs)[source]
idaes.dmf.resource.TY_CODE = 'code'

Resource type for source code

idaes.dmf.resource.TY_DATA = 'data'

Resource type for generic data

idaes.dmf.resource.TY_EXPERIMENT = 'experiment'

Resource type for experiments

idaes.dmf.resource.TY_FLOWSHEET = 'flowsheet'

Resource type for a process flowsheet

idaes.dmf.resource.TY_JSON = 'json'

Resource type for JSON data

idaes.dmf.resource.TY_NOTEBOOK = 'notebook'

Resource type for a Jupyter Notebook

idaes.dmf.resource.TY_OTHER = 'other'

Resource type for unspecified type of resource

idaes.dmf.resource.TY_PROPERTY = 'propertydb'

Resource type for property data

idaes.dmf.resource.TY_RESOURCE_JSON = 'resource_json'

Resource type for a JSON serialized resource

idaes.dmf.resource.TY_SURRMOD = 'surrogate_model'

Resource type for a surrogate model

idaes.dmf.resource.TY_TABULAR = 'tabular_data'

Resource type for tabular data

class idaes.dmf.resource.Triple(subject, predicate, object)

Provide attribute access to an RDF subject, predicate, object triple

object

Alias for field number 2

predicate

Alias for field number 1

subject

Alias for field number 0

idaes.dmf.resource.create_relation(rel)[source]

Create a relationship between two Resource instances.

Relations are stored in both the subject and object resources, in the following way:

If R = (subject)S, (predicate)P, and (object)O
then store the following:
  In S.relations: {predicate: P, identifier:O.id, role:subject}
  In O.relations: {predicate: P, identifier:S.id, role:object}
Parameters:rel (Triple) – Relation triple. The ‘subject’ and ‘object’ parts should be Resource, and the ‘predicate’ should be a simple string.
Returns:None
Raises:ValueError – if this relation already exists in the subject or object resource, or the predicate is not in the list of valid ones in RELATION_PREDICATES
idaes.dmf.resource.create_relation_args(*args)[source]

Syntactic sugar to take 3 args instead of a Triple.

idaes.dmf.resource.date_float(value)[source]

Convert a date to a floating point seconds since the UNIX epoch.

idaes.dmf.resource.identifier_str(value=None, allow_prefix=False)[source]

Generate or validate a unique identifier.

If generating, you will get a UUID in hex format

>>> identifier_str()  
'...'

If validating, anything that is not 32 lowercase letters or digits will fail.

>>> identifier_str('A' * 32)   
Traceback (most recent call last):
ValueError: Bad format for identifier "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA":
must match regular expression "[0-9a-f]{32}"
Parameters:value (str) – If given, validate that it is a 32-byte str If not given or None, set new random value.
Raises:ValuError, if a value is given, and it is invalid.
idaes.dmf.resource.triple_from_resource_relations(id_, rrel)[source]

Create a Triple from one entry in resource[‘relations’].

Parameters:
  • id (str) – Identifier of the containing resource.
  • rrel (dict) – Stored relation with three keys, see create_relation().
Returns:

A triple

Return type:

Triple

idaes.dmf.resource.version_list(value)[source]

Semantic version.

Three numeric identifiers, separated by a dot. Trailing non-numeric characters allowed.

Inputs, string or tuple, may have less than three numeric identifiers, but internally the value will be padded with zeros to always be of length four.

A leading dash or underscore in the trailing non-numeric characters is removed.

Some examples of valid inputs and how they translate to 4-part versions:

>>> version_list('1')
[1, 0, 0, '']
>>> version_list('1.1')
[1, 1, 0, '']
>>> version_list('1a')
[1, 0, 0, 'a']
>>> version_list('1.12.1')
[1, 12, 1, '']
>>> version_list('1.12.13-1')
[1, 12, 13, '1']

Some examples of invalid inputs:

>>> for bad_input in ('rc3',      # too short
...                   '1.a.1.',   # non-number in middle
...                   '1.12.13.x' # too long
...     ):
...     try:
...         version_list(bad_input)
...     except ValueError:
...         print(f"failed: {bad_input}")
...
failed: rc3
failed: 1.a.1.
failed: 1.12.13.x
Returns:[major:int, minor:int, debug:int, release-type:str]
Return type:list
idaes.dmf.resourcedb module

Resource database.

class idaes.dmf.resourcedb.ResourceDB(dbfile=None, connection=None)[source]

A database interface to all the resources within a given DMF workspace.

delete(id_=None, idlist=None, filter_dict=None, internal_ids=False)[source]

Delete one or more resources with given identifiers.

Parameters:
  • id (Union[str,int]) – If given, delete this id.
  • idlist (list) – If given, delete ids in this list
  • filter_dict (dict) – If given, perform a search and delete ids it finds.
  • internal_ids (bool) – If True, treat identifiers as numeric (internal) identifiers. Otherwise treat them as resource (string) indentifiers.
Returns:

(list[str]) Identifiers

find(filter_dict, id_only=False, flags=0)[source]

Find and return records based on the provided filter.

Parameters:
  • filter_dict (dict) – Search filter. For syntax, see docs in dmf.DMF.find().
  • id_only (bool) – If true, return only the identifier of each resource; otherwise a Resource object is returned.
  • flags (int) – Flag values for, e.g., regex searches
Returns:

generator of int|Resource, depending on the value of id_only

find_one(*args, **kwargs)[source]

Same as find(), but returning only first value or None.

Find all resources connected to the identified one.

Parameters:
  • id (str) – Unique ID of target resource.
  • filter_dict (dict) – Filter to these resources
  • outgoing
  • maxdepth
  • meta (List[str]) – Metadata fields to extract
Returns:

Generator of (depth, relation, metadata)

Raises:

KeyError if the resource is not found.

get(identifier)[source]

Get a resource by identifier.

Parameters:identifier – Internal identifier
Returns:(Resource) A resource or None
put(resource)[source]

Put this resource into the database.

Parameters:resource (Resource) – The resource to add
Returns:None
Raises:errors.DuplicateResourceError – If there is already a resource in the database with the same “id”.
update(id_, new_dict)[source]

Update the identified resource with new values.

Parameters:
  • id (int) – Identifier of resource to update
  • new_dict (dict) – New dictionary of resource values
Returns:

None

Raises:
  • ValueError – If new resource is of wrong type
  • KeyError – If old resource is not found
idaes.dmf.surrmod module

Surrogate modeling helper classes and functions. This is used to run ALAMO on property data.

class idaes.dmf.surrmod.SurrogateModel(experiment, **kwargs)[source]

Run ALAMO to generate surrogate models.

Automatically track the objects in the DMF.

Example:

model = SurrogateModel(dmf, simulator='linsim.py')
rsrc = dmf.fetch_one(1) # get resource ID 1
data = rsrc.property_table.data
model.set_input_data(data, ['temp'], 'density')
results = model.run()
PARAM_DATA_KEY = 'parameters'

Key in resource ‘data’ for params

run(**kwargs)[source]

Run ALAMO.

Parameters:**kwargs – Additional arguments merged with those passed to the class constructor. Any duplicate values will override the earlier ones.
Returns:The dictionary returned from alamopy.doalamo()
Return type:dict
set_input_data(data, x_colnames, z_colname)[source]

Set input from provided dataframe or property data.

Parameters:
  • data (PropertyData|pandas.DataFrame) – Input data
  • x_colnames (List[str]|str) – One or more column names for parameters
  • z_colname (str) – Column for response variable
Returns:

None

Raises:

KeyError – if columns are not found in data

set_input_data_np(x, z, xlabels=None, zlabel='z')[source]

Set input data from numpy arrays.

Parameters:
  • x (arr) – Numpy array with parameters
  • xlabels (List[str]) – List of labels for x
  • zlabel (str) – Label for z
  • z (arr) – Numpy array with response variables
Returns:

None

set_validation_data(data, x_colnames, z_colname)[source]

Set validation data from provided data.

Parameters:
  • data (PropertyData|pandas.DataFrame) – Input data
  • x_colnames (List[str]|str) – One or more column names for parameters
  • z_colname (str) – Column for response variable
Returns:

None

Raises:

KeyError – if columns are not found in data

set_validation_data_np(x, z, xlabels=None, zlabel='z')[source]

Set input data from numpy arrays.

Parameters:
  • x (arr) – Numpy array with parameters
  • xlabels (List[str]) – List of labels for x
  • zlabel (str) – Label for z
  • z (arr) – Numpy array with response variables
Returns:

None

idaes.dmf.tabular module

Tabular data handling

class idaes.dmf.tabular.Column(name, data)[source]

Generic, abstract column

class idaes.dmf.tabular.Fields[source]

Constants for field names.

DATA_NAME = 'name'

Keys for data mapping

class idaes.dmf.tabular.Metadata(values=None)[source]

Class to import metadata.

author

Publication author(s).

date

Publication date

static from_csv(file_or_path)[source]

Import metadata from simple text format.

Example input:

Source,Han, J., Jin, J., Eimer, D.A., Melaaen, M.C.,"Density of             Water(1) + Monoethanolamine(2) + CO2(3) from (298.15 to 413.15) K            and Surface Tension of Water(1) + Monethanolamine(2) from (             303.15 to 333.15)K", J. Chem. Eng. Data, 2012, Vol. 57,             pg. 1095-1103"
Retrieval,"J. Morgan, date unknown"
Notes,r is MEA weight fraction in aqueous soln. (CO2-free basis)
Parameters:file_or_path (str or file) – Input file
Returns:(PropertyMetadata) New instance
info

Publication venue, etc.

source

Full publication info.

title

Publication title.

class idaes.dmf.tabular.Table(data=None, metadata=None)[source]

Tabular data and metadata together (at last!)

as_dict()[source]

Represent as a Python dictionary.

Returns:(dict) Dictionary representation
dump(fp, **kwargs)[source]

Dump to file as JSON. Convenience method, equivalent to converting to a dict and calling json.dump().

Parameters:
  • fp (file) – Write output to this file
  • **kwargs – Keywords passed to json.dump()
Returns:

see json.dump()

dumps(**kwargs)[source]

Dump to string as JSON. Convenience method, equivalent to converting to a dict and calling json.dumps().

Parameters:**kwargs – Keywords passed to json.dumps()
Returns:(str) JSON-formatted data
classmethod load(file_or_path, validate=True)[source]

Create from JSON input.

Parameters:
  • file_or_path (file or str) – Filename or file object from which to read the JSON-formatted data.
  • validate (bool) – If true, apply validation to input JSON data.

Example input:

{
    "meta": [{
        "datatype": "MEA",
        "info": "J. Chem. Eng. Data, 2009, Vol 54, pg. 3096-30100",
        "notes": "r is MEA weight fraction in aqueous soln.",
        "authors": "Amundsen, T.G., Lars, E.O., Eimer, D.A.",
        "title": "Density and Viscosity of Monoethanolamine + etc."
    }],
    "data": [
        {
            "name": "Viscosity Value",
            "units": "mPa-s",
            "values": [2.6, 6.2],
            "error_type": "absolute",
            "errors": [0.06, 0.004],
            "type": "property"
        }
    ]
}
class idaes.dmf.tabular.TabularData(data, error_column=False)[source]

Class representing tabular data that knows how to construct itself from a CSV file.

You can build objects from multiple CSV files as well. See the property database section of the API docs for details, or read the code in add_csv() and the tests in idaes_dmf.propdb.tests.test_mergecsv.

as_arr()[source]

Export property data as arrays.

Returns:(values[M,N], errors[M,N]) Two arrays of floats, each with M columns having N values.
Raises:ValueError if the columns are not all the same length
as_list()[source]

Export the data as a list.

Output will be in same form as data passed to constructor.

Returns:(list) List of dicts
errors_dataframe()[source]

Get errors as a dataframe.

Returns:Pandas dataframe for values.
Return type:pd.DataFrame
Raises:ImportError – If pandas or numpy were never successfully imported.
static from_csv(file_or_path, error_column=False)[source]

Import the CSV data.

Expected format of the files is a header plus data rows.

Header: Index-column, Column-name(1), Error-column(1), Column-name(2), Error-column(2), .. Data: <index>, <val>, <errval>, <val>, <errval>, ..

Column-name is in the format “Name (units)”

Error-column is in the format “<type> Error”, where “<type>” is the error type.

Parameters:
  • file_or_path (file-like or str) – Input file
  • error_column (bool) – If True, look for an error column after each value column. Otherwise, all columns are assumed to be values.
Returns:

New table of data

Return type:

TabularData

get_column(key)[source]

Get an object for the given named column.

Parameters:key (str) – Name of column
Returns:(TabularColumn) Column object.
Raises:KeyError – No column by that name.
get_column_index(key)[source]

Get an index for the given named column.

Parameters:key (str) – Name of column
Returns:(int) Column number.
Raises:KeyError – No column by that name.
names()[source]

Get column names.

Returns:List of column names.
Return type:list[str]
num_columns

Number of columns in this table.

A “column” is defined as data + error. So if there are two columns of data, each with an associated error column, then num_columns is 2 (not 4).

Returns:Number of columns.
Return type:int
num_rows

Number of rows in this table.

obj.num_rows is a synonym for len(obj)

Returns:Number of rows.
Return type:int
values_dataframe()[source]

Get values as a dataframe.

Returns:(pd.DataFrame) Pandas dataframe for values.
Raises:ImportError – If pandas or numpy were never successfully imported.
class idaes.dmf.tabular.TabularObject[source]

Abstract Property data class.

as_dict()[source]

Return Python dict representation.

idaes.dmf.userapi module

Data Management Framework high-level functions.

idaes.dmf.userapi.find_property_packages(dmf, properties=None)[source]

Find all property packages matching provided criteria.

Return the matching packages as a generator.

Parameters:
  • dmf (DMF) – Data Management Framework instance
  • properties (List[str]) – Names of properties that must be present in the returned packages.
Returns:

Each object has the property

data (properties and default units) in its .data attribute.

Return type:

Generator[idaes.dmf.resource.Resource]

idaes.dmf.userapi.get_workspace(path='', name=None, desc=None, create=False, errs=None, **kwargs)[source]

Create or load a DMF workspace.

If the DMF constructor, throws an exception, this catches it and prints the error to the provided stream (or stdout).

See DMF for details on arguments.

Parameters:
  • path (str) – Path to workspace.
  • name (str) – Name to be used for workspace.
  • desc (str) – Longer description of workspace.
  • create (bool) – If the path to the workspace does not exist, this controls whether to create it.
  • errs (object) – Stream for errors, stdout is used if None
Returns:

New instance, or None if it failed.

Return type:

DMF

idaes.dmf.util module

Utility functions.

class idaes.dmf.util.CPrint(color=True)[source]

Colorized terminal printing.

Codes are below. To use:

cprint = CPrint() cprint(‘This has no colors’) # just like print() cprint(‘This is @b[blue] and @_r[red underlined]’)

You can use the same class as a no-op by just passing color=False to the constructor.

class idaes.dmf.util.TempDir(*args)[source]

Simple context manager for mkdtemp().

idaes.dmf.util.datetime_timestamp(v)[source]

Get numeric timestamp. This will work under both Python 2 and 3.

Parameters:v (datetime.datetime) – Date/time value
Returns:(float) Floating point timestamp
idaes.dmf.util.get_file(file_or_path, mode='r')[source]

Open a file for reading, or simply return the file object.

idaes.dmf.util.get_module_author(mod)[source]

Find and return the module author.

Parameters:mod (module) – Python module
Returns:(str) Author string or None if not found
Raises:nothing
idaes.dmf.util.get_module_version(mod)[source]

Find and return the module version.

Version must look like a semantic version with <a>.<b>.<c> parts; there can be arbitrary extra stuff after the <c>. For example:

1.0.12
0.3.6
1.2.3-alpha-rel0
Parameters:mod (module) – Python module
Returns:(str) Version string or None if not found
Raises:ValueError if version is found but not valid
idaes.dmf.util.is_jupyter_notebook(filename, check_contents=True)[source]

See if this is a Jupyter notebook.

idaes.dmf.util.is_python(filename)[source]

See if this is a Python file. Do not import the source code.

idaes.dmf.util.is_resource_json(filename, max_bytes=1000000.0)[source]

Is this file a JSON Resource?

Parameters:
  • filename (str) – Full path to file
  • max_bytes (int) – Max. allowable size. Since we try to parse the file, this saves potential DoS issues. Large files are a bad idea anyways, since this is metadata and may be stored somewhere with a record size limit (like MongoDB).
Returns:

(bool) Whether it’s a resource JSON file.

idaes.dmf.util.mkdir_p(path, *args)[source]

Try to create all non-existent components of a path.

Parameters:
  • path (str) – Path to create
  • args – Other arguments for os.mkdir().
Returns:

None

Raises:

os.error – Raised from os.mkdir()

idaes.dmf.util.uuid_prefix_len(uuids, step=4, maxlen=32)[source]

Get smallest multiple of step len prefix that gives unique values.

The algorithm is not fancy, but good enough: build sets of the ids at increasing prefix lengths until the set has all ids (no duplicates). Experimentally this takes ~.1ms for 1000 duplicate ids (the worst case).

idaes.dmf.workspace module

Workspace classes and functions.

class idaes.dmf.workspace.Fields[source]

Workspace configuration fields.

class idaes.dmf.workspace.Workspace(path, create=False, add_defaults=False, html_paths=None)[source]

DMF Workspace.

In essence, a workspace is some information at the root of a directory tree, a database (currently file-based, so also in the directory tree) of Resources, and a set of files associated with these resources.

Workspace Configuration

When the DMF is initialized, the workspace is given as a path to a directory. In that directory is a special file named config.yaml, that contains metadata about the workspace. The very existence of a file by that name is taken by the DMF code as an indication that the containing directory is a DMF workspace:

/path/to/dmf: Root DMF directory
 |
 +- config.yaml: Configuration file
 +- resourcedb.json: Resource metadata "database" (uses TinyDB)
 +- files: Data files for all resources

The configuration file is a YAML formatted file

The configuration file defines the following key/value pairs:

_id
Unique identifier for the workspace. This is auto-generated by the library, of course.
name
Short name for the workspace.
description
Possibly longer text describing the workspace.
created
Date at which the workspace was created, as string in the ISO8601 format.
modified
Date at which the workspace was last modified, as string in the ISO8601 format.
htmldocs
Full path to the location of the built (not source) Sphinx HTML documentation for the idaes_dmf package. See DMF Help Configuration for more details.

There are many different possible “styles” of formatting a list of values in YAML, but we prefer the simple block-indented style, where the key is on its own line and the values are each indented with a dash:

_id: fe5372a7e51d498fb377da49704874eb
created: '2018-07-16 11:10:44'
description: A bottomless trashcan
modified: '2018-07-16 11:10:44'
name: Oscar the Grouch's Home
htmldocs:
- '{dmf_root}/doc/build/html/dmf'
- '{dmf_root}/doc/build/html/models'

Any paths in the workspace configuration, e.g., for the “htmldocs”, can use two special variables that will take on values relative to the workspace location. This avoids hardcoded paths and makes the workspace more portable across environments. {ws_root} will be replaces with the path to the workspace directory, and {dmf_root} will be replaced with the path to the (installed) DMF package.

The config.yaml file will allow keys and values it does not know about. These will be accessible, loaded into a Python dictionary, via the meta attribute on the Workspace instance. This may be useful for passing additional user-defined information into the DMF at startup.

CONF_CREATED = 'created'

Configuration field for created date

CONF_DESC = 'description'

Configuration field for description

CONF_MODIFIED = 'modified'

Configuration field for modified date

CONF_NAME = 'name'

Configuration field for name

ID_FIELD = '_id'

Name of ID field

WORKSPACE_CONFIG = 'config.yaml'

Name of configuration file placed in WORKSPACE_DIR

configuration_file

Configuration file path.

get_doc_paths()[source]

Get paths to generated HTML Sphinx docs.

Returns:(list) Paths or empty list if not found.
meta

Get metadata.

This reads and parses the configuration. Therefore, one way to force a config refresh is to simply refer to this property, e.g.:

dmf = DMF(path='my-workspace')
#  ... do stuff that alters the config ...
dmf.meta  # re-read/parse the config
Returns:(dict) Metadata for this workspace.
root

Root path for this workspace. This is the path containing the configuration file.

set_doc_paths(paths: List[str], replace: bool = False)[source]

Set paths to generated HTML Sphinx docs.

Parameters:
  • paths – New paths to add.
  • replace – If True, replace any existing paths. Otherwise merge new paths with existing ones.
set_meta(values, remove=None)[source]

Update metadata with new values.

Parameters:
  • values (dict) – Values to add or change
  • remove (list) – Keys of values to remove.
wsid

Get workspace identifier (from config file).

Returns:Unique identifier.
Return type:str
idaes.dmf.workspace.find_workspaces(root)[source]

Find workspaces at or below ‘root’.

Parameters:root (str) – Path to start at
Returns:paths, which are all workspace roots.
Return type:List[str]
idaes.functions package
idaes.property_models package
Subpackages
idaes.property_models.examples package
Submodules
idaes.property_models.examples.BFW_properties module

Basic property package for water liquid.

Please verify the valid ranges for the temperature before using this property package.

All unit is SI and mole basis

class idaes.property_models.examples.BFW_properties.BFWParameterBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    default_arguments
    Default arguments to use with Property Package
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(BFWParameterBlock) New instance

class idaes.property_models.examples.BFW_properties.BFWStateBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    parameters
    A reference to an instance of the Property Parameter Block associated with this property package.
    defined_state
    Flag indicating whether the state should be considered fully defined, and thus whether constraints such as sum of mass/mole fractions should be included, default - False. Valid values: { True - state variables will be fully defined, False - state variables will not be fully defined.}
    has_phase_equilibrium
    Flag indicating whether phase equilibrium constraints should be constructed in this state block, default - True. Valid values: { True - StateBlock should calculate phase equilibrium, False - StateBlock should not calculate phase equilibrium.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(BFWStateBlock) New instance

class idaes.property_models.examples.BFW_properties.PhysicalParameterData(component)[source]

Property Parameter Block Class.

Contains parameters and indexing sets associated with properties for superheated steam.

build()[source]

Callable method for Block construction.

classmethod define_metadata(obj)[source]

Set all the metadata for properties and units.

This method should be implemented by subclasses. In the implementation, they should set information into the object provided as an argument.

Parameters:pcm (PropertyClassMetadata) – Add metadata to this object.
Returns:None
class idaes.property_models.examples.BFW_properties.StateTestBlockData(component)[source]

An example property package for boiler feed water properties.

build()[source]

Callable method for Block construction.

define_state_vars()[source]

Define state variables for ports.

get_enthalpy_density_terms(p)[source]

Define enthalpy density terms for control volume.

get_enthalpy_flow_terms(p)[source]

Define enthalpy flow terms for control volume.

get_material_density_terms(p, j)[source]

Define material density terms for control volume.

get_material_flow_terms(p, j)[source]

Define material flow terms for control volume.

model_check()[source]

Model checks for property block.

idaes.property_models.examples.methane_combustion_ideal module

Example property package for the combustion of methane in air using Gibbs energy minimisation.

class idaes.property_models.examples.methane_combustion_ideal.MethaneCombustionParameterBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    default_arguments
    Default arguments to use with Property Package
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(MethaneCombustionParameterBlock) New instance

class idaes.property_models.examples.methane_combustion_ideal.MethaneCombustionStateBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    parameters
    A reference to an instance of the Property Parameter Block associated with this property package.
    defined_state
    Flag indicating whether the state should be considered fully defined, and thus whether constraints such as sum of mass/mole fractions should be included, default - False. Valid values: { True - state variables will be fully defined, False - state variables will not be fully defined.}
    has_phase_equilibrium
    Flag indicating whether phase equilibrium constraints should be constructed in this state block, default - True. Valid values: { True - StateBlock should calculate phase equilibrium, False - StateBlock should not calculate phase equilibrium.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(MethaneCombustionStateBlock) New instance

class idaes.property_models.examples.methane_combustion_ideal.MethaneCombustionStateBlockData(component)[source]

An example property package for ideal gas properties with Gibbs energy

build()[source]

Callable method for Block construction

define_state_vars()[source]

Method that returns a dictionary of state variables used in property package. Implement a placeholder method which returns an Exception to force users to overload this.

get_enthalpy_density_terms(p)[source]

Method which returns a valid expression for enthalpy density to use in the energy balances.

get_enthalpy_flow_terms(p)[source]

Method which returns a valid expression for enthalpy flow to use in the energy balances.

get_material_density_terms(p, j)[source]

Method which returns a valid expression for material density to use in the material balances .

get_material_flow_terms(p, j)[source]

Method which returns a valid expression for material flow to use in the material balances.

model_check()[source]

Model checks for property block

class idaes.property_models.examples.methane_combustion_ideal.PhysicalParameterData(component)[source]

Property Parameter Block Class

Contains parameters and indexing sets associated with properties for superheated steam.

build()[source]

Callable method for Block construction.

classmethod define_metadata(obj)[source]

Set all the metadata for properties and units.

This method should be implemented by subclasses. In the implementation, they should set information into the object provided as an argument.

Parameters:pcm (PropertyClassMetadata) – Add metadata to this object.
Returns:None
idaes.property_models.examples.saponification_reactions module

Example property package for the saponification of Ethyl Acetate with NaOH Assumes dilute solutions with properties of H2O.

class idaes.property_models.examples.saponification_reactions.ReactionBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    parameters
    A reference to an instance of the Reaction Parameter Block associated with this property package.
    state_block
    A reference to an instance of a StateBlock with which this reaction block should be associated.
    has_equilibrium
    Flag indicating whether equilibrium constraints should be constructed in this reaction block, default - True. Valid values: { True - ReactionBlock should enforce equilibrium constraints, False - ReactionBlock should not enforce equilibrium constraints.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(ReactionBlock) New instance

class idaes.property_models.examples.saponification_reactions.ReactionBlockData(component)[source]

An example reaction package for saponification of ethyl acetate

build()[source]

Callable method for Block construction

get_reaction_rate_basis()[source]

Method which returns an Enum indicating the basis of the reaction rate term.

model_check()[source]

Model checks for property block

class idaes.property_models.examples.saponification_reactions.ReactionParameterData(component)[source]

Property Parameter Block Class

Contains parameters and indexing sets associated with properties for superheated steam.

build()[source]

Callable method for Block construction.

classmethod define_metadata(obj)[source]

Set all the metadata for properties and units.

This method should be implemented by subclasses. In the implementation, they should set information into the object provided as an argument.

Parameters:pcm (PropertyClassMetadata) – Add metadata to this object.
Returns:None
class idaes.property_models.examples.saponification_reactions.SaponificationReactionParameterBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    property_package
    Reference to associated PropertyPackageParameter object
    default_arguments
    Default arguments to use with Property Package
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(SaponificationReactionParameterBlock) New instance

idaes.property_models.examples.saponification_thermo module

Example property package for the saponification of Ethyl Acetate with NaOH Assumes dilute solutions with properties of H2O.

class idaes.property_models.examples.saponification_thermo.PhysicalParameterData(component)[source]

Property Parameter Block Class

Contains parameters and indexing sets associated with properties for superheated steam.

build()[source]

Callable method for Block construction.

classmethod define_metadata(obj)[source]

Set all the metadata for properties and units.

This method should be implemented by subclasses. In the implementation, they should set information into the object provided as an argument.

Parameters:pcm (PropertyClassMetadata) – Add metadata to this object.
Returns:None
class idaes.property_models.examples.saponification_thermo.SaponificationParameterBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    default_arguments
    Default arguments to use with Property Package
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(SaponificationParameterBlock) New instance

class idaes.property_models.examples.saponification_thermo.SaponificationStateBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    parameters
    A reference to an instance of the Property Parameter Block associated with this property package.
    defined_state
    Flag indicating whether the state should be considered fully defined, and thus whether constraints such as sum of mass/mole fractions should be included, default - False. Valid values: { True - state variables will be fully defined, False - state variables will not be fully defined.}
    has_phase_equilibrium
    Flag indicating whether phase equilibrium constraints should be constructed in this state block, default - True. Valid values: { True - StateBlock should calculate phase equilibrium, False - StateBlock should not calculate phase equilibrium.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(SaponificationStateBlock) New instance

class idaes.property_models.examples.saponification_thermo.SaponificationStateBlockData(component)[source]

An example property package for properties for saponification of ethyl acetate

build()[source]

Callable method for Block construction

define_state_vars()[source]

Method that returns a dictionary of state variables used in property package. Implement a placeholder method which returns an Exception to force users to overload this.

get_enthalpy_density_terms(p)[source]

Method which returns a valid expression for enthalpy density to use in the energy balances.

get_enthalpy_flow_terms(p)[source]

Method which returns a valid expression for enthalpy flow to use in the energy balances.

get_material_density_terms(p, j)[source]

Method which returns a valid expression for material density to use in the material balances .

get_material_flow_basis()[source]

Method which returns an Enum indicating the basis of the material flow term.

get_material_flow_terms(p, j)[source]

Method which returns a valid expression for material flow to use in the material balances.

model_check()[source]

Model checks for property block

idaes.property_models.iapws95 package
Submodules
idaes.property_models.iapws95.iapws95_wrap_ph module

IDAES IAPWS-95 Steam properties

Dropped all critical enhancments and non-analytic terms ment to imporve accruacy near the critical point. These tend to cause singularities in the equations, and it is assumend that we will try to avoid operating very close to the critical point.

References: (some of this is only used in the C++ part)
International Association for the Properties of Water and Steam (2016).
IAPWS R6-95 (2016), “Revised Release on the IAPWS Formulation 1995 for the Properties of Ordinary Water Substance for General Scientific Use,” URL: http://iapws.org/relguide/IAPWS95-2016.pdf
Wagner, W., A. Pruss (2002). “The IAPWS Formulation 1995 for the
Thermodynamic Properties of Ordinary Water Substance for General and Scientific Use.” J. Phys. Chem. Ref. Data, 31, 387-535.
Wagner, W. et al. (2000). “The IAPWS Industrial Formulation 1997 for the
Thermodynamic Properties of Water and Steam,” ASME J. Eng. Gas Turbines and Power, 122, 150-182.
Akasaka, R. (2008). “A Reliable and Useful Method to Determine the Saturation
State from Helmholtz Energy Equations of State.” Journal of Thermal Science and Technology, 3(3), 442-451.
International Association for the Properties of Water and Steam (2011).
IAPWS R15-11, “Release on the IAPWS Formulation 2011 for the Thermal Conductivity of Ordinary Water Substance,” URL: http://iapws.org/relguide/ThCond.pdf
International Association for the Properties of Water and Steam (2008).
IAPWS R12-08, “Release on the IAPWS Formulation 2008 for the Viscosity of Ordinary Water Substance,” URL: http://iapws.org/relguide/visc.pdf
class idaes.property_models.iapws95.iapws95_wrap_ph.Iapws95ParameterBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    default_arguments
    Default arguments to use with Property Package
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Iapws95ParameterBlock) New instance

class idaes.property_models.iapws95.iapws95_wrap_ph.Iapws95ParameterBlockData(component)[source]
build()[source]

General build method for PropertyParameterBlocks. Inheriting models should call super().build.

Parameters:None
Returns:None
classmethod define_metadata(obj)[source]

Set all the metadata for properties and units.

This method should be implemented by subclasses. In the implementation, they should set information into the object provided as an argument.

Parameters:pcm (PropertyClassMetadata) – Add metadata to this object.
Returns:None
class idaes.property_models.iapws95.iapws95_wrap_ph.Iapws95StateBlock(*args, **kwargs)

This is some placeholder doc.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    parameters
    A reference to an instance of the Property Parameter Block associated with this property package.
    defined_state
    Flag indicating whether the state should be considered fully defined, and thus whether constraints such as sum of mass/mole fractions should be included, default - False. Valid values: { True - state variables will be fully defined, False - state variables will not be fully defined.}
    has_phase_equilibrium
    Flag indicating whether phase equilibrium constraints should be constructed in this state block, default - True. Valid values: { True - StateBlock should calculate phase equilibrium, False - StateBlock should not calculate phase equilibrium.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Iapws95StateBlock) New instance

class idaes.property_models.iapws95.iapws95_wrap_ph.Iapws95StateBlockData(component)[source]

This is a property package for calcuating thermophysical properties of water

build(*args)[source]

Callable method for Block construction

define_state_vars()[source]

Method that returns a dictionary of state variables used in property package. Implement a placeholder method which returns an Exception to force users to overload this.

get_enthalpy_density_terms(p)[source]

Method which returns a valid expression for enthalpy density to use in the energy balances.

get_enthalpy_flow_terms(p)[source]

Method which returns a valid expression for enthalpy flow to use in the energy balances.

get_material_density_terms(p, j)[source]

Method which returns a valid expression for material density to use in the material balances .

get_material_flow_terms(p, j)[source]

Method which returns a valid expression for material flow to use in the material balances.

idaes.property_models.iapws95.iapws95_wrap_ph.htpx(T, P=None, x=None)[source]

Conveneince function to calculate steam enthalpy from temperature and either pressure or vapor fraction. This function can be used for inlet streams and initialization where temperature is known instread of enthalpy. :param T: Temperature [K] :param P: Pressure [Pa], None if saturated steam :param x: Vapor fraction [mol vapor/mol total], None if superheated or subcooled

Returns:Molar enthalpy [J/mol].
idaes.property_models.ideal package
Submodules
idaes.property_models.ideal.BTX_ideal_VLE module

Example ideal parameter block for the VLE calucations for a Benzene-Toluene-o-Xylene system.

class idaes.property_models.ideal.BTX_ideal_VLE.BTXParameterBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    default_arguments
    Default arguments to use with Property Package
    valid_phase
    Flag indicating the valid phase for a given set of conditions, and thus corresponding constraints should be included, default - (‘Vap’, ‘Liq’). Valid values: { ‘Liq’ - Liquid only, ‘Vap’ - Vapor only, (‘Vap’, ‘Liq’) - Vapor-liquid equilibrium, (‘Liq’, ‘Vap’) - Vapor-liquid equilibrium,}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(BTXParameterBlock) New instance

class idaes.property_models.ideal.BTX_ideal_VLE.BTXParameterData(component)[source]
build()[source]

Callable method for Block construction.

idaes.property_models.ideal.ideal_prop_pack_VLE module

Ideal property package with VLE calucations. Correlations to compute Cp_comp, h_comp and vapor pressure are obtained from “The properties of gases and liquids by Robert C. Reid” and “Perry’s Chemical Engineers Handbook by Robert H. Perry”. SI units.

class idaes.property_models.ideal.ideal_prop_pack_VLE.IdealParameterData(component)[source]

Property Parameter Block Class Contains parameters and indexing sets associated with properties for BTX system.

build()[source]

Callable method for Block construction.

classmethod define_metadata(obj)[source]

Define properties supported and units.

class idaes.property_models.ideal.ideal_prop_pack_VLE.IdealStateBlock(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    parameters
    A reference to an instance of the Property Parameter Block associated with this property package.
    defined_state
    Flag indicating whether the state should be considered fully defined, and thus whether constraints such as sum of mass/mole fractions should be included, default - False. Valid values: { True - state variables will be fully defined, False - state variables will not be fully defined.}
    has_phase_equilibrium
    Flag indicating whether phase equilibrium constraints should be constructed in this state block, default - True. Valid values: { True - StateBlock should calculate phase equilibrium, False - StateBlock should not calculate phase equilibrium.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(IdealStateBlock) New instance

class idaes.property_models.ideal.ideal_prop_pack_VLE.IdealStateBlockData(component)[source]

An example property package for ideal VLE.

build()[source]

Callable method for Block construction.

calculate_bubble_point_pressure(clear_components=True)[source]

“To compute the bubble point pressure of the mixture.

calculate_bubble_point_temperature(clear_components=True)[source]

“To compute the bubble point temperature of the mixture.

calculate_dew_point_pressure(clear_components=True)[source]

“To compute the dew point pressure of the mixture.

calculate_dew_point_temperature(clear_components=True)[source]

“To compute the dew point temperature of the mixture.

define_state_vars()[source]

Define state vars.

get_enthalpy_density_terms(p)[source]

Create enthalpy density terms.

get_enthalpy_flow_terms(p)[source]

Create enthalpy flow terms.

get_material_density_terms(p, j)[source]

Create material density terms.

get_material_flow_basis()[source]

Method which returns an Enum indicating the basis of the material flow term.

get_material_flow_terms(p, j)[source]

Create material flow terms for control volume.

model_check()[source]

Model checks for property block.

idaes.property_models.ideal.test_ideal module

Tests for ideal state block; tests for construction and solves Author: Jaffer Ghouse

idaes.ui package
Submodules
idaes.ui.report module
idaes.ui.report.active_equalities(blk)[source]

Generator returning active equality constraints in a model.

Parameters:blk – a Pyomo block in which to look for variables.
idaes.ui.report.active_equality_set(blk)[source]

Generator returning active equality constraints in a model.

Parameters:blk – a Pyomo block in which to look for variables.
idaes.ui.report.count_equality_constraints(blk)[source]

Count active equality constraints.

idaes.ui.report.count_free_variables(blk)[source]

Count free variables that are in active equality constraints. Ignore inequalities, because this is used in the degrees of freedom calculations

idaes.ui.report.degrees_of_freedom(blk)[source]

Return the degrees of freedom.

idaes.ui.report.fixed_variables(blk)[source]

Generator returning fixed variables in a model.

Parameters:blk – a Pyomo block in which to look for variables.
idaes.ui.report.free_variables(blk)[source]

Generator returning free variables in a model. same as unfixed

Parameters:blk – a Pyomo block in which to look for variables.
idaes.ui.report.free_variables_in_active_equalities_set(blk)[source]

Return a set of variables that are contined in active equalities.

idaes.ui.report.large_residuals(blk, tol=1e-05)[source]

Generator return active Pyomo constraints with residuals greater than tol.

Parameters:
  • blk – a Pyomo block in which to look for constraints
  • tol – show constraints with residuals greated than tol
idaes.ui.report.stale_variables(blk)[source]

Generator returning stale variables in a model.

Parameters:blk – a Pyomo block in which to look for variables.
idaes.ui.report.unfixed_variables(blk)[source]

Generator returning free variables in a model.

Parameters:blk – a Pyomo block in which to look for variables.
idaes.ui.report.variables_in_active_equalities_set(blk)[source]

Return a set of variables that are contined in active equalities.

idaes.unit_models package
Subpackages
idaes.unit_models.convergence package
Subpackages
idaes.unit_models.convergence.pressure_changer package
Submodules
idaes.unit_models.convergence.pressure_changer.pressure_changer_conv_eval module
idaes.unit_models.icons package
idaes.unit_models.power_generation package
Submodules
idaes.unit_models.power_generation.feedwater_heater_0D module

This file contains 0D feedwater heater models. These models are suitable for steady state calculations. For dynamic modeling 1D models are required. There are two models included here.

  1. FWHCondensing0D: this is a regular 0D heat exchanger model with a constraint added to ensure all the steam fed to the feedwater heater is condensed at the outlet. At the side_1 outlet the molar enthalpy is equal to the the staurated liquid molar enthalpy.
  2. FWH0D is a feedwater heater model with three sections and a mixer for combining another feedwater heater’s drain outlet with steam extracted from the turbine. The drain mixer, desuperheat, and drain cooling sections are optional. Only the condensing section is required.
class idaes.unit_models.power_generation.feedwater_heater_0D.FWH0D(*args, **kwargs)

Feedwater Heater Model This is a 0D feedwater heater model. The model may contain three 0D heat exchanger models representing the desuperheat, condensing and drain cooling sections of the feedwater heater. Only the condensing section must be included. A drain mixer can also be optionally included, which mixes the drain outlet of another feedwater heater with the steam fed into the condensing section.

Args:

rule (function): A rule function or None. Default rule calls build(). concrete (bool): If True, make this a toplevel model. Default - False. ctype (str): Pyomo ctype of the block. Default - “Block” default (dict): Default ProcessBlockData config

Keys
dynamic
Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
has_holdup
Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
has_drain_mixer
Add a mixer to the inlet of the condensing section to add water from the drain of another feedwaterheater to the steam, if True
has_desuperheat
Add a mixer desuperheat section to the heat exchanger
has_drain_cooling
Add a section after condensing section to cool condensate.
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
condense

ProcessBlockData

dynamic
Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
has_holdup
Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
side_1

A config block used to construct the side_1 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
side_2

A config block used to construct the side_2 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
delta_temperature_rule
Rule for equation for temperature difference
flow_pattern
Heat exchanger flow pattern, default - HeatExchangerFlowPattern.countercurrent. Valid values: { HeatExchangerFlowPattern.countercurrent - countercurrent flow, HeatExchangerFlowPattern.cocurrent - cocurrent flow, HeatExchangerFlowPattern.crossflow - cross flow, factor times countercurrent temperature difference.}
desuperheat

ProcessBlockData

dynamic
Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
has_holdup
Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
side_1

A config block used to construct the side_1 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
side_2

A config block used to construct the side_2 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
delta_temperature_rule
Rule for equation for temperature difference
flow_pattern
Heat exchanger flow pattern, default - HeatExchangerFlowPattern.countercurrent. Valid values: { HeatExchangerFlowPattern.countercurrent - countercurrent flow, HeatExchangerFlowPattern.cocurrent - cocurrent flow, HeatExchangerFlowPattern.crossflow - cross flow, factor times countercurrent temperature difference.}
cooling

ProcessBlockData

dynamic
Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
has_holdup
Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
side_1

A config block used to construct the side_1 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
side_2

A config block used to construct the side_2 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
delta_temperature_rule
Rule for equation for temperature difference
flow_pattern
Heat exchanger flow pattern, default - HeatExchangerFlowPattern.countercurrent. Valid values: { HeatExchangerFlowPattern.countercurrent - countercurrent flow, HeatExchangerFlowPattern.cocurrent - cocurrent flow, HeatExchangerFlowPattern.crossflow - cross flow, factor times countercurrent temperature difference.}
initialize (dict): ProcessBlockData config for individual elements. Keys
are BlockData indexes and values are dictionaries described under the “default” argument above.
idx_map (function): Function to take the index of a BlockData element and
return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:
(FWH0D) New instance
class idaes.unit_models.power_generation.feedwater_heater_0D.FWH0DData(component)[source]
build()[source]

General build method for UnitModelBlockData. This method calls a number of sub-methods which automate the construction of expected attributes of unit models.

Inheriting models should call super().build.

Parameters:None
Returns:None
initialize(*args, **kwargs)[source]

This is a general purpose initialization routine for simple unit models. This method assumes a single ControlVolume block called controlVolume, and first initializes this and then attempts to solve the entire unit.

More complex models should overload this method with their own initialization routines,

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating which solver to use during initialization (default = ‘ipopt’)
Returns:

None

class idaes.unit_models.power_generation.feedwater_heater_0D.FWHCondensing0D(*args, **kwargs)

Feedwater Heater Condensing Section The feedwater heater condensing section model is a normal 0D heat exchanger model with an added constraint to calculate the steam flow such that the outlet of side_1 is a saturated liquid.

Args:

rule (function): A rule function or None. Default rule calls build(). concrete (bool): If True, make this a toplevel model. Default - False. ctype (str): Pyomo ctype of the block. Default - “Block” default (dict): Default ProcessBlockData config

Keys
dynamic
Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
has_holdup
Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
side_1

A config block used to construct the side_1 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
side_2

A config block used to construct the side_2 control volume.

material_balance_type
Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
energy_balance_type
Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
momentum_balance_type
Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
has_phase_equilibrium
Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
has_pressure_change
Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
property_package
Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
property_package_args
A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
delta_temperature_rule
Rule for equation for temperature difference
flow_pattern
Heat exchanger flow pattern, default - HeatExchangerFlowPattern.countercurrent. Valid values: { HeatExchangerFlowPattern.countercurrent - countercurrent flow, HeatExchangerFlowPattern.cocurrent - cocurrent flow, HeatExchangerFlowPattern.crossflow - cross flow, factor times countercurrent temperature difference.}
initialize (dict): ProcessBlockData config for individual elements. Keys
are BlockData indexes and values are dictionaries described under the “default” argument above.
idx_map (function): Function to take the index of a BlockData element and
return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:
(FWHCondensing0D) New instance
class idaes.unit_models.power_generation.feedwater_heater_0D.FWHCondensing0DData(component)[source]
build()[source]

Building model

Parameters:None
Returns:None
initialize(*args, **kwargs)[source]

Use the regular heat exchanger initilization, with the extraction rate constraint deactivated; then it activates the constraint and calculates a steam inlet flow rate.

idaes.unit_models.power_generation.turbine_inlet module

Steam turbine inlet stage model. This model is based on:

Liese, (2014). “Modeling of a Steam Turbine Including Partial Arc Admission
for Use in a Process Simulation Software Environment.” Journal of Engineering for Gas Turbines and Power. v136.
class idaes.unit_models.power_generation.turbine_inlet.TurbineInletStage(*args, **kwargs)

Inlet stage steam turbine model

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    compressor
    Indicates whether this unit should be considered a compressor (True (default), pressure increase) or an expander (False, pressure decrease).
    thermodynamic_assumption
    Flag to set the thermodynamic assumption to use for the unit. - ThermodynamicAssumption.isothermal (default) - ThermodynamicAssumption.isentropic - ThermodynamicAssumption.pump - ThermodynamicAssumption.adiabatic
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(TurbineInletStage) New instance

class idaes.unit_models.power_generation.turbine_inlet.TurbineInletStageData(component)[source]
build()[source]
Parameters:None
Returns:None
initialize(state_args={}, outlvl=0, solver='ipopt', optarg={'max_iter': 30, 'tol': 1e-06})[source]

Initialize the inlet turbine stage model. This deactivates the specialized constraints, then does the isentropic turbine initialization, then reactivates the constraints and solves.

Parameters:
  • state_args (dict) – Initial state for property initialization
  • outlvl (int) – Amount of output (0 to 3) 0 is lowest
  • solver (str) – Solver to use for initialization
  • optarg (dict) – Solver arguments dictionary
idaes.unit_models.power_generation.turbine_multistage module

Multistage steam turbine for power generation.

Liese, (2014). “Modeling of a Steam Turbine Including Partial Arc Admission
for Use in a Process Simulation Software Environment.” Journal of Engineering for Gas Turbines and Power. v136, November
class idaes.unit_models.power_generation.turbine_multistage.TurbineMultistage(*args, **kwargs)

Multistage steam turbine with optional reheat and extraction

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether the model is dynamic.
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    has_phase_equilibrium
    Argument indicating whether phase equilibrium should be calculated for the resulting mixed stream, default - False. Valid values: { True - calculate phase equilibrium in mixed stream, False - do not calculate equilibrium in mixed stream.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    num_parallel_inlet_stages
    Number of parallel inlet stages to simulate partial arc admission. Default=4
    num_hp
    Number of high pressure stages not including inlet stage
    num_ip
    Number of intermediate pressure stages
    num_lp
    Number of low pressure stages not including outlet stage
    hp_split_locations
    A list of index locations of splitters in the HP section. The indexes indicate after which stage to include splitters. 0 is between the inlet stage and the first regular HP stage.
    ip_split_locations
    A list of index locations of splitters in the IP section. The indexes indicate after which stage to include splitters.
    lp_split_locations
    A list of index locations of splitters in the LP section. The indexes indicate after which stage to include splitters.
    hp_disconnect
    HP Turbine stages to not connect to next with an arc. This is usually used to insert addtional units between stages on a flowsheet, such as a reheater
    ip_disconnect
    IP Turbine stages to not connect to next with an arc. This is usually used to insert addtional units between stages on a flowsheet, such as a reheater
    lp_disconnect
    LP Turbine stages to not connect to next with an arc. This is usually used to insert addtional units between stages on a flowsheet, such as a reheater
    hp_split_num_outlets
    Dict, hp split index: number of splitter outlets, if not 2
    ip_split_num_outlets
    Dict, ip split index: number of splitter outlets, if not 2
    lp_split_num_outlets
    Dict, lp split index: number of splitter outlets, if not 2
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(TurbineMultistage) New instance

class idaes.unit_models.power_generation.turbine_multistage.TurbineMultistageData(component)[source]
build()[source]

General build method for UnitModelBlockData. This method calls a number of sub-methods which automate the construction of expected attributes of unit models.

Inheriting models should call super().build.

Parameters:None
Returns:None
initialize(outlvl=0, solver='ipopt', optarg={'max_iter': 35, 'tol': 1e-06})[source]

Initialize

throttle_cv_fix(value)[source]

Fix the thottle valve coefficients. These are generally the same for each of the parallel stages so this provides a convenient way to set them.

Parameters:value – The value to fix the turbine inlet flow coefficients at
turbine_inlet_cf_fix(value)[source]

Fix the inlet turbine stage flow coefficient. These are generally the same for each of the parallel stages so this provides a convenient way to set them.

Parameters:value – The value to fix the turbine inlet flow coefficients at
turbine_outlet_cf_fix(value)[source]

Fix the inlet turbine stage flow coefficient. These are generally the same for each of the parallel stages so this provides a convenient way to set them.

Parameters:value – The value to fix the turbine inlet flow coefficients at
idaes.unit_models.power_generation.turbine_outlet module

Steam turbine outlet stage model. This model is based on:

Liese, (2014). “Modeling of a Steam Turbine Including Partial Arc Admission
for Use in a Process Simulation Software Environment.” Journal of Engineering for Gas Turbines and Power. v136.
class idaes.unit_models.power_generation.turbine_outlet.TurbineOutletStage(*args, **kwargs)

Outlet stage steam turbine model

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    compressor
    Indicates whether this unit should be considered a compressor (True (default), pressure increase) or an expander (False, pressure decrease).
    thermodynamic_assumption
    Flag to set the thermodynamic assumption to use for the unit. - ThermodynamicAssumption.isothermal (default) - ThermodynamicAssumption.isentropic - ThermodynamicAssumption.pump - ThermodynamicAssumption.adiabatic
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(TurbineOutletStage) New instance

class idaes.unit_models.power_generation.turbine_outlet.TurbineOutletStageData(component)[source]
build()[source]
Parameters:None
Returns:None
initialize(state_args={}, outlvl=0, solver='ipopt', optarg={'max_iter': 30, 'tol': 1e-06})[source]

Initialize the outlet turbine stage model. This deactivates the specialized constraints, then does the isentropic turbine initialization, then reactivates the constraints and solves.

Parameters:
  • state_args (dict) – Initial state for property initialization
  • outlvl (int) – Amount of output (0 to 3) 0 is lowest
  • solver (str) – Solver to use for initialization
  • optarg (dict) – Solver arguments dictionary
idaes.unit_models.power_generation.turbine_stage module

Steam turbine stage model. This is a standard isentropic turbine. Under off-design conditions the base efficiency and pressure ratio do not change much for the stages between the inlet and outlet. This model is based on:

Liese, (2014). “Modeling of a Steam Turbine Including Partial Arc Admission
for Use in a Process Simulation Software Environment.” Journal of Engineering for Gas Turbines and Power. v136.
class idaes.unit_models.power_generation.turbine_stage.TurbineStage(*args, **kwargs)

Basic steam turbine model

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    compressor
    Indicates whether this unit should be considered a compressor (True (default), pressure increase) or an expander (False, pressure decrease).
    thermodynamic_assumption
    Flag to set the thermodynamic assumption to use for the unit. - ThermodynamicAssumption.isothermal (default) - ThermodynamicAssumption.isentropic - ThermodynamicAssumption.pump - ThermodynamicAssumption.adiabatic
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(TurbineStage) New instance

class idaes.unit_models.power_generation.turbine_stage.TurbineStageData(component)[source]
build()[source]
Parameters:None
Returns:None
initialize(state_args={}, outlvl=0, solver='ipopt', optarg={'max_iter': 30, 'tol': 1e-06})[source]

Initialize the turbine stage model. This deactivates the specialized constraints, then does the isentropic turbine initialization, then reactivates the constraints and solves.

Parameters:
  • state_args (dict) – Initial state for property initialization
  • outlvl (int) – Amount of output (0 to 3) 0 is lowest
  • solver (str) – Solver to use for initialization
  • optarg (dict) – Solver arguments dictionary
idaes.unit_models.power_generation.valve_steam module

This provides valve models for steam and liquid water. These are for steam cycle control valves and the turbine throttle valves.

class idaes.unit_models.power_generation.valve_steam.SteamValve(*args, **kwargs)

Basic steam valve models

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    compressor
    Indicates whether this unit should be considered a compressor (True (default), pressure increase) or an expander (False, pressure decrease).
    thermodynamic_assumption
    Flag to set the thermodynamic assumption to use for the unit. - ThermodynamicAssumption.isothermal (default) - ThermodynamicAssumption.isentropic - ThermodynamicAssumption.pump - ThermodynamicAssumption.adiabatic
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    valve_function
    The type of valve function, if custom provide an expression rule with the valve_function_rule argument. default - ValveFunctionType.linear Valid values - { ValveFunctionType.linear, ValveFunctionType.quick_opening, ValveFunctionType.equal_percentage, ValveFunctionType.custom}
    valve_function_rule
    This is a rule that returns a time indexed valve function expression. This is required only if valve_function==ValveFunctionType.custom
    phase
    Expected phase of fluid in valve in {“Liq”, “Vap”}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(SteamValve) New instance

class idaes.unit_models.power_generation.valve_steam.SteamValveData(component)[source]
build()[source]
Parameters:None
Returns:None
initialize(state_args={}, outlvl=0, solver='ipopt', optarg={'max_iter': 30, 'tol': 1e-06})[source]

Initialize the turbine stage model. This deactivates the specialized constraints, then does the isentropic turbine initialization, then reactivates the constraints and solves.

Parameters:
  • state_args (dict) – Initial state for property initialization
  • outlvl (int) – Amount of output (0 to 3) 0 is lowest
  • solver (str) – Solver to use for initialization
  • optarg (dict) – Solver arguments dictionary
idaes.unit_models.power_generation.valve_steam_config module

Define configuration block for the SteamValve model.

class idaes.unit_models.power_generation.valve_steam_config.ValveFunctionType[source]

An enumeration.

Submodules
idaes.unit_models.cstr module

Standard IDAES CSTR model.

class idaes.unit_models.cstr.CSTR(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of material balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_heat_transfer
    Indicates whether terms for heat transfer should be constructed, default - False. Valid values: { True - include heat transfer terms, False - exclude heat transfer terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    has_equilibrium_reactions
    Indicates whether terms for equilibrium controlled reactions should be constructed, default - True. Valid values: { True - include equilibrium reaction terms, False - exclude equilibrium reaction terms.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    has_heat_of_reaction
    Indicates whether terms for heat of reaction terms should be constructed, default - False. Valid values: { True - include heat of reaction terms, False - exclude heat of reaction terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PhysicalParameterObject - a PhysicalParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    reaction_package
    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}
    reaction_package_args
    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(CSTR) New instance

class idaes.unit_models.cstr.CSTRData(component)[source]

Standard CSTR Unit Model Class

build()[source]

Begin building model (pre-DAE transformation). :param None:

Returns:None
idaes.unit_models.equilibrium_reactor module

Standard IDAES Equilibrium Reactor model.

class idaes.unit_models.equilibrium_reactor.EquilibriumReactor(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = False. Equilibrium Reactors do not support dynamic behavior.
    has_holdup
    Indicates whether holdup terms should be constructed or not. default - False. Equilibrium reactors do not have defined volume, thus this must be False.
    material_balance_type
    Indicates what type of material balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_rate_reactions
    Indicates whether terms for rate controlled reactions should be constructed, along with constraints equating these to zero, default - True. Valid values: { True - include rate reaction terms, False - exclude rate reaction terms.}
    has_equilibrium_reactions
    Indicates whether terms for equilibrium controlled reactions should be constructed, default - True. Valid values: { True - include equilibrium reaction terms, False - exclude equilibrium reaction terms.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default - True. Valid values: { True - include phase equilibrium term, False - exclude phase equlibirum terms.}
    has_heat_transfer
    Indicates whether terms for heat transfer should be constructed, default - False. Valid values: { True - include heat transfer terms, False - exclude heat transfer terms.}
    has_heat_of_reaction
    Indicates whether terms for heat of reaction terms should be constructed, default - False. Valid values: { True - include heat of reaction terms, False - exclude heat of reaction terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PhysicalParameterObject - a PhysicalParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    reaction_package
    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}
    reaction_package_args
    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(EquilibriumReactor) New instance

class idaes.unit_models.equilibrium_reactor.EquilibriumReactorData(component)[source]

Standard Equilibrium Reactor Unit Model Class

build()[source]

Begin building model.

Parameters:None
Returns:None
idaes.unit_models.feed module

Standard IDAES Feed block.

class idaes.unit_models.feed.Feed(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = False. Feed blocks are always steady-state.
    has_holdup
    Feed blocks do not contain holdup, thus this must be False.
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PhysicalParameterObject - a PhysicalParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Feed) New instance

class idaes.unit_models.feed.FeedData(component)[source]

Standard Feed Block Class

build()[source]

Begin building model.

Parameters:None
Returns:None
initialize(state_args={}, outlvl=0, solver='ipopt', optarg={'tol': 1e-06})[source]

This method calls the initialization method of the state block.

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating which solver to use during initialization (default = ‘ipopt’)
Returns:

None

idaes.unit_models.feed_flash module

Standard IDAES Feed block with phase equilibrium.

class idaes.unit_models.feed_flash.FeedFlash(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Feed units do not support dynamic behavior.
    has_holdup
    Feed units do not have defined volume, thus this must be False.
    material_balance_type
    Indicates what type of material balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PhysicalParameterObject - a PhysicalParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(FeedFlash) New instance

class idaes.unit_models.feed_flash.FeedFlashData(component)[source]

Standard Feed block with phase equilibrium

build()[source]

Begin building model.

Parameters:None
Returns:None
idaes.unit_models.flash module

Standard IDAES flash model.

class idaes.unit_models.flash.Flash(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = False. Flash units do not support dynamic behavior.
    has_holdup
    Indicates whether holdup terms should be constructed or not. default - False. Flash units do not have defined volume, thus this must be False.
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_heat_transfer
    Indicates whether terms for heat transfer should be constructed, default - False. Valid values: { True - include heat transfer terms, False - exclude heat transfer terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - True. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Flash) New instance

class idaes.unit_models.flash.FlashData(component)[source]

Standard Flash Unit Model Class

build()[source]

Begin building model (pre-DAE transformation).

Parameters:None
Returns:None
idaes.unit_models.gibbs_reactor module

Standard IDAES Gibbs reactor model.

class idaes.unit_models.gibbs_reactor.GibbsReactor(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Gibbs reactors do not support dynamic models, thus this must be False.
    has_holdup
    Gibbs reactors do not have defined volume, thus this must be False.
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_heat_transfer
    Indicates whether terms for heat transfer should be constructed, default - False. Valid values: { True - include heat transfer terms, False - exclude heat transfer terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(GibbsReactor) New instance

class idaes.unit_models.gibbs_reactor.GibbsReactorData(component)[source]

Standard Gibbs Reactor Unit Model Class

This model assume all possible reactions reach equilibrium such that the system partial molar Gibbs free energy is minimized. Since some species mole flow rate might be very small, the natural log of the species molar flow rate is used. Instead of specifying the system Gibbs free energy as an objective function, the equations for zero partial derivatives of the grand function with Lagrangian multiple terms with repect to product species mole flow rates and the multiples are specified as constraints.

build()[source]

Begin building model (pre-DAE transformation).

Parameters:None
Returns:None
idaes.unit_models.heat_exchanger module

Heat Exchanger Models.

class idaes.unit_models.heat_exchanger.HeatExchanger(*args, **kwargs)

Simple 0D heat exchanger model.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    side_1
    A config block used to construct the side_1 control volume.
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    side_2
    A config block used to construct the side_2 control volume.
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    delta_temperature_rule
    Rule for equation for temperature difference
    flow_pattern
    Heat exchanger flow pattern, default - HeatExchangerFlowPattern.countercurrent. Valid values: { HeatExchangerFlowPattern.countercurrent - countercurrent flow, HeatExchangerFlowPattern.cocurrent - cocurrent flow, HeatExchangerFlowPattern.crossflow - cross flow, factor times countercurrent temperature difference.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(HeatExchanger) New instance

class idaes.unit_models.heat_exchanger.HeatExchangerData(component)[source]

Simple 0D heat exchange unit. Unit model to transfer heat from one material to another.

build()[source]

Building model

Parameters:None
Returns:None
initialize(state_args_1=None, state_args_2=None, outlvl=0, solver='ipopt', optarg={'tol': 1e-06}, duty=1000)[source]

Heat exchanger initialization method.

Parameters:
  • state_args_1 – a dict of arguments to be passed to the property initialization for side_1 (see documentation of the specific property package) (default = {}).
  • state_args_2 – a dict of arguments to be passed to the property initialization for side_2 (see documentation of the specific property package) (default = {}).
  • outlvl – sets output level of initialisation routine * 0 = no output (default) * 1 = return solver state for each step in routine * 2 = return solver state for each step in subroutines * 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating which solver to use during initialization (default = ‘ipopt’)
  • duty – an initial guess for the amount of heat transfered (default = 10000)
Returns:

None

set_scaling_factor_energy(f)[source]

This function sets scaling_factor_energy for both side_1 and side_2. This factor multiplies the energy balance and heat transfer equations in the heat exchnager. The value of this factor should be about 1/(expected heat duty).

Parameters:f – Energy balance scaling factor
class idaes.unit_models.heat_exchanger.HeatExchangerFlowPattern[source]

An enumeration.

class idaes.unit_models.heat_exchanger.Heater(*args, **kwargs)

Simple 0D heater/cooler model.

Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Heater) New instance

class idaes.unit_models.heat_exchanger.HeaterData(component)[source]

Simple 0D heater unit. Unit model to add or remove heat from a material.

build()[source]

Building model :param None:

Returns:None
idaes.unit_models.heat_exchanger.delta_temperature_amtd_rule(b, t)[source]

This is a rule for a temperaure difference expression to calculate \(\Delta T\) in the heat exchanger model using arithmetic-mean temperature difference (AMTD). It can be supplied to “delta_temperature_rule” HeatExchanger configuration option.

idaes.unit_models.heat_exchanger.delta_temperature_lmtd_rule(b, t)[source]

This is a rule for a temperaure difference expression to calculate \(\Delta T\) in the heat exchanger model using log-mean temperature difference (LMTD). It can be supplied to “delta_temperature_rule” HeatExchanger configuration option.

idaes.unit_models.heat_exchanger.delta_temperature_underwood2_rule(b, t)[source]

This is a rule for a temperaure difference expression to calculate \(\Delta T\) in the heat exchanger model using log-mean temperature difference (LMTD) approximation given by Underwood (1970). It can be supplied to “delta_temperature_rule” HeatExchanger configuration option. This uses a cube root function that works with negative numbers returning the real negative root. This function should always evaluate successfully.

idaes.unit_models.heat_exchanger.delta_temperature_underwood_rule(b, t)[source]

This is a rule for a temperaure difference expression to calculate \(\Delta T\) in the heat exchanger model using log-mean temperature difference (LMTD) approximation given by Underwood (1970). It can be supplied to “delta_temperature_rule” HeatExchanger configuration option.

idaes.unit_models.heat_exchanger_1D module

Basic IDAES 1D Heat Exchanger Model.

1D Single pass shell and tube HX model with 0D wall conduction model

class idaes.unit_models.heat_exchanger_1D.HeatExchanger1D(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    shell_side
    shell side config arguments
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentTotal. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    has_phase_equilibrium
    Argument to enable phase equilibrium on the shell side. - True - include phase equilibrium term - False - do not include phase equilinrium term
    property_package
    Property parameter object used to define property calculations (default = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a ParameterBlock object
    property_package_args
    A dict of arguments to be passed to the PropertyBlockData and used when constructing these (default = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a dict (see property package for documentation)
    transformation_method
    Discretization method to use for DAE transformation. See Pyomo documentation for supported transformations.
    transformation_scheme
    Discretization scheme to use when transformating domain. See Pyomo documentation for supported schemes.
    tube_side
    tube side config arguments
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentTotal. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    has_phase_equilibrium
    Argument to enable phase equilibrium on the shell side. - True - include phase equilibrium term - False - do not include phase equilinrium term
    property_package
    Property parameter object used to define property calculations (default = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a ParameterBlock object
    property_package_args
    A dict of arguments to be passed to the PropertyBlockData and used when constructing these (default = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a dict (see property package for documentation)
    transformation_method
    Discretization method to use for DAE transformation. See Pyomo documentation for supported transformations.
    transformation_scheme
    Discretization scheme to use when transformating domain. See Pyomo documentation for supported schemes.
    finite_elements
    Number of finite elements to use when discretizing length domain (default=20)
    collocation_points
    Number of collocation points to use per finite element when discretizing length domain (default=3)
    flow_type
    Flow configuration of heat exchanger - HeatExchangerFlowPattern.cocurrent: shell and tube flows from 0 to 1 - HeatExchangerFlowPattern.countercurrent: shell side flows from 0 to 1 tube side flows from 1 to 0
    has_wall_conduction
    Argument to enable type of wall heat conduction model. - WallConductionType.zero_dimensional - 0D wall model, - WallConductionType.one_dimensional - 1D wall model along the thickness of the tube, - WallConductionType.two_dimensional - 2D wall model along the lenghth and thickness of the tube
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(HeatExchanger1D) New instance

class idaes.unit_models.heat_exchanger_1D.HeatExchanger1DData(component)[source]

Standard Heat Exchanger 1D Unit Model Class.

build()[source]

Begin building model (pre-DAE transformation).

Parameters:None
Returns:None
initialize(shell_state_args=None, tube_state_args=None, outlvl=1, solver='ipopt', optarg={'tol': 1e-06})[source]

Initialisation routine for the unit (default solver ipopt).

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating whcih solver to use during initialization (default = ‘ipopt’)
Returns:

None

class idaes.unit_models.heat_exchanger_1D.WallConductionType[source]

An enumeration.

idaes.unit_models.mixer module

General purpose mixer block for IDAES models

class idaes.unit_models.mixer.Mixer(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = False. Mixer blocks are always steady-state.
    has_holdup
    Mixer blocks do not contain holdup, thus this must be False.
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    inlet_list
    A list containing names of inlets, default - None. Valid values: { None - use num_inlets argument, list - a list of names to use for inlets.}
    num_inlets
    Argument indicating number (int) of inlets to construct, not used if inlet_list arg is provided, default - None. Valid values: { None - use inlet_list arg instead, or default to 2 if neither argument provided, int - number of inlets to create (will be named with sequential integers from 1 to num_inlets).}
    has_phase_equilibrium
    Argument indicating whether phase equilibrium should be calculated for the resulting mixed stream, default - False. Valid values: { True - calculate phase equilibrium in mixed stream, False - do not calculate equilibrium in mixed stream.}
    material_mixing_type
    Argument indicating what method to use when mixing material flows of incoming streams, default - MixingType.extensive. Valid values: { MixingType.none - do not include material mixing equations, MixingType.extensive - mix total flows of each phase-component pair.}
    energy_mixing_type
    Argument indicating what method to use when mixing energy flows of incoming streams, default - MixingType.extensive. Valid values: { MixingType.none - do not include energy mixing equations, MixingType.extensive - mix total enthalpy flows of each phase.}
    momentum_mixing_type
    Argument indicating what method to use when mixing momentum/ pressure of incoming streams, default - MomentumMixingType.minimize. Valid values: { MomentumMixingType.none - do not include momentum mixing equations, MomentumMixingType.minimize - mixed stream has pressure equal to the minimimum pressure of the incoming streams (uses smoothMin operator), MomentumMixingType.equality - enforces equality of pressure in mixed and all incoming streams., MomentumMixingType.minimize_and_equality - add constraints for pressure equal to the minimum pressure of the inlets and constraints for equality of pressure in mixed and all incoming streams. When the model is initially built, the equality constraints are deactivated. This option is useful for switching between flow and pressure driven simulations.}
    mixed_state_block
    An existing state block to use as the outlet stream from the Mixer block, default - None. Valid values: { None - create a new StateBlock for the mixed stream, StateBlock - a StateBock to use as the destination for the mixed stream.}
    construct_ports
    Argument indicating whether model should construct Port objects linked to all inlet states and the mixed state, default - True. Valid values: { True - construct Ports for all states, False - do not construct Ports.
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Mixer) New instance

class idaes.unit_models.mixer.MixerData(component)[source]

This is a general purpose model for a Mixer block with the IDAES modeling framework. This block can be used either as a stand-alone Mixer unit operation, or as a sub-model within another unit operation.

This model creates a number of StateBlocks to represent the incoming streams, then writes a set of phase-component material balances, an overall enthalpy balance and a momentum balance (2 options) linked to a mixed-state StateBlock. The mixed-state StateBlock can either be specified by the user (allowing use as a sub-model), or created by the Mixer.

When being used as a sub-model, Mixer should only be used when a set of new StateBlocks are required for the streams to be mixed. It should not be used to mix streams from mutiple ControlVolumes in a single unit model - in these cases the unit model developer should write their own mixing equations.

add_energy_mixing_equations(inlet_blocks, mixed_block)[source]

Add energy mixing equations (total enthalpy balance).

add_inlet_state_blocks(inlet_list)[source]

Construct StateBlocks for all inlet streams.

Parameters:of strings to use as StateBlock names (list) –
Returns:list of StateBlocks
add_material_mixing_equations(inlet_blocks, mixed_block)[source]

Add material mixing equations (phase-component balances).

add_mixed_state_block()[source]

Constructs StateBlock to represent mixed stream.

Returns:New StateBlock object
add_port_objects(inlet_list, inlet_blocks, mixed_block)[source]

Adds Port objects if required.

Parameters:
  • list of inlet StateBlock objects (a) –
  • mixed state StateBlock object (a) –
Returns:

None

add_pressure_equality_equations(inlet_blocks, mixed_block)[source]

Add pressure equality equations. Note that this writes a number of constraints equal to the number of inlets, enforcing equality between all inlets and the mixed stream.

add_pressure_minimization_equations(inlet_blocks, mixed_block)[source]

Add pressure minimization equations. This is done by sequential comparisons of each inlet to the minimum pressure so far, using the IDAES smooth minimum fuction.

build()[source]

General build method for MixerData. This method calls a number of sub-methods which automate the construction of expected attributes of unit models.

Inheriting models should call super().build.

Parameters:None
Returns:None
create_inlet_list()[source]

Create list of inlet stream names based on config arguments.

Returns:list of strings
get_mixed_state_block()[source]

Validates StateBlock provided in user arguments for mixed stream.

Returns:The user-provided StateBlock or an Exception
initialize(outlvl=0, optarg={}, solver='ipopt', hold_state=False)[source]

Initialisation routine for mixer (default solver ipopt)

Keyword Arguments:
 
  • outlvl – sets output level of initialisation routine. Valid values: 0 - no output (default), 1 - return solver state for each step in routine, 2 - include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={})
  • solver – str indicating whcih solver to use during initialization (default = ‘ipopt’)
  • hold_state – flag indicating whether the initialization routine should unfix any state variables fixed during initialization, default - False. Valid values: True - states variables are not unfixed, and a dict of returned containing flags for which states were fixed during initialization, False - state variables are unfixed after initialization by calling the release_state method.
Returns:

If hold_states is True, returns a dict containing flags for which states were fixed during initialization.

model_check()[source]

This method executes the model_check methods on the associated state blocks (if they exist). This method is generally called by a unit model as part of the unit’s model_check method.

Parameters:None
Returns:None
release_state(flags, outlvl=0)[source]

Method to release state variables fixed during initialisation.

Keyword Arguments:
 
  • flags – dict containing information of which state variables were fixed during initialization, and should now be unfixed. This dict is returned by initialize if hold_state = True.
  • outlvl – sets output level of logging
Returns:

None

use_equal_pressure_constraint()[source]

Deactivate the mixer pressure = mimimum inlet pressure constraint and activate the mixer pressure and all inlet pressures are equal constraints. This should only be used when momentum_mixing_type == MomentumMixingType.minimize_and_equality.

use_minimum_inlet_pressure_constraint()[source]

Activate the mixer pressure = mimimum inlet pressure constraint and deactivate the mixer pressure and all inlet pressures are equal constraints. This should only be used when momentum_mixing_type == MomentumMixingType.minimize_and_equality.

class idaes.unit_models.mixer.MixingType[source]

An enumeration.

class idaes.unit_models.mixer.MomentumMixingType[source]

An enumeration.

idaes.unit_models.plug_flow_reactor module

Standard IDAES PFR model.

class idaes.unit_models.plug_flow_reactor.PFR(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_equilibrium_reactions
    Indicates whether terms for equilibrium controlled reactions should be constructed, default - True. Valid values: { True - include equilibrium reaction terms, False - exclude equilibrium reaction terms.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    has_heat_of_reaction
    Indicates whether terms for heat of reaction terms should be constructed, default - False. Valid values: { True - include heat of reaction terms, False - exclude heat of reaction terms.}
    has_heat_transfer
    Indicates whether terms for heat transfer should be constructed, default - False. Valid values: { True - include heat transfer terms, False - exclude heat transfer terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    reaction_package
    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}
    reaction_package_args
    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}
    length_domain_set
    A list of values to be used when constructing the length domain of the reactor. Point must lie between 0.0 and 1.0, default - [0.0, 1.0]. Valid values: { a list of floats}
    transformation_method
    Method to use to transform domain. Must be a method recognised by the Pyomo TransformationFactory, default - “dae.finite_difference”.
    transformation_scheme
    Scheme to use when transformating domain. See Pyomo documentation for supported schemes, default - “BACKWARD”.
    finite_elements
    Number of finite elements to use when transforming length domain, default - 20.
    collocation_points
    Number of collocation points to use when transforming length domain, default - 3.
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(PFR) New instance

class idaes.unit_models.plug_flow_reactor.PFRData(component)[source]

Standard Plug Flow Reactor Unit Model Class

build()[source]

Begin building model (pre-DAE transformation).

Parameters:None
Returns:None
idaes.unit_models.pressure_changer module

Standard IDAES pressure changer model.

class idaes.unit_models.pressure_changer.PressureChanger(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_phase_equilibrium
    Indicates whether terms for phase equilibrium should be constructed, default = False. Valid values: { True - include phase equilibrium terms False - exclude phase equilibrium terms.}
    compressor
    Indicates whether this unit should be considered a compressor (True (default), pressure increase) or an expander (False, pressure decrease).
    thermodynamic_assumption
    Flag to set the thermodynamic assumption to use for the unit. - ThermodynamicAssumption.isothermal (default) - ThermodynamicAssumption.isentropic - ThermodynamicAssumption.pump - ThermodynamicAssumption.adiabatic
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(PressureChanger) New instance

class idaes.unit_models.pressure_changer.PressureChangerData(component)[source]

Standard Compressor/Expander Unit Model Class

add_adiabatic()[source]

Add constraints for adiabatic assumption.

Parameters:None
Returns:None
add_isentropic()[source]

Add constraints for isentropic assumption.

Parameters:None
Returns:None
add_isothermal()[source]

Add constraints for isothermal assumption.

Parameters:None
Returns:None
add_performance()[source]

Define constraints which describe the behaviour of the unit model.

Parameters:None
Returns:None
add_pump()[source]

Add constraints for the incompressible fluid assumption

Parameters:None
Returns:None
build()[source]
Parameters:None
Returns:None
init_isentropic(state_args, outlvl, solver, optarg)[source]

Initialisation routine for unit (default solver ipopt)

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating whcih solver to use during initialization (default = ‘ipopt’)
Returns:

None

initialize(state_args={}, routine=None, outlvl=0, solver='ipopt', optarg={'tol': 1e-06})[source]

General wrapper for pressure changer initialisation routines

Keyword Arguments:
 
  • routine – str stating which initialization routine to execute * None - use routine matching thermodynamic_assumption * ‘isentropic’ - use isentropic initialization routine * ‘isothermal’ - use isothermal initialization routine
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating whcih solver to use during initialization (default = ‘ipopt’)
Returns:

None

model_check()[source]

Check that pressure change matches with compressor argument (i.e. if compressor = True, pressure should increase or work should be positive)

Parameters:None
Returns:None
set_geometry()[source]

Define the geometry of the unit as necessary, and link to control volume

Parameters:None
Returns:None
class idaes.unit_models.pressure_changer.ThermodynamicAssumption[source]

An enumeration.

idaes.unit_models.product module

Standard IDAES Product block.

class idaes.unit_models.product.Product(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = False. Product blocks are always steady- state.
    has_holdup
    Product blocks do not contain holdup, thus this must be False.
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PhysicalParameterObject - a PhysicalParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Product) New instance

class idaes.unit_models.product.ProductData(component)[source]

Standard Product Block Class

build()[source]

Begin building model.

Parameters:None
Returns:None
initialize(state_args={}, outlvl=0, solver='ipopt', optarg={'tol': 1e-06})[source]

This method calls the initialization method of the state block.

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating which solver to use during initialization (default = ‘ipopt’)
Returns:

None

idaes.unit_models.separator module

General purpose separator block for IDAES models

class idaes.unit_models.separator.EnergySplittingType[source]

An enumeration.

class idaes.unit_models.separator.Separator(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = False. Product blocks are always steady- state.
    has_holdup
    Product blocks do not contain holdup, thus this must be False.
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    outlet_list
    A list containing names of outlets, default - None. Valid values: { None - use num_outlets argument, list - a list of names to use for outlets.}
    num_outlets
    Argument indicating number (int) of outlets to construct, not used if outlet_list arg is provided, default - None. Valid values: { None - use outlet_list arg instead, or default to 2 if neither argument provided, int - number of outlets to create (will be named with sequential integers from 1 to num_outlets).}
    split_basis
    Argument indicating basis to use for splitting mixed stream, default - SplittingType.totalFlow. Valid values: { SplittingType.totalFlow - split based on total flow (split fraction indexed only by time and outlet), SplittingType.phaseFlow - split based on phase flows (split fraction indexed by time, outlet and phase), SplittingType.componentFlow - split based on component flows (split fraction indexed by time, outlet and components), SplittingType.phaseComponentFlow - split based on phase-component flows ( split fraction indexed by both time, outlet, phase and components).}
    energy_split_basis
    Argument indicating basis to use for splitting energy this is not used for when ideal_separation == True. default - EnergySplittingType.equal_temperature. Valid values: { EnergySplittingType.equal_temperature - outlet temperatures equal inlet EnergySplittingType.equal_molar_enthalpy - oulet molar enthalpies equal inlet}
    ideal_separation
    Argument indicating whether ideal splitting should be used. Ideal splitting assumes perfect spearation of material, and attempts to avoid duplication of StateBlocks by directly partitioning outlet flows to ports, default - True. Valid values: { True - use ideal splitting methods, False - use explicit splitting equations with split fractions.}
    ideal_split_map
    Dictionary containing information on how extensive variables should be partitioned when using ideal splitting (ideal_separation = True). default - None. Valid values: { dict with keys of indexing set members and values indicating which outlet this combination of keys should be partitioned to. E.g. {(“Vap”, “H2”): “outlet_1”}}
    mixed_state_block
    An existing state block to use as the source stream from the Separator block, default - None. Valid values: { None - create a new StateBlock for the mixed stream, StateBlock - a StateBock to use as the source for the mixed stream.}
    construct_ports
    Argument indicating whether model should construct Port objects linked the mixed state and all outlet states, default - True. Valid values: { True - construct Ports for all states, False - do not construct Ports.
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Separator) New instance

class idaes.unit_models.separator.SeparatorData(component)[source]

This is a general purpose model for a Separator block with the IDAES modeling framework. This block can be used either as a stand-alone Separator unit operation, or as a sub-model within another unit operation.

This model creates a number of StateBlocks to represent the outgoing streams, then writes a set of phase-component material balances, an overall enthalpy balance (2 options), and a momentum balance (2 options) linked to a mixed-state StateBlock. The mixed-state StateBlock can either be specified by the user (allowing use as a sub-model), or created by the Separator.

When being used as a sub-model, Separator should only be used when a set of new StateBlocks are required for the streams to be separated. It should not be used to separate streams to go to mutiple ControlVolumes in a single unit model - in these cases the unit model developer should write their own splitting equations.

add_energy_splitting_constraints(mixed_block)[source]

Creates constraints for splitting the energy flows - done by equating temperatures in outlets.

add_inlet_port_objects(mixed_block)[source]

Adds inlet Port object if required.

Parameters:mixed state StateBlock object (a) –
Returns:None
add_material_splitting_constraints(mixed_block)[source]

Creates constraints for splitting the material flows

add_mixed_state_block()[source]

Constructs StateBlock to represent mixed stream.

Returns:New StateBlock object
add_momentum_splitting_constraints(mixed_block)[source]

Creates constraints for splitting the momentum flows - done by equating pressures in outlets.

add_outlet_port_objects(outlet_list, outlet_blocks)[source]

Adds outlet Port objects if required.

Parameters:list of outlet StateBlock objects (a) –
Returns:None
add_outlet_state_blocks(outlet_list)[source]

Construct StateBlocks for all outlet streams.

Parameters:of strings to use as StateBlock names (list) –
Returns:list of StateBlocks
add_split_fractions(outlet_list)[source]

Creates outlet Port objects and tries to partiton mixed stream flows between these

Parameters:
  • representing the mixed flow to be split (StateBlock) –
  • list of names for outlets (a) –
Returns:

None

build()[source]

General build method for SeparatorData. This method calls a number of sub-methods which automate the construction of expected attributes of unit models.

Inheriting models should call super().build.

Parameters:None
Returns:None
create_outlet_list()[source]

Create list of outlet stream names based on config arguments.

Returns:list of strings
get_mixed_state_block()[source]

Validates StateBlock provided in user arguments for mixed stream.

Returns:The user-provided StateBlock or an Exception
initialize(outlvl=0, optarg={}, solver='ipopt', hold_state=False)[source]

Initialisation routine for separator (default solver ipopt)

Keyword Arguments:
 
  • outlvl – sets output level of initialisation routine. Valid values: 0 - no output (default), 1 - return solver state for each step in routine, 2 - include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default=None)
  • solver – str indicating whcih solver to use during initialization (default = ‘ipopt’)
  • hold_state – flag indicating whether the initialization routine should unfix any state variables fixed during initialization, default - False. Valid values: True - states variables are not unfixed, and a dict of returned containing flags for which states were fixed during initialization, False - state variables are unfixed after initialization by calling the release_state method.
Returns:

If hold_states is True, returns a dict containing flags for which states were fixed during initialization.

model_check()[source]

This method executes the model_check methods on the associated state blocks (if they exist). This method is generally called by a unit model as part of the unit’s model_check method.

Parameters:None
Returns:None
partition_outlet_flows(mb, outlet_list)[source]

Creates outlet Port objects and tries to partiton mixed stream flows between these

Parameters:
  • representing the mixed flow to be split (StateBlock) –
  • list of names for outlets (a) –
Returns:

None

release_state(flags, outlvl=0)[source]

Method to release state variables fixed during initialisation.

Keyword Arguments:
 
  • flags – dict containing information of which state variables were fixed during initialization, and should now be unfixed. This dict is returned by initialize if hold_state = True.
  • outlvl – sets output level of logging
Returns:

None

class idaes.unit_models.separator.SplittingType[source]

An enumeration.

idaes.unit_models.statejunction module

Standard IDAES StateJunction model.

class idaes.unit_models.statejunction.StateJunction(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this unit will be dynamic or not, default = False.
    has_holdup
    Indicates whether holdup terms should be constructed or not. default - False. StateJunctions do not have defined volume, thus this must be False.
    property_package
    Property parameter object used to define property state block, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PhysicalParameterObject - a PhysicalParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(StateJunction) New instance

class idaes.unit_models.statejunction.StateJunctionData(component)[source]

Standard StateJunction Unit Model Class

build()[source]

Begin building model. :param None:

Returns:None
initialize(state_args={}, outlvl=0, solver='ipopt', optarg={'tol': 1e-06})[source]

This method initializes the StateJunction block by calling the initialize method on the property block.

Keyword Arguments:
 
  • state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating which solver to use during initialization (default = ‘ipopt’)
Returns:

None

idaes.unit_models.stoichiometric_reactor module

Standard IDAES STOICHIOMETRIC reactor model

class idaes.unit_models.stoichiometric_reactor.StoichiometricReactor(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}
    has_holdup
    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { True - construct holdup terms, False - do not construct holdup terms}
    material_balance_type
    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentPhase. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}
    energy_balance_type
    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single ethalpy balance for material, EnergyBalanceType.enthalpyPhase - ethalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}
    momentum_balance_type
    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}
    has_heat_of_reaction
    Indicates whether terms for heat of reaction terms should be constructed, default - False. Valid values: { True - include heat of reaction terms, False - exclude heat of reaction terms.}
    has_heat_transfer
    Indicates whether terms for heat transfer should be constructed, default - False. Valid values: { True - include heat transfer terms, False - exclude heat transfer terms.}
    has_pressure_change
    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}
    property_package
    Property parameter object used to define property calculations, default - useDefault. Valid values: { useDefault - use default package from parent model or flowsheet, PropertyParameterObject - a PropertyParameterBlock object.}
    property_package_args
    A ConfigBlock with arguments to be passed to a property block(s) and used when constructing these, default - None. Valid values: { see property package for documentation.}
    reaction_package
    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}
    reaction_package_args
    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(StoichiometricReactor) New instance

class idaes.unit_models.stoichiometric_reactor.StoichiometricReactorData(component)[source]

Standard Stoichiometric Reactor Unit Model Class This model assumes that all given reactions are irreversible, and that each reaction has a fixed rate_reaction extent which has to be specified by the user.

build()[source]

Begin building model (pre-DAE transformation). :param None:

Returns:None
idaes.unit_models.translator module

Generic template for a translator block.

class idaes.unit_models.translator.Translator(*args, **kwargs)
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().
  • concrete (bool) – If True, make this a toplevel model. Default - False.
  • ctype (str) – Pyomo ctype of the block. Default - “Block”
  • default (dict) –

    Default ProcessBlockData config

    Keys
    dynamic
    Translator blocks are always steady-state.
    has_holdup
    Translator blocks do not contain holdup.
    outlet_state_defined
    Indicates whether unit model will fully define outlet state. If False, the outlet property package will enforce constraints such as sum of mole fractions and phase equilibrium. default - True. Valid values: { True - outlet state will be fully defined, False - outlet property package should enforce sumation and equilibrium constraints.}
    has_phase_equilibrium
    Indicates whether outlet property package should enforce phase equilibrium constraints. default - False. Valid values: { True - outlet property package should calculate phase equilibrium, False - outlet property package should notcalculate phase equilibrium.}
    inlet_property_package
    Property parameter object used to define property calculations for the incoming stream, default - None. Valid values: { PhysicalParameterObject - a PhysicalParameterBlock object.}
    inlet_property_package_args
    A ConfigBlock with arguments to be passed to the property block associated with the incoming stream, default - None. Valid values: { see property package for documentation.}
    outlet_property_package
    Property parameter object used to define property calculations for the outgoing stream, default - None. Valid values: { PhysicalParameterObject - a PhysicalParameterBlock object.}
    outlet_property_package_args
    A ConfigBlock with arguments to be passed to the property block associated with the outgoing stream, default - None. Valid values: { see property package for documentation.}
  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries described under the “default” argument above.
  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to overide the default behavior of matching the BlockData index exactly to the index in initialize.
Returns:

(Translator) New instance

class idaes.unit_models.translator.TranslatorData(component)[source]

Standard Translator Block Class

build()[source]

Begin building model.

Parameters:None
Returns:None
initialize(state_args_in={}, state_args_out={}, outlvl=0, solver='ipopt', optarg={'tol': 1e-06})[source]

This method calls the initialization method of the state blocks.

Keyword Arguments:
 
  • state_args_in – a dict of arguments to be passed to the inlet property package (to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • state_args_out – a dict of arguments to be passed to the outlet property package (to provide an initial state for initialization (see documentation of the specific property package) (default = {}).
  • outlvl

    sets output level of initialisation routine

    • 0 = no output (default)
    • 1 = return solver state for each step in routine
    • 2 = return solver state for each step in subroutines
    • 3 = include solver output infomation (tee=True)
  • optarg – solver options dictionary object (default={‘tol’: 1e-6})
  • solver – str indicating which solver to use during initialization (default = ‘ipopt’)
Returns:

None

idaes.util package
Submodules
idaes.util.sphinxdoctest_plugin module

This module implements pytest plugin for Sphinx doc tests.

In a nutshell, it uses the pytest pytest_collect_file() plugin hook to recognize the Sphinx Makefile. Then it does a quick and dirty parse of that Makefile to extract the command Sphinx is using to run the doctests, which it recognizes by being the first command in the Makefile target named by SPHINX_DOCTEST_TARGET. The parser is able to handle simple Makefile variable expansion, though not currently nested variables so don’t do that.

The mechanics of the pytest plugin mechanism are such that the Makefile is wrapped with a subclass of pytest.File, SphinxMakefile, which implements the collect method to yield a subclass of pytest.Item called SphinxItem, that in turn implements a few methods to run the test and report the result. The bulk of the code in running the test is parsing the output to look for errors, and thus decide whether all the doctests passed, or not.

The drawback of this whole setup is of course some extra complexity. The advantage is that (a) whatever the Makefile does is what this plugin should do, for running the command, as long as the command is the first (and only significant) thing that occurs in the target, and (b) if there ends up being more than one Makefile, it should all continue to work.

exception idaes.util.sphinxdoctest_plugin.SphinxCommandFailed[source]
class idaes.util.sphinxdoctest_plugin.SphinxDoctestFailure(name, parent, details)[source]
class idaes.util.sphinxdoctest_plugin.SphinxDoctestItem(name, parent, wd, cmd)[source]
repr_failure(excinfo)[source]

This is called when self.runtest() raises an exception.

runtest()[source]

Run the Sphinx doctest.

class idaes.util.sphinxdoctest_plugin.SphinxDoctestSuccess(name, parent=None, config=None, session=None, nodeid=None)[source]
exception idaes.util.sphinxdoctest_plugin.SphinxHadErrors[source]
class idaes.util.sphinxdoctest_plugin.SphinxMakefile(fspath, parent=None, config=None, session=None, nodeid=None)[source]
collect()[source]

returns a list of children (items and collectors) for this collection node.

warnings_file

Get warnings and errors output file, if any, from the Sphinx Makefile.

class idaes.util.sphinxdoctest_plugin.SphinxWarnings(fspath, parent=None, config=None, session=None, nodeid=None)[source]
collect()[source]

returns a list of children (items and collectors) for this collection node.

class idaes.util.sphinxdoctest_plugin.SphinxWarningsItem(name, parent, path: pathlib.Path)[source]
repr_failure(excinfo)[source]

This is called when self.runtest() raises an exception.

idaes.vis package

The idaes.vis subpackage contains the framework and implementation of plots that are expected to be of general utility within the IDAES framework.

For users, an entry point is provided for IDAES classes to produce plots with the idaes.vis.plotbase.PlotRegistry singleton.

Plots will inherit from the interface in idaes.vis.plotbase.PlotBase, which provides some basic methods.

The current implementations all use the Python “bokeh” package, and can be found in idaes.vis.bokeh_plots.

For more details, please refer to the visualization section of the main IDAES documentation.

Submodules
idaes.vis.bokeh_plots module

Bokeh plots.

class idaes.vis.bokeh_plots.BokehPlot(current_plot=None)[source]
annotate(x, y, label)[source]

Annotate a plot with a given point and a label.

Parameters:
  • x – Value of independent variable.
  • y – Value of dependent variable.
  • label – Text label.
Returns:

None

Raises:

None

resize(height=-1, width=-1)[source]

Resize a plot’s height and width.

Parameters:
  • height – Height in screen units.
  • width – Width in screen units.
Returns:

None

Raises:

None

save(destination)[source]

Save the current plot object to HTML in filepath provided by destination.

Parameters:destination – Valid file path to save HTML to.
Returns:filename where HTML is saved.
Raises:None
show(in_notebook=True)[source]

Display plot in a Jupyter notebook.

Parameters:
  • self – Plot object.
  • in_notebook – Display in Jupyter notebook or generate HTML file.
Returns:

None

Raises:

None

class idaes.vis.bokeh_plots.HeatExchangerNetwork(exchangers, stream_list, mark_temperatures_with_tooltips=False, mark_modules_with_tooltips=False, stage_width=2, y_stream_step=1)[source]
class idaes.vis.bokeh_plots.ProfilePlot(data_frame, x='', y=None, title='', xlab='', ylab='', y_axis_type='auto', legend=None)[source]
idaes.vis.plotbase module

Base classes for visualization and plotting in IDAES.

Create new plots by inheriting from PlotBase. See the idaes.vis.bokeh_plots module for examples.

class idaes.vis.plotbase.PlotBase(current_plot)[source]

Abstract base class for a plot.

annotate(x, y, label: str)[source]

Annotate a plot with a given point and a label.

Parameters:
  • x – Value of independent variable.
  • y – Value of dependent variable.
  • label – Text label.
resize(height: int = -1, width: int = -1)[source]

Resize a plot’s height and width.

Parameters:
  • height – Height in screen units.
  • width – Width in screen units.
Returns:

None

Raises:

None

save(destination: str)[source]

Save the current plot object to HTML in filepath provided by destination.

Parameters:destination – Valid file path to save HTML to.
Returns:filename where HTML is saved.
Raises:None
show(in_notebook=True)[source]

Display plot in a Jupyter notebook.

Parameters:in_notebook – Display in Jupyter notebook or generate HTML file.
Returns:None
Raises:None
classmethod validate(data_frame: pandas.core.frame.DataFrame, x: str, y: List[T], legend=None)[source]

Validate that the plot parameters are valid.

Parameters:
  • data_frame – a pandas data frame of any type.
  • x – Key in data-frame to use as x-axis.
  • y – Keys in data-frame to use as y-axis.
  • legend – List of labels to use as legend for a plot.
Returns:

True, ‘’ on valid data frames (if x and y are in the data frame keys) False, “message” on invalid data

class idaes.vis.plotbase.PlotRegistry[source]

Set of associations between objects/classes + a plot name, and the parameters and values needed to perform the plot.

The basic idea is to create a set of named plots associated with a given IDAES class, and then allow the user or other APIs to invoke that plot once the data is populated in an instance of the class. This keeps the details of how to create plots of a given type in the classes that will create them.

For example:

class MyIdaesClass(ProcessBase):
  # .. code for the class
  def plot_setup(self, plot_class):
      # .. details of creating plot_instance from object contents ..
      return plot_instance
PlotRegistry().register(MyIdaesClass, 'basic', MyIdaesClass.plot_setup)

# .. and, later ..
obj = MyIdaesClass(...)
# .. do things that fill "obj" with data ..
# now create the plot
plot = PlotRegistry().get(obj, 'basic')
plot.show()

XXX: This class is not actually used (yet) by any of the IDAES models.

get(obj, name: str)[source]

Get a plot object for the given object + name.

Parameters:
  • obj – Object for which to get the plot
  • name – Registered name of plot to get
Returns:

Return value of setup function given to register(), or, if that is empty, the retrieved plot object.

register(obj, name: str, plot: Type[CT_co], setup_fn=None, overwrite: bool = False)[source]

Register an object/plot combination.

Parameters:
  • obj – Class or instance
  • name – Name for this association
  • plot – Plot class
  • setup_fn – Optional setup function to call. Function should take two arguments: plot class instance, obj assoc. with plot.
  • overwrite – If true, allow overwrite of existing entry in the registry
remove_all()[source]

Remove all entries from the registry.

Since the registry is a singleton, this removes all entries from ALL instances. Use with care.

idaes.vis.plotutils module
class idaes.vis.plotutils.HENStreamType[source]

Enum type defining hot and cold streams

idaes.vis.plotutils.add_exchanger_labels(plot, x, y_start, y_end, label_font_size, exchanger, module_marker_line_color, module_marker_fill_color, mark_modules_with_tooltips)[source]

Plot exchanger labels for an exchanger (for Q and A) on a heat exchanger network diagram and add module markers (if needed).

Parameters:
  • plot – bokeh.plotting.plotting.figure instance.
  • label_font_size – font-size for labels.
  • x – x-axis coordinate of exchanger (exchangers are vertical lines so we just need 1 x-value)
  • y_start – y-axis coordinate of exchanger start.
  • y_end – y-axis coordinate of exchanger end.
  • exchanger

    exchanger dictionary of the form:

    {'hot': 'H2', 'cold': 'C1', 'Q': 1400, 'A': 159, 'annual_cost': 28358,
     'stg': 2}
    
  • module_marker_line_color – color of border of the module marker.
  • module_marker_fill_color – color inside the module marker.
  • mark_modules_with_tooltips – whether to add tooltips to plot or not (currently not utilized).
Returns:

modified bokeh.plotting.plotting.figure instance with labels added.

Raises:

None

idaes.vis.plotutils.add_module_markers_to_heat_exchanger_plot(plot, x, y, modules, line_color, fill_color, mark_modules_with_tooltips)[source]

Plot module markers as tooltips to a heat exchanger network diagram.

Parameters:
  • plot – bokeh.plotting.plotting.figure instance.
  • x – x-axis coordinate of module marker tooltip.
  • y – y-axis coordinate of module marker tooltip.
  • modules – dict containing modules.
  • line_color – color of border of the module marker.
  • fill_color – color inside the module marker.
  • mark_modules_with_tooltips – whether to add tooltips to plot or not (currently not utilized).
Returns:

bokeh.plotting.plotting.figure instance with module markers added.

Raises:

None

idaes.vis.plotutils.get_color_dictionary(set_to_color)[source]

Given a set, return a dictionary of the form:

{'set_member': valid_bokeh_color}
Args:
set_to_color: set of unique elements, e.g: [1,2,3] or [“1”, “2”, “3”]
Returns:

Dictionary of the form:

{'set_member': valid_bokeh_color}
Raises:
None
idaes.vis.plotutils.get_stream_y_values(exchangers, hot_streams, cold_streams, y_stream_step=1)[source]

Return a dict containing the layout of the heat exchanger diagram including any stage splits.

Parameters:
  • exchangers

    List of exchangers where each exchanger is a dict of the form:

    {'hot': 'H2', 'cold': 'C1', 'Q': 1400, 'A': 159, 'annual_cost': 28358,
    'stg': 2}
    

    where hot is the hot stream name, cold is the cold stream name, A is the area (in m^2), annual_cost is the annual cost in $, Q is the amount of heat transferred from one stream to another in a given exchanger and stg is the stage the exchanger belongs to. Additionally a ‘utility_type’ can specify if we draw the cold stream as water (idaes.vis.plot_utils.HENStreamType.cold_utility) or the hot stream as steam (idaes.vis.plot_utils.HENStreamType.hot_utility).

    Additionally, the exchanger could have the key ‘modules’, like this:

    {'hot': 'H1', 'cold': 'C1', 'Q': 667, 'A': 50, 'annual_cost': 10979, 'stg': 3,
    'modules': {10: 1, 20: 2}}
    
  • hot_streams

    List of dicts representing hot streams where each item is a dict of the form:

    {'name':'H1', 'temps': [443, 435, 355, 333], 'type': HENStreamType.hot}
    
  • cold_streams

    List of dicts representing cold streams where each item is a dict of the form:

    {'name':'H1', 'temps': [443, 435, 355, 333], 'type': HENStreamType.hot}
    
  • y_stream_step – how many units on the HEN diagram to leave between each stream (or sub-stream) and the one above it. Defaults to 1.
Returns:

* stream_y_values_dict : a dict of each stream name as key and value being a dict of the form

{'default_y_value': 2, 'split_y_values': [1,3]}.

This indicates what the default y value of this stream will be on the diagram and what values we’ll use when it splits.

* hot_split_streams : list of tuples of the form (a,b) where a is a hot stream name and b is the max. times it will split over all the stages.

* cold_split_streams : list of tuples of the form (a,b) where a is a cold stream name and b is the max. times it will split over all the stages.

Return type:

Tuple containing 3 dictionaries to be used when plotting the HEN

Raises:

None

idaes.vis.plotutils.is_hot_or_cold_utility(exchanger)[source]

Return if an exchanger is a hot or a cold utility by checking if it has the key utility_type.

Parameters:exchanger – dict representing the exchanger.
Returns:True if utility_type in the exchanger dict passed.
Raises:None
idaes.vis.plotutils.plot_line_segment(plot, x_start, x_end, y_start, y_end, color='white', legend=None)[source]

Plot a line segment on a bokeh figure.

Parameters:
  • plot – bokeh.plotting.plotting.figure instance.
  • x_start – x-axis coordinate of 1st point in line.
  • x_end – x-axis coordinate of 2nd point in line.
  • y_start – y-axis coordinate of 1st point in line.
  • y_end – y-axis coordinate of 2nd point in line.
  • color – color of line (defaults to white).
  • legend – what legend to associate with (defaults to None).
Returns:

modified bokeh.plotting.plotting.figure instance with line added.

Raises:

None

idaes.vis.plotutils.plot_stream_arrow(plot, line_color, stream_arrow_temp, temp_label_font_size, x_start, x_end, y_start, y_end, stream_name=None)[source]

Plot a stream arrow for the heat exchanger network diagram.

Parameters:
  • plot – bokeh.plotting.plotting.figure instance.
  • line_color – color of arrow (defaults to white).
  • stream_arrow_temp – Tempreature of the stream to be plotted.
  • temp_label_font_size – font-size of the temperature label to be added.
  • x_start – x-axis coordinate of arrow base.
  • x_end – x-axis coordinate of arrow head.
  • y_start – y-axis coordinate of arrow base.
  • y_end – y-axis coordinate of arrow head.
  • stream_name – Name of the stream to add as a label to arrow (defaults to None).
Returns:

modified bokeh.plotting.plotting.figure instance with stream arrow added.

Raises:

None

idaes.vis.plotutils.turn_off_grid_and_axes_ticks(plot)[source]

Turn off axis ticks and grid lines on a bokeh figure object.

Parameters:plot – bokeh.plotting.plotting.figure instance.
Returns:modified bokeh.plotting.plotting.figure instance.
Raises:None
Submodules
idaes.ver module

The API in this module is mostly for internal use, e.g. from ‘setup.py’ to get the version of the package. But Version has been written to be usable as a general versioning interface.

Example of using the class directly:

>>> from idaes.ver import Version
>>> my_version = Version(1, 2, 3)
>>> print(my_version)
1.2.3
>>> tuple(my_version)
(1, 2, 3)
>>> my_version = Version(1, 2, 3, 'alpha')
>>> print(my_version)
1.2.3a
>>> tuple(my_version)
(1, 2, 3, 'alpha')
>>> my_version = Version(1, 2, 3, 'candidate', 1)
>>> print(my_version)
1.2.3rc1
>>> tuple(my_version)
(1, 2, 3, 'candidate', 1)

If you want to add a version to a class, e.g. a model, then simply inherit from HasVersion and initialize it with the same arguments you would give the Version constructor:

>>> from idaes.ver import HasVersion
>>> class MyClass(HasVersion):
...     def __init__(self):
...         super(MyClass, self).__init__(1, 2, 3, 'alpha')
...
>>> obj = MyClass()
>>> print(obj.version)
1.2.3a
class idaes.ver.HasVersion(*args)[source]

Interface for a versioned class.

class idaes.ver.Version(major, minor, micro, releaselevel='final', serial=None)[source]

This class attempts to be compliant with a subset of PEP 440.

Note: If you actually happen to read the PEP, you will notice that pre- and post- releases, as well as “release epochs”, are not supported.

idaes.ver.package_version = <idaes.ver.Version object>

Package’s version as an object

Glossary

API
Acronym for “Application Programming Interface”, this is the set of functions used by an external program to invoke the functionality of a library or application. For IDAES, it usually refers to Python functions and classes/methods in a Python module. By analogy, the APIs are to the IDAES library what a steering wheel, gearshift and pedals are to a car.
CRADA
Cooperative Research and Development Agreement. A legal agreement between two or more parties that involves a statement of work and terms for sharing non-public data.
NDA
Non-Disclosure Agreement. A legal agreement between two or more parties that involves terms for sharing non-public data.

License

Institute for the Design of Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE Framework) Copyright (c) 2019, 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.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of the Institute for the Design of Advanced Energy Systems (IDAES), University of California, Lawrence Berkeley National Laboratory, National Technology & Engineering Solutions of Sandia, LLC, Sandia National Laboratories, Carnegie Mellon University, West Virginia University Research Corporation, U.S. Dept. of Energy, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

You are under no obligation whatsoever to provide any bug fixes, patches, or upgrades to the features, functionality or performance of the source code (“Enhancements”) to anyone; however, if you choose to make your Enhancements available either publicly, or directly to Lawrence Berkeley National Laboratory, without imposing a separate written license agreement for such Enhancements, then you hereby grant Lawrence Berkeley National Laboratory the following license: a non-exclusive, royalty-free perpetual license to install, use, modify, prepare derivative works, incorporate into other computer software, distribute, and sublicense such enhancements or derivative works thereof, in binary and source code form.

Indices and tables