Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*- chemreac.chemistry ==================
This module collects classes useful for describing substances, reactions and reaction systems. The classes have methods to help with consistent low-level conversion to numerical parameters of the model.
"""
# TODO: somewhere: add check for massconservation and charge conservation
""" Substance class to represent a chemical speices.
Parameters ========== name: string unique string representation e.g. "H2O", "CNO-", "OCN-" charge: integer charge of substance mass: float molar mass (default None) formula: e.g. periodictable.formulas.Formula instance optional, if formula instance provides `mass` attribute it is used as mass in the case mass=None tex_name: string optional, TeX formated string, e.g. '$\mathrm{OH^{-}}$' multiplicity: integer optional, 1 for singlet, 2 for doublet... D: float (optional) diffusion coefficent, for now: isothermal, isotropic and only for one medium. default: 0.0 **kwargs: additional freely chosen attributes
Attributes ========== all_substances dictionary (name, insatnce) of all Substance instances.
Examples ======== >>> Substance(name='H2O', charge=0, tex_name=r'$\mathrm{H_{2}O}$', pKa=14) <Substance 'H2O'> >>> Substance.all_substances['H2O'] <Substance 'H2O'> >>> 'H2O' in Substance.all_substances True
""" # weakref => If instance is deleted GC can kill it. # We manually keep track och instances in order to ensure unique names
tex_name=None, multiplicity=None, D=0.0, **kwargs): raise KeyError( 'Substance name already exists: ' + name + ' id=' + str(id(self.__class__.all_substances[name]))) else:
def name(self):
# Thanks to total_ordering it is sufficient to specify eq and lt """ Equality of Substance instances is solely determined from .name """ # all_substances dictionary lookup in __init__ should # prevent collisions
""" See ``chemreac.util.physchem.electrical_mobility_from_D`` """ return electrical_mobility_from_D(self.D, self.charge, Temp, **kwargs)
""" Convenience function to generate a OrderedDict of Substance instances from a sequence of names and corresponding sequences of kwargs to Substance class.
Parameters ---------- names: sequence of strings names of substances **kwargs: sequences of corresponding keyword arguments
Examples -------- >>> mk_sn_dict_from_names( ... 'ABCD', D=[0.1, 0.2, 0.3, 0.4]) # doctest: +NORMALIZE_WHITESPACE OrderedDict([('A', <Substance 'A'>), ('B', <Substance 'B'>), ('C', <Substance 'C'>), ('D', <Substance 'D'>)])
"""
in enumerate(names)])
""" Reaction with kinetics governed by the law of mass-action. Example:
A + R --> A + P; r = k*A*R
Also supports
5*C1 + C2 --> B; r = k*C1*C2
by specifying active reactants C1, C2 and inactive reaktants 4*C1.
reactants and products are dictionaries with substance names as keys and positive integers giving their stoichiometric coeffecients as values
rate constant i either given as k (T optional as validity info) or as Ea and A for use in the Arrhenius equation
and ref contains optional information on origin of data.
along the same lines `name` is possible to use if the reaction is known under a certain name, e.g. "H2O2 auto-decomposition"
Parameters ---------- active_reac: dict dictionary mapping substance name (string) to stoichiometric coefficient (integer) of reactant, these affect rate expression. products: dict dictionary mapping substance name (string) to stoichiometric coefficient (integer) inactv_reac: dict (optional) Same as active_reac but does not affect rate expression. k: float rate coefficient T: float absolute temperature Ea: float activation energy A: float preexponential prefactor (Arrhenius type eq.) ref: string (optional) Reference key name: string (optional) Descriptive name of reaction """
def reactants(self): self.active_reac.items()):
k=None, T=None, Ea=None, A=None, ref=None, name=None):
else ' $\\rightarrow$ ') else: ((str(v)+' ') if v > 1 else '') + names.get( k, getattr(k, 'tex_name', str(k)) if tex else str(k)) for k, v in filter(itemgetter(1), d.items()) ] for d in (self.active_reac, self.inactv_reac, self.products)] " + ".join(inactv), " + ".join(prod))
def species_names(self):
return [self.reactants[n] for n in species_names]
return [self.products[n] for n in species_names]
""" Collection of reactions forming a system (model).
Parameters ---------- rxns: sequence sequence of :py:class:`Reaction` instances name: string (optional) Name of ReactionSystem (e.g. model name / citation key) substances: sequence (optional) Sequence of Substance instances, will be used in doing a sanity check and as default in method :meth:`to_ReactionDiffusion`
Attributes ---------- rxns sequence of :class:`Reaction` instances species_names names of occurring species k rates for rxns ns number of species nr number of reactions
"""
def rxns(self):
def rxns(self, val):
""" Check for conservation of mass and charge. """ for rxn in rxns: net_chg = 0 net_mass = 0.0 for reac, n in rxn.reactants.items(): net_chg -= self.substances[reac].charge net_mass -= self.substances[reac].mass for reac, n in rxn.products.items(): net_chg += self.substances[reac].charge net_mass += self.substances[reac].mass assert net_chg == 0 assert abs(net_mass) < 0.01
def from_ReactionDiffusion(cls, rd):
**kwargs): """ Creates a :class:`ReactionDiffusion` instance from ``self``.
Parameters ---------- substances: sequence of Substance instances pass to override self.substances (optional) ordered_names: sequence of names pass to override self.ordered_names() \*\*kwargs: Keyword arguments passed on to :class:`ReactionDiffusion` """
return
['D', 'mobility', 'name', 'tex_name'], ['D', 'mobility', 'substance_names', 'substance_tex_names']):
self.ns, self.stoich_active(ordered_names), self.stoich_prod(ordered_names), self.k, stoich_inactv=self.stoich_inactv(ordered_names), **kwargs)
def species_names(self):
'active_reac', ordered_names or self.ordered_names())
'products', ordered_names or self.ordered_names())
'inactv_reac', ordered_names or self.ordered_names())
def k(self): """ List of rate constants """
def ns(self): """ Number of species """
def nr(self): """ Number of reactions """ return len(self._rxns) |