def build_phase_separator(): m = pyo.ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = iapws95.Iapws95ParameterBlock() m.fs.unit = HelmPhaseSeparator( default={'property_package': m.fs.properties}) return m
def build(self): """ Begin building model (pre-DAE transformation). Args: None Returns: None """ # Call UnitModel.build to setup dynamics super().build() # Build Control Volume 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_geometry() self.control_volume.add_state_blocks(has_phase_equilibrium=False) self.control_volume.add_material_balances( balance_type=self.config.material_balance_type,) self.control_volume.add_energy_balances( balance_type=self.config.energy_balance_type, has_heat_transfer=self.config.has_heat_transfer) self.control_volume.add_momentum_balances( balance_type=self.config.momentum_balance_type, has_pressure_change=True) self.flash = HelmPhaseSeparator( default={ "dynamic": False, "property_package": self.config.property_package, } ) self.mixer = Mixer( default={ "dynamic": False, "property_package": self.config.property_package, "inlet_list": ["FeedWater", "SaturatedWater"], "mixed_state_block": self.control_volume.properties_in, } ) # instead of creating a new block use control volume to return solution # Inlet Ports # FeedWater to Drum (from Pipe or Economizer) self.feedwater_inlet = Port(extends=self.mixer.FeedWater) # Sat water from water wall self.water_steam_inlet = Port(extends=self.flash.inlet) # Exit Ports # Liquid to Downcomer # self.liquid_outlet = Port(extends=self.mixer.outlet) self.add_outlet_port('liquid_outlet', self.control_volume) # Steam to superheaters self.steam_outlet = Port(extends=self.flash.vap_outlet) # constraint to make pressures of two inlets of drum mixer the same @self.Constraint(self.flowsheet().config.time, doc="Mixter pressure identical") def mixer_pressure_eqn(b, t): return b.mixer.SaturatedWater.pressure[t]*1e-6 == \ b.mixer.FeedWater.pressure[t]*1e-6 self.stream_flash_out = Arc( source=self.flash.liq_outlet, destination=self.mixer.SaturatedWater ) # Pyomo arc connect flash liq_outlet with mixer SaturatedWater inlet pyo.TransformationFactory("network.expand_arcs").apply_to(self) # Add object references self.volume = pyo.Reference(self.control_volume.volume) # Set references to balance terms at unit level if (self.config.has_heat_transfer is True and self.config.energy_balance_type != EnergyBalanceType.none): self.heat_duty = pyo.Reference(self.control_volume.heat) if (self.config.has_pressure_change is True and self.config.momentum_balance_type != 'none'): self.deltaP = pyo.Reference(self.control_volume.deltaP) # Set Unit Geometry and Holdup Volume self._set_geometry() # Construct performance equations self._make_performance()