def basic_model(cb=delta_temperature_lmtd_callback):
    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},
                "delta_temperature_callback": cb,
                "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.get_costing()
    m.fs.unit.initialize()
    return m
def test_heater_tpx_lg_total_2():
    """Test liquid/vapor form with T-P-x state vars and total mass balances. In
    this case you end up with all vapor at the end.
    """
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95.Iapws95ParameterBlock(
        default={
            "phase_presentation": iapws95.PhaseType.LG,
            "state_vars": iapws95.StateVars.TPX
        })
    m.fs.heater = Heater(
        default={
            "property_package": m.fs.properties,
            "material_balance_type": MaterialBalanceType.componentTotal
        })
    m.fs.heater.inlet.temperature.fix(326.1667075078748)
    m.fs.heater.inlet.vapor_frac.fix(0.0)
    m.fs.heater.inlet.flow_mol.fix(100)
    m.fs.heater.inlet.pressure.fix(101325)
    m.fs.heater.heat_duty[0].fix(100 * 50000)
    prop_in = m.fs.heater.control_volume.properties_in[0]
    prop_out = m.fs.heater.control_volume.properties_out[0]
    prop_out.temperature = 400
    prop_out.vapor_frac = 0.9
    m.fs.heater.initialize(outlvl=5)
    assert degrees_of_freedom(m) == 0
    solver.solve(m, tee=True)
    assert abs(value(prop_out.temperature) - 534.6889772922356) <= 2e-4
    assert abs(value(prop_in.phase_frac["Liq"]) - 1) <= 1e-2
    assert abs(value(prop_out.phase_frac["Liq"]) - 0) <= 1e-2
    assert abs(value(prop_in.phase_frac["Vap"]) - 0) <= 1e-2
    assert abs(value(prop_out.phase_frac["Vap"]) - 1) <= 1e-2
def test_heater_ph_lg_total():
    """Test liquid/vapor form with P-H state vars and total mass balances
    """
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95.Iapws95ParameterBlock(
        default={"phase_presentation": iapws95.PhaseType.LG})
    m.fs.heater = Heater(
        default={
            "property_package": m.fs.properties,
            "material_balance_type": MaterialBalanceType.componentTotal
        })
    m.fs.heater.inlet.enth_mol.fix(4000)
    m.fs.heater.inlet.flow_mol.fix(100)
    m.fs.heater.inlet.pressure.fix(101325)
    m.fs.heater.heat_duty[0].fix(100 * 20000)
    m.fs.heater.initialize()
    assert degrees_of_freedom(m) == 0
    solver.solve(m)
    prop_in = m.fs.heater.control_volume.properties_in[0]
    prop_out = m.fs.heater.control_volume.properties_out[0]
    assert value(prop_in.temperature) == pytest.approx(326.166707, rel=1e-5)
    assert value(prop_out.temperature) == pytest.approx(373.12429, rel=1e-5)
    assert value(prop_in.phase_frac["Liq"]) == pytest.approx(1, rel=1e-5)
    assert value(prop_out.phase_frac["Liq"]) == pytest.approx(0.5953219,
                                                              rel=1e-5)
    assert value(prop_in.phase_frac["Vap"]) == pytest.approx(0, abs=1e-5)
    assert value(prop_out.phase_frac["Vap"]) == pytest.approx(0.4046781,
                                                              rel=1e-4)
Beispiel #4
0
def build_turbine():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95.Iapws95ParameterBlock()
    m.fs.turb = TurbineInletStage(
        default={"property_package": m.fs.properties})
    return m
def test_heater_ph_l_phase():
    """Test liquid phase only form with P-H state vars and phase mass balances
    """
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95.Iapws95ParameterBlock(
        default={"phase_presentation": iapws95.PhaseType.L})
    m.fs.heater = Heater(
        default={
            "property_package": m.fs.properties,
            "material_balance_type": MaterialBalanceType.componentPhase
        })
    m.fs.heater.inlet.enth_mol.fix(3000)
    m.fs.heater.inlet.flow_mol.fix(100)
    m.fs.heater.inlet.pressure.fix(101325)
    m.fs.heater.heat_duty[0].fix(100 * 1000)
    m.fs.heater.initialize()
    assert degrees_of_freedom(m) == 0
    solver.solve(m)
    prop_in = m.fs.heater.control_volume.properties_in[0]
    prop_out = m.fs.heater.control_volume.properties_out[0]
    assert abs(value(prop_in.temperature) - 312.88896252921666) <= 1e-4
    assert abs(value(prop_out.temperature) - 326.166707507874) <= 1e-4
    assert abs(value(prop_in.phase_frac["Liq"]) - 1) <= 1e-6
    assert abs(value(prop_out.phase_frac["Liq"]) - 1) <= 1e-6
    assert abs(value(prop_in.phase_frac["Vap"]) - 0) <= 1e-6
    assert abs(value(prop_out.phase_frac["Vap"]) - 0) <= 1e-6
