Example #1
0
    def test_k_rxn(self):
        m = self._make_model()
        rxn_block = m.fs.reaction_block

        n_scen = 4
        mols = pyunits.mol/pyunits.s
        kgs = pyunits.kg/pyunits.s
        K = pyunits.K
        bar = pyunits.bar
        state_values = {
            "gas_state.flow_mol": [1.0*mols]*n_scen,
            "solid_state.flow_mass": [1.0*kgs]*n_scen,
            "gas_state.temperature": [1000.0*K, 1100.0*K, 1200.0*K, 1300.0*K],
            "solid_state.temperature": [1000.0*K, 1100.0*K, 1200.0*K, 1300.0*K],
            "gas_state.pressure": [1.0*bar]*n_scen,
            "solid_state.particle_porosity": [0.27]*n_scen,
            "gas_state.mole_frac_comp[O2]": [0.25]*n_scen,
            "gas_state.mole_frac_comp[N2]": [0.25]*n_scen,
            "gas_state.mole_frac_comp[H2O]": [0.25]*n_scen,
            "gas_state.mole_frac_comp[CO2]": [0.25]*n_scen,
            "solid_state.mass_frac_comp[Fe2O3]": [1.0/3.0]*n_scen,
            "solid_state.mass_frac_comp[Fe3O4]": [1.0/3.0]*n_scen,
            "solid_state.mass_frac_comp[Al2O3]": [1.0/3.0]*n_scen,
            }
        state_values = ComponentMap((m.fs.find_component(name), values)
                for name, values in state_values.items())

        # Units of k_rxn are "non-physical" si units, chosen to be
        # consistent with the reaction rate rule.
        target_values = {
                "reaction_block.k_rxn[R1]": [
                    5.7556e-5,
                    6.7076e-5,
                    7.6203e-5,
                    8.4888e-5,
                    ],
                }
        target_values = ComponentMap((m.fs.find_component(name), values)
                for name, values in target_values.items())

        assert degrees_of_freedom(m.fs) == 0

        param_sweeper = ParamSweeper(n_scen, state_values,
                output_values=target_values)
        with param_sweeper:
            for inputs, outputs in param_sweeper:
                solve_strongly_connected_components(m.fs)

                # Make sure property equalites have been converged
                assert number_large_residuals(m.fs, tol=1e-8) == 0

                # Sanity checks that inputs are properly set
                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), rel=1e-3)

                # Make sure properties have been calculated as expected
                for var, val in outputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), rel=1e-3)
Example #2
0
    def test_mw(self):
        m = self._make_model()
        state = m.fs.state

        # Define a somewhat arbitrary set of values we'd like to use to
        # test molecular weight.
        n_scenario = 7
        state_values = {
            "flow_mol": [1.0 * pyunits.mol / pyunits.s] * n_scenario,
            "temperature": [300.0 * pyunits.K] * n_scenario,
            "pressure": [1.0 * pyunits.bar] * n_scenario,
            "mole_frac_comp[O2]": [1.0, 0.5, 0.25, 0.0, 0.0, 0.0, 0.0],
            "mole_frac_comp[N2]": [0.0, 0.5, 0.25, 1.0, 0.0, 0.0, 0.0],
            "mole_frac_comp[H2O]": [0.0, 0.0, 0.25, 0.0, 1.0, 0.0, 0.5],
            "mole_frac_comp[CO2]": [0.0, 0.0, 0.25, 0.0, 0.0, 1.0, 0.5],
        }
        state_values = ComponentMap((state.find_component(name), values)
                                    for name, values in state_values.items())
        target_values = {
            "mw": [
                32.0 * pyunits.g / pyunits.mol,
                30.0 * pyunits.g / pyunits.mol,
                30.5 * pyunits.g / pyunits.mol,
                28.0 * pyunits.g / pyunits.mol,
                18.0 * pyunits.g / pyunits.mol,
                44.0 * pyunits.g / pyunits.mol,
                31.0 * pyunits.g / pyunits.mol,
            ]
        }
        target_values = ComponentMap((state.find_component(name), values)
                                     for name, values in target_values.items())

        # Construct mw and all prerequisites
        state.mw

        param_sweeper = ParamSweeper(
            n_scenario,
            state_values,
            output_values=target_values,
        )
        with param_sweeper:
            for inputs, target in param_sweeper:
                solve_strongly_connected_components(state)

                # Check that state block has been been solved correctly
                assert number_large_residuals(state, tol=1e-8) == 0

                # Sanity check that inputs have been set properly
                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(val, abs=1e-8)

                # Check that the state block computes the property values
                # we expect
                for var, val in target.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(val, abs=1e-8)
