<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <atom:link href="http://kitchingroup.cheme.cmu.edu/blog/feed/index.xml" rel="self" type="application/rss+xml" />
    <title>The Kitchin Research Group</title>
    <link>https://kitchingroup.cheme.cmu.edu/blog</link>
    <description>Chemical Engineering at Carnegie Mellon University</description>
    <pubDate>Sat, 01 Nov 2025 13:47:46 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    
    <item>
      <title>Using events in odelay with multiple equations</title>
      <link>https://kitchingroup.cheme.cmu.edu/blog/2013/09/19/Using-events-in-odelay-with-multiple-equations</link>
      <pubDate>Thu, 19 Sep 2013 10:33:57 EDT</pubDate>
      <category><![CDATA[odes]]></category>
      <guid isPermaLink="false">MiO1XcdCK3eQ-SMVjDzj-kwL2V0=</guid>
      <description>Using events in odelay with multiple equations</description>
      <content:encoded><![CDATA[



&lt;p&gt;
&lt;code&gt;odelay&lt;/code&gt; was recently updated to support multiple odes with events. Here is an example. We want the solutions to:
&lt;/p&gt;

\begin{align}
\frac{dy_1}{dx} = y_2 \\
\frac{dy_2}{dx} = -y_1
\end{align}

&lt;p&gt;
with initial conditions \(y_1(0) = 2\) and \(y_2(0) = 1\). We want to stop the integration when \(y_2 = -1\) and find out when \(dy_1/dx=0\) and at a maximum.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; pycse &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; odelay
&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; matplotlib.pyplot &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; plt
&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; numpy &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; np

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;ode&lt;/span&gt;(Y,x):
    &lt;span style="color: #8b008b;"&gt;y1&lt;/span&gt;, &lt;span style="color: #8b008b;"&gt;y2&lt;/span&gt; = Y
    &lt;span style="color: #8b008b;"&gt;dy1dx&lt;/span&gt; = y2
    &lt;span style="color: #8b008b;"&gt;dy2dx&lt;/span&gt; = -y1
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; [dy1dx, dy2dx]

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;event1&lt;/span&gt;(Y, x):
    &lt;span style="color: #8b008b;"&gt;y1&lt;/span&gt;, &lt;span style="color: #8b008b;"&gt;y2&lt;/span&gt; = Y
    &lt;span style="color: #8b008b;"&gt;value&lt;/span&gt; = y2 - (-1.0)
    &lt;span style="color: #8b008b;"&gt;isterminal&lt;/span&gt; = &lt;span style="color: #cd0000;"&gt;True&lt;/span&gt;
    &lt;span style="color: #8b008b;"&gt;direction&lt;/span&gt;  = 0
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; value, isterminal, direction

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;event2&lt;/span&gt;(Y, x):
    &lt;span style="color: #8b008b;"&gt;dy1dx&lt;/span&gt;, &lt;span style="color: #8b008b;"&gt;dy2dx&lt;/span&gt; = ode(Y,x)
    &lt;span style="color: #8b008b;"&gt;value&lt;/span&gt; = dy1dx - 0.0
    &lt;span style="color: #8b008b;"&gt;isterminal&lt;/span&gt; = &lt;span style="color: #cd0000;"&gt;False&lt;/span&gt;
    &lt;span style="color: #8b008b;"&gt;direction&lt;/span&gt; = -1  &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;derivative is decreasing towards a maximum&lt;/span&gt;
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; value, isterminal, direction

&lt;span style="color: #8b008b;"&gt;Y0&lt;/span&gt; = [2.0, 1.0]
&lt;span style="color: #8b008b;"&gt;xspan&lt;/span&gt; = np.linspace(0, 5)
&lt;span style="color: #8b008b;"&gt;X&lt;/span&gt;, &lt;span style="color: #8b008b;"&gt;Y&lt;/span&gt;, &lt;span style="color: #8b008b;"&gt;XE&lt;/span&gt;, &lt;span style="color: #8b008b;"&gt;YE&lt;/span&gt;, &lt;span style="color: #8b008b;"&gt;IE&lt;/span&gt; = odelay(ode, Y0, xspan, events=[event1, event2])

plt.plot(X, Y)
&lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; ie,xe,ye &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;zip&lt;/span&gt;(IE, XE, YE):
    &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; ie == 1: &lt;span style="color: #ff0000; font-weight: bold;"&gt;#&lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;this is the second event&lt;/span&gt;
        &lt;span style="color: #8b008b;"&gt;y1&lt;/span&gt;,y2 = ye
        plt.plot(xe, y1, &lt;span style="color: #228b22;"&gt;'ro'&lt;/span&gt;) 
        
plt.legend([&lt;span style="color: #228b22;"&gt;'$y_1$'&lt;/span&gt;, &lt;span style="color: #228b22;"&gt;'$y_2$'&lt;/span&gt;], loc=&lt;span style="color: #228b22;"&gt;'best'&lt;/span&gt;)
plt.savefig(&lt;span style="color: #228b22;"&gt;'images/odelay-mult-eq.png'&lt;/span&gt;)
plt.show()
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
Here are the plotted results:
&lt;p&gt;&lt;img src="/img/./images/odelay-mult-eq.png"&gt;&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;Copyright (C) 2013 by John Kitchin. See the &lt;a href="/copying.html"&gt;License&lt;/a&gt; for information about copying.&lt;p&gt;&lt;p&gt;&lt;a href="/org/2013/09/19/Using-events-in-odelay-with-multiple-equations.org"&gt;org-mode source&lt;/a&gt;&lt;p&gt;]]></content:encoded>
    </item>
    <item>
      <title>Units in ODEs</title>
      <link>https://kitchingroup.cheme.cmu.edu/blog/2013/03/25/Units-in-ODEs</link>
      <pubDate>Mon, 25 Mar 2013 09:58:55 EDT</pubDate>
      <category><![CDATA[odes]]></category>
      <category><![CDATA[units]]></category>
      <guid isPermaLink="false">FdTHKq-uXguv32LWpkuvJNDxF3g=</guid>
      <description>Units in ODEs</description>
      <content:encoded><![CDATA[


&lt;p&gt;
We reconsider a simple ODE but this time with units. We will use the quantities package again. 
&lt;/p&gt;

&lt;p&gt;
Here is the ODE, \(\frac{dCa}{dt} = -k Ca\) with \(C_A(0) = 1.0\) mol/L and \(k = 0.23\) 1/s. Compute the concentration after 5 s.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; quantities &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; u

k = 0.23 / u.s
Ca0 = 1 * u.mol / u.L

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;dCadt&lt;/span&gt;(Ca, t):
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; -k * Ca

&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; numpy &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; np
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scipy.integrate &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; odeint

tspan = np.linspace(0, 5) * u.s

sol = odeint(dCadt, Ca0, tspan)

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; sol[-1]
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
[ 0.31663678]
&lt;/pre&gt;

&lt;p&gt;
No surprise, the units are lost. Now we start wrapping odeint. We wrap everything, and then test two examples including a single ODE, and a coupled set of ODEs with mixed units.
&lt;/p&gt;


&lt;div class="org-src-container"&gt;

&lt;pre class="src src-python"&gt;&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; quantities &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; u
&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; matplotlib.pyplot &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; plt

&lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; numpy &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; np
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scipy.integrate &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; odeint &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; _odeint

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;odeint&lt;/span&gt;(func, y0, t, args=(),
           Dfun=&lt;span style="color: #8b0000;"&gt;None&lt;/span&gt;, col_deriv=0, full_output=0,
           ml=&lt;span style="color: #8b0000;"&gt;None&lt;/span&gt;, mu=&lt;span style="color: #8b0000;"&gt;None&lt;/span&gt;, rtol=&lt;span style="color: #8b0000;"&gt;None&lt;/span&gt;, atol=&lt;span style="color: #8b0000;"&gt;None&lt;/span&gt;,
           tcrit=&lt;span style="color: #8b0000;"&gt;None&lt;/span&gt;, h0=0.0, hmax=0.0, hmin=0.0,
           ixpr=0, mxstep=0, mxhnil=0, mxordn=12,
           mxords=5, printmessg=0):

    &lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;wrapped_func&lt;/span&gt;(Y0, T, *args):
        &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;put units on T if they are on the original t&lt;/span&gt;
        &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;check for units so we don't put them on twice&lt;/span&gt;
        &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;not&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;hasattr&lt;/span&gt;(T, &lt;span style="color: #228b22;"&gt;'units'&lt;/span&gt;) &lt;span style="color: #8b0000;"&gt;and&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;hasattr&lt;/span&gt;(t, &lt;span style="color: #228b22;"&gt;'units'&lt;/span&gt;):
            T = T * t.units
        &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;now for the dependent variable units. Y0 may be a scalar or&lt;/span&gt;
        &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;a list or an array. we want to check each element of y0 for&lt;/span&gt;
        &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;units, and add them to the corresponding element of Y0 if we&lt;/span&gt;
        &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;need to.&lt;/span&gt;
        &lt;span style="color: #8b0000;"&gt;try:&lt;/span&gt;
            uY0 = [x &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; x &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; Y0] &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;a list copy of contents of Y0&lt;/span&gt;
            &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;this works if y0 is an iterable, eg. a list or array&lt;/span&gt;
            &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; i, yi &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;enumerate&lt;/span&gt;(y0):
                &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;not&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;hasattr&lt;/span&gt;(uY0[i],&lt;span style="color: #228b22;"&gt;'units'&lt;/span&gt;) &lt;span style="color: #8b0000;"&gt;and&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;hasattr&lt;/span&gt;(yi, &lt;span style="color: #228b22;"&gt;'units'&lt;/span&gt;):
               
                    uY0[i] = uY0[i] * yi.units
                
        &lt;span style="color: #8b0000;"&gt;except&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;TypeError&lt;/span&gt;:
            &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;we have a scalar&lt;/span&gt;
            &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;not&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;hasattr&lt;/span&gt;(Y0, &lt;span style="color: #228b22;"&gt;'units'&lt;/span&gt;) &lt;span style="color: #8b0000;"&gt;and&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;hasattr&lt;/span&gt;(y0, &lt;span style="color: #228b22;"&gt;'units'&lt;/span&gt;):
                uY0 = Y0 * y0.units
       
        val = func(uY0, t, *args)

        &lt;span style="color: #8b0000;"&gt;try:&lt;/span&gt;
            &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; np.array([&lt;span style="color: #8b0000;"&gt;float&lt;/span&gt;(x) &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; x &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; val])
        &lt;span style="color: #8b0000;"&gt;except&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;TypeError&lt;/span&gt;:
            &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;float&lt;/span&gt;(val)
    
    &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; full_output:
        y, infodict = _odeint(wrapped_func, y0, t, args,
                              Dfun, col_deriv, full_output,
                              ml, mu, rtol, atol,
                              tcrit, h0, hmax, hmin,
                              ixpr, mxstep, mxhnil, mxordn,
                              mxords, printmessg)
    &lt;span style="color: #8b0000;"&gt;else:&lt;/span&gt;
        y = _odeint(wrapped_func, y0, t, args,
                    Dfun, col_deriv, full_output,
                    ml, mu, rtol, atol,
                    tcrit, h0, hmax, hmin,
                    ixpr, mxstep, mxhnil, mxordn,
                    mxords, printmessg)

    &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;now we need to put units onto the solution units should be the&lt;/span&gt;
    &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;same as y0. We cannot put mixed units in an array, so, we return a list&lt;/span&gt;
    m,n = y.shape &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;y is an ndarray, so it has a shape&lt;/span&gt;
    &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; n &amp;gt; 1: &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;more than one equation, we need a list&lt;/span&gt;
        uY = [0 &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; yi &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;range&lt;/span&gt;(n)]
        
        &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; i, yi &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;enumerate&lt;/span&gt;(y0):
            &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;not&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;hasattr&lt;/span&gt;(uY[i],&lt;span style="color: #228b22;"&gt;'units'&lt;/span&gt;) &lt;span style="color: #8b0000;"&gt;and&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;hasattr&lt;/span&gt;(yi, &lt;span style="color: #228b22;"&gt;'units'&lt;/span&gt;):
                uY[i] = y[:,i] * yi.units
            &lt;span style="color: #8b0000;"&gt;else:&lt;/span&gt;
                uY[i] = y[:,i]
                
    &lt;span style="color: #8b0000;"&gt;else:&lt;/span&gt;
        uY = y * y0.units

    y = uY


    &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; full_output:
        &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; y, infodict
    &lt;span style="color: #8b0000;"&gt;else:&lt;/span&gt;
        &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; y

&lt;span style="color: #ff0000; font-weight: bold;"&gt;#&lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;#################################################################&lt;/span&gt;
&lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;test a single ODE&lt;/span&gt;
k = 0.23 / u.s
Ca0 = 1 * u.mol / u.L

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;dCadt&lt;/span&gt;(Ca, t):
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; -k * Ca

tspan = np.linspace(0, 5) * u.s
sol = odeint(dCadt, Ca0, tspan)

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; sol[-1]

plt.plot(tspan, sol)
plt.xlabel(&lt;span style="color: #228b22;"&gt;'Time ({0})'&lt;/span&gt;.format(tspan.dimensionality.latex))
plt.ylabel(&lt;span style="color: #228b22;"&gt;'$C_A$ ({0})'&lt;/span&gt;.format(sol.dimensionality.latex))
plt.savefig(&lt;span style="color: #228b22;"&gt;'images/ode-units-ca.png'&lt;/span&gt;)

&lt;span style="color: #ff0000; font-weight: bold;"&gt;#&lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;#################################################################&lt;/span&gt;
&lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;test coupled ODEs&lt;/span&gt;
lbmol = 453.59237*u.mol

kprime = 0.0266 * lbmol / u.hr / u.lb
Fa0 = 1.08 * lbmol / u.hr
alpha = 0.0166 / u.lb
epsilon = -0.15

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;dFdW&lt;/span&gt;(F, W, alpha0):
    X, y = F
    dXdW = kprime / Fa0 * (1.0 - X)/(1.0 + epsilon * X) * y
    dydW = - alpha0 * (1.0 + epsilon * X) / (2.0 * y)
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; [dXdW, dydW]

X0 = 0.0 * u.dimensionless
y0 = 1.0

&lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;initial conditions&lt;/span&gt;
F0 = [X0, y0] &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;one without units, one with units, both are dimensionless&lt;/span&gt;

wspan = np.linspace(0,60) * u.lb

sol = odeint(dFdW, F0, wspan, args=(alpha,))
X, y = sol

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'Test 2'&lt;/span&gt;
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; X[-1]
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; y[-1]

plt.figure()
plt.plot(wspan, X, wspan, y)
plt.legend([&lt;span style="color: #228b22;"&gt;'X'&lt;/span&gt;,&lt;span style="color: #228b22;"&gt;'$P/P_0$'&lt;/span&gt;])
plt.xlabel(&lt;span style="color: #228b22;"&gt;'Catalyst weight ({0})'&lt;/span&gt;.format(wspan.dimensionality.latex))
plt.savefig(&lt;span style="color: #228b22;"&gt;'images/ode-coupled-units-pdrpo.png'&lt;/span&gt;)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
[ 0.31663678] mol/L
Test 2
0.665569578156 dimensionless
0.263300470681
&lt;/pre&gt;

&lt;p&gt;&lt;img src="/img/./images/ode-units-ca.png"&gt;&lt;p&gt;

&lt;p&gt;&lt;img src="/img/./images/ode-coupled-units-pdrpo.png"&gt;&lt;p&gt;

&lt;p&gt;
That is not too bad. This is another example of a function you would want to save in a module for reuse. There is one bad feature of the wrapped odeint function, and that is that it changes the solution for coupled ODEs from an ndarray to a list. That is necessary because you apparently cannot have mixed units in an ndarray. It is fine, however, to have a list of mixed units. This is not a huge problem, but it changes the syntax for plotting results for the wrapped odeint function compared to the unwrapped function without units. 
&lt;/p&gt;
&lt;p&gt;Copyright (C) 2013 by John Kitchin. See the &lt;a href="/copying.html"&gt;License&lt;/a&gt; for information about copying.&lt;p&gt;&lt;p&gt;&lt;a href="/org/2013/03/25/Units-in-ODEs.org"&gt;org-mode source&lt;/a&gt;&lt;p&gt;]]></content:encoded>
    </item>
  </channel>
</rss>