Beispiel #6
0
def model():
    m = pyo.ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.prop_water = iapws95.Iapws95ParameterBlock()
    n_waterwalls = 10
    m.fs.ww_zones = pyo.RangeSet(n_waterwalls)
    m.fs.Waterwalls = WaterwallSection(
        m.fs.ww_zones,
        default={
            "dynamic": False,
            "has_holdup": False,
            "property_package": m.fs.prop_water,
            "has_heat_transfer": True,
            "has_pressure_change": True,
        },
    )

    def arc_rule(b, i):
        return {
            "source": m.fs.Waterwalls[i].outlet,
            "destination": m.fs.Waterwalls[i + 1].inlet
        }

    m.arc = Arc(pyo.RangeSet(n_waterwalls - 1), rule=arc_rule)

    # Pyomo expands arcs writing constraints outlet unit 1 = inlet unit 2
    pyo.TransformationFactory("network.expand_arcs").apply_to(m)

    return m
Beispiel #7
0
def test_condenser_steady():
    m = pyo.ConcreteModel()
    m.fs = idaes.core.FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95.Iapws95ParameterBlock()
    m.fs.unit = HelmNtuCondenser(
        default={
            "dynamic": False,
            "shell": {
                "has_pressure_change": False,
                "property_package": m.fs.properties,
            },
            "tube": {
                "has_pressure_change": False,
                "property_package": m.fs.properties,
            },
        })

    m.fs.unit.shell_inlet.flow_mol.fix(100)
    m.fs.unit.shell_inlet.pressure[:] = 9000
    m.fs.unit.shell_inlet.enth_mol.fix(30000)

    m.fs.unit.tube_inlet.flow_mol.fix(1200)
    m.fs.unit.tube_inlet.pressure.fix(101325)
    m.fs.unit.tube_inlet.enth_mol.fix(1800)

    m.fs.unit.area.fix(1000)
    m.fs.unit.overall_heat_transfer_coefficient.fix(500)

    m.fs.unit.initialize(unfix='pressure')
    solver.solve(m)

    assert (pyo.value(m.fs.unit.shell_inlet.pressure[0]) == pytest.approx(
        14036.3360, rel=1e-2))
    def iapws_underwood(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
                },
                "delta_temperature_callback":
                delta_temperature_underwood_callback,
                "flow_pattern": HeatExchangerFlowPattern.countercurrent
            })

        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)

        return m
Beispiel #9
0
def create_model_steady_state(f=100, p=5e5, h=5e4):
    """ Create a steady state heater model.
    """
    m = pyo.ConcreteModel(name="Dynamic Heater Test")
    m.fs = FlowsheetBlock(default={"dynamic": False})
    # Create a property parameter block
    m.fs.prop_water = iapws95.Iapws95ParameterBlock(
        default={"phase_presentation": iapws95.PhaseType.MIX})
    m.fs.heater = Heater(
        default={
            "has_holdup": False,
            "has_pressure_change": True,
            "material_balance_type": MaterialBalanceType.componentTotal,
            "property_package": m.fs.prop_water
        })

    m.fs.heater.inlet.enth_mol.fix(50000)
    m.fs.heater.inlet.pressure.fix(5e5)
    m.fs.heater.inlet.flow_mol.fix(100)
    m.fs.heater.heat_duty.fix(0)
    m.fs.heater.deltaP.fix(0)

    m.fs.heater.initialize()

    solver = pyo.SolverFactory("ipopt")
    solver.options = {'tol': 1e-6, 'linear_solver': "ma27", 'max_iter': 25}
    return m, solver