Example #3
0
    def test_dens_mass_particle(self):
        m = self._make_model()
        state = m.fs.state

        n_scen = 3
        state_values = {
            "flow_mass": [1.0 * pyunits.kg / pyunits.s] * n_scen,
            "temperature": [1200.0 * pyunits.K] * n_scen,
            "particle_porosity": [0.22, 0.27, 0.32],
            "mass_frac_comp[Fe2O3]": [1.0 / 3.0] * n_scen,
            "mass_frac_comp[Fe3O4]": [1.0 / 3.0] * n_scen,
            "mass_frac_comp[Al2O3]": [1.0 / 3.0] * n_scen,
        }
        state_values = ComponentMap((state.find_component(name), values)
                                    for name, values in state_values.items())
        kgm3 = pyunits.kg / pyunits.m**3
        target_values = {
            "dens_mass_particle": [
                3648.888 * kgm3,
                3414.985 * kgm3,
                3181.081 * kgm3,
            ],
        }
        target_values = ComponentMap((state.find_component(name), values)
                                     for name, values in target_values.items())

        param_sweeper = ParamSweeper(
            n_scen,
            state_values,
            output_values=target_values,
        )
        with param_sweeper:
            for inputs, outputs in param_sweeper:
                solve_strongly_connected_components(state)

                # Check that we have eliminated infeasibility
                assert number_large_residuals(state, tol=1e-8) == 0

                # Sanity check that inputs have been set properly
                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)

                for var, val in outputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)
Example #4
0
    def test_dens_mass_skeletal(self):
        m = self._make_model()
        state = m.fs.state

        n_scen = 4
        state_values = {
            "flow_mass": [1.0 * pyunits.kg / pyunits.s] * n_scen,
            "temperature": [1200.0 * pyunits.K] * n_scen,
            "particle_porosity": [0.27] * n_scen,
            "mass_frac_comp[Fe2O3]": [1.0, 0.0, 0.0, 1.0 / 3.0],
            "mass_frac_comp[Fe3O4]": [0.0, 1.0, 0.0, 1.0 / 3.0],
            "mass_frac_comp[Al2O3]": [0.0, 0.0, 1.0, 1.0 / 3.0],
        }
        state_values = ComponentMap((state.find_component(name), values)
                                    for name, values in state_values.items())
        kgm3 = pyunits.kg / pyunits.m**3
        target_values = {
            "dens_mass_skeletal": [
                5250.000 * kgm3,
                5000.000 * kgm3,
                3987.000 * kgm3,
                4678.061 * kgm3,
            ],
        }
        target_values = ComponentMap((state.find_component(name), values)
                                     for name, values in target_values.items())

        param_sweeper = ParamSweeper(
            n_scen,
            state_values,
            output_values=target_values,
        )
        with param_sweeper:
            for inputs, outputs in param_sweeper:
                solve_strongly_connected_components(state)

                assert number_large_residuals(state, tol=1e-8) == 0

                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)

                for var, val in outputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)
Example #5
0
def initialize_steady(m):
    """
    This is my approach for initializing the steady state model.
    Set state variables to their inlet values, except gas temperature,
    which is initialized to the temperature of the solid inlet.
    Then deactivate discretization equations and strongly connected
    component decomposition.
    """
    gas_inlet_names = set_gas_values_to_inlets(m)
    solid_inlet_names = set_solid_values_to_inlets(m)
    set_gas_temperature_to_solid_inlet(m)

    gas_phase = m.fs.MB.gas_phase
    solid_phase = m.fs.MB.solid_phase
    gas_length = m.fs.MB.gas_phase.length_domain
    solid_length = m.fs.MB.solid_phase.length_domain
    gas_disc_eqs = [
        con for _, con, _ in generate_discretization_components_along_set(
            m, gas_length)
    ]
    solid_disc_eqs = [
        con for _, con, _ in generate_discretization_components_along_set(
            m, solid_length)
    ]

    gas_sum_eqn_slice = gas_phase.properties[:, :].sum_component_eqn
    gas_sum_eqn_slice.attribute_errors_generate_exceptions = False
    solid_sum_eqn_slice = solid_phase.properties[:, :].sum_component_eqn
    solid_sum_eqn_slice.attribute_errors_generate_exceptions = False

    to_deactivate = []
    to_deactivate.extend(gas_sum_eqn_slice)
    to_deactivate.extend(solid_sum_eqn_slice)
    to_deactivate.extend(gas_disc_eqs)
    to_deactivate.extend(solid_disc_eqs)

    to_fix = []
    for name in gas_inlet_names + solid_inlet_names:
        ref = m.find_component(name)
        to_fix.extend(ref.values())

    with TemporarySubsystemManager(to_fix=to_fix, to_deactivate=to_deactivate):
        solve_strongly_connected_components(m)
Example #6
0
def initialize_steady_without_solid_temperature(m):
    """
    """
    gas_inlet_names = set_gas_values_to_inlets(m)
    solid_inlet_names = set_solid_values_to_inlets(m)

    gas_phase = m.fs.MB.gas_phase
    solid_phase = m.fs.MB.solid_phase
    gas_length = m.fs.MB.gas_phase.length_domain
    solid_length = m.fs.MB.solid_phase.length_domain
    gas_disc_eqs = [
        con for _, con, _ in generate_discretization_components_along_set(
            m, gas_length)
    ]
    solid_disc_eqs = [
        con for _, con, _ in generate_discretization_components_along_set(
            m, solid_length)
    ]

    gas_sum_eqn_slice = gas_phase.properties[:, :].sum_component_eqn
    gas_sum_eqn_slice.attribute_errors_generate_exceptions = False
    solid_sum_eqn_slice = solid_phase.properties[:, :].sum_component_eqn
    solid_sum_eqn_slice.attribute_errors_generate_exceptions = False

    to_deactivate = []
    to_deactivate.extend(gas_sum_eqn_slice)
    to_deactivate.extend(solid_sum_eqn_slice)
    to_deactivate.extend(gas_disc_eqs)
    to_deactivate.extend(solid_disc_eqs)

    to_fix = []
    for name in gas_inlet_names + solid_inlet_names:
        ref = m.find_component(name)
        to_fix.extend(ref.values())

    with TemporarySubsystemManager(to_fix=to_fix, to_deactivate=to_deactivate):
        solve_strongly_connected_components(m)
