def test_setInputs_outlet_state_block():

    # vapor-liquid (Wilson)
    m.fs1.state_block_Wilson_vl.flow_mol.fix(1)
    m.fs1.state_block_Wilson_vl.temperature.fix(368)
    m.fs1.state_block_Wilson_vl.pressure.fix(101325)
    m.fs1.state_block_Wilson_vl.mole_frac["benzene"].fix(0.5)

    assert degrees_of_freedom(m.fs1.state_block_Wilson_vl) == 4

    # liquid only (Wilson)
    m.fs1.state_block_Wilson_l.flow_mol.fix(1)
    m.fs1.state_block_Wilson_l.temperature.fix(368)
    m.fs1.state_block_Wilson_l.pressure.fix(101325)
    m.fs1.state_block_Wilson_l.mole_frac["benzene"].fix(0.5)

    assert degrees_of_freedom(m.fs1.state_block_Wilson_l) == 0

    # vapour only (Wilson)
    m.fs1.state_block_Wilson_v.flow_mol.fix(1)
    m.fs1.state_block_Wilson_v.temperature.fix(368)
    m.fs1.state_block_Wilson_v.pressure.fix(101325)
    m.fs1.state_block_Wilson_v.mole_frac["benzene"].fix(0.5)

    assert degrees_of_freedom(m.fs1.state_block_Wilson_v) == 0
def test_setInputs_inlet_state_block():

    # vapor-liquid (Wilson)
    m.fs.state_block_Wilson_vl.flow_mol.fix(1)
    m.fs.state_block_Wilson_vl.temperature.fix(368)
    m.fs.state_block_Wilson_vl.pressure.fix(101325)
    m.fs.state_block_Wilson_vl.mole_frac["benzene"].fix(0.5)
    m.fs.state_block_Wilson_vl.mole_frac["toluene"].fix(0.5)

    assert degrees_of_freedom(m.fs.state_block_Wilson_vl) == 4

    # Fix Wilson specific variables
    m.fs.state_block_Wilson_vl.vol_mol_comp.fix()
    m.fs.state_block_Wilson_vl.tau.fix()

    assert degrees_of_freedom(m.fs.state_block_Wilson_vl) == 0

    # liquid only (Wilson)
    m.fs.state_block_Wilson_l.flow_mol.fix(1)
    m.fs.state_block_Wilson_l.temperature.fix(368)
    m.fs.state_block_Wilson_l.pressure.fix(101325)
    m.fs.state_block_Wilson_l.mole_frac["benzene"].fix(0.5)
    m.fs.state_block_Wilson_l.mole_frac["toluene"].fix(0.5)

    assert degrees_of_freedom(m.fs.state_block_Wilson_l) == 0

    # vapour only (Wilson)
    m.fs.state_block_Wilson_v.flow_mol.fix(1)
    m.fs.state_block_Wilson_v.temperature.fix(368)
    m.fs.state_block_Wilson_v.pressure.fix(101325)
    m.fs.state_block_Wilson_v.mole_frac["benzene"].fix(0.5)
    m.fs.state_block_Wilson_v.mole_frac["toluene"].fix(0.5)

    assert degrees_of_freedom(m.fs.state_block_Wilson_v) == 0
Beispiel #3
0
def test_setInputs_inlet_state_blocks():

    # vapor-liquid
    m.fs.state_block_vl.flow_mol.fix(1)
    m.fs.state_block_vl.temperature.fix(368)
    m.fs.state_block_vl.pressure.fix(101325)
    m.fs.state_block_vl.mole_frac["benzene"].fix(0.5)
    m.fs.state_block_vl.mole_frac["toluene"].fix(0.5)

    assert degrees_of_freedom(m.fs.state_block_vl) == 0

    # liquid only
    m.fs.state_block_l.flow_mol.fix(1)
    m.fs.state_block_l.temperature.fix(362)
    m.fs.state_block_l.pressure.fix(101325)
    m.fs.state_block_l.mole_frac["benzene"].fix(0.5)
    m.fs.state_block_l.mole_frac["toluene"].fix(0.5)

    assert degrees_of_freedom(m.fs.state_block_l) == 0

    # vapor only
    m.fs.state_block_v.flow_mol.fix(1)
    m.fs.state_block_v.temperature.fix(375)
    m.fs.state_block_v.pressure.fix(101325)
    m.fs.state_block_v.mole_frac["benzene"].fix(0.5)
    m.fs.state_block_v.mole_frac["toluene"].fix(0.5)

    assert degrees_of_freedom(m.fs.state_block_v) == 0
Beispiel #4
0
def test_setInputs_inlet_state_block():

    # vapor-liquid (NRTL)
    m.fs.state_block_NRTL_vl.flow_mol.fix(1)
    m.fs.state_block_NRTL_vl.temperature.fix(368)
    m.fs.state_block_NRTL_vl.pressure.fix(101325)
    m.fs.state_block_NRTL_vl.mole_frac["benzene"].fix(0.5)
    m.fs.state_block_NRTL_vl.mole_frac["toluene"].fix(0.5)

    assert degrees_of_freedom(m.fs.state_block_NRTL_vl) == 6

    # Fix NRTL specific variables and check if DOF is 0
    m.fs.state_block_NRTL_vl.alpha.fix()
    m.fs.state_block_NRTL_vl.tau.fix()

    assert degrees_of_freedom(m.fs.state_block_NRTL_vl) == 0

    # liquid only (NRTL)
    m.fs.state_block_NRTL_l.flow_mol.fix(1)
    m.fs.state_block_NRTL_l.temperature.fix(368)
    m.fs.state_block_NRTL_l.pressure.fix(101325)
    m.fs.state_block_NRTL_l.mole_frac["benzene"].fix(0.5)
    m.fs.state_block_NRTL_l.mole_frac["toluene"].fix(0.5)

    assert degrees_of_freedom(m.fs.state_block_NRTL_l) == 0

    # vapour only (NRTL)
    m.fs.state_block_NRTL_v.flow_mol.fix(1)
    m.fs.state_block_NRTL_v.temperature.fix(368)
    m.fs.state_block_NRTL_v.pressure.fix(101325)
    m.fs.state_block_NRTL_v.mole_frac["benzene"].fix(0.5)
    m.fs.state_block_NRTL_v.mole_frac["toluene"].fix(0.5)

    assert degrees_of_freedom(m.fs.state_block_NRTL_v) == 0
Beispiel #5
0
def test_setInputs():
    """Set inlet and operating conditions for co-current heat exchanger."""
    # HX dimensions
    m.fs.HX_co_current.d_shell.fix(1.04)
    m.fs.HX_co_current.d_tube_outer.fix(0.01167)
    m.fs.HX_co_current.d_tube_inner.fix(0.01067)
    m.fs.HX_co_current.N_tubes.fix(1176)
    m.fs.HX_co_current.shell_length.fix(4.85)
    m.fs.HX_co_current.tube_length.fix(4.85)
    m.fs.HX_co_current.shell_heat_transfer_coefficient.fix(2000)
    m.fs.HX_co_current.tube_heat_transfer_coefficient.fix(51000)

    # Boundary conditions
    for t in m.fs.time:
        # Unit HX01
        # NETL baseline study
        m.fs.HX_co_current.shell_inlet.flow_mol[0].fix(2300)  # mol/s
        m.fs.HX_co_current.shell_inlet.temperature[0].fix(676)  # K
        m.fs.HX_co_current.shell_inlet.pressure[0].fix(7.38E6)  # Pa
        m.fs.HX_co_current.shell_inlet.vapor_frac[0].fix(1)

        m.fs.HX_co_current.tube_inlet.flow_mol[0].fix(26.6)  # mol/s
        m.fs.HX_co_current.tube_inlet.temperature[0].fix(529)  # K
        m.fs.HX_co_current.tube_inlet.pressure[0].fix(2.65E7)  # Pa
        m.fs.HX_co_current.tube_inlet.vapor_frac[0].fix(0)

    assert degrees_of_freedom(m.fs.HX_co_current) == 0

    """Set inlet and operating conditions for counter-current
       heat exchanger."""

    # HX dimensions
    m.fs.HX_counter_current.d_shell.fix(1.04)
    m.fs.HX_counter_current.d_tube_outer.fix(0.01167)
    m.fs.HX_counter_current.d_tube_inner.fix(0.01067)
    m.fs.HX_counter_current.N_tubes.fix(1176)
    m.fs.HX_counter_current.shell_length.fix(4.85)
    m.fs.HX_counter_current.tube_length.fix(4.85)
    m.fs.HX_counter_current.shell_heat_transfer_coefficient.fix(2000)
    m.fs.HX_counter_current.tube_heat_transfer_coefficient.fix(51000)

    # Boundary conditions
    for t in m.fs.time:
        # Unit HX01
        # NETL baseline study
        m.fs.HX_counter_current.shell_inlet.flow_mol[0].fix(2300)  # mol/s
        m.fs.HX_counter_current.shell_inlet.temperature[0].fix(676)  # K
        m.fs.HX_counter_current.shell_inlet.pressure[0].fix(7.38E6)  # Pa
        m.fs.HX_counter_current.shell_inlet.vapor_frac[0].fix(1)

        m.fs.HX_counter_current.tube_inlet.flow_mol[0].fix(26.6)  # mol/s
        m.fs.HX_counter_current.tube_inlet.temperature[0].fix(529)  # K
        m.fs.HX_counter_current.tube_inlet.pressure[0].fix(2.65E7)  # Pa
        m.fs.HX_counter_current.tube_inlet.vapor_frac[0].fix(0)

    assert degrees_of_freedom(m.fs.HX_counter_current) == 0
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_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_initialize_heat_exchanger(build_heat_exchanger):
    m = build_heat_exchanger
    init_state1 = {"flow_mol": 100, "pressure": 101325, "enth_mol": 4000}
    init_state2 = {"flow_mol": 100, "pressure": 101325, "enth_mol": 3500}

    m.fs.heat_exchanger.area.fix(1000)
    m.fs.heat_exchanger.overall_heat_transfer_coefficient.fix(100)
    prop_in_1 = m.fs.heat_exchanger.side_1.properties_in[0]
    prop_out_1 = m.fs.heat_exchanger.side_1.properties_out[0]
    prop_in_2 = m.fs.heat_exchanger.side_2.properties_in[0]
    prop_out_2 = m.fs.heat_exchanger.side_2.properties_out[0]
    prop_in_1.flow_mol.fix(100)
    prop_in_1.pressure.fix(101325)
    prop_in_1.enth_mol.fix(4000)
    prop_in_2.flow_mol.fix(100)
    prop_in_2.pressure.fix(101325)
    prop_in_2.enth_mol.fix(3000)

    m.fs.heat_exchanger.heat_duty.value = 10000
    m.fs.heat_exchanger.initialize(state_args_1=init_state1,
                                   state_args_2=init_state2,
                                   outlvl=5)
    solver.solve(m)
    assert degrees_of_freedom(m) == 0
    print(value(m.fs.heat_exchanger.delta_temperature[0]))
    print(value(m.fs.heat_exchanger.side_1.heat[0]))
    print(value(m.fs.heat_exchanger.side_2.heat[0]))
    assert abs(value(prop_in_1.temperature) - 326.1667075078748) <= 1e-4
    assert abs(value(prop_out_1.temperature) - 313.81921851031814) <= 1e-4
    assert abs(value(prop_in_2.temperature) - 312.88896252921734) <= 1e-4
    assert abs(value(prop_out_2.temperature) - 325.23704823703537) <= 1e-4
    assert abs(value(prop_in_1.phase_frac["Liq"]) - 1) <= 1e-6
    assert abs(value(prop_out_1.phase_frac["Liq"]) - 1) <= 1e-6
    assert abs(value(prop_in_1.phase_frac["Vap"]) - 0) <= 1e-6
    assert abs(value(prop_out_1.phase_frac["Vap"]) - 0) <= 1e-6
