Beispiel #1
0
def test_get_odesys__late_binding():
    def _gibbs(args, T, R, backend, **kwargs):
        H, S = args
        return backend.exp(-(H - T*S)/(R*T))

    def _eyring(args, T, R, k_B, h, backend, **kwargs):
        H, S = args
        return k_B/h*T*backend.exp(-(H - T*S)/(R*T))

    gibbs_pk = ('temperature', 'molar_gas_constant')
    eyring_pk = gibbs_pk + ('Boltzmann_constant', 'Planck_constant')

    GibbsEC = MassActionEq.from_callback(_gibbs, argument_names=('H', 'S'), parameter_keys=gibbs_pk)
    EyringMA = MassAction.from_callback(_eyring, argument_names=('H', 'S'), parameter_keys=eyring_pk)

    uk_equil = ('He_assoc', 'Se_assoc')
    beta = GibbsEC(unique_keys=uk_equil)  # equilibrium parameters

    uk_kinet = ('Ha_assoc', 'Sa_assoc')
    bimol_barrier = EyringMA(unique_keys=uk_kinet)  # activation parameters

    eq = Equilibrium({'Fe+3', 'SCN-'}, {'FeSCN+2'}, beta)
    rsys = ReactionSystem(eq.as_reactions(kf=bimol_barrier))
    odesys, extra = get_odesys(rsys, include_params=False)
    pk, unique, p_units = map(extra.get, 'param_keys unique p_units'.split())
    assert sorted(unique) == sorted(uk_equil + uk_kinet)
    assert sorted(pk) == sorted(eyring_pk)
Beispiel #2
0
def test_get_odesys__late_binding():
    def _gibbs(args, T, R, backend, **kwargs):
        H, S = args
        return backend.exp(-(H - T*S)/(R*T))

    def _eyring(args, T, R, k_B, h, backend, **kwargs):
        H, S = args
        return k_B/h*T*backend.exp(-(H - T*S)/(R*T))

    gibbs_pk = ('temperature', 'molar_gas_constant')
    eyring_pk = gibbs_pk + ('Boltzmann_constant', 'Planck_constant')

    GibbsEC = MassActionEq.from_callback(_gibbs, argument_names=('H', 'S'), parameter_keys=gibbs_pk)
    EyringMA = MassAction.from_callback(_eyring, argument_names=('H', 'S'), parameter_keys=eyring_pk)

    uk_equil = ('He_assoc', 'Se_assoc')
    beta = GibbsEC(unique_keys=uk_equil)  # equilibrium parameters

    uk_kinet = ('Ha_assoc', 'Sa_assoc')
    bimol_barrier = EyringMA(unique_keys=uk_kinet)  # activation parameters

    eq = Equilibrium({'Fe+3', 'SCN-'}, {'FeSCN+2'}, beta)
    rsys = ReactionSystem(eq.as_reactions(kf=bimol_barrier))
    odesys, extra = get_odesys(rsys, include_params=False)
    pk, unique, p_units = map(extra.get, 'param_keys unique p_units'.split())
    assert sorted(unique) == sorted(uk_equil + uk_kinet)
    assert sorted(pk) == sorted(eyring_pk)
Beispiel #3
0
def test_get_odesys__Equilibrium_as_reactions():
    from chempy import Equilibrium, ReactionSystem
    eq = Equilibrium({'Fe+3', 'SCN-'}, {'FeSCN+2'}, 10**2)
    substances = 'Fe+3 SCN- FeSCN+2'.split()
    rsys = ReactionSystem(eq.as_reactions(kf=3.0), substances)
    odesys, extra = get_odesys(rsys)
    init_conc = {'Fe+3': 1.0, 'SCN-': .3, 'FeSCN+2': 0}
    tout, Cout, info = odesys.integrate(5, init_conc, integrator='cvode', atol=1e-11, rtol=1e-12)
    cmplx_ref = binary_rev(tout, 3, 3.0/100, init_conc['FeSCN+2'], init_conc['Fe+3'], init_conc['SCN-'])
    assert np.allclose(Cout[:, 2], cmplx_ref)