Example #7
0
    def test_reaction_rate(self):
        m = self._make_model()
        rxn_block = m.fs.reaction_block

        n_scen = 9
        mols = pyunits.mol/pyunits.s
        kgs = pyunits.kg/pyunits.s
        K = pyunits.K
        bar = pyunits.bar
        state_values = {
            "gas_state.flow_mol": [1.0*mols]*n_scen,
            "solid_state.flow_mass": [1.0*kgs]*n_scen,
            "gas_state.temperature": [1273.0*K]*n_scen,
            "solid_state.temperature": [
                1273.0*K, 1273.0*K, 1273.0*K,
                1273.0*K, 1273.0*K, 1273.0*K,
                1100.0*K, 1200.0*K, 1300.0*K,
                ],
            "gas_state.pressure": [1.0*bar]*n_scen,
            "solid_state.particle_porosity": [0.27]*n_scen,
            "gas_state.mole_frac_comp[O2]":  [
                1.0, 0.7, 0.0, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
                ],
            "gas_state.mole_frac_comp[N2]":  [
                0.0, 0.1, 1/3, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
                ],
            "gas_state.mole_frac_comp[H2O]": [
                0.0, 0.1, 1/3, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
                ],
            "gas_state.mole_frac_comp[CO2]": [
                0.0, 0.1, 1/3, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
                ],
            "solid_state.mass_frac_comp[Fe2O3]": [
                1/3, 1/3, 1/3, 2/3, 0.0, 1/3, 1/3, 1/3, 1/3,
                ],
            "solid_state.mass_frac_comp[Fe3O4]": [
                1/3, 1/3, 1/3, 0.0, 2/3, 1/3, 1/3, 1/3, 1/3,
                ],
            "solid_state.mass_frac_comp[Al2O3]": [1/3]*n_scen,
            }
        state_values = ComponentMap((m.fs.find_component(name), values)
                for name, values in state_values.items())

        molm3s = pyunits.mol/pyunits.m**3/pyunits.s
        target_values = {
                "reaction_block.reaction_rate[R1]": [
                    351.367*molm3s,
                    245.957*molm3s,
                    0.0*molm3s,
                    0.0*molm3s,
                    271.731*molm3s,
                    87.842*molm3s,
                    71.344*molm3s,
                    81.051*molm3s,
                    90.288*molm3s,
                    ],
                }
        target_values = ComponentMap((m.fs.find_component(name), values)
                for name, values in target_values.items())

        assert degrees_of_freedom(m.fs) == 0

        param_sweeper = ParamSweeper(n_scen, state_values,
                output_values=target_values)
        with param_sweeper:
            for inputs, outputs in param_sweeper:
                solve_strongly_connected_components(m.fs)

                # Make sure property equalites have been converged
                assert number_large_residuals(m.fs, tol=1e-8) == 0

                # Sanity checks that inputs are properly set
                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)

                # Make sure properties have been calculated as expected
                for var, val in outputs.items():
                    if value(val) != 0:
                        # To get around Pyomo issue #1627
                        val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)
Example #8
0
    def test_dens_mol(self):
        m = self._make_model()
        state = m.fs.state

        n_scen = 8
        state_values = {
            "flow_mol": [1.0 * pyunits.mol / pyunits.s] * n_scen,
            "temperature": [
                200.0 * pyunits.K,
                300.0 * pyunits.K,
                600.0 * pyunits.K,
                900.0 * pyunits.K,
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
            ],
            "pressure": [
                1.0 * pyunits.bar,
                1.0 * pyunits.bar,
                1.0 * pyunits.bar,
                1.0 * pyunits.bar,
                1.0 * pyunits.bar,
                0.5 * pyunits.bar,
                1.5 * pyunits.bar,
                2.0 * pyunits.bar,
            ],
            "mole_frac_comp[O2]": [0.25] * n_scen,
            "mole_frac_comp[N2]": [0.25] * n_scen,
            "mole_frac_comp[H2O]": [0.25] * n_scen,
            "mole_frac_comp[CO2]": [0.25] * n_scen,
        }
        state_values = ComponentMap((state.find_component(name), values)
                                    for name, values in state_values.items())

        u = pyunits.mol / pyunits.m**3
        target_values = {
            "dens_mol": [
                # Calculated by P*1e5/(T*8.314462618)
                60.136 * u,
                40.091 * u,
                20.045 * u,
                13.364 * u,
                10.023 * u,
                5.011 * u,
                15.034 * u,
                20.045 * u,
            ]
        }
        target_values = ComponentMap((state.find_component(name), values)
                                     for name, values in target_values.items())

        # Construct dens_mol and all prerequisites
        state.dens_mol
        assert_units_consistent(state.ideal_gas)

        param_sweeper = ParamSweeper(n_scen,
                                     state_values,
                                     output_values=target_values)
        with param_sweeper:
            for inputs, target in param_sweeper:
                solve_strongly_connected_components(state)

                # Check that state block equations have been converged
                assert number_large_residuals(state, tol=1e-8) == 0

                # Sanity check that inputs are what we expect
                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(val, abs=1e-3)

                # Check that state block performs the calculations we expect
                for var, val in target.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(val, abs=1e-3)
