Pump¶
Tutorial: Pump Unit Model with IAPWS Property Package¶
Learning Outcomes¶
- Demonstrate use of the Pump unit model in IDAES
- Demonstrate different simulation options available
Problem Statement¶
In this example, we will pump a stream of water at atmospheric pressure to a pressure of 201325 Pa using a simple pump unit model. We will be using the IAPWS property package for the water properties. It is assumed that the pump operates at steady state.
The inlet specifications are as follows:
- Flow Rate = 100 mol/s
- Mole fraction (H2O) = 1
- Pressure = 101325 Pa
- Temperature = 298.15 K
We will simulate 2 different cases, depending on the operating specifications by the user:
Case 1:In this case, we will specify the pump efficiency and the pressure increase variable on the pump unit model.
- Pressure Increase = 100000 Pa
- Pump Efficiency = 0.8
Case 2: In this case, we will specify the pump efficiency but will specify the pressure of the outlet stream directly.
- Outlet Pressure = 201325 Pa
- Pump efficiency = 0.8
IDAES documentation reference for pump model: https://idaes-pse.readthedocs.io/en/stable/
Setting up the problem in IDAES¶
In the following cell, we will be importing the necessary components from Pyomo and IDAES.
# Import objects from pyomo package
from pyomo.environ import ConcreteModel, SolverFactory, value, units
# Import the main FlowsheetBlock from IDAES. The flowsheet block will contain the unit model
from idaes.core import FlowsheetBlock
# Import idaes logger to set output levels
import idaes.logger as idaeslog
# Create the ConcreteModel and the FlowsheetBlock, and attach the flowsheet block to it.
m = ConcreteModel()
m.fs = FlowsheetBlock(dynamic=False) # dynamic or ss flowsheet needs to be specified here
# Import the IAPWS property package to create a properties block for the flowsheet
from idaes.models.properties import iapws95
from idaes.models.properties.helmholtz.helmholtz import (
PhaseType
)
# Add properties parameter block to the flowsheet with specifications
m.fs.properties = iapws95.Iapws95ParameterBlock(phase_presentation=PhaseType.L)
Case 1: Fix pressure change and pump efficiency¶
Add Pump Unit Model¶
# Import pump unit model from the model library
from idaes.models.unit_models.pressure_changer import Pump
# Create an instance of the pump unit, attaching it to the flowsheet
# Specify that the property package to be used with the pump is the one we created earlier.
m.fs.pump_case_1 = Pump(property_package=m.fs.properties)
# Import the degrees_of_freedom function from the idaes.core.util.model_statistics package
# DOF = Number of Model Variables - Number of Model Constraints
from idaes.core.util.model_statistics import degrees_of_freedom
# Call the degrees_of_freedom function, get intitial DOF
DOF_initial = degrees_of_freedom(m)
print("The initial DOF is {0}".format(DOF_initial))
The initial DOF is 5
Fix Inlet Stream Conditions¶
# Fix the stream inlet conditions
m.fs.pump_case_1.inlet.flow_mol[0].fix(100) #mol/s
# Use the htpx method to obtain the molar enthalpy of inlet stream based on given conditions of temperature and pressure
m.fs.pump_case_1.inlet.enth_mol[0].fix(value(iapws95.htpx(T=298.15*units.K, P=101325*units.Pa))) #J/mol
m.fs.pump_case_1.inlet.pressure[0].fix(101325) #Pa
Fix Pressure Change and Pump Efficiency¶
# Fix pump conditions
m.fs.pump_case_1.deltaP.fix(100000)
m.fs.pump_case_1.efficiency_pump.fix(0.8)
# Call the degrees_of_freedom function, get final DOF
DOF_final = degrees_of_freedom(m)
print("The final DOF is {0}".format(DOF_final))
The final DOF is 0
Initialization¶
# Initialize the flowsheet, and set the logger level to INFO
m.fs.pump_case_1.initialize(outlvl=idaeslog.INFO)
2023-03-04 01:48:28 [INFO] idaes.init.fs.pump_case_1.control_volume: Initialization Complete 2023-03-04 01:48:28 [INFO] idaes.init.fs.pump_case_1: Initialization Complete: optimal - Optimal Solution Found
Solve Model¶
# Solve the simulation using ipopt
# Note: If the degrees of freedom = 0, we have a square problem
opt = SolverFactory('ipopt')
solve_status = opt.solve(m, tee=True)
Ipopt 3.13.2: ****************************************************************************** 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 version of Ipopt was compiled from source code available at https://github.com/IDAES/Ipopt as part of the Institute for the Design of Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse. This version of Ipopt was compiled using HSL, a collection of Fortran codes for large-scale scientific computation. All technical papers, sales and publicity material resulting from use of the HSL codes within IPOPT must contain the following acknowledgement: HSL, a collection of Fortran codes for large-scale scientific computation. See http://www.hsl.rl.ac.uk. ****************************************************************************** This is Ipopt version 3.13.2, running with linear solver ma27. Number of nonzeros in equality constraint Jacobian...: 14 Number of nonzeros in inequality constraint Jacobian.: 0 Number of nonzeros in Lagrangian Hessian.............: 6 Total number of variables............................: 6 variables with only lower bounds: 0 variables with lower and upper bounds: 2 variables with only upper bounds: 0 Total number of equality constraints.................: 6 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.89e-07 0.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0 1 0.0000000e+00 2.38e-08 5.16e-07 -1.0 9.86e-07 - 9.90e-01 1.00e+00h 1 Number of Iterations....: 1 (scaled) (unscaled) Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00 Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00 Constraint violation....: 1.2580136100548369e-09 2.3806933313608170e-08 Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00 Overall NLP error.......: 1.2580136100548369e-09 2.3806933313608170e-08 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.008 Total CPU secs in NLP function evaluations = 0.003 EXIT: Optimal Solution Found.
View Results¶
# Display a readable report
m.fs.pump_case_1.report()
==================================================================================== Unit : fs.pump_case_1 Time: 0.0 ------------------------------------------------------------------------------------ Unit Performance Variables: Key : Value : Units : Fixed : Bounds Efficiency : 0.80000 : dimensionless : True : (None, None) Mechanical Work : 225.85 : watt : False : (None, None) Pressure Change : 1.0000e+05 : pascal : True : (None, None) Pressure Ratio : 1.9869 : dimensionless : False : (None, None) ------------------------------------------------------------------------------------ Stream Table Units Inlet Outlet Molar Flow mole / second 100.00 100.00 Mass Flow kilogram / second 1.8015 1.8015 T kelvin 298.15 298.16 P pascal 1.0132e+05 2.0132e+05 Vapor Fraction dimensionless 0.0000 0.0000 Molar Enthalpy joule / mole 1890.2 1892.4 ====================================================================================
Case 2: Fix outlet pressure and pump efficiency¶
Add Pump Unit Model¶
# Create an instance of another pump unit, attaching it to the same flowsheet
# Specify that the property package to be used with the pump is the one we created earlier.
m.fs.pump_case_2 = Pump(property_package=m.fs.properties)
# Call the degrees_of_freedom function, get intitial DOF
DOF_initial = degrees_of_freedom(m.fs.pump_case_2)
print("The initial DOF is {0}".format(DOF_initial))
The initial DOF is 5
Fix Inlet Stream Conditions¶
# Fix the stream inlet conditions
m.fs.pump_case_2.inlet.flow_mol[0].fix(100) # mol/s
# Use the htpx method to obtain the molar enthalpy of inlet stream based on given conditions of temperature and pressure
m.fs.pump_case_2.inlet.enth_mol[0].fix(value(iapws95.htpx(T=298.15*units.K, P=101325*units.Pa))) # J/mol
m.fs.pump_case_2.inlet.pressure[0].fix(101325) # Pa
Fix Outlet Pressure & Pump Efficiency¶
# Fix outlet stream conditions
m.fs.pump_case_2.outlet.pressure[0].fix(201325)
# Fix pump efficiency
m.fs.pump_case_2.efficiency_pump.fix(0.8)
DOF_final = degrees_of_freedom(m.fs.pump_case_2)
print('The final degrees of freedom is: {0}'.format(DOF_final))
The final degrees of freedom is: 0
Initialization¶
# Initialize the flowsheet, and set the logger level to INFO
m.fs.pump_case_2.initialize(outlvl=idaeslog.INFO)
2023-03-04 01:48:28 [INFO] idaes.init.fs.pump_case_2.control_volume: Initialization Complete 2023-03-04 01:48:28 [INFO] idaes.init.fs.pump_case_2: Initialization Complete: optimal - Optimal Solution Found
Solve Model¶
# Solve the simulation using ipopt
# Note: If the degrees of freedom = 0, we have a square problem
opt = SolverFactory('ipopt')
solve_status = opt.solve(m.fs.pump_case_2, tee=True)
Ipopt 3.13.2: ****************************************************************************** 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 version of Ipopt was compiled from source code available at https://github.com/IDAES/Ipopt as part of the Institute for the Design of Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse. This version of Ipopt was compiled using HSL, a collection of Fortran codes for large-scale scientific computation. All technical papers, sales and publicity material resulting from use of the HSL codes within IPOPT must contain the following acknowledgement: HSL, a collection of Fortran codes for large-scale scientific computation. See http://www.hsl.rl.ac.uk. ****************************************************************************** This is Ipopt version 3.13.2, running with linear solver ma27. Number of nonzeros in equality constraint Jacobian...: 11 Number of nonzeros in inequality constraint Jacobian.: 0 Number of nonzeros in Lagrangian Hessian.............: 3 Total number of variables............................: 6 variables with only lower bounds: 0 variables with lower and upper bounds: 1 variables with only upper bounds: 0 Total number of equality constraints.................: 6 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.89e-07 0.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0 1 0.0000000e+00 2.38e-08 5.16e-07 -1.0 9.86e-07 - 9.90e-01 1.00e+00h 1 Number of Iterations....: 1 (scaled) (unscaled) Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00 Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00 Constraint violation....: 1.2580136100548369e-09 2.3806933313608170e-08 Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00 Overall NLP error.......: 1.2580136100548369e-09 2.3806933313608170e-08 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.007 Total CPU secs in NLP function evaluations = 0.003 EXIT: Optimal Solution Found.
View Results¶
# Display a readable report
m.fs.pump_case_2.report()
==================================================================================== Unit : fs.pump_case_2 Time: 0.0 ------------------------------------------------------------------------------------ Unit Performance Variables: Key : Value : Units : Fixed : Bounds Efficiency : 0.80000 : dimensionless : True : (None, None) Mechanical Work : 225.85 : watt : False : (None, None) Pressure Change : 1.0000e+05 : pascal : False : (None, None) Pressure Ratio : 1.9869 : dimensionless : False : (None, None) ------------------------------------------------------------------------------------ Stream Table Units Inlet Outlet Molar Flow mole / second 100.00 100.00 Mass Flow kilogram / second 1.8015 1.8015 T kelvin 298.15 298.16 P pascal 1.0132e+05 2.0132e+05 Vapor Fraction dimensionless 0.0000 0.0000 Molar Enthalpy joule / mole 1890.2 1892.4 ====================================================================================