<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.3.3">Jekyll</generator><link href="https://wengzf20.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://wengzf20.github.io/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-11-14T15:41:09+00:00</updated><id>https://wengzf20.github.io/feed.xml</id><title type="html">Zifeng Weng</title><subtitle>Zifeng Weng — computational fluid dynamics, combustion, and energy research.</subtitle><entry><title type="html">A walkthrough of GPU-accelerated CFD</title><link href="https://wengzf20.github.io/blog/2026/GPUforCFD/" rel="alternate" type="text/html" title="A walkthrough of GPU-accelerated CFD" /><published>2026-07-12T00:00:00+00:00</published><updated>2026-07-12T00:00:00+00:00</updated><id>https://wengzf20.github.io/blog/2026/GPUforCFD</id><content type="html" xml:base="https://wengzf20.github.io/blog/2026/GPUforCFD/"><![CDATA[<h2 id="running-pelec-on-amd-mi325x-gpu">Running PeleC on AMD MI325X GPU</h2>

<p>This section walks through getting PeleC running on <strong>AMD Instinct MI325X</strong> GPUs with
<strong>ROCm 7.2.0 / HIP</strong>, using the classic <strong>Sedov blast-wave</strong> test case, and reports the
CPU-vs-GPU speedup we measured.</p>

<h3 id="setup">Setup</h3>

<p>Load the ROCm toolchain and point PeleC at its submodules:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>module load rocm-7.2.0/ucx-1.18.0/ompi/5.0.9    <span class="c"># depends on the cluster</span>
<span class="nb">export </span><span class="nv">HIP_PLATFORM</span><span class="o">=</span>amd    <span class="c"># target AMD (use 'nvidia' for NVIDIA)</span>
<span class="nb">export </span><span class="nv">PELE_HOME</span><span class="o">=</span>/path/to/PeleC
<span class="nb">export </span><span class="nv">PELE_PHYSICS_HOME</span><span class="o">=</span><span class="k">${</span><span class="nv">PELE_HOME</span><span class="k">}</span>/Submodules/PelePhysics
<span class="nb">export </span><span class="nv">AMREX_HOME</span><span class="o">=</span><span class="k">${</span><span class="nv">PELE_PHYSICS_HOME</span><span class="k">}</span>/Submodules/amrex
</code></pre></div></div>

<p>Sanity-check the toolchain is visible via <code class="language-plaintext highlighter-rouge">hipcc --version</code> and <code class="language-plaintext highlighter-rouge">rocm-smi</code>.</p>

<p>Then configure PeleC’s <code class="language-plaintext highlighter-rouge">GNUmakefile</code> to select the backend,</p>

<div class="language-make highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">USE_MPI</span> <span class="o">=</span> TRUE     <span class="c"># use TRUE, not True or true</span>
<span class="nv">USE_HIP</span> <span class="o">=</span> TRUE     <span class="c"># &lt;-- AMD GPU backend</span>
<span class="nv">AMD_ARCH</span> <span class="o">=</span> gfx942  <span class="c"># specific to MI325X</span>
<span class="nv">USE_CUDA</span> <span class="o">=</span> FALSE
<span class="c"># Profiling
</span><span class="nv">TINY_PROFILE</span> <span class="o">=</span> TRUE
</code></pre></div></div>

<p>Last compile the case, such as <code class="language-plaintext highlighter-rouge">Sedov</code> via</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>make TPLrealclean <span class="o">&amp;&amp;</span> make realclean    <span class="c"># clean previous config</span>
make TPL    <span class="c"># third-party libs (SUNDIALS, etc.)</span>
make <span class="nt">-j</span>
</code></pre></div></div>

<p>A correct GPU build produces an executable whose name carries the backend, e.g.
<code class="language-plaintext highlighter-rouge">PeleC3d.hip.TPROF.MPI.HIP.ex</code>. Run the executable via</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mpirun <span class="nt">-np</span> 1 ./PeleC3d.hip.TPROF.MPI.HIP.ex example.inp <span class="o">&gt;</span> log.run 2&gt;&amp;1
</code></pre></div></div>

<p>By default AMReX pre-reserves a large device
memory pool at startup — <strong>3/4 of total GPU memory</strong> (192 GiB of the MI325X’s 256 GiB) —
as a performance optimization to avoid repeated slow <code class="language-plaintext highlighter-rouge">hipMalloc</code> calls during the run.
On a <strong>shared</strong> GPU that reservation can’t fit, limit the memory size (e.g. 2GB) via</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mpirun <span class="nt">-np</span> 1 ./PeleC3d.hip.TPROF.MPI.HIP.ex example.inp <span class="se">\</span>
       amrex.the_arena_init_size<span class="o">=</span>2147483648 <span class="o">&gt;</span> log.run 2&gt;&amp;1
</code></pre></div></div>

<h3 id="performance-comparison">Performance comparison</h3>

<p>Same case (Sedov blast, 64³ = 262,144 cells), 1000 timesteps, single rank each.</p>

<table>
  <thead>
    <tr>
      <th>Backend</th>
      <th>Clock time</th>
      <th>Per timestep</th>
      <th>Speedup</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>CPU (AMD EPYC 9575F, 1 core)</td>
      <td>373.9 s</td>
      <td>~0.388 s</td>
      <td>1×</td>
    </tr>
    <tr>
      <td>GPU (MI325X, 1 card)</td>
      <td>1.85 s</td>
      <td>~0.0014 s</td>
      <td><strong>~200×</strong></td>
    </tr>
  </tbody>
</table>

<p>A single MI325X GPU completes the run <strong>~200× faster</strong> than a single EPYC 9575F CPU core
(~280× per steady-state timestep).</p>]]></content><author><name></name></author><category term="GPU" /><summary type="html"><![CDATA[Running PeleC on AMD MI325X GPU]]></summary></entry><entry><title type="html">Reactive flow solvers</title><link href="https://wengzf20.github.io/blog/2024/ReactiveFlowSolver/" rel="alternate" type="text/html" title="Reactive flow solvers" /><published>2024-07-18T00:00:00+00:00</published><updated>2024-07-18T00:00:00+00:00</updated><id>https://wengzf20.github.io/blog/2024/ReactiveFlowSolver</id><content type="html" xml:base="https://wengzf20.github.io/blog/2024/ReactiveFlowSolver/"><![CDATA[<blockquote>
  <p><strong>Living notes.</strong> This page is updated periodically.</p>
</blockquote>

<h2 id="solvers-implemented-in-openfoam">Solvers implemented in OpenFOAM</h2>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Solver</th>
      <th style="text-align: left">Features</th>
      <th style="text-align: left">Relevant Links</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">DLBFoam</td>
      <td style="text-align: left">Dynamic load balancing model for solving chemistry</td>
      <td style="text-align: left"><a href="https://github.com/Aalto-CFD/DLBFoam.git">Repository</a></td>
    </tr>
    <tr>
      <td style="text-align: left">hybridCentralSolvers</td>
      <td style="text-align: left">To be added</td>
      <td style="text-align: left"><a href="https://github.com/unicfdlab/hybridCentralSolvers.git">Repository</a></td>
    </tr>
    <tr>
      <td style="text-align: left">EBIDNSFoam</td>
      <td style="text-align: left">To be added</td>
      <td style="text-align: left"><a href="https://vbt.ebi.kit.edu/english/594.php">Request</a></td>
    </tr>
    <tr>
      <td style="text-align: left">blastFoam</td>
      <td style="text-align: left">To be added</td>
      <td style="text-align: left"><a href="https://github.com/synthetik-technologies/blastfoam.git">Origin</a></td>
    </tr>
    <tr>
      <td style="text-align: left">CTreactingFoam</td>
      <td style="text-align: left">Reacting flow solver based on OpenFOAM and Cantera; Detailed transport; Strang splitting scheme and a well-balanced splitting scheme; Diagnostic methods: conservative chemical explosive mode analysis (CCEMA), and global pathway analysis (GPA)</td>
      <td style="text-align: left"><a href="https://doi.org/10.3390/aerospace9020102">Origin</a> <br /> <a href="https://github.com/UMN-CRFEL/OpenFOAM-Cantera">Repository</a></td>
    </tr>
    <tr>
      <td style="text-align: left">RSDFoam</td>
      <td style="text-align: left">Real gas shock and detonation simulation solver in OpenFOAM 9</td>
      <td style="text-align: left"><a href="https://linkinghub.elsevier.com/retrieve/pii/S0045793023002372">Origin</a> <br /> <a href="https://linkinghub.elsevier.com/retrieve/pii/S0010218024000713">Application 1</a></td>
    </tr>
    <tr>
      <td style="text-align: left">detonationFoam</td>
      <td style="text-align: left">Extension of rhoCentralFoam including HLLC-P, DLBFoam, 2D AMR; Flame and detonation simulation</td>
      <td style="text-align: left"><a href="https://doi.org/10.17632/x45zh4nz28.1">Origin</a> <br /> <a href="https://github.com/JieSun-pku/detonationFoam">Repository</a></td>
    </tr>
    <tr>
      <td style="text-align: left">reactingPimpleCentralFoam</td>
      <td style="text-align: left">OpenFOAM v2012; Pressure-based semi-implicit; Central-upwind (Kurganov and Tadmor); Detonation simulation with detailed chemistry, mixture of different stabilities, shock-attached and lab coordinates</td>
      <td style="text-align: left"><a href="https://doi.org/10.51560/ofj.v4.125">Origin</a> <br /> <a href="https://github.com/Vigneshwaran-Sankar/reactingPimpleCentralFoam-for-detonations">Repository</a></td>
    </tr>
    <tr>
      <td style="text-align: left">exaFoam</td>
      <td style="text-align: left">To be added</td>
      <td style="text-align: left">To be added</td>
    </tr>
    <tr>
      <td style="text-align: left">gpuFoam</td>
      <td style="text-align: left">Tools and extensions for GPU-accelerated OpenFOAM simulations</td>
      <td style="text-align: left"><a href="https://github.com/vttresearch/gpuFoam.git">Repository</a></td>
    </tr>
  </tbody>
</table>

<h2 id="solvers-in-other-platforms">Solvers in other platforms</h2>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Solver</th>
      <th style="text-align: left">Features</th>
      <th style="text-align: left">Relevant Links</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">PeleC</td>
      <td style="text-align: left">To be added</td>
      <td style="text-align: left">To be added</td>
    </tr>
    <tr>
      <td style="text-align: left">OpenCFD</td>
      <td style="text-align: left">To be added</td>
      <td style="text-align: left">To be added</td>
    </tr>
    <tr>
      <td style="text-align: left">PyFR</td>
      <td style="text-align: left">To be added</td>
      <td style="text-align: left">To be added</td>
    </tr>
    <tr>
      <td style="text-align: left">PyFR</td>
      <td style="text-align: left">To be added</td>
      <td style="text-align: left">To be added</td>
    </tr>
  </tbody>
</table>]]></content><author><name></name></author><category term="Code" /><summary type="html"><![CDATA[This post collects reactive flow solver I met in my research]]></summary></entry><entry><title type="html">Implementation notes of OpenFOAM-9</title><link href="https://wengzf20.github.io/blog/2024/OpenFOAM/" rel="alternate" type="text/html" title="Implementation notes of OpenFOAM-9" /><published>2024-05-24T00:00:00+00:00</published><updated>2024-05-24T00:00:00+00:00</updated><id>https://wengzf20.github.io/blog/2024/OpenFOAM</id><content type="html" xml:base="https://wengzf20.github.io/blog/2024/OpenFOAM/"><![CDATA[<blockquote>
  <p><strong>Living notes.</strong> This page is updated periodically.</p>
</blockquote>

