Пример #1
0
def test_initialize():
    '''Very rough test, just to make sure degrees of freedom are not violated.
    '''
    mod = make_model(horizon=2, ntfe=20, ntcp=1, inlet_E=11.91, inlet_S=12.92)

    assert degrees_of_freedom(mod) == 0

    originally_active = ComponentMap([
        (comp, comp.active)
        for comp in mod.component_data_objects((Block, Constraint))
    ])
    originally_fixed = ComponentMap([
        (var, var.fixed) for var in mod.component_data_objects(Var)
    ])

    initialize_by_time_element(mod.fs,
                               mod.fs.time,
                               solver=solver,
                               outlvl=idaeslog.DEBUG,
                               fix_diff_only=False)
    assert degrees_of_freedom(mod) == 0

    for comp in mod.component_data_objects((Block, Constraint)):
        assert comp.active == originally_active[comp]
    for var in mod.component_data_objects(Var):
        assert var.fixed == originally_fixed[var]
Пример #2
0
    def test_initialize(self, iron_oc):
        optarg = {
                 "bound_push": 1e-8,
                 'halt_on_ampl_error': 'yes',
                 'linear_solver': 'ma27'
                  }

        initialization_tester(iron_oc)

        solver = get_solver('ipopt', optarg)  # create solver

        initialize_by_time_element(iron_oc.fs, iron_oc.fs.time, solver=solver)
Пример #3
0
def test_initialize_by_time_element():
    horizon = 6
    time_set = [0, horizon]
    ntfe = 60  # For a finite element every six seconds
    ntcp = 2
    m = ConcreteModel(name='CSTR model for testing')
    m.fs = FlowsheetBlock(default={
        'dynamic': True,
        'time_set': time_set,
        'time_units': pyunits.minute
    })

    m.fs.properties = AqueousEnzymeParameterBlock()
    m.fs.reactions = EnzymeReactionParameterBlock(
        default={'property_package': m.fs.properties})
    m.fs.cstr = CSTR(
        default={
            "property_package": m.fs.properties,
            "reaction_package": m.fs.reactions,
            "material_balance_type": MaterialBalanceType.componentTotal,
            "energy_balance_type": EnergyBalanceType.enthalpyTotal,
            "momentum_balance_type": MomentumBalanceType.none,
            "has_heat_of_reaction": True
        })

    # Time discretization
    disc = TransformationFactory('dae.collocation')
    disc.apply_to(m,
                  wrt=m.fs.time,
                  nfe=ntfe,
                  ncp=ntcp,
                  scheme='LAGRANGE-RADAU')

    # Fix geometry variables
    m.fs.cstr.volume[0].fix(1.0)

    # Fix initial conditions:
    for p, j in m.fs.properties.phase_list * m.fs.properties.component_list:
        if j == 'Solvent':
            continue
        m.fs.cstr.control_volume.material_holdup[0, p, j].fix(0)

    # Fix inlet conditions
    # This is a huge hack because I didn't know that the proper way to
    # have multiple inlets to a CSTR was to use a mixer.
    # I 'combine' both my inlet streams before sending them to the CSTR.
    for t, j in m.fs.time * m.fs.properties.component_list:
        if t <= 2:
            if j == 'E':
                m.fs.cstr.inlet.conc_mol[t, j].fix(11.91 * 0.1 / 2.2)
            elif j == 'S':
                m.fs.cstr.inlet.conc_mol[t, j].fix(12.92 * 2.1 / 2.2)
            elif j != 'Solvent':
                m.fs.cstr.inlet.conc_mol[t, j].fix(0)
        elif t <= 4:
            if j == 'E':
                m.fs.cstr.inlet.conc_mol[t, j].fix(5.95 * 0.1 / 2.2)
            elif j == 'S':
                m.fs.cstr.inlet.conc_mol[t, j].fix(12.92 * 2.1 / 2.2)
            elif j != 'Solvent':
                m.fs.cstr.inlet.conc_mol[t, j].fix(0)
        else:
            if j == 'E':
                m.fs.cstr.inlet.conc_mol[t, j].fix(8.95 * 0.1 / 2.2)
            elif j == 'S':
                m.fs.cstr.inlet.conc_mol[t, j].fix(16.75 * 2.1 / 2.2)
            elif j != 'Solvent':
                m.fs.cstr.inlet.conc_mol[t, j].fix(0)

    m.fs.cstr.inlet.conc_mol[:, 'Solvent'].fix(1.)

    m.fs.cstr.inlet.flow_vol.fix(2.2)
    m.fs.cstr.inlet.temperature.fix(300)

    # Fix outlet conditions
    m.fs.cstr.outlet.flow_vol.fix(2.2)
    m.fs.cstr.outlet.temperature[m.fs.time.first()].fix(300)

    assert degrees_of_freedom(m) == 0

    initialize_by_time_element(m.fs, m.fs.time, solver=solver)

    assert degrees_of_freedom(m) == 0

    # Assert that the result looks how we expect
    assert m.fs.cstr.outlet.conc_mol[0, 'S'].value == 0
    assert abs(m.fs.cstr.outlet.conc_mol[2, 'S'].value - 11.389) < 1e-2
    assert abs(m.fs.cstr.outlet.conc_mol[4, 'P'].value - 0.2191) < 1e-3
    assert abs(m.fs.cstr.outlet.conc_mol[6, 'E'].value - 0.0327) < 1e-3
    assert abs(m.fs.cstr.outlet.temperature[6].value - 289.7) < 1

    # Assert that model is still fixed and deactivated as expected
    assert (m.fs.cstr.control_volume.material_holdup[m.fs.time.first(), 'aq',
                                                     'S'].fixed)

    for t in m.fs.time:
        if t != m.fs.time.first():
            assert (not m.fs.cstr.control_volume.material_holdup[t, 'aq',
                                                                 'S'].fixed)

            assert not m.fs.cstr.outlet.temperature[t].fixed
        assert (
            m.fs.cstr.control_volume.material_holdup_calculation[t, 'aq',
                                                                 'C'].active)

        assert m.fs.cstr.control_volume.properties_out[t].active
        assert not m.fs.cstr.outlet.conc_mol[t, 'S'].fixed
        assert m.fs.cstr.inlet.conc_mol[t, 'S'].fixed

    # Assert that constraints are feasible after initialization
    for con in m.fs.component_data_objects(Constraint, active=True):
        assert value(con.body) - value(con.upper) < 1e-5
        assert value(con.lower) - value(con.body) < 1e-5

    results = solver.solve(m.fs)
    assert check_optimal_termination(results)
