<?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>
  </channel>
</rss>