Beispiel #9
0
def test_initialize():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.properties = BTXParameterBlock()

    m.fs.ff = FeedFlash(default={"property_package": m.fs.properties})

    m.fs.ff.flow_mol.fix(1)
    m.fs.ff.temperature.fix(368)
    m.fs.ff.pressure.fix(101325)
    m.fs.ff.mole_frac[0, "benzene"].fix(0.5)
    m.fs.ff.mole_frac[0, "toluene"].fix(0.5)

    assert degrees_of_freedom(m) == 0

    m.fs.ff.initialize(outlvl=5, optarg={'tol': 1e-6})

    assert (pytest.approx(101325.0,
                          abs=1e3) == m.fs.ff.outlet.pressure[0].value)
    assert (pytest.approx(368.00,
                          abs=1e-0) == m.fs.ff.outlet.temperature[0].value)
    assert (pytest.approx(1.0, abs=1e-2) == m.fs.ff.outlet.flow_mol[0].value)
    assert (pytest.approx(0.3961, abs=1e-3) == m.fs.ff.control_volume.
            properties_out[0].flow_mol_phase["Vap"].value)
Beispiel #10
0
def test_tutorial_3():
    f = import_file(join(example, "Tutorial_3_Dynamic_Flowsheets"))
    m, results = f.main()

    # Check for optimal solution
    assert results.solver.termination_condition == TerminationCondition.optimal
    assert results.solver.status == SolverStatus.ok

    assert degrees_of_freedom(m) == 0

    assert m.fs.time.last() == 20.0
    assert len(m.fs.time) == 51

    assert (m.fs.Tank2.outlet.flow_vol[20.0].value == pytest.approx(1.0,
                                                                    abs=1e-2))
    assert (m.fs.Tank2.outlet.conc_mol_comp[20.0,
                                            "Ethanol"].value == pytest.approx(
                                                43.62, abs=1e-1))
    assert (
        m.fs.Tank2.outlet.conc_mol_comp[20.0,
                                        "EthylAcetate"].value == pytest.approx(
                                            1.65, abs=1e-1))
    assert (m.fs.Tank2.outlet.conc_mol_comp[20.0,
                                            "NaOH"].value == pytest.approx(
                                                6.38, abs=1e-1))
    assert (m.fs.Tank2.outlet.conc_mol_comp[20.0, "SodiumAcetate"].value ==
            pytest.approx(43.62, abs=1e-1))
    assert (m.fs.Tank2.outlet.conc_mol_comp[20.0,
                                            "H2O"].value == pytest.approx(
                                                55388.0, abs=1))
    assert (m.fs.Tank2.outlet.pressure[20.0].value == pytest.approx(101325,
                                                                    abs=1))
    assert (m.fs.Tank2.outlet.temperature[20.0].value == pytest.approx(
        303.66, abs=1e-1))
Beispiel #11
0
def test_tutorial_2():
    f = import_file(join(example, "Tutorial_2_Basic_Flowsheet_Optimization"))
    m, results = f.main()

    # Check for optimal solution
    assert results.solver.termination_condition == TerminationCondition.optimal
    assert results.solver.status == SolverStatus.ok

    assert degrees_of_freedom(m) == 1

    assert (m.fs.Tank2.outlet.flow_vol[0].value == pytest.approx(1.0,
                                                                 abs=1e-2))
    assert (m.fs.Tank2.outlet.conc_mol_comp[0,
                                            "Ethanol"].value == pytest.approx(
                                                92.106, abs=1e-2))
    assert (
        m.fs.Tank2.outlet.conc_mol_comp[0,
                                        "EthylAcetate"].value == pytest.approx(
                                            7.894, abs=1e-2))
    assert (m.fs.Tank2.outlet.conc_mol_comp[0, "NaOH"].value == pytest.approx(
        7.894, abs=1e-2))
    assert (m.fs.Tank2.outlet.conc_mol_comp[0, "SodiumAcetate"].value ==
            pytest.approx(92.106, abs=1e-2))
    assert (m.fs.Tank2.outlet.conc_mol_comp[0, "H2O"].value == pytest.approx(
        55388.0, abs=1))
    assert (m.fs.Tank2.outlet.pressure[0].value == pytest.approx(101325,
                                                                 abs=1))
    assert (m.fs.Tank2.outlet.temperature[0].value == pytest.approx(304.23,
                                                                    abs=1e-1))

    assert (m.fs.Tank1.volume[0].value == pytest.approx(1.215, abs=1e-2))
    assert (m.fs.Tank2.volume[0].value == pytest.approx(1.785, abs=1e-2))
Beispiel #12
0
def test_initialize():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.properties = SaponificationParameterBlock()

    m.fs.prod = Product(default={"property_package": m.fs.properties})

    m.fs.prod.flow_vol.fix(1.0e-03)
    m.fs.prod.conc_mol_comp[0, "H2O"].fix(55388.0)
    m.fs.prod.conc_mol_comp[0, "NaOH"].fix(100.0)
    m.fs.prod.conc_mol_comp[0, "EthylAcetate"].fix(100.0)
    m.fs.prod.conc_mol_comp[0, "SodiumAcetate"].fix(0.0)
    m.fs.prod.conc_mol_comp[0, "Ethanol"].fix(0.0)

    m.fs.prod.temperature.fix(303.15)
    m.fs.prod.pressure.fix(101325.0)

    assert degrees_of_freedom(m) == 0

    m.fs.prod.initialize(outlvl=5, optarg={'tol': 1e-6})

    assert m.fs.prod.inlet.flow_vol[0].value == 1.0e-03
    assert m.fs.prod.inlet.conc_mol_comp[0, "H2O"].value == 55388.0
    assert m.fs.prod.inlet.conc_mol_comp[0, "NaOH"].value == 100.0
    assert m.fs.prod.inlet.conc_mol_comp[0, "EthylAcetate"].value == 100.0
    assert m.fs.prod.inlet.conc_mol_comp[0, "SodiumAcetate"].value == 0.0
    assert m.fs.prod.inlet.conc_mol_comp[0, "Ethanol"].value == 0.0
Beispiel #13
0
def test_setInputs():
    m.fs.flash.inlet.flow_mol.fix(1)
    m.fs.flash.inlet.temperature.fix(368)
    m.fs.flash.inlet.pressure.fix(101325)
    m.fs.flash.inlet.mole_frac[0, "benzene"].fix(0.5)
    m.fs.flash.inlet.mole_frac[0, "toluene"].fix(0.5)

    m.fs.flash.heat_duty.fix(0)
    m.fs.flash.deltaP.fix(0)

    assert degrees_of_freedom(m) == 0
