<?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>Handling units with dimensionless equations</title>
      <link>https://kitchingroup.cheme.cmu.edu/blog/2013/03/26/Handling-units-with-dimensionless-equations</link>
      <pubDate>Tue, 26 Mar 2013 16:47:39 EDT</pubDate>
      <category><![CDATA[units]]></category>
      <guid isPermaLink="false">ThYbAQH3SJBJdrPYuFVMHzSzFMw=</guid>
      <description>Handling units with dimensionless equations</description>
      <content:encoded><![CDATA[


&lt;p&gt;
As we have seen, handling units with third party functions is fragile, and often requires additional code to wrap the function to handle the units. An alternative approach that avoids the wrapping is to rescale the equations so they are dimensionless. Then, we should be able to use all the standard external functions without modification. We obtain the final solutions by rescaling back to the answers we want.
&lt;/p&gt;

&lt;p&gt;
Before doing the examples, let us consider how the quantities package handles dimensionless numbers.
&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

a = 5 * u.m
L = 10 * u.m &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;characteristic length&lt;/span&gt;

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; a/L
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; type(a/L)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
0.5 dimensionless
&amp;lt;class 'quantities.quantity.Quantity'&amp;gt;
&lt;/pre&gt;

&lt;p&gt;
As you can see, the dimensionless number is scaled properly, and is listed as dimensionless. The result is still an instance of a quantities object though. That is not likely to be a problem.
&lt;/p&gt;

&lt;p&gt;
Now, we consider using fsolve with dimensionless equations. Our goal is to solve \(C_A = C_{A0} \exp(-k t)\) for the time required to reach a desired \(C_A\). We let \(X = Ca / Ca0\) and \(\tau = t * k\), which leads to \(X = \exp{-\tau}\) in dimensionless terms.
&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; numpy &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; np
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scipy.optimize &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; fsolve

CA0 = 1 * u.mol / u.L
CA = 0.01 * u.mol / u.L  &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;desired exit concentration&lt;/span&gt;
k = 1.0 / u.s

&lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;we need new dimensionless variables&lt;/span&gt;
&lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;let X = Ca / Ca0&lt;/span&gt;
&lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;so, Ca = Ca0 * X&lt;/span&gt;

&lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;let tau = t * k&lt;/span&gt;
&lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;so t = tau / k&lt;/span&gt;

X = CA / CA0 &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;desired exit dimensionless concentration&lt;/span&gt;

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;func&lt;/span&gt;(tau):
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; X - np.exp(-tau)

tauguess = 2

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; func(tauguess) &lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;confirm we have a dimensionless function&lt;/span&gt;

tau_sol, = fsolve(func, tauguess)
t = tau_sol / k
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; t
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
-0.125335283237 dimensionless
4.60517018599 s
&lt;/pre&gt;

&lt;p&gt;
Now consider the ODE \(\frac{dCa}{dt} = -k Ca\). We let \(X = Ca/Ca0\), so \(Ca0 dX = dCa\). Let \(\tau = t * k\) which in this case is dimensionless. That means \(d\tau = k dt\). Substitution of these new variables leads to:
&lt;/p&gt;

&lt;p&gt;
\(Ca0*k \frac{dX}{d\tau} = -k Ca0 X \)
&lt;/p&gt;

&lt;p&gt;
or equivalently:
\(\frac{dX}{d\tau} = -X \)
&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: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;Let X = Ca/Ca0  -&amp;gt; Ca = Ca0 * X  dCa = dX/Ca0&lt;/span&gt;
&lt;span style="color: #ff0000; font-weight: bold;"&gt;# &lt;/span&gt;&lt;span style="color: #ff0000; font-weight: bold;"&gt;let tau = t * k -&amp;gt; dt = 1/k dtau&lt;/span&gt;


&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;dXdtau&lt;/span&gt;(X, tau):
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; -X

&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
tauspan = tspan * k

X0 = 1
X_sol = odeint(dXdtau, X0, tauspan)

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'Ca at t = {0} = {1}'&lt;/span&gt;.format(tspan[-1], X_sol.flatten()[-1] * Ca0)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
Ca at t = 5.0 s = 0.316636777351 mol/L
&lt;/pre&gt;

&lt;p&gt;
That is pretty much it. Using dimensionless quantities simplifies the need to write wrapper code, although it does increase the effort to rederive your equations (with corresponding increased opportunities to make mistakes). Using units to confirm your dimensionless derivation reduces those opportunities.
&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/26/Handling-units-with-dimensionless-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>
    <item>
      <title>Handling units with the quantities module</title>
      <link>https://kitchingroup.cheme.cmu.edu/blog/2013/03/22/Handling-units-with-the-quantities-module</link>
      <pubDate>Fri, 22 Mar 2013 22:00:30 EDT</pubDate>
      <category><![CDATA[units]]></category>
      <guid isPermaLink="false">UhtI1qezAIHVt3Xwf6qr3d9JkTg=</guid>
      <description>Handling units with the quantities module</description>
      <content:encoded><![CDATA[


&lt;p&gt;
The quantities module (&lt;a href="https://pypi.python.org/pypi/quantities" &gt;https://pypi.python.org/pypi/quantities&lt;/a&gt;) is another option for handling units in python. We are going to try the previous example. It does not work, because scipy.optimize.fsolve is not designed to work with 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; numpy &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; np

&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scipy.optimize &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; fsolve
CA0 = 1 * u.mol / u.L
CA = 0.01 * u.mol / u.L
k = 1.0 / u.s

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;func&lt;/span&gt;(t):
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; CA - CA0 * np.exp(-k * t)

tguess = 4 * u.s

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; func(tguess)

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; fsolve(func, tguess)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
&amp;gt;&amp;gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; ... ... &amp;gt;&amp;gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; -0.00831563888873 mol/L
&amp;gt;&amp;gt;&amp;gt; Traceback (most recent call last):
  File "&amp;lt;stdin&amp;gt;", line 1, in &amp;lt;module&amp;gt;
  File "c:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 115, in fsolve
    _check_func('fsolve', 'func', func, x0, args, n, (n,))
  File "c:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 13, in _check_func
    res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
  File "&amp;lt;stdin&amp;gt;", line 2, in func
  File "c:\Python27\lib\site-packages\quantities-0.10.1-py2.7.egg\quantities\quantity.py", line 231, in __array_prepare__
    res._dimensionality = p_dict[uf](*objs)
  File "c:\Python27\lib\site-packages\quantities-0.10.1-py2.7.egg\quantities\dimensionality.py", line 347, in _d_dimensionless
    raise ValueError("quantity must be dimensionless")
ValueError: quantity must be dimensionless
&lt;/pre&gt;

&lt;p&gt;
Our function works fine with units, but fsolve does not pass numbers with units back to the function, so this function fails because the exponential function gets an argument with dimensions in it.  We can create a new function that solves this problem. We need to &amp;ldquo;wrap&amp;rdquo; the function we want to solve to make sure that it uses units, but returns a float number. Then, we put the units back onto the final solved value. Here is how we do that.
&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; numpy &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; np

&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scipy.optimize &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; fsolve &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; _fsolve

CA0 = 1 * u.mol / u.L
CA = 0.01 * u.mol / u.L
k = 1.0 / u.s

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;func&lt;/span&gt;(t):
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; CA - CA0 * np.exp(-k * t)

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;fsolve&lt;/span&gt;(func, t0):
    &lt;span style="color: #228b22;"&gt;'wrapped fsolve command to work with units'&lt;/span&gt;
    tU = t0 / &lt;span style="color: #8b0000;"&gt;float&lt;/span&gt;(t0)  &lt;span style="color: #ff0000; font-weight: bold;"&gt;# units on initial guess, normalized&lt;/span&gt;
    &lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;wrapped_func&lt;/span&gt;(t):
        &lt;span style="color: #228b22;"&gt;'t will be unitless, so we add unit to it. t * tU has units.'&lt;/span&gt;
        &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;float&lt;/span&gt;(func(t * tU))

    sol, = _fsolve(wrapped_func, t0)
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; sol * tU
    
tguess = 4 * u.s

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; fsolve(func, tguess)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
4.60517018599 s
&lt;/pre&gt;

&lt;p&gt;
It is a little tedious to do this, but we might only have to do it once if we store the new fsolve command in a module. You might notice the wrapped function we wrote above only works for one dimensional problems. If there are multiple dimensions, we have to be a little more careful. In the next example, we expand the wrapped function definition to do both one and multidimensional problems. It appears we cannot use numpy.array element-wise multiplication because you cannot mix units in an array. We will use lists instead. When the problem is one-dimensional, the function will take a scalar, but when it is multidimensional it will take a list or array. We will use try/except blocks to handle these two cases. We will assume multidimensional cases, and if that raises an exception because the argument is not a list, we assume it is scalar. Here is the more robust code example. 
&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; numpy &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; np

&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scipy.optimize &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; fsolve &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; _fsolve

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;fsolve&lt;/span&gt;(func, t0):
    &lt;span style="color: #228b22;"&gt;'''wrapped fsolve command to work with units. We get the units on&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;    the function argument, then wrap the function so we can add units&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;    to the argument and return floats. Finally we call the original&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;    fsolve from scipy. Note: this does not support all of the options&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;    to fsolve.'''&lt;/span&gt; 

    &lt;span style="color: #8b0000;"&gt;try:&lt;/span&gt;
        tU = [t / &lt;span style="color: #8b0000;"&gt;float&lt;/span&gt;(t) &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; t &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; t0]  &lt;span style="color: #ff0000; font-weight: bold;"&gt;# units on initial guess, normalized&lt;/span&gt;
    &lt;span style="color: #8b0000;"&gt;except&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;TypeError&lt;/span&gt;:
        tU = t0 / &lt;span style="color: #8b0000;"&gt;float&lt;/span&gt;(t0)
    
    &lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;wrapped_func&lt;/span&gt;(t):
        &lt;span style="color: #228b22;"&gt;'t will be unitless, so we add unit to it. t * tU has units.'&lt;/span&gt;    
        &lt;span style="color: #8b0000;"&gt;try:&lt;/span&gt;
            T = [x1 * x2 &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; x1,x2 &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;zip&lt;/span&gt;(t, tU)]
        &lt;span style="color: #8b0000;"&gt;except&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;TypeError&lt;/span&gt;:
            T = t * tU

        &lt;span style="color: #8b0000;"&gt;try:&lt;/span&gt;
            &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; [&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; func(T)]
        &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;(func(T))

    sol = _fsolve(wrapped_func, t0)
    &lt;span style="color: #8b0000;"&gt;try:&lt;/span&gt;
        &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; [x1 * x2 &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; x1,x2 &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;zip&lt;/span&gt;(sol, tU)]
    &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; sol * tU

&lt;span style="color: #ff0000; font-weight: bold;"&gt;### Problem 1&lt;/span&gt;
CA0 = 1 * u.mol / u.L
CA = 0.01 * u.mol / u.L
k = 1.0 / u.s

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;func&lt;/span&gt;(t):
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; CA - CA0 * np.exp(-k * t)


tguess = 4 * u.s
sol1, = fsolve(func, tguess)
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'sol1 = '&lt;/span&gt;,sol1

&lt;span style="color: #ff0000; font-weight: bold;"&gt;### Problem 2&lt;/span&gt;
&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;func2&lt;/span&gt;(X):
    a,b = X
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; [a**2 - 4*u.kg**2,
            b**2 - 25*u.J**2]

Xguess = [2.2*u.kg, 5.2*u.J]
s2a, s2b = fsolve(func2, Xguess)
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'s2a = {0}\ns2b = {1}'&lt;/span&gt;.format(s2a, s2b)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
sol1 =  4.60517018599 s
s2a = 2.0 kg
s2b = 5.0 J
&lt;/pre&gt;

&lt;p&gt;
That is pretty good. There is still room for improvement in the wrapped function, as it does not support all of the options that scipy.optimize.fsolve supports. Here is a draft of a function that does that. We have to return different numbers of arguments depending on the value of full_output. This function works, but I have not fully tested all the options. Here are three examples that work, including one with an argument.
&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; numpy &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; np

&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scipy.optimize &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; fsolve &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; _fsolve

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;fsolve&lt;/span&gt;(func, t0, args=(), 
           fprime=&lt;span style="color: #8b0000;"&gt;None&lt;/span&gt;, full_output=0, col_deriv=0, 
           xtol=1.49012e-08, maxfev=0, band=&lt;span style="color: #8b0000;"&gt;None&lt;/span&gt;, 
           epsfcn=0.0, factor=100, diag=&lt;span style="color: #8b0000;"&gt;None&lt;/span&gt;):
    &lt;span style="color: #228b22;"&gt;'''wrapped fsolve command to work with units. We get the units on&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;    the function argument, then wrap the function so we can add units&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;    to the argument and return floats. Finally we call the original&lt;/span&gt;
&lt;span style="color: #228b22;"&gt;    fsolve from scipy. '''&lt;/span&gt; 

    &lt;span style="color: #8b0000;"&gt;try:&lt;/span&gt;
        tU = [t / &lt;span style="color: #8b0000;"&gt;float&lt;/span&gt;(t) &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; t &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; t0]  &lt;span style="color: #ff0000; font-weight: bold;"&gt;# units on initial guess, normalized&lt;/span&gt;
    &lt;span style="color: #8b0000;"&gt;except&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;TypeError&lt;/span&gt;:
        tU = t0 / &lt;span style="color: #8b0000;"&gt;float&lt;/span&gt;(t0)
    
    &lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;wrapped_func&lt;/span&gt;(t, *args):
        &lt;span style="color: #228b22;"&gt;'t will be unitless, so we add unit to it. t * tU has units.'&lt;/span&gt;    
        &lt;span style="color: #8b0000;"&gt;try:&lt;/span&gt;
            T = [x1 * x2 &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; x1,x2 &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;zip&lt;/span&gt;(t, tU)]
        &lt;span style="color: #8b0000;"&gt;except&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;TypeError&lt;/span&gt;:
            T = t * tU

        &lt;span style="color: #8b0000;"&gt;try:&lt;/span&gt;
            &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; [&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; func(T, *args)]
        &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;(func(T))

    sol = _fsolve(wrapped_func, t0, args, 
           fprime, full_output, col_deriv, 
           xtol, maxfev, band, 
           epsfcn, factor, diag)

    &lt;span style="color: #8b0000;"&gt;if&lt;/span&gt; full_output:
        x, infodict, ier, mesg = sol
        &lt;span style="color: #8b0000;"&gt;try:&lt;/span&gt;
            x = [x1 * x2 &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; x1,x2 &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;zip&lt;/span&gt;(x, tU)]
        &lt;span style="color: #8b0000;"&gt;except&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;TypeError&lt;/span&gt;:
            x = x * tU
        &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; x, infodict, ier, mesg
    &lt;span style="color: #8b0000;"&gt;else:&lt;/span&gt;
        &lt;span style="color: #8b0000;"&gt;try:&lt;/span&gt;
            x = [x1 * x2 &lt;span style="color: #8b0000;"&gt;for&lt;/span&gt; x1,x2 &lt;span style="color: #8b0000;"&gt;in&lt;/span&gt; &lt;span style="color: #8b0000;"&gt;zip&lt;/span&gt;(sol, tU)]
        &lt;span style="color: #8b0000;"&gt;except&lt;/span&gt; &lt;span style="color: #cd0000;"&gt;TypeError&lt;/span&gt;:
            x = sol * tU
        &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; x

&lt;span style="color: #ff0000; font-weight: bold;"&gt;### Problem 1&lt;/span&gt;
CA0 = 1 * u.mol / u.L
CA = 0.01 * u.mol / u.L
k = 1.0 / u.s

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;func&lt;/span&gt;(t):
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; CA - CA0 * np.exp(-k * t)


tguess = 4 * u.s
sol1, = fsolve(func, tguess)
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'sol1 = '&lt;/span&gt;,sol1

&lt;span style="color: #ff0000; font-weight: bold;"&gt;### Problem 2&lt;/span&gt;
&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;func2&lt;/span&gt;(X):
    a,b = X
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; [a**2 - 4*u.kg**2,
            b**2 - 25*u.J**2]

Xguess = [2.2*u.kg, 5.2*u.J]
sol, infodict, ier, mesg = fsolve(func2, Xguess, full_output=1)
s2a, s2b = sol
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'s2a = {0}\ns2b = {1}'&lt;/span&gt;.format(s2a, s2b)

&lt;span style="color: #ff0000; font-weight: bold;"&gt;### Problem 3 - with an arg&lt;/span&gt;
&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;func3&lt;/span&gt;(a, arg):
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; a**2 - 4*u.kg**2 + arg**2

Xguess = 1.5 * u.kg
arg = 0.0* u.kg

sol3, = fsolve(func3, Xguess, args=(arg,))
print&lt;span style="color: #228b22;"&gt;'sol3 = '&lt;/span&gt;, sol3
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
sol1 =  4.60517018599 s
s2a = 2.0 kg
s2b = 5.0 J
sol3 =  2.0 kg
&lt;/pre&gt;

&lt;p&gt;
The only downside I can see in the quantities module is that it only handle temperature differences, and not absolute temperatures. If you only use absolute temperatures, this would not be a problem I think. But, if you have mixed temperature scales, the quantities module does not convert them on an absolute scale.
&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

T = 20 * u.degC

&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; T.rescale(u.K)
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; T.rescale(u.degF)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
20.0 K
36.0 degF
&lt;/pre&gt;

&lt;p&gt;
Nevertheless, this module seems pretty promising, and there are a lot more features than shown here. Some documentation can be found at &lt;a href="http://pythonhosted.org/quantities/" &gt;http://pythonhosted.org/quantities/&lt;/a&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/03/22/Handling-units-with-the-quantities-module.org"&gt;org-mode source&lt;/a&gt;&lt;p&gt;]]></content:encoded>
    </item>
    <item>
      <title>Using units in python</title>
      <link>https://kitchingroup.cheme.cmu.edu/blog/2013/01/19/Using-units-in-python</link>
      <pubDate>Sat, 19 Jan 2013 09:00:00 EST</pubDate>
      <category><![CDATA[units]]></category>
      <category><![CDATA[python]]></category>
      <guid isPermaLink="false">rdKo8xMQa_EEDbO5mMTrkgm-E-o=</guid>
      <description>Using units in python</description>
      <content:encoded><![CDATA[


&lt;p&gt;
&lt;a href="http://matlab.cheme.cmu.edu/2011/08/05/using-cmu-units-in-matlab-for-basic-calculations/" &gt;Units in Matlab&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
I think an essential feature in an engineering computational environment is properly handling units and unit conversions. Mathcad supports that pretty well. I wrote a &lt;a href="https://github.com/jkitchin/matlab-cmu" &gt;package&lt;/a&gt; for doing it in Matlab. Today I am going to explore units in python. Here are some of the packages that I have found which support units to some extent
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="http://pypi.python.org/pypi/units/" &gt;http://pypi.python.org/pypi/units/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://packages.python.org/quantities/user/tutorial.html" &gt;http://packages.python.org/quantities/user/tutorial.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dirac.cnrs-orleans.fr/ScientificPython/ScientificPythonManual/Scientific.Physics.PhysicalQuantities-module.html" &gt;http://dirac.cnrs-orleans.fr/ScientificPython/ScientificPythonManual/Scientific.Physics.PhysicalQuantities-module.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://home.scarlet.be/be052320/Unum.html" &gt;http://home.scarlet.be/be052320/Unum.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://simtk.org/home/python_units" &gt;https://simtk.org/home/python_units&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://docs.enthought.com/scimath/units/intro.html" &gt;http://docs.enthought.com/scimath/units/intro.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
The last one looks most promising.
&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; numpy &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; np
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scimath.units.volume &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; liter
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scimath.units.substance &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; mol

q = np.array([1, 2, 3]) * mol
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; q

P = q / liter
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; P
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
[1.0*mol 2.0*mol 3.0*mol]
[1000.0*m**-3*mol 2000.0*m**-3*mol 3000.0*m**-3*mol]
&lt;/pre&gt;

&lt;p&gt;
That doesn't look too bad. It is a little clunky to have to import every unit, and it is clear the package is saving everything in SI units by default. Let us try to solve an equation.
&lt;/p&gt;

&lt;p&gt;
Find the time that solves this equation. 
&lt;/p&gt;

&lt;p&gt;
\(0.01 = C_{A0} e^{-kt}\)
&lt;/p&gt;

&lt;p&gt;
First we solve without units. That way we know the answer.
&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; numpy &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; np
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scipy.optimize &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; fsolve

CA0 = 1.0  &lt;span style="color: #ff0000; font-weight: bold;"&gt;# mol/L&lt;/span&gt;
CA = 0.01  &lt;span style="color: #ff0000; font-weight: bold;"&gt;# mol/L&lt;/span&gt;
k = 1.0    &lt;span style="color: #ff0000; font-weight: bold;"&gt;# 1/s&lt;/span&gt;

&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;func&lt;/span&gt;(t):
    z = CA - CA0 * np.exp(-k*t)
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; z

t0 = 2.3

t, = fsolve(func, t0)
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'t = {0:1.2f} seconds'&lt;/span&gt;.format(t)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
t = 4.61 seconds
&lt;/pre&gt;


&lt;p&gt;
Now, with units. I note here that I tried the obvious thing of just importing the units, and adding them on, but the package is unable to work with floats that have units. For some functions, there must be an ndarray with units which is practically what the UnitScalar code below does. 
&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; numpy &lt;span style="color: #8b0000;"&gt;as&lt;/span&gt; np
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scipy.optimize &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; fsolve
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scimath.units.volume &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; liter
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scimath.units.substance &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; mol
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scimath.units.time &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; second
&lt;span style="color: #8b0000;"&gt;from&lt;/span&gt; scimath.units.api &lt;span style="color: #8b0000;"&gt;import&lt;/span&gt; has_units, UnitScalar

CA0 = UnitScalar(1.0, units = mol / liter)
CA = UnitScalar(0.01, units = mol / liter)
k = UnitScalar(1.0, units = 1 / second)

&lt;span style="color: #8b0000;"&gt;@has_units&lt;/span&gt;(inputs=&lt;span style="color: #228b22;"&gt;"t::units=s"&lt;/span&gt;,
           outputs=&lt;span style="color: #228b22;"&gt;"result::units=mol/liter"&lt;/span&gt;)
&lt;span style="color: #8b0000;"&gt;def&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;func&lt;/span&gt;(t):
    z = CA - CA0 * &lt;span style="color: #8b0000;"&gt;float&lt;/span&gt;(np.exp(-k*t))
    &lt;span style="color: #8b0000;"&gt;return&lt;/span&gt; z

t0 = UnitScalar(2.3, units = second)

t, = fsolve(func, t0)
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; &lt;span style="color: #228b22;"&gt;'t = {0:1.2f} seconds'&lt;/span&gt;.format(t)
&lt;span style="color: #8b0000;"&gt;print&lt;/span&gt; type(t)
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
t = 4.61 seconds
&amp;lt;type 'numpy.float64'&amp;gt;
&lt;/pre&gt;

&lt;p&gt;
This is some heavy syntax that in the end does not preserve the units. In my Matlab package, we had to &amp;ldquo;wrap&amp;rdquo; many functions like fsolve so they would preserve units. Clearly this package will need that as well. Overall, in its current implementation this package does not do what I would expect all the time.&lt;sup&gt;&lt;a id="fnr.1" name="fnr.1" class="footref" href="#fn.1"&gt;1&lt;/a&gt;&lt;/sup&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/01/19/Using-units-in-python.org"&gt;org-mode source&lt;/a&gt;&lt;p&gt;]]></content:encoded>
    </item>
  </channel>
</rss>