Example #9
0
    def test_cp(self):
        m = self._make_model()
        state = m.fs.state

        n_scen = 8
        state_values = {
            "flow_mol": [1.0 * pyunits.mol / pyunits.s] * n_scen,
            "temperature": [
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
                300.0 * pyunits.K,
                600.0 * pyunits.K,
                900.0 * pyunits.K,
                1200.0 * pyunits.K,
            ],
            "pressure": [1.0 * pyunits.bar] * n_scen,
            "mole_frac_comp[O2]": [1.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25],
            "mole_frac_comp[N2]": [0.0, 1.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25],
            "mole_frac_comp[H2O]":
            [0.0, 0.0, 1.0, 0.0, 0.25, 0.25, 0.25, 0.25],
            "mole_frac_comp[CO2]":
            [0.0, 0.0, 0.0, 1.0, 0.25, 0.25, 0.25, 0.25],
        }
        state_values = ComponentMap((state.find_component(name), values)
                                    for name, values in state_values.items())

        u = pyunits.kJ / pyunits.mol / pyunits.K
        kJkgK = pyunits.kJ / pyunits.kg / pyunits.K
        target_values = {
            "cp_mol_comp[O2]": [
                0.03566421043844448 * u,
                0.03566421043844444 * u,
                0.03566421043844444 * u,
                0.03566421043844444 * u,
                0.02408660519211111 * u,
                0.031970683705777776 * u,
                0.03435676292601234 * u,
                0.03566421043844444 * u,
            ],
            "cp_mol_comp[N2]": [
                0.03372177593533332 * u,
                0.03372177593533333 * u,
                0.03372177593533333 * u,
                0.03372177593533333 * u,
                0.03059729435133333 * u,
                0.030104019077333333 * u,
                0.03208929344525926 * u,
                0.03372177593533333 * u,
            ],
            "cp_mol_comp[H2O]": [
                0.0437510227322222 * u,
                0.04375102273222223 * u,
                0.04375102273222223 * u,
                0.04375102273222223 * u,
                0.03359738794555556 * u,
                0.036317861208888885 * u,
                0.039997715202839505 * u,
                0.04375102273222223 * u,
            ],
            "cp_mol_comp[CO2]": [
                0.05634605443600005 * u,
                0.056346054436000007 * u,
                0.056346054436000007 * u,
                0.056346054436000007 * u,
                0.037217621149000006 * u,
                0.047317934392 * u,
                0.053001289534111116 * u,
                0.056346054436000007 * u,
            ],
            "cp_mol": [
                0.03566421043844448 * u,
                0.03372177593533333 * u,
                0.04375102273222223 * u,
                0.056346054436000007 * u,
                0.0313747271595 * u,
                0.036427624596 * u,
                0.03986126527705556 * u,
                0.25 * (
                    # Component values at 1200 K have been computed.
                    0.03566421043844444 * u + 0.03372177593533333 * u +
                    0.04375102273222223 * u + 0.056346054436000007 * u),
            ],
            "cp_mass": [
                1.1145065762013922 * kJkgK,
                1.2043491405476134 * kJkgK,
                2.4306123740123473 * kJkgK,
                1.280592146272725 * kJkgK,
                1.0286795790000056 * kJkgK,
                1.194348347409837 * kJkgK,
                1.3069267303952685 * kJkgK,
                1.3892054388688537 * kJkgK,
            ],
        }
        target_values = ComponentMap((state.find_component(name), values)
                                     for name, values in target_values.items())

        # Construct cp_mass and all prerequisites.
        # This constructs cp_mol and cp_mol_comp as well.
        state.cp_mass

        param_sweeper = ParamSweeper(n_scen,
                                     state_values,
                                     output_values=target_values)
        with param_sweeper:
            for inputs, target in param_sweeper:
                solve_strongly_connected_components(state)

                # Make sure property equations have been converged
                assert number_large_residuals(state, tol=1e-8) == 0

                # Sanity check that inputs are properly set
                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)

                # Make sure properties have been calculated as expected
                for var, val in target.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)
