Example #1
0
def test_get_model_logger(caplog):
    log = idaeslog.getModelLogger("My Model 1")
    assert isinstance(log, logging.LoggerAdapter)
    assert log.name == "idaes.model.My Model 1"
    caplog.set_level(idaeslog.INFO)
    log.info_low("Hello! from INFO_LOW")
    log.info("Hello! from INFO")
    log.info_high("Hello! from INFO_HIGH")
    for record in caplog.records:
        assert record.message in ["Hello! from INFO", "Hello! from INFO_LOW"]
    log = idaeslog.getModelLogger("idaes.My Model 2")
    assert log.name == "idaes.model.My Model 2"
    HeatExchanger,
    MomentumMixingType,  # Enum type for mixer pressure calculation selection
)
from idaes.core.util import copy_port_values as _set_port  # for model intialization
from idaes.core.util.model_statistics import degrees_of_freedom
from idaes.core.util.tables import create_stream_table_dataframe  # as Pandas DataFrame

# Callback used to construct heat exchangers with the Underwood approx. for LMTD
from idaes.generic_models.unit_models.heat_exchanger import delta_temperature_underwood_callback

# Pressure changer type (e.g. adiabatic, pump, isentropic...)
from idaes.generic_models.unit_models.pressure_changer import ThermodynamicAssumption
import idaes.logger as idaeslog
import idaes.core.util.scaling as iscale

_log = idaeslog.getModelLogger(__name__, logging.INFO)


def create_model():
    """Create the flowsheet and add unit models. Fixing model inputs is done
    in a separate function to try to keep this fairly clean and easy to follow.

    Args:
        None

    Returns:
        (ConcreteModel) Steam cycle model
    """
    ############################################################################
    #  Flowsheet and Properties                                                #
    ############################################################################
Example #3
0
    def build(self):
        """Build the model.

        Args:
            None
        Returns:
            None
        """
        # Setup model build logger
        model_log = idaeslog.getModelLogger(self.name, tag="unit")

        # Call UnitModel.build to setup dynamics
        super(TrayData, self).build()

        # Create the inlet list to build inlet state blocks
        if self.config.is_feed_tray:
            inlet_list = ["feed", "liq", "vap"]
        else:
            inlet_list = ["liq", "vap"]

        # Create a dict to set up the inlet state blocks
        state_block_args = dict(**self.config.property_package_args)
        state_block_args["has_phase_equilibrium"] = True
        state_block_args["defined_state"] = True

        for i in inlet_list:
            state_obj = self.config.property_package.build_state_block(
                self.flowsheet().time,
                doc="State block for " + i + "_inlet to tray",
                default=state_block_args)

            setattr(self, "properties_in_" + i, state_obj)

        # Create a dict to set up the mixed outlet state blocks
        mixed_block_args = dict(**self.config.property_package_args)
        mixed_block_args["has_phase_equilibrium"] = True
        mixed_block_args["defined_state"] = False

        self.properties_out = self.config.property_package.\
            build_state_block(self.flowsheet().time,
                              doc="State block for mixed outlet from tray",
                              default=mixed_block_args)

        self._add_material_balance()
        self._add_energy_balance()
        self._add_pressure_balance()

        # Get liquid and vapor phase objects from the property package
        # to be used below. Avoids repition.
        _liquid_list = []
        _vapor_list = []
        for p in self.config.property_package.phase_list:
            pobj = self.config.property_package.get_phase(p)
            if pobj.is_vapor_phase():
                _vapor_list.append(p)
            elif pobj.is_liquid_phase():
                _liquid_list.append(p)
            else:
                _liquid_list.append(p)
                model_log.warning(
                    "A non-liquid/non-vapor phase was detected but will "
                    "be treated as a liquid.")

        # Create a pyomo set for indexing purposes. This set is appended to
        # model otherwise results in an abstract set.
        self._liquid_set = Set(initialize=_liquid_list)
        self._vapor_set = Set(initialize=_vapor_list)

        self._add_ports()