<h2 id="output-precision-writeprecision">Output precision (<code class="language-plaintext highlighter-rouge">writePrecision</code>)</h2>

<ul>
  <li>
    <p>Use finer precision to reduce truncated error when re-run the simulation from a given time step.</p>
  </li>
  <li>
    <p>In AMR, large truncated error might lead to wrong point coordinates and zero cell volume.</p>
  </li>
</ul>

<h2 id="load-balanced-adaptive-mesh-refinement">Load-balanced adaptive mesh refinement</h2>

<ul>
  <li>The library doesn’t compatible with openmpi-3.1.0.</li>
</ul>

<h2 id="implementation-of-fvcdiv">Implementation of <code class="language-plaintext highlighter-rouge">fvc::div</code></h2>

<p><code class="language-plaintext highlighter-rouge">fvc::div</code> functions were realized in the following ways</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// in src/finiteVolume/finiteVolume/fvc/fvcDiv.C</span>
<span class="c1">// fvc::div(vf,name) --- vf: volume field; name: scheme</span>
<span class="k">return</span> <span class="n">fv</span><span class="o">::</span><span class="n">divScheme</span><span class="o">&lt;</span><span class="n">Type</span><span class="o">&gt;::</span><span class="n">New</span>
<span class="p">(</span>
    <span class="n">vf</span><span class="p">.</span><span class="n">mesh</span><span class="p">(),</span> <span class="n">vf</span><span class="p">.</span><span class="n">mesh</span><span class="p">().</span><span class="n">divScheme</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="p">).</span><span class="n">ref</span><span class="p">().</span><span class="n">fvcDiv</span><span class="p">(</span><span class="n">vf</span><span class="p">);</span>

<span class="c1">// fvc::div(flux,vf,name) --- flux: surfaceScalarField&amp;</span>
<span class="k">return</span> <span class="n">fv</span><span class="o">::</span><span class="n">convectionScheme</span><span class="o">&lt;</span><span class="n">Type</span><span class="o">&gt;::</span><span class="n">New</span>
<span class="p">(</span>
    <span class="n">vf</span><span class="p">.</span><span class="n">mesh</span><span class="p">(),</span>
    <span class="n">flux</span><span class="p">,</span>
    <span class="n">vf</span><span class="p">.</span><span class="n">mesh</span><span class="p">().</span><span class="n">divScheme</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="p">).</span><span class="n">ref</span><span class="p">().</span><span class="n">fvcDiv</span><span class="p">(</span><span class="n">flux</span><span class="p">,</span> <span class="n">vf</span><span class="p">);</span>
</code></pre></div></div>

<p>The implementation first selects and constructs a divergence or convection scheme, then calls its <code class="language-plaintext highlighter-rouge">fvcDiv</code> function.</p>

<h3 id="scheme-selection">Scheme selection</h3>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// in src/finiteVolume/finiteVolume/divSchemes/divScheme/divScheme.C</span>
<span class="c1">// divScheme</span>
    <span class="k">typename</span> <span class="n">IstreamConstructorTable</span><span class="o">::</span><span class="n">iterator</span> <span class="n">cstrIter</span> <span class="o">=</span> <span class="n">IstreamConstructorTablePtr_</span><span class="o">-&gt;</span><span class="n">find</span><span class="p">(</span><span class="n">schemeName</span><span class="p">);</span>
    <span class="k">return</span> <span class="nf">cstrIter</span><span class="p">()(</span><span class="n">mesh</span><span class="p">,</span> <span class="n">schemeData</span><span class="p">);</span>
