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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)