Example #4
0
    def build(self):
        """Build the model.

        Args:
            None
        Returns:
            None
        """
        # Setup model build logger
        model_log = idaeslog.getModelLogger(self.name, tag="unit")

        # Call UnitModel.build to setup dynamics
        super(ReboilerData, self).build()

        # Add Control Volume for the Reboiler
        self.control_volume = ControlVolume0DBlock(
            default={
                "dynamic": self.config.dynamic,
                "has_holdup": self.config.has_holdup,
                "property_package": self.config.property_package,
                "property_package_args": self.config.property_package_args
            })

        self.control_volume.add_state_blocks(has_phase_equilibrium=True)

        self.control_volume.add_material_balances(
            balance_type=self.config.material_balance_type,
            has_phase_equilibrium=True)

        self.control_volume.add_energy_balances(
            balance_type=self.config.energy_balance_type,
            has_heat_transfer=True)

        self.control_volume.add_momentum_balances(
            balance_type=self.config.momentum_balance_type,
            has_pressure_change=self.config.has_pressure_change)

        # Get liquid and vapor phase objects from the property package
        # to be used below. Avoids repition.
        _liquid_list = []
        _vapor_list = []
        for p in self.config.property_package.phase_list:
            pobj = self.config.property_package.get_phase(p)
            if pobj.is_vapor_phase():
                _vapor_list.append(p)
            elif pobj.is_liquid_phase():
                _liquid_list.append(p)
            else:
                _liquid_list.append(p)
                model_log.warning(
                    "A non-liquid/non-vapor phase was detected but will "
                    "be treated as a liquid.")

        # Create a pyomo set for indexing purposes. This set is appended to
        # model otherwise results in an abstract set.
        self._liquid_set = Set(initialize=_liquid_list)
        self._vapor_set = Set(initialize=_vapor_list)

        if self.config.has_boilup_ratio is True:

            self.boilup_ratio = Var(initialize=0.5,
                                    doc="boilup ratio for reboiler")

            def rule_boilup_ratio(self, t):
                if hasattr(self.control_volume.properties_out[t],
                           "flow_mol_phase"):
                    return self.boilup_ratio * \
                        sum(self.control_volume.properties_out[t].
                            flow_mol_phase[p] for p in self._liquid_set) == \
                        sum(self.control_volume.
                            properties_out[t].flow_mol_phase["Vap"]
                            for p in self._vapor_set)
                elif hasattr(self.control_volume.properties_out[t],
                             "flow_mol_phase_comp"):
                    return self.boilup_ratio * \
                        sum(self.control_volume.properties_out[t].
                            flow_mol_phase_comp[p, i]
                            for p in self._liquid_set
                            for i in self.control_volume.properties_out[t].
                            params.component_list) == \
                        sum(self.control_volume.properties_out[t].
                            flow_mol_phase_comp[p, i]
                            for p in self._vapor_set
                            for i in self.control_volume.properties_out[t].
                            params.component_list)
                else:
                    raise PropertyNotSupportedError(
                        "Unrecognized names for flow variables encountered "
                        "while building the constraint for reboiler.")

            self.eq_boilup_ratio = Constraint(self.flowsheet().time,
                                              rule=rule_boilup_ratio)

        self._make_ports()

        self._make_splits_reboiler()

        # Add object reference to variables of the control volume
        # Reference to the heat duty
        add_object_reference(self, "heat_duty", self.control_volume.heat)
        # Reference to the pressure drop (if set to True)
        if self.config.has_pressure_change:
            add_object_reference(self, "deltaP", self.control_volume.deltaP)