Пример #4
0
def main(m):
    m.fs = FlowsheetBlock(default={"dynamic": True,
                                   "time_set": [0, 3600],
                                   "time_units": pyunits.s})

    m.fs.gas_props = GasPhaseParameterBlock()
    m.fs.solid_props = SolidPhaseParameterBlock()
    m.fs.solid_rxns = HeteroReactionParameterBlock(
            default={"solid_property_package": m.fs.solid_props,
                     "gas_property_package": m.fs.gas_props})

    m.fs.TGA = FixedBed0D(default={
                    "energy_balance_type": EnergyBalanceType.none,
                    "gas_property_package": m.fs.gas_props,
                    "solid_property_package": m.fs.solid_props,
                    "reaction_package": m.fs.solid_rxns})

    # Discretize time domain
    m.discretizer = TransformationFactory('dae.finite_difference')
    m.discretizer.apply_to(m,
                           nfe=100,
                           wrt=m.fs.time,
                           scheme="BACKWARD")

    # Set reactor design conditions
    m.fs.TGA.bed_diameter.fix(1)  # diameter of the TGA reactor [m]
    m.fs.TGA.bed_height.fix(1)  # height of solids in the TGA reactor [m]

    # Set initial conditions of the solid phase
    m.fs.TGA.solids[0].particle_porosity.fix(0.20)
    m.fs.TGA.solids[0].mass_frac_comp['Fe2O3'].fix(0.45)
    m.fs.TGA.solids[0].mass_frac_comp['Fe3O4'].fix(0)
    m.fs.TGA.solids[0].mass_frac_comp['Al2O3'].fix(0.55)
    m.fs.TGA.solids[0].temperature.fix(1273.15)

    # Set conditions of the gas phase (this is all fixed as gas side assumption
    # is excess gas flowrate which means all state variables remain unchanged)
    for t in m.fs.time:
        m.fs.TGA.gas[t].temperature.fix(1273.15)
        m.fs.TGA.gas[t].pressure.fix(1.01325E5)  # 1atm
        m.fs.TGA.gas[t].mole_frac_comp['CO2'].fix(0.4)
        m.fs.TGA.gas[t].mole_frac_comp['H2O'].fix(0.5)
        m.fs.TGA.gas[t].mole_frac_comp['CH4'].fix(0.1)

    # Solver options
    optarg = {
             "bound_push": 1e-8,
             'halt_on_ampl_error': 'yes',
             'linear_solver': 'ma27'
              }

    t_start = time.time()  # Run start time

    m.fs.TGA.initialize()

    t_initialize = time.time()  # Initialization time

    solver = get_solver('ipopt', optarg)  # create solver

    initialize_by_time_element(m.fs, m.fs.time, solver=solver)
    solver.solve(m, tee=True)

    t_simulation = time.time()  # Simulation time

    print("\n")
    print("----------------------------------------------------------")
    print('Total initialization time: ', value(t_initialize - t_start), " s")
    print("----------------------------------------------------------")

    print("\n")
    print("----------------------------------------------------------")
    print('Total simulation time: ', value(t_simulation - t_start), " s")
    print("----------------------------------------------------------")

    return m