def test_initialization_isothermal(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.props = pp.Iapws95ParameterBlock() m.fs.pc = PressureChanger( default={ "property_package": m.fs.props, "thermodynamic_assumption": ThermodynamicAssumption.isothermal }) m.fs.pc.deltaP.fix(-1e3) m.fs.pc.inlet.flow_mol.fix(27.5e3) m.fs.pc.inlet.enth_mol.fix(4000) m.fs.pc.inlet.pressure.fix(2e6) assert degrees_of_freedom(m) == 0 init_state = {"flow_mol": 27.5e3, "pressure": 2e6, "enth_mol": 4000} m.fs.pc.initialize(state_args=init_state, outlvl=5) assert (pytest.approx(27500.0, abs=1e-2) == m.fs.pc.outlet.flow_mol[0].value) assert (pytest.approx(3999.984582673592, abs=1e-2) == m.fs.pc.outlet.enth_mol[0].value) assert (pytest.approx(1999000.0, abs=1e-2) == m.fs.pc.outlet.pressure[0].value) solver.solve(m)
def test_initialization_isentropic(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.props = pp.Iapws95ParameterBlock() m.fs.pc = PressureChanger( default={ "property_package": m.fs.props, "thermodynamic_assumption": ThermodynamicAssumption.isentropic }) init_state = {"flow_mol": 27.5e3, "pressure": 2e6, "enth_mol": 4000} m.fs.pc.inlet.flow_mol.fix(27.5e3) m.fs.pc.inlet.enth_mol.fix(4000) m.fs.pc.inlet.pressure.fix(2e6) m.fs.pc.deltaP.fix(-1e3) m.fs.pc.efficiency_isentropic.fix(0.83) assert degrees_of_freedom(m) == 0 m.fs.pc.initialize(state_args=init_state, outlvl=5, optarg={'tol': 1e-6}) assert (pytest.approx(27.5e3, abs=1e-2) == m.fs.pc.outlet.flow_mol[0].value) assert (pytest.approx(3999.979732728688, abs=1e-2) == m.fs.pc.outlet.enth_mol[0].value) assert (pytest.approx(1999000.0, abs=1e-2) == m.fs.pc.outlet.pressure[0].value) solver.solve(m)
def test_cv(): model = ConcreteModel() model.prop_param = iapws95.Iapws95ParameterBlock() model.prop_in = iapws95.Iapws95StateBlock( default={"parameters": model.prop_param}) cond = read_data("prop.txt", col=7) phase = read_data("prop.txt", col=13) for i, c in enumerate(cond): if c[2] == "undefined": continue if (c[0] > 640 and c[0] < 680) and (c[1] > 2.1e7 and c[1] < 3.1e7): #near critical and non-analytic terms were omitted continue if phase[i][2] in ["liquid", "supercritical"]: p = "Liq" else: p = "Vap" model.prop_in.temperature.set_value(c[0]) model.prop_in.pressure = c[1] cv = value(model.prop_in.cv_mol_phase[p] / model.prop_in.mw / 1000) rho = value(model.prop_in.dens_mass_phase[p]) if rho > 250 and rho < 420 and c[0] < 700 and c[0] > 640: tol = 0.03 # steep part in sc region else: tol = 0.003 assert (abs(cv - c[2]) / c[2] < tol)
def build_turbine(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = iapws95.Iapws95ParameterBlock() m.fs.turb = TurbineOutletStage( default={"property_package": m.fs.properties}) return m
def build_turbine_for_run_test(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = iapws95.Iapws95ParameterBlock() # roughly based on NETL baseline studies m.fs.turb = TurbineMultistage( default={ "property_package": m.fs.properties, "num_hp": 7, "num_ip": 14, "num_lp": 11, "hp_split_locations": [4, 7], "ip_split_locations": [5, 14], "lp_split_locations": [4, 7, 9, 11], "hp_disconnect": [7], "ip_split_num_outlets": { 14: 3 } }) # Add reheater m.fs.reheat = Heater(default={"property_package": m.fs.properties}) m.fs.hp_to_reheat = Arc(source=m.fs.turb.hp_split[7].outlet_1, destination=m.fs.reheat.inlet) m.fs.reheat_to_ip = Arc(source=m.fs.reheat.outlet, destination=m.fs.turb.ip_stages[1].inlet) return m
def test_fwh_model(): model = pyo.ConcreteModel() model.fs = FlowsheetBlock(default={ "dynamic": False, "default_property_package": iapws95.Iapws95ParameterBlock()}) model.fs.properties = model.fs.config.default_property_package model.fs.fwh = FWH0D(default={ "has_desuperheat":True, "has_drain_cooling":True, "has_drain_mixer":True, "property_package":model.fs.properties}) model.fs.fwh.desuperheat.inlet_1.flow_mol.fix(100) model.fs.fwh.desuperheat.inlet_1.flow_mol.unfix() model.fs.fwh.desuperheat.inlet_1.pressure.fix(201325) model.fs.fwh.desuperheat.inlet_1.enth_mol.fix(60000) model.fs.fwh.drain_mix.drain.flow_mol.fix(1) model.fs.fwh.drain_mix.drain.pressure.fix(201325) model.fs.fwh.drain_mix.drain.enth_mol.fix(20000) model.fs.fwh.cooling.inlet_2.flow_mol.fix(400) model.fs.fwh.cooling.inlet_2.pressure.fix(101325) model.fs.fwh.cooling.inlet_2.enth_mol.fix(3000) model.fs.fwh.condense.area.fix(1000) model.fs.fwh.condense.overall_heat_transfer_coefficient.fix(100) model.fs.fwh.desuperheat.area.fix(1000) model.fs.fwh.desuperheat.overall_heat_transfer_coefficient.fix(10) model.fs.fwh.cooling.area.fix(1000) model.fs.fwh.cooling.overall_heat_transfer_coefficient.fix(10) model.fs.fwh.initialize(optarg={"max_iter":50}) assert(degrees_of_freedom(model) == 0) assert(abs(pyo.value(model.fs.fwh.desuperheat.inlet_1.flow_mol[0]) - 98.335) < 0.01)
def get_initialized_model(self): """ Returns an initialized model for the PressureChanger unit model convergence evaluation Returns ------- Pyomo model : returns a pyomo model of the PressureChanger unit """ m = pe.ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.props = pp.Iapws95ParameterBlock() m.fs.pc = PressureChanger( default={ "property_package": m.fs.props, "thermodynamic_assumption": 'isothermal' }) m.fs.pc.deltaP.fix(-1e3) m.fs.pc.inlet[:].flow_mol.fix(27.5e3) m.fs.pc.inlet[:].enth_mol.fix(4000) m.fs.pc.inlet[:].pressure.fix(2e6) init_state = {"flow_mol": 27.5e3, "pressure": 2e6, "enth_mol": 4000} m.fs.pc.initialize(state_args=init_state, outlvl=0) # Create a solver for initialization opt = self.get_solver() opt.solve(m) # return the initialized model return m
def build_heat_exchanger(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = iapws95.Iapws95ParameterBlock() m.fs.heat_exchanger = HeatExchanger(default={ "side_1":{"property_package": m.fs.properties}, "side_2":{"property_package": m.fs.properties}}) return m
def iapws(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = iapws95.Iapws95ParameterBlock() m.fs.unit = Heater(default={"property_package": m.fs.properties}) return m
def build_valve_liquid(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = iapws95.Iapws95ParameterBlock() m.fs.valve = SteamValve(default={ "property_package": m.fs.properties, "phase": "Liq" }) return m
def test_tau_sat(): model = ConcreteModel() model.prop_param = iapws95.Iapws95ParameterBlock() model.prop_in = iapws95.Iapws95StateBlock(default={"parameters":model.prop_param}) cond = read_data("sat_prop.txt", col=2) for c in cond: tau = value(model.prop_in.func_tau_sat(c[1]/1000.0)) T = 647.096/tau print("{}, {}, {}".format(c[1], c[0], T)) assert(abs(T-c[0]) < 0.1)
def test_build_pc(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.props = pp.Iapws95ParameterBlock() m.fs.pc = PressureChanger(default={"property_package": m.fs.props}) assert hasattr(m.fs.pc, "inlet") assert hasattr(m.fs.pc, "outlet") assert len(m.fs.pc.inlet.vars) == 3 assert len(m.fs.pc.outlet.vars) == 3
def iapws(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = iapws95.Iapws95ParameterBlock( default={"phase_presentation": iapws95.PhaseType.LG}) m.fs.unit = Feed(default={"property_package": m.fs.properties}) return m
def test_make_performance(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.props = pp.Iapws95ParameterBlock() m.fs.pc = PressureChanger(default={"property_package": m.fs.props}) assert hasattr(m.fs.pc, "work_mechanical") assert m.fs.pc.work_mechanical == m.fs.pc.control_volume.work assert hasattr(m.fs.pc, "deltaP") assert hasattr(m.fs.pc, "ratioP") assert hasattr(m.fs.pc, "ratioP_calculation")
def test_set_geometry_include_holdup_true(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.props = pp.Iapws95ParameterBlock() m.fs.pc = PressureChanger(default={ "property_package": m.fs.props, "has_holdup": True }) assert hasattr(m.fs.pc, "volume") assert hasattr(m.fs.pc.control_volume, "material_holdup")
def test_make_isothermal(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.props = pp.Iapws95ParameterBlock() m.fs.pc = PressureChanger( default={ "property_package": m.fs.props, "thermodynamic_assumption": ThermodynamicAssumption.isothermal }) assert hasattr(m.fs.pc, "isothermal")
def test_report_isentropic(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.props = pp.Iapws95ParameterBlock() m.fs.pc = PressureChanger( default={ "property_package": m.fs.props, "thermodynamic_assumption": ThermodynamicAssumption.isentropic }) m.fs.pc.report()
def test_liquid_enthalpy_sat(): model = ConcreteModel() model.prop_param = iapws95.Iapws95ParameterBlock() model.prop_in = iapws95.Iapws95StateBlock(default={"parameters":model.prop_param}) cond = read_data("sat_prop.txt", col=5) for c in cond: if c[0] > 645: # getting very close to ciritical point tol = 0.01 else: tol = 0.001 model.prop_in.pressure = c[1] enth = value(model.prop_in.enth_mol_sat_phase["Liq"]/model.prop_in.mw/1000.0) assert(abs((enth-c[2])/c[2]) < tol)
def iapws(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = iapws95.Iapws95ParameterBlock() m.fs.unit = Mixer( default={ "property_package": m.fs.properties, "material_balance_type": MaterialBalanceType.componentTotal, "momentum_mixing_type": MomentumMixingType.equality }) return m
def iapws(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = iapws95.Iapws95ParameterBlock() m.fs.unit = PressureChanger( default={ "property_package": m.fs.properties, "thermodynamic_assumption": ThermodynamicAssumption.isentropic, "compressor": True }) return m
def test_vapor_density_sat(): model = ConcreteModel() model.prop_param = iapws95.Iapws95ParameterBlock() model.prop_in = iapws95.Iapws95StateBlock(default={"parameters":model.prop_param}) cond = read_data("sat_prop.txt", col=14) for c in cond: if c[0] > 645: # getting very close to ciritical point tol = 0.01 else: tol = 0.001 model.prop_in.temperature.set_value(c[0]) model.prop_in.pressure = c[1] rho = value(model.prop_in.dens_mass_phase["Vap"]) assert(abs(rho-c[2])/c[2] < tol)
def iapws(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = iapws95.Iapws95ParameterBlock( default={"phase_presentation": iapws95.PhaseType.LG}) m.fs.unit = Flash( default={ "property_package": m.fs.properties, "ideal_separation": False, "energy_split_basis": EnergySplittingType.enthalpy_split }) return m
def test_make_pump(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.props = pp.Iapws95ParameterBlock() m.fs.pc = PressureChanger( default={ "property_package": m.fs.props, "thermodynamic_assumption": ThermodynamicAssumption.pump }) assert hasattr(m.fs.pc, "work_fluid") assert hasattr(m.fs.pc, "efficiency_pump") assert hasattr(m.fs.pc, "fluid_work_calculation") assert hasattr(m.fs.pc, "actual_work")
def test_enthalpy_vapor_as_function_of_p_and_tau(): model = ConcreteModel() model.prop_param = iapws95.Iapws95ParameterBlock() model.prop_in = iapws95.Iapws95StateBlock(default={"parameters":model.prop_param}) cond = read_data("prop.txt", col=5) phase = read_data("prop.txt", col=13) for i, c in enumerate(cond): if phase[i][2] in ["liquid", "supercritical"]: continue model.prop_in.temperature.set_value(c[0]) h = value(model.prop_in.func_hvpt(c[1]/1000, 647.096/c[0])) rho = value(model.prop_in.dens_mass_phase["Vap"]) if rho > 250 and rho < 420 and c[0] < 700 and c[0] > 640: tol = 0.03 # steep part in sc region else: tol = 0.003 assert(abs(h-c[2])/c[2] < tol)
def iapws(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = iapws95.Iapws95ParameterBlock() m.fs.unit = HeatExchanger( default={ "shell": { "property_package": m.fs.properties }, "tube": { "property_package": m.fs.properties }, "flow_pattern": HeatExchangerFlowPattern.countercurrent }) return m
def test_make_isentropic(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.props = pp.Iapws95ParameterBlock() m.fs.pc = PressureChanger( default={ "property_package": m.fs.props, "thermodynamic_assumption": ThermodynamicAssumption.isentropic }) assert hasattr(m.fs.pc, "efficiency_isentropic") assert hasattr(m.fs.pc, "work_isentropic") assert hasattr(m.fs.pc, "isentropic_pressure") assert hasattr(m.fs.pc, "isentropic_material") assert hasattr(m.fs.pc, "isentropic") assert hasattr(m.fs.pc, "isentropic_energy_balance") assert hasattr(m.fs.pc, "actual_work")
def main(): """ Make the flowsheet object, fix some variables, and solve the problem """ # Create a Concrete Model as the top level object m = ConcreteModel() # Add a flowsheet object to the model m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.prop_water = iapws95.Iapws95ParameterBlock() build_boiler(m.fs) TransformationFactory("network.expand_arcs").apply_to(m) # Create a solver solver = SolverFactory('ipopt') return (m, solver)
def test_costing(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = iapws95.Iapws95ParameterBlock() m.fs.unit = HeatExchanger( default={ "shell": { "property_package": m.fs.properties }, "tube": { "property_package": m.fs.properties }, "flow_pattern": HeatExchangerFlowPattern.countercurrent }) # Set inputs m.fs.unit.inlet_1.flow_mol[0].fix(100) m.fs.unit.inlet_1.enth_mol[0].fix(4000) m.fs.unit.inlet_1.pressure[0].fix(101325) m.fs.unit.inlet_2.flow_mol[0].fix(100) m.fs.unit.inlet_2.enth_mol[0].fix(3500) m.fs.unit.inlet_2.pressure[0].fix(101325) m.fs.unit.area.fix(1000) m.fs.unit.overall_heat_transfer_coefficient.fix(100) assert degrees_of_freedom(m) == 0 m.fs.unit.initialize() m.fs.unit.get_costing() calculate_variable_from_constraint(m.fs.unit.costing.base_cost, m.fs.unit.costing.base_cost_eq) calculate_variable_from_constraint(m.fs.unit.costing.purchase_cost, m.fs.unit.costing.cp_cost_eq) results = solver.solve(m) assert m.fs.unit.costing.purchase_cost.value == \ pytest.approx(52442.7363,1e-5)
def test_internal_energy(): model = ConcreteModel() model.prop_param = iapws95.Iapws95ParameterBlock() model.prop_in = iapws95.Iapws95StateBlock(default={"parameters":model.prop_param}) cond = read_data("prop.txt", col=4) phase = read_data("prop.txt", col=13) for i, c in enumerate(cond): if phase[i][2] in ["liquid", "supercritical"]: p = "Liq" else: p = "Vap" model.prop_in.temperature.set_value(c[0]) model.prop_in.pressure = c[1] u = value(model.prop_in.energy_internal_mol_phase[p]/model.prop_in.mw/1000) rho = value(model.prop_in.dens_mass_phase[p]) if rho > 250 and rho < 420 and c[0] < 700 and c[0] > 640: tol = 0.02 # steep part in sc region else: tol = 0.002 assert(abs(u-c[2])/c[2] < tol)
def test_density(): model = ConcreteModel() model.prop_param = iapws95.Iapws95ParameterBlock() model.prop_in = iapws95.Iapws95StateBlock(default={"parameters":model.prop_param}) cond = read_data("prop.txt", col=2) phase = read_data("prop.txt", col=13) for i, c in enumerate(cond): if phase[i][2] in ["liquid", "supercritical"]: p = "Liq" else: p = "Vap" model.prop_in.temperature.set_value(c[0]) model.prop_in.pressure = c[1] rho = value(model.prop_in.dens_mass_phase[p]) if rho > 250 and rho < 420 and c[0] < 700 and c[0] > 645: tol = 0.03 # steep part in sc region elif c[1] < 20: tol = 0.005 #very low pressure < 20 Pa else: tol = 0.001 assert(abs(rho-c[2])/c[2] < tol)