def test_set_values(self): m = _make_simple_model() n_scenario = 2 input_values = ComponentMap([ (m.v3, [1.3, 2.3]), (m.v4, [1.4, 2.4]), ]) to_fix = [m.v3, m.v4] to_deactivate = [m.con1] with ParamSweeper(2, input_values, to_fix=to_fix, to_deactivate=to_deactivate) as sweeper: self.assertFalse(m.v1.fixed) self.assertFalse(m.v2.fixed) self.assertTrue(m.v3.fixed) self.assertTrue(m.v4.fixed) self.assertFalse(m.con1.active) self.assertTrue(m.con2.active) self.assertTrue(m.con3.active) for i, (inputs, outputs) in enumerate(sweeper): self.assertEqual(len(inputs), 2) self.assertEqual(len(outputs), 0) self.assertIn(m.v3, inputs) self.assertIn(m.v4, inputs) for var, val in inputs.items(): self.assertEqual(var.value, val) self.assertEqual(var.value, input_values[var][i]) # Values have been reset after exit. self.assertIs(m.v3.value, None) self.assertIs(m.v4.value, None)
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_with_solve(self): m = _make_simple_model() ipopt = pyo.SolverFactory("ipopt") n_scenario = 2 input_values = ComponentMap([ (m.v3, [1.3, 2.3]), (m.v4, [1.4, 2.4]), ]) _v1_val_1 = pyo.sqrt(3*1.4+1.3) _v1_val_2 = pyo.sqrt(3*2.4+2.3) _v2_val_1 = pyo.sqrt(2*1.4 - _v1_val_1) _v2_val_2 = pyo.sqrt(2*2.4 - _v1_val_2) output_values = ComponentMap([ (m.v1, [_v1_val_1, _v1_val_2]), (m.v2, [_v2_val_1, _v2_val_2]), ]) to_fix = [m.v3, m.v4] to_deactivate = [m.con1] to_reset = [m.v1, m.v2] # Initialize values so we don't fail due to bad initialization m.v1.set_value(1.0) m.v2.set_value(1.0) with ParamSweeper(n_scenario, input_values, output_values, to_fix=to_fix, to_deactivate=to_deactivate, to_reset=to_reset, ) as sweeper: self.assertFalse(m.v1.fixed) self.assertFalse(m.v2.fixed) self.assertTrue(m.v3.fixed) self.assertTrue(m.v4.fixed) self.assertFalse(m.con1.active) self.assertTrue(m.con2.active) self.assertTrue(m.con3.active) for i, (inputs, outputs) in enumerate(sweeper): ipopt.solve(m) for var, val in inputs.items(): # These values should not have been altered. # I believe exact equality should be appropriate here. self.assertEqual(var.value, val) self.assertEqual(var.value, input_values[var][i]) for var, val in outputs.items(): self.assertAlmostEqual(var.value, val, delta=1e-8) self.assertAlmostEqual(var.value, output_values[var][i], delta=1e-8) # Values have been reset after exit. self.assertIs(m.v1.value, 1.0) self.assertIs(m.v2.value, 1.0) self.assertIs(m.v3.value, None) self.assertIs(m.v4.value, None)
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 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_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_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_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_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_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_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_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)
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)