<span class="c1">// convection scheme</span>
    <span class="k">typename</span> <span class="n">IstreamConstructorTable</span><span class="o">::</span><span class="n">iterator</span> <span class="n">cstrIter</span> <span class="o">=</span> <span class="n">IstreamConstructorTablePtr_</span><span class="o">-&gt;</span><span class="n">find</span><span class="p">(</span><span class="n">schemeName</span><span class="p">);</span>
    <span class="k">return</span> <span class="nf">cstrIter</span><span class="p">()(</span><span class="n">mesh</span><span class="p">,</span> <span class="n">faceFlux</span><span class="p">,</span> <span class="n">schemeData</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="divergence-evaluation">Divergence evaluation</h3>

<p>Only one type is available: <code class="language-plaintext highlighter-rouge">gaussDivScheme</code>. The essential code is</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// fvcDiv function in src/finiteVolume/finiteVolume/convectionSchemes/gaussConvectionScheme/gaussConvectionScheme.C</span>
<span class="n">fvc</span><span class="o">::</span><span class="n">surfaceIntegrate</span>
<span class="p">(</span>
    <span class="k">this</span><span class="o">-&gt;</span><span class="n">tinterpScheme_</span><span class="p">().</span><span class="n">dotInterpolate</span><span class="p">(</span><span class="k">this</span><span class="o">-&gt;</span><span class="n">mesh_</span><span class="p">.</span><span class="n">Sf</span><span class="p">(),</span> <span class="n">vf</span><span class="p">)</span>
<span class="p">)</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">tinterpScheme_</code> was initialized in father class,</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">tinterpScheme_</span><span class="p">(</span><span class="n">surfaceInterpolationScheme</span><span class="o">&lt;</span><span class="n">Type</span><span class="o">&gt;::</span><span class="n">New</span><span class="p">(</span><span class="n">mesh</span><span class="p">,</span> <span class="n">is</span><span class="p">))</span> <span class="c1">// is: Istream for divScheme</span>
</code></pre></div></div>

<h3 id="convection-evaluation">Convection evaluation</h3>

<p>Three types were available</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">gaussConvectionScheme</code></li>
  <li><code class="language-plaintext highlighter-rouge">boundedConvectionScheme</code></li>
  <li><code class="language-plaintext highlighter-rouge">multivariateGaussConvectionScheme</code></li>
</ul>

<p>We only check <code class="language-plaintext highlighter-rouge">gaussConvectionScheme</code>, the essential code is</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">fvc</span><span class="o">::</span><span class="n">surfaceIntegrate</span><span class="p">(</span><span class="n">flux</span><span class="p">(</span><span class="n">faceFlux</span><span class="p">,</span> <span class="n">vf</span><span class="p">))</span>

<span class="c1">// flux(faceFlux, vf) is defined as</span>
    <span class="n">faceFlux</span><span class="o">*</span><span class="nf">interpolate</span><span class="p">(</span><span class="n">faceFlux</span><span class="p">,</span> <span class="n">vf</span><span class="p">);</span>
<span class="c1">// interpolate(faceFlux, vf) is defined as</span>
    <span class="k">return</span> <span class="nf">tinterpScheme_</span><span class="p">().</span><span class="n">interpolate</span><span class="p">(</span><span class="n">vf</span><span class="p">);</span>
</code></pre></div></div>

<p>during the construction, <code class="language-plaintext highlighter-rouge">tinterpScheme_</code> is a pointer for the specified surface interpolation scheme.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">tinterpScheme_</span>
<span class="p">(</span>
    <span class="n">surfaceInterpolationScheme</span><span class="o">&lt;</span><span class="n">Type</span><span class="o">&gt;::</span><span class="n">New</span><span class="p">(</span><span class="n">mesh</span><span class="p">,</span> <span class="n">faceFlux</span><span class="p">,</span> <span class="n">is</span><span class="p">)</span>
<span class="p">)</span>
</code></pre></div></div>

<p>The exact interpolation methods, like linear, WENO, were realized in corresponding class.</p>

<h2 id="implementation-of-fvmdiv">Implementation of <code class="language-plaintext highlighter-rouge">fvm::div</code></h2>

<p><code class="language-plaintext highlighter-rouge">fvm::div</code> calculates the matrix for the divergence of the given field and flux. It only provides convection scheme. The code is</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// fvm::div(flux,vf,name) is</span>
<span class="k">return</span> <span class="n">fv</span><span class="o">::</span><span class="n">convectionScheme</span><span class="o">&lt;</span><span class="n">Type</span><span class="o">&gt;::</span><span class="n">New</span>
<span class="p">(</span>
    <span class="n">vf</span><span class="p">.</span><span class="n">mesh</span><span class="p">(),</span>
    <span class="n">flux</span><span class="p">,</span>
    <span class="n">vf</span><span class="p">.</span><span class="n">mesh</span><span class="p">().</span><span class="n">divScheme</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="p">)().</span><span class="n">fvmDiv</span><span class="p">(</span><span class="n">flux</span><span class="p">,</span> <span class="n">vf</span><span class="p">);</span>
</code></pre></div></div>

<p>In <code class="language-plaintext highlighter-rouge">gaussConvectionScheme</code>, the function <code class="language-plaintext highlighter-rouge">fvmDiv</code> calls several functions via the surface interpolation object <code class="language-plaintext highlighter-rouge">tinterpScheme_</code>, including</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">weights(vf)</code></li>
  <li><code class="language-plaintext highlighter-rouge">corrected()</code></li>
  <li><code class="language-plaintext highlighter-rouge">correction(vf)</code></li>
</ul>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// return type: tmp&lt;fvMatrix&lt;Type&gt;&gt; fvmDiv</span>
    <span class="n">tmp</span><span class="o">&lt;</span><span class="n">surfaceScalarField</span><span class="o">&gt;</span> <span class="n">tweights</span> <span class="o">=</span> <span class="n">tinterpScheme_</span><span class="p">().</span><span class="n">weights</span><span class="p">(</span><span class="n">vf</span><span class="p">);</span>
    <span class="k">const</span> <span class="n">surfaceScalarField</span><span class="o">&amp;</span> <span class="n">weights</span> <span class="o">=</span> <span class="n">tweights</span><span class="p">();</span>

    <span class="p">...</span>

    <span class="n">fvm</span><span class="p">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">=</span> <span class="o">-</span><span class="n">weights</span><span class="p">.</span><span class="n">primitiveField</span><span class="p">()</span><span class="o">*</span><span class="n">faceFlux</span><span class="p">.</span><span class="n">primitiveField</span><span class="p">();</span>
    <span class="n">fvm</span><span class="p">.</span><span class="n">upper</span><span class="p">()</span> <span class="o">=</span> <span class="n">fvm</span><span class="p">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">+</span> <span class="n">faceFlux</span><span class="p">.</span><span class="n">primitiveField</span><span class="p">();</span>
    <span class="n">fvm</span><span class="p">.</span><span class="n">negSumDiag</span><span class="p">();</span>

    <span class="p">...</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">tinterpScheme_</span><span class="p">().</span><span class="n">corrected</span><span class="p">())</span>
    <span class="p">{</span>
        <span class="n">fvm</span> <span class="o">+=</span> <span class="n">fvc</span><span class="o">::</span><span class="n">surfaceIntegrate</span><span class="p">(</span><span class="n">faceFlux</span><span class="o">*</span><span class="n">tinterpScheme_</span><span class="p">().</span><span class="n">correction</span><span class="p">(</span><span class="n">vf</span><span class="p">));</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="n">tfvm</span><span class="p">;</span>
</code></pre></div></div>

<h2 id="implementation-of-fvcgrad">Implementation of <code class="language-plaintext highlighter-rouge">fvc::grad</code></h2>

<p>For a volume field, <code class="language-plaintext highlighter-rouge">fvc::grad(vf, name)</code> selects the gradient scheme:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// fvc::grad(vf,name)</span>
<span class="k">return</span> <span class="n">fv</span><span class="o">::</span><span class="n">gradScheme</span><span class="o">&lt;</span><span class="n">Type</span><span class="o">&gt;::</span><span class="n">New</span>
<span class="p">(</span>
    <span class="n">vf</span><span class="p">.</span><span class="n">mesh</span><span class="p">(),</span>
    <span class="n">vf</span><span class="p">.</span><span class="n">mesh</span><span class="p">().</span><span class="n">gradScheme</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="p">)().</span><span class="n">grad</span><span class="p">(</span><span class="n">vf</span><span class="p">,</span> <span class="n">name</span><span class="p">);</span>
</code></pre></div></div>
<p>Here, several gradient schemes are available. Again, we only focus on <code class="language-plaintext highlighter-rouge">gaussGrad</code>.</p>

<p>For surface mesh</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// fvc::grad(ssf,name)</span>
<span class="k">return</span> <span class="n">fv</span><span class="o">::</span><span class="n">gaussGrad</span><span class="o">&lt;</span><span class="n">Type</span><span class="o">&gt;::</span><span class="n">gradf</span><span class="p">(</span><span class="n">ssf</span><span class="p">,</span> <span class="s">"grad("</span> <span class="o">+</span> <span class="n">ssf</span><span class="p">.</span><span class="n">name</span><span class="p">()</span> <span class="o">+</span> <span class="sc">')'</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="the-grad-evaluation-path">The <code class="language-plaintext highlighter-rouge">grad</code> evaluation path</h3>

<p>The <code class="language-plaintext highlighter-rouge">grad</code> function is implemented in the base class <code class="language-plaintext highlighter-rouge">gradScheme</code>.</p>

<p><strong>Step 1 — Check the cache</strong></p>

<p>The implementation checks the cached gradient.</p>

<p><strong>Step 2 — Calculate the gradient</strong></p>

<p><code class="language-plaintext highlighter-rouge">calcGrad(vsf, name)</code> first calls <code class="language-plaintext highlighter-rouge">gradf(tinterpScheme_().interpolate(vsf), name)</code>.
The interpolation scheme is created without a face flux, using
<code class="language-plaintext highlighter-rouge">surfaceInterpolationScheme&lt;Type&gt;::New(mesh, is)</code>.</p>

<p><strong>Step 3 — Correct the boundary conditions</strong></p>

<p>The calculation then calls <code class="language-plaintext highlighter-rouge">correctBoundaryConditions(vsf, gGrad)</code>.</p>

<h3 id="the-gradf-implementation">The <code class="language-plaintext highlighter-rouge">gradf</code> implementation</h3>

<blockquote>
  <p><strong>Coming soon.</strong> This subsection is under development.</p>
</blockquote>

<h2 id="implementation-of-surfaceinterpolationscheme">Implementation of <code class="language-plaintext highlighter-rouge">surfaceInterpolationScheme</code></h2>

<p>The implementations of <code class="language-plaintext highlighter-rouge">fvc::div</code>, <code class="language-plaintext highlighter-rouge">fvm::div</code>, and <code class="language-plaintext highlighter-rouge">fvc::grad</code> rely on interpolation. Each interpolation scheme provides the functions needed by the corresponding operators:</p>

<table>
  <thead>
    <tr>
      <th>Operator</th>
      <th>Required interpolation functions</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">fvc::div(vf)</code></td>
      <td><code class="language-plaintext highlighter-rouge">dotInterpolate</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">fvc::div(flux, vf)</code> and <code class="language-plaintext highlighter-rouge">fvc::grad</code></td>
      <td><code class="language-plaintext highlighter-rouge">interpolate</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">fvm::div(flux, vf)</code></td>
      <td><code class="language-plaintext highlighter-rouge">weights(vf)</code>, <code class="language-plaintext highlighter-rouge">corrected()</code>, <code class="language-plaintext highlighter-rouge">correction(vf)</code></td>
    </tr>
  </tbody>
</table>

<p>Here we use linear interpolation as an example,</p>

<blockquote>
  <p><strong>Coming soon.</strong> This section is under development.</p>
</blockquote>

<h2 id="implementation-of-mapfields">Implementation of <code class="language-plaintext highlighter-rouge">mapFields</code></h2>

<h3 id="mapping-workflow">Mapping workflow</h3>

<p><code class="language-plaintext highlighter-rouge">mapFields</code> operates in two steps: constructing the mesh mapping and mapping the fields.</p>

<p><strong>Step 1 — Construct the mesh mapping</strong></p>

<p>Construct a <code class="language-plaintext highlighter-rouge">meshToMesh0</code> object:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">meshToMesh0</span> <span class="nf">meshToMesh0Interp</span>
<span class="p">(</span>
    <span class="n">meshSource</span><span class="p">,</span>
    <span class="n">meshTarget</span><span class="p">,</span>
    <span class="n">patchMap</span><span class="p">,</span> <span class="c1">// neglected for consistent map</span>
    <span class="n">cuttingPatches</span>
<span class="p">);</span>
</code></pre></div></div>

<p><strong>Step 2 — Map the fields</strong></p>

<p>Map fields found in the target case via the template class <code class="language-plaintext highlighter-rouge">MapConsistentVolFields</code>:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">MapVolFields</span><span class="o">&lt;</span><span class="n">scalar</span><span class="o">&gt;</span> <span class="c1">// type includes vector, sphericalTensor, symmTensor, tensor</span>
<span class="p">(</span>
    <span class="n">objects</span><span class="p">,</span>
    <span class="n">meshToMesh0Interp</span><span class="p">,</span>
    <span class="n">mapOrder</span><span class="p">,</span>
    <span class="n">CombineOp</span><span class="o">&lt;</span><span class="n">scalar</span><span class="o">&gt;</span><span class="p">()</span>
<span class="p">);</span>
</code></pre></div></div>

<p>The first step takes much longer time over the whole mapFields execution especially for large mesh size.</p>

<h3 id="how-meshtomesh0-finds-matching-cells">How <code class="language-plaintext highlighter-rouge">meshToMesh0</code> finds matching cells</h3>

<p>The <code class="language-plaintext highlighter-rouge">meshToMesh0</code> class finds the mapping between source and target meshes through <code class="language-plaintext highlighter-rouge">calcAddressing()</code>. The main stages are outlined below, followed by a simplification for translated meshes.</p>

<p><strong>Step 1 — Mark boundary cells</strong></p>

<p>Visit all boundaries and mark the cells next to them.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Set reference to boundary</span>
<span class="k">const</span> <span class="n">polyPatchList</span><span class="o">&amp;</span> <span class="n">patchesFrom</span> <span class="o">=</span> <span class="n">fromMesh_</span><span class="p">.</span><span class="n">boundaryMesh</span><span class="p">();</span>

<span class="n">forAll</span><span class="p">(</span><span class="n">patchesFrom</span><span class="p">,</span> <span class="n">patchi</span><span class="p">)</span>
<span class="p">{</span>
    <span class="c1">// Get reference to cells next to the boundary</span>
    <span class="k">const</span> <span class="n">labelUList</span><span class="o">&amp;</span> <span class="n">bCells</span> <span class="o">=</span> <span class="n">patchesFrom</span><span class="p">[</span><span class="n">patchi</span><span class="p">].</span><span class="n">faceCells</span><span class="p">();</span>

    <span class="n">forAll</span><span class="p">(</span><span class="n">bCells</span><span class="p">,</span> <span class="n">facei</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">boundaryCell</span><span class="p">[</span><span class="n">bCells</span><span class="p">[</span><span class="n">facei</span><span class="p">]]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><strong>Step 2 — Construct the octree</strong></p>

<p>The octree is used to search cell that containing a given point</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">indexedOctree</span><span class="o">&lt;</span><span class="n">treeDataCell</span><span class="o">&gt;</span> <span class="n">oc</span>
<span class="p">(</span>
    <span class="n">treeDataCell</span><span class="p">(</span><span class="nb">false</span><span class="p">,</span> <span class="n">fromMesh_</span><span class="p">,</span> <span class="n">polyMesh</span><span class="o">::</span><span class="n">CELL_TETS</span><span class="p">),</span>
    <span class="n">shiftedBb</span><span class="p">,</span>      <span class="c1">// overall bounding box</span>
    <span class="mi">8</span><span class="p">,</span>              <span class="c1">// maxLevel</span>
    <span class="mi">10</span><span class="p">,</span>             <span class="c1">// leafsize</span>
    <span class="mf">6.0</span>             <span class="c1">// duplicity</span>
<span class="p">);</span>
</code></pre></div></div>

<p><strong>Step 3 — Calculate cell addressing</strong></p>

<p>Calculate addressing for internal and boundary points. This is the most time-consuming stage.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// realized in calculateMeshToMesh0Addressing.C</span>
<span class="n">cellAddresses</span>
<span class="p">(</span>
    <span class="n">cellAddressing_</span><span class="p">,</span>
    <span class="n">toMesh_</span><span class="p">.</span><span class="n">cellCentres</span><span class="p">(),</span>
    <span class="n">fromMesh_</span><span class="p">,</span>
    <span class="n">boundaryCell</span><span class="p">,</span>
    <span class="n">oc</span>
<span class="p">);</span>
</code></pre></div></div>

<p>In this step, there are three levels of search. Both level 2 and 3 use octree for search which is the major computation overhead.</p>

<table>
  <thead>
    <tr>
      <th>Search level</th>
      <th>Purpose</th>
      <th>Search method</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Find a nearby source cell and check whether it contains the target point</td>
      <td>Neighbour-array search, followed by <code class="language-plaintext highlighter-rouge">polyMesh::pointInCell</code></td>
    </tr>
    <tr>
      <td>2</td>
      <td>Handle boundary points</td>
      <td>Octree search</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Handle points in other regions of the domain</td>
      <td>Octree search</td>
    </tr>
  </tbody>
</table>

<p><strong>Neighbour-search details.</strong> Starting from cell zero, the search visits neighbouring cells and moves to a cell closer to the target point. It repeats until no neighbour is closer. Once the nearest source cell has been found, <code class="language-plaintext highlighter-rouge">polyMesh::pointInCell</code> checks whether the target point lies inside it.</p>

<h3 id="optimization-for-translated-meshes">Optimization for translated meshes</h3>

<p>In most of my preprocessing, the target mesh the translated source mesh in one direction, in this case, the Level 2 and 3 search can be neglected. The octree construction is also neglected.</p>]]></content><author><name></name></author><category term="Notes" /><category term="Code" /><summary type="html"><![CDATA[notes for running simulations in OpenFOAM.]]></summary></entry><entry><title type="html">Journals and their abbreviated titles</title><link href="https://wengzf20.github.io/blog/2024/journalAbbreviation/" rel="alternate" type="text/html" title="Journals and their abbreviated titles" /><published>2024-03-06T00:00:00+00:00</published><updated>2024-03-06T00:00:00+00:00</updated><id>https://wengzf20.github.io/blog/2024/journalAbbreviation</id><content type="html" xml:base="https://wengzf20.github.io/blog/2024/journalAbbreviation/"><![CDATA[<blockquote>
  <p><strong>Living notes.</strong> This page is updated periodically.</p>
</blockquote>

<p>The abbreviated title is generated via <a href="https://cassi.cas.org/search.jsp">CAS Source Index (CASSI) Search Tool</a>.</p>

<h2 id="journal-abbreviations">Journal abbreviations</h2>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Journal</th>
      <th style="text-align: left">Abbreviated title</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">Applications in Energy and Combustion Science</td>
      <td style="text-align: left">Appl. Energy Combust. Sci.</td>
    </tr>
    <tr>
      <td style="text-align: left"><a href="https://onlinelibrary.wiley.com/journal/10974601">International Journal of Chemical Kinetics </a></td>
      <td style="text-align: left">Int. J. Chem. Kinet.</td>
    </tr>
    <tr>
      <td style="text-align: left"><a href="https://www.sciencedirect.com/journal/progress-in-energy-and-combustion-science">Progress in Energy and Combustion Science</a></td>
      <td style="text-align: left">Prog. Energy Combust. Sci.</td>
    </tr>
    <tr>
      <td style="text-align: left"><a href="https://www.sciencedirect.com/journal/combustion-and-flame">Combustion and Flame</a></td>
      <td style="text-align: left">Combust. Flame</td>
    </tr>
    <tr>
      <td style="text-align: left"><a href="https://www.sciencedirect.com/journal/proceedings-of-the-combustion-institute">Proceedings of the Combustion Institute</a></td>
      <td style="text-align: left">Proc. Combust. Inst.</td>
    </tr>
    <tr>
      <td style="text-align: left"><a href="https://www.tandfonline.com/journals/gcst20"> Combustion Science and Technology</a></td>
      <td style="text-align: left">Combust. Sci. Technol.</td>
    </tr>
    <tr>
      <td style="text-align: left"><a href="https://www.cambridge.org/core/journals/journal-of-fluid-mechanics">Journal of Fluid Mechanics</a></td>
      <td style="text-align: left">J. Fluid Mech.</td>
    </tr>
    <tr>
      <td style="text-align: left"><a href="https://journals.aps.org/prfluids/">Physical Review Fluids</a></td>
      <td style="text-align: left">Phys. Rev. Fluids</td>
    </tr>
    <tr>
      <td style="text-align: left"><a href="https://www.sciencedirect.com/journal/computer-physics-communications">Computer Physics Communications</a></td>
      <td style="text-align: left">Comput. Phys. Commun.</td>
    </tr>
    <tr>
      <td style="text-align: left"><a href="https://www.sciencedirect.com/journal/computers-and-fluids">Computers &amp; Fluids</a></td>
      <td style="text-align: left">Comput. Fluids</td>
    </tr>
    <tr>
      <td style="text-align: left"><a href="http://aip.scitation.org/journal/phf">Physics of Fluids</a></td>
      <td style="text-align: left">Phys. Fluids</td>
    </tr>
    <tr>
      <td style="text-align: left"><a href="https://www.sciencedirect.com/journal/international-journal-of-hydrogen-energy">International Journal of Hydrogen Energy</a></td>
      <td style="text-align: left">Int. J. Hydrogen Energy</td>
    </tr>
    <tr>
      <td style="text-align: left"><a href="https://www.sciencedirect.com/journal/journal-of-computational-physics">Journal of Computational Physics</a></td>
      <td style="text-align: left">J. Comput. Phys.</td>
    </tr>
    <tr>
      <td style="text-align: left"><a href="https://www.sciencedirect.com/journal/international-journal-of-multiphase-flow">International Journal of Multiphase Flow</a></td>
      <td style="text-align: left">Int. J. Multiphase Flow</td>
    </tr>
  </tbody>
</table>]]></content><author><name></name></author><category term="Notes" /><summary type="html"><![CDATA[Living notes. This page is updated periodically.]]></summary></entry><entry><title type="html">Notes for OpenFOAM in Linux</title><link href="https://wengzf20.github.io/blog/2024/linux/" rel="alternate" type="text/html" title="Notes for OpenFOAM in Linux" /><published>2024-02-18T00:00:00+00:00</published><updated>2024-02-18T00:00:00+00:00</updated><id>https://wengzf20.github.io/blog/2024/linux</id><content type="html" xml:base="https://wengzf20.github.io/blog/2024/linux/"><![CDATA[<blockquote>
  <p><strong>Living notes.</strong> This page is updated periodically.</p>
</blockquote>

<h2 id="moving-files-to-trash">Moving files to trash</h2>

<p>Move file to trash and empty trash periodically instead of using <code class="language-plaintext highlighter-rouge">rm</code></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># ban rm</span>
<span class="nb">echo</span> <span class="nt">-e</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">alias 'rm'='echo "</span>The use of <span class="nb">rm </span>is banned on this system.<span class="s2">"'"</span> <span class="o">&gt;&gt;</span> ~/.bashrc
<span class="nb">source</span> ~/.bashrc
<span class="c"># move file to transh</span>
gio trash path/to/your/files
</code></pre></div></div>

<h2 id="parallel-compression">Parallel compression</h2>

<p>Compress files in parallel using <code class="language-plaintext highlighter-rouge">pigz</code>.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">tar </span>cf - /path/to/directory | pigz <span class="nt">-p</span> 4 <span class="o">&gt;</span> directory.tar.gz
</code></pre></div></div>

<p>In this command:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">tar cf - /path/to/directory</code> creates an archive of the specified directory and outputs it to standard output (<code class="language-plaintext highlighter-rouge">-</code>).</li>
  <li><code class="language-plaintext highlighter-rouge">pigz -p 4</code> takes the <code class="language-plaintext highlighter-rouge">tar</code> output from standard input and compresses it using 4 cores (<code class="language-plaintext highlighter-rouge">-p 4</code> option).</li>
  <li><code class="language-plaintext highlighter-rouge">&gt; directory.tar.gz</code> redirects the compressed output to a file named <code class="language-plaintext highlighter-rouge">directory.tar.gz</code>.</li>
</ul>

<h2 id="zip-file-extraction">Zip file extraction</h2>

<p>Check the content of the compressed file</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>unzip <span class="nt">-l</span> file.zip
</code></pre></div></div>
<p>Extract part of the compressed file</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>unzip file/in/zip directory/in/zip/<span class="k">*</span>
</code></pre></div></div>

<h2 id="upgrading-gcc-for-cantera-and-openfoam-compilation">Upgrading GCC for Cantera and OpenFOAM compilation</h2>

<p>The compilation of OpenFOAM requires GCC version 5.4 or above (support c++14), Linux cluster based on CentOS Linux usually has default gcc version 4.8.5. To upgrade gcc,</p>
<ol>
  <li>
    <p>get source code from website,</p>

    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> wget <span class="s1">'https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-9.3.0/gcc-9.3.0.tar.gz'</span>
 or
 wget <span class="s1">'https://ftp.gnu.org/gnu/gcc/gcc-9.3.0/gcc-9.3.0.tar.gz'</span>
</code></pre></div>    </div>
  </li>
  <li>
    <p>uncompress it the download dependencies:</p>

    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">tar </span>xzf gcc-9.3.0.tar.gz
<span class="nb">cd </span>gcc-9.3.0
./contrib/download_prerequisites
</code></pre></div>    </div>
  </li>
  <li>
    <p>build the source code and install</p>

    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir </span>build <span class="o">&amp;&amp;</span> <span class="nb">cd </span>build/
../configure <span class="nt">--prefix</span><span class="o">=</span>/dir/to/install/gcc-9.5.0 <span class="nt">--disable-multilib</span> <span class="c"># build only 64bit lib</span>
make <span class="nt">-j</span> 16 <span class="o">&amp;&amp;</span> make <span class="nb">install</span>
</code></pre></div>    </div>
  </li>
  <li>
    <p>(option) Update the environmental</p>

    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span><span class="nv">$PATH</span>:/dir/to/install/gcc-9.3.0/bin
<span class="nb">export </span><span class="nv">LD_LIBRARY_PATH</span><span class="o">=</span><span class="nv">$LD_LIBRARY_PATH</span>:/dir/to/install/gcc-9.3.0/lib:/dir/to/install/gcc-9.3.0/lib64:/dir/to/install/gcc-9.3.0/libexec
<span class="nb">export </span><span class="nv">INCLUDE</span><span class="o">=</span><span class="nv">$INCLUDE</span>:/dir/to/install/gcc-9.3.0/include
<span class="c"># check installation</span>
/dir/to/install/gcc-9.3.0/bin/gcc <span class="nt">--version</span>
</code></pre></div>    </div>
  </li>
  <li>
    <p>specify g++ and gcc version used for compilation</p>

    <p>For OpenFOAM, in directory ‘~/OpenFOAM/OpenFOAM-9/wmake/rules/linux64Gcc/’,</p>

    <div class="language-make highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># in c
</span><span class="nv">cc</span>          <span class="o">=</span> /dir/to/install/gcc-9.3.0/bin/gcc <span class="nt">-m64</span>
<span class="c"># in c++
</span><span class="nv">CC</span>          <span class="o">=</span> /dir/to/install/gcc-9.3.0/bin/g++ <span class="nt">-std</span><span class="o">=</span>c++14 <span class="nt">-m64</span>
</code></pre></div>    </div>

    <p>For Cantera, change CC and CXX environmental varibles in SConstruct</p>

    <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># ************************************
# *** Compiler Configuration Tests ***
# ************************************
</span><span class="n">env</span><span class="p">[</span><span class="s">'CC'</span><span class="p">]</span><span class="o">=</span><span class="s">'/dir/to/install/gcc-9.3.0/bin/gcc'</span>
<span class="n">env</span><span class="p">[</span><span class="s">'CXX'</span><span class="p">]</span><span class="o">=</span><span class="s">'/dir/to/install/gcc-9.3.0/bin/g++'</span>
</code></pre></div>    </div>
  </li>
</ol>

<h2 id="installing-open-mpi-for-openfoam-compilation">Installing Open MPI for OpenFOAM compilation</h2>

<ol>
  <li>
    <p>get source code from website,</p>

    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> wget <span class="s1">'https://download.open-mpi.org/release/open-mpi/v3.1/openmpi-3.1.0.tar.gz'</span>
</code></pre></div>    </div>
  </li>
  <li>
    <p>uncompress it the download dependencies:</p>

    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">tar </span>xzf openmpi-3.1.0.tar.gz
<span class="nb">cd </span>openmpi-3.1.0
</code></pre></div>    </div>
  </li>
  <li>
    <p>build the source code and install</p>

    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir </span>build <span class="o">&amp;&amp;</span> <span class="nb">cd </span>build/
../configure <span class="nt">--prefix</span><span class="o">=</span>/dir/to/install/openmpi-3.1.0
make <span class="nt">-j</span> 16 <span class="o">&amp;&amp;</span> make <span class="nb">install</span>
</code></pre></div>    </div>
  </li>
  <li>
    <p>Update the environmental</p>

    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span><span class="nv">$PATH</span>:/dir/to/install/openmpi-3.1.0/bin
<span class="nb">export </span><span class="nv">LD_LIBRARY_PATH</span><span class="o">=</span><span class="nv">$LD_LIBRARY_PATH</span>:/dir/to/install/openmpi-3.1.0/lib
<span class="c"># check installation</span>
mpic++ <span class="nt">--showme</span>:version
</code></pre></div>    </div>
  </li>
</ol>]]></content><author><name></name></author><category term="Notes" /><category term="Code" /><summary type="html"><![CDATA[notes for using linux.]]></summary></entry><entry><title type="html">CompressibleInterFoam: theory, implementation and examples</title><link href="https://wengzf20.github.io/blog/2024/compressibleInterFoam/" rel="alternate" type="text/html" title="CompressibleInterFoam: theory, implementation and examples" /><published>2024-02-01T00:00:00+00:00</published><updated>2024-02-01T00:00:00+00:00</updated><id>https://wengzf20.github.io/blog/2024/compressibleInterFoam</id><content type="html" xml:base="https://wengzf20.github.io/blog/2024/compressibleInterFoam/"><![CDATA[<blockquote>
  <p><strong>Work in progress.</strong> These notes describe OpenFOAM 9. Sections marked “Coming soon” are incomplete.</p>
