def test_get_odesys_3(): M = u.molar s = u.second mol = u.mol m = u.metre substances = list(map(Substance, 'H2O H+ OH-'.split())) dissociation = Reaction({'H2O': 1}, {'H+': 1, 'OH-': 1}, 2.47e-5/s) recombination = Reaction({'H+': 1, 'OH-': 1}, {'H2O': 1}, 1.37e11/M/s) rsys = ReactionSystem([dissociation, recombination], substances) odesys = get_odesys( rsys, include_params=True, unit_registry=SI_base_registry, output_conc_unit=M)[0] c0 = {'H2O': 55.4*M, 'H+': 1e-7*M, 'OH-': 1e-4*mol/m**3} x, y, p = odesys.to_arrays(-42*u.second, rsys.as_per_substance_array(c0, unit=M), ()) fout = odesys.f_cb(x, y, p) time_unit = get_derived_unit(SI_base_registry, 'time') conc_unit = get_derived_unit(SI_base_registry, 'concentration') r1 = to_unitless(55.4*2.47e-5*M/s, conc_unit/time_unit) r2 = to_unitless(1e-14*1.37e11*M/s, conc_unit/time_unit) assert np.all(abs(fout[:, 0] - r2 + r1)) < 1e-10 assert np.all(abs(fout[:, 1] - r1 + r2)) < 1e-10 assert np.all(abs(fout[:, 2] - r1 + r2)) < 1e-10
def test_get_odesys_3(): M = u.molar s = u.second mol = u.mol m = u.metre substances = list(map(Substance, 'H2O H+ OH-'.split())) dissociation = Reaction({'H2O': 1}, {'H+': 1, 'OH-': 1}, 2.47e-5/s) recombination = Reaction({'H+': 1, 'OH-': 1}, {'H2O': 1}, 1.37e11/M/s) rsys = ReactionSystem([dissociation, recombination], substances) odesys = get_odesys( rsys, include_params=True, unit_registry=SI_base_registry, output_conc_unit=M)[0] c0 = {'H2O': 55.4*M, 'H+': 1e-7*M, 'OH-': 1e-4*mol/m**3} x, y, p = odesys.pre_process(-42*u.second, rsys.as_per_substance_array(c0, unit=M)) fout = odesys.f_cb(x, y, p) time_unit = get_derived_unit(SI_base_registry, 'time') conc_unit = get_derived_unit(SI_base_registry, 'concentration') r1 = to_unitless(55.4*2.47e-5*M/s, conc_unit/time_unit) r2 = to_unitless(1e-14*1.37e11*M/s, conc_unit/time_unit) assert abs(fout[0] - r2 + r1) < 1e-10 assert abs(fout[1] - r1 + r2) < 1e-10 assert abs(fout[2] - r1 + r2) < 1e-10
def test_chained_parameter_variation_from_ReactionSystem(): g_E_mol_J = 2.1e-7 rsys = ReactionSystem.from_string( """ (H2O) -> e-(aq) + H+ + OH; Radiolytic(%.2e*mol/J) 2 OH -> H2O2; 3.6e9/M/s H+ + OH- -> H2O; 1.4e11/M/s H2O -> H+ + OH-; 1.4e-3/s N2O + e-(aq) -> N2 + O-; 9.6e9/M/s O- + H+ -> OH; 1e11/M/s """ % g_E_mol_J # neglecting a large body of reactions (just a test-case after all) ) ureg = SI_base_registry field_u = get_derived_unit(ureg, 'doserate') * get_derived_unit(ureg, 'density') rd = ReactionDiffusion.from_ReactionSystem(rsys, fields=[[0*field_u]], unit_registry=ureg, param_names=['doserate']) dens_kg_dm3 = 0.998 odesys = rd._as_odesys( variables_from_params=dict( density=lambda self, params: dens_kg_dm3*1e3*u.kg/u.m**3 ) ) npoints = 5 durations = [59*u.second, 42*u.minute, 2*u.hour] doserates = [135*u.Gy/u.s, 11*u.Gy/u.s, 180*u.Gy/u.minute] M = u.molar ic = defaultdict(lambda: 0*M, {'H2O': 55.4*M, 'H+': 1e-7*M, 'OH-': 1e-7*M, 'N2O': 20e-3*M}) result = odesys.chained_parameter_variation(durations, ic, {'doserate': doserates}, npoints=npoints) ref_xout_s = [0] for dur in map(lambda dur: to_unitless(dur, u.s), durations): ref_xout_s += list(np.linspace(ref_xout_s[-1], ref_xout_s[-1] + dur, npoints+1)[1:]) assert allclose(result.xout, ref_xout_s*u.s) N2_M = to_unitless(result.named_dep('N2'), u.M) H2O2_M = to_unitless(result.named_dep('H2O2'), u.M) e_accum_molar = 0 for i, (dur, dr) in enumerate(zip(durations, doserates)): dur_s = to_unitless(dur, u.s) dr_Gy_s = to_unitless(dr, u.Gy/u.s) local_ts = np.linspace(0, dur_s, npoints+1) # local_ic = {k: result.named_dep(k)[i*npoints] for k in odesys.names} for j, (lt, ld) in enumerate(zip(local_ts[1:], np.diff(local_ts))): e_accum_molar += ld*g_E_mol_J*dr_Gy_s*dens_kg_dm3 assert abs(N2_M[i*npoints + j + 1] - e_accum_molar)/e_accum_molar < 1e-3 assert abs(H2O2_M[i*npoints + j + 1] - e_accum_molar)/e_accum_molar < 1e-3 res2 = odesys.integrate(durations[0], ic, {'doserate': doserates[0]}, integrator='cvode') dr2 = res2.params[res2.odesys.param_names.index('doserate')] assert np.asarray(res2.params).shape[-1] == len(odesys.param_names) assert allclose(dr2, doserates[0]) assert allclose(res2.xout[-1], durations[0]) assert allclose(res2.named_dep('N2')[-1], durations[0]*doserates[0]*g_E_mol_J*u.mol/u.J*dens_kg_dm3*u.kg/u.dm3) to_unitless(res2.xout, u.s) to_unitless(res2.yout, u.molar) to_unitless(dr2, u.Gy/u.s)
def test_get_odesys__with_units(): a = Substance('A') b = Substance('B') molar = u.molar second = u.second r = Reaction({'A': 2}, {'B': 1}, param=1e-3/molar/second) rsys = ReactionSystem([r], [a, b]) odesys = get_odesys(rsys, include_params=True, unit_registry=SI_base_registry)[0] c0 = { 'A': 13*u.mol / u.metre**3, 'B': .2 * u.molar } conc_unit = get_derived_unit(SI_base_registry, 'concentration') t = np.linspace(0, 10)*u.hour xout, yout, info = odesys.integrate( t, rsys.as_per_substance_array(c0, unit=conc_unit), atol=1e-10, rtol=1e-12) t_unitless = to_unitless(xout, u.second) Aref = dimerization_irrev(t_unitless, 1e-6, 13.0) # Aref = 1/(1/13 + 2*1e-6*t_unitless) yref = np.zeros((xout.size, 2)) yref[:, 0] = Aref yref[:, 1] = 200 + (13-Aref)/2 assert allclose(yout, yref*conc_unit)
def test_get_odesys__with_units(): a = Substance('A') b = Substance('B') molar = u.molar second = u.second r = Reaction({'A': 2}, {'B': 1}, param=1e-3/molar/second) rsys = ReactionSystem([r], [a, b]) odesys = get_odesys(rsys, include_params=True, unit_registry=SI_base_registry)[0] c0 = { 'A': 13*u.mol / u.metre**3, 'B': .2 * u.molar } conc_unit = get_derived_unit(SI_base_registry, 'concentration') t = np.linspace(0, 10)*u.hour xout, yout, info = odesys.integrate( t, rsys.as_per_substance_array(c0, unit=conc_unit), atol=1e-10, rtol=1e-12) t_unitless = to_unitless(xout, u.second) Aref = dimerization_irrev(t_unitless, 1e-6, 13.0) # Aref = 1/(1/13 + 2*1e-6*t_unitless) yref = np.zeros((xout.size, 2)) yref[:, 0] = Aref yref[:, 1] = 200 + (13-Aref)/2 print((yout - yref*conc_unit)/yout) assert allclose(yout, yref*conc_unit)
def radyields2pdf_table(rd, output_dir=None, save=True, unit_registry=None, siunitx=False, fmtstr='{0:.3f}', **kwargs): """ Generate a table with radiolytic yields Calls chempy.util.table.render_tex_to_pdf Parameters ---------- rd: ReactionDiffusion output_dir: str save: bool unit_registry: dict siunitx: bool fmtstr: str \*\*kwargs: extends the table template dictionary """ line_term = r' \\' col_delim = ' & ' header = (col_delim.join(rd.substance_latex_names or rd.substance_names) + line_term) lines = [] for cur_gs in rd.g_values: if unit_registry is not None: gunit = get_derived_unit(unit_registry, 'radiolytic_yield') cur_gs = to_unitless(cur_gs, gunit) lines.append(col_delim.join(map( lambda v: fmtstr.format(v), cur_gs)) + line_term) table_template_dict = { 'table_env': 'table', 'alignment': ('@{}S' if siunitx else '@{}l')*rd.n, 'header': header, 'short_cap': 'G-values', 'long_cap': 'G-values', 'label': 'none', 'body': '\n'.join(lines) } table_template_dict.update(kwargs) table = tex_templates['table']['default'] % table_template_dict _envs = ['landscape', 'tiny'] _pkgs = (['siunitx'] if siunitx else []) + [ 'booktabs', 'lscape', 'amsmath', 'hyperref'] contents = tex_templates['document']['default'] % { 'usepkg': '\n'.join([r'\usepackage{%s}' % pkg for pkg in _pkgs]), 'begins': '\n'.join([r'\begin{%s}' % env for env in _envs]), 'ends': '\n'.join([r'\end{%s}' % env for env in _envs[::-1]]), 'table': table } return render_tex_to_pdf(contents, 'gvalues.tex', 'gvalues.pdf', output_dir, save)