Beispiel #10
0
def test_deprecated_delta_T_method(caplog):
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.prop_steam = iapws95.Iapws95ParameterBlock()
    m.fs.prop_fluegas = FlueGasParameterBlock()

    caplog.clear()
    m.fs.unit = BoilerHeatExchanger(
        default={
            "delta_temperature_callback": delta_temperature_lmtd_callback,
            "tube": {
                "property_package": m.fs.prop_steam
            },
            "shell": {
                "property_package": m.fs.prop_fluegas
            },
            "has_pressure_change": True,
            "has_holdup": True,
            "delta_T_method": HeatExchangerFlowPattern.countercurrent,
            "tube_arrangement": TubeArrangement.inLine,
            "side_1_water_phase": "Liq",
            "has_radiation": True,
        })
    n_warn = 0
    n_depreacted = 0
    for record in caplog.records:
        if record.levelno == idaeslog.WARNING:
            n_warn += 1
        if "deprecated" in record.msg:
            n_depreacted += 1
    assert n_warn == 1
    assert n_depreacted == 1
    assert m.fs.unit.config.flow_pattern == HeatExchangerFlowPattern.countercurrent
Beispiel #11
0
def build_turbine_for_run_test():
    m = pyo.ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95.Iapws95ParameterBlock()
    # roughly based on NETL baseline studies
    m.fs.turb = HelmTurbineMultistage(
        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
Beispiel #12
0
def tu(delta_temperature_callback=delta_temperature_underwood_tune_callback):
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.properties = PhysicalParameterTestBlock()
    m.fs.prop_steam = iapws95.Iapws95ParameterBlock()
    m.fs.prop_fluegas = FlueGasParameterBlock()

    m.fs.unit = BoilerHeatExchanger(
        default={
            "delta_temperature_callback": delta_temperature_callback,
            "tube": {
                "property_package": m.fs.prop_steam
            },
            "shell": {
                "property_package": m.fs.prop_fluegas
            },
            "has_pressure_change": True,
            "has_holdup": False,
            "flow_pattern": HeatExchangerFlowPattern.countercurrent,
            "tube_arrangement": TubeArrangement.inLine,
            "side_1_water_phase": "Liq",
            "has_radiation": True,
        })

    assert_units_consistent(m)
Beispiel #13
0
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 concrete_tube(self):
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.properties = iapws95.Iapws95ParameterBlock(
            default={"phase_presentation": iapws95.PhaseType.LG})

        m.fs.unit = ConcreteTubeSide(
            default={
                "property_package": m.fs.properties,
                "flow_type": HeatExchangerFlowPattern.cocurrent
            })

        m.fs.unit.d_tube_outer.fix(0.01167)
        m.fs.unit.d_tube_inner.fix(0.01167)
        m.fs.unit.tube_length.fix(4.85)
        m.fs.unit.tube_heat_transfer_coefficient.fix(500)

        m.fs.unit.tube_inlet.flow_mol[0].fix(1)  # mol/s
        m.fs.unit.tube_inlet.pressure[0].fix(101325)  # Pa
        m.fs.unit.tube_inlet.enth_mol[0].\
            fix(iapws95.htpx(300*pyunits.K, 101325*pyunits.Pa))  # K

        m.fs.unit.temperature_wall[0, :].fix(1000)

        return m
    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_turbine_dyn():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": True, "time_set": [0, 4]})
    m.fs.properties = iapws95.Iapws95ParameterBlock()
    m.fs.turb = HelmTurbineInletStage(
        default={"property_package": m.fs.properties})
    return m
Beispiel #17
0
def test_compressor():
    m = pyo.ConcreteModel()
    m.fs = idaes.core.FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95.Iapws95ParameterBlock()
    m.fs.unit1 = cmodels.Compressor(default={"property_package": m.fs.properties})
    m.fs.unit2 = hmodels.HelmIsentropicCompressor(default={"property_package": m.fs.properties})

    # set inputs
    Fin = 1000 # mol/s
    Tin = 500 # K
    Pin = 2222782.4 # Pa
    Pout = 2.7*Pin # Pa
    hin = pyo.value(iapws95.htpx(Tin*pyo.units.K, Pin*pyo.units.Pa)) # J/mol
    eff = 0.324

    m.fs.unit1.inlet.flow_mol[0].fix(Fin)
    m.fs.unit2.inlet.flow_mol[0].fix(Fin)
    m.fs.unit1.inlet.enth_mol[0].fix(hin)
    m.fs.unit2.inlet.enth_mol[0].fix(hin)
    m.fs.unit1.inlet.pressure[0].fix(Pin)
    m.fs.unit2.inlet.pressure[0].fix(Pin)
    m.fs.unit1.outlet.pressure[0].fix(Pout)
    m.fs.unit2.outlet.pressure[0].fix(Pout)
    m.fs.unit1.efficiency_isentropic.fix(eff)
    m.fs.unit2.efficiency_isentropic.fix(eff)
    m.fs.unit1.initialize()
    m.fs.unit2.initialize()

    assert pyo.value(m.fs.unit1.control_volume.properties_out[0].temperature) == \
        pytest.approx(
            pyo.value(m.fs.unit2.control_volume.properties_out[0].temperature),
            rel=1e-7
        )
    assert pyo.value(m.fs.unit1.control_volume.work[0]) == pytest.approx(
        pyo.value(m.fs.unit2.control_volume.work[0]), rel=1e-7)
Beispiel #18
0
 def model_transport(self):
     # This model is used to test transport properties
     model = ConcreteModel()
     model.prop_param = iapws95.Iapws95ParameterBlock()
     model.prop_in = iapws95.Iapws95StateBlock(
         default={"parameters": model.prop_param})
     return model
Beispiel #19
0
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 test_turbine(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": False
            })
        # set inputs
        m.fs.unit.inlet.flow_mol[0].fix(1000)  # mol/s
        Tin = 500  # K
        Pin = 1000000  # Pa
        Pout = 700000  # Pa
        hin = iapws95.htpx(Tin * units.K, Pin * units.Pa)
        m.fs.unit.inlet.enth_mol[0].fix(hin)
        m.fs.unit.inlet.pressure[0].fix(Pin)

        m.fs.unit.deltaP.fix(Pout - Pin)
        m.fs.unit.efficiency_isentropic.fix(0.9)

        m.fs.unit.initialize()

        m.fs.unit.get_costing()
        calculate_variable_from_constraint(m.fs.unit.costing.purchase_cost,
                                           m.fs.unit.costing.cp_cost_eq)
        assert degrees_of_freedom(m) == 0

        assert_units_consistent(m.fs.unit)

        solver.solve(m, tee=True)
        assert m.fs.unit.costing.purchase_cost.value ==\
            pytest.approx(213199, 1e-5)