</blockquote>

<p>CompressibleInterFoam is a default multiphase solver in OpenFOAM. It is capable of solving two compressible, non-isothermal immiscible fluids, with/without cavitation. The phase interface is captured using volume of fluid (VoF) approach. The following analysis is based on OpenFOAM 9.</p>

<h2 id="conservation-equations">Conservation equations</h2>

<p>The phase-wise mass-conservation equations are</p>

<div class="math-block">
\begin{equation} \label{eq:mass_alpha1}
\frac{\partial\left(\rho_1 \alpha_1\right)}{\partial t}+\nabla \cdot\left(\rho_1 \boldsymbol{U} \alpha_1\right)=\dot{m}
\end{equation}
</div>

<div class="math-block">
\begin{equation} \label{eq:mass_alpha2}
\frac{\partial\left(\rho_2 \alpha_2\right)}{\partial t}+\nabla \cdot\left(\rho_2 \boldsymbol{U} \alpha_2\right)=-\dot{m}
\end{equation}
</div>

<p>where \(\alpha_{1}+\alpha_{2} = 1\); \(\dot{m}\) is the source term from phase change. If there is no phase change, \(\dot{m}\) is zero.</p>

<p>Consider only the volume fraction in the l.h.s., and move other parts to the r.h.s. to be the source term. Eq. \(\eqref{eq:mass_alpha1}\) and \(\eqref{eq:mass_alpha2}\) were re-written as</p>