Example #10
0
    def test_enth(self):
        m = self._make_model()
        state = m.fs.state

        n_scen = 7
        state_values = {
            "flow_mol": [1.0 * pyunits.mol / pyunits.s] * n_scen,
            "temperature": [
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
                # We do not test enthalpy at 300 K. The Shomate equation
                # we use is not valid below 500 K.
                #300.0*pyunits.K,
                600.0 * pyunits.K,
                900.0 * pyunits.K,
                1200.0 * pyunits.K,
            ],
            "pressure": [1.0 * pyunits.bar] * n_scen,
            "mole_frac_comp[O2]": [1.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25],
            "mole_frac_comp[N2]": [0.0, 1.0, 0.0, 0.0, 0.25, 0.25, 0.25],
            "mole_frac_comp[H2O]": [0.0, 0.0, 1.0, 0.0, 0.25, 0.25, 0.25],
            "mole_frac_comp[CO2]": [0.0, 0.0, 0.0, 1.0, 0.25, 0.25, 0.25],
        }
        state_values = ComponentMap((state.find_component(name), values)
                                    for name, values in state_values.items())

        u = pyunits.kJ / pyunits.mol
        target_values = {
            "enth_mol_comp[O2]": [
                29.760175857866656 * u,
                29.760175857866656 * u,
                29.760175857866656 * u,
                29.760175857866656 * u,
                #0.5175085434916653*u,
                9.248259058533336 * u,
                19.241674269713887 * u,
                29.760175857866656 * u,
            ],
            "enth_mol_comp[N2]": [
                28.1081423656 * u,
                28.1081423656 * u,
                28.1081423656 * u,
                28.1081423656 * u,
                #-0.021818752399997976*u,
                8.8939164816 * u,
                18.223311732266666 * u,
                28.1081423656 * u,
            ],
            "enth_mol_comp[H2O]": [
                34.505905041333335 * u,
                34.505905041333335 * u,
                34.505905041333335 * u,
                34.505905041333335 * u,
                #0.06267505633334736*u,
                10.500564354666665 * u,
                21.939189237444452 * u,
                34.505905041333335 * u,
            ],
            "enth_mol_comp[CO2]": [
                44.474410900800024 * u,
                44.474410900800024 * u,
                44.474410900800024 * u,
                44.474410900800024 * u,
                #0.06585135367498651*u,
                12.906441898799983 * u,
                28.031785067675003 * u,
                44.474410900800024 * u,
            ],
            "enth_mol": [
                29.760175857866656 * u,
                28.1081423656 * u,
                34.505905041333335 * u,
                44.474410900800024 * u,
                #0.15605405027500296*u,
                10.387295448399996 * u,
                21.858990076775 * u,
                0.25 * (29.760175857866656 * u + 28.1081423656 * u +
                        34.505905041333335 * u + 44.474410900800024 * u),
            ],
        }
        target_values = ComponentMap((state.find_component(name), values)
                                     for name, values in target_values.items())

        # Construct enth_mol and all prerequisites, including enth_mol_comp
        state.enth_mol

        param_sweeper = ParamSweeper(n_scen,
                                     state_values,
                                     output_values=target_values)
        with param_sweeper:
            for inputs, target in param_sweeper:
                solve_strongly_connected_components(state)

                # Make sure property equations have been converged
                assert number_large_residuals(state, tol=1e-8) == 0

                # Sanity check that inputs are properly set
                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)

                # Make sure properties have been calculated as expected
                for var, val in target.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)
Example #11
0
    def test_diffusion_comp(self):
        m = self._make_model()
        state = m.fs.state

        n_scen = 11
        bar = pyunits.bar
        K = pyunits.K
        state_values = {
            "flow_mol": [1.0 * pyunits.mol / pyunits.s] * n_scen,
            "temperature": [
                1200.0 * K,
                1200.0 * K,
                1200.0 * K,
                1200.0 * K,
                300.0 * K,
                600.0 * K,
                900.0 * K,
                1200.0 * K,
                1200.0 * K,
                1200.0 * K,
                1200.0 * K,
            ],
            "pressure": [
                1.0 * bar,
                1.0 * bar,
                1.0 * bar,
                1.0 * bar,
                1.0 * bar,
                1.0 * bar,
                1.0 * bar,
                1.0 * bar,
                0.5 * bar,
                1.5 * bar,
                2.0 * bar,
            ],
            "mole_frac_comp[O2]": [
                # Note that diffusivity is not defined for a pure
                # component in itself (zero gradient, zero net diffusion)
                0.90,
                0.025,
                0.025,
                0.025,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25
            ],
            "mole_frac_comp[N2]": [
                0.025, 0.90, 0.025, 0.025, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
                0.25
            ],
            "mole_frac_comp[H2O]": [
                0.025, 0.025, 0.90, 0.025, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
                0.25
            ],
            "mole_frac_comp[CO2]": [
                0.025, 0.025, 0.025, 0.90, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25,
                0.25
            ],
        }
        state_values = ComponentMap((state.find_component(name), values)
                                    for name, values in state_values.items())

        cm = pyunits.cm
        s = pyunits.s
        target_values = {
            # These values look reasonable
            # TODO: Verify with external source.
            "diffusion_comp[O2]": [
                3.11792621830951 * cm**2 / s,
                2.456227751888218 * cm**2 / s,
                3.034740091620132 * cm**2 / s,
                1.9479388404541838 * cm**2 / s,
                0.206691259894311 * cm**2 / s,
                0.6952237580376006 * cm**2 / s,
                1.4134625566198689 * cm**2 / s,
                2.3384446637321363 * cm**2 / s,
                4.676889327464272 * cm**2 / s,
                1.5589631091547582 * cm**2 / s,
                1.1692223318660684 * cm**2 / s,
            ],
            "diffusion_comp[N2]": [
                2.457518754629481 * cm**2 / s,
                3.1383309495574956 * cm**2 / s,
                3.0334118458311523 * cm**2 / s,
                1.9790010245966736 * cm**2 / s,
                0.2080439152537244 * cm**2 / s,
                0.6997735302088169 * cm**2 / s,
                1.422712718932098 * cm**2 / s,
                2.353748212168125 * cm**2 / s,
                4.70749642433625 * cm**2 / s,
                1.5691654747787498 * cm**2 / s,
                1.176874106084062 * cm**2 / s,
            ],
            "diffusion_comp[H2O]": [
                3.0845168350215713 * cm**2 / s,
                3.0811129521516416 * cm**2 / s,
                3.719143107603082 * cm**2 / s,
                2.5051274838003996 * cm**2 / s,
                0.24654668546150185 * cm**2 / s,
                0.8292808959890481 * cm**2 / s,
                1.6860147281349098 * cm**2 / s,
                2.7893573307023156 * cm**2 / s,
                5.578714661404631 * cm**2 / s,
                1.8595715538015434 * cm**2 / s,
                1.3946786653511578 * cm**2 / s,
            ],
            "diffusion_comp[CO2]": [
                1.929322600571961 * cm**2 / s,
                1.9589681584041365 * cm**2 / s,
                2.4422863072776697 * cm**2 / s,
                2.7098612589802444 * cm**2 / s,
                0.17964011927809195 * cm**2 / s,
                0.6042349293467888 * cm**2 / s,
                1.2284727588198259 * cm**2 / s,
                2.0323959442351844 * cm**2 / s,
                4.064791888470369 * cm**2 / s,
                1.3549306294901227 * cm**2 / s,
                1.0161979721175922 * cm**2 / s,
            ],
        }
        target_values = ComponentMap((state.find_component(name), values)
                                     for name, values in target_values.items())

        # Construct diffusion_comp and all prerequisites
        state.diffusion_comp

        assert_units_consistent(state.diffusion_comp_constraint)

        param_sweeper = ParamSweeper(n_scen,
                                     state_values,
                                     output_values=target_values)
        with param_sweeper:
            for inputs, target in param_sweeper:
                solve_strongly_connected_components(state)

                # Make sure property equations have been converged
                assert number_large_residuals(state, tol=1e-8) == 0

                # Sanity check that inputs are properly set
                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)

                # Make sure properties have been calculated as expected
                for var, val in target.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)
