def equilibrium_problem_with_h2o_co2_nacl_halite_dissolved_60C_300bar(): """ Build a problem with H2O, H+, Na+, Cl-, HCO3-, CO2(aq), CO3-- and Halite at 60 °C and 300 bar """ database = Database("supcrt98.xml") editor = ChemicalEditor(database) aqueous = editor.addAqueousPhase( ["H2O(l)", "H+", "OH-", "Na+", "Cl-", "HCO3-", "CO2(aq)", "CO3--", "CO(aq)"] ) aqueous.setActivityModelDrummondCO2() gaseous = editor.addGaseousPhase(["H2O(g)", "CO2(g)"]) gaseous.setChemicalModelSpycherPruessEnnis() editor.addMineralPhase("Halite") system = ChemicalSystem(editor) problem = EquilibriumProblem(system) problem.add("H2O", 1, "kg") problem.add("CO2", 100, "g") problem.add("NaCl", 1, "mol") problem.setTemperature(60, "celsius") problem.setPressure(300, "bar") return (system, problem)
def test_equilibrium_CH4_CO2_H2S_liq_gas(temperature, pressure, num_regression): """ This test checks the capability of solving a ternary mixture with @param Temperature temperature in Kelvin which will be used to compute equilibrium @param Pressure pressure in bar which will be used to compute equilibrium """ db = Database("supcrt98.xml") editor = ChemicalEditor(db) eos_params = CubicEOSParams( phase_identification_method=PhaseIdentificationMethod. GibbsEnergyAndEquationOfStateMethod, ) editor.addGaseousPhase(["CH4(g)", "H2S(g)", "CO2(g)"]).setChemicalModelPengRobinson(eos_params) editor.addLiquidPhase(["CH4(liq)", "H2S(liq)", "CO2(liq)" ]).setChemicalModelPengRobinson(eos_params) system = ChemicalSystem(editor) problem = EquilibriumProblem(system) problem.setTemperature(temperature, "K") problem.setPressure(pressure, "bar") problem.add("CH4(g)", 0.60, "mol") problem.add("H2S(g)", 0.35, "mol") problem.add("CO2(g)", 0.05, "mol") solver = EquilibriumSolver(problem.system()) options = EquilibriumOptions() options.hessian = GibbsHessian.Exact options.nonlinear.max_iterations = 100 options.optimum.max_iterations = 200 options.optimum.ipnewton.step = StepMode.Conservative solver.setOptions(options) state = ChemicalState(system) result = solver.solve(state, problem) assert result.optimum.succeeded species_amount = { "CH4(g)": np.asarray([state.speciesAmount("CH4(g)")]), "H2S(g)": np.asarray([state.speciesAmount("H2S(g)")]), "CO2(g)": np.asarray([state.speciesAmount("CO2(g)")]), "CH4(liq)": np.asarray([state.speciesAmount("CH4(liq)")]), "H2S(liq)": np.asarray([state.speciesAmount("H2S(liq)")]), "CO2(liq)": np.asarray([state.speciesAmount("CO2(liq)")]), } num_regression.check(species_amount)
def equilibrium_problem_using_thermofun_aq17_database(): """ Build a problem using ThermoFun database aq17 """ database = thermofun.Database("databases/thermofun/aq17-thermofun.json") editor = ChemicalEditor(database) editor.setTemperatures([500.0], "celsius") editor.setPressures([3000.0], "bar") editor.addAqueousPhase([ "Al(OH)2+", "Al(OH)3@", "Al(OH)4-", "Al+3", "AlH3SiO4+2", "AlOH+2", "Ca+2", "CaCO3@", "CaCl+", "CaCl2@", "CaHCO3+", "CaHSiO3+", "CaOH+", "CaSiO3@", "K+", "KAlO2@", "KCl@", "KOH@", "KCO3-", "KHCO3@", "Mg+2", "MgCO3@", "MgCl+", "MgCl2@", "MgHCO3+", "MgHSiO3+", "MgOH+", "MgSiO3@", "Na+", "NaAl(OH)4@", "NaCO3-", "NaCl@", "NaHCO3@", "NaHSiO3@", "NaOH@", "HSiO3-", "SiO2@", "CO@", "CO2@", "CO3-2", "HCO3-", "CH4@", "Cl-", "HCl@", "H2@", "O2@", "OH-", "H+", "H2O@" ]) editor.addMineralPhase("Albite") editor.addMineralPhase("Andalusite") editor.addMineralPhase("Calcite") editor.addMineralPhase("Corundum") editor.addMineralPhase("Diopside") editor.addMineralPhase("Dolomite") editor.addMineralPhase("Enstatite") editor.addMineralPhase("Grossular") editor.addMineralPhase("Margarite") editor.addMineralPhase("Microcline") editor.addMineralPhase("Muscovite") editor.addMineralPhase("Pargasite-Mg") editor.addMineralPhase("Phlogopite") editor.addMineralPhase("Quartz") editor.addMineralPhase("Sanidine") editor.addMineralPhase("Sillimanite") editor.addMineralPhase("Zoisite") system = ChemicalSystem(editor) problem = EquilibriumProblem(system) problem.add("H2O", 1000, "g") problem.add("CO2", 0.001, "g") problem.add("CaCO3", 1, "g") problem.add("MgSiO3", 1, "g") problem.add("NaCl", 5, "g") problem.add("NaAlSi3O8", 37, "g") problem.add("KAl3Si3O10(OH)2", 13, "g") problem.add("SiO2", 30, "g") problem.add("KAlSi3O8", 20, "g") problem.setTemperature(500.0, "celsius") problem.setPressure(3000.0, "bar") return (system, problem)
def brine_co2_path(): editor = ChemicalEditor() editor.addAqueousPhaseWithElementsOf("H2O NaCl CaCO3 MgCO3") editor.addGaseousPhase(["H2O(g)", "CO2(g)"]) editor.addMineralPhase("Calcite") editor.addMineralPhase("Magnesite") editor.addMineralPhase("Dolomite") editor.addMineralPhase("Halite") editor.addMineralReaction("Calcite") \ .setEquation("Calcite = Ca++ + CO3--") \ .addMechanism("logk = -5.81 mol/(m2*s); Ea = 23.5 kJ/mol") \ .addMechanism("logk = -0.30 mol/(m2*s); Ea = 14.4 kJ/mol; a[H+] = 1.0") \ .setSpecificSurfaceArea(10, "cm2/g") editor.addMineralReaction("Magnesite") \ .setEquation("Magnesite = Mg++ + CO3--") \ .addMechanism("logk = -9.34 mol/(m2*s); Ea = 23.5 kJ/mol") \ .addMechanism("logk = -6.38 mol/(m2*s); Ea = 14.4 kJ/mol; a[H+] = 1.0") \ .setSpecificSurfaceArea(10, "cm2/g") editor.addMineralReaction("Dolomite") \ .setEquation("Dolomite = Ca++ + Mg++ + 2*CO3--") \ .addMechanism("logk = -7.53 mol/(m2*s); Ea = 52.2 kJ/mol") \ .addMechanism("logk = -3.19 mol/(m2*s); Ea = 36.1 kJ/mol; a[H+] = 0.5") \ .setSpecificSurfaceArea(10, "cm2/g") system = ChemicalSystem(editor) reactions = ReactionSystem(editor) partition = Partition(system) partition.setKineticSpecies(["Calcite", "Magnesite", "Dolomite"]) problem = EquilibriumProblem(system) problem.setPartition(partition) problem.setTemperature(60, "celsius") problem.setPressure(100, "bar") problem.add("H2O", 1, "kg") problem.add("NaCl", 0.5, "mol") problem.add("CO2", 1, "mol") state = equilibrate(problem) state.setSpeciesMass("Calcite", 100, "g") state.setSpeciesMass("Dolomite", 50, "g") path = KineticPath(reactions) path.setPartition(partition) return path, state
def test_equilibrium_H2S_liq_gas(temperature, pressure, num_regression): db = Database("supcrt98.xml") editor = ChemicalEditor(db) eos_params = CubicEOSParams( model=CubicEOSModel.PengRobinson, phase_identification_method=PhaseIdentificationMethod. GibbsEnergyAndEquationOfStateMethod, ) editor.addGaseousPhase(["H2S(g)"]).setChemicalModelCubicEOS(eos_params) editor.addLiquidPhase(["H2S(liq)"]).setChemicalModelCubicEOS(eos_params) system = ChemicalSystem(editor) problem = EquilibriumProblem(system) problem.setTemperature(temperature, "K") problem.setPressure(pressure, "Pa") problem.add("H2S(g)", 1.0, "mol") solver = EquilibriumSolver(problem.system()) options = EquilibriumOptions() options.hessian = GibbsHessian.Exact options.nonlinear.max_iterations = 100 options.optimum.max_iterations = 200 options.optimum.ipnewton.step = StepMode.Conservative options.optimum.tolerance = 1e-17 solver.setOptions(options) state = ChemicalState(system) result = solver.solve(state, problem) assert result.optimum.succeeded species_amounts = { "H2S(g)": np.asarray([state.speciesAmount("H2S(g)")]), "H2S(liq)": np.asarray([state.speciesAmount("H2S(liq)")]), } num_regression.check(species_amounts)
def equilibrium_problem_with_h2o_co2_nacl_halite_60C_300bar(): """ Build a problem with 1 kg of H2O, 100 g of CO2 and 0.1 mol of NaCl at 60 °C and 300 bar """ database = Database("supcrt98.xml") editor = ChemicalEditor(database) editor.addAqueousPhase("H2O NaCl CO2") editor.addGaseousPhase(["H2O(g)", "CO2(g)"]) editor.addMineralPhase("Halite") system = ChemicalSystem(editor) problem = EquilibriumProblem(system) problem.add("H2O", 1, "kg") problem.add("CO2", 100, "g") problem.add("NaCl", 0.1, "mol") problem.setTemperature(60, "celsius") problem.setPressure(300, "bar") return (system, problem)
def test_different_results(state_regression): from reaktoro import ChemicalEditor, ChemicalState, ChemicalSystem, Database, EquilibriumProblem, EquilibriumSolver, Partition database = Database('supcrt07.xml') editor = ChemicalEditor(database) aqueous_elements = ["C", "Ca", "Cl", "Fe", "H", "Na", "O", "S", "Ba", "Sr"] aqueous_phase = editor.addAqueousPhaseWithElements(aqueous_elements) assert aqueous_phase.name() == 'Aqueous' mineral_species = [ "Anhydrite", "Barite", "Calcite", "Celestite", "Siderite", "Pyrrhotite" ] for mineral in mineral_species: editor.addMineralPhase(mineral) gaseous_species = ["CO2(g)", "H2S(g)", "CH4(g)"] editor.addGaseousPhase(gaseous_species) chemical_system = ChemicalSystem(editor) element_index = { e.name(): index for index, e in enumerate(chemical_system.elements()) } species_index = { s.name(): index for index, s in enumerate(chemical_system.species()) } phase_index = { p.name(): index for index, p in enumerate(chemical_system.phases()) } reaktoro_case = get_reaktoro_case() equilibrium_problem = EquilibriumProblem(chemical_system) equilibrium_problem.setTemperature(reaktoro_case.temperature_in_K) equilibrium_problem.setPressure(reaktoro_case.pressure_in_Pa) partition = Partition(chemical_system) partition.setInertPhases([phase_index['Gaseous']]) equilibrium_problem.setPartition(partition) chemical_state = ChemicalState(chemical_system) for name, index, molar_amount in reaktoro_case.species_amounts: assert index == species_index[name] chemical_state.setSpeciesAmount(index, molar_amount) equilibrium_problem.addState(chemical_state) solver = EquilibriumSolver(chemical_system) solver.setPartition(partition) result = solver.solve(chemical_state, equilibrium_problem) assert result.optimum.succeeded state_regression.check(chemical_state, default_tol=dict(atol=1e-5, rtol=1e-14))
def test_equilibrium_CH4_H2S_CO2_H2O_liq_gas_aq(temperature, pressure, num_regression): """ This test checks the capability of solving a system that has CH4, H2S, CO2, H2O with @param Temperature temperature in Kelvin which will be used to compute equilibrium @param Pressure pressure in bar which will be used to compute equilibrium """ db = Database("supcrt98.xml") editor = ChemicalEditor(db) eos_params = CubicEOSParams( phase_identification_method=PhaseIdentificationMethod. GibbsEnergyAndEquationOfStateMethod, ) editor.addAqueousPhase(["CO2(aq)", "H2S(aq)", "H2O(l)"]) editor.addGaseousPhase(["CH4(g)", "CO2(g)", "H2S(g)", "H2O(g)"]).setChemicalModelCubicEOS(eos_params) editor.addLiquidPhase(["CH4(liq)", "CO2(liq)", "H2S(liq)", "H2O(liq)"]).setChemicalModelCubicEOS(eos_params) system = ChemicalSystem(editor) problem = EquilibriumProblem(system) problem.setTemperature(temperature, "K") problem.setPressure(pressure, "bar") problem.add("H2O(g)", 0.50, "mol") problem.add("CO2(g)", 0.05, "mol") problem.add("H2S(g)", 0.40, "mol") problem.add("CH4(g)", 0.05, "mol") # This is a workaround to avoid an Eigen assertion when in Debug: # `DenseBase::resize() does not actually allow to resize.`, triggered by `y(iee) = optimum_state.y * RT;` problem.add("Z", 1e-15, "mol") solver = EquilibriumSolver(problem.system()) options = EquilibriumOptions() options.hessian = GibbsHessian.Exact options.nonlinear.max_iterations = 100 options.optimum.max_iterations = 200 options.optimum.ipnewton.step = StepMode.Conservative options.optimum.tolerance = 1e-14 solver.setOptions(options) state = ChemicalState(system) result = solver.solve(state, problem) assert result.optimum.succeeded species_amount = { "CO2(aq)": np.asarray([state.speciesAmount("CO2(g)")]), "H2S(aq)": np.asarray([state.speciesAmount("H2S(aq)")]), "H2O(l)": np.asarray([state.speciesAmount("H2O(l)")]), "CH4(g)": np.asarray([state.speciesAmount("CH4(g)")]), "CO2(g)": np.asarray([state.speciesAmount("CO2(g)")]), "H2S(g)": np.asarray([state.speciesAmount("H2S(g)")]), "H2O(g)": np.asarray([state.speciesAmount("H2O(g)")]), "CH4(liq)": np.asarray([state.speciesAmount("CH4(liq)")]), "CO2(liq)": np.asarray([state.speciesAmount("CO2(liq)")]), "H2S(liq)": np.asarray([state.speciesAmount("H2S(liq)")]), "H2O(liq)": np.asarray([state.speciesAmount("H2O(liq)")]), } num_regression.check(species_amount)