<div class="math-block">
\begin{equation} \label{eq:mass_alpha1_comp}
\frac{\partial \alpha_1}{\partial t}+\nabla \cdot\left(\boldsymbol{U} \alpha_1\right)=-\frac{\alpha_1}{\rho_1} \frac{D \rho_1}{D t} + \frac{\dot{m}}{\rho_1}
\end{equation}
</div>

<div class="math-block">
\begin{equation} \label{eq:mass_alpha2_comp}
\frac{\partial \alpha_2}{\partial t}+\nabla \cdot\left(\boldsymbol{U} \alpha_2\right)=-\frac{\alpha_2}{\rho_2} \frac{D \rho_2}{D t} - \frac{\dot{m}}{\rho_2}
\end{equation}
</div>

<p>Adding these two equations gives</p>

<div class="math-block">
\begin{equation} \label{eq:divU}
\nabla \cdot\boldsymbol{U}=-\left(\frac{\alpha_1}{\rho_1} \frac{D \rho_1}{D t}+\frac{\alpha_2}{\rho_2} \frac{D \rho_2}{D t}\right)+\dot{m}\left(\frac{1}{\rho_1}-\frac{1}{\rho_2}\right)
\end{equation}
</div>

<p>The 1st and 2nd term in the r.h.s. are the compressibility and phase change effects.</p>

<p>Substitute this expression into Eq. \(\eqref{eq:mass_alpha1_comp}\) by adding and subtracting \(\alpha_{1}\nabla \cdot\boldsymbol{U}\):</p>

<div class="math-block">
\begin{equation} \label{eq:mass_alpha1_final}
\frac{\partial \alpha_1}{\partial t}+\nabla \cdot\left(\boldsymbol{U} \alpha_1\right)=\alpha_1 \alpha_2 \left(\frac{1}{\rho_1} \frac{D \rho_1}{D t}-\frac{1}{\rho_2} \frac{D \rho_2}{D t}\right)
+\alpha_1 \nabla \cdot \boldsymbol{U}+\dot{m}\left(\frac{\alpha_2}{\rho_1}+\frac{\alpha_1}{\rho_2}\right)
\end{equation}
</div>

<p>The compressibility, \(\alpha_1 \nabla \cdot \boldsymbol{U}\) and phase change are source terms for the alpha equation. They are separated into \(S_{p}\) and \(S_{u}\) in the MULES algorithm. \(S_{p}\) is implicit source term, \(S_{u}\) is explicit source term.</p>

<h2 id="mules-method">MULES method</h2>

<h3 id="source-term-decomposition">Source-term decomposition</h3>

<p>In Eq. \(\eqref{eq:mass_alpha1_final}\), it was defined</p>

<div class="math-block">
\begin{equation}
\mathrm{dgdt}=-\alpha_1 \alpha_2 \left(\frac{1}{\rho_1} \frac{D \rho_1}{D t}-\frac{1}{\rho_2} \frac{D \rho_2}{D t}\right)
\end{equation}
</div>

<p>dgdt was calculated in the pEqn, i.e.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">dgdt</span> <span class="o">=</span>
<span class="p">(</span>
    <span class="n">alpha1</span><span class="o">*</span><span class="p">(</span><span class="n">p_rghEqnComp2</span> <span class="o">&amp;</span> <span class="n">p_rgh</span><span class="p">)</span>
    <span class="o">-</span> <span class="n">alpha2</span><span class="o">*</span><span class="p">(</span><span class="n">p_rghEqnComp1</span> <span class="o">&amp;</span> <span class="n">p_rgh</span><span class="p">)</span>
<span class="p">);</span>
</code></pre></div></div>

