def getArrheniusJSMath(A, Aunits, n, nunits, Ea, Eaunits, T0, T0units): result = '{0!s}'.format(getLaTeXScientificNotation(A)) if n != 0: if T0 != 1: result += r' \left( \frac{{T}}{{ {0:g} \ \mathrm{{ {1!s} }} }} \right)^{{ {2:.2f} }}'.format(T0, T0units, n) else: result += r' T^{{ {0:.2f} }}'.format(n) if Ea != 0: result += r' \exp \left( - \, \frac{{ {0:.2f} \ \mathrm{{ {1!s} }} }}{{ R T }} \right)'.format(Ea, Eaunits) result += ' \ \mathrm{{ {0!s} }}'.format(Aunits) return result
def get_temp_specific_rate(kinetics, temperature): """ Return the rate in nice units given a specified temperature. Outputs in pretty Latex scientific notation. """ if kinetics is None: return "// There are no kinetics for this entry." kunits, kunits_low, kfactor, numReactants = getRateCoefficientUnits(kinetics) rate = kinetics.getRateCoefficient(temperature)*kfactor result = '<div class="math">k(T) = {0!s}'.format(getLaTeXScientificNotation(rate)) result += '\ \mathrm{{ {0!s} }}</div>'.format(kunits) return mark_safe(result)
def get_specific_rate(kinetics, eval): """ Return the rate in nice units given a specified temperature. Outputs in pretty Latex scientific notation. """ if kinetics is None: return "// There are no kinetics for this entry." temperature, pressure = eval kunits, kunits_low, kfactor = getRateCoefficientUnits(kinetics) rate = kinetics.get_rate_coefficient(temperature, pressure)*kfactor result = '<script type="math/tex; mode=display">k(T, P) = {0!s}'.format(getLaTeXScientificNotation(rate)) result += '\ \mathrm{{ {0!s} }}</script>'.format(kunits) return mark_safe(result)
def getArrheniusJSMath(A, Aunits, n, nunits, Ea, Eaunits, T0, T0units): result = '{0!s}'.format(getLaTeXScientificNotation(A)) if n != 0: if T0 != 1: result += r' \left( \frac{{T}}{{ {0:g} \ \mathrm{{ {1!s} }} }} \right)^{{ {2:.2f} }}'.format(T0, T0units, n) else: result += r' T^{{ {0:.2f} }}'.format(n) if Ea > 0: result += r' \exp \left( - \, \frac{{ {0:.2f} \ \mathrm{{ {1!s} }} }}{{ R T }} \right)'.format(Ea, Eaunits) elif Ea < 0: result += r' \exp \left(\frac{{ {0:.2f} \ \mathrm{{ {1!s} }} }}{{ R T }} \right)'.format(-Ea, Eaunits) result += ' \ \mathrm{{ {0!s} }}'.format(Aunits) return result
def get_specific_rate(kinetics, eval): """ Return the rate in nice units given a specified temperature. Outputs in pretty Latex scientific notation. """ if kinetics is None: return "// There are no kinetics for this entry." temperature, pressure = eval kunits, kunits_low, kfactor, numReactants = getRateCoefficientUnits(kinetics) rate = kinetics.getRateCoefficient(temperature, pressure)*kfactor result = '<script type="math/tex; mode=display">k(T, P) = {0!s}'.format(getLaTeXScientificNotation(rate)) result += '\ \mathrm{{ {0!s} }}</script>'.format(kunits) return mark_safe(result)
def render_thermo_math(thermo, user=None): """ Return a math representation of the given `thermo` using jsMath. If a `user` is specified, the user's preferred units will be used; otherwise default units will be used. """ # Define other units and conversion factors to use if user and user.is_authenticated(): user_profile = UserProfile.objects.get(user=user) Tunits = str(user_profile.temperatureUnits) Punits = str(user_profile.pressureUnits) Cpunits = str(user_profile.heatCapacityUnits) Hunits = str(user_profile.energyUnits) Sunits = str(user_profile.heatCapacityUnits) Gunits = str(user_profile.energyUnits) else: Tunits = 'K' Punits = 'bar' Cpunits = 'cal/(mol*K)' Hunits = 'kcal/mol' Sunits = 'cal/(mol*K)' Gunits = 'kcal/mol' Tfactor = Quantity(1, Tunits).getConversionFactorFromSI() Pfactor = Quantity(1, Punits).getConversionFactorFromSI() Cpfactor = Quantity(1, Cpunits).getConversionFactorFromSI() Hfactor = Quantity(1, Hunits).getConversionFactorFromSI() Sfactor = Quantity(1, Sunits).getConversionFactorFromSI() Gfactor = Quantity(1, Gunits).getConversionFactorFromSI() # The string that will be returned to the template result = '' if isinstance(thermo, ThermoData): # The thermo is in ThermoData format result += '<table class="thermoEntryData">\n' if thermo.H298 is not None: result += '<tr>' result += r' <td class="key"><span class="math">\Delta H_\mathrm{f}^\circ(298 \ \mathrm{K})</span></td>' result += r' <td class="equals">=</td>' result += r' <td class="value"><span class="math">{0:.2f} \ \mathrm{{ {1!s} }}</span></td>'.format(thermo.H298.value_si * Hfactor, Hunits) result += '</tr>\n' if thermo.S298 is not None: result += '<tr>' result += r' <td class="key"><span class="math">\Delta S_\mathrm{f}^\circ(298 \ \mathrm{K})</span></td>' result += r' <td class="equals">=</td>' result += r' <td class="value"><span class="math">{0:.2f} \ \mathrm{{ {1!s} }}</span></td>'.format(thermo.S298.value_si * Sfactor, Sunits) result += '</tr>\n' if thermo.Tdata is not None and thermo.Cpdata is not None: for T, Cp in zip(thermo.Tdata.value_si, thermo.Cpdata.value_si): result += '<tr>' result += r' <td class="key"><span class="math">C_\mathrm{{p}}^\circ({0:g} \ \mathrm{{ {1!s} }})</span></td>'.format(T * Tfactor, Tunits) result += r' <td class="equals">=</td>' result += r' <td class="value"><span class="math">{0:.2f} \ \mathrm{{ {1!s} }}</span></td>'.format(Cp * Cpfactor, Cpunits) result += '</tr>\n' result += '</table>\n' elif isinstance(thermo, Wilhoit): # The thermo is in Wilhoit format result += '<div class="math">\n' result += r'\begin{split}' result += r'C_\mathrm{p}(T) &= C_\mathrm{p}(0) + \left[ C_\mathrm{p}(\infty) -' result += r' C_\mathrm{p}(0) \right] y^2 \left[ 1 + (y - 1) \sum_{i=0}^3 a_i y^i \right] \\' result += r'H^\circ(T) &= H_0 + \int_0^\infty C_\mathrm{p}(T) \ dT \\' result += r'S^\circ(T) &= S_0 + \int_0^\infty \frac{C_\mathrm{p}(T)}{T} \ dT\\' result += r'y &\equiv \frac{T}{T + B}' result += r'\end{split}' result += '</div>\n' result += '<table class="thermoEntryData">\n' result += '<tr>' result += r' <td class="key"><span class="math">C_\mathrm{p}(0)</span></td>' result += r' <td class="equals">=</td>' result += r' <td class="value"><span class="math">{0:.2f} \ \mathrm{{ {1!s} }}</span></td>'.format(thermo.cp0.value_si * Cpfactor, Cpunits) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">C_\mathrm{p}(\infty)</span></td>' result += r' <td class="equals">=</td>' result += r' <td class="value"><span class="math">{0:.2f} \ \mathrm{{ {1!s} }}</span></td>'.format(thermo.cpInf.value_si * Cpfactor, Cpunits) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">a_0</span></td>' result += r' <td class="equals">=</td>' result += r' <td class="value"><span class="math">{0!s}</span></td>'.format(getLaTeXScientificNotation(thermo.a0)) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">a_1</span></td>' result += r' <td class="equals">=</td>' result += r' <td class="value"><span class="math">{0!s}</span></td>'.format(getLaTeXScientificNotation(thermo.a1)) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">a_2</span></td>' result += r' <td class="equals">=</td>' result += r' <td class="value"><span class="math">{0!s}</span></td>'.format(getLaTeXScientificNotation(thermo.a2)) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">a_3</span></td>' result += r' <td class="equals">=</td>' result += r' <td class="value"><span class="math">{0!s}</span></td>'.format(getLaTeXScientificNotation(thermo.a3)) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">H_0</span></td>' result += r' <td class="equals">=</td>' result += r' <td class="value"><span class="math">{0:.2f} \ \mathrm{{ {1!s} }}</span></td>'.format(thermo.H0.value_si * Hfactor, Hunits) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">S_0</span></td>' result += r' <td class="equals">=</td>' result += r' <td class="value"><span class="math">{0:.2f} \ \mathrm{{ {1!s} }}</span></td>'.format(thermo.S0.value_si * Sfactor, Sunits) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">B</span></td>' result += r' <td class="equals">=</td>' result += r' <td class="value"><span class="math">{0:.2f} \ \mathrm{{ {1!s} }}</span></td>'.format(thermo.B.value_si * Tfactor, Tunits) result += '</tr>\n' result += '</table>\n' elif isinstance(thermo, NASA): # The thermo is in NASA format result += '<div class="math">\n' result += r'\frac{C_\mathrm{p}^\circ(T)}{R} = a_{-2} T^{-2} + a_{-1} T^{-1} + a_0 + a_1 T + a_2 T^2 + a_3 T^3 + a_4 T^4' result += '</div>\n' result += '<div class="math">\n' result += r'\frac{H^\circ(T)}{RT} = -a_{-2} T^{-2} + a_{-1} \frac{\ln T}{T} + a_0 + \frac{1}{2} a_1 T + \frac{1}{3} a_2 T^2 + \frac{1}{4} a_3 T^3 + \frac{1}{5} a_4 T^4 + \frac{a_5}{T}' result += '</div>\n' result += '<div class="math">\n' result += r'\frac{S^\circ(T)}{R} = -\frac{1}{2} a_{-2} T^{-2} - a_{-1} T^{-1} + a_0 \ln T + a_1 T + \frac{1}{2} a_2 T^2 + \frac{1}{3} a_3 T^3 + \frac{1}{4} a_4 T^4 + a_6' result += '</div>\n' result += '<table class="thermoEntryData">\n' result += '<tr>' result += r' <td class="key">Temperature range</td>' result += r' <td class="equals">=</td>' for polynomial in thermo.polynomials: result += r' <td class="value">{0:g} to {1:g} {2!s}</td>'.format(polynomial.Tmin.value_si * Tfactor, polynomial.Tmax.value_si * Tfactor, Tunits) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">a_{-2}</span></td>' result += r' <td class="equals">=</td>' for polynomial in thermo.polynomials: result += r' <td class="value"><span class="math">{0!s}</span></td>'.format(getLaTeXScientificNotation(polynomial.cm2)) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">a_{-1}</span></td>' result += r' <td class="equals">=</td>' for polynomial in thermo.polynomials: result += r' <td class="value"><span class="math">{0!s}</span></td>'.format(getLaTeXScientificNotation(polynomial.cm1)) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">a_0</span></td>' result += r' <td class="equals">=</td>' for polynomial in thermo.polynomials: result += r' <td class="value"><span class="math">{0!s}</span></td>'.format(getLaTeXScientificNotation(polynomial.c0)) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">a_1</span></td>' result += r' <td class="equals">=</td>' for polynomial in thermo.polynomials: result += r' <td class="value"><span class="math">{0!s}</span></td>'.format(getLaTeXScientificNotation(polynomial.c1)) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">a_2</span></td>' result += r' <td class="equals">=</td>' for polynomial in thermo.polynomials: result += r' <td class="value"><span class="math">{0!s}</span></td>'.format(getLaTeXScientificNotation(polynomial.c2)) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">a_3</span></td>' result += r' <td class="equals">=</td>' for polynomial in thermo.polynomials: result += r' <td class="value"><span class="math">{0!s}</span></td>'.format(getLaTeXScientificNotation(polynomial.c3)) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">a_4</span></td>' result += r' <td class="equals">=</td>' for polynomial in thermo.polynomials: result += r' <td class="value"><span class="math">{0!s}</span></td>'.format(getLaTeXScientificNotation(polynomial.c4)) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">a_5</span></td>' result += r' <td class="equals">=</td>' for polynomial in thermo.polynomials: result += r' <td class="value"><span class="math">{0!s}</span></td>'.format(getLaTeXScientificNotation(polynomial.c5)) result += '</tr>\n' result += '<tr>' result += r' <td class="key"><span class="math">a_6</span></td>' result += r' <td class="equals">=</td>' for polynomial in thermo.polynomials: result += r' <td class="value"><span class="math">{0!s}</span></td>'.format(getLaTeXScientificNotation(polynomial.c6)) result += '</tr>\n' result += '</table>\n' elif isinstance(thermo, list): # The thermo is a link index = thermo[1] url = reverse('database.views.thermoEntry', {'section': section, 'subsection': subsection, 'index': index}) result += '<table class="thermoEntryData">\n' result += '<tr>' result += r' <td class="key">Link:</td>' result += r' <td class="value"><a href="{0!s}">{1}</a></td>'.format(url, index) result += '</tr>\n' result += '<\table>\n' # Temperature range if isinstance(thermo, (ThermoData, Wilhoit, NASA)): result += '<table class="thermoEntryData">' if thermo.Tmin is not None and thermo.Tmax is not None: result += '<tr><td class="key">Temperature range</td><td class="equals">=</td><td class="value">{0:g} to {1:g} {2!s}</td></tr>'.format(thermo.Tmin.value_si, thermo.Tmax.value_si, Tunits) result += '</table>' return mark_safe(result)
def render_kinetics_math(kinetics, user=None): """ Return a math representation of the given `kinetics` using jsMath. If a `user` is specified, the user's preferred units will be used; otherwise default units will be used. """ if kinetics is None: return mark_safe("<p>There are no kinetics for this entry.</p>") # Define other units and conversion factors to use if user and user.is_authenticated(): user_profile = UserProfile.objects.get(user=user) Tunits = str(user_profile.temperatureUnits) Punits = str(user_profile.pressureUnits) Eunits = str(user_profile.energyUnits) else: Tunits = 'K' Punits = 'bar' Eunits = 'kcal/mol' kunits, kunits_low, kfactor, numReactants = getRateCoefficientUnits(kinetics, user=user) Tfactor = Quantity(1, Tunits).getConversionFactorFromSI() Pfactor = Quantity(1, Punits).getConversionFactorFromSI() Efactor = Quantity(1, Eunits).getConversionFactorFromSI() if kunits == 's^-1': kunits = 's^{-1}' # The string that will be returned to the template result = '' if isinstance(kinetics, Arrhenius): # The kinetics is in Arrhenius format result += r'<div class="math">k(T) = {0!s}</div>'.format(getArrheniusJSMath( kinetics.A.value * kfactor, kunits, kinetics.n.value, '', kinetics.Ea.value * Efactor, Eunits, kinetics.T0.value * Tfactor, Tunits, )) elif isinstance(kinetics, ArrheniusEP): # The kinetics is in ArrheniusEP format result += r'<div class="math">k(T) = {0!s}'.format(getLaTeXScientificNotation(kinetics.A.value * kfactor)) if kinetics.n.value != 0: result += r' T^{{ {0:.2f} }}'.format(kinetics.n.value) result += r' \exp \left( - \, \frac{{ {0:.2f} \ \mathrm{{ {1!s} }} + {2:.2f} \Delta H_\mathrm{{rxn}}^\circ }}{{ R T }} \right)'.format(kinetics.E0.value * Efactor, Eunits, kinetics.alpha.value) result += ' \ \mathrm{{ {0!s} }}</div>'.format(kunits) elif isinstance(kinetics, KineticsData): # The kinetics is in KineticsData format result += r'<table class="KineticsData">' result += r'<tr><th>Temperature</th><th>Rate coefficient</th></tr>' for T, k in zip(kinetics.Tdata.values, kinetics.kdata.values): result += r'<tr><td><span class="math">{0:g} \ \mathrm{{ {1!s} }}</span></td><td><span class="math">{2!s} \ \mathrm{{ {3!s} }}</span></td></tr>'.format(T * Tfactor, Tunits, getLaTeXScientificNotation(k * kfactor), kunits) result += r'</table>' # fit to an arrhenius arr = kinetics.toArrhenius() result += "Fitted to an Arrhenius:" result += r'<div class="math">k(T) = {0!s}</div>'.format(getArrheniusJSMath( arr.A.value * kfactor, kunits, arr.n.value, '', arr.Ea.value * Efactor, Eunits, arr.T0.value * Tfactor, Tunits, )) elif isinstance(kinetics, PDepArrhenius): # The kinetics is in PDepArrhenius format for P, arrh in zip(kinetics.pressures.values, kinetics.arrhenius): result += r'<div class="math">k(T, \ {0:g} \ \mathrm{{ {1!s} }}) = {2}</div>'.format( P * Pfactor, Punits, getArrheniusJSMath( arrh.A.value * kfactor, kunits, arrh.n.value, '', arrh.Ea.value * Efactor, Eunits, arrh.T0.value * Tfactor, Tunits, ), ) elif isinstance(kinetics, Chebyshev): # The kinetics is in Chebyshev format result += r"""<div class="math"> \begin{split} \log k(T,P) &= \sum_{t=1}^{N_T} \sum_{p=1}^{N_P} C_{tp} \phi_t(\tilde{T}) \phi_p(\tilde{P}) [\mathrm{ {{ kineticsParameters.coeffs.1 }} }] \\ \tilde{T} &\equiv \frac{2T^{-1} - T_\mathrm{min}^{-1} - T_\mathrm{max}^{-1}}{T_\mathrm{max}^{-1} - T_\mathrm{min}^{-1}} \\ \tilde{P} &\equiv \frac{2 \log P - \log P_\mathrm{min} - \log P_\mathrm{max}}{\log P_\mathrm{max} - \log P_\mathrm{min}} \end{split}</div><br/> <div class="math">\mathbf{C} = \begin{bmatrix} """ for t in range(kinetics.degreeT): for p in range(kinetics.degreeP): if p > 0: result += ' & ' result += '{0:g}'.format(kinetics.coeffs[t,p]) result += '\\\\ \n' result += '\end{bmatrix}</div>' elif isinstance(kinetics, Troe): # The kinetics is in Troe format Fcent = r'(1 - \alpha) \exp \left( -T/T_3 \right) + \alpha \exp \left( -T/T_1 \right) + \exp \left( -T_2/T \right)' if kinetics.T2 is not None: Fcent += r' + \exp \left( -T_2/T \right)' result += r"""<div class="math"> \begin{{split}} k(T,P) &= k_\infty(T) \left[ \frac{{P_\mathrm{{r}}}}{{1 + P_\mathrm{{r}}}} \right] F \\ P_\mathrm{{r}} &= \frac{{k_0(T)}}{{k_\infty(T)}} [\mathrm{{M}}] \\ \log F &= \left\{{1 + \left[ \frac{{\log P_\mathrm{{r}} + c}}{{n - d (\log P_\mathrm{{r}} + c)}} \right]^2 \right\}}^{{-1}} \log F_\mathrm{{cent}} \\ c &= -0.4 - 0.67 \log F_\mathrm{{cent}} \\ n &= 0.75 - 1.27 \log F_\mathrm{{cent}} \\ d &= 0.14 \\ F_\mathrm{{cent}} &= {0} \end{{split}} </div><div class="math">\begin{{split}} """.format(Fcent) result += r'k_\infty(T) &= {0!s} \\'.format(getArrheniusJSMath( kinetics.arrheniusHigh.A.value * kfactor, kunits, kinetics.arrheniusHigh.n.value, '', kinetics.arrheniusHigh.Ea.value * Efactor, Eunits, kinetics.arrheniusHigh.T0.value * Tfactor, Tunits, )) result += r'k_0(T) &= {0!s} \\'.format(getArrheniusJSMath( kinetics.arrheniusLow.A.value * kfactor * kfactor, kunits_low, kinetics.arrheniusLow.n.value, '', kinetics.arrheniusLow.Ea.value * Efactor, Eunits, kinetics.arrheniusLow.T0.value * Tfactor, Tunits, )) result += r'\alpha &= {0:g} \\'.format(kinetics.alpha.value) result += r'T_3 &= {0:g} \ \mathrm{{ {1!s} }} \\'.format(kinetics.T3.value * Tfactor, Tunits) result += r'T_1 &= {0:g} \ \mathrm{{ {1!s} }} \\'.format(kinetics.T1.value * Tfactor, Tunits) if kinetics.T2 is not None: result += r'T_2 &= {0:g} \ \mathrm{{ {1!s} }} \\'.format(kinetics.T2.value * Tfactor, Tunits) result += r'\end{split}</div>' elif isinstance(kinetics, Lindemann): # The kinetics is in Lindemann format result += r"""<div class="math"> \begin{{split}} k(T,P) &= k_\infty(T) \left[ \frac{{P_\mathrm{{r}}}}{{1 + P_\mathrm{{r}}}} \right] \\ P_\mathrm{{r}} &= \frac{{k_0(T)}}{{k_\infty(T)}} [\mathrm{{M}}] \\ \end{{split}} </div><div class="math">\begin{{split}} """.format() result += r'k_\infty(T) &= {0!s} \\'.format(getArrheniusJSMath( kinetics.arrheniusHigh.A.value * kfactor, kunits, kinetics.arrheniusHigh.n.value, '', kinetics.arrheniusHigh.Ea.value * Efactor, Eunits, kinetics.arrheniusHigh.T0.value * Tfactor, Tunits, )) result += r'k_0(T) &= {0!s} \\'.format(getArrheniusJSMath( kinetics.arrheniusLow.A.value * kfactor * kfactor, kunits_low, kinetics.arrheniusLow.n.value, '', kinetics.arrheniusLow.Ea.value * Efactor, Eunits, kinetics.arrheniusLow.T0.value * Tfactor, Tunits, )) result += r'\end{split}</div>' elif isinstance(kinetics, ThirdBody): # The kinetics is in ThirdBody format result += r"""<div class="math"> k(T,P) = k_0(T) [\mathrm{{M}}] </div><div class="math"> """.format() result += r'k_0(T) = {0!s}'.format(getArrheniusJSMath( kinetics.arrheniusHigh.A.value * kfactor * kfactor, kunits_low, kinetics.arrheniusHigh.n.value, '', kinetics.arrheniusHigh.Ea.value * Efactor, Eunits, kinetics.arrheniusHigh.T0.value * Tfactor, Tunits, )) result += '</div>' elif isinstance(kinetics, MultiKinetics): # The kinetics is in MultiKinetics format result = '' start = '' for i, k in enumerate(kinetics.kineticsList): res = render_kinetics_math(k, user=user) start += '{0} + '.format(res.split(' = ')[0].replace('<div class="math">k(T', 'k_{{ {0:d} }}(T'.format(i+1), 1)) result += res.replace('k(T', 'k_{{ {0:d} }}(T'.format(i+1), 1) + '<br/>' result = r"""<div class="math"> k(T,P) = {0!s} </div><br/> """.format(start[:-3]) + result # Collision efficiencies if hasattr(kinetics, 'efficiencies'): result += '<table>\n' result += '<tr><th colspan="2">Collision efficiencies</th></tr>' for smiles, eff in kinetics.efficiencies.iteritems(): result += '<tr><td>{0}</td><td>{1:g}</td></tr>\n'.format(getStructureMarkup(smiles), eff) result += '</table><br/>\n' # Temperature and pressure ranges result += '<table class="kineticsEntryData">' if kinetics.Tmin is not None and kinetics.Tmax is not None: result += '<tr><td class="key">Temperature range</td><td class="equals">=</td><td class="value">{0:g} to {1:g} {2!s}</td></tr>'.format(kinetics.Tmin.value * Tfactor, kinetics.Tmax.value * Tfactor, Tunits) if kinetics.Pmin is not None and kinetics.Pmax is not None: result += '<tr><td class="key">Pressure range</td><td class="equals">=</td><td class="value">{0:g} to {1:g} {2!s}</td></tr>'.format(kinetics.Pmin.value * Pfactor, kinetics.Pmax.value * Pfactor, Punits) result += '</table>' return mark_safe(result)
def render_kinetics_math(kinetics, user=None): """ Return a math representation of the given `kinetics` using MathJax. If a `user` is specified, the user's preferred units will be used; otherwise default units will be used. """ if kinetics is None: return mark_safe("<p>There are no kinetics for this entry.</p>") # Define other units and conversion factors to use if user and user.is_authenticated: user_profile = UserProfile.objects.get(user=user) Tunits = user_profile.temperature_units Punits = user_profile.pressure_units Eunits = user_profile.energy_units else: Tunits = 'K' Punits = 'Pa' Eunits = 'J/mol' kunits, kunits_low, kfactor = getRateCoefficientUnits(kinetics, user=user) Tfactor = Quantity(1, Tunits).get_conversion_factor_from_si() Pfactor = Quantity(1, Punits).get_conversion_factor_from_si() Efactor = Quantity(1, Eunits).get_conversion_factor_from_si() if kunits == 's^-1': kunits = 's^{-1}' # The string that will be returned to the template result = '' if isinstance(kinetics, (Arrhenius, SurfaceArrhenius, StickingCoefficient)): # The kinetics is in Arrhenius format result += r'<script type="math/tex; mode=display">k(T) = {0!s}</script>'.format(getArrheniusJSMath( kinetics.A.value_si * kfactor, kunits, kinetics.n.value_si, '', kinetics.Ea.value_si * Efactor, Eunits, kinetics.T0.value_si * Tfactor, Tunits, )) elif isinstance(kinetics, (ArrheniusEP, SurfaceArrheniusBEP, StickingCoefficientBEP)): # The kinetics is in ArrheniusEP format result += r'<script type="math/tex; mode=display">k(T) = {0!s}'.format(getLaTeXScientificNotation(kinetics.A.value_si * kfactor)) if kinetics.n.value_si != 0: result += r' T^{{ {0:.2f} }}'.format(kinetics.n.value_si) result += r' \exp \left( - \, \frac{{ {0:.2f} \ \mathrm{{ {1!s} }} + {2:.2f} \Delta H_\mathrm{{rxn}}^\circ }}{{ R T }} \right)'.format(kinetics.E0.value_si * Efactor, Eunits, kinetics.alpha.value_si) result += r' \ \mathrm{{ {0!s} }}</script>'.format(kunits) elif isinstance(kinetics, ArrheniusBM): # The kinetics is in ArrheniusBM format result += r'<script type="math/tex; mode=display">\begin{{split}}k(T) &= {0!s}'.format(getLaTeXScientificNotation(kinetics.A.value_si * kfactor)) if kinetics.n.value_si != 0: result += r' T^{{ {0:.2f} }}' .format(kinetics.n.value_si) result += r' \exp \left(- \, \frac{{ E_\mathrm{{a}} }}{{RT}} \right) \ \mathrm{{ {0!s} }} \\'.format(kunits) result += r''' E_\mathrm{{a}} &= \frac{{ \left( w_{{0}} + 0.5 \Delta H_\mathrm{{rxn}} \right) \left( V_\mathrm{{p}} - 2 w_{{0}} + \Delta H_\mathrm{{rxn}} \right) ^ {{2}} }} {{ V_\mathrm{{p}} ^ {{2}} - \left( 2 w_{{0}} \right) ^ {{2}} + \Delta H_\mathrm{{rxn}} ^ {{2}} }} \\ V_\mathrm{{p}} &= 2 w_{{0}} \left( \frac{{ w_{{0}} + E_{{0}} }} {{ w_{{0}} - E_{{0}} }} \right) \\ w_{{0}} &= {0:.2f}\ \mathrm{{ {1!s} }} \\ E_{{0}} &= {2:.2f}\ \mathrm{{ {1!s} }} \end{{split}}</script> '''.format(kinetics.w0.value_si * Efactor, Eunits, kinetics.E0.value_si * Efactor) elif isinstance(kinetics, KineticsData): # The kinetics is in KineticsData format result += r'<table class="KineticsData">' result += r'<tr><th>Temperature</th><th>Rate coefficient</th></tr>' for T, k in zip(kinetics.Tdata.value_si, kinetics.kdata.value_si): result += r'<tr><td><script type="math/tex">{0:g} \ \mathrm{{ {1!s} }}</script></td><td><script type="math/tex">{2!s} \ \mathrm{{ {3!s} }}</script></td></tr>'.format(T * Tfactor, Tunits, getLaTeXScientificNotation(k * kfactor), kunits) result += r'</table>' # fit to an arrhenius arr = kinetics.to_arrhenius() result += "Fitted to an Arrhenius:" result += r'<script type="math/tex; mode=display">k(T) = {0!s}</script>'.format(getArrheniusJSMath( arr.A.value_si * kfactor, kunits, arr.n.value_si, '', arr.Ea.value_si * Efactor, Eunits, arr.T0.value_si * Tfactor, Tunits, )) elif isinstance(kinetics, PDepArrhenius): # The kinetics is in PDepArrhenius format for P, arrh in zip(kinetics.pressures.value_si, kinetics.arrhenius): if isinstance(arrh, Arrhenius): result += r'<script type="math/tex; mode=display">k(T, {0} \mathrm{{ {1!s} }}) = {2}</script>'.format( getLaTeXScientificNotation(P * Pfactor), Punits, getArrheniusJSMath( arrh.A.value_si * kfactor, kunits, arrh.n.value_si, '', arrh.Ea.value_si * Efactor, Eunits, arrh.T0.value_si * Tfactor, Tunits, ), ) elif isinstance(arrh, MultiArrhenius): start = (r'<script type="math/tex; mode=display">' r'k(T, {0} \mathrm{{ {1!s} }}) = '.format(getLaTeXScientificNotation(P * Pfactor), Punits)) res = '' for i, k in enumerate(arrh.arrhenius): start += 'k_{{ {0:d} }}(T, {1} \mathrm{{ {2!s} }}) + '.format(i + 1, getLaTeXScientificNotation(P * Pfactor), Punits) res += r'<script type="math/tex; mode=display">k_{{ {0:d} }}(T, {1} \mathrm{{ {2!s} }}) = {3}</script>'.format( i + 1, getLaTeXScientificNotation(P * Pfactor), Punits, getArrheniusJSMath( k.A.value_si * kfactor, kunits, k.n.value_si, '', k.Ea.value_si * Efactor, Eunits, k.T0.value_si * Tfactor, Tunits, ), ) result += start[:-3] + '</script>\n' + res + '<br/>' elif isinstance(kinetics, Chebyshev): # The kinetics is in Chebyshev format result += r"""<script type="math/tex; mode=display"> \begin{split} \log k(T,P) &= \sum_{t=1}^{N_T} \sum_{p=1}^{N_P} C_{tp} \phi_t(\tilde{T}) \phi_p(\tilde{P}) [\mathrm{""" + kinetics.kunits + r""" }] \\ \tilde{T} &\equiv \frac{2T^{-1} - T_\mathrm{min}^{-1} - T_\mathrm{max}^{-1}}{T_\mathrm{max}^{-1} - T_\mathrm{min}^{-1}} \\ \tilde{P} &\equiv \frac{2 \log P - \log P_\mathrm{min} - \log P_\mathrm{max}}{\log P_\mathrm{max} - \log P_\mathrm{min}} \end{split}</script><br/> <script type="math/tex; mode=display">\mathbf{C} = \begin{bmatrix} """ for t in range(kinetics.degreeT): for p in range(kinetics.degreeP): if p > 0: result += ' & ' result += '{0:g}'.format(kinetics.coeffs.value_si[t, p]) result += '\\\\ \n' result += '\end{bmatrix}</script>' elif isinstance(kinetics, Troe): # The kinetics is in Troe format Fcent = r'(1 - \alpha) \exp \left( -T/T_3 \right) + \alpha \exp \left( -T/T_1 \right) + \exp \left( -T_2/T \right)' if kinetics.T2 is not None: Fcent += r' + \exp \left( -T_2/T \right)' result += r"""<script type="math/tex; mode=display"> \begin{{split}} k(T,P) &= k_\infty(T) \left[ \frac{{P_\mathrm{{r}}}}{{1 + P_\mathrm{{r}}}} \right] F \\ P_\mathrm{{r}} &= \frac{{k_0(T)}}{{k_\infty(T)}} [\mathrm{{M}}] \\ \log F &= \left\{{1 + \left[ \frac{{\log P_\mathrm{{r}} + c}}{{n - d (\log P_\mathrm{{r}} + c)}} \right]^2 \right\}}^{{-1}} \log F_\mathrm{{cent}} \\ c &= -0.4 - 0.67 \log F_\mathrm{{cent}} \\ n &= 0.75 - 1.27 \log F_\mathrm{{cent}} \\ d &= 0.14 \\ F_\mathrm{{cent}} &= {0} \end{{split}} </script><script type="math/tex; mode=display">\begin{{split}} """.format(Fcent) result += r'k_\infty(T) &= {0!s} \\'.format(getArrheniusJSMath( kinetics.arrheniusHigh.A.value_si * kfactor, kunits, kinetics.arrheniusHigh.n.value_si, '', kinetics.arrheniusHigh.Ea.value_si * Efactor, Eunits, kinetics.arrheniusHigh.T0.value_si * Tfactor, Tunits, )) result += r'k_0(T) &= {0!s} \\'.format(getArrheniusJSMath( kinetics.arrheniusLow.A.value_si * kfactor * kfactor, kunits_low, kinetics.arrheniusLow.n.value_si, '', kinetics.arrheniusLow.Ea.value_si * Efactor, Eunits, kinetics.arrheniusLow.T0.value_si * Tfactor, Tunits, )) result += r'\alpha &= {0:g} \\'.format(kinetics.alpha) result += r'T_3 &= {0:g} \ \mathrm{{ {1!s} }} \\'.format(kinetics.T3.value_si * Tfactor, Tunits) result += r'T_1 &= {0:g} \ \mathrm{{ {1!s} }} \\'.format(kinetics.T1.value_si * Tfactor, Tunits) if kinetics.T2 is not None: result += r'T_2 &= {0:g} \ \mathrm{{ {1!s} }} \\'.format(kinetics.T2.value_si * Tfactor, Tunits) result += r'\end{split}</script>' elif isinstance(kinetics, Lindemann): # The kinetics is in Lindemann format result += r"""<script type="math/tex; mode=display"> \begin{{split}} k(T,P) &= k_\infty(T) \left[ \frac{{P_\mathrm{{r}}}}{{1 + P_\mathrm{{r}}}} \right] \\ P_\mathrm{{r}} &= \frac{{k_0(T)}}{{k_\infty(T)}} [\mathrm{{M}}] \\ \end{{split}} </script><script type="math/tex; mode=display">\begin{{split}} """.format() result += r'k_\infty(T) &= {0!s} \\'.format(getArrheniusJSMath( kinetics.arrheniusHigh.A.value_si * kfactor, kunits, kinetics.arrheniusHigh.n.value_si, '', kinetics.arrheniusHigh.Ea.value_si * Efactor, Eunits, kinetics.arrheniusHigh.T0.value_si * Tfactor, Tunits, )) result += r'k_0(T) &= {0!s} \\'.format(getArrheniusJSMath( kinetics.arrheniusLow.A.value_si * kfactor * kfactor, kunits_low, kinetics.arrheniusLow.n.value_si, '', kinetics.arrheniusLow.Ea.value_si * Efactor, Eunits, kinetics.arrheniusLow.T0.value_si * Tfactor, Tunits, )) result += r'\end{split}</script>' elif isinstance(kinetics, ThirdBody): # The kinetics is in ThirdBody format result += r"""<script type="math/tex; mode=display"> k(T,P) = k_0(T) [\mathrm{{M}}] </script><script type="math/tex; mode=display"> """.format() result += r'k_0(T) = {0!s}'.format(getArrheniusJSMath( kinetics.arrheniusLow.A.value_si * kfactor * kfactor, kunits_low, kinetics.arrheniusLow.n.value_si, '', kinetics.arrheniusLow.Ea.value_si * Efactor, Eunits, kinetics.arrheniusLow.T0.value_si * Tfactor, Tunits, )) result += '</script>' elif isinstance(kinetics, (MultiArrhenius, MultiPDepArrhenius)): # The kinetics is in MultiArrhenius or MultiPDepArrhenius format result = '' start = r'<script type="math/tex; mode=display">k(T, P) = ' for i, k in enumerate(kinetics.arrhenius): res = render_kinetics_math(k, user=user) start += 'k_{{ {0:d} }}(T, P) + '.format(i+1) result += res.replace('k(T', 'k_{{ {0:d} }}(T'.format(i+1)) + '<br/>' result = start[:-3] + '</script><br/>' + result # Collision efficiencies if hasattr(kinetics, 'efficiencies') and kinetics.efficiencies: result += '<table>\n' result += '<tr><th colspan="2">Collision efficiencies</th></tr>' for smiles, eff in kinetics.efficiencies.items(): result += '<tr><td>{0}</td><td>{1:g}</td></tr>\n'.format(getStructureMarkup(smiles), eff) result += '</table><br/>\n' # Temperature and pressure ranges result += '<table class="kineticsEntryData">' if kinetics.Tmin is not None and kinetics.Tmax is not None: result += '<tr><td class="key">Temperature range</td><td class="equals">=</td><td class="value">{0:g} to {1:g} {2!s}</td></tr>'.format(kinetics.Tmin.value_si * Tfactor, kinetics.Tmax.value_si * Tfactor, Tunits) if kinetics.Pmin is not None and kinetics.Pmax is not None: result += '<tr><td class="key">Pressure range</td><td class="equals">=</td><td class="value">{0:g} to {1:g} {2!s}</td></tr>'.format(kinetics.Pmin.value_si * Pfactor, kinetics.Pmax.value_si * Pfactor, Punits) result += '</table>' return mark_safe(result)