Example #12
0
    def test_therm_cond(self):
        m = self._make_model()
        state = m.fs.state

        n_scen = 8
        state_values = {
            "flow_mol": [1.0 * pyunits.mol / pyunits.s] * n_scen,
            "temperature": [
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
                300.0 * pyunits.K,
                600.0 * pyunits.K,
                900.0 * pyunits.K,
                1200.0 * pyunits.K,
            ],
            "pressure": [1.0 * pyunits.bar] * n_scen,
            "mole_frac_comp[O2]": [1.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25],
            "mole_frac_comp[N2]": [0.0, 1.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25],
            "mole_frac_comp[H2O]":
            [0.0, 0.0, 1.0, 0.0, 0.25, 0.25, 0.25, 0.25],
            "mole_frac_comp[CO2]":
            [0.0, 0.0, 0.0, 1.0, 0.25, 0.25, 0.25, 0.25],
        }
        state_values = ComponentMap((state.find_component(name), values)
                                    for name, values in state_values.items())

        u = pyunits.kJ / pyunits.m / pyunits.K / pyunits.s
        target_values = {
            "therm_cond": [
                8.490673044994837e-05 * u,
                7.803113104821915e-05 * u,
                0.0001245121534187936 * u,
                7.844692969560201e-05 * u,
                2.1981943936613706e-05 * u,
                4.567583423706824e-05 * u,
                6.946515568649932e-05 * u,
                9.30078254960681e-05 * u,
            ],
        }
        target_values = ComponentMap((state.find_component(name), values)
                                     for name, values in target_values.items())

        # Construct therm_cond and all prerequisites
        state.therm_cond

        param_sweeper = ParamSweeper(n_scen,
                                     state_values,
                                     output_values=target_values)
        with param_sweeper:
            for inputs, target in param_sweeper:
                solve_strongly_connected_components(state)

                # Make sure property equations have been converged
                assert number_large_residuals(state, tol=1e-8) == 0

                # Sanity check that inputs are properly set
                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)

                # Make sure properties have been calculated as expected
                for var, val in target.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)
Example #13
0
    def test_visc_d(self):
        m = self._make_model()
        state = m.fs.state

        n_scen = 8
        state_values = {
            "flow_mol": [1.0 * pyunits.mol / pyunits.s] * n_scen,
            "temperature": [
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
                1200.0 * pyunits.K,
                300.0 * pyunits.K,
                600.0 * pyunits.K,
                900.0 * pyunits.K,
                1200.0 * pyunits.K,
            ],
            "pressure": [1.0 * pyunits.bar] * n_scen,
            "mole_frac_comp[O2]": [1.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25],
            "mole_frac_comp[N2]": [0.0, 1.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25],
            "mole_frac_comp[H2O]":
            [0.0, 0.0, 1.0, 0.0, 0.25, 0.25, 0.25, 0.25],
            "mole_frac_comp[CO2]":
            [0.0, 0.0, 0.0, 1.0, 0.25, 0.25, 0.25, 0.25],
        }
        state_values = ComponentMap((state.find_component(name), values)
                                    for name, values in state_values.items())

        target_values = {
            "visc_d": [
                # These values were copied after a solve.
                # TODO: Cross-reference with another source.
                5.534440949133228e-05 * pyunits.Pa * pyunits.s,
                4.67667824296429e-05 * pyunits.Pa * pyunits.s,
                4.6232771210527155e-05 * pyunits.Pa * pyunits.s,
                4.512867970060493e-05 * pyunits.Pa * pyunits.s,
                1.6181534595116313e-05 * pyunits.Pa * pyunits.s,
                2.866222939903063e-05 * pyunits.Pa * pyunits.s,
                3.909320395131273e-05 * pyunits.Pa * pyunits.s,
                4.838841106600266e-05 * pyunits.Pa * pyunits.s,
            ]
        }
        target_values = ComponentMap((state.find_component(name), values)
                                     for name, values in target_values.items())

        # Construct visc_d and all prerequisites
        state.visc_d

        param_sweeper = ParamSweeper(n_scen,
                                     state_values,
                                     output_values=target_values)
        with param_sweeper:
            for inputs, target in param_sweeper:
                solve_strongly_connected_components(state)

                # Make sure property equations have been converged
                assert number_large_residuals(state, tol=1e-8) == 0

                # Sanity check that inputs are properly set
                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)

                # Make sure properties have been calculated as expected
                for var, val in target.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)
