def test_ReactionSystem__to_ReactionDiffusion(): sbstncs = mk_sn_dict_from_names('AB') r1 = Reaction({'A': 2}, {'B': 1}, 3.0) rsys = ReactionSystem([r1], sbstncs) rd = ReactionDiffusion.from_ReactionSystem(rsys) assert rd.stoich_active == [[0, 0]] assert rd.stoich_prod == [[1]] assert rd.k == [3.0]
def test_autobinary(): from chemreac.chemistry import ( Reaction, ReactionSystem, mk_sn_dict_from_names ) sbstncs = mk_sn_dict_from_names('AB') k = 3.0 r1 = Reaction({'A': 2}, {'B': 1}, k) rsys = ReactionSystem([r1], sbstncs) rd = ReactionDiffusion.from_ReactionSystem(rsys) _test_f_and_dense_jac_rmaj(rd, 0, [1, 37], [-2*3, 3])
def test_chemistry(): sbstncs = mk_sn_dict_from_names('ABC', D=[.1, .2, .3]) r1 = Reaction({'A': 1, 'B': 1}, {'C': 1}, 0.3) rsys = ReactionSystem([r1], sbstncs) rd = ReactionDiffusion.from_ReactionSystem(rsys) serialized_rd = load(JSON_PATH) assert rd.stoich_active == serialized_rd.stoich_active assert rd.stoich_prod == serialized_rd.stoich_prod assert rd.stoich_inact == serialized_rd.stoich_inact assert np.allclose(rd.k, serialized_rd.k) assert np.allclose(rd.D, serialized_rd.D)
def test_autodimerization(arrhenius): # A + A -> B from chemreac.chemistry import ( Reaction, ReactionSystem, mk_sn_dict_from_names ) sbstncs = mk_sn_dict_from_names('AB') if arrhenius: from chempy.kinetics.arrhenius import ArrheniusParam k = ArrheniusParam(7e11, -8.314472*298.15*(np.log(3) - np.log(7) - 11*np.log(10))) variables = {'temperature': 298.15} param = 3.0 else: param = k = 3.0 variables = None r1 = Reaction({'A': 2}, {'B': 1}, k) rsys = ReactionSystem([r1], sbstncs) rd = ReactionDiffusion.from_ReactionSystem(rsys, variables=variables) t = np.linspace(0, 5, 3) A0, B0 = 1.0, 0.0 integr = run(rd, [A0, B0], t) Aref = 1/(1/A0+2*param*t) yref = np.vstack((Aref, (A0-Aref)/2)).transpose() assert np.allclose(integr.yout[:, 0, :], yref)
def plot_per_reaction_contribution(integr, substances, equilibria=None, field_yields=False, **kwargs): """ Plots contributions to concentration derivatives of selected substances from individual reactions. Parameters ---------- integr: Integration instance substances: sequence of Substance instances equilibria: set of tuples of reaction indices (optional) When passed only net effect of equilibria reaction will be plotted field_yields: bool (default: False) If ``True`` contributions from g_values times field will be shown **kwargs: kwargs passed on to _plot_analysis Returns ------- list of matplotlib.axes.Axes instances """ rd = integr.rd if rd.N != 1: # should be quite straight forward to implement raise NotImplementedError indices = [ri if isinstance(ri, int) else rd.substance_names.index(ri) for ri in substances] if rd.substance_latex_names is not None: print_names = rd.substance_latex_names use_tex = True else: print_names = rd.substance_names use_tex = False substances = mk_sn_dict_from_names(rd.substance_names, latex_name=rd.substance_latex_names) if field_yields: # Let's use negative reaction indices for each field -1: 0, -2: 1 rxn_indices = range(-len(rd.fields), 0) else: rxn_indices = [] if equilibria is not None: equilibria_participants = [] for rxnidxs in equilibria: equilibria_participants.extend(rxnidxs) rxn_indices.append(rxnidxs) for ri in range(rd.nr): if ri not in equilibria_participants: rxn_indices.append(ri) else: rxn_indices += range(rd.nr) labels = [] for rxni in rxn_indices: if isinstance(rxni, int): if rxni >= 0: rxn = rd.to_Reaction(rxni) labels.append("R" + str(rxni) + ": " + ("$" + rxn.latex(substances) + "$") if use_tex else str(rxn)) else: # Field production! fi = -rxni - 1 if rd.g_value_parents[fi] == -1: # No parents parent = "" else: parent = print_names[rd.g_value_parents[fi]] + "$\\rightsquigarrow$" if use_tex else " ~~~> " labels.append( "G_" + str(fi) + ": " + parent + ", ".join([print_names[si] for si in range(rd.n) if rd.g_values[fi][si] != 0]) ) else: rxn = rd.to_Reaction(rxni[0]) labels.append( "R(" + ", ".join(map(str, rxni)) + "): " + ("$" + rxn.latex(dict(zip(rd.substance_names, print_names))) + "$") if use_tex else str(rxn) ) def cb(rd_, tout_, yout_, specie_indices_): bi = 0 # bin index, N=1 only implemented for now per_rxn = _get_per_rxn_out(rd_, tout_, yout_, specie_indices_) out = np.zeros((yout_.shape[0], len(specie_indices_), len(rxn_indices))) for i, rxns in enumerate(rxn_indices): if isinstance(rxns, int): if rxns >= 0: out[:, :, i] = per_rxn[:, :, rxns] else: fi = -rxns - 1 for sii, si in enumerate(specie_indices_): out[:, sii, i] = rd.g_values[fi][si] * rd.fields[fi][bi] else: for rxn_idx in rxns: out[:, :, i] += per_rxn[:, :, rxn_idx] return out axes = _plot_analysis( cb, labels, rd, integr.tout, integr.yout, indices, titles=["$" + print_names[i] + "$" for i in indices], **kwargs ) for ax in axes: ax.set_ylabel(r"Reaction rate / $M\cdot s^{-1}$") return axes