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 # ############################################################################
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()
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)
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[:])
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(
# 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})