<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Shun Li&#39;s Blog</title>
    <link>https://blog.lishun.space/</link>
    <description>Recent content on Shun Li&#39;s Blog</description>
    <image>
      <title>Shun Li&#39;s Blog</title>
      <url>https://blog.lishun.space/images/avatar.png</url>
      <link>https://blog.lishun.space/images/avatar.png</link>
    </image>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 08 Aug 2025 00:00:00 +0800</lastBuildDate>
    <atom:link href="https://blog.lishun.space/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Discontinuous Galerkin Method for 1D Scalar Conservation Laws</title>
      <link>https://blog.lishun.space/posts/dg-1d-code-from-scratch/</link>
      <pubDate>Fri, 08 Aug 2025 00:00:00 +0800</pubDate>
      <guid>https://blog.lishun.space/posts/dg-1d-code-from-scratch/</guid>
      <description>&lt;p&gt;A Python implementation of the Discontinuous Galerkin (DG) method for solving one-dimensional scalar hyperbolic conservation laws.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt; Shu, Chi-Wang. &amp;ldquo;Discontinuous Galerkin Methods: General Approach and Stability.&amp;rdquo; (2008).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;numpy&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;np&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;plt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;numpy.polynomial&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;legendre&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pandas&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;plt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcParams&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;savefig.dpi&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;300&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;figure.autolayout&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;text.usetex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;font.family&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;serif&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;font.serif&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Times New Roman&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;pdf.fonttype&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;42&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;ps.fonttype&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;42&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;font.size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;axes.labelsize&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;axes.titlesize&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;xtick.labelsize&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;ytick.labelsize&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;legend.fontsize&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;lines.linewidth&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;lines.markersize&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;axes.linewidth&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;lines.markerfacecolor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;lines.markeredgecolor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;auto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;xtick.direction&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;in&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;ytick.direction&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;in&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;legend.facecolor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;white&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;legend.edgecolor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;black&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;legend.framealpha&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;1-burgers-equation&#34;&gt;1. Burgers Equation&lt;/h2&gt;