Beispiel #14
0
def test_initialize(build_turbine):
    """Initialize a turbine model"""
    m = build_turbine
    # set inlet
    m.fs.turb.inlet.enth_mol[0].value = 47115
    m.fs.turb.inlet.flow_mol[0].value = 15000
    m.fs.turb.inlet.pressure[0].value = 8e4

    m.fs.turb.initialize(outlvl=1)
    for c in active_equalities(m):
        assert (abs(c.body() - c.lower) < 1e-4)
    assert (degrees_of_freedom(m) == 3
            )  #inlet was't fixed and still shouldn't be
Beispiel #15
0
def test_initialize(build_turbine):
    """Initialize a turbine model"""
    m = build_turbine
    # set inlet
    m.fs.turb.inlet.enth_mol[0].value = 70000
    m.fs.turb.inlet.flow_mol[0].value = 15000
    m.fs.turb.inlet.pressure[0].value = 8e6
    m.fs.turb.efficiency_isentropic.fix(0.8)
    m.fs.turb.ratioP.fix(0.7)
    m.fs.turb.initialize(outlvl=4)
    for c in active_equalities(m):
        assert (abs(c.body() - c.lower) < 1e-4)
    assert (degrees_of_freedom(m) == 3
            )  #inlet was't fixed and still shouldn't be
Beispiel #16
0
def test_initialize(build_turbine):
    """Initialize a turbine model"""
    m = build_turbine
    hin = iapws95_ph.htpx(T=880, P=2.4233e7)
    # set inlet
    m.fs.turb.inlet.enth_mol[0].value = hin
    m.fs.turb.inlet.flow_mol[0].value = 26000 / 4.0
    m.fs.turb.inlet.pressure[0].value = 2.4233e7

    m.fs.turb.initialize(outlvl=1)
    for c in active_equalities(m):
        assert (abs(c.body() - c.lower) < 1e-4)
    assert (degrees_of_freedom(m) == 3
            )  #inlet was't fixed and still shouldn't be
def test_heater_q1(build_heater):
    m = build_heater
    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 abs(value(prop_in.temperature) - 326.1667075078748) <= 1e-4
    assert abs(value(prop_out.temperature) - 373.12429584768876) <= 1e-4
    assert abs(value(prop_in.phase_frac["Liq"]) - 1) <= 1e-6
    assert abs(value(prop_out.phase_frac["Liq"]) - 0.5953218682380845) <= 1e-6
    assert abs(value(prop_in.phase_frac["Vap"]) - 0) <= 1e-6
    assert abs(value(prop_out.phase_frac["Vap"]) - 0.40467813176191547) <= 1e-6
Beispiel #18
0
def test_initialize():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.properties = SaponificationParameterBlock()
    m.fs.reactions = SaponificationReactionParameterBlock(
        default={"property_package": m.fs.properties})

    m.fs.cstr = CSTR(
        default={
            "property_package": m.fs.properties,
            "reaction_package": m.fs.reactions,
            "has_equilibrium_reactions": False,
            "has_heat_transfer": False,
            "has_pressure_change": False
        })

    m.fs.cstr.inlet.flow_vol.fix(1.0e-03)
    m.fs.cstr.inlet.conc_mol_comp[0, "H2O"].fix(55388.0)
    m.fs.cstr.inlet.conc_mol_comp[0, "NaOH"].fix(100.0)
    m.fs.cstr.inlet.conc_mol_comp[0, "EthylAcetate"].fix(100.0)
    m.fs.cstr.inlet.conc_mol_comp[0, "SodiumAcetate"].fix(0.0)
    m.fs.cstr.inlet.conc_mol_comp[0, "Ethanol"].fix(0.0)

    m.fs.cstr.inlet.temperature.fix(303.15)
    m.fs.cstr.inlet.pressure.fix(101325.0)

    m.fs.cstr.control_volume.volume.fix(1.5e-03)

    assert degrees_of_freedom(m) == 0

    m.fs.cstr.initialize(outlvl=5, optarg={'tol': 1e-6})

    assert (pytest.approx(101325.0,
                          abs=1e-2) == m.fs.cstr.outlet.pressure[0].value)
    assert (pytest.approx(303.15,
                          abs=1e-2) == m.fs.cstr.outlet.temperature[0].value)
    assert (pytest.approx(
        20.80,
        abs=1e-2) == m.fs.cstr.outlet.conc_mol_comp[0, "EthylAcetate"].value)
Beispiel #19
0
def test_initialize():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.properties = SaponificationParameterBlock()
    m.fs.reactions = SaponificationReactionParameterBlock(
        default={"property_package": m.fs.properties})

    m.fs.rstoic = StoichiometricReactor(
        default={
            "property_package": m.fs.properties,
            "reaction_package": m.fs.reactions,
            "has_heat_transfer": False,
            "has_pressure_change": False
        })

    m.fs.rstoic.inlet.flow_vol.fix(1.0)
    m.fs.rstoic.inlet.conc_mol_comp[0, "H2O"].fix(55388.0)
    m.fs.rstoic.inlet.conc_mol_comp[0, "NaOH"].fix(100.0)
    m.fs.rstoic.inlet.conc_mol_comp[0, "EthylAcetate"].fix(100.0)
    m.fs.rstoic.inlet.conc_mol_comp[0, "SodiumAcetate"].fix(0.0)
    m.fs.rstoic.inlet.conc_mol_comp[0, "Ethanol"].fix(0.0)

    m.fs.rstoic.inlet.temperature.fix(303.15)
    m.fs.rstoic.inlet.pressure.fix(101325.0)

    m.fs.rstoic.rate_reaction_extent[:, 'R1'].fix(
        0.9 * m.fs.rstoic.inlet.conc_mol_comp[0, "NaOH"].value)

    assert degrees_of_freedom(m) == 0

    m.fs.rstoic.initialize(outlvl=5, optarg={'tol': 1e-6})

    assert (pytest.approx(101325.0,
                          abs=1e-2) == m.fs.rstoic.outlet.pressure[0].value)
    assert (pytest.approx(303.15,
                          abs=1e-2) == m.fs.rstoic.outlet.temperature[0].value)
    assert (pytest.approx(
        90, abs=1e-2) == m.fs.rstoic.outlet.conc_mol_comp[0, "Ethanol"].value)