Example #14
0
    def test_dens_mol_comp(self):
        m = self._make_model()
        state = m.fs.state

        n_scen = 5
        state_values = {
            "flow_mol": [1.0 * pyunits.mol / pyunits.s] * n_scen,
            "temperature": [1200.0 * pyunits.K] * n_scen,
            "pressure": [1.0 * pyunits.bar] * n_scen,
            "mole_frac_comp[O2]": [1.0, 0.0, 0.0, 0.0, 0.25],
            "mole_frac_comp[N2]": [0.0, 1.0, 0.0, 0.0, 0.25],
            "mole_frac_comp[H2O]": [0.0, 0.0, 1.0, 0.0, 0.25],
            "mole_frac_comp[CO2]": [0.0, 0.0, 0.0, 1.0, 0.25],
        }
        state_values = ComponentMap((state.find_component(name), values)
                                    for name, values in state_values.items())

        u = pyunits.mol / pyunits.m**3
        target_values = {
            "dens_mol": [10.023 * u] * n_scen,
            "dens_mol_comp[O2]": [
                10.023 * u,
                0.0 * u,
                0.0 * u,
                0.0 * u,
                0.25 * 10.023 * u,
            ],
            "dens_mol_comp[N2]": [
                0.0 * u,
                10.023 * u,
                0.0 * u,
                0.0 * u,
                0.25 * 10.023 * u,
            ],
            "dens_mol_comp[H2O]": [
                0.0 * u,
                0.0 * u,
                10.023 * u,
                0.0 * u,
                0.25 * 10.023 * u,
            ],
            "dens_mol_comp[CO2]": [
                0.0 * u,
                0.0 * u,
                0.0 * u,
                10.023 * u,
                0.25 * 10.023 * u,
            ],
        }
        target_values = ComponentMap((state.find_component(name), values)
                                     for name, values in target_values.items())

        # Construct dens_mol_comp and all prerequisites
        state.dens_mol_comp

        param_sweeper = ParamSweeper(n_scen,
                                     state_values,
                                     output_values=target_values)
        with param_sweeper:
            for inputs, target in param_sweeper:
                solve_strongly_connected_components(state)

                # Make sure property equations have been converged
                assert number_large_residuals(state, tol=1e-8) == 0

                # Sanity check that inputs have been set properly
                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    # ^ Problem converting units when value is zero
                    assert var.value == pytest.approx(value(val), abs=1e-3)

                # Make sure property values are what we expect
                for var, val in target.items():
                    #val = value(pyunits.convert(val, var.get_units()))
                    # ^ Problem converting units when value is zero
                    assert var.value == pytest.approx(value(val), abs=1e-3)
Example #15
0
    def test_oc_conv(self):
        m = self._make_model()
        rxn_block = m.fs.reaction_block

        n_scen = 3
        mols = pyunits.mol/pyunits.s
        kgs = pyunits.kg/pyunits.s
        K = pyunits.K
        bar = pyunits.bar
        state_values = {
            "gas_state.flow_mol": [1.0*mols]*n_scen,
            "solid_state.flow_mass": [1.0*kgs]*n_scen,
            "gas_state.temperature": [1273.0*K]*n_scen,
            "solid_state.temperature": [1273.0*K]*n_scen,
            "gas_state.pressure": [1.0*bar]*n_scen,
            "solid_state.particle_porosity": [0.27]*n_scen,
            "gas_state.mole_frac_comp[O2]": [0.25]*n_scen,
            "gas_state.mole_frac_comp[N2]": [0.25]*n_scen,
            "gas_state.mole_frac_comp[H2O]": [0.25]*n_scen,
            "gas_state.mole_frac_comp[CO2]": [0.25]*n_scen,
            "solid_state.mass_frac_comp[Fe2O3]": [2/3, 0.0, 1/3],
            "solid_state.mass_frac_comp[Fe3O4]": [0.0, 2/3, 1/3],
            "solid_state.mass_frac_comp[Al2O3]": [1/3]*n_scen,
            }
        state_values = ComponentMap((m.fs.find_component(name), values)
                for name, values in state_values.items())

        target_values = {
                "reaction_block.OC_conv": [
                    1.0,
                    0.0,
                    0.4915,
                    ],
                "reaction_block.OC_conv_temp": [
                    2.005e-4,
                    1.0,
                    0.6371,
                    ],
                }
        target_values = ComponentMap((m.fs.find_component(name), values)
                for name, values in target_values.items())

        assert degrees_of_freedom(m.fs) == 0

        param_sweeper = ParamSweeper(n_scen, state_values,
                output_values=target_values)
        with param_sweeper:
            for inputs, outputs in param_sweeper:
                solve_strongly_connected_components(m.fs)

                # Make sure property equalites have been converged
                assert number_large_residuals(m.fs, tol=1e-8) == 0

                # Sanity checks that inputs are properly set
                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)

                # Make sure properties have been calculated as expected
                for var, val in outputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)