def test_pump():
    m = pyo.ConcreteModel()
    m.fs = idaes.core.FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95.Iapws95ParameterBlock()
    m.fs.unit1 = cmodels.Pump(default={"property_package": m.fs.properties})
    m.fs.unit2 = hmodels.HelmPump(
        default={"property_package": m.fs.properties})
    # set inputs

    Fin = 1e4  # mol/s
    hin = 4000  # J/mol
    Pin = 101325  # Pa
    Pout = 2 * Pin  # Pa
    eff = 0.7
    m.fs.unit1.inlet.flow_mol[0].fix(Fin)
    m.fs.unit2.inlet.flow_mol[0].fix(Fin)
    m.fs.unit1.inlet.enth_mol[0].fix(hin)
    m.fs.unit2.inlet.enth_mol[0].fix(hin)
    m.fs.unit1.inlet.pressure[0].fix(Pin)
    m.fs.unit2.inlet.pressure[0].fix(Pin)
    m.fs.unit1.outlet.pressure[0].fix(Pout)
    m.fs.unit2.outlet.pressure[0].fix(Pout)
    m.fs.unit1.efficiency_pump.fix(eff)
    m.fs.unit2.efficiency_pump.fix(eff)
    m.fs.unit1.initialize()
    m.fs.unit2.initialize()

    assert pyo.value(m.fs.unit1.control_volume.work[0]) == pytest.approx(
        pyo.value(m.fs.unit2.control_volume.work[0]), rel=1e-7)
    assert pyo.value(m.fs.unit1.control_volume.properties_out[0].temperature) == \
        pytest.approx(
            pyo.value(m.fs.unit2.control_volume.properties_out[0].temperature),
            rel=1e-7
        )
    def test_pump(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.pump,
                "compressor": True
            })
        # set inputs
        m.fs.unit.inlet.flow_mol[0].fix(10000)
        m.fs.unit.inlet.enth_mol[0].fix(4000)
        m.fs.unit.inlet.pressure[0].fix(101325)
        m.fs.unit.deltaP.fix(50000)
        m.fs.unit.efficiency_pump.fix(0.9)
        iscale.calculate_scaling_factors(m)

        assert degrees_of_freedom(m) == 0

        m.fs.unit.get_costing(pump_type='centrifugal',
                              Mat_factor='nickel',
                              pump_motor_type_factor='enclosed')

        m.fs.unit.initialize()
        # check costing block initialization
        assert m.fs.unit.costing.purchase_cost.value == \
            pytest.approx(70115.019, abs=1e-2)

        assert_units_consistent(m.fs.unit)

        solver.solve(m, tee=True)
        assert m.fs.unit.costing.purchase_cost.value == \
            pytest.approx(70115.0, 1e-5)