Beispiel #4
0
def test_get_odesys__Equilibrium_as_reactions():
    from chempy import Equilibrium, ReactionSystem
    eq = Equilibrium({'Fe+3', 'SCN-'}, {'FeSCN+2'}, 10**2)
    substances = 'Fe+3 SCN- FeSCN+2'.split()
    rsys = ReactionSystem(eq.as_reactions(kf=3.0), substances)
    odesys, extra = get_odesys(rsys)
    init_conc = {'Fe+3': 1.0, 'SCN-': .3, 'FeSCN+2': 0}
    tout, Cout, info = odesys.integrate(5, init_conc, integrator='cvode', atol=1e-11, rtol=1e-12)
    cmplx_ref = binary_rev(tout, 3, 3.0/100, init_conc['FeSCN+2'], init_conc['Fe+3'], init_conc['SCN-'])
    assert np.allclose(Cout[:, 2], cmplx_ref)
Beispiel #5
0
def test_get_odesys__Equilibrium_as_reactions():
    from chempy import Equilibrium, ReactionSystem

    eq = Equilibrium({"Fe+3", "SCN-"}, {"FeSCN+2"}, 10 ** 2)
    substances = "Fe+3 SCN- FeSCN+2".split()
    rsys = ReactionSystem(eq.as_reactions(kf=3.0), substances)
    odesys, extra = get_odesys(rsys)
    init_conc = {"Fe+3": 1.0, "SCN-": 0.3, "FeSCN+2": 0}
    tout, Cout, info = odesys.integrate(
        5, init_conc, integrator="cvode", atol=1e-11, rtol=1e-12
    )
    cmplx_ref = binary_rev(
        tout, 3, 3.0 / 100, init_conc["FeSCN+2"], init_conc["Fe+3"], init_conc["SCN-"]
    )
    assert np.allclose(Cout[:, 2], cmplx_ref)
Beispiel #6
0
 def melange(self):
     '''Calcule Xmax, affiche le(s) réactif(s) limitant(s)'''
     #Génère la liste de tuples (n/coeff,occurence) triée par ordre croissant de n/coeff
     local_list=[(k, len(list(v)))
             for k, v in itertools.groupby(sorted(self.etat_ini.values()))]
     #initialisation
     RL='Réactif(s) limitant(s):'
     #Pour tout les éléments dans la liste contenant les formules (k) si le réactif est limitant
     for elt in [k for k,v in self.etat_ini.items() if v==local_list[0][0]]:
         #Incrémente la chaîne en ajoutant une virgule
         RL+=str(elt)+','
     #Retient tout sauf la dernière virgule
     RL=RL[:-1]
     #Création d'un label avec un texte "Résultats" & incrémentation de la variable ligne
     Label(self.top.frame3,text="Résultats:").grid(row=self.ligne, sticky=W)
     self.ligne+=1
     #Création d'un label avec un texte "RL" en rouge & incrémentation de la variable ligne
     Label(self.top.frame3,text=RL, fg="red").grid(row=self.ligne, sticky=W)
     self.ligne+=1
     #Affectation du nb de réactifs limitant
     txt="Réactif(s) limitant(s): "+str(local_list[0][1])+"."
     #Création d'un label avec le texte 'txt' en rouge & incrémentation de la variable ligne
     Label(self.top.frame3,text=txt).grid(row=self.ligne, sticky=W)
     self.ligne+=1
     #Affectation de Xmax
     txt="Avancement maximal: Xmax="+"{:5.2E}".format(local_list[0][0])+ " mol"
     #Création d'un label avec le texte 'txt' & incrémentation de la variable ligne
     Label(self.top.frame3,text=txt).grid(row=self.ligne, sticky=W)
     self.ligne+=1
     #Création d'un label avec l'équation-bilan & incrémentation de la variable ligne
     Label(self.top.frame3,text=Equilibrium(self.Liste_reac, self.Liste_prod)).grid(row=self.ligne, sticky=W)
     self.ligne+=1
     #retourne Xmax
     return local_list[0][0]
