##############################################################################
# Institute for the Design of Advanced Energy Systems Process Systems
# Engineering Framework (IDAES PSE Framework) Copyright (c) 2018, by the
# software owners: The Regents of the University of California, through
# Lawrence Berkeley National Laboratory, National Technology & Engineering
# Solutions of Sandia, LLC, Carnegie Mellon University, West Virginia
# University Research Corporation, et al. All rights reserved.
#
# Please see the files COPYRIGHT.txt and LICENSE.txt for full copyright and
# license information, respectively. Both files are also available online
# at the URL "https://github.com/IDAES/idaes".
##############################################################################
"""
Standard IDAES feed block.
"""
from __future__ import division
# Import Python libraries
import logging
# Import Pyomo libraries
from pyomo.network import Port
from pyomo.common.config import ConfigValue, In
# Import IDAES cores
from idaes.core import UnitBlockData, declare_process_block_class, \
HoldupStatic, CONFIG_Base
from idaes.core.util.config import is_parameter_block, list_of_strings
__author__ = "Andrew Lee"
# Set up logger
logger = logging.getLogger('idaes.unit_model')
[docs]@declare_process_block_class("Feed")
class FeedData(UnitBlockData):
"""
Standard Feed Block Class
"""
CONFIG = CONFIG_Base()
# Set dynamic flag, as model is only steady-state
CONFIG.dynamic = False
CONFIG.get('dynamic')._default = False
CONFIG.get('dynamic')._domain = In([False])
# Set default values of inherited attributes
CONFIG.get('include_holdup')._default = False
CONFIG.get("material_balance_type")._default = 'component_phase'
CONFIG.get("energy_balance_type")._default = 'total'
CONFIG.get("momentum_balance_type")._default = 'total'
CONFIG.get("has_rate_reactions")._default = False
CONFIG.get("has_equilibrium_reactions")._default = False
CONFIG.get("has_phase_equilibrium")._default = False
CONFIG.get("has_mass_transfer")._default = False
CONFIG.get("has_heat_transfer")._default = False
CONFIG.get("has_work_transfer")._default = False
CONFIG.get("has_pressure_change")._default = False
# Add unit model attributes
CONFIG.declare("property_package", ConfigValue(
default=None,
domain=is_parameter_block,
description="Property package to use for holdup",
doc="""Property parameter object used to define property calculations
(default = 'use_parent_value')
- 'use_parent_value' - get package from parent (default = None)
- a ParameterBlock object"""))
CONFIG.declare("property_package_args", ConfigValue(
default={},
description="Arguments to use for constructing property packages",
doc="""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)"""))
CONFIG.declare("outlet_list", ConfigValue(
domain=list_of_strings,
description="List of outlet names",
doc="""A list containing names of outlets (default = None)
- None - default single outlet
- list - a list of names for outlets"""))
CONFIG.declare("num_outlets", ConfigValue(
domain=int,
description="Number of outlets to unit",
doc="""Argument indication number (int) of outlets to construct
(default = None). Not used if outlet_list arg is provided.
- None - use outlet_list arg instead
- int - Outlets will be named with sequential numbers from 1
to num_outlets"""))
[docs] def build(self):
"""
Begin building model (pre-DAE transformation).
Args:
None
Returns:
None
"""
# Call UnitModel.build to setup dynamics
super(FeedData, self).build()
# Build Holdup Block
self.holdup = HoldupStatic()
[docs] def post_transform_build(self):
"""
Continue model construction after DAE transformation.
Args:
None
Returns:
None
"""
# Make references to state variables
self._set_feed_references()
# Build Outlets
self.build_outlets(outlets=self.config.outlet_list,
num_outlets=self.config.num_outlets)
def _set_feed_references(self):
"""
Create references to feed state variables.
Args:
None
Returns:
None
"""
# Use a Pyomo Port to collect the feed state variables
def feed_rule(b, t):
return b.holdup.properties[t].declare_port_members()
f = Port(self.time,
rule=feed_rule,
doc="Feed object")
setattr(self, "feed", f)
[docs] def display(blk, display_block=False, ostream=None, prefix=""):
"""
Display the contents of Feed unit.
Args:
display_block : indicates whether to display the entire Block
object (default = False).
ostream : output stream (default = None)
prefix : str to append to each line of output (default = '')
Returns:
None
"""
if display_block:
blk.display()
else:
blk.feed.display()
[docs] def fix(blk, var, comp=None, value=None, time=None):
"""
Method for fixing Vars in Feed Block.
Args:
var : variable name to be fixed (as str)
comp : index of var to be fixed (if applicable, default = None)
value : value to use when fixing var (default = None)
time : list of time points at which to fix var (can be float, int
or list)
Returns:
None
"""
if isinstance(time, (int, float)):
time = [time]
if time is None:
if comp is None:
if value is None:
blk.feed[:].vars[var].fix()
else:
blk.feed[:].vars[var].fix(value)
else:
if value is None:
blk.feed[:].vars[var][comp].fix()
else:
blk.feed[:].vars[var][comp].fix(value)
else:
for t in time:
if comp is None:
if value is None:
blk.feed[t].vars[var].fix()
else:
blk.feed[t].vars[var].fix(value)
else:
if value is None:
blk.feed[t].vars[var][comp].fix()
else:
blk.feed[t].vars[var][comp].fix(value)
[docs] def unfix(blk, var, comp=None, time=None):
"""
Method for unfixing Vars in Feed Block.
Args:
var : variable name to be unfixed (as str)
comp : index of var to be unfixed (if applicable, default = None)
time : list of time points at which to unfix var (can be float, int
or list)
Returns:
None
"""
if isinstance(time, (int, float)):
time = [time]
if time is None:
if comp is None:
blk.feed[:].vars[var].unfix()
else:
blk.feed[:].vars[var][comp].unfix()
else:
for t in time:
if comp is None:
blk.feed[t].vars[var].unfix()
else:
blk.feed[t].vars[var][comp].unfix()