def test_heater_ph_l_phase_two():
    """Test liquid phase only form with P-H state vars and phase mass balances
    where the result is a two phase mixture.  For the P-H vars if there are
    two phases, using the liquid only properties will case the phase fraction
    to report all liquid even though really it is not.  Only use this option
    if you are sure you do not have a vapor phase.
    """
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95.Iapws95ParameterBlock(
        default={"phase_presentation": iapws95.PhaseType.L})
    m.fs.heater = Heater(
        default={
            "property_package": m.fs.properties,
            "material_balance_type": MaterialBalanceType.componentPhase
        })
    m.fs.heater.inlet.enth_mol.fix(3000)
    m.fs.heater.inlet.flow_mol.fix(100)
    m.fs.heater.inlet.pressure.fix(101325)
    m.fs.heater.heat_duty[0].fix(100 * 1000)
    m.fs.heater.initialize()
    assert degrees_of_freedom(m) == 0
    solver.solve(m)
    prop_in = m.fs.heater.control_volume.properties_in[0]
    prop_out = m.fs.heater.control_volume.properties_out[0]
    assert abs(value(prop_in.temperature) - 312.88896252921666) <= 1e-4
    assert abs(value(prop_out.temperature) - 326.166707507874) <= 1e-4
    assert abs(value(prop_in.phase_frac["Liq"]) - 1) <= 1e-6
    assert abs(value(prop_out.phase_frac["Liq"]) - 1) <= 1e-6
    assert abs(value(prop_in.phase_frac["Vap"]) - 0) <= 1e-6
    assert abs(value(prop_out.phase_frac["Vap"]) - 0) <= 1e-6
    def test_compressor(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
            })
        # set inputs
        m.fs.unit.inlet.flow_mol[0].fix(10000)
        m.fs.unit.inlet.enth_mol[0].fix(4000)
        m.fs.unit.inlet.pressure[0].fix(101325)
        m.fs.unit.deltaP.fix(500000)
        m.fs.unit.efficiency_isentropic.fix(0.9)
        iscale.calculate_scaling_factors(m)

        assert degrees_of_freedom(m) == 0

        m.fs.unit.get_costing(mover_type="compressor")

        m.fs.unit.initialize()

        assert m.fs.unit.costing.purchase_cost.value == \
            pytest.approx(334598.679, abs=1e-3)

        assert_units_consistent(m.fs.unit)

        solver.solve(m, tee=True)
        assert m.fs.unit.costing.purchase_cost.value == \
            pytest.approx(334598.679, abs=1e-3)
def test_heater_tpx_g_phase():
    """Test vapor phase only form with T-P-x state vars and phase mass balances
    """
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95.Iapws95ParameterBlock(
        default={
            "phase_presentation": iapws95.PhaseType.G,
            "state_vars": iapws95.StateVars.TPX
        })
    m.fs.heater = Heater(
        default={
            "property_package": m.fs.properties,
            "material_balance_type": MaterialBalanceType.componentPhase
        })
    m.fs.heater.inlet.flow_mol.fix(100)
    m.fs.heater.inlet.temperature.fix(422.60419933276177)
    m.fs.heater.inlet.pressure.fix(101325)
    m.fs.heater.heat_duty[0].fix(100 * 10000)
    prop_in = m.fs.heater.control_volume.properties_in[0]
    prop_out = m.fs.heater.control_volume.properties_out[0]
    prop_out.temperature = 550
    prop_out.pressure = 101325
    prop_out.flow_mol = 100
    m.fs.heater.initialize(outlvl=5)
    assert degrees_of_freedom(m) == 0
    solver.solve(m)
    assert abs(value(prop_out.temperature) - 698.1604861702295) <= 1e-4
    assert abs(value(prop_in.phase_frac["Liq"]) - 0) <= 1e-6
    assert abs(value(prop_out.phase_frac["Liq"]) - 0) <= 1e-6
    assert abs(value(prop_in.phase_frac["Vap"]) - 1) <= 1e-6
    assert abs(value(prop_out.phase_frac["Vap"]) - 1) <= 1e-6