def test_fwh_model():
    model = pyo.ConcreteModel()
    model.fs = FlowsheetBlock(
        default={
            "dynamic": False,
            "default_property_package": 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 test_build():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.properties = SaponificationParameterBlock()

    m.fs.sj = StateJunction(default={"property_package": m.fs.properties})

    assert hasattr(m.fs.sj, "inlet")
    assert len(m.fs.sj.inlet.vars) == 4
    assert hasattr(m.fs.sj.inlet, "flow_vol")
    assert hasattr(m.fs.sj.inlet, "conc_mol_comp")
    assert hasattr(m.fs.sj.inlet, "temperature")
    assert hasattr(m.fs.sj.inlet, "pressure")

    assert hasattr(m.fs.sj, "outlet")
    assert len(m.fs.sj.outlet.vars) == 4
    assert hasattr(m.fs.sj.outlet, "flow_vol")
    assert hasattr(m.fs.sj.outlet, "conc_mol_comp")
    assert hasattr(m.fs.sj.outlet, "temperature")
    assert hasattr(m.fs.sj.outlet, "pressure")

    assert degrees_of_freedom(m) == 0
Beispiel #22
0
def main():
    # Create a Concrete Model as the top level object
    m = ConcreteModel()

    # Add a flowsheet object to the model
    m.fs = FlowsheetBlock(default={"dynamic": False})

    # Add property packages to flowsheet library
    m.fs.thermo_params = thermo_props.HDAParameterBlock()
    m.fs.reaction_params = reaction_props.HDAReactionParameterBlock(
        default={"property_package": m.fs.thermo_params})

    # Create unit models
    m.fs.M101 = Mixer(
        default={
            "property_package": m.fs.thermo_params,
            "inlet_list": ["toluene_feed", "hydrogen_feed", "vapor_recycle"]
        })

    m.fs.H101 = Heater(
        default={
            "property_package": m.fs.thermo_params,
            "has_pressure_change": False,
            "has_phase_equilibrium": True
        })

    m.fs.R101 = StoichiometricReactor(
        default={
            "property_package": m.fs.thermo_params,
            "reaction_package": m.fs.reaction_params,
            "has_heat_of_reaction": True,
            "has_heat_transfer": True,
            "has_pressure_change": False
        })

    m.fs.F101 = Flash(
        default={
            "property_package": m.fs.thermo_params,
            "has_heat_transfer": True,
            "has_pressure_change": True
        })

    m.fs.S101 = Splitter(
        default={
            "property_package": m.fs.thermo_params,
            "ideal_separation": False,
            "outlet_list": ["purge", "recycle"]
        })

    # This is needed to avoid pressure degeneracy in recylce loop
    m.fs.C101 = PressureChanger(
        default={
            "property_package": m.fs.thermo_params,
            "compressor": True,
            "thermodynamic_assumption": ThermodynamicAssumption.isothermal
        })

    m.fs.F102 = Flash(
        default={
            "property_package": m.fs.thermo_params,
            "has_heat_transfer": True,
            "has_pressure_change": True
        })

    m.fs.H101.control_volume.scaling_factor_energy = 1e-3
    m.fs.R101.control_volume.scaling_factor_energy = 1e-3
    m.fs.F101.control_volume.scaling_factor_energy = 1e-3
    m.fs.C101.control_volume.scaling_factor_energy = 1e-3
    m.fs.F102.control_volume.scaling_factor_energy = 1e-3

    # Connect units
    m.fs.s03 = Arc(source=m.fs.M101.outlet, destination=m.fs.H101.inlet)
    m.fs.s04 = Arc(source=m.fs.H101.outlet, destination=m.fs.R101.inlet)
    m.fs.s05 = Arc(source=m.fs.R101.outlet, destination=m.fs.F101.inlet)
    m.fs.s06 = Arc(source=m.fs.F101.vap_outlet, destination=m.fs.S101.inlet)
    m.fs.s08 = Arc(source=m.fs.S101.recycle, destination=m.fs.C101.inlet)
    m.fs.s09 = Arc(source=m.fs.C101.outlet,
                   destination=m.fs.M101.vapor_recycle)
    m.fs.s10 = Arc(source=m.fs.F101.liq_outlet, destination=m.fs.F102.inlet)

    TransformationFactory("network.expand_arcs").apply_to(m)

    # Set operating conditions
    m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Vap", "benzene"].fix(1e-5)
    m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Vap", "toluene"].fix(1e-5)
    m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Vap", "hydrogen"].fix(1e-5)
    m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Vap", "methane"].fix(1e-5)
    m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Liq", "benzene"].fix(1e-5)
    m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Liq", "toluene"].fix(0.30)
    m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Liq", "hydrogen"].fix(1e-5)
    m.fs.M101.toluene_feed.flow_mol_phase_comp[0, "Liq", "methane"].fix(1e-5)
    m.fs.M101.toluene_feed.temperature.fix(303.2)
    m.fs.M101.toluene_feed.pressure.fix(350000)

    m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Vap", "benzene"].fix(1e-5)
    m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Vap", "toluene"].fix(1e-5)
    m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Vap", "hydrogen"].fix(0.30)
    m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Vap", "methane"].fix(0.02)
    m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Liq", "benzene"].fix(1e-5)
    m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Liq", "toluene"].fix(1e-5)
    m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Liq", "hydrogen"].fix(1e-5)
    m.fs.M101.hydrogen_feed.flow_mol_phase_comp[0, "Liq", "methane"].fix(1e-5)
    m.fs.M101.hydrogen_feed.temperature.fix(303.2)
    m.fs.M101.hydrogen_feed.pressure.fix(350000)

    m.fs.H101.outlet.temperature.fix(600)

    m.fs.R101.conversion = Var(initialize=0.75, bounds=(0, 1))

    m.fs.R101.conv_constraint = Constraint(
        expr=m.fs.R101.conversion *
        m.fs.R101.inlet.flow_mol_phase_comp[0, "Vap", "toluene"] == (
            m.fs.R101.inlet.flow_mol_phase_comp[0, "Vap", "toluene"] -
            m.fs.R101.outlet.flow_mol_phase_comp[0, "Vap", "toluene"]))

    m.fs.R101.conversion.fix(0.75)
    m.fs.R101.heat_duty.fix(0)

    m.fs.F101.vap_outlet.temperature.fix(325.0)
    m.fs.F101.deltaP.fix(0)

    m.fs.S101.split_fraction[0, "purge"].fix(0.2)

    m.fs.C101.outlet.pressure.fix(350000)

    m.fs.F102.vap_outlet.temperature.fix(375)
    m.fs.F102.deltaP.fix(-200000)

    # Define expressions
    # Product purity
    m.fs.purity = Expression(
        expr=m.fs.F102.vap_outlet.flow_mol_phase_comp[0, "Vap", "benzene"] /
        (m.fs.F102.vap_outlet.flow_mol_phase_comp[0, "Vap", "benzene"] +
         m.fs.F102.vap_outlet.flow_mol_phase_comp[0, "Vap", "toluene"]))

    # Operating cost ($/yr)
    m.fs.cooling_cost = Expression(expr=0.212e-7 * -m.fs.F101.heat_duty[0] +
                                   0.212e-7 * -m.fs.R101.heat_duty[0])
    m.fs.heating_cost = Expression(expr=2.2e-7 * m.fs.H101.heat_duty[0] +
                                   1.9e-7 * m.fs.F102.heat_duty[0])
    m.fs.operating_cost = Expression(
        expr=(3600 * 24 * 365 * (m.fs.heating_cost + m.fs.cooling_cost)))
    print(degrees_of_freedom(m))

    # Initialize Units
    # Define method for initialising each block
    def function(unit):
        unit.initialize(outlvl=1)

    # Create instance of sequential decomposition tool
    seq = SequentialDecomposition()
    seq.options.select_tear_method = "heuristic"
    seq.options.tear_method = "Wegstein"
    seq.options.iterLim = 5

    # Determine tear stream and calculation order
    G = seq.create_graph(m)
    heu_result = seq.tear_set_arcs(G, method="heuristic")
    order = seq.calculation_order(G)

    # Display tear stream and calculation order
    for o in heu_result:
        print(o.name)
    for o in order:
        for oo in o:
            print(oo.name)

    # Set guesses for tear stream
    tear_guesses = {
        "flow_mol_phase_comp": {
            (0, "Vap", "benzene"): 1e-5,
            (0, "Vap", "toluene"): 1e-5,
            (0, "Vap", "hydrogen"): 0.30,
            (0, "Vap", "methane"): 0.02,
            (0, "Liq", "benzene"): 1e-5,
            (0, "Liq", "toluene"): 0.30,
            (0, "Liq", "hydrogen"): 1e-5,
            (0, "Liq", "methane"): 1e-5
        },
        "temperature": {
            0: 303
        },
        "pressure": {
            0: 350000
        }
    }
    seq.set_guesses_for(m.fs.H101.inlet, tear_guesses)

    # Run sequential initialisation
    seq.run(m, function)

    # # Create a solver
    solver = SolverFactory('ipopt')
    solver.options = {'tol': 1e-6}
    solver.options = {'tol': 1e-6, 'max_iter': 5000}
    results = solver.solve(m, tee=True)

    # Print results
    print("M101 Outlet")
    m.fs.M101.outlet.display()

    print("H101 Outlet")
    m.fs.H101.outlet.display()

    print("R101 Outlet")
    m.fs.R101.outlet.display()

    print("F101")
    m.fs.F101.liq_outlet.display()
    m.fs.F101.vap_outlet.display()

    print("F102")
    m.fs.F102.liq_outlet.display()
    m.fs.F102.vap_outlet.display()

    print("Purge")
    m.fs.S101.purge.display()

    print("Purity:", value(m.fs.purity))

    # Optimize process
    m.fs.objective = Objective(sense=minimize, expr=m.fs.operating_cost)

    # Decision variables
    m.fs.H101.outlet.temperature.unfix()
    m.fs.R101.heat_duty.unfix()
    m.fs.F101.vap_outlet.temperature.unfix()
    m.fs.F102.vap_outlet.temperature.unfix()
    m.fs.F102.deltaP.unfix()

    # Variable bounds
    m.fs.H101.outlet.temperature[0].setlb(500)
    m.fs.H101.outlet.temperature[0].setub(600)
    m.fs.R101.outlet.temperature[0].setlb(600)
    m.fs.R101.outlet.temperature[0].setub(800)
    m.fs.F101.vap_outlet.temperature[0].setlb(298.0)
    m.fs.F101.vap_outlet.temperature[0].setub(450.0)
    m.fs.F102.vap_outlet.temperature[0].setlb(298.0)
    m.fs.F102.vap_outlet.temperature[0].setub(450.0)
    m.fs.F102.vap_outlet.pressure[0].setlb(105000)
    m.fs.F102.vap_outlet.pressure[0].setub(110000)

    # Additional Constraints
    m.fs.overhead_loss = Constraint(
        expr=m.fs.F101.vap_outlet.flow_mol_phase_comp[0, "Vap",
                                                      "benzene"] <= 0.20 *
        m.fs.R101.outlet.flow_mol_phase_comp[0, "Vap", "benzene"])

    m.fs.product_flow = Constraint(
        expr=m.fs.F102.vap_outlet.flow_mol_phase_comp[0, "Vap",
                                                      "benzene"] >= 0.15)

    m.fs.product_purity = Constraint(expr=m.fs.purity >= 0.80)

    # Create a solver
    solver = SolverFactory('ipopt')
    solver.options = {'tol': 1e-6}
    solver.options = {'tol': 1e-6, 'max_iter': 5000}
    results = solver.solve(m, tee=True)

    # Print optimization results
    print()
    print("Optimal Solution")
    m.fs.operating_cost.display()
    m.fs.H101.heat_duty.display()
    m.fs.R101.heat_duty.display()
    m.fs.F101.heat_duty.display()
    m.fs.F102.heat_duty.display()

    # Print results
    print("M101 Outlet")
    m.fs.M101.outlet.display()

    print("H101 Outlet")
    m.fs.H101.outlet.display()

    print("R101 Outlet")
    m.fs.R101.outlet.display()

    print("F101")
    m.fs.F101.liq_outlet.display()
    m.fs.F101.vap_outlet.display()

    print("F102")
    m.fs.F102.liq_outlet.display()
    m.fs.F102.vap_outlet.display()

    print("Purge")
    m.fs.S101.purge.display()

    print("Recycle")
    m.fs.S101.recycle.display()

    print("Purity:", value(m.fs.purity))

    # For testing purposes
    return (m, results)
Beispiel #23
0
def test_initialize_temperature():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.properties = MethaneCombustionParameterBlock()

    m.fs.gibbs = GibbsReactor(default={
        "property_package": m.fs.properties,
        "has_heat_transfer": True
    })

    m.fs.gibbs.inlet.flow_mol_comp[0, "H2"].fix(10.0)
    m.fs.gibbs.inlet.flow_mol_comp[0, "N2"].fix(150.0)
    m.fs.gibbs.inlet.flow_mol_comp[0, "O2"].fix(40.0)
    m.fs.gibbs.inlet.flow_mol_comp[0, "CO2"].fix(1e-5)
    m.fs.gibbs.inlet.flow_mol_comp[0, "CH4"].fix(30.0)
    m.fs.gibbs.inlet.flow_mol_comp[0, "CO"].fix(1e-5)
    m.fs.gibbs.inlet.flow_mol_comp[0, "H2O"].fix(1e-5)
    m.fs.gibbs.inlet.flow_mol_comp[0, "NH3"].fix(1e-5)
    m.fs.gibbs.inlet.temperature[0].fix(1500.0)
    m.fs.gibbs.inlet.pressure[0].fix(101325.0)

    m.fs.gibbs.outlet.temperature[0].fix(2844.38)

    assert degrees_of_freedom(m) == 0

    m.fs.gibbs.initialize(outlvl=5,
                          optarg={'tol': 1e-6},
                          state_args={
                              'temperature': 2844.38,
                              'pressure': 101325.0,
                              'flow_mol_comp': {
                                  'CH4': 1e-5,
                                  'CO': 23.0,
                                  'CO2': 7.05,
                                  'H2': 29.0,
                                  'H2O': 41.0,
                                  'N2': 150.0,
                                  'NH3': 1e-5,
                                  'O2': 1.0
                              }
                          })

    assert (pytest.approx(
        0.0, abs=1e-2) == m.fs.gibbs.outlet.flow_mol_comp[0, "CH4"].value)
    assert (pytest.approx(
        22.614, abs=1e-2) == m.fs.gibbs.outlet.flow_mol_comp[0, "CO"].value)
    assert (pytest.approx(
        7.386, abs=1e-2) == m.fs.gibbs.outlet.flow_mol_comp[0, "CO2"].value)
    assert (pytest.approx(
        28.806, abs=1e-2) == m.fs.gibbs.outlet.flow_mol_comp[0, "H2"].value)
    assert (pytest.approx(
        41.194, abs=1e-2) == m.fs.gibbs.outlet.flow_mol_comp[0, "H2O"].value)
    assert (pytest.approx(
        150.0, abs=1e-2) == m.fs.gibbs.outlet.flow_mol_comp[0, "N2"].value)
    assert (pytest.approx(
        0.0, abs=1e-2) == m.fs.gibbs.outlet.flow_mol_comp[0, "NH3"].value)
    assert (pytest.approx(
        0.710, abs=1e-2) == m.fs.gibbs.outlet.flow_mol_comp[0, "O2"].value)
    assert (pytest.approx(161882.3, abs=1e-2) == m.fs.gibbs.heat_duty[0].value)
    assert (pytest.approx(101325.0,
                          abs=1e-2) == m.fs.gibbs.outlet.pressure[0].value)
def test_initialize():
    """Make a turbine model and make sure it doesn't throw exception"""
    m = build_turbine_for_run_test()
    turb = m.fs.turb

    # Set the inlet of the turbine
    p = 2.4233e7
    hin = iapws95_ph.htpx(T=880, P=p)
    m.fs.turb.inlet_split.inlet.enth_mol[0].fix(hin)
    m.fs.turb.inlet_split.inlet.flow_mol[0].fix(26000)
    m.fs.turb.inlet_split.inlet.pressure[0].fix(p)

    # Set the inlet of the ip section, which is disconnected
    # here to insert reheater
    p = 7.802e+06
    hin = iapws95_ph.htpx(T=880, P=p)
    m.fs.turb.ip_stages[1].inlet.enth_mol[0].value = hin
    m.fs.turb.ip_stages[1].inlet.flow_mol[0].value = 25220.0
    m.fs.turb.ip_stages[1].inlet.pressure[0].value = p

    for i, s in turb.hp_stages.items():
        s.ratioP[:] = 0.88
        s.efficiency_isentropic[:] = 0.9
    for i, s in turb.ip_stages.items():
        s.ratioP[:] = 0.85
        s.efficiency_isentropic[:] = 0.9
    for i, s in turb.lp_stages.items():
        s.ratioP[:] = 0.82
        s.efficiency_isentropic[:] = 0.9

    turb.hp_split[4].split_fraction[0, "outlet_2"].fix(0.03)
    turb.hp_split[7].split_fraction[0, "outlet_2"].fix(0.03)
    turb.ip_split[5].split_fraction[0, "outlet_2"].fix(0.04)
    turb.ip_split[14].split_fraction[0, "outlet_2"].fix(0.04)
    turb.ip_split[14].split_fraction[0, "outlet_3"].fix(0.15)
    turb.lp_split[4].split_fraction[0, "outlet_2"].fix(0.04)
    turb.lp_split[7].split_fraction[0, "outlet_2"].fix(0.04)
    turb.lp_split[9].split_fraction[0, "outlet_2"].fix(0.04)
    turb.lp_split[11].split_fraction[0, "outlet_2"].fix(0.04)

    # Congiure with reheater for a full test
    turb.ip_stages[1].inlet.unfix()
    turb.inlet_split.inlet.flow_mol.unfix()
    turb.inlet_mix.use_equal_pressure_constraint()
    turb.initialize(outlvl=1)

    for t in m.fs.time:
        m.fs.reheat.inlet.flow_mol[t].value = \
            value(turb.hp_split[7].outlet_1_state[t].flow_mol)
        m.fs.reheat.inlet.enth_mol[t].value = \
            value(turb.hp_split[7].outlet_1_state[t].enth_mol)
        m.fs.reheat.inlet.pressure[t].value = \
            value(turb.hp_split[7].outlet_1_state[t].pressure)
    m.fs.reheat.initialize(outlvl=4)

    def reheat_T_rule(b, t):
        return m.fs.reheat.control_volume.properties_out[t].temperature == 880

    m.fs.reheat.temperature_out_equation = Constraint(
        m.fs.reheat.flowsheet().config.time, rule=reheat_T_rule)

    TransformationFactory("network.expand_arcs").apply_to(m)
    m.fs.turb.outlet_stage.control_volume.properties_out[0].pressure.fix()

    assert (degrees_of_freedom(m) == 0)
    solver.solve(m, tee=True)
    for c in active_equalities(m):
        assert (abs(c.body() - c.lower) < 1e-4)

    return m
Beispiel #25
0
    def initialize(blk, flow_vol=None, temperature=None, pressure=None,
                   conc_mol_comp=None, state_vars_fixed=False,
                   hold_state=False, outlvl=0,
                   solver='ipopt', optarg={'tol': 1e-8}):
        '''
        Initialisation routine for property package.

        Keyword Arguments:
            flow_mol_comp : value at which to initialize component flows
                             (default=None)
            pressure : value at which to initialize pressure (default=None)
            temperature : value at which to initialize temperature
                          (default=None)
            outlvl : sets output level of initialisation routine

                     * 0 = no output (default)
                     * 1 = return solver state for each step in routine
                     * 2 = include solver output infomation (tee=True)
            state_vars_fixed: Flag to denote if state vars have already been
                              fixed.
                              - True - states have already been fixed by the
                                       control volume 1D. Control volume 0D
                                       does not fix the state vars, so will
                                       be False if this state block is used
                                       with 0D blocks.
                             - False - states have not been fixed. The state
                                       block will deal with fixing/unfixing.
            optarg : solver options dictionary object (default=None)
            solver : str indicating whcih solver to use during
                     initialization (default = 'ipopt')
            hold_state : flag indicating whether the initialization routine
                         should unfix any state variables fixed during
                         initialization (default=False).
                         - True - states varaibles are not unfixed, and
                                 a dict of returned containing flags for
                                 which states were fixed during
                                 initialization.
                        - False - state variables are unfixed after
                                 initialization by calling the
                                 relase_state method

        Returns:
            If hold_states is True, returns a dict containing flags for
            which states were fixed during initialization.
        '''
        # Deactivate the constraints specific for outlet block i.e.
        # when defined state is False
        for k in blk.keys():
            if blk[k].config.defined_state is False:
                blk[k].conc_water_eqn.deactivate()

        if state_vars_fixed is False:
            # Fix state variables if not already fixed
            Fflag = {}
            Pflag = {}
            Tflag = {}
            Cflag = {}

            for k in blk.keys():
                # Fix state vars if not already fixed
                if blk[k].flow_vol.fixed is True:
                    Fflag[k] = True
                else:
                    Fflag[k] = False
                    if flow_vol is None:
                        blk[k].flow_vol.fix(1.0)
                    else:
                        blk[k].flow_vol.fix(flow_vol)

                for j in blk[k]._params.component_list:
                    if blk[k].conc_mol_comp[j].fixed is True:
                        Cflag[k, j] = True
                    else:
                        Cflag[k, j] = False
                        if conc_mol_comp is None:
                            if j == "H2O":
                                blk[k].conc_mol_comp[j].fix(55388.0)
                            else:
                                blk[k].conc_mol_comp[j].fix(100.0)
                        else:
                            blk[k].conc_mol_comp[j].fix(conc_mol_comp[j])

                if blk[k].pressure.fixed is True:
                    Pflag[k] = True
                else:
                    Pflag[k] = False
                    if pressure is None:
                        blk[k].pressure.fix(101325.0)
                    else:
                        blk[k].pressure.fix(pressure)

                if blk[k].temperature.fixed is True:
                    Tflag[k] = True
                else:
                    Tflag[k] = False
                    if temperature is None:
                        blk[k].temperature.fix(298.15)
                    else:
                        blk[k].temperature.fix(temperature)

            # If input block, return flags, else release state
            flags = {"Fflag": Fflag, "Pflag": Pflag,
                     "Tflag": Tflag, "Cflag": Cflag}

        else:
            # Check when the state vars are fixed already result in dof 0
            for k in blk.keys():
                if degrees_of_freedom(blk[k]) != 0:
                    raise Exception("State vars fixed but degrees of freedom "
                                    "for state block is not zero during "
                                    "initialization.")

        opt = SolverFactory(solver)
        opt.options = optarg

        # Post initialization reactivate constraints specific for
        # all blocks other than the inlet
        for k in blk.keys():
            if not blk[k].config.defined_state:
                blk[k].conc_water_eqn.activate()

        if state_vars_fixed is False:
            if hold_state is True:
                return flags
            else:
                blk.release_state(flags)

        if outlvl > 0:
            if outlvl > 0:
                _log.info('{} Initialisation Complete.'.format(blk.name))
    def initialize(blk,
                   flow_mol=None,
                   mole_frac=None,
                   temperature=None,
                   pressure=None,
                   state_vars_fixed=False,
                   hold_state=False,
                   outlvl=1,
                   solver='ipopt',
                   optarg={'tol': 1e-8}):
        """
        Initialisation routine for property package.
        Keyword Arguments:
            flow_mol_comp : value at which to initialize component flows
                             (default=None)
            pressure : value at which to initialize pressure (default=None)
            temperature : value at which to initialize temperature
                          (default=None)
            outlvl : sets output level of initialisation routine
                     * 0 = no output (default)
                     * 1 = return solver state for each step in routine
                     * 2 = include solver output infomation (tee=True)
            optarg : solver options dictionary object (default=None)
            state_vars_fixed: Flag to denote if state vars have already been
                              fixed.
                              - True - states have already been fixed by the
                                       control volume 1D. Control volume 0D
                                       does not fix the state vars, so will
                                       be False if this state block is used
                                       with 0D blocks.
                             - False - states have not been fixed. The state
                                       block will deal with fixing/unfixing.
            solver : str indicating whcih solver to use during
                     initialization (default = 'ipopt')
            hold_state : flag indicating whether the initialization routine
                         should unfix any state variables fixed during
                         initialization (default=False).
                         - True - states varaibles are not unfixed, and
                                 a dict of returned containing flags for
                                 which states were fixed during
                                 initialization.
                        - False - state variables are unfixed after
                                 initialization by calling the
                                 relase_state method
        Returns:
            If hold_states is True, returns a dict containing flags for
            which states were fixed during initialization.
        """

        _log.info('Starting {} initialisation'.format(blk.name))

        # Deactivate the constraints specific for outlet block i.e.
        # when defined state is False
        for k in blk.keys():
            if blk[k].config.defined_state is False:
                blk[k].sum_mole_frac_out.deactivate()

        # Fix state variables if not already fixed
        if state_vars_fixed is False:
            Fflag = {}
            Xflag = {}
            Pflag = {}
            Tflag = {}

            for k in blk.keys():
                if blk[k].flow_mol.fixed is True:
                    Fflag[k] = True
                else:
                    Fflag[k] = False
                    if flow_mol is None:
                        blk[k].flow_mol.fix(1.0)
                    else:
                        blk[k].flow_mol.fix(flow_mol)

                for j in blk[k]._params.component_list:
                    if blk[k].mole_frac[j].fixed is True:
                        Xflag[k, j] = True
                    else:
                        Xflag[k, j] = False
                        if mole_frac is None:
                            blk[k].mole_frac[j].fix(
                                1 / len(blk[k]._params.component_list))
                        else:
                            blk[k].mole_frac[j].fix(mole_frac[j])

                if blk[k].pressure.fixed is True:
                    Pflag[k] = True
                else:
                    Pflag[k] = False
                    if pressure is None:
                        blk[k].pressure.fix(101325.0)
                    else:
                        blk[k].pressure.fix(pressure)

                if blk[k].temperature.fixed is True:
                    Tflag[k] = True
                else:
                    Tflag[k] = False
                    if temperature is None:
                        blk[k].temperature.fix(325)
                    else:
                        blk[k].temperature.fix(temperature)

            # ---------------------------------------------------------------------
            # If input block, return flags, else release state
            flags = {
                "Fflag": Fflag,
                "Xflag": Xflag,
                "Pflag": Pflag,
                "Tflag": Tflag
            }

        else:
            # Check when the state vars are fixed already result in dof 0
            for k in blk.keys():
                if degrees_of_freedom(blk[k]) != 0:
                    raise Exception("State vars fixed but degrees of freedom "
                                    "for state block is not zero during "
                                    "initialization.")
        # Set solver options
        if outlvl > 1:
            stee = True
        else:
            stee = False

        if optarg is None:
            sopt = {'tol': 1e-8}
        else:
            sopt = optarg

        opt = SolverFactory('ipopt')
        opt.options = sopt

        # ---------------------------------------------------------------------
        # If present, initialize bubble and dew point calculations
        for k in blk.keys():
            if hasattr(blk[k], "eq_temperature_bubble"):
                calculate_variable_from_constraint(
                    blk[k].temperature_bubble, blk[k].eq_temperature_bubble)

            if hasattr(blk[k], "eq_temperature_dew"):
                calculate_variable_from_constraint(blk[k].temperature_dew,
                                                   blk[k].eq_temperature_dew)

            if hasattr(blk[k], "eq_pressure_bubble"):
                calculate_variable_from_constraint(blk[k].pressure_bubble,
                                                   blk[k].eq_pressure_bubble)

            if hasattr(blk[k], "eq_pressure_dew"):
                calculate_variable_from_constraint(blk[k].pressure_dew,
                                                   blk[k].eq_pressure_dew)

        if outlvl > 0:
            _log.info("Dew and bubble points initialization for "
                      "{} completed".format(blk.name))

        # ---------------------------------------------------------------------
        # If flash, initialize T1 and Teq
        for k in blk.keys():
            if blk[k].config.has_phase_equilibrium:
                blk[k]._t1.value = max(blk[k].temperature.value,
                                       blk[k].temperature_bubble.value)
                blk[k]._teq.value = min(blk[k]._t1.value,
                                        blk[k].temperature_dew.value)

        if outlvl > 0:
            _log.info("Equilibrium temperature initialization for "
                      "{} completed".format(blk.name))

        # ---------------------------------------------------------------------
        # Initialize flow rates and compositions
        # TODO : This will need ot be generalised more when we move to a
        # modular implementation
        for k in blk.keys():
            if blk[k]._params.config.valid_phase == "Liq":
                blk[k].flow_mol_phase['Liq'].value = \
                    blk[k].flow_mol.value

                for j in blk[k]._params.component_list:
                    blk[k].mole_frac_phase['Liq', j].value = \
                        blk[k].mole_frac[j].value

            elif blk[k]._params.config.valid_phase == "Vap":
                blk[k].flow_mol_phase['Vap'].value = \
                    blk[k].flow_mol.value

                for j in blk[k]._params.component_list:
                    blk[k].mole_frac_phase['Vap', j].value = \
                        blk[k].mole_frac[j].value

            else:
                # Seems to work best with default values for phase flows
                for j in blk[k]._params.component_list:
                    blk[k].mole_frac_phase['Vap', j].value = \
                        blk[k].mole_frac[j].value
                    blk[k].mole_frac_phase['Liq', j].value = \
                        blk[k].mole_frac[j].value

                    calculate_variable_from_constraint(
                        blk[k].pressure_sat[j], blk[k].eq_pressure_sat[j])

        # ---------------------------------------------------------------------
        # Solve phase equilibrium constraints
        for k in blk.keys():
            for c in blk[k].component_objects(Constraint):
                # Deactivate all property constraints
                if c.local_name not in ("total_flow_balance",
                                        "component_flow_balances",
                                        "equilibrium_constraint",
                                        "sum_mole_frac", "_t1_constraint",
                                        "_teq_constraint", "eq_pressure_dew",
                                        "eq_pressure_bubble",
                                        "eq_temperature_dew",
                                        "eq_temperature_bubble",
                                        "eq_pressure_sat"):
                    c.deactivate()

        results = solve_indexed_blocks(opt, [blk], tee=stee)

        if outlvl > 0:
            if results.solver.termination_condition \
                    == TerminationCondition.optimal:
                _log.info("Phase state initialization for "
                          "{} completed".format(blk.name))
            else:
                _log.warning("Phase state initialization for "
                             "{} failed".format(blk.name))

        # ---------------------------------------------------------------------
        # Initialize other properties
        for k in blk.keys():
            for c in blk[k].component_objects(Constraint):
                # Activate all constraints except sum_mole_frac_out
                if c.local_name not in ("sum_mole_frac_out"):
                    c.activate()

        if outlvl > 0:
            if results.solver.termination_condition \
                    == TerminationCondition.optimal:
                _log.info("Property initialization for "
                          "{} completed".format(blk.name))
            else:
                _log.warning("Property initialization for "
                             "{} failed".format(blk.name))

        # ---------------------------------------------------------------------
        # Return state to initial conditions
        for k in blk.keys():
            if (blk[k].config.defined_state is False):
                blk[k].sum_mole_frac_out.activate()

        if state_vars_fixed is False:
            if hold_state is True:
                return flags
            else:
                blk.release_state(flags)

        if outlvl > 0:
            _log.info("Initialisation completed for {}".format(blk.name))
    def initialize(self, *args, **kwargs):
        config = self.config # sorter ref to config for less line splitting
        sp = StoreSpec.value_isfixed_isactive(only_fixed=True)
        istate = to_json(self, return_dict=True, wts=sp)

        # the initilization here isn't straight forward since the heat exchanger
        # may have 3 stages and they are countercurrent.  For simplicity each
        # stage in initialized with the same cooling water inlet conditions then
        # the whole feedwater heater is solved together.  There are more robust
        # approaches which can be implimented if the need arises.

        # initialize desuperheat if include
        if config.has_desuperheat:
            if config.has_drain_cooling:
                _set_port(self.desuperheat.inlet_2, self.cooling.inlet_2)
            else:
                _set_port(self.desuperheat.inlet_2, self.condense.inlet_2)
            self.desuperheat.initialize(*args, **kwargs)
            self.desuperheat.inlet_1.flow_mol.unfix()
            if config.has_drain_mixer:
                _set_port(self.drain_mix.steam, self.desuperheat.outlet_1)
            else:
                _set_port(self.condense.inlet_1, self.desuperheat.outlet_1)
            # fix the steam and fwh inlet for init
            self.desuperheat.inlet_1.fix()
            self.desuperheat.inlet_1.flow_mol.unfix() #unfix for extract calc

        # initialize mixer if included
        if config.has_drain_mixer:
            self.drain_mix.steam.fix()
            self.drain_mix.drain.fix()
            self.drain_mix.outlet.unfix()
            self.drain_mix.initialize(*args, **kwargs)
            _set_port(self.condense.inlet_1, self.drain_mix.outlet)
            if config.has_desuperheat:
                self.drain_mix.steam.unfix()
            else:
                self.drain_mix.steam.flow_mol.unfix()
        # Initialize condense section
        if config.has_drain_cooling:
            _set_port(self.condense.inlet_2, self.cooling.inlet_2)
            self.cooling.inlet_2.fix()
        else:
            self.condense.inlet_2.fix()
        self.condense.initialize(*args, **kwargs)
        # Initialize drain cooling if included
        if config.has_drain_cooling:
            _set_port(self.cooling.inlet_1, self.condense.outlet_1)
            self.cooling.initialize(*args, **kwargs)

        # Solve all together
        outlvl = kwargs.get("outlvl", 0)
        opt = SolverFactory(kwargs.get("solver", "ipopt"))
        opt.options = kwargs.get("oparg", {})
        tee = True if outlvl >= 3 else False
        assert(degrees_of_freedom(self)==0)
        results = opt.solve(self, tee=tee)
        if results.solver.termination_condition == TerminationCondition.optimal:
            if outlvl >= 2:
                _log.info('{} Initialization Complete.'.format(self.name))
        else:
            _log.warning('{} Initialization Failed.'.format(self.name))

        from_json(self, sd=istate, wts=sp)
Beispiel #28
0
def test_initialize_total_flow():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.properties = SaponificationParameterBlock()

    m.fs.sb = Separator(default={
            "property_package": m.fs.properties,
            "ideal_separation": False,
            "split_basis": SplittingType.totalFlow})

    m.fs.sb.inlet.flow_vol.fix(1.0e-03)
    m.fs.sb.inlet.conc_mol_comp[0, "H2O"].fix(55388.0)
    m.fs.sb.inlet.conc_mol_comp[0, "NaOH"].fix(100.0)
    m.fs.sb.inlet.conc_mol_comp[0, "EthylAcetate"].fix(100.0)
    m.fs.sb.inlet.conc_mol_comp[0, "SodiumAcetate"].fix(0.0)
    m.fs.sb.inlet.conc_mol_comp[0, "Ethanol"].fix(0.0)

    m.fs.sb.inlet.temperature.fix(303.15)
    m.fs.sb.inlet.pressure.fix(101325.0)

    m.fs.sb.split_fraction[0, "outlet_1"].fix(0.2)

    assert degrees_of_freedom(m) == 0

    m.fs.sb.initialize(outlvl=5, optarg={'tol': 1e-6})

    assert (pytest.approx(0.2, abs=1e-3) ==
             m.fs.sb.split_fraction[0, "outlet_1"].value)
    assert (pytest.approx(0.8, abs=1e-3) ==
             m.fs.sb.split_fraction[0, "outlet_2"].value)

    assert (pytest.approx(101325.0, abs=1e-2) ==
            m.fs.sb.outlet_1.pressure[0].value)
    assert (pytest.approx(303.15, abs=1e-2) ==
            m.fs.sb.outlet_1.temperature[0].value)
    assert (pytest.approx(2e-4, abs=1e-6) ==
            m.fs.sb.outlet_1.flow_vol[0].value)
    assert (pytest.approx(55388.0, abs=1e-2) ==
            m.fs.sb.outlet_1.conc_mol_comp[0, "H2O"].value)
    assert (pytest.approx(100.0, abs=1e-2) ==
            m.fs.sb.outlet_1.conc_mol_comp[0, "NaOH"].value)
    assert (pytest.approx(100.0, abs=1e-2) ==
            m.fs.sb.outlet_1.conc_mol_comp[0, "EthylAcetate"].value)
    assert (pytest.approx(0.0, abs=1e-2) ==
            m.fs.sb.outlet_1.conc_mol_comp[0, "SodiumAcetate"].value)
    assert (pytest.approx(0.0, abs=1e-2) ==
            m.fs.sb.outlet_1.conc_mol_comp[0, "Ethanol"].value)

    assert (pytest.approx(101325.0, abs=1e-2) ==
            m.fs.sb.outlet_2.pressure[0].value)
    assert (pytest.approx(303.15, abs=1e-2) ==
            m.fs.sb.outlet_2.temperature[0].value)
    assert (pytest.approx(8e-4, abs=1e-6) ==
            m.fs.sb.outlet_2.flow_vol[0].value)
    assert (pytest.approx(55388.0, abs=1e-2) ==
            m.fs.sb.outlet_2.conc_mol_comp[0, "H2O"].value)
    assert (pytest.approx(100.0, abs=1e-2) ==
            m.fs.sb.outlet_2.conc_mol_comp[0, "NaOH"].value)
    assert (pytest.approx(100.0, abs=1e-2) ==
            m.fs.sb.outlet_2.conc_mol_comp[0, "EthylAcetate"].value)
    assert (pytest.approx(0.0, abs=1e-2) ==
            m.fs.sb.outlet_2.conc_mol_comp[0, "SodiumAcetate"].value)
    assert (pytest.approx(0.0, abs=1e-2) ==
            m.fs.sb.outlet_2.conc_mol_comp[0, "Ethanol"].value)
    def initialize(blk,
                   flow_mol_comp=None,
                   temperature=None,
                   pressure=None,
                   hold_state=False,
                   outlvl=0,
                   state_vars_fixed=False,
                   solver='ipopt',
                   optarg={'tol': 1e-8}):
        '''
        Initialisation routine for property package.

        Keyword Arguments:
            flow_mol_comp : value at which to initialize component flows
                             (default=None)
            pressure : value at which to initialize pressure (default=None)
            temperature : value at which to initialize temperature
                          (default=None)
            outlvl : sets output level of initialisation routine

                     * 0 = no output (default)
                     * 1 = return solver state for each step in routine
                     * 2 = include solver output infomation (tee=True)
            state_vars_fixed: Flag to denote if state vars have already been
                              fixed.
                              - True - states have already been fixed by the
                                       control volume 1D. Control volume 0D
                                       does not fix the state vars, so will
                                       be False if this state block is used
                                       with 0D blocks.
                             - False - states have not been fixed. The state
                                       block will deal with fixing/unfixing.
            optarg : solver options dictionary object (default=None)
            solver : str indicating whcih solver to use during
                     initialization (default = 'ipopt')
            hold_state : flag indicating whether the initialization routine
                         should unfix any state variables fixed during
                         initialization (default=False).
                         - True - states varaibles are not unfixed, and
                                 a dict of returned containing flags for
                                 which states were fixed during
                                 initialization.
                        - False - state variables are unfixed after
                                 initialization by calling the
                                 relase_state method

        Returns:
            If hold_states is True, returns a dict containing flags for
            which states were fixed during initialization.
        '''
        if state_vars_fixed is False:
            # Fix state variables if not already fixed
            Fcflag = {}
            Pflag = {}
            Tflag = {}

            for k in blk.keys():
                for j in blk[k]._params.component_list:
                    if blk[k].flow_mol_comp[j].fixed is True:
                        Fcflag[k, j] = True
                    else:
                        Fcflag[k, j] = False
                        if flow_mol_comp is None:
                            blk[k].flow_mol_comp[j].fix(1.0)
                        else:
                            blk[k].flow_mol_comp[j].fix(flow_mol_comp[j])

                if blk[k].pressure.fixed is True:
                    Pflag[k] = True
                else:
                    Pflag[k] = False
                    if pressure is None:
                        blk[k].pressure.fix(101325.0)
                    else:
                        blk[k].pressure.fix(pressure)

                if blk[k].temperature.fixed is True:
                    Tflag[k] = True
                else:
                    Tflag[k] = False
                    if temperature is None:
                        blk[k].temperature.fix(1500.0)
                    else:
                        blk[k].temperature.fix(temperature)

                for j in blk[k]._params.component_list:
                    blk[k].mole_frac[j] = \
                        (value(blk[k].flow_mol_comp[j]) /
                         sum(value(blk[k].flow_mol_comp[i])
                             for i in blk[k]._params.component_list))

            # If input block, return flags, else release state
            flags = {"Fcflag": Fcflag, "Pflag": Pflag, "Tflag": Tflag}

        else:
            # Check when the state vars are fixed already result in dof 0
            for k in blk.keys():
                if degrees_of_freedom(blk[k]) != 0:
                    raise Exception("State vars fixed but degrees of freedom "
                                    "for state block is not zero during "
                                    "initialization.")
        # Set solver options
        if outlvl > 1:
            stee = True
        else:
            stee = False

        opt = SolverFactory(solver)
        opt.options = optarg

        # ---------------------------------------------------------------------
        # Initialise values
        for k in blk.keys():
            for j in blk[k]._params.component_list:

                if hasattr(blk[k], "cp_shomate_eqn"):
                    calculate_variable_from_constraint(
                        blk[k].cp_mol_comp[j], blk[k].cp_shomate_eqn[j])

                if hasattr(blk[k], "enthalpy_shomate_eqn"):
                    calculate_variable_from_constraint(
                        blk[k].enth_mol_phase_comp["Vap", j],
                        blk[k].enthalpy_shomate_eqn[j])

                if hasattr(blk[k], "entropy_shomate_eqn"):
                    calculate_variable_from_constraint(
                        blk[k].entr_mol_phase_comp["Vap", j],
                        blk[k].entropy_shomate_eqn[j])

                if hasattr(blk[k], "partial_gibbs_energy_eqn"):
                    calculate_variable_from_constraint(
                        blk[k].gibbs_mol_phase_comp["Vap", j],
                        blk[k].partial_gibbs_energy_eqn[j])

            if hasattr(blk[k], "ideal_gas"):
                calculate_variable_from_constraint(
                    blk[k].dens_mol_phase["Vap"], blk[k].ideal_gas)

            if hasattr(blk[k], "mixture_heat_capacity_eqn"):
                calculate_variable_from_constraint(
                    blk[k].cp_mol, blk[k].mixture_heat_capacity_eqn)

            if hasattr(blk[k], "mixture_enthalpy_eqn"):
                calculate_variable_from_constraint(blk[k].enth_mol,
                                                   blk[k].mixture_enthalpy_eqn)

            if hasattr(blk[k], "mixture_entropy_eqn"):
                calculate_variable_from_constraint(blk[k].entr_mol,
                                                   blk[k].mixture_entropy_eqn)

            if hasattr(blk[k], "total_flow_eqn"):
                calculate_variable_from_constraint(blk[k].flow_mol,
                                                   blk[k].total_flow_eqn)

            if hasattr(blk[k], "mixture_gibbs_eqn"):
                calculate_variable_from_constraint(blk[k].gibbs_mol,
                                                   blk[k].mixture_gibbs_eqn)

        results = solve_indexed_blocks(opt, blk, tee=stee)

        if outlvl > 0:
            if results.solver.termination_condition \
                    == TerminationCondition.optimal:
                _log.info('{} Initialisation Step 1 Complete.'.format(
                    blk.name))
            else:
                _log.warning('{} Initialisation Step 1 Failed.'.format(
                    blk.name))

        # ---------------------------------------------------------------------
        if outlvl > 0:
            if outlvl > 0:
                _log.info('{} Initialisation Complete.'.format(blk.name))

        if state_vars_fixed is False:
            if hold_state is True:
                return flags
            else:
                blk.release_state(flags)
Beispiel #30
0
    def initialize(self,
                   state_args={},
                   outlvl=0,
                   solver='ipopt',
                   optarg={
                       'tol': 1e-6,
                       'max_iter': 30
                   }):
        """
        Initialize the turbine stage model.  This deactivates the
        specialized constraints, then does the isentropic turbine initialization,
        then reactivates the constraints and solves.

        Args:
            state_args (dict): Initial state for property initialization
            outlvl (int): Amount of output (0 to 3) 0 is lowest
            solver (str): Solver to use for initialization
            optarg (dict): Solver arguments dictionary
        """
        stee = True if outlvl >= 3 else False
        # sp is what to save to make sure state after init is same as the start
        #   saves value, fixed, and active state, doesn't load originally free
        #   values, this makes sure original problem spec is same but initializes
        #   the values of free vars
        sp = StoreSpec.value_isfixed_isactive(only_fixed=True)
        istate = to_json(self, return_dict=True, wts=sp)

        # fix inlet and free outlet
        for t in self.flowsheet().config.time:
            for k, v in self.inlet.vars.items():
                v[t].fix()
            for k, v in self.outlet.vars.items():
                v[t].unfix()
            # If there isn't a good guess for efficiency or outlet pressure
            # provide something reasonable.
            eff = self.efficiency_isentropic[t]
            eff.fix(
                eff.value if value(eff) > 0.3 and value(eff) < 1.0 else 0.8)
            # for outlet pressure try outlet pressure, pressure ratio, delta P,
            # then if none of those look reasonable use a pressure ratio of 0.8
            # to calculate outlet pressure
            Pout = self.outlet.pressure[t]
            Pin = self.inlet.pressure[t]
            prdp = value((self.deltaP[t] - Pin) / Pin)
            if self.deltaP[t].fixed:
                Pout.value = value(Pin - Pout)
            if self.ratioP[t].fixed:
                Pout.value = value(self.ratioP[t] * Pin)
            if value(Pout / Pin) > 0.99 or value(Pout / Pin) < 0.1:
                if value(self.ratioP[t]) < 0.99 and value(
                        self.ratioP[t]) > 0.1:
                    Pout.fix(value(Pin * self.ratioP[t]))
                elif prdp < 0.99 and prdp > 0.1:
                    Pout.fix(value(prdp * Pin))
                else:
                    Pout.fix(value(Pin * 0.8))
            else:
                Pout.fix()
            self.deltaP[t] = value(Pout - Pin)
            self.ratioP[t] = value(Pout / Pin)

        self.deltaP[:].unfix()
        self.ratioP[:].unfix()

        for t in self.flowsheet().config.time:
            self.properties_isentropic[t].pressure.value = \
                value(self.outlet.pressure[t])
            self.properties_isentropic[t].flow_mol.value = \
                value(self.inlet.flow_mol[t])
            self.properties_isentropic[t].enth_mol.value = \
                value(self.inlet.enth_mol[t]*0.95)
            self.outlet.flow_mol[t].value = \
                value(self.inlet.flow_mol[t])
            self.outlet.enth_mol[t].value = \
                value(self.inlet.enth_mol[t]*0.95)

        # Make sure the initialization problem has no degrees of freedom
        # This shouldn't happen here unless there is a bug in this
        dof = degrees_of_freedom(self)
        try:
            assert (dof == 0)
        except:
            _log.exception("degrees_of_freedom = {}".format(dof))
            raise

        # one bad thing about reusing this is that the log messages aren't
        # really compatible with being nested inside another initialization
        super(TurbineStageData, self).initialize(state_args=state_args,
                                                 outlvl=outlvl,
                                                 solver=solver,
                                                 optarg=optarg)

        # reload original spec
        from_json(self, sd=istate, wts=sp)