&lt;p&gt;Consider the scalar conservation law
&lt;/p&gt;
$$u_t + f(u)_x = 0$$&lt;p&gt;with the flux function $f(u) = \frac{u^2}{2}$, which yields the inviscid Burgers equation:
&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>A Python implementation of the Discontinuous Galerkin (DG) method for solving one-dimensional scalar hyperbolic conservation laws.</p>
<p><strong>Reference:</strong> Shu, Chi-Wang. &ldquo;Discontinuous Galerkin Methods: General Approach and Stability.&rdquo; (2008).</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">numpy.polynomial</span> <span class="kn">import</span> <span class="n">legendre</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">rcParams</span><span class="o">.</span><span class="n">update</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;savefig.dpi&#34;</span><span class="p">:</span> <span class="mi">300</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;figure.autolayout&#34;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;text.usetex&#34;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;font.family&#34;</span><span class="p">:</span> <span class="s2">&#34;serif&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;font.serif&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;Times New Roman&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;pdf.fonttype&#34;</span><span class="p">:</span> <span class="mi">42</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;ps.fonttype&#34;</span><span class="p">:</span> <span class="mi">42</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;font.size&#34;</span><span class="p">:</span> <span class="mi">14</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;axes.labelsize&#34;</span><span class="p">:</span> <span class="mi">14</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;axes.titlesize&#34;</span><span class="p">:</span> <span class="mi">14</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;xtick.labelsize&#34;</span><span class="p">:</span> <span class="mi">14</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;ytick.labelsize&#34;</span><span class="p">:</span> <span class="mi">14</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;legend.fontsize&#34;</span><span class="p">:</span> <span class="mi">14</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;lines.linewidth&#34;</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;lines.markersize&#34;</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;axes.linewidth&#34;</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;lines.markerfacecolor&#34;</span><span class="p">:</span> <span class="s2">&#34;none&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;lines.markeredgecolor&#34;</span><span class="p">:</span> <span class="s2">&#34;auto&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;xtick.direction&#34;</span><span class="p">:</span> <span class="s2">&#34;in&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;ytick.direction&#34;</span><span class="p">:</span> <span class="s2">&#34;in&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;legend.facecolor&#34;</span><span class="p">:</span> <span class="s2">&#34;white&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;legend.edgecolor&#34;</span><span class="p">:</span> <span class="s2">&#34;black&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;legend.framealpha&#34;</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span></code></pre></div><h2 id="1-burgers-equation">1. Burgers Equation</h2>
<p>Consider the scalar conservation law
</p>
$$u_t + f(u)_x = 0$$<p>with the flux function $f(u) = \frac{u^2}{2}$, which yields the inviscid Burgers equation:
</p>
$$u_t + \left(\frac{1}{2}u^2\right)_x = 0$$<h3 id="method-of-characteristics">Method of Characteristics</h3>
<p>For the Burgers equation, the characteristic line passing through point $(\xi, 0)$ is given by
</p>
$$x = \xi + u_0(\xi)t$$<p>The solution $u$ remains constant along this characteristic line: $u(x,t) = u_0(\xi)$.</p>
<p><strong>Solution construction:</strong></p>
<ul>
<li>If a unique characteristic line passes through $(x,t)$, then $u(x,t) = u_0(\xi)$ where $\xi$ is the unique root of the nonlinear equation (solved via Newton&rsquo;s method):
$$G(u) = u - u_0(x - ut) = 0$$</li>
<li>If multiple characteristic lines pass through $(x,t)$, the equation has multiple roots, but only one corresponds to the physical solution. A suitable initial guess is required.</li>
<li>If no characteristic line passes through $(x,t)$, the equation has no solution—this corresponds to a rarefaction wave region.</li>
</ul>
<h3 id="sine-wave-initial-condition">Sine Wave Initial Condition</h3>
<p>Consider the periodic initial condition:
</p>
$$\begin{aligned}
u_t + \left(\frac{u^2}{2}\right)_x &= 0, \quad x \in [x_l, x_r] \\
u(x,0) &= \alpha + \beta \sin(wx + \phi), \quad w = \frac{2\pi}{x_r - x_l}, \beta > 0
\end{aligned}$$<p>The solution takes the form:
</p>
$$u(x,t) = \alpha + \beta \,\widetilde{u}(wx + \phi - \alpha w t, \beta w t)$$<p>where $\widetilde{u}$ solves the sine-wave problem on $[-\pi, \pi]$:
</p>
$$\begin{aligned}
\widetilde{u}_t + \left(\frac{\widetilde{u}^2}{2}\right)_x &= 0 \\
\widetilde{u}(x,0) &= \sin(x)
\end{aligned}$$<p>For this problem, the nonlinear equation becomes:
</p>
$$G(u) = u - \sin(x - ut)$$<p>Newton&rsquo;s iteration:
</p>
$$u^{(n+1)} = u^{(n)} - \frac{G(u^{(n)})}{G'(u^{(n)})} = u^{(n)} - \frac{u^{(n)} - \sin(x - u^{(n)}t)}{1 + \cos(x - u^{(n)}t)t}$$<p>A suitable initial guess is:
</p>
$$u^{(0)} = \frac{x}{\pi/2 + t}, \quad x \in [-\pi, \pi]$$<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">burgers_f</span><span class="p">(</span><span class="n">u</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Flux function f(u) = u^2/2&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">u</span><span class="o">**</span><span class="mi">2</span> <span class="o">/</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">burgers_df</span><span class="p">(</span><span class="n">u</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Flux derivative f&#39;(u) = u&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">u</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">burgers_sin_solver_kernel</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">t</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Solve the sine-wave initial value problem for Burgers equation.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    x : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Spatial coordinates in [-pi, pi]
</span></span></span><span class="line"><span class="cl"><span class="s2">    t : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Time
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Returns
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------
</span></span></span><span class="line"><span class="cl"><span class="s2">    u : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Solution u(x,t) = sin(x - u*t)
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">u</span> <span class="o">=</span> <span class="n">x</span> <span class="o">/</span> <span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">pi</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">+</span> <span class="n">t</span><span class="p">)</span>  <span class="c1"># initial guess</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Newton iteration</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">100000</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">du</span> <span class="o">=</span> <span class="p">(</span><span class="n">u</span> <span class="o">-</span> <span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="n">x</span> <span class="o">-</span> <span class="n">u</span> <span class="o">*</span> <span class="n">t</span><span class="p">))</span> <span class="o">/</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="n">np</span><span class="o">.</span><span class="n">cos</span><span class="p">(</span><span class="n">x</span> <span class="o">-</span> <span class="n">u</span> <span class="o">*</span> <span class="n">t</span><span class="p">)</span> <span class="o">*</span> <span class="n">t</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">u</span> <span class="o">=</span> <span class="n">u</span> <span class="o">-</span> <span class="n">du</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">np</span><span class="o">.</span><span class="n">max</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">du</span><span class="p">))</span> <span class="o">&lt;</span> <span class="mf">1e-10</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">break</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">u</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">burgers_sin_solver</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">w</span><span class="p">,</span> <span class="n">phi</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Solve Burgers equation with sinusoidal initial condition.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    u(x,0) = a + b*sin(w*x + phi)
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    x : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Spatial coordinates
</span></span></span><span class="line"><span class="cl"><span class="s2">    t : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Time
</span></span></span><span class="line"><span class="cl"><span class="s2">    a : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Mean value
</span></span></span><span class="line"><span class="cl"><span class="s2">    b : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Amplitude
</span></span></span><span class="line"><span class="cl"><span class="s2">    w : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Angular frequency
</span></span></span><span class="line"><span class="cl"><span class="s2">    phi : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Phase shift
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Returns
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------
</span></span></span><span class="line"><span class="cl"><span class="s2">    u : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Solution at (x,t)
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">x_tilde</span> <span class="o">=</span> <span class="n">w</span> <span class="o">*</span> <span class="n">x</span> <span class="o">+</span> <span class="n">phi</span> <span class="o">-</span> <span class="n">a</span> <span class="o">*</span> <span class="n">w</span> <span class="o">*</span> <span class="n">t</span>
</span></span><span class="line"><span class="cl">    <span class="n">x_tilde</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">mod</span><span class="p">(</span><span class="n">x_tilde</span> <span class="o">+</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">)</span> <span class="o">-</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span>  <span class="c1"># map to [-pi, pi]</span>
</span></span><span class="line"><span class="cl">    <span class="n">t_tilde</span> <span class="o">=</span> <span class="n">b</span> <span class="o">*</span> <span class="n">w</span> <span class="o">*</span> <span class="n">t</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span> <span class="o">*</span> <span class="n">burgers_sin_solver_kernel</span><span class="p">(</span><span class="n">x_tilde</span><span class="p">,</span> <span class="n">t_tilde</span><span class="p">)</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplots</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">tend</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mf">0.5</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="mf">2.0</span><span class="p">,</span> <span class="mf">3.0</span><span class="p">]:</span>
</span></span><span class="line"><span class="cl">    <span class="n">x</span><span class="p">,</span> <span class="n">dx</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="n">endpoint</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">retstep</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">x</span> <span class="o">+=</span> <span class="n">dx</span> <span class="o">/</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">u</span> <span class="o">=</span> <span class="n">burgers_sin_solver</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">tend</span><span class="p">,</span> <span class="n">a</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">w</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">phi</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">tend</span> <span class="o">&gt;=</span> <span class="mf">1.0</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">u0</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">s</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">u0</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="o">*</span> <span class="n">tend</span><span class="p">,</span> <span class="n">u0</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="s2">&#34;--&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">u</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="sa">f</span><span class="s2">&#34;t=</span><span class="si">{</span><span class="n">tend</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">ax</span><span class="o">.</span><span class="n">legend</span><span class="p">()</span>
</span></span></code></pre></div><img src="assets/DG-1D-code-from-scratch_5_1.png" style="display: block; margin: 1rem auto;"/>
<h2 id="2-time-integration-ssp-rk3">2. Time Integration: SSP-RK3</h2>
<p>For the ODE problem $u_t = L(u, t)$, the Strong Stability Preserving (SSP) Runge-Kutta method of order 3 is given by:</p>
$$\begin{aligned}
u^{(1)} &= u^n + \Delta t\, L(u^n, t^n) \\
u^{(2)} &= \frac{3}{4}u^n + \frac{1}{4}\left(u^{(1)} + \Delta t\, L(u^{(1)}, t^n + \Delta t)\right) \\
u^{n+1} &= \frac{1}{3}u^n + \frac{2}{3}\left(u^{(2)} + \Delta t\, L(u^{(2)}, t^n + \frac{\Delta t}{2})\right)
\end{aligned}$$<p>When a post-processing operator is applied after each stage (e.g., for limiters):</p>
$$\begin{aligned}
u^{(1)} &= P\left(u^n + \Delta t\, L(u^n, t^n)\right) \\
u^{(2)} &= P\left(\frac{3}{4}u^n + \frac{1}{4}\left(u^{(1)} + \Delta t\, L(u^{(1)}, t^n + \Delta t)\right)\right) \\
u^{n+1} &= P\left(\frac{1}{3}u^n + \frac{2}{3}\left(u^{(2)} + \Delta t\, L(u^{(2)}, t^n + \frac{\Delta t}{2})\right)\right)
\end{aligned}$$<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">SSP_RK3_with_post_process</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="n">dt</span><span class="p">,</span> <span class="n">op_L</span><span class="p">,</span> <span class="n">post_process</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    SSP-RK3 time stepping with optional post-processing.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    u : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Current solution
</span></span></span><span class="line"><span class="cl"><span class="s2">    t : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Current time
</span></span></span><span class="line"><span class="cl"><span class="s2">    dt : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Time step
</span></span></span><span class="line"><span class="cl"><span class="s2">    op_L : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        Spatial operator L(u, t)
</span></span></span><span class="line"><span class="cl"><span class="s2">    post_process : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        Post-processing operator (e.g., limiter)
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Returns
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------
</span></span></span><span class="line"><span class="cl"><span class="s2">    unew : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Solution at next time level
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">u1_pre</span> <span class="o">=</span> <span class="n">u</span> <span class="o">+</span> <span class="n">dt</span> <span class="o">*</span> <span class="n">op_L</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">u1</span> <span class="o">=</span> <span class="n">post_process</span><span class="p">(</span><span class="n">u1_pre</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">u2_pre</span> <span class="o">=</span> <span class="mi">3</span> <span class="o">/</span> <span class="mi">4</span> <span class="o">*</span> <span class="n">u</span> <span class="o">+</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">4</span> <span class="o">*</span> <span class="p">(</span><span class="n">u1</span> <span class="o">+</span> <span class="n">dt</span> <span class="o">*</span> <span class="n">op_L</span><span class="p">(</span><span class="n">u1</span><span class="p">,</span> <span class="n">t</span> <span class="o">+</span> <span class="n">dt</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="n">u2</span> <span class="o">=</span> <span class="n">post_process</span><span class="p">(</span><span class="n">u2_pre</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">unew_pre</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">3</span> <span class="o">*</span> <span class="n">u</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">/</span> <span class="mi">3</span> <span class="o">*</span> <span class="p">(</span><span class="n">u2</span> <span class="o">+</span> <span class="n">dt</span> <span class="o">*</span> <span class="n">op_L</span><span class="p">(</span><span class="n">u2</span><span class="p">,</span> <span class="n">t</span> <span class="o">+</span> <span class="n">dt</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="n">unew</span> <span class="o">=</span> <span class="n">post_process</span><span class="p">(</span><span class="n">unew_pre</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">unew</span>
</span></span></code></pre></div><h2 id="3-numerical-flux-lax-friedrichs">3. Numerical Flux: Lax-Friedrichs</h2>
<p>The Lax-Friedrichs (LF) numerical flux is given by:
</p>
$$f^{LF}(u^-, u^+) = \frac{1}{2}\left(f(u^-) + f(u^+)\right) - \frac{\alpha}{2}(u^+ - u^-)$$<p>where $\alpha = \max |f'(u)|$ is the maximum wave speed.</p>
<p>For Burgers equation $f(u) = u^2/2$, we have $f'(u) = u$. Since $f'$ is monotonic, the local wave speed is:
</p>
$$\alpha = \max(|u^-|, |u^+|)$$<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_LF_flux</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">get_alpha</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Create Lax-Friedrichs numerical flux function.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    f : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        Physical flux function
</span></span></span><span class="line"><span class="cl"><span class="s2">    get_alpha : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        Function to compute maximum wave speed
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Returns
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------
</span></span></span><span class="line"><span class="cl"><span class="s2">    fhat_lf : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        Numerical flux function
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">fhat_lf</span><span class="p">(</span><span class="n">ul</span><span class="p">,</span> <span class="n">ur</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="p">(</span><span class="n">f</span><span class="p">(</span><span class="n">ul</span><span class="p">)</span> <span class="o">+</span> <span class="n">f</span><span class="p">(</span><span class="n">ur</span><span class="p">))</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">-</span> <span class="n">get_alpha</span><span class="p">(</span><span class="n">ul</span><span class="p">,</span> <span class="n">ur</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">*</span> <span class="p">(</span><span class="n">ur</span> <span class="o">-</span> <span class="n">ul</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">fhat_lf</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">burgers_get_alpha</span><span class="p">(</span><span class="n">ul</span><span class="p">,</span> <span class="n">ur</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Maximum wave speed for Burgers equation.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">maximum</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">burgers_df</span><span class="p">(</span><span class="n">ul</span><span class="p">)),</span> <span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">burgers_df</span><span class="p">(</span><span class="n">ur</span><span class="p">)))</span>
</span></span></code></pre></div><h2 id="4-gaussian-quadrature">4. Gaussian Quadrature</h2>
<p>Gaussian quadrature on the standard interval $[-1, 1]$:
</p>
$$\int_{-1}^1 g(\xi)\,d\xi \approx \sum_{i=1}^{k_g} w_i g(\xi_i)$$<p>where $\{\xi_i\}$ are quadrature nodes and $\{w_i\}$ are corresponding weights.</p>
<p>For a general interval $[x_l, x_r]$, using the change of variables $x = \frac{x_l + x_r}{2} + \frac{x_r - x_l}{2}\xi$:
</p>
$$\int_{x_l}^{x_r} f(x)\,dx \approx \frac{x_r-x_l}{2} \sum_{i=1}^{k_g} w_i f(x_i),\quad x_i = \frac{x_l + x_r}{2} + \frac{x_r - x_l}{2} \xi_i$$<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">gauss_quadrature</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">xl</span><span class="p">,</span> <span class="n">xr</span><span class="p">,</span> <span class="n">gk</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Compute integral using Gaussian quadrature.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    f : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        Function to integrate
</span></span></span><span class="line"><span class="cl"><span class="s2">    xl, xr : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Integration interval
</span></span></span><span class="line"><span class="cl"><span class="s2">    gk : int
</span></span></span><span class="line"><span class="cl"><span class="s2">        Number of quadrature points
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Returns
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------
</span></span></span><span class="line"><span class="cl"><span class="s2">    result : float or array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Integral value
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">x</span> <span class="o">=</span> <span class="p">(</span><span class="n">xl</span> <span class="o">+</span> <span class="n">xr</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl">    <span class="n">dx</span> <span class="o">=</span> <span class="n">xr</span> <span class="o">-</span> <span class="n">xl</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">scalar_flag</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">isscalar</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">atleast_1d</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>  <span class="c1"># shape = (n,)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">points</span><span class="p">,</span> <span class="n">weights</span> <span class="o">=</span> <span class="n">legendre</span><span class="o">.</span><span class="n">leggauss</span><span class="p">(</span><span class="n">gk</span><span class="p">)</span>  <span class="c1"># shape = (gk,), (gk,)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># shape = (n, np.newaxis) + (gk,) = (n, gk)</span>
</span></span><span class="line"><span class="cl">    <span class="n">x_nodes</span> <span class="o">=</span> <span class="n">x</span><span class="p">[:,</span> <span class="n">np</span><span class="o">.</span><span class="n">newaxis</span><span class="p">]</span> <span class="o">+</span> <span class="n">dx</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">points</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># shape = (n, gk) * (gk,) = (n, gk)</span>
</span></span><span class="line"><span class="cl">    <span class="n">integral_values</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">x_nodes</span><span class="p">)</span> <span class="o">*</span> <span class="n">weights</span>
</span></span><span class="line"><span class="cl">    <span class="n">result</span> <span class="o">=</span> <span class="n">dx</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">integral_values</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>  <span class="c1"># shape = (n,)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">result</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">scalar_flag</span> <span class="k">else</span> <span class="n">result</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>  <span class="c1"># shape = (n,) or scalar</span>
</span></span></code></pre></div><h2 id="5-legendre-basis-functions">5. Legendre Basis Functions</h2>
<p>Let $p_0, p_1, \dots, p_k$ denote the Legendre polynomials on $[-1, 1]$:
</p>
$$p_0(\xi) = 1, \quad p_1(\xi) = \xi, \quad p_2(\xi) = \frac{1}{2}(3\xi^2 - 1), \quad \dots$$<p>For a single point $\xi \in [-1, 1]$, the basis function values form a vector:
</p>
$$[p_0(\xi), p_1(\xi), \dots, p_k(\xi)]^T \in \mathbb{R}^{k+1}$$<p>For points $\vec{\xi} \in [-1, 1]^n$, the basis matrix is:
</p>
$$M = \begin{bmatrix}
p_0(\xi_1) & p_0(\xi_2) & \cdots & p_0(\xi_n) \\
p_1(\xi_1) & p_1(\xi_2) & \cdots & p_1(\xi_n) \\
\vdots & \vdots & \ddots & \vdots \\
p_k(\xi_1) & p_k(\xi_2) & \cdots & p_k(\xi_n)
\end{bmatrix} \in \mathbb{R}^{(k+1) \times n}$$<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">basis_eval</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">points</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Evaluate Legendre basis functions.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    k : int
</span></span></span><span class="line"><span class="cl"><span class="s2">        Polynomial degree
</span></span></span><span class="line"><span class="cl"><span class="s2">    points : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Points in [-1, 1]
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Returns
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------
</span></span></span><span class="line"><span class="cl"><span class="s2">    result : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Shape (k+1, len(points)) or (k+1,) if scalar
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">scalar_flag</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">isscalar</span><span class="p">(</span><span class="n">points</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">points</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">atleast_1d</span><span class="p">(</span><span class="n">points</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">coeff</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">identity</span><span class="p">(</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">result</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">points</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">result</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">legendre</span><span class="o">.</span><span class="n">Legendre</span><span class="p">(</span><span class="n">coeff</span><span class="p">[</span><span class="n">i</span><span class="p">])(</span><span class="n">points</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># shape = (k+1, len(points)) or (k+1,)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">result</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">scalar_flag</span> <span class="k">else</span> <span class="n">result</span>
</span></span></code></pre></div><h2 id="6-basis-function-derivatives">6. Basis Function Derivatives</h2>
<p>The derivatives $p'_0(\xi), p'_1(\xi), \dots, p'_k(\xi)$ are also needed.</p>
<p>For a single point $\xi$, the derivative vector is:
</p>
$$[p'_0(\xi), p'_1(\xi), \dots, p'_k(\xi)]^T \in \mathbb{R}^{k+1}$$<p>The recurrence relation for Legendre polynomial derivatives:
</p>
$$p'_n(\xi) = \frac{n}{\xi^2 - 1}(p_n(\xi) - p_{n-1}(\xi)), \quad n \geq 1$$<p><strong>Note:</strong> This formula is not valid at endpoints $\xi = \pm 1$.</p>
<p>For transformation to physical coordinates $x$:
</p>
$$\partial_x p_i\left(\frac{x - x_j}{h/2}\right) = \frac{2}{h} p'_i\left(\frac{x - x_j}{h/2}\right)$$<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">basis_dx_eval</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">points</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Evaluate derivatives of Legendre basis functions.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    k : int
</span></span></span><span class="line"><span class="cl"><span class="s2">        Polynomial degree
</span></span></span><span class="line"><span class="cl"><span class="s2">    points : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Points in [-1, 1]
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Returns
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------
</span></span></span><span class="line"><span class="cl"><span class="s2">    result : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Shape (k+1, len(points)) or (k+1,) if scalar
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">scalar_flag</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">isscalar</span><span class="p">(</span><span class="n">points</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">points</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">atleast_1d</span><span class="p">(</span><span class="n">points</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">coeff</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">identity</span><span class="p">(</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">result</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">points</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">f1</span> <span class="o">=</span> <span class="n">legendre</span><span class="o">.</span><span class="n">Legendre</span><span class="p">(</span><span class="n">coeff</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">        <span class="n">f2</span> <span class="o">=</span> <span class="n">legendre</span><span class="o">.</span><span class="n">Legendre</span><span class="p">(</span><span class="n">coeff</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">        <span class="n">result</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">i</span> <span class="o">/</span> <span class="p">(</span><span class="n">points</span><span class="o">**</span><span class="mi">2</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">points</span> <span class="o">*</span> <span class="n">f1</span><span class="p">(</span><span class="n">points</span><span class="p">)</span> <span class="o">-</span> <span class="n">f2</span><span class="p">(</span><span class="n">points</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># shape = (k+1, len(points)) or (k+1,)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">result</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">scalar_flag</span> <span class="k">else</span> <span class="n">result</span>
</span></span></code></pre></div><h2 id="7-inner-products-of-basis-functions">7. Inner Products of Basis Functions</h2>
<p>The $L^2$ inner products of Legendre polynomials are:
</p>
$$\int_{-1}^1 (p_n(\xi))^2\,d\xi = \frac{2}{2n+1}, \quad n = 0,1,2,\dots$$<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">basis_inner_vec</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">gk</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Compute L2 inner products of basis functions.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    k : int
</span></span></span><span class="line"><span class="cl"><span class="s2">        Polynomial degree
</span></span></span><span class="line"><span class="cl"><span class="s2">    gk : int
</span></span></span><span class="line"><span class="cl"><span class="s2">        Quadrature order
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Returns
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------
</span></span></span><span class="line"><span class="cl"><span class="s2">    result : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Vector of inner products (k+1,)
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">coeff</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">identity</span><span class="p">(</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">result</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">f</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">t</span><span class="p">:</span> <span class="n">legendre</span><span class="o">.</span><span class="n">Legendre</span><span class="p">(</span><span class="n">coeff</span><span class="p">[</span><span class="n">i</span><span class="p">])(</span><span class="n">t</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl">        <span class="n">result</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">gauss_quadrature</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">gk</span><span class="p">)</span>  <span class="c1"># = 2 / (2 * i + 1)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">result</span>
</span></span></code></pre></div><h2 id="8-l2-projection">8. L2 Projection</h2>
<p>Given a function $f$, we compute its $L^2$ projection onto the piecewise polynomial space.</p>
<p>On each cell $I_j = [x_{j-1/2}, x_{j+1/2}]$, the projection is:
</p>
$$f(x) \approx \sum_{i=0}^{k} c_i^{(j)} p_i^{(j)}(x), \quad p_i^{(j)}(x) := p_i\left(\frac{x - x_j}{h/2}\right)$$<p>The coefficients are determined by orthogonality:
</p>
$$\int_{I_j} f(x) p_i^{(j)}(x)\,dx = c_i^{(j)} \int_{I_j} (p_i^{(j)}(x))^2\,dx$$<p>Thus:
</p>
$$c_i^{(j)} = \frac{\int_{I_j} f(x) p_i^{(j)}(x)\,dx}{\frac{h}{2} \int_{-1}^1 (p_i(\xi))^2\,d\xi}$$<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">l2_projection</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">dx</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">gk</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    L2 projection of function f onto piecewise polynomial space.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    f : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        Function to project
</span></span></span><span class="line"><span class="cl"><span class="s2">    x : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Cell centers
</span></span></span><span class="line"><span class="cl"><span class="s2">    dx : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Cell size
</span></span></span><span class="line"><span class="cl"><span class="s2">    k : int
</span></span></span><span class="line"><span class="cl"><span class="s2">        Polynomial degree
</span></span></span><span class="line"><span class="cl"><span class="s2">    gk : int
</span></span></span><span class="line"><span class="cl"><span class="s2">        Quadrature order
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Returns
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------
</span></span></span><span class="line"><span class="cl"><span class="s2">    result : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Projection coefficients (n, k+1) or (k+1,) if scalar
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">scalar_flag</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">isscalar</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">atleast_1d</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">coeff</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">identity</span><span class="p">(</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Denominator: integral of basis function squared</span>
</span></span><span class="line"><span class="cl">    <span class="n">inners</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">f2</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">t</span><span class="p">:</span> <span class="n">legendre</span><span class="o">.</span><span class="n">Legendre</span><span class="p">(</span><span class="n">coeff</span><span class="p">[</span><span class="n">i</span><span class="p">])(</span><span class="n">t</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl">        <span class="n">inners</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">dx</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">gauss_quadrature</span><span class="p">(</span><span class="n">f2</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">gk</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Numerator: integral of f * basis</span>
</span></span><span class="line"><span class="cl">    <span class="n">result</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">([</span><span class="n">n</span><span class="p">,</span> <span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="n">f1</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">t</span><span class="p">:</span> <span class="n">f</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="o">*</span> <span class="n">legendre</span><span class="o">.</span><span class="n">Legendre</span><span class="p">(</span><span class="n">coeff</span><span class="p">[</span><span class="n">i</span><span class="p">])(</span><span class="mi">2</span> <span class="o">*</span> <span class="p">(</span><span class="n">t</span> <span class="o">-</span> <span class="n">x</span><span class="p">[</span><span class="n">j</span><span class="p">])</span> <span class="o">/</span> <span class="n">dx</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">result</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">                <span class="n">gauss_quadrature</span><span class="p">(</span><span class="n">f1</span><span class="p">,</span> <span class="n">x</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">-</span> <span class="n">dx</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="n">x</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">+</span> <span class="n">dx</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="n">gk</span><span class="p">)</span> <span class="o">/</span> <span class="n">inners</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">            <span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># shape = (n, k+1) or (k+1,)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">result</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">scalar_flag</span> <span class="k">else</span> <span class="n">result</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span></span></code></pre></div><h2 id="9-error-calculation">9. Error Calculation</h2>
<p>Compute errors between exact solution $f(x)$ and DG approximation $f_h(x)$.</p>
<p>On each cell $I_j = [x_{j-1/2}, x_{j+1/2}]$:
</p>
$$f_h(x) = \sum_{i=0}^{n-1} c_i^{(j)} p_i^{(j)}(x),\,\, p_i^{(j)}(x) := p_i(\frac{x - x_j}{h/2})$$<p><strong>L1 and L2 errors:</strong>
</p>
$$\begin{aligned}
\|f - f_h\|_{1,\Omega} &= \int_\Omega |f - f_h|\,dx = \sum_j \int_{I_j} |f - f_h|\,dx \\
\|f - f_h\|_{2,\Omega} &= \left(\int_{\Omega} (f(x) - f_h(x))^2\,dx\right)^{\frac12} = \left(\sum_j \int_{I_j} (f(x) - f_h(x))^2\,dx  \right)^{\frac12}
\end{aligned}$$<p><strong>L∞ error:</strong>
</p>
$$\|f - f_h\|_{\infty,\Omega} = \max_j \|f - f_h\|_{\infty, I_j}$$<p>All integrals are evaluated numerically using Gaussian quadrature.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">error4DG</span><span class="p">(</span><span class="n">uexact</span><span class="p">,</span> <span class="n">uh</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">dx</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="n">gk</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Compute L1, L2, and Linf errors for DG solution.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    uexact : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        Exact solution function u(x, t)
</span></span></span><span class="line"><span class="cl"><span class="s2">    uh : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        DG coefficients (n, k+1)
</span></span></span><span class="line"><span class="cl"><span class="s2">    x : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Cell centers
</span></span></span><span class="line"><span class="cl"><span class="s2">    dx : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Cell size
</span></span></span><span class="line"><span class="cl"><span class="s2">    t : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Time
</span></span></span><span class="line"><span class="cl"><span class="s2">    gk : int
</span></span></span><span class="line"><span class="cl"><span class="s2">        Quadrature order
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Returns
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------
</span></span></span><span class="line"><span class="cl"><span class="s2">    err_inf, err_l1, err_l2 : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        L∞, L1, and L2 errors
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">points</span><span class="p">,</span> <span class="n">weights</span> <span class="o">=</span> <span class="n">legendre</span><span class="o">.</span><span class="n">leggauss</span><span class="p">(</span><span class="n">gk</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">err_inf</span><span class="p">,</span> <span class="n">err_l1</span><span class="p">,</span> <span class="n">err_l2</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">xi</span><span class="p">,</span> <span class="n">ui</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">uh</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">u</span> <span class="o">=</span> <span class="n">uexact</span><span class="p">(</span><span class="n">xi</span> <span class="o">+</span> <span class="n">dx</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">points</span><span class="p">,</span> <span class="n">t</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">uh_val</span> <span class="o">=</span> <span class="n">legendre</span><span class="o">.</span><span class="n">Legendre</span><span class="p">(</span><span class="n">ui</span><span class="p">)(</span><span class="n">points</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">err_inf</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">max</span><span class="p">([</span><span class="n">err_inf</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">max</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">u</span> <span class="o">-</span> <span class="n">uh_val</span><span class="p">))])</span>
</span></span><span class="line"><span class="cl">        <span class="n">err_l1</span> <span class="o">+=</span> <span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">u</span> <span class="o">-</span> <span class="n">uh_val</span><span class="p">)</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">err_l2</span> <span class="o">+=</span> <span class="p">((</span><span class="n">u</span> <span class="o">-</span> <span class="n">uh_val</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">err_l1</span> <span class="o">*=</span> <span class="n">dx</span> <span class="o">/</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl">    <span class="n">err_l2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">dx</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">err_l2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">err_inf</span><span class="p">,</span> <span class="n">err_l1</span><span class="p">,</span> <span class="n">err_l2</span>
</span></span></code></pre></div><h2 id="10-tvdtvb-limiters">10. TVD/TVB Limiters</h2>
<h3 id="101-minmod-function">10.1 Minmod Function</h3>
<p>The <strong>minmod</strong> function is a standard TVD (Total Variation Diminishing) limiter:
</p>
$$m(a_1, \dots, a_s) = \begin{cases}
s \min(|a_1|, \dots, |a_s|), & \text{if } \text{sign}(a_1) = \dots = \text{sign}(a_s) \\
0, & \text{otherwise}
\end{cases}$$<p>The modified <strong>TVB minmod</strong> function introduces a threshold $M > 0$:
</p>
$$\widetilde{m}(a_1, \dots, a_s) = \begin{cases}
a_1, & \text{if } |a_1| \leq M \Delta x^2 \\
m(a_1, \dots, a_s), & \text{otherwise}
\end{cases}$$<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">minmod</span><span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a2</span><span class="p">,</span> <span class="n">a3</span><span class="p">,</span> <span class="n">h</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Minmod TVD limiter.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    a1, a2, a3 : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Input values
</span></span></span><span class="line"><span class="cl"><span class="s2">    h : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Cell size (unused)
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Returns
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------
</span></span></span><span class="line"><span class="cl"><span class="s2">    result : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Minmod of inputs
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pos_mask</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">a2</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">a3</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">neg_mask</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">a2</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">a3</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">result</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">pos_mask</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">minimum</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">minimum</span><span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a2</span><span class="p">),</span> <span class="n">a3</span><span class="p">),</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">result</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">neg_mask</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">maximum</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">maximum</span><span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a2</span><span class="p">),</span> <span class="n">a3</span><span class="p">),</span> <span class="n">result</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">tvd</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Return minmod as TVD limiter.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">minmod</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">tvb</span><span class="p">(</span><span class="n">m</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Create TVB minmod limiter.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    m : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        TVB constant
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Returns
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------
</span></span></span><span class="line"><span class="cl"><span class="s2">    minmod_tilde : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        TVB limiter function
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">minmod_tilde</span><span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a2</span><span class="p">,</span> <span class="n">a3</span><span class="p">,</span> <span class="n">h</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">condition</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">a1</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">m</span> <span class="o">*</span> <span class="n">h</span><span class="o">**</span><span class="mi">2</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">condition</span><span class="p">,</span> <span class="n">a1</span><span class="p">,</span> <span class="n">minmod</span><span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a2</span><span class="p">,</span> <span class="n">a3</span><span class="p">,</span> <span class="n">h</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">minmod_tilde</span>
</span></span></code></pre></div><h3 id="102-tvdtvb-limiter-for-dg">10.2 TVD/TVB Limiter for DG</h3>
<p>When applying limiters to DG, we must preserve the cell average (no modification for $k=0$).</p>
<p>Let the DG approximation on cell $I_j$ be:
</p>
$$u_h(x) = \sum_{i=0}^{k} c_i^{(j)} p_i^{(j)}(x), \quad p_i^{(j)}(x) := p_i\left(\frac{x - x_j}{h/2}\right)$$<p><strong>Step 1:</strong> Compute cell average and boundary values:
</p>
$$\begin{bmatrix} \bar{u}_j & u_{j-1/2} & u_{j+1/2} \end{bmatrix} = \begin{bmatrix} c_0^{(j)} & \cdots & c_k^{(j)} \end{bmatrix} \begin{bmatrix} \bar{p}_0 & p_0(-1) & p_0(1) \\ \bar{p}_1 & p_1(-1) & p_1(1) \\ \vdots & \vdots & \vdots \\ \bar{p}_k & p_k(-1) & p_k(1) \end{bmatrix}$$<p><strong>Step 2:</strong> Apply limiter to modify boundary values:
</p>
$$\begin{aligned}
u_{j-1/2}^{mod} &= \bar{u}_j - m(\bar{u}_j - u_{j-1/2}, \bar{u}_{j+1} - \bar{u}_j, \bar{u}_j - \bar{u}_{j-1}) \\
u_{j+1/2}^{mod} &= \bar{u}_j + m(u_{j+1/2} - \bar{u}_j, \bar{u}_{j+1} - \bar{u}_j, \bar{u}_j - \bar{u}_{j-1})
\end{aligned}$$<p><strong>Step 3:</strong> Reconstruct polynomial from modified values:</p>
<ul>
<li>For $k=1$: polynomial uniquely determined by cell average and one boundary</li>
<li>For $k=2$: polynomial uniquely determined by cell average and both boundaries</li>
<li>For $k \geq 3$: degenerate to $P^2$ (set higher coefficients to zero)</li>
</ul>
<p><strong>Coefficient formulas:</strong></p>
<p>For $k=1$:
</p>
$$\begin{bmatrix} c_0^{(j)} & c_1^{(j)} \end{bmatrix}^{mod} = \begin{bmatrix} \bar{u}_j & u_{j-1/2}^{mod} \end{bmatrix} \begin{bmatrix} \bar{p}_0 & p_0(-1) \\ \bar{p}_1 & p_1(-1) \end{bmatrix}^{-1}$$<p>For $k \geq 2$:
</p>
$$\begin{bmatrix} c_0^{(j)} & c_1^{(j)} & c_2^{(j)} \end{bmatrix}^{mod} = \begin{bmatrix} \bar{u}_j & u_{j-1/2}^{mod} & u_{j+1/2}^{mod} \end{bmatrix} \begin{bmatrix} \bar{p}_0 & p_0(-1) & p_0(1) \\ \bar{p}_1 & p_1(-1) & p_1(1) \\ \bar{p}_2 & p_2(-1) & p_2(1) \end{bmatrix}^{-1}$$<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">dg_lim</span><span class="p">(</span><span class="n">lim</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">gk</span><span class="p">,</span> <span class="n">h</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Create DG limiter post-processor.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    lim : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        TVD/TVB limiter function
</span></span></span><span class="line"><span class="cl"><span class="s2">    k : int
</span></span></span><span class="line"><span class="cl"><span class="s2">        Polynomial degree
</span></span></span><span class="line"><span class="cl"><span class="s2">    gk : int
</span></span></span><span class="line"><span class="cl"><span class="s2">        Quadrature order
</span></span></span><span class="line"><span class="cl"><span class="s2">    h : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Cell size
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Returns
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------
</span></span></span><span class="line"><span class="cl"><span class="s2">    processer : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        Post-processing function
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">assert</span> <span class="n">k</span> <span class="o">&gt;=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">points</span><span class="p">,</span> <span class="n">weights</span> <span class="o">=</span> <span class="n">legendre</span><span class="o">.</span><span class="n">leggauss</span><span class="p">(</span><span class="n">gk</span><span class="p">)</span>  <span class="c1"># shape = # (gk,), (gk,)</span>
</span></span><span class="line"><span class="cl">    <span class="n">M</span> <span class="o">=</span> <span class="n">basis_eval</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">points</span><span class="p">)</span>  <span class="c1"># shape = (k+1, gk)</span>
</span></span><span class="line"><span class="cl">    <span class="n">vm</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">M</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span>  <span class="c1"># cell averages, shape = (k+1,)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">vl</span> <span class="o">=</span> <span class="n">basis_eval</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>  <span class="c1"># left boundary, shape = (k+1,)</span>
</span></span><span class="line"><span class="cl">    <span class="n">vr</span> <span class="o">=</span> <span class="n">basis_eval</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>  <span class="c1"># right boundary</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">k</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">Mat2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([[</span><span class="n">vm</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">vm</span><span class="p">[</span><span class="mi">1</span><span class="p">]],</span> <span class="p">[</span><span class="n">vl</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">vl</span><span class="p">[</span><span class="mi">1</span><span class="p">]]])</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">Mat3</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="p">[</span>
</span></span><span class="line"><span class="cl">                <span class="p">[</span><span class="n">vm</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">vm</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">vm</span><span class="p">[</span><span class="mi">2</span><span class="p">]],</span>
</span></span><span class="line"><span class="cl">                <span class="p">[</span><span class="n">vl</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">vl</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">vl</span><span class="p">[</span><span class="mi">2</span><span class="p">]],</span>
</span></span><span class="line"><span class="cl">                <span class="p">[</span><span class="n">vr</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">vr</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">vr</span><span class="p">[</span><span class="mi">2</span><span class="p">]],</span>
</span></span><span class="line"><span class="cl">            <span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">processer</span><span class="p">(</span><span class="n">uh</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;Apply limiter to DG coefficients.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">ul</span> <span class="o">=</span> <span class="n">uh</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">vl</span><span class="p">)</span>  <span class="c1"># shape = (n,)</span>
</span></span><span class="line"><span class="cl">        <span class="n">um</span> <span class="o">=</span> <span class="n">uh</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">vm</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">ur</span> <span class="o">=</span> <span class="n">uh</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">vr</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">um_delta_r</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">roll</span><span class="p">(</span><span class="n">um</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">-</span> <span class="n">um</span>
</span></span><span class="line"><span class="cl">        <span class="n">um_delta_l</span> <span class="o">=</span> <span class="n">um</span> <span class="o">-</span> <span class="n">np</span><span class="o">.</span><span class="n">roll</span><span class="p">(</span><span class="n">um</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">ul_mod</span> <span class="o">=</span> <span class="n">um</span> <span class="o">-</span> <span class="n">lim</span><span class="p">(</span><span class="n">um</span> <span class="o">-</span> <span class="n">ul</span><span class="p">,</span> <span class="n">um_delta_l</span><span class="p">,</span> <span class="n">um_delta_r</span><span class="p">,</span> <span class="n">h</span><span class="p">)</span>  <span class="c1"># shape = (n,)</span>
</span></span><span class="line"><span class="cl">        <span class="n">ur_mod</span> <span class="o">=</span> <span class="n">um</span> <span class="o">+</span> <span class="n">lim</span><span class="p">(</span><span class="n">ur</span> <span class="o">-</span> <span class="n">um</span><span class="p">,</span> <span class="n">um_delta_l</span><span class="p">,</span> <span class="n">um_delta_r</span><span class="p">,</span> <span class="n">h</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">uh_mod</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros_like</span><span class="p">(</span><span class="n">uh</span><span class="p">)</span>  <span class="c1"># shape = (n, k+1)</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">k</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">B</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">stack</span><span class="p">([</span><span class="n">um</span><span class="p">,</span> <span class="n">ul_mod</span><span class="p">],</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>  <span class="c1"># shape = (2, n)</span>
</span></span><span class="line"><span class="cl">            <span class="n">uh_mod</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">solve</span><span class="p">(</span><span class="n">Mat2</span><span class="p">,</span> <span class="n">B</span><span class="p">)</span><span class="o">.</span><span class="n">T</span>  <span class="c1"># shape = (n, 2)</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">B</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">stack</span><span class="p">([</span><span class="n">um</span><span class="p">,</span> <span class="n">ul_mod</span><span class="p">,</span> <span class="n">ur_mod</span><span class="p">],</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>  <span class="c1"># shape = (3, n)</span>
</span></span><span class="line"><span class="cl">            <span class="n">uh_mod</span><span class="p">[:,</span> <span class="p">:</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">solve</span><span class="p">(</span><span class="n">Mat3</span><span class="p">,</span> <span class="n">B</span><span class="p">)</span><span class="o">.</span><span class="n">T</span>  <span class="c1"># shape = (n, 3)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">uh_mod</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">processer</span>
</span></span></code></pre></div><h2 id="11-rkdg-scheme">11. RKDG Scheme</h2>
<p>The fully discrete DG scheme (using forward Euler as example) is:
</p>
$$\int_{I_j} u_h^{n+1} v\,dx = \int_{I_j} u_h^n v\,dx + \Delta t \left\{ \int_{I_j} f(u_h^n) v_x\,dx - \hat{f}_{j+1/2} v_{j+1/2}^- + \hat{f}_{j-1/2} v_{j-1/2}^+ \right\}, \quad \forall v \in P^k(I_j)$$<p>where $\hat{f}_{j+1/2} = \hat{f}(u^-_{j+1/2}, u^+_{j+1/2})$ is the numerical flux.</p>
<p><strong>Implementation notes:</strong></p>
<ul>
<li>Mass matrix: $\int_{I_j} u_h v\,dx \Rightarrow \frac{\Delta x}{2} \mathbf{c}^T M W M^T$</li>
<li>Flux integral: $\int_{I_j} f(u_h) v_x\,dx \Rightarrow \frac{\Delta x}{2} \cdot \frac{2}{\Delta x} \mathbf{f}^T W D^T$</li>
<li>Boundary fluxes: $\hat{f}_{j+1/2} v_{j+1/2}^- \Rightarrow \hat{f}_{j+1/2} \mathbf{p}(-1)$</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">RKDG</span><span class="p">(</span><span class="n">uh0</span><span class="p">,</span> <span class="n">dx</span><span class="p">,</span> <span class="n">tend</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">gk</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">fhat</span><span class="p">,</span> <span class="n">df</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Runge-Kutta Discontinuous Galerkin solver.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    uh0 : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        Initial DG coefficients (n, k+1)
</span></span></span><span class="line"><span class="cl"><span class="s2">    dx : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Cell size
</span></span></span><span class="line"><span class="cl"><span class="s2">    tend : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Final time
</span></span></span><span class="line"><span class="cl"><span class="s2">    k : int
</span></span></span><span class="line"><span class="cl"><span class="s2">        Polynomial degree
</span></span></span><span class="line"><span class="cl"><span class="s2">    gk : int
</span></span></span><span class="line"><span class="cl"><span class="s2">        Quadrature order
</span></span></span><span class="line"><span class="cl"><span class="s2">    f : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        Physical flux function
</span></span></span><span class="line"><span class="cl"><span class="s2">    fhat : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        Numerical flux function
</span></span></span><span class="line"><span class="cl"><span class="s2">    df : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        Flux derivative for CFL
</span></span></span><span class="line"><span class="cl"><span class="s2">    **kwargs : dict
</span></span></span><span class="line"><span class="cl"><span class="s2">        Additional options (e.g., lim for limiter)
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Returns
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------
</span></span></span><span class="line"><span class="cl"><span class="s2">    uh : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        DG coefficients at final time
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">points</span><span class="p">,</span> <span class="n">weights</span> <span class="o">=</span> <span class="n">legendre</span><span class="o">.</span><span class="n">leggauss</span><span class="p">(</span><span class="n">gk</span><span class="p">)</span>  <span class="c1"># shape = (gk,), (gk,)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Basis matrices</span>
</span></span><span class="line"><span class="cl">    <span class="n">M</span> <span class="o">=</span> <span class="n">basis_eval</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">points</span><span class="p">)</span>  <span class="c1"># shape = (k+1, gk)</span>
</span></span><span class="line"><span class="cl">    <span class="n">D</span> <span class="o">=</span> <span class="p">(</span><span class="mi">2</span> <span class="o">/</span> <span class="n">dx</span><span class="p">)</span> <span class="o">*</span> <span class="n">basis_dx_eval</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">points</span><span class="p">)</span>  <span class="c1"># shape = (k+1, gk)</span>
</span></span><span class="line"><span class="cl">    <span class="n">M_inv</span> <span class="o">=</span> <span class="p">(</span><span class="mi">2</span> <span class="o">/</span> <span class="n">dx</span><span class="p">)</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">diag</span><span class="p">(</span><span class="mf">1.0</span> <span class="o">/</span> <span class="n">basis_inner_vec</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">gk</span><span class="p">))</span>  <span class="c1"># shape =(k+1, k+1)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Boundary evaluation matrices</span>
</span></span><span class="line"><span class="cl">    <span class="n">vl</span> <span class="o">=</span> <span class="n">basis_eval</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>  <span class="c1"># shape = (k+1,)</span>
</span></span><span class="line"><span class="cl">    <span class="n">vr</span> <span class="o">=</span> <span class="n">basis_eval</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">vc</span> <span class="o">=</span> <span class="n">basis_eval</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">op_L</span><span class="p">(</span><span class="n">uh</span><span class="p">,</span> <span class="n">t</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;Spatial operator L(u, t).&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># Neighbor cells</span>
</span></span><span class="line"><span class="cl">        <span class="n">uh_l</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">roll</span><span class="p">(</span><span class="n">uh</span><span class="p">,</span> <span class="n">shift</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>  <span class="c1"># shape = (n, k+1)</span>
</span></span><span class="line"><span class="cl">        <span class="n">uh_r</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">roll</span><span class="p">(</span><span class="n">uh</span><span class="p">,</span> <span class="n">shift</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1"># Boundary values</span>
</span></span><span class="line"><span class="cl">        <span class="n">ul_m</span> <span class="o">=</span> <span class="n">uh_l</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">vr</span><span class="p">)</span>  <span class="c1"># left value from left neighbor,shape = (n,)</span>
</span></span><span class="line"><span class="cl">        <span class="n">ul_p</span> <span class="o">=</span> <span class="n">uh</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">vl</span><span class="p">)</span>  <span class="c1"># left value from current cell</span>
</span></span><span class="line"><span class="cl">        <span class="n">ur_m</span> <span class="o">=</span> <span class="n">uh</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">vr</span><span class="p">)</span>  <span class="c1"># right value from current cell</span>
</span></span><span class="line"><span class="cl">        <span class="n">ur_p</span> <span class="o">=</span> <span class="n">uh_r</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">vl</span><span class="p">)</span>  <span class="c1"># right value from right neighbor</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1"># Numerical fluxes</span>
</span></span><span class="line"><span class="cl">        <span class="n">fhat_l</span> <span class="o">=</span> <span class="n">fhat</span><span class="p">(</span><span class="n">ul_m</span><span class="p">,</span> <span class="n">ul_p</span><span class="p">)</span>  <span class="c1"># shape = (n,)</span>
</span></span><span class="line"><span class="cl">        <span class="n">fhat_r</span> <span class="o">=</span> <span class="n">fhat</span><span class="p">(</span><span class="n">ur_m</span><span class="p">,</span> <span class="n">ur_p</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1"># Volume term: integral of f(u) * v_x</span>
</span></span><span class="line"><span class="cl">        <span class="n">tmp_u</span> <span class="o">=</span> <span class="n">uh</span> <span class="o">@</span> <span class="n">M</span>  <span class="c1"># (n, k+1) @ (k+1, gk) = (n, gk)</span>
</span></span><span class="line"><span class="cl">        <span class="n">tmp_fu</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">tmp_u</span><span class="p">)</span> <span class="o">*</span> <span class="n">weights</span>  <span class="c1"># (n, gk) * (gk,) = (n, gk)</span>
</span></span><span class="line"><span class="cl">        <span class="n">int_fu_vx</span> <span class="o">=</span> <span class="p">(</span><span class="n">dx</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">tmp_fu</span> <span class="o">@</span> <span class="n">D</span><span class="o">.</span><span class="n">T</span><span class="p">)</span>  <span class="c1"># (n, gk) @ (gk, k+1) = (n, k+1)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1"># Flux terms at boundaries</span>
</span></span><span class="line"><span class="cl">        <span class="n">fhatl_vl</span> <span class="o">=</span> <span class="n">fhat_l</span><span class="p">[:,</span> <span class="n">np</span><span class="o">.</span><span class="n">newaxis</span><span class="p">]</span> <span class="o">*</span> <span class="n">vl</span>  <span class="c1"># (n, np.newaxis) * (k+1,) = (n, k+1)</span>
</span></span><span class="line"><span class="cl">        <span class="n">fhatr_vr</span> <span class="o">=</span> <span class="n">fhat_r</span><span class="p">[:,</span> <span class="n">np</span><span class="o">.</span><span class="n">newaxis</span><span class="p">]</span> <span class="o">*</span> <span class="n">vr</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1"># Residual</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># (n, k+1) @ (k+1, k+1) = (n, k+1)</span>
</span></span><span class="line"><span class="cl">        <span class="n">delta</span> <span class="o">=</span> <span class="p">(</span><span class="n">int_fu_vx</span> <span class="o">-</span> <span class="n">fhatr_vr</span> <span class="o">+</span> <span class="n">fhatl_vl</span><span class="p">)</span> <span class="o">@</span> <span class="n">M_inv</span><span class="o">.</span><span class="n">T</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">delta</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Post-processing (limiter)</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="s2">&#34;lim&#34;</span> <span class="ow">in</span> <span class="n">kwargs</span> <span class="ow">and</span> <span class="n">k</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">post_processer</span> <span class="o">=</span> <span class="n">dg_lim</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s2">&#34;lim&#34;</span><span class="p">],</span> <span class="n">k</span><span class="p">,</span> <span class="n">gk</span><span class="p">,</span> <span class="n">dx</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">post_processer</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">u</span><span class="p">:</span> <span class="n">u</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Time stepping</span>
</span></span><span class="line"><span class="cl">    <span class="n">cfl</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">/</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">dt0</span> <span class="o">=</span> <span class="n">cfl</span> <span class="o">*</span> <span class="p">(</span><span class="n">dx</span> <span class="o">**</span> <span class="p">((</span><span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">3</span><span class="p">))</span> <span class="k">if</span> <span class="n">k</span> <span class="o">&gt;</span> <span class="mi">2</span> <span class="k">else</span> <span class="n">cfl</span> <span class="o">*</span> <span class="n">dx</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">uh</span> <span class="o">=</span> <span class="n">uh0</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">t</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="n">t</span> <span class="o">&lt;</span> <span class="n">tend</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># Adaptive time step based on CFL</span>
</span></span><span class="line"><span class="cl">        <span class="n">alpha_global</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">max</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">df</span><span class="p">(</span><span class="n">uh</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">vc</span><span class="p">))))</span>
</span></span><span class="line"><span class="cl">        <span class="n">dt</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">dt0</span> <span class="o">/</span> <span class="n">alpha_global</span><span class="p">,</span> <span class="n">tend</span> <span class="o">-</span> <span class="n">t</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">uh</span> <span class="o">=</span> <span class="n">SSP_RK3_with_post_process</span><span class="p">(</span><span class="n">uh</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="n">dt</span><span class="p">,</span> <span class="n">op_L</span><span class="p">,</span> <span class="n">post_processer</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">t</span> <span class="o">+=</span> <span class="n">dt</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">uh</span>
</span></span></code></pre></div><h2 id="12-numerical-examples">12. Numerical Examples</h2>
<h3 id="test-problem">Test Problem</h3>
<p>Burgers equation with sinusoidal initial condition:
</p>
$$u_0(x) = \frac{1}{2} + \sin(x), \quad x \in [-\pi, \pi]$$<p>The exact solution is computed using the method of characteristics.</p>
<p><strong>Breaking time:</strong> $T_b = 1$</p>
<ul>
<li>For $t < T_b$: Solution remains smooth; DG achieves $(k+1)$-th order accuracy.</li>
<li>For $t \geq T_b$: Discontinuity (shock) forms; numerical oscillations appear for $k \geq 1$.</li>
</ul>
<p><strong>Handling shocks:</strong></p>
<ul>
<li>TVD limiter suppresses oscillations but reduces accuracy.</li>
<li>TVB limiter with suitable $M > 0$ controls oscillations while maintaining higher accuracy.</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">burgers_init</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Initial condition: u(x,0) = 1/2 + sin(x)&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">burgers_sin_solver</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">t</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">a</span><span class="o">=</span><span class="mf">0.5</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">w</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">phi</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">burgers_exact</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">t</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Exact solution using method of characteristics.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">burgers_sin_solver</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">t</span><span class="o">=</span><span class="n">t</span><span class="p">,</span> <span class="n">a</span><span class="o">=</span><span class="mf">0.5</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">w</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">phi</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">order</span><span class="p">(</span><span class="n">xlist</span><span class="p">,</span> <span class="n">ylist</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Compute convergence order from error data.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="o">-</span><span class="n">np</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">ylist</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span> <span class="o">/</span> <span class="n">ylist</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span> <span class="o">/</span> <span class="n">np</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">xlist</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span> <span class="o">/</span> <span class="n">xlist</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">err_table</span><span class="p">(</span><span class="n">nums</span><span class="p">,</span> <span class="n">err_l1</span><span class="p">,</span> <span class="n">err_l2</span><span class="p">,</span> <span class="n">err_inf</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Create error table with convergence orders.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">ord_l1</span> <span class="o">=</span> <span class="n">order</span><span class="p">(</span><span class="n">nums</span><span class="p">,</span> <span class="n">err_l1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">ord_l2</span> <span class="o">=</span> <span class="n">order</span><span class="p">(</span><span class="n">nums</span><span class="p">,</span> <span class="n">err_l2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">ord_linf</span> <span class="o">=</span> <span class="n">order</span><span class="p">(</span><span class="n">nums</span><span class="p">,</span> <span class="n">err_inf</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">data</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;m&#34;</span><span class="p">:</span> <span class="n">nums</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;L1 error&#34;</span><span class="p">:</span> <span class="n">err_l1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;L1 order&#34;</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">r_</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">nan</span><span class="p">,</span> <span class="n">ord_l1</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;L2 error&#34;</span><span class="p">:</span> <span class="n">err_l2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;L2 order&#34;</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">r_</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">nan</span><span class="p">,</span> <span class="n">ord_l2</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;Linf error&#34;</span><span class="p">:</span> <span class="n">err_inf</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;Linf order&#34;</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">r_</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">nan</span><span class="p">,</span> <span class="n">ord_linf</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">order_test</span><span class="p">(</span><span class="o">*</span><span class="p">,</span> <span class="n">init</span><span class="p">,</span> <span class="n">exact</span><span class="p">,</span> <span class="n">xleft</span><span class="p">,</span> <span class="n">xright</span><span class="p">,</span> <span class="n">nlist</span><span class="p">,</span> <span class="n">tend</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">gk</span><span class="o">=</span><span class="mi">7</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Convergence order test.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    ----------
</span></span></span><span class="line"><span class="cl"><span class="s2">    init : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        Initial condition
</span></span></span><span class="line"><span class="cl"><span class="s2">    exact : callable
</span></span></span><span class="line"><span class="cl"><span class="s2">        Exact solution
</span></span></span><span class="line"><span class="cl"><span class="s2">    xleft, xright : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Domain bounds
</span></span></span><span class="line"><span class="cl"><span class="s2">    nlist : array
</span></span></span><span class="line"><span class="cl"><span class="s2">        List of mesh sizes
</span></span></span><span class="line"><span class="cl"><span class="s2">    tend : float
</span></span></span><span class="line"><span class="cl"><span class="s2">        Final time
</span></span></span><span class="line"><span class="cl"><span class="s2">    k : int
</span></span></span><span class="line"><span class="cl"><span class="s2">        Polynomial degree
</span></span></span><span class="line"><span class="cl"><span class="s2">    gk : int
</span></span></span><span class="line"><span class="cl"><span class="s2">        Quadrature order
</span></span></span><span class="line"><span class="cl"><span class="s2">    **kwargs : dict
</span></span></span><span class="line"><span class="cl"><span class="s2">        Additional DG parameters
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">err_inf</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros_like</span><span class="p">(</span><span class="n">nlist</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">float64</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">err_l1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros_like</span><span class="p">(</span><span class="n">nlist</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">float64</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">err_l2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros_like</span><span class="p">(</span><span class="n">nlist</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">float64</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">cnt</span><span class="p">,</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">nlist</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">x</span><span class="p">,</span> <span class="n">dx</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="n">xleft</span><span class="p">,</span> <span class="n">xright</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">endpoint</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">retstep</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">x</span> <span class="o">+=</span> <span class="n">dx</span> <span class="o">/</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">u0</span> <span class="o">=</span> <span class="n">l2_projection</span><span class="p">(</span><span class="n">init</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">dx</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">gk</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">uh</span> <span class="o">=</span> <span class="n">RKDG</span><span class="p">(</span><span class="n">u0</span><span class="p">,</span> <span class="n">dx</span><span class="p">,</span> <span class="n">tend</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">gk</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">err_inf</span><span class="p">[</span><span class="n">cnt</span><span class="p">],</span> <span class="n">err_l1</span><span class="p">[</span><span class="n">cnt</span><span class="p">],</span> <span class="n">err_l2</span><span class="p">[</span><span class="n">cnt</span><span class="p">]</span> <span class="o">=</span> <span class="n">error4DG</span><span class="p">(</span><span class="n">exact</span><span class="p">,</span> <span class="n">uh</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">dx</span><span class="p">,</span> <span class="n">tend</span><span class="p">,</span> <span class="n">gk</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">df</span> <span class="o">=</span> <span class="n">err_table</span><span class="p">(</span><span class="n">nlist</span><span class="p">,</span> <span class="n">err_l1</span><span class="p">,</span> <span class="n">err_l2</span><span class="p">,</span> <span class="n">err_inf</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">df</span><span class="o">.</span><span class="n">to_string</span><span class="p">(</span><span class="n">index</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">float_format</span><span class="o">=</span><span class="s2">&#34;</span><span class="si">%.2e</span><span class="s2">&#34;</span><span class="p">))</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">shock_test</span><span class="p">(</span><span class="o">*</span><span class="p">,</span> <span class="n">init</span><span class="p">,</span> <span class="n">exact</span><span class="p">,</span> <span class="n">xleft</span><span class="p">,</span> <span class="n">xright</span><span class="p">,</span> <span class="n">nlist</span><span class="p">,</span> <span class="n">n_ref</span><span class="p">,</span> <span class="n">tend</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">gk</span><span class="o">=</span><span class="mi">7</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    Shock capturing test: compare DG solution with reference exact solution.
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">x_ref</span><span class="p">,</span> <span class="n">dx_ref</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="n">xleft</span><span class="p">,</span> <span class="n">xright</span><span class="p">,</span> <span class="n">n_ref</span><span class="p">,</span> <span class="n">endpoint</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">retstep</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">x_ref</span> <span class="o">+=</span> <span class="n">dx_ref</span> <span class="o">/</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">u_exact_ref</span> <span class="o">=</span> <span class="n">exact</span><span class="p">(</span><span class="n">x_ref</span><span class="p">,</span> <span class="n">tend</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">nlist</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">x</span><span class="p">,</span> <span class="n">dx</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="n">xleft</span><span class="p">,</span> <span class="n">xright</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">endpoint</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">retstep</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">x</span> <span class="o">+=</span> <span class="n">dx</span> <span class="o">/</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">u0</span> <span class="o">=</span> <span class="n">l2_projection</span><span class="p">(</span><span class="n">init</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">dx</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">gk</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">uh</span> <span class="o">=</span> <span class="n">RKDG</span><span class="p">(</span><span class="n">u0</span><span class="p">,</span> <span class="n">dx</span><span class="p">,</span> <span class="n">tend</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">gk</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1"># Evaluate at cell centers</span>
</span></span><span class="line"><span class="cl">        <span class="n">uh_point_value</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros_like</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">x</span><span class="p">)):</span>
</span></span><span class="line"><span class="cl">            <span class="n">uh_point_value</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">legendre</span><span class="o">.</span><span class="n">Legendre</span><span class="p">(</span><span class="n">uh</span><span class="p">[</span><span class="n">i</span><span class="p">])(</span><span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplots</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">6</span><span class="p">,</span> <span class="mi">5</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x_ref</span><span class="p">,</span> <span class="n">u_exact_ref</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="sa">r</span><span class="s2">&#34;$u_</span><span class="si">{exact}</span><span class="s2">$&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="n">x</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="n">uh_point_value</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="n">linestyle</span><span class="o">=</span><span class="s2">&#34;None&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="n">marker</span><span class="o">=</span><span class="s2">&#34;o&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="n">markersize</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="n">markerfacecolor</span><span class="o">=</span><span class="s2">&#34;none&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="n">label</span><span class="o">=</span><span class="sa">r</span><span class="s2">&#34;$u_h$&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">ax</span><span class="o">.</span><span class="n">legend</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="n">ax</span><span class="o">.</span><span class="n">grid</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</span></span></code></pre></div><h3 id="test-1-dg-p0">Test 1: DG P0</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># DG P0</span>
</span></span><span class="line"><span class="cl"><span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;k&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;init&#34;</span><span class="p">:</span> <span class="n">burgers_init</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;exact&#34;</span><span class="p">:</span> <span class="n">burgers_exact</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;xleft&#34;</span><span class="p">:</span> <span class="o">-</span><span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;xright&#34;</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;f&#34;</span><span class="p">:</span> <span class="n">burgers_f</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;df&#34;</span><span class="p">:</span> <span class="n">burgers_df</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;fhat&#34;</span><span class="p">:</span> <span class="n">get_LF_flux</span><span class="p">(</span><span class="n">burgers_f</span><span class="p">,</span> <span class="n">burgers_get_alpha</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;=== DG P0: Convergence Test (t=0.5) ===&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">order_test</span><span class="p">(</span><span class="n">tend</span><span class="o">=</span><span class="mf">0.5</span><span class="p">,</span> <span class="n">nlist</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">20</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">80</span><span class="p">,</span> <span class="mi">160</span><span class="p">,</span> <span class="mi">320</span><span class="p">]),</span> <span class="o">**</span><span class="n">config</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">=== DG P0: Shock Test (t=1.5) ===&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">shock_test</span><span class="p">(</span><span class="n">tend</span><span class="o">=</span><span class="mf">1.5</span><span class="p">,</span> <span class="n">nlist</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">40</span><span class="p">,</span> <span class="mi">160</span><span class="p">]),</span> <span class="n">n_ref</span><span class="o">=</span><span class="mi">320</span><span class="p">,</span> <span class="o">**</span><span class="n">config</span><span class="p">)</span>
</span></span></code></pre></div><pre tabindex="0"><code>=== DG P0: Convergence Test (t=0.5) ===
m  L1 error  L1 order  L2 error  L2 order  Linf error  Linf order
20  4.48e-01       NaN  2.36e-01       NaN    3.71e-01         NaN
40  2.26e-01  9.84e-01  1.22e-01  9.57e-01    2.28e-01    7.05e-01
80  1.16e-01  9.71e-01  6.30e-02  9.48e-01    1.24e-01    8.72e-01
160  5.84e-02  9.84e-01  3.22e-02  9.71e-01    6.40e-02    9.58e-01
320  2.94e-02  9.90e-01  1.63e-02  9.85e-01    3.24e-02    9.83e-01
</code></pre><img src="assets/DG-1D-code-from-scratch_33_1.png" style="display: block; margin: 1rem auto;"/>
<img src="assets/DG-1D-code-from-scratch_33_2.png" style="display: block; margin: 1rem auto;"/>
<h3 id="test-2-dg-p1">Test 2: DG P1</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># DG P1</span>
</span></span><span class="line"><span class="cl"><span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;k&#34;</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;init&#34;</span><span class="p">:</span> <span class="n">burgers_init</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;exact&#34;</span><span class="p">:</span> <span class="n">burgers_exact</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;xleft&#34;</span><span class="p">:</span> <span class="o">-</span><span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;xright&#34;</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;f&#34;</span><span class="p">:</span> <span class="n">burgers_f</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;df&#34;</span><span class="p">:</span> <span class="n">burgers_df</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;fhat&#34;</span><span class="p">:</span> <span class="n">get_LF_flux</span><span class="p">(</span><span class="n">burgers_f</span><span class="p">,</span> <span class="n">burgers_get_alpha</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;=== DG P1: Convergence Test (t=0.5) ===&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">order_test</span><span class="p">(</span><span class="n">tend</span><span class="o">=</span><span class="mf">0.5</span><span class="p">,</span> <span class="n">nlist</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">20</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">80</span><span class="p">,</span> <span class="mi">160</span><span class="p">,</span> <span class="mi">320</span><span class="p">]),</span> <span class="o">**</span><span class="n">config</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">=== DG P1: Shock Test (t=1.5) ===&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">shock_test</span><span class="p">(</span><span class="n">tend</span><span class="o">=</span><span class="mf">1.5</span><span class="p">,</span> <span class="n">nlist</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">40</span><span class="p">,</span> <span class="mi">160</span><span class="p">]),</span> <span class="n">n_ref</span><span class="o">=</span><span class="mi">320</span><span class="p">,</span> <span class="o">**</span><span class="n">config</span><span class="p">)</span>
</span></span></code></pre></div><pre tabindex="0"><code>=== DG P1: Convergence Test (t=0.5) ===
m  L1 error  L1 order  L2 error  L2 order  Linf error  Linf order
20  2.35e-02       NaN  1.48e-02       NaN    3.07e-02         NaN
40  6.03e-03  1.96e+00  3.95e-03  1.91e+00    9.02e-03    1.77e+00
80  1.53e-03  1.98e+00  1.04e-03  1.93e+00    2.41e-03    1.90e+00
160  3.89e-04  1.98e+00  2.68e-04  1.95e+00    6.26e-04    1.94e+00
320  9.86e-05  1.98e+00  6.84e-05  1.97e+00    1.59e-04    1.98e+00
</code></pre><img src="assets/DG-1D-code-from-scratch_35_1.png" style="display: block; margin: 1rem auto;"/>
<img src="assets/DG-1D-code-from-scratch_35_2.png" style="display: block; margin: 1rem auto;"/>
<h3 id="test-3-dg-p2">Test 3: DG P2</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># DG P2</span>
</span></span><span class="line"><span class="cl"><span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;k&#34;</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;init&#34;</span><span class="p">:</span> <span class="n">burgers_init</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;exact&#34;</span><span class="p">:</span> <span class="n">burgers_exact</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;xleft&#34;</span><span class="p">:</span> <span class="o">-</span><span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;xright&#34;</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;f&#34;</span><span class="p">:</span> <span class="n">burgers_f</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;df&#34;</span><span class="p">:</span> <span class="n">burgers_df</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;fhat&#34;</span><span class="p">:</span> <span class="n">get_LF_flux</span><span class="p">(</span><span class="n">burgers_f</span><span class="p">,</span> <span class="n">burgers_get_alpha</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;=== DG P2: Convergence Test (t=0.5) ===&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">order_test</span><span class="p">(</span><span class="n">tend</span><span class="o">=</span><span class="mf">0.5</span><span class="p">,</span> <span class="n">nlist</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">20</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">80</span><span class="p">,</span> <span class="mi">160</span><span class="p">,</span> <span class="mi">320</span><span class="p">]),</span> <span class="o">**</span><span class="n">config</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">=== DG P2: Shock Test (t=1.5) ===&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">shock_test</span><span class="p">(</span><span class="n">tend</span><span class="o">=</span><span class="mf">1.5</span><span class="p">,</span> <span class="n">nlist</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">40</span><span class="p">,</span> <span class="mi">160</span><span class="p">]),</span> <span class="n">n_ref</span><span class="o">=</span><span class="mi">320</span><span class="p">,</span> <span class="o">**</span><span class="n">config</span><span class="p">)</span>
</span></span></code></pre></div><pre tabindex="0"><code>=== DG P2: Convergence Test (t=0.5) ===
m  L1 error  L1 order  L2 error  L2 order  Linf error  Linf order
20  1.26e-03       NaN  1.02e-03       NaN    3.59e-03         NaN
40  1.63e-04  2.95e+00  1.41e-04  2.86e+00    5.75e-04    2.64e+00
80  2.08e-05  2.98e+00  1.89e-05  2.90e+00    8.23e-05    2.81e+00
160  2.63e-06  2.98e+00  2.47e-06  2.94e+00    1.13e-05    2.86e+00
320  3.32e-07  2.99e+00  3.16e-07  2.96e+00    1.49e-06    2.92e+00
</code></pre><img src="assets/DG-1D-code-from-scratch_37_1.png" style="display: block; margin: 1rem auto;"/>
<img src="assets/DG-1D-code-from-scratch_37_2.png" style="display: block; margin: 1rem auto;"/>
<h3 id="test-4-dg-p2-with-tvd-limiter">Test 4: DG P2 with TVD Limiter</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># DG P2 + TVD limiter</span>
</span></span><span class="line"><span class="cl"><span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;k&#34;</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;init&#34;</span><span class="p">:</span> <span class="n">burgers_init</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;exact&#34;</span><span class="p">:</span> <span class="n">burgers_exact</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;xleft&#34;</span><span class="p">:</span> <span class="o">-</span><span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;xright&#34;</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;f&#34;</span><span class="p">:</span> <span class="n">burgers_f</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;df&#34;</span><span class="p">:</span> <span class="n">burgers_df</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;fhat&#34;</span><span class="p">:</span> <span class="n">get_LF_flux</span><span class="p">(</span><span class="n">burgers_f</span><span class="p">,</span> <span class="n">burgers_get_alpha</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;lim&#34;</span><span class="p">:</span> <span class="n">tvd</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;=== DG P2 + TVD: Convergence Test (t=0.5) ===&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">order_test</span><span class="p">(</span><span class="n">tend</span><span class="o">=</span><span class="mf">0.5</span><span class="p">,</span> <span class="n">nlist</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">20</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">80</span><span class="p">,</span> <span class="mi">160</span><span class="p">,</span> <span class="mi">320</span><span class="p">]),</span> <span class="o">**</span><span class="n">config</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">=== DG P2 + TVD: Shock Test (t=1.5) ===&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">shock_test</span><span class="p">(</span><span class="n">tend</span><span class="o">=</span><span class="mf">1.5</span><span class="p">,</span> <span class="n">nlist</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">40</span><span class="p">,</span> <span class="mi">160</span><span class="p">]),</span> <span class="n">n_ref</span><span class="o">=</span><span class="mi">320</span><span class="p">,</span> <span class="o">**</span><span class="n">config</span><span class="p">)</span>
</span></span></code></pre></div><pre tabindex="0"><code>=== DG P2 + TVD: Convergence Test (t=0.5) ===
m  L1 error  L1 order  L2 error  L2 order  Linf error  Linf order
20  7.93e-02       NaN  5.23e-02       NaN    5.80e-02         NaN
40  1.94e-02  2.03e+00  1.64e-02  1.68e+00    2.32e-02    1.32e+00
80  4.30e-03  2.17e+00  4.63e-03  1.82e+00    8.28e-03    1.49e+00
160  9.08e-04  2.24e+00  1.28e-03  1.85e+00    3.09e-03    1.42e+00
320  1.86e-04  2.29e+00  3.47e-04  1.89e+00    1.13e-03    1.46e+00
</code></pre><img src="assets/DG-1D-code-from-scratch_39_1.png" style="display: block; margin: 1rem auto;"/>
<img src="assets/DG-1D-code-from-scratch_39_2.png" style="display: block; margin: 1rem auto;"/>
<h3 id="test-5-dg-p2-with-tvb-limiter-m5">Test 5: DG P2 with TVB Limiter (M=5)</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># DG P2 + TVB limiter (M=5)</span>
</span></span><span class="line"><span class="cl"><span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;k&#34;</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;init&#34;</span><span class="p">:</span> <span class="n">burgers_init</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;exact&#34;</span><span class="p">:</span> <span class="n">burgers_exact</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;xleft&#34;</span><span class="p">:</span> <span class="o">-</span><span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;xright&#34;</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;f&#34;</span><span class="p">:</span> <span class="n">burgers_f</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;df&#34;</span><span class="p">:</span> <span class="n">burgers_df</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;fhat&#34;</span><span class="p">:</span> <span class="n">get_LF_flux</span><span class="p">(</span><span class="n">burgers_f</span><span class="p">,</span> <span class="n">burgers_get_alpha</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;lim&#34;</span><span class="p">:</span> <span class="n">tvb</span><span class="p">(</span><span class="mi">5</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;=== DG P2 + TVB (M=5): Convergence Test (t=0.5) ===&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">order_test</span><span class="p">(</span><span class="n">tend</span><span class="o">=</span><span class="mf">0.5</span><span class="p">,</span> <span class="n">nlist</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">20</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">80</span><span class="p">,</span> <span class="mi">160</span><span class="p">,</span> <span class="mi">320</span><span class="p">]),</span> <span class="o">**</span><span class="n">config</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">=== DG P2 + TVB (M=5): Shock Test (t=1.5) ===&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">shock_test</span><span class="p">(</span><span class="n">tend</span><span class="o">=</span><span class="mf">1.5</span><span class="p">,</span> <span class="n">nlist</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">40</span><span class="p">,</span> <span class="mi">160</span><span class="p">]),</span> <span class="n">n_ref</span><span class="o">=</span><span class="mi">320</span><span class="p">,</span> <span class="o">**</span><span class="n">config</span><span class="p">)</span>
</span></span></code></pre></div><pre tabindex="0"><code>=== DG P2 + TVB (M=5): Convergence Test (t=0.5) ===
m  L1 error  L1 order  L2 error  L2 order  Linf error  Linf order
20  1.26e-03       NaN  1.02e-03       NaN    3.59e-03         NaN
40  1.63e-04  2.95e+00  1.41e-04  2.86e+00    5.75e-04    2.64e+00
80  2.08e-05  2.98e+00  1.89e-05  2.90e+00    8.23e-05    2.81e+00
160  2.63e-06  2.98e+00  2.47e-06  2.94e+00    1.13e-05    2.86e+00
320  3.32e-07  2.99e+00  3.16e-07  2.96e+00    1.49e-06    2.92e+00
</code></pre><img src="assets/DG-1D-code-from-scratch_41_1.png" style="display: block; margin: 1rem auto;"/>
<img src="assets/DG-1D-code-from-scratch_41_2.png" style="display: block; margin: 1rem auto;"/>
]]></content:encoded>
    </item>
  </channel>
</rss>