Example #5
0
    def build(self):
        """Build the model.

        Args:
            None
        Returns:
            None
        """
        # Setup model build logger
        model_log = idaeslog.getModelLogger(self.name, tag="unit")

        # Call UnitModel.build to setup dynamics
        super(CondenserData, self).build()

        # Check config arguments
        if self.config.temperature_spec is None:
            raise ConfigurationError("temperature_spec config argument "
                                     "has not been specified. Please select "
                                     "a valid option.")
        if (self.config.condenser_type == CondenserType.partialCondenser) and \
                (self.config.temperature_spec ==
                 TemperatureSpec.atBubblePoint):
            raise ConfigurationError("condenser_type set to partial but "
                                     "temperature_spec set to atBubblePoint. "
                                     "Select customTemperature and specify "
                                     "outlet temperature.")

        # Add Control Volume for the condenser
        self.control_volume = ControlVolume0DBlock(
            default={
                "dynamic": self.config.dynamic,
                "has_holdup": self.config.has_holdup,
                "property_package": self.config.property_package,
                "property_package_args": self.config.property_package_args
            })

        self.control_volume.add_state_blocks(has_phase_equilibrium=True)

        self.control_volume.add_material_balances(
            balance_type=self.config.material_balance_type,
            has_phase_equilibrium=True)

        self.control_volume.add_energy_balances(
            balance_type=self.config.energy_balance_type,
            has_heat_transfer=True)

        self.control_volume.add_momentum_balances(
            balance_type=self.config.momentum_balance_type,
            has_pressure_change=self.config.has_pressure_change)

        # Get liquid and vapor phase objects from the property package
        # to be used below. Avoids repition.
        _liquid_list = []
        _vapor_list = []
        for p in self.config.property_package.phase_list:
            pobj = self.config.property_package.get_phase(p)
            if pobj.is_vapor_phase():
                _vapor_list.append(p)
            elif pobj.is_liquid_phase():
                _liquid_list.append(p)
            else:
                _liquid_list.append(p)
                model_log.warning(
                    "A non-liquid/non-vapor phase was detected but will "
                    "be treated as a liquid.")

        # Create a pyomo set for indexing purposes. This set is appended to
        # model otherwise results in an abstract set.
        self._liquid_set = Set(initialize=_liquid_list)
        self._vapor_set = Set(initialize=_vapor_list)

        self._make_ports()

        if self.config.condenser_type == CondenserType.totalCondenser:

            self._make_splits_total_condenser()

            if (self.config.temperature_spec == TemperatureSpec.atBubblePoint):
                # Option 1: if true, condition for total condenser
                # (T_cond = T_bubble)
                # Option 2: if this is false, then user has selected
                # custom temperature spec and needs to fix an outlet
                # temperature.
                def rule_total_cond(self, t):
                    return self.control_volume.properties_out[t].\
                        temperature == self.control_volume.properties_out[t].\
                        temperature_bubble

                self.eq_total_cond_spec = Constraint(self.flowsheet().time,
                                                     rule=rule_total_cond)

        else:
            self._make_splits_partial_condenser()

        # Add object reference to variables of the control volume
        # Reference to the heat duty
        self.heat_duty = Reference(self.control_volume.heat[:])

        # Reference to the pressure drop (if set to True)
        if self.config.has_pressure_change:
            self.deltaP = Reference(self.control_volume.deltaP[:])
Example #6
0
from idaes.unit_models import (  # basic IDAES unit models, and enum
    Mixer, HeatExchanger, PressureChanger,
    MomentumMixingType,  # Enum type for mixer pressure calculation selection
)
from idaes.core.util import copy_port_values as _set_port  # for model intialization
from idaes.core.util.model_statistics import degrees_of_freedom
from idaes.core.util.tables import create_stream_table_dataframe  # as Pandas DataFrame

# Callback used to construct heat exchangers with the Underwood approx. for LMTD
from idaes.unit_models.heat_exchanger import delta_temperature_underwood_callback

# Pressure changer type (e.g. adiabatic, pump, isentropic...)
from idaes.unit_models.pressure_changer import ThermodynamicAssumption
from idaes.logger import getModelLogger, getInitLogger, init_tee, condition

_log = getModelLogger(__name__, logging.INFO)


def import_steam_cycle():
    # build concrete model
    # import steam cycle model and initialize flowsheet
    import idaes.examples.power_generation.supercritical_steam_cycle as steam_cycle

    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--initialize_from_file",
        help="File from which to load initialized values. If specified, the "
        "initialization proceedure will be skipped.",
        default=None,
    )
    parser.add_argument(
Example #7
0
# Import Unit Model Modules
from idaes.generic_models.properties import iapws95

# Import IDAES standard unit model
import idaes.logger as idaeslog
from idaes.power_generation.unit_models.drum import Drum
from idaes.power_generation.unit_models.downcomer import Downcomer
from idaes.power_generation.unit_models.waterwall_section import \
    WaterwallSection
from idaes.power_generation.properties.flue_gas_ideal import \
    FlueGasParameterBlock

# import plotting libraries
import matplotlib.pyplot as plt

_log = idaeslog.getModelLogger(__name__)


def main(m=None):
    """ Create concrete model, make the flowsheet object, fix some variables,
    and solve the problem.
    if m concrete model already exists this function only builds the unit
    models, fixes the inputs, and initializes the units.
    This is useful to import subsections of a flowsheet
    (i.e. boiler subsystem + steam cycle) if concrete model already exists
    we assume m.fs flowsheet, m.fs.prop_water and m.fs.prop_gas also exist"""
    if m is None:
        # Create a Concrete Model as the top level object
        m = pyo.ConcreteModel()
        # Add a flowsheet object to the model
        m.fs = FlowsheetBlock(default={"dynamic": False})