Example #16
0
    def test_cp(self):
        m = self._make_model()
        state = m.fs.state

        n_scen = 4
        K = pyunits.K
        state_values = {
            "flow_mass": [1.0 * pyunits.kg / pyunits.s] * n_scen,
            "temperature": [1000.0 * K, 1100 * K, 1200 * K, 1300 * K],
            "particle_porosity": [0.27] * n_scen,
            "mass_frac_comp[Fe2O3]": [1.0 / 3.0] * n_scen,
            "mass_frac_comp[Fe3O4]": [1.0 / 3.0] * n_scen,
            "mass_frac_comp[Al2O3]": [1.0 / 3.0] * n_scen,
        }
        state_values = ComponentMap((state.find_component(name), values)
                                    for name, values in state_values.items())
        kJmolK = pyunits.kJ / pyunits.mol / pyunits.K
        kJkgK = pyunits.kJ / pyunits.kg / pyunits.K
        target_values = {
            "cp_mol_comp[Fe2O3]": [
                0.1401 * kJmolK,
                0.1408 * kJmolK,
                0.1415 * kJmolK,
                0.1423 * kJmolK,
            ],
            "cp_mol_comp[Fe3O4]": [
                0.2008 * kJmolK,
                0.2008 * kJmolK,
                0.2008 * kJmolK,
                0.2008 * kJmolK,
            ],
            "cp_mol_comp[Al2O3]": [
                0.1249 * kJmolK,
                0.1268 * kJmolK,
                0.1285 * kJmolK,
                0.1299 * kJmolK,
            ],
            "cp_mass": [
                0.9899 * kJkgK,
                0.9975 * kJkgK,
                1.0045 * kJkgK,
                1.0108 * kJkgK,
            ],
        }
        target_values = ComponentMap((state.find_component(name), values)
                                     for name, values in target_values.items())

        param_sweeper = ParamSweeper(
            n_scen,
            state_values,
            output_values=target_values,
        )
        with param_sweeper:
            for inputs, outputs in param_sweeper:
                solve_strongly_connected_components(state)

                # Check that we have eliminated infeasibility
                assert number_large_residuals(state, tol=1e-8) == 0

                # Sanity check that inputs have been set properly
                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)

                for var, val in outputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)
Example #17
0
    def test_enth(self):
        m = self._make_model()
        state = m.fs.state

        n_scen = 4
        K = pyunits.K
        state_values = {
            "flow_mass": [1.0 * pyunits.kg / pyunits.s] * n_scen,
            "temperature": [1000.0 * K, 1100 * K, 1200 * K, 1300 * K],
            "particle_porosity": [0.27] * n_scen,
            "mass_frac_comp[Fe2O3]": [1.0 / 3.0] * n_scen,
            "mass_frac_comp[Fe3O4]": [1.0 / 3.0] * n_scen,
            "mass_frac_comp[Al2O3]": [1.0 / 3.0] * n_scen,
        }
        state_values = ComponentMap((state.find_component(name), values)
                                    for name, values in state_values.items())
        kJmol = pyunits.kJ / pyunits.mol
        kJkg = pyunits.kJ / pyunits.kg
        target_values = {
            "enth_mol_comp[Fe2O3]": [
                101.043 * kJmol,
                115.086 * kJmol,
                129.198 * kJmol,
                143.385 * kJmol,
            ],
            "enth_mol_comp[Fe3O4]": [
                147.591 * kJmol,
                167.674 * kJmol,
                187.757 * kJmol,
                207.841 * kJmol,
            ],
            "enth_mol_comp[Al2O3]": [
                77.925 * kJmol,
                90.513 * kJmol,
                103.279 * kJmol,
                116.199 * kJmol,
            ],
            "enth_mass": [
                678.156 * kJkg,
                777.534 * kJkg,
                877.640 * kJkg,
                978.408 * kJkg,
            ],
        }
        target_values = ComponentMap((state.find_component(name), values)
                                     for name, values in target_values.items())

        param_sweeper = ParamSweeper(
            n_scen,
            state_values,
            output_values=target_values,
        )
        with param_sweeper:
            for inputs, outputs in param_sweeper:
                solve_strongly_connected_components(state)

                # Check that we have eliminated infeasibility
                assert number_large_residuals(state, tol=1e-8) == 0

                # Sanity check that inputs have been set properly
                for var, val in inputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)

                for var, val in outputs.items():
                    val = value(pyunits.convert(val, var.get_units()))
                    assert var.value == pytest.approx(value(val), abs=1e-3)