def test_config():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.properties = PhysicalParameterTestBlock()
    m.fs.prop_steam = iapws95.Iapws95ParameterBlock()
    m.fs.prop_fluegas = FlueGasParameterBlock()

    m.fs.unit = BoilerHeatExchanger(
        default={
            "side_1_property_package": m.fs.prop_steam,
            "side_2_property_package": m.fs.prop_fluegas,
            "has_pressure_change": True,
            "has_holdup": False,
            "delta_T_method": DeltaTMethod.counterCurrent,
            "tube_arrangement": TubeArrangement.inLine,
            "side_1_water_phase": "Liq",
            "has_radiation": True
        })

    # Check unit config arguments
    # There are 8 to 10 arguments since you can add a side 1 and 2 config by
    # side_1, side_2, or whatever the user named them
    assert len(m.fs.unit.config) >= 12 and len(m.fs.unit.config) <= 16

    assert not m.fs.unit.config.dynamic
    assert not m.fs.unit.config.has_holdup
    assert m.fs.unit.config.delta_T_method == \
        DeltaTMethod.counterCurrent
def test_heater_tpx_lg_phase():
    """Test liquid/vapor form with T-P-x state vars and phase mass balances.

    This again has the problem where the property package calculates a vapor
    fraction, but you have a mass balance for each phase.
    """
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95.Iapws95ParameterBlock(
        default={
            "phase_presentation": iapws95.PhaseType.LG,
            "state_vars": iapws95.StateVars.TPX
        })
    m.fs.heater = Heater(
        default={
            "property_package": m.fs.properties,
            "material_balance_type": MaterialBalanceType.componentPhase
        })
    m.fs.heater.inlet.temperature.fix(326.1667075078748)
    m.fs.heater.inlet.vapor_frac.fix(0.0)
    m.fs.heater.inlet.flow_mol.fix(100)
    m.fs.heater.inlet.pressure.fix(101325)
    m.fs.heater.heat_duty[0].fix(100 * 50000)

    assert degrees_of_freedom(m) == -1
Beispiel #28
0
def build_drum1D():
    # 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})
    # Add property packages to flowsheet library
    m.fs.prop_water = iapws95.Iapws95ParameterBlock()
    m.fs.unit = Drum1D(
        default={
            "property_package": m.fs.prop_water,
            "has_holdup": True,
            "has_heat_transfer": True,
            "has_pressure_change": True,
            "finite_elements": 4,
            "drum_inner_diameter": 1.2,
            "drum_thickness": 0.119
        })

    m.fs.unit.drum_length.fix(15.3256)
    m.fs.unit.level[:].fix(0.6)
    m.fs.unit.number_downcomer.fix(6)
    m.fs.unit.downcomer_diameter.fix(0.38)
    m.fs.unit.temperature_ambient[:].fix(298.15)
    m.fs.unit.insulation_thickness.fix(0.145)

    return m
Beispiel #29
0
 def valve_model(self):
     m = ConcreteModel()
     m.fs = FlowsheetBlock(default={"dynamic": False})
     m.fs.properties = iapws95.Iapws95ParameterBlock()
     m.fs.valve = Valve(
         default={
             "valve_function_callback": self.type,
             "property_package": m.fs.properties
         })
     fin = 900  # mol/s
     pin = 200000  # Pa
     pout = 100000  # Pa
     tin = 300  # K
     hin = iapws95.htpx(T=tin * units.K, P=pin * units.Pa)  # J/mol
     # Calculate the flow coefficient to give 1000 mol/s flow with given P
     if self.type == ValveFunctionType.linear:
         cv = 1000 / math.sqrt(pin - pout) / 0.5
     elif self.type == ValveFunctionType.quick_opening:
         cv = 1000 / math.sqrt(pin - pout) / math.sqrt(0.5)
     elif self.type == ValveFunctionType.equal_percentage:
         cv = 1000 / math.sqrt(pin - pout) / 100**(0.5 - 1)
     # set inlet
     m.fs.valve.inlet.enth_mol[0].fix(hin)
     m.fs.valve.inlet.flow_mol[0].fix(fin)
     m.fs.valve.inlet.flow_mol[0].unfix()
     m.fs.valve.inlet.pressure[0].fix(pin)
     m.fs.valve.outlet.pressure[0].fix(pout)
     m.fs.valve.Cv.fix(cv)
     m.fs.valve.valve_opening.fix(0.5)
     iscale.calculate_scaling_factors(m)
     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