<p>In solving Eq. \(\eqref{eq:mass_alpha1_final}\), dgdt was separated according to its sign in each cell</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="p">(</span><span class="n">dgdt</span><span class="p">[</span><span class="n">celli</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mf">0.0</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">SpRef</span><span class="p">[</span><span class="n">celli</span><span class="p">]</span> <span class="o">-=</span> <span class="n">dgdt</span><span class="p">[</span><span class="n">celli</span><span class="p">]</span><span class="o">/</span><span class="n">max</span><span class="p">(</span><span class="mf">1.0</span> <span class="o">-</span> <span class="n">alpha1</span><span class="p">[</span><span class="n">celli</span><span class="p">],</span> <span class="mf">1e-4</span><span class="p">);</span>
    <span class="n">SuRef</span><span class="p">[</span><span class="n">celli</span><span class="p">]</span> <span class="o">+=</span> <span class="n">dgdt</span><span class="p">[</span><span class="n">celli</span><span class="p">]</span><span class="o">/</span><span class="n">max</span><span class="p">(</span><span class="mf">1.0</span> <span class="o">-</span> <span class="n">alpha1</span><span class="p">[</span><span class="n">celli</span><span class="p">],</span> <span class="mf">1e-4</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">dgdt</span><span class="p">[</span><span class="n">celli</span><span class="p">]</span> <span class="o">&lt;</span> <span class="mf">0.0</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">SpRef</span><span class="p">[</span><span class="n">celli</span><span class="p">]</span> <span class="o">+=</span> <span class="n">dgdt</span><span class="p">[</span><span class="n">celli</span><span class="p">]</span><span class="o">/</span><span class="n">max</span><span class="p">(</span><span class="n">alpha1</span><span class="p">[</span><span class="n">celli</span><span class="p">],</span> <span class="mf">1e-4</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The code means, if dgdt &gt; 0</p>

\[S_p = \text{phaseChangeS}[1] -\frac{\mathrm{dgdt}}{\alpha_{2}}, S_u = \text{phaseChangeS}[0] + \frac{\mathrm{dgdt}}{\alpha_{2}}\]

<p>if dgdt &lt; 0</p>

\[S_p = \text{phaseChangeS}[1] + \frac{dgdt}{\alpha_{1}}, S_u = \text{phaseChangeS}[0]\]

<p>\(S_p\), \(S_u\) together with other terms were sending to</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// In src/twoPhaseModels/twoPhaseMixture/VoF/alphaEqn.H</span>
<span class="k">if</span> <span class="p">(</span><span class="n">divU</span><span class="p">.</span><span class="n">valid</span><span class="p">())</span>
<span class="p">{</span>
    <span class="n">MULES</span><span class="o">::</span><span class="n">explicitSolve</span>
    <span class="p">(</span>
        <span class="n">geometricOneField</span><span class="p">(),</span> <span class="c1">// 1</span>
        <span class="n">alpha1</span><span class="p">,</span>
        <span class="n">phiCN</span><span class="p">,</span>  <span class="c1">// phi for Euler ddt method, i.e. U</span>
        <span class="n">alphaPhi10</span><span class="p">,</span> <span class="c1">// alpha*U</span>
        <span class="n">Sp</span><span class="p">(),</span>
        <span class="p">(</span><span class="n">Su</span><span class="p">()</span> <span class="o">+</span> <span class="n">divU</span><span class="p">()</span><span class="o">*</span><span class="n">min</span><span class="p">(</span><span class="n">alpha1</span><span class="p">(),</span> <span class="n">scalar</span><span class="p">(</span><span class="mi">1</span><span class="p">)))(),</span>
        <span class="n">oneField</span><span class="p">(),</span>
        <span class="n">zeroField</span><span class="p">()</span>
    <span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="explicit-update-and-limiting">Explicit update and limiting</h3>

<p>In <code class="language-plaintext highlighter-rouge">MULES::explicitSolve</code>, the reciprocal time step is calculated, the limiter is applied, and another <code class="language-plaintext highlighter-rouge">explicitSolve</code> overload is called.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// In src/finiteVolume/fvMatrices/solvers/MULES/MULESTemplates.C</span>
<span class="k">const</span> <span class="n">scalar</span> <span class="n">rDeltaT</span> <span class="o">=</span> <span class="mf">1.0</span><span class="o">/</span><span class="n">mesh</span><span class="p">.</span><span class="n">time</span><span class="p">().</span><span class="n">deltaTValue</span><span class="p">();</span>
<span class="n">limit</span><span class="p">(</span><span class="n">rDeltaT</span><span class="p">,</span> <span class="n">rho</span><span class="p">,</span> <span class="n">psi</span><span class="p">,</span> <span class="n">phi</span><span class="p">,</span> <span class="n">phiPsi</span><span class="p">,</span> <span class="n">Sp</span><span class="p">,</span> <span class="n">Su</span><span class="p">,</span> <span class="n">psiMax</span><span class="p">,</span> <span class="n">psiMin</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>
<span class="n">explicitSolve</span><span class="p">(</span><span class="n">rDeltaT</span><span class="p">,</span> <span class="n">rho</span><span class="p">,</span> <span class="n">psi</span><span class="p">,</span> <span class="n">phiPsi</span><span class="p">,</span> <span class="n">Sp</span><span class="p">,</span> <span class="n">Su</span><span class="p">);</span>
<span class="c1">// rho - geometricOneField()</span>
<span class="c1">// psi - alpha1</span>
<span class="c1">// phiPsi - alphaPhi10</span>
<span class="c1">// Sp - SpRef</span>
<span class="c1">// Su - SuRef + alpha1*divU()</span>
</code></pre></div></div>

<p>In the latter <code class="language-plaintext highlighter-rouge">explicitSolve</code> call, \(\alpha_1\) for next time step was obtained via</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// In src/finiteVolume/fvMatrices/solvers/MULES/MULESTemplates.C</span>
<span class="n">psiIf</span> <span class="o">=</span>
<span class="p">(</span>
    <span class="n">rho</span><span class="p">.</span><span class="n">oldTime</span><span class="p">().</span><span class="n">field</span><span class="p">()</span><span class="o">*</span><span class="n">psi0</span><span class="o">*</span><span class="n">rDeltaT</span>
    <span class="o">+</span> <span class="n">Su</span><span class="p">.</span><span class="n">field</span><span class="p">()</span>
    <span class="o">-</span> <span class="n">psiIf</span>
<span class="p">)</span><span class="o">/</span><span class="p">(</span><span class="n">rho</span><span class="p">.</span><span class="n">field</span><span class="p">()</span><span class="o">*</span><span class="n">rDeltaT</span> <span class="o">-</span> <span class="n">Sp</span><span class="p">.</span><span class="n">field</span><span class="p">());</span>
</code></pre></div></div>

<p>This means:</p>

\[\alpha_1(t+\Delta t)=\frac{\alpha_1(t)/\Delta t  + \mathrm{Su.field} - \frac{1}{V_P} \sum_f U\alpha_1 S_{f}}{1/\Delta t-\mathrm{Sp.field} }\]

<p>The corresponding equation was</p>

\[\frac{\partial \alpha_1}{\partial t}+\nabla \cdot(\boldsymbol{U} \alpha_1)=\alpha_1 S_{p} + S_{u} + \alpha_{1}\nabla\cdot\boldsymbol{U}\]

<blockquote>
  <p><strong>Implementation note:</strong> <code class="language-plaintext highlighter-rouge">Su.field()</code> = \(S_u+\alpha_{1}\nabla\cdot\boldsymbol{U}\), \(\alpha_1 S_{p} + S_{u}\) is implemented in <code class="language-plaintext highlighter-rouge">alphaSuSp.H</code> in the solver.</p>
</blockquote>

<!-- - <span style="color: red;">**if dgdt > 0**</span>
    $$\alpha_1 S_{p} + S_{u} = \alpha_{1}\text{phaseChangeS}[1]  + \text{phaseChangeS}[0] + (1-\alpha_{1})\frac{\mathrm{dgdt}}{\alpha_{2}} $$
    $$= \alpha_{1}\text{phaseChangeS}[1]  + \text{phaseChangeS}[0] + \mathrm{dgdt} $$

- <span style="color: red;">**if dgdt < 0**</span>
    $$\alpha_1 S_{p} + S_{u} = \alpha_{1}\text{phaseChangeS}[1]  + \text{phaseChangeS}[0] + \mathrm{dgdt} $$

    <span style="color: red;">**These two cases indicate**</span>
    $$\alpha_{1}\text{phaseChangeS}[1]  + \text{phaseChangeS}[0]  = \dot{m}\left(\frac{\alpha_2}{\rho_1}+\frac{\alpha_1}{\rho_2}\right)$$
    according to the derivation in the last section. </span> -->

<h2 id="pressure-velocity-coupling">Pressure-velocity coupling</h2>

<p>The velocity field is firstly estimated from the momentum equation, then the velocity field is inserted to Eq. \(\eqref{eq:divU}\).</p>

<div class="math-block">
\begin{equation}
\nabla \cdot (\mathbf{H}_{\boldsymbol{U}} - \frac{1}{a_p} \nabla p_{\mathrm{rgh}}) = -\left(\frac{\alpha_1}{\rho_1} \frac{D \rho_1}{D t} + \frac{\alpha_2}{\rho_2} \frac{D \rho_2}{D t}\right) + \dot{m}\left(\frac{1}{\rho_1} - \frac{1}{\rho_2}\right)
\end{equation}
</div>

<p>The source code for the pressure–Poisson equation is</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">fvScalarMatrix</span> <span class="nf">p_rghEqnIncomp</span>
<span class="p">(</span>
    <span class="n">fvc</span><span class="o">::</span><span class="n">div</span><span class="p">(</span><span class="n">phiHbyA</span><span class="p">)</span> <span class="o">-</span> <span class="n">fvm</span><span class="o">::</span><span class="n">laplacian</span><span class="p">(</span><span class="n">rAUf</span><span class="p">,</span> <span class="n">p_rgh</span><span class="p">)</span>
    <span class="o">==</span> <span class="n">Sp_rgh</span>
<span class="p">);</span>

<span class="n">solve</span>
<span class="p">(</span>
    <span class="n">p_rghEqnComp1</span><span class="p">()</span> <span class="o">+</span> <span class="n">p_rghEqnComp2</span><span class="p">()</span> <span class="o">+</span> <span class="n">p_rghEqnIncomp</span>
<span class="p">);</span>
</code></pre></div></div>

<p>where <em>p_rghEqnIncomp</em> means the incompressible part while <em>p_rghEqnComp1</em> and <em>p_rghEqnComp2</em> are compressible parts corresponding to the two phases.</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">fvc::div(phiHbyA)</code>: \(\nabla \cdot \mathbf{H}_{\boldsymbol{U}}\)</li>
  <li><code class="language-plaintext highlighter-rouge">fvm::laplacian(rAUf, p_rgh)</code>: \(\nabla \cdot ( \frac{1}{a_p} \nabla p_{\mathrm{rgh}})\)</li>
  <li><code class="language-plaintext highlighter-rouge">Sp_rgh</code>: source term from phase change, i.e. \(\dot{m}\left(\frac{1}{\rho_1}-\frac{1}{\rho_2}\right)\)</li>
  <li><code class="language-plaintext highlighter-rouge">p_rghEqnComp1()</code>: \(\frac{\alpha_1}{\rho_1} \frac{D \rho_1}{D t}\)</li>
  <li><code class="language-plaintext highlighter-rouge">p_rghEqnComp2()</code>: \(\frac{\alpha_2}{\rho_2} \frac{D \rho_2}{D t}\)</li>
</ul>

<h3 id="compressibility-treatment">Compressibility treatment</h3>

<blockquote>
  <p><strong>Coming soon.</strong> This section is under development.</p>
</blockquote>

<!-- By assuming constant temperature, the pressure and density can be related with
$$d\rho_{i} = \left(\frac{\partial \rho_{i}}{\partial p}\right)_{T}dp = \psi_{i}dp\text{\quad or\quad}\rho_{i}^* = \rho_{i}^n + \psi_{i}(p^* - p^n)$$
In the pimple loop, the pressure possion equation might be solved for several times in a single time step (for either *nOuterCorrectors* > 1 or *nCorrectors* > 1),  -->

<!-- first, the pressure effect on density was consider in the equation -->

<h2 id="phase-change-model">Phase-change model</h2>

<h3 id="coupling-to-the-volume-fraction-and-pressure-equations">Coupling to the volume-fraction and pressure equations</h3>

<p>The phase change model was included in the \(\alpha\) equation via</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Pair</span><span class="o">&lt;</span><span class="n">tmp</span><span class="o">&lt;</span><span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span><span class="o">&gt;&gt;</span> <span class="n">phaseChangeS</span>
<span class="p">(</span>
    <span class="n">phaseChange</span><span class="p">.</span><span class="n">Salpha</span><span class="p">(</span><span class="n">alpha1</span><span class="p">)</span>
<span class="p">);</span>

<span class="k">if</span> <span class="p">(</span><span class="n">phaseChangeS</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">valid</span><span class="p">())</span>
<span class="p">{</span>
    <span class="n">Su</span> <span class="o">=</span> <span class="n">phaseChangeS</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
    <span class="n">Sp</span> <span class="o">=</span> <span class="n">phaseChangeS</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
<span class="p">}</span>
</code></pre></div></div>

<p>and pressure equation via</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">fvScalarMatrix</span> <span class="nf">Sp_rgh</span><span class="p">(</span><span class="n">phaseChange</span><span class="p">.</span><span class="n">Sp_rgh</span><span class="p">(</span><span class="n">rho</span><span class="p">,</span> <span class="n">gh</span><span class="p">,</span> <span class="n">p_rgh</span><span class="p">));</span>
</code></pre></div></div>

<h3 id="schnerrsauer-model-volume-fraction-source">Schnerr–Sauer model: volume-fraction source</h3>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Foam</span><span class="o">::</span><span class="n">Pair</span><span class="o">&lt;</span><span class="n">Foam</span><span class="o">::</span><span class="n">tmp</span><span class="o">&lt;</span><span class="n">Foam</span><span class="o">::</span><span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span><span class="o">&gt;&gt;</span>
<span class="n">Foam</span><span class="o">::</span><span class="n">twoPhaseChangeModels</span><span class="o">::</span><span class="n">SchnerrSauer</span><span class="o">::</span><span class="n">mDotAlphal</span><span class="p">()</span> <span class="k">const</span>
<span class="p">{</span>
    <span class="p">...</span>
    <span class="k">const</span> <span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span> <span class="n">pCoeff</span><span class="p">(</span><span class="k">this</span><span class="o">-&gt;</span><span class="n">pCoeff</span><span class="p">(</span><span class="n">p</span><span class="p">));</span>
    <span class="p">...</span>
    <span class="k">return</span> <span class="n">Pair</span><span class="o">&lt;</span><span class="n">tmp</span><span class="o">&lt;</span><span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span><span class="o">&gt;&gt;</span>
    <span class="p">(</span>
        <span class="n">Cc_</span><span class="o">*</span><span class="n">limitedAlpha1</span><span class="o">*</span><span class="n">pCoeff</span><span class="o">*</span><span class="n">max</span><span class="p">(</span><span class="n">p</span> <span class="o">-</span> <span class="n">pSat</span><span class="p">(),</span> <span class="n">p0_</span><span class="p">),</span>
        <span class="n">Cv_</span><span class="o">*</span><span class="p">(</span><span class="mf">1.0</span> <span class="o">+</span> <span class="n">alphaNuc</span><span class="p">()</span> <span class="o">-</span> <span class="n">limitedAlpha1</span><span class="p">)</span><span class="o">*</span><span class="n">pCoeff</span><span class="o">*</span><span class="n">min</span><span class="p">(</span><span class="n">p</span> <span class="o">-</span> <span class="n">pSat</span><span class="p">(),</span> <span class="n">p0_</span><span class="p">)</span>
    <span class="p">);</span>
<span class="p">}</span>
    <span class="c1">// Note:</span>
    <span class="c1">// pCoeff = (3*rho1()*rho2())*sqrt(2/(3*rho1()))</span>
    <span class="c1">//   *rRb(limitedAlpha1)/(rho*sqrt(mag(p - pSat()) + 0.01*pSat()));</span>
</code></pre></div></div>

\[\dot{m}=\underbrace{\alpha_{v}\dot{m}_{c}}_{\text{condensation}}+\underbrace{\alpha_{l}\dot{m}_{v}}_{\text{vaporization}}\]

\[\begin{aligned}
&amp; \dot{m}_{c} = C_{c}\alpha_{l}\frac{3\rho_{l}\rho_{v}}{\rho R_{b} \sqrt{|P-P_{s}|}}\sqrt{\frac{2}{3\rho_{l}}}max(P-P_{s},0) \geq 0 \\
&amp;\dot{m}_{v} = C_{v}(1+\alpha_{Nuc}-\alpha_{l})\frac{3\rho_{l}\rho_{v}}{\rho R_{b} \sqrt{|P-P_{s}|}}\sqrt{\frac{2}{3\rho_{l}}}min(P-P_{s},0) \leq 0\\
&amp;\text{pcoeff} = \frac{3\rho_{l}\rho_{v}}{\rho R_{b} \sqrt{|P-P_{s}|}}\sqrt{\frac{2}{3\rho_{l}}}
\end{aligned}\]

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Foam</span><span class="o">::</span><span class="n">Pair</span><span class="o">&lt;</span><span class="n">Foam</span><span class="o">::</span><span class="n">tmp</span><span class="o">&lt;</span><span class="n">Foam</span><span class="o">::</span><span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span><span class="o">&gt;&gt;</span>
<span class="n">Foam</span><span class="o">::</span><span class="n">twoPhaseChangeModels</span><span class="o">::</span><span class="n">cavitationModel</span><span class="o">::</span><span class="n">Salpha</span>
<span class="p">(</span>
    <span class="n">volScalarField</span><span class="o">&amp;</span> <span class="n">alpha</span>
<span class="p">)</span> <span class="k">const</span>
<span class="p">{</span>
    <span class="p">...</span>
    <span class="k">const</span> <span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span> <span class="n">vDotcAlphal</span><span class="p">(</span><span class="n">alphalCoeff</span><span class="o">*</span><span class="n">mDotAlphal</span><span class="p">[</span><span class="mi">0</span><span class="p">]());</span>
    <span class="k">const</span> <span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span> <span class="n">vDotvAlphal</span><span class="p">(</span><span class="n">alphalCoeff</span><span class="o">*</span><span class="n">mDotAlphal</span><span class="p">[</span><span class="mi">1</span><span class="p">]());</span>
    <span class="k">return</span> <span class="n">Pair</span><span class="o">&lt;</span><span class="n">tmp</span><span class="o">&lt;</span><span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span><span class="o">&gt;&gt;</span> <span class="c1">// mdot =  \alpha_{l}S_{p} + S_{u}</span>
    <span class="p">(</span>
        <span class="mf">1.0</span><span class="o">*</span><span class="n">vDotcAlphal</span><span class="p">,</span> <span class="c1">// Su</span>
        <span class="n">vDotvAlphal</span> <span class="o">-</span> <span class="n">vDotcAlphal</span> <span class="c1">// Sp</span>
    <span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The source term in \(\alpha_{l}\) equation, \(S_{\alpha}\) was separated as</p>

\[\begin{aligned}
S_{\alpha} &amp;= \alpha_{l,coeff}\dot{m} \\
&amp;= \alpha_{l,coeff}(\alpha_{l}\dot{m}_{v} + \alpha_{v}\dot{m}_{c}) \\
&amp;= \alpha_{l,coeff}[\alpha_{l}(\dot{m}_{v}-\dot{m}_{c}) + \dot{m}_{c}]\\
&amp;= \underbrace{\alpha_{l}\alpha_{l,coeff}(\dot{m}_{v}-\dot{m}_{c})}_{\alpha_{l} \text{Sp} &lt;0} + \underbrace{\alpha_{l,coeff}\dot{m}_{c}}_{\text{Su} &gt;0} \\
&amp;= \alpha_{l}\text{Sp} + \text{Su}
\end{aligned}\]

\[\alpha_{l,coeff} = \left(\frac{1}{\rho_l}-\alpha_{l}\left(\frac{1}{\rho_l}-\frac{1}{\rho_v}\right)\right) &gt; 0\]

<p>In OpenFOAM, fvm::Sp handles negative source term. fvm::Sp makes the negative source term implicit so it contributes to the diagonal and increases its diagonal contribution. This can help convergence when the source term is negative on the rhs (sink term). (ref.: OpenFOAM® Beginner training session)</p>

<h3 id="schnerrsauer-model-pressure-source">Schnerr–Sauer model: pressure source</h3>

<p>The mass transfer rate in pEqn, \(\dot{m}_{p}\) was defined as</p>

\[\dot{m}_{p} = -\frac{\dot{m}}{P-P_{s}} = \underbrace{-\frac{\alpha_{l}\dot{m}_{v}}{P-P_{s}}}_{\dot{m}_{p,v} \leq 0 } - \underbrace{\frac{(1-\alpha_{l})\dot{m}_{c}}{P-P_{s}}}_{\dot{m}_{p,c} \geq 0 }  =
\dot{m}_{p,v} - \dot{m}_{p,c}\]

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Foam</span><span class="o">::</span><span class="n">Pair</span><span class="o">&lt;</span><span class="n">Foam</span><span class="o">::</span><span class="n">tmp</span><span class="o">&lt;</span><span class="n">Foam</span><span class="o">::</span><span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span><span class="o">&gt;&gt;</span>
<span class="n">Foam</span><span class="o">::</span><span class="n">twoPhaseChangeModels</span><span class="o">::</span><span class="n">SchnerrSauer</span><span class="o">::</span><span class="n">mDotP</span><span class="p">()</span> <span class="k">const</span>
<span class="p">{</span>
    <span class="k">const</span> <span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span> <span class="n">apCoeff</span><span class="p">(</span><span class="n">limitedAlpha1</span><span class="o">*</span><span class="n">pCoeff</span><span class="p">);</span>

    <span class="k">return</span> <span class="n">Pair</span><span class="o">&lt;</span><span class="n">tmp</span><span class="o">&lt;</span><span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span><span class="o">&gt;&gt;</span>
    <span class="p">(</span>
        <span class="n">Cc_</span><span class="o">*</span><span class="p">(</span><span class="mf">1.0</span> <span class="o">-</span> <span class="n">limitedAlpha1</span><span class="p">)</span><span class="o">*</span><span class="n">pos0</span><span class="p">(</span><span class="n">p</span> <span class="o">-</span> <span class="n">pSat</span><span class="p">())</span><span class="o">*</span><span class="n">apCoeff</span><span class="p">,</span>

        <span class="p">(</span><span class="o">-</span><span class="n">Cv_</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="mf">1.0</span> <span class="o">+</span> <span class="n">alphaNuc</span><span class="p">()</span> <span class="o">-</span> <span class="n">limitedAlpha1</span><span class="p">)</span><span class="o">*</span><span class="n">neg</span><span class="p">(</span><span class="n">p</span> <span class="o">-</span> <span class="n">pSat</span><span class="p">())</span><span class="o">*</span><span class="n">apCoeff</span>
    <span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

\[\begin{aligned}
&amp; \dot{m}_{p,c} = C_{c}(1-\alpha_{l})*\underbrace{\alpha_{l}\text{pcoeff}}_{\text{apcoeff}}*\text{pos0}(P-P_{s}) =\frac{1-\alpha_{l}}{P-P_{s}}\dot{m}_{c} \geq 0 \\
&amp;\dot{m}_{p,v} = -C_{v}(1+\alpha_{Nuc}-\alpha_{l})*\underbrace{\alpha_{l}\text{pcoeff}}_{\text{apcoeff}}*\text{neg}(P-P_{s}) = -\frac{\alpha_{l}}{P-P_{s}}\dot{m}_{v} \leq 0
\end{aligned}\]

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Foam</span><span class="o">::</span><span class="n">tmp</span><span class="o">&lt;</span><span class="n">Foam</span><span class="o">::</span><span class="n">fvScalarMatrix</span><span class="o">&gt;</span>
<span class="n">Foam</span><span class="o">::</span><span class="n">twoPhaseChangeModels</span><span class="o">::</span><span class="n">cavitationModel</span><span class="o">::</span><span class="n">Sp_rgh</span>
<span class="p">(</span>
    <span class="k">const</span> <span class="n">volScalarField</span><span class="o">&amp;</span> <span class="n">rho</span><span class="p">,</span>
    <span class="k">const</span> <span class="n">volScalarField</span><span class="o">&amp;</span> <span class="n">gh</span><span class="p">,</span>
    <span class="n">volScalarField</span><span class="o">&amp;</span> <span class="n">p_rgh</span>
<span class="p">)</span> <span class="k">const</span>
<span class="p">{</span>
    <span class="k">const</span> <span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span> <span class="n">pCoeff</span><span class="p">(</span><span class="mf">1.0</span><span class="o">/</span><span class="n">rho1</span><span class="p">()</span> <span class="o">-</span> <span class="mf">1.0</span><span class="o">/</span><span class="n">rho2</span><span class="p">());</span>
    <span class="k">const</span> <span class="n">Pair</span><span class="o">&lt;</span><span class="n">tmp</span><span class="o">&lt;</span><span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span><span class="o">&gt;&gt;</span> <span class="n">mDotP</span> <span class="o">=</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">mDotP</span><span class="p">();</span>

    <span class="k">const</span> <span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span> <span class="n">vDotcP</span><span class="p">(</span><span class="n">pCoeff</span><span class="o">*</span><span class="n">mDotP</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
    <span class="k">const</span> <span class="n">volScalarField</span><span class="o">::</span><span class="n">Internal</span> <span class="n">vDotvP</span><span class="p">(</span><span class="n">pCoeff</span><span class="o">*</span><span class="n">mDotP</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>

    <span class="k">return</span>
        <span class="p">(</span><span class="n">vDotvP</span> <span class="o">-</span> <span class="n">vDotcP</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">pSat</span><span class="p">()</span> <span class="o">-</span> <span class="n">rho</span><span class="p">()</span><span class="o">*</span><span class="n">gh</span><span class="p">())</span>
      <span class="o">-</span> <span class="n">fvm</span><span class="o">::</span><span class="n">Sp</span><span class="p">(</span><span class="n">vDotvP</span> <span class="o">-</span> <span class="n">vDotcP</span><span class="p">,</span> <span class="n">p_rgh</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

\[\begin{aligned}
S_{P}&amp;= \left(\frac{1}{\rho_{l}}-\frac{1}{\rho_{v}}\right)\dot{m}\\
&amp; = \left(\frac{1}{\rho_{l}}-\frac{1}{\rho_{v}}\right)(\dot{m}_{p,v} - \dot{m}_{p,c})(P_{s}-P)\\
&amp; = \underbrace{\left(\frac{1}{\rho_{l}}-\frac{1}{\rho_{v}}\right)(\dot{m}_{p,v} - \dot{m}_{p,c})P_{s}}_{\text{Su}&gt;0}\quad \underbrace{-\left(\frac{1}{\rho_{l}}-\frac{1}{\rho_{v}}\right)(\dot{m}_{p,v} - \dot{m}_{p,c})P}_{P*\text{Sp}&lt;0}\\
\end{aligned}\]

<p>(Note: \({1}/{\rho_{l}}-{1}/{\rho_{v}} &lt;0\))</p>

<h2 id="temperature-equation">Temperature equation</h2>

<blockquote>
  <p><strong>Coming soon.</strong> This section is under development.</p>
</blockquote>

<!-- ```bash
fvScalarMatrix TEqn
(
    fvm::ddt(rho, T) + fvm::div(rhoPhi, T) - fvm::Sp(contErr, T)
    - fvm::laplacian(turbulence.alphaEff(), T)
    + (
        fvc::div(fvc::absolute(phi, U), p)()() // - contErr/rho*p
        + (fvc::ddt(rho, K) + fvc::div(rhoPhi, K))()()
        - (U()&(fvModels.source(rho, U)&U)()) - contErr*K
    )
    *(
        alpha1()/mixture.thermo1().Cv()()
        + alpha2()/mixture.thermo2().Cv()()
    )
    ==
    fvModels.source(rho, T)
);
```
 $$\frac{\partial \rho T}{\partial t} + \nabla\cdot(\rho \boldsymbol{U} T) - err*T - \nabla\cdot(\alpha_{eff}\nabla T) $$
 $$+ (\frac{\alpha_{1}}{C_{v,1}} + \frac{\alpha_{2}}{C_{v,2}})$$
 $$*[\nabla\cdot(U p) + \frac{\partial \rho K}{\partial t} + \nabla\cdot(\rho\boldsymbol{U} K) $$

 $$- U\otimes(fvSource(\rho U)\otimes U) - err*K]$$
 $$== fvSource(\rho T)$$

  $$\frac{\partial \rho T}{\partial t} + \nabla\cdot(\rho \boldsymbol{U} T) - \nabla\cdot(\alpha_{eff}\nabla T) $$
 $$+ (\frac{\alpha_{1}}{C_{v,1}} + \frac{\alpha_{2}}{C_{v,2}})*[\nabla\cdot(U p) + \frac{\partial \rho K}{\partial t} + \nabla\cdot(\rho\boldsymbol{U} K)]== 0$$

## Counter-gradient transport (interfaceCompression scheme)
In the VoF treatment, a common closure used for counter-gradient transport has the form
> D.A.P. Solis, “Development of a compressible VOF solver for cavitating flows,” (n.d.).

$$
\begin{aligned}
& \alpha_1 \rho \frac{\mathrm{D} T}{\mathrm{D} t}+\frac{\alpha_{\mathrm{l}}}{c_{p, 1}} \rho \frac{\mathrm{D} K}{\mathrm{D} t}=\left(\frac{\partial p}{\partial t}+\nabla \cdot\left(k_{\mathrm{l}} \nabla T\right)\right) \frac{\alpha_{\mathrm{l}}}{c_{p, 1}}+\frac{\alpha_{\mathrm{l}}}{c_{p, 1}} \dot{m}_1 h_{\mathrm{g}}-\frac{\rho}{\rho_{\mathrm{l}} c_{p, 1}} \dot{m}_1 h_1 \\
& \alpha_{\mathrm{g}} \rho \frac{\mathrm{D} T}{\mathrm{D} t}+\frac{\alpha_{\mathrm{g}}}{c_{p, \mathrm{~g}}} \rho \frac{\mathrm{D} K}{\mathrm{D} t}=\left(\frac{\partial p}{\partial t}+\nabla \cdot\left(k_{\mathrm{g}} \nabla T\right)\right) \frac{\alpha_{\mathrm{g}}}{c_{p, \mathrm{~g}}}-\frac{\alpha_{\mathrm{g}}}{c_{p, \mathrm{~g}}} \dot{m}_{\mathrm{g}} h_{\mathrm{g}}
\end{aligned}
$$

$$
\begin{array}{r}
\rho \frac{\mathrm{D} T}{\mathrm{D} t}+\left(\frac{\alpha_1}{c_{p, 1}}+\frac{\alpha_{\mathrm{g}}}{c_{p, \mathrm{~g}}}\right)\left(\rho \frac{\mathrm{D} K}{\mathrm{D} t}-\frac{\partial p}{\partial t}\right)-\left(\alpha_1 \nabla \cdot(\right. \\
\left.\cdot\left(\alpha_{\mathrm{Eff}, 1} \nabla T\right)+\alpha_{\mathrm{g}} \nabla \cdot\left(\alpha_{\mathrm{Eff}, \mathrm{g}} \nabla T\right)\right)= \\
\dot{m}_1 h_{\mathrm{g}}\left(\frac{\alpha_1}{c_{p, 1}}+\frac{\alpha_{\mathrm{g}}}{c_{p, \mathrm{~g}}}\right)-\frac{\rho}{\rho_1 c_{p, 1}} \dot{m}_1 h_1,
\end{array}
$$

## Reference
> 1. $\alpha$ equation: Shi, X., Zheng, K., & Yin, B. (2023). Numerical method for gas-liquid two-phase flow with phase change heat transfer considering compressibility using OpenFOAM. International Journal of Thermal Sciences, 188, 108195.
> 2. momentum equation and coupling: S.T. Miller, H. Jasak, D.A. Boger, E.G. Paterson, and A. Nedungadi, “A pressure-based, compressible, two-phase flow finite volume method for underwater explosions,” Computers & Fluids 87, 132–143 (2013).  -->]]></content><author><name></name></author><category term="Solvers" /><category term="OpenFOAM" /><summary type="html"><![CDATA[this post is intended for a thorough introduction to compressibleInterFoam, including the governing equation, implementation in OpenFOAM and some demos.]]></summary></entry><entry><title type="html">An introduction to RSDFoam</title><link href="https://wengzf20.github.io/blog/2023/RSDFoam/" rel="alternate" type="text/html" title="An introduction to RSDFoam" /><published>2023-06-01T00:00:00+00:00</published><updated>2023-06-01T00:00:00+00:00</updated><id>https://wengzf20.github.io/blog/2023/RSDFoam</id><content type="html" xml:base="https://wengzf20.github.io/blog/2023/RSDFoam/"><![CDATA[<p>RSDFoam is a solver for <strong>R</strong>eal gas <strong>S</strong>hock and <strong>D</strong>etonation simulation based on Open<strong>FOAM</strong>. The present solver was based on <strong>the reactive Euler equations</strong>. It has considered the nonidealities in the equation of state, thermodynamic functions and mass action law brought about by the interaction between the fluid particles and by their finite volume.</p>

<h2 id="implementation">Implementation</h2>

<p>RSDFoam was a connection between Cantera and blastFoam. A number of real gas models based on cubic equation of state were implemented by the authors in Cantera 2.4. The solver also utilize the the efficient chemistry solver (CVODE) and flexible input formats in Cantera. BlastFoam offers a number of CFD capabilities including high-order flux evaluation, time integration, etc.</p>

<div class="row">
    <div class="col-sm-12">
        <img src="/assets/img/forblogs/RSDFoam/CanteraDiagram.png" alt="example image" class="img-fluid rounded z-depth-1" loading="lazy" />
    </div>
</div>
<div class="caption">
    Inheritance diagram for implementing real gas models in Cantera. Dashed arrow denotes an instance, indicated onto the dashed line, is created in the class pointed at.
</div>

<div class="row">
    <div class="col-sm-12">
        <img src="/assets/img/forblogs/RSDFoam/RSDFoamDiagram.png" alt="example image" class="img-fluid rounded z-depth-1" loading="lazy" />
    </div>
</div>
<div class="caption">
    Inheritance diagram for classes used in the connection between blastFoam and Cantera. Dashed arrow denotes an instance, indicated onto the dashed line, is created in the class pointed at.
</div>

<h2 id="validation">Validation</h2>

<p>RSDFoam has been thoroughly validated against analytical solutions, previous numerical simulation results and experimental data. The satisfactory agreement demonstrates the accuracy and robustness of the solver for real gas based shock and detonation simulation.</p>

<h3 id="shock-tube-problem">Shock tube problem</h3>

<div class="row">
    <div class="col-sm-4">
        <img src="/assets/img/forblogs/RSDFoam/Sod_P.png" alt="example image" class="img-fluid rounded z-depth-1" loading="lazy" />
    </div>
    <div class="col-sm-4">
        <img src="/assets/img/forblogs/RSDFoam/Sod_rho.png" alt="example image" class="img-fluid rounded z-depth-1" loading="lazy" />
    </div>
    <div class="col-sm-4">
        <img src="/assets/img/forblogs/RSDFoam/Sod_T.png" alt="example image" class="img-fluid rounded z-depth-1" loading="lazy" />
    </div>
</div>
<div class="caption">
    Analytical and numerical solutions of Sod shock tube problem at 0.05 s.
</div>

<h3 id="oblique-shock">Oblique shock</h3>

<div class="row justify-content-sm-center">
    <div class="col-sm-6 mt-3 mt-md-0">
        <img src="/assets/img/forblogs/RSDFoam/ObliquePolar.png" alt="example image" class="img-fluid rounded z-depth-1" loading="lazy" />
    </div>
</div>
<div class="caption">
    The oblique shock wave angle and deflection angle relation calculated for IG gas and RK gas.
</div>

<h3 id="constant-volume-reactor">Constant volume reactor</h3>

<div class="row justify-content-sm-center">
    <div class="col-sm-12 mt-3 mt-md-0">
        <img src="/assets/img/forblogs/RSDFoam/CVIDT.png" alt="example image" class="img-fluid rounded z-depth-1" loading="lazy" />
    </div>
</div>
<div class="caption">
    Ignition delay time of stoichiometric (a) H<sub>2</sub>–air and (b) DME–O<sub>2</sub> mixtures calculated with IG and RK EoS. The second row shows the relative differences of IDT obtained with IG and RK EoS.
</div>

<h3 id="detonation-speed">Detonation speed</h3>

<div class="row justify-content-sm-center">
    <div class="col-sm-8 mt-3 mt-md-0">
        <img src="/assets/img/forblogs/RSDFoam/DetSpeed.png" alt="example image" class="img-fluid rounded z-depth-1" loading="lazy" />
    </div>
</div>
<div class="caption">
    Comparison of steady detonation speed calculated with CJ theory and RSDFoam, and measured by Bauer et al [1].
</div>

<h3 id="reaction-zone-structure-of-steady-planar-detonation">Reaction zone structure of steady planar detonation</h3>

<div class="row justify-content-sm-center">
    <div class="col-sm-4 mt-3 mt-md-0">
        <img src="/assets/img/forblogs/RSDFoam/ZND_P.png" alt="example image" class="img-fluid rounded z-depth-1" loading="lazy" />
    </div>
    <div class="col-sm-4 mt-3 mt-md-0">
        <img src="/assets/img/forblogs/RSDFoam/ZND_T.png" alt="example image" class="img-fluid rounded z-depth-1" loading="lazy" />
    </div>
    <div class="col-sm-4 mt-3 mt-md-0">
        <img src="/assets/img/forblogs/RSDFoam/ZND_massFraction.png" alt="example image" class="img-fluid rounded z-depth-1" loading="lazy" />
    </div>
</div>
<div class="caption">
    Flow structure of detonations obtained with 1D unsteady simulation and the ZND theory.
</div>

<h3 id="pulsating-detonation">Pulsating detonation</h3>

<div class="row justify-content-sm-center">
    <div class="col-sm-12 mt-3 mt-md-0">
        <img src="/assets/img/forblogs/RSDFoam/pulsatingDet.png" alt="example image" class="img-fluid rounded z-depth-1" loading="lazy" />
    </div>
</div>
<div class="caption">
    Shock pressure of pulsating detonation. Four mesh sizes were used for the convergence study.
</div>

<h3 id="two-dimensional-cellular-detonation">Two-dimensional cellular detonation</h3>

<div class="row justify-content-sm-center">
    <div class="col-sm-12 mt-3 mt-md-0">
        <img src="/assets/img/forblogs/RSDFoam/CellularStructure.png" alt="example image" class="img-fluid rounded z-depth-1" loading="lazy" />
    </div>
</div>
<div class="caption">
    Numerical soot foils obtained with (a) IG EoS and (b) NA EoS.
</div>

<h2 id="using-the-solver">Using the solver</h2>

<p>Source codes and demos are available upon reasonable request.</p>

<p>Please cite our papers if you use this solver for your research</p>

<div class="language-bibtex highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">@article</span><span class="p">{</span><span class="nl">WengCAF2023</span><span class="p">,</span>
  <span class="na">title</span> <span class="p">=</span> <span class="s">{Implementation of an  Solver for Shock and Detonation Simulation at High Pressure}</span><span class="p">,</span>
  <span class="na">author</span> <span class="p">=</span> <span class="s">{Weng, Zifeng and M{\'e}vel, R{\'e}my}</span><span class="p">,</span>
  <span class="na">year</span> <span class="p">=</span> <span class="s">{2023}</span><span class="p">,</span>
  <span class="na">journal</span> <span class="p">=</span> <span class="s">{Computers \&amp; Fluids}</span><span class="p">,</span>
  <span class="na">pages</span> <span class="p">=</span> <span class="s">{106012}</span><span class="p">,</span>
  <span class="na">doi</span> <span class="p">=</span> <span class="s">{10.1016/j.compfluid.2023.106012}</span>
<span class="p">}</span>
</code></pre></div></div>

<details class="references"><summary>Previous works using this solver</summary>
<pre>
[1] Zifeng Weng, Rémy Mével. An OpenFOAM Solver for Shock and Detonation Simulation in Real Gas. The 29th ICDERS. At: Siheung, South Korea (2023).
[2] Zifeng Weng, Rémy Mével. Implementation of an OpenFOAM solver for shock and detonation simulation at high pressure.  Computers &amp; Fluids 265, 106012 (2023).
[3] Zifeng Weng, Rémy Mével. Linear and non-linear stability of gaseous detonation at elevated pressure. Combustion and Flame 262, 113361 (2024).
[4] Zifeng Weng, Rémy Mével. Dynamics of detonation cellular structure in linear and nonlinear instability regimes. (under reviewed)
</pre>
</details>

<details class="references"><summary>References</summary>
<pre>
[1] R.G. Schmitt, and P.B. Butler, “Detonation Properties of Gases at Elevated Initial Pressures,” Combustion Science and Technology 106(1–3), 167–191 (1995).
</pre>
</details>]]></content><author><name></name></author><category term="Solvers" /><category term="OpenFOAM" /><summary type="html"><![CDATA[an in-house solver for real gas shock and detonation simulation]]></summary></entry></feed>