Beispiel #7
0
    def test_equilibrate_pH_non_trivial(init_conc, env_T):

        equilibria = {
            'water':
            Equilibrium.from_string(f"H2O = H+ + OH-; {K_H2O / M / M}"),
            'ammonia':
            Equilibrium.from_string(
                f"NH3 + H2O = NH4+ + OH-; {EQUILIBRIUM_CONST['K_NH3'].at(env_T) / M}"
            ),
            'sulfonic_first':
            Equilibrium.from_string(
                f"H2SO3(aq) = H+ + HSO3-; {EQUILIBRIUM_CONST['K_SO2'].at(env_T) / M}"
            ),
            'sulfonic_second':
            Equilibrium.from_string(
                f"HSO3- = H+ + SO3-2; {EQUILIBRIUM_CONST['K_HSO3'].at(env_T) / M}"
            ),
            'carbonic_first':
            Equilibrium.from_string(
                f"H2CO3(aq) = H+ + HCO3-; {EQUILIBRIUM_CONST['K_CO2'].at(env_T) / M}"
            ),
            'carbonic_second':
            Equilibrium.from_string(
                f"HCO3- = H+ + CO3-2; {EQUILIBRIUM_CONST['K_HCO3'].at(env_T) / M}"
            )
        }
        substances = [
            Species.from_formula(f) for f in
            'H2O OH- H+ NH3 NH4+ H2CO3(aq) HCO3- CO3-2 H2SO3(aq) HSO3- SO3-2'.
            split()
        ]
        eqsys = EqSystem(equilibria.values(), substances)

        x, sol, sane = eqsys.root(init_conc)
        assert sol['success'] and sane

        H_idx = 2
        assert substances[H_idx].name == 'H+'
        expected_pH = -np.log10(x[H_idx])

        eqs = {}
        for key in EQUILIBRIUM_CONST.keys():
            eqs[key] = np.full(1, EQUILIBRIUM_CONST[key].at(env_T))

        actual_pH = np.empty(1)
        formulae = Formulae()
        ChemistryMethods.equilibrate_H_body(
            within_tolerance=formulae.trivia.within_tolerance,
            pH2H=formulae.trivia.pH2H,
            H2pH=formulae.trivia.H2pH,
            N_mIII=np.full(1, init_conc['NH3'] * 1e3),
            N_V=np.full(1, init_conc['HNO3(aq)'] * 1e3),
            C_IV=np.full(1, init_conc['H2CO3(aq)'] * 1e3),
            S_IV=np.full(1, init_conc['H2SO3(aq)'] * 1e3),
            S_VI=np.full(1, init_conc['HSO4-'] * 1e3),
            K_HNO3=eqs['K_HNO3'].data,
            K_HCO3=eqs['K_HCO3'].data,
            K_HSO3=eqs['K_HSO3'].data,
            K_HSO4=eqs['K_HSO4'].data,
            K_CO2=eqs['K_CO2'].data,
            K_NH3=eqs['K_NH3'].data,
            K_SO2=eqs['K_SO2'].data,
            cell_id=np.zeros(1, dtype=int),
            # output
            do_chemistry_flag=np.empty(1),
            pH=actual_pH,
            # params
            H_min=formulae.trivia.pH2H(aqueous_chemistry.default_pH_max),
            H_max=formulae.trivia.pH2H(aqueous_chemistry.default_pH_min),
            ionic_strength_threshold=aqueous_chemistry.
            default_ionic_strength_threshold,
            rtol=aqueous_chemistry.default_pH_rtol)

        np.testing.assert_allclose(actual_pH[0], expected_pH, rtol=1e-5)
Beispiel #8
0
from chempy import Equilibrium
from sympy import symbols
def balance (first, next, some1, some2)
	K1, K2, Kw = symbols('K1 K2 Kw')
	e1 = Equilibrium(first, next, K1)
	e2 = Equilibrium(some1, some2, K2)
	coeff = Equilibrium.eliminate([e1, e2], 'e-')

	redox = e1*coeff[0] + e2*coeff[1]
	print(redox)
	autoprot = Equilibrium({'H2O': 1}, {'H+': 1, 'OH-': 1}, Kw)
	n = redox.cancel(autoprot)
	redox2 = redox + n*autoprot
	print(redox2)
 
# the Free Software Foundation; either version 3, or (at your option)
# any later version.

# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with GNU Emacs; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA,
#!/usr/bin/python
# -*- coding: utf-8 -*-

from chempy import Equilibrium
from sympy import symbols

K1, K2, Kw = symbols('K1 K2 Kw')
e1 = Equilibrium({'MnO4-': 1, 'H+': 8, 'e-': 5}, {'Mn+2': 1, 'H2O': 4}, K1)
e2 = Equilibrium({'O2': 1, 'H2O': 2, 'e-': 4}, {'OH-': 4}, K2)
coeff = Equilibrium.eliminate([e1, e2], 'e-')
coeff
redox = e1 * coeff[0] + e2 * coeff[1]
print(redox)
autoprot = Equilibrium({'H2O': 1}, {'H+': 1, 'OH-': 1}, Kw)
n = redox.cancel(autoprot)
print(n)
redox2 = redox + n * autoprot
print(redox2)