Files
GridFire/docs/html/index.html

968 lines
93 KiB
HTML
Raw Normal View History

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.13.2"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>GridFire: GridFire</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="doxygen-awesome.css" rel="stylesheet" type="text/css"/>
<link href="doxygen-awesome-sidebar-only.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
2025-11-27 15:06:27 -05:00
<div id="projectname">GridFire<span id="projectnumber">&#160;v0.7.0_rc2</span>
</div>
<div id="projectbrief">General Purpose Nuclear Network</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.13.2 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() { codefold.init(0); });
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search',true);
$(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function(){initNavTree('index.html',''); initResizable(true); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div><div class="header">
<div class="headertitle"><div class="title">GridFire </div></div>
</div><!--header-->
<div class="contents">
2025-11-25 14:31:59 -05:00
<div class="textblock"><p align="center"><a class="anchor" id="md_docs_2static_2mainpage"></a> </p>
<p><img src="https://github.com/4D-STAR/GridFire/blob/main/assets/logo/GridFire.png?raw=true" alt="OPAT Core Libraries Logo" width="300" class="inline"/> </p>
<hr />
<p> <img src="https://img.shields.io/pypi/v/gridfire?style=for-the-badge" alt="PyPI - Version" class="inline"/> <img src="https://img.shields.io/pypi/wheel/gridfire?style=for-the-badge" alt="PyPI - Wheel" class="inline"/></p>
<p><img src="https://img.shields.io/github/license/4D-STAR/GridFire?style=for-the-badge" alt="GitHub License" class="inline"/> <img src="https://img.shields.io/badge/Funded%20by-ERC-blue?style=for-the-badge&amp;logo=europeancommission" alt="ERC" class="inline"/></p>
2025-11-27 15:06:27 -05:00
<p>![Dynamic Regex Badge](<a href="https://img.shields.io/badge/dynamic/regex?url=https%3A%2F%2Fraw.githubusercontent.com%2F4D-STAR%2FGridFire%2Frefs%2Fheads%2Fmain%2Fmeson.build&search=version%3A%20'(.%2B)'%2C&style=for-the-badge&label=Main%20Branch%20Version">https://img.shields.io/badge/dynamic/regex?url=https%3A%2F%2Fraw.githubusercontent.com%2F4D-STAR%2FGridFire%2Frefs%2Fheads%2Fmain%2Fmeson.build&amp;search=version%3A%20'(.%2B)'%2C&amp;style=for-the-badge&amp;label=Main%20Branch%20Version</a>) <img src="https://img.shields.io/github/commit-activity/w/4D-STAR/GridFire?style=for-the-badge" alt="GitHub commit activity" class="inline"/></p>
2025-11-25 14:31:59 -05:00
<hr />
<h1><a class="anchor" id="autotoc_md2"></a>
2025-07-31 10:54:31 -04:00
Introduction</h1>
2025-11-25 14:31:59 -05:00
<p>GridFire is a C++ library designed to perform general nuclear network evolution. It is part of the larger SERiF project within the 4D-STAR collaboration. GridFire is primarily focused on modeling the most relevant burning stages for stellar evolution modeling. Currently, there is limited support for inverse reactions. Therefore, GridFire has a limited set of tools to evolve a fusing plasma in NSE; however, this is not the primary focus of the library and has therefore not had significant development. For those interested in modeling super nova, neutron star mergers, or other high-energy astrophysical phenomena, we <b>strongly</b> recommend using <a href="https://bitbucket.org/jlippuner/skynet/src/master/">SkyNet</a>.</p>
2025-11-27 15:06:27 -05:00
<h2><a class="anchor" id="autotoc_md3"></a>
2025-07-31 10:54:31 -04:00
Design Philosophy and Workflow</h2>
<p>GridFire is architected to balance physical fidelity, computational efficiency, and extensibility when simulating complex nuclear reaction networks. Users begin by defining a composition, which is used to construct a full GraphEngine representation of the reaction network. A GraphNetwork uses <a href="https://reaclib.jinaweb.org/index.php">JINA Reaclib</a> reaction rates (<a href="https://iopscience.iop.org/article/10.1088/0067-0049/189/1/240">Cyburt et al., ApJS 189 (2010) 240.</a>) along with a dynamically constructed network topology. To manage the inherent stiffness and multiscale nature of these networks, GridFire employs a layered view strategy: partitioning algorithms isolate fast and slow processes, adaptive culling removes negligible reactions at runtime, and implicit solvers stably integrate the remaining stiff system. This modular pipeline allows researchers to tailor accuracy versus performance trade-offs, reuse common engine components, and extend screening or partitioning models without modifying core integration routines.</p>
2025-11-27 15:06:27 -05:00
<h2><a class="anchor" id="autotoc_md4"></a>
2025-07-24 11:10:45 -04:00
Funding</h2>
<p>GridFire is a part of the 4D-STAR collaboration.</p>
<p>4D-STAR is funded by European Research Council (ERC) under the Horizon Europe programme (Synergy Grant agreement No. 101071505: 4D-STAR) Work for this project is funded by the European Union. Views and opinions expressed are however those of the author(s) only and do not necessarily reflect those of the European Union or the European Research Council.</p>
2025-11-27 15:06:27 -05:00
<h1><a class="anchor" id="autotoc_md5"></a>
2025-07-31 10:54:31 -04:00
Usage</h1>
2025-11-27 15:06:27 -05:00
<h2><a class="anchor" id="autotoc_md6"></a>
2025-07-31 10:54:31 -04:00
Python installation</h2>
2025-11-25 14:31:59 -05:00
<p>By far the easiest way to install is with pip. This will install either pre-compiled wheels or, if your system has not had a wheel compiled for it, it will try to build locally (this may take <b>a long time</b>). The python bindings are just that and should maintain nearly the same speed as the C++ code. End users are strongly encouraged to use the python module rather than the C++ code.</p>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md7"></a>
2025-07-31 10:54:31 -04:00
pypi</h3>
2025-11-25 14:31:59 -05:00
<p>Installing from pip is as simple as. </p><div class="fragment"><div class="line">pip install gridfire</div>
2025-07-31 10:54:31 -04:00
</div><!-- fragment --><p>These wheels have been compiled on many systems</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Version </th><th class="markdownTableHeadNone">Platform </th><th class="markdownTableHeadNone">Architecture </th><th class="markdownTableHeadNone">CPython Versions </th><th class="markdownTableHeadNone">PyPy Versions </th></tr>
<tr class="markdownTableRowOdd">
2025-11-25 14:31:59 -05:00
<td class="markdownTableBodyNone">0.7.0_rc1 </td><td class="markdownTableBodyNone">macOS </td><td class="markdownTableBodyNone">arm64 </td><td class="markdownTableBodyNone">3.8, 3.9, 3.10, 3.11, 3.12, 3.13 (std &amp; t), 3.14 (std &amp; t) </td><td class="markdownTableBodyNone">3.10, 3.11 </td></tr>
2025-07-31 10:54:31 -04:00
<tr class="markdownTableRowEven">
2025-11-25 14:31:59 -05:00
<td class="markdownTableBodyNone">0.7.0_rc1 </td><td class="markdownTableBodyNone">Linux </td><td class="markdownTableBodyNone">aarch64 </td><td class="markdownTableBodyNone">3.8, 3.9, 3.10, 3.11, 3.12, 3.13 (std &amp; t), 3.14 (std &amp; t) </td><td class="markdownTableBodyNone">3.10, 3.11 </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">0.7.0_rc1 </td><td class="markdownTableBodyNone">Linux </td><td class="markdownTableBodyNone">x86_64 </td><td class="markdownTableBodyNone">3.8, 3.9, 3.10, 3.11, 3.12, 3.13 (std &amp; t), 3.14 (std &amp; t) </td><td class="markdownTableBodyNone">3.10, 3.11 </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">0.5.0 </td><td class="markdownTableBodyNone">macOS </td><td class="markdownTableBodyNone">arm64 </td><td class="markdownTableBodyNone">3.8, 3.9, 3.10, 3.11, 3.12, 3.13 (std &amp; t), 3.14 (std &amp; t) </td><td class="markdownTableBodyNone">3.10, 3.11 </td></tr>
2025-07-31 10:54:31 -04:00
<tr class="markdownTableRowOdd">
2025-11-25 14:31:59 -05:00
<td class="markdownTableBodyNone">0.5.0 </td><td class="markdownTableBodyNone">Linux </td><td class="markdownTableBodyNone">aarch64 </td><td class="markdownTableBodyNone">3.8, 3.9, 3.10, 3.11, 3.12, 3.13 (std &amp; t), 3.14 (std &amp; t) </td><td class="markdownTableBodyNone">3.10, 3.11 </td></tr>
<tr class="markdownTableRowEven">
2025-07-31 10:54:31 -04:00
<td class="markdownTableBodyNone">0.5.0 </td><td class="markdownTableBodyNone">Linux </td><td class="markdownTableBodyNone">x86_64 </td><td class="markdownTableBodyNone">3.8, 3.9, 3.10, 3.11, 3.12, 3.13 (std &amp; t), 3.14 (std &amp; t) </td><td class="markdownTableBodyNone">3.10, 3.11 </td></tr>
</table>
<blockquote class="doxtable">
2025-11-25 14:31:59 -05:00
<p><b>Note</b>: Currently macOS x86_64 does <b>not</b> have a precompiled wheel. Due to that platform being phased out it is likely that there will never be precompiled wheels or releases for it. </p>
2025-07-31 10:54:31 -04:00
</blockquote>
<blockquote class="doxtable">
2025-07-31 15:41:27 -04:00
<p><b>Note:</b> macOS wheels were targeted to macOS 12 Monterey and should work on any version more recent than that (at least as of August 2025). </p>
2025-07-31 10:54:31 -04:00
</blockquote>
<blockquote class="doxtable">
<p><b>Note:</b> Linux wheels were compiled using manylinux_2_28 and are expected to work on Debian 10+, Ubuntu 18.10+, Fedora 29+, or CentOS/RHEL 8+ </p>
</blockquote>
<blockquote class="doxtable">
<p><b>Note:</b> If your system does not have a prebuilt wheel the source distribution will download from pypi and try to build. This may simply not work if you do not have the correct system dependencies installed. If it fails the best bet is to try to build boost &gt;= 1.83.0 from source and install (<a href="https://www.boost.org/">https://www.boost.org/</a>) as that is the most common broken dependency. </p>
</blockquote>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md8"></a>
2025-07-31 10:54:31 -04:00
source</h3>
<p>The user may also build the python bindings directly from source</p>
<div class="fragment"><div class="line">git clone https://github.com/4D-STAR/GridFire</div>
<div class="line">cd GridFire</div>
<div class="line">pip install .</div>
</div><!-- fragment --><blockquote class="doxtable">
<p><b>Note:</b> that if you do not have all system dependencies installed this will fail, the steps in further sections address these in more detail. </p>
</blockquote>
2025-11-25 14:31:59 -05:00
<blockquote class="doxtable">
<p><b>Note:</b> If you are using macos you should use the included <code>pip_install_mac_patch.sh</code> script instead of <code>pip install .</code> as this will automatically patch the build shared object libraries such that they can be loaded by the macos dynamic loader. </p>
</blockquote>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md9"></a>
2025-07-31 10:54:31 -04:00
source for developers</h3>
2025-07-31 15:41:27 -04:00
<p>If you are a developer and would like an editable and incremental python install <code>meson-python</code> makes this very easy</p>
2025-07-31 10:54:31 -04:00
<div class="fragment"><div class="line">git clone https://github.com/4D-STAR/GridFire</div>
<div class="line">cd GridFire</div>
<div class="line">pip install -e . --no-build-isolation -vv</div>
2025-07-31 15:41:27 -04:00
</div><!-- fragment --><p>This will generate incremental builds whenever source code changes, and you run a python script automatically (note that since <code>meson setup</code> must run for each of these it does still take a few seconds to recompile regardless of how small a source code change you have made). It is <b>strongly</b> recommended that developers use this approach and end users <em>do not</em>.</p>
2025-11-27 15:06:27 -05:00
<h4><a class="anchor" id="autotoc_md10"></a>
2025-11-25 14:31:59 -05:00
Patching Shared Object Files</h4>
<p>If you need to patch shared object files generated by meson-python directly you should first locate the shared object file these will be in the site-packages and site-packages/fourdst directories for your python environment.</p>
<p>Look for files named</p>
<ul>
<li><code>site-packages/gridfire.cpython-3*-darwin.so</code></li>
<li><code>site-packages/fourdst/_phys.cpython-3*-darwin.so</code></li>
</ul>
<p>then, for each of these files, run</p>
<div class="fragment"><div class="line">otool -l &lt;Path/to/file&gt; | grep RPATH -A2</div>
</div><!-- fragment --><p>count the number of occurrences of duplicate RPATH entries (these should look like <code>@loaderpath/.gridfire.mesonpy.libs</code> or <code>@loaderpath/../.fourdst.mesonpy.libs</code>). Then use <code>install_name_tool</code> to remove <b>all but one of these</b> from each shared object file.</p>
<p>If for example there are 4 occurrences of the path <code>@loader_path/../.fourdst.mesonpy.libs</code> in <code>_phys.cpython-3*-darwin.so</code> then you should run the following command 3 times </p><div class="fragment"><div class="line">install_name_tool -delete_rpath @loader_path/../.fourdst.mesonpy.libs site-packages/fourdst/_phys.cpython-314-darwin.so</div>
</div><!-- fragment --><p>the same for the other shared object file (make sure to count the duplicate rpath entries for each separately as there may be a different number of duplicates in each shared object file).</p>
<p>We also include a script at <code>pip_install_mac_patch.sh</code> which will do this automatically for you.</p>
2025-11-27 15:06:27 -05:00
<h2><a class="anchor" id="autotoc_md11"></a>
2025-07-31 10:54:31 -04:00
Automatic Build and Installation</h2>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md12"></a>
2025-07-31 10:54:31 -04:00
Script Build and Installation Instructions</h3>
<p>The easiest way to build GridFire is using the <code>install.sh</code> or <code>install-tui.sh</code> scripts in the root directory. To use these scripts, simply run:</p>
<div class="fragment"><div class="line">./install.sh</div>
<div class="line"># or</div>
<div class="line">./install-tui.sh</div>
</div><!-- fragment --><p> The regular installation script will select a standard "ideal" set of build options for you. If you want more control over the build options, you can use the <code>install-tui.sh</code> script, which will provide a text-based user interface to select the build options you want.</p>
<p>Generally, both are intended to be easy to use and will prompt you automatically to install any missing dependencies.</p>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md13"></a>
2025-07-31 15:41:27 -04:00
Currently, known good platforms</h3>
2025-07-31 10:54:31 -04:00
<p>The installation script has been tested and found to work on clean installations of the following platforms:</p><ul>
<li>MacOS 15.3.2 (Apple Silicon + brew installed)</li>
<li>Fedora 42.0 (aarch64)</li>
<li>Ubuntu 25.04 (aarch64)</li>
<li>Ubuntu 22.04 (X86_64)</li>
</ul>
<blockquote class="doxtable">
<p><b>Note:</b> On Ubuntu 22.04 the user needs to install boost libraries manually as the versions in the Ubuntu repositories are too old. The installer automatically detects this and will instruct the user in how to do this. </p>
</blockquote>
2025-11-27 15:06:27 -05:00
<h2><a class="anchor" id="autotoc_md14"></a>
2025-07-31 10:54:31 -04:00
Manual Build Instructions</h2>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md15"></a>
2025-07-24 11:10:45 -04:00
Prerequisites</h3>
2025-07-31 10:54:31 -04:00
<p>These only need to be manually installed if the user is not making use of the <code>install.sh</code> or <code>install-tui.sh</code></p>
2025-11-27 15:06:27 -05:00
<h4><a class="anchor" id="autotoc_md16"></a>
2025-07-31 10:54:31 -04:00
Required</h4>
<ul>
2025-07-24 11:10:45 -04:00
<li>C++ compiler supporting C++23 standard</li>
<li>Meson build system (&gt;= 1.5.0)</li>
2025-07-31 10:54:31 -04:00
<li>Python 3.8 or newer</li>
<li>CMake 3.20 or newer</li>
<li>ninja 1.10.0 or newer</li>
2025-07-24 11:10:45 -04:00
<li>Python packages: <code>meson-python&gt;=0.15.0</code></li>
2025-07-31 10:54:31 -04:00
<li>Boost libraries (&gt;= 1.83.0) installed system-wide (or at least findable by meson with pkg-config)</li>
</ul>
2025-11-27 15:06:27 -05:00
<h4><a class="anchor" id="autotoc_md17"></a>
2025-07-31 10:54:31 -04:00
Optional</h4>
<ul>
<li>dialog (used by the <code>install.sh</code> script, not needed if using pip or meson directly)</li>
<li>pip (used by the <code>install.sh</code> script or by calling pip directly, not needed if using meson directly)</li>
</ul>
2025-07-24 11:10:45 -04:00
<blockquote class="doxtable">
2025-07-31 10:54:31 -04:00
<p><b>Note:</b> Boost is the only external library dependency used by GridFire directly. </p>
</blockquote>
<blockquote class="doxtable">
<p><b>Note:</b> Windows is not supported at this time and <em>there are no plans to support it in the future</em>. Windows users are encouraged to use WSL2 or a Linux VM. </p>
2025-07-24 11:10:45 -04:00
</blockquote>
2025-07-31 10:54:31 -04:00
<blockquote class="doxtable">
<p><b>Note:</b> If <code>install-tui.sh</code> is not able to find a usable version of boost it will provide directions to fetch, compile, and install a usable version. </p>
</blockquote>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md18"></a>
2025-07-31 10:54:31 -04:00
Install Scripts</h3>
2025-07-31 15:41:27 -04:00
<p>GridFire ships with an installer (<code>install.sh</code>) which is intended to make the process of installation both easier and more repeatable.</p>
2025-11-27 15:06:27 -05:00
<h4><a class="anchor" id="autotoc_md19"></a>
2025-07-31 10:54:31 -04:00
Ease of Installation</h4>
2025-07-31 15:41:27 -04:00
<p>Both scripts are intended to automate installation more or less completely. This includes dependency checking. In the event that a dependency cannot be found they try to install (after explicitly asking for user permission). If that does not work they will provide a clear message as to what went wrong.</p>
2025-11-27 15:06:27 -05:00
<h4><a class="anchor" id="autotoc_md20"></a>
2025-07-31 10:54:31 -04:00
Reproducibility</h4>
2025-07-31 15:41:27 -04:00
<p>The TUI mode provides easy modification of meson build system and compiler settings which can then be saved to a config file. This config file can then be loaded by either tui mode or cli mode (with the <code>--config</code>) flag meaning that build configurations can be made and reused. Note that this is <b>not</b> a deterministically reproducible build system as it does not interact with any system dependencies or settings, only meson and compiler settings.</p>
2025-11-27 15:06:27 -05:00
<h4><a class="anchor" id="autotoc_md21"></a>
2025-07-31 10:54:31 -04:00
Examples</h4>
2025-11-27 15:06:27 -05:00
<h5><a class="anchor" id="autotoc_md22"></a>
2025-07-31 10:54:31 -04:00
TUI config and saving</h5>
<p><a href="https://asciinema.org/a/ahIrQPL71ErZv5EKKujfO1ZEW"><img src="https://asciinema.org/a/ahIrQPL71ErZv5EKKujfO1ZEW.svg" alt="asciicast" style="pointer-events: none;" class="inline"/></a></p>
2025-11-27 15:06:27 -05:00
<h5><a class="anchor" id="autotoc_md23"></a>
2025-07-31 10:54:31 -04:00
TUI config loading and meson setup</h5>
<p><a href="https://asciinema.org/a/zGdzt9kYsETltG0TJKC50g3BK"><img src="https://asciinema.org/a/zGdzt9kYsETltG0TJKC50g3BK.svg" alt="asciicast" style="pointer-events: none;" class="inline"/></a></p>
2025-11-27 15:06:27 -05:00
<h5><a class="anchor" id="autotoc_md24"></a>
2025-07-31 10:54:31 -04:00
CLI config loading, setup, and build</h5>
<p><a href="https://asciinema.org/a/GYaWTXZbDJRD4ohde0s3DkFMC"><img src="https://asciinema.org/a/GYaWTXZbDJRD4ohde0s3DkFMC.svg" alt="asciicast" style="pointer-events: none;" class="inline"/></a></p>
<blockquote class="doxtable">
2025-07-31 15:41:27 -04:00
<p><b>Note:</b> <code>install-tui.sh</code> is simply a script which calls <code>install.sh</code> with the <code>--tui</code> flag. You can get the exact same results by running <code>install.sh --tui</code>. </p>
2025-07-31 10:54:31 -04:00
</blockquote>
<blockquote class="doxtable">
<p><b>Note:</b> Call <code>install.sh</code> with the <code>--help</code> or <code>--h</code> flag to see command line options </p>
</blockquote>
<blockquote class="doxtable">
<p><b>Note:</b> <code>clang</code> tends to compile GridFire much faster than <code>gcc</code> thus why I select it in the above asciinema recording. </p>
</blockquote>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md25"></a>
2025-07-24 11:10:45 -04:00
Dependency Installation on Common Platforms</h3>
<ul>
2025-07-31 10:54:31 -04:00
<li><b>Ubuntu/Debian:</b> <div class="fragment"><div class="line">sudo apt-get update</div>
<div class="line">sudo apt-get install -y build-essential meson python3 python3-pip libboost-all-dev</div>
2025-07-24 11:10:45 -04:00
</div><!-- fragment --></li>
2025-07-31 10:54:31 -04:00
</ul>
<blockquote class="doxtable">
<p><b>Note:</b> Depending on the ubuntu version you have the libboost-all-dev libraries may be too old. If this is the case refer to the boost documentation for how to download and install a version <code>&gt;=1.83.0</code> </p>
</blockquote>
<blockquote class="doxtable">
2025-07-31 15:41:27 -04:00
<p><b>Note:</b> On recent versions of ubuntu python has switched to being externally managed by the system. We <b>strongly</b> recommend that if you install manually all python packages are installed inside some kind of virtual environment (e.g. <code>pyenv</code>, <code>conda</code>, <code>python-venv</code>, etc...). When using the installer script this is handled automatically using <code>python-venv</code>. </p>
2025-07-31 10:54:31 -04:00
</blockquote>
<ul>
2025-07-24 11:10:45 -04:00
<li><b>Fedora/CentOS/RHEL:</b> <div class="fragment"><div class="line">sudo dnf install -y gcc-c++ meson python3 python3-pip boost-devel</div>
</div><!-- fragment --></li>
2025-07-31 10:54:31 -04:00
<li><b>macOS (Homebrew):</b> <div class="fragment"><div class="line">brew update</div>
<div class="line">brew install boost meson python</div>
2025-07-24 11:10:45 -04:00
</div><!-- fragment --></li>
</ul>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md26"></a>
2025-07-24 11:10:45 -04:00
Building the C++ Library</h3>
<div class="fragment"><div class="line">meson setup build</div>
<div class="line">meson compile -C build</div>
2025-11-27 15:06:27 -05:00
</div><!-- fragment --><h4><a class="anchor" id="autotoc_md27"></a>
2025-07-31 10:54:31 -04:00
Clang vs. GCC</h4>
2025-07-31 15:41:27 -04:00
<p>As noted above <code>clang</code> tends to compile GridFire much faster than <code>gcc</code>. If your system has both <code>clang</code> and <code>gcc</code> installed you may force meson to use clang via environmental variables</p>
2025-07-31 10:54:31 -04:00
<div class="fragment"><div class="line">CC=clang CXX=clang++ meson setup build_clang</div>
<div class="line">meson compile -C build_clang</div>
2025-11-27 15:06:27 -05:00
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md28"></a>
2025-07-24 11:10:45 -04:00
Installing the Library</h3>
<div class="fragment"><div class="line">meson install -C build</div>
2025-11-27 15:06:27 -05:00
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md29"></a>
2025-07-31 10:54:31 -04:00
Minimum compiler versions</h3>
2025-07-31 15:41:27 -04:00
<p>GridFire uses C++23 features and therefore only compilers and standard library implementations which support C++23 are supported. Generally we have found that <code>gcc &gt;= 13.0.0</code> or <code>clang &gt;= 16.0.0</code> work well.</p>
2025-11-27 15:06:27 -05:00
<h2><a class="anchor" id="autotoc_md30"></a>
2025-07-24 11:10:45 -04:00
Code Architecture and Logical Flow</h2>
<p>GridFire is organized into a series of composable modules, each responsible for a specific aspect of nuclear reaction network modeling. The core components include:</p>
<ul>
2025-07-31 15:41:27 -04:00
<li><b>Engine Module:</b> Core interfaces and implementations (e.g., <code>GraphEngine</code>) that evaluate reaction network rate equations and energy generation. Also implemented <code>Views</code> submodule.</li>
2025-07-31 10:54:31 -04:00
<li><b>Engine::Views Module:</b> Composable engine optimization and modification (e.g. <code>MultiscalePartitioningEngineView</code>) which can be used to make a problem more tractable or applicable.</li>
<li><b>Screening Module:</b> Implements nuclear reaction screening corrections (e.g. <code>WeakScreening</code> (<a href="https://adsabs.harvard.edu/full/1954AuJPh...7..373S">Salpeter, 1954</a>), <code>BareScreening</code>) affecting reaction rates.</li>
<li><b>Reaction Module:</b> Parses and manages Reaclib reaction rate data, providing temperature- and density-dependent rate evaluations.</li>
2025-07-31 10:54:31 -04:00
<li><b>Partition Module:</b> Implements partition functions (e.g., <code>GroundStatePartitionFunction</code>, <code>RauscherThielemannPartitionFunction</code> (<a href="https://www.sciencedirect.com/science/article/pii/S0092640X00908349?via%3Dihub]">Rauscher &amp; Thielemann, 2000</a>) to weight reaction rates based on nuclear properties.</li>
2025-11-25 14:31:59 -05:00
<li><b>Solver Module:</b> Defines numerical integration strategies (e.g., <code>CVODESolverStrategy</code>) for solving the stiff ODE systems arising from reaction networks.</li>
<li><b>io Module:</b> Defines shared interface for parsing network data from files</li>
<li><b>trigger Module:</b> Defines interface for complex trigger logic so that repartitioning can be followed.</li>
<li><b>Policy Module:</b> Contains "policies" which are small modular units of code that enforce certain contracts. For example the <code>ProtonProtonReactionChainPolicy</code> enforces than an engine must include at least all the reactions in the proton-proton chain. This module exposes the primary construction interface for users. I.e. select a policy (such as <code>MainSequencePolicy</code>), provide a composition, and get back an engine which satisfies that policy.</li>
<li><b>Python Interface:</b> Exposes <em>almost</em> all C++ functionality to Python, allowing users to define compositions, configure engines, and run simulations directly from Python scripts.</li>
2025-07-24 11:10:45 -04:00
</ul>
<p>Generally a user will start by selecting a base engine (currently we only offer <code>GraphEngine</code>), which constructs the full reaction network graph from a given composition. The user can then apply various engine views to adapt the network topology, such as partitioning fast and slow reactions, adaptively culling low-flow pathways, or priming the network with specific species. Finally, a numerical solver is selected to integrate the network over time, producing updated abundances and diagnostics.</p>
2025-11-27 15:06:27 -05:00
<h2><a class="anchor" id="autotoc_md31"></a>
2025-07-31 10:54:31 -04:00
Engines</h2>
2025-11-25 14:31:59 -05:00
<p>GridFire is, at its core, based on a series of <code>Engines</code>. These are constructs which know how to report information on series of ODEs which need to be solved to evolve abundances. The important thing to understand about <code>Engines</code> is that they contain all the detailed physics GridFire uses. For example a <code>Solver</code> takes an <code>Engine</code> but does not compute physics itself. Rather, it asks the <code>Engine</code> for stuff like the jacobian matrix, stoichiometry, nuclear energy generation rate, and change in abundance with time.</p>
2025-07-31 15:41:27 -04:00
<p>Refer to the API documentation for the exact interface which an <code>Engine</code> must implement to be compatible with GridFire solvers.</p>
<p>Currently, we only implement <code>GraphEngine</code> which is intended to be a very general and adaptable <code>Engine</code>.</p>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md32"></a>
2025-07-31 10:54:31 -04:00
GraphEngine</h3>
<p>In GridFire the <code>GraphEngine</code> will generally be the most fundamental building block of a nuclear network. A <code>GraphEngine</code> represents a directional hypergraph connecting some set of atomic species through reactions listed in the <a href="https://reaclib.jinaweb.org/index.php">JINA Reaclib database</a>.</p>
2025-07-31 15:41:27 -04:00
<p><code>GraphEngine</code>s are constructed from a seed composition of species from which they recursively expand their topology outward, following known reaction pathways and adding new species to the tracked list as they expand.</p>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md33"></a>
2025-07-24 11:10:45 -04:00
GraphEngine Configuration Options</h3>
<p>GraphEngine exposes runtime configuration methods to tailor network construction and rate evaluations:</p>
<ul>
<li><b>Constructor Parameters:</b><ul>
2025-07-31 10:54:31 -04:00
<li><code>composition</code>: The initial seed composition to start network construction from.</li>
2025-07-31 15:41:27 -04:00
<li><code>BuildDepthType</code> (<code>Full</code>, <code>Shallow</code>, <code>SecondOrder</code>, etc...): controls number of recursions used to construct the network topology. Can either be a member of the <code>NetworkBuildDepth</code> enum or an integer.</li>
<li><code>partition::PartitionFunction</code>: Partition function used when evaluating detailed balance for inverse rates.</li>
2025-11-25 14:31:59 -05:00
<li><code>NetworkConstructionFlags</code>: A bitwise flag telling the network how to construct itself. That is, what reaction types should be used in construction. For example one might use <code>NetworkConstructionFlags::STRONG | NetworkConstructionFlags::BETA_PLUS</code> to use all strong reactions and β+ decay. By Default this is set to use reaclib strong and reaclib weak (no WRL included by default due to current pathological stiffness issues).</li>
</ul>
</li>
2025-07-24 11:10:45 -04:00
<li><b>setPrecomputation(bool precompute):</b><ul>
<li>Enable/disable caching of reaction rates and stoichiometric data at initialization.</li>
<li><em>Effect:</em> Reduces per-step overhead; increases memory and setup time.</li>
</ul>
</li>
2025-07-24 11:10:45 -04:00
<li><b>setScreeningModel(ScreeningType type):</b><ul>
<li>Choose plasma screening (models: <code>BARE</code>, <code>WEAK</code>).</li>
<li><em>Effect:</em> Alters rate enhancement under dense/low-T conditions, impacting stiffness.</li>
</ul>
2025-07-24 11:10:45 -04:00
</li>
<li><b>setUseReverseReactions(bool useReverse):</b><ul>
<li>Toggle inclusion of reverse (detailed balance) reactions.</li>
<li><em>Effect:</em> Improves equilibrium fidelity; increases network size and stiffness.</li>
</ul>
</li>
</ul>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md34"></a>
2025-07-24 11:10:45 -04:00
Available Partition Functions</h3>
<table class="markdownTable">
<tr class="markdownTableHead">
2025-07-31 10:54:31 -04:00
<th class="markdownTableHeadNone">Function Name </th><th class="markdownTableHeadNone">Identifier / Enum </th><th class="markdownTableHeadNone">Description </th></tr>
2025-07-24 11:10:45 -04:00
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><code>GroundStatePartitionFunction</code> </td><td class="markdownTableBodyNone">"GroundState" </td><td class="markdownTableBodyNone">Weights using nuclear ground-state spin factors. </td></tr>
<tr class="markdownTableRowEven">
2025-07-31 10:54:31 -04:00
<td class="markdownTableBodyNone"><code>RauscherThielemannPartitionFunction</code> </td><td class="markdownTableBodyNone">"RauscherThielemann" </td><td class="markdownTableBodyNone">Interpolates normalized g-factors per Rauscher &amp; Thielemann. </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><code>CompositePartitionFunction</code> </td><td class="markdownTableBodyNone">"Composite" </td><td class="markdownTableBodyNone">Combines multiple partition functions for situations where different partitions functions are used for different domains </td></tr>
2025-07-24 11:10:45 -04:00
</table>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md35"></a>
2025-07-31 10:54:31 -04:00
AutoDiff</h3>
2025-07-31 15:41:27 -04:00
<p>One of the primary tasks any engine must accomplish is to report the jacobian matrix of the system to the solver. <code>GraphEngine</code> uses <code>CppAD</code>, a C++ auto differentiation library, to generate analytic jacobian matrices very efficiently.</p>
2025-11-27 15:06:27 -05:00
<h2><a class="anchor" id="autotoc_md36"></a>
2025-07-31 10:54:31 -04:00
Reaclib in GridFire</h2>
<p>All reactions in JINA Reaclib which only include reactants iron and lighter were downloaded on June 17th, 2025 where the most recent documented change on the JINA Reaclib site was on June 24th, 2021.</p>
2025-07-31 15:41:27 -04:00
<p>All of these reactions have been compiled into a header file which is then statically compiled into the gridfire binaries (specifically into lib_reaction_reaclib.cpp.o). This does increase the binary size by a few MB; however, the benefit is faster load times and more importantly no need for end users to manage resource files.</p>
<p>If a developer wants to add new reaclib reactions we include a script at <code>utils/reaclib/format.py</code> which can ingest a reaclib data file and produce the needed header file. More details on this process are included in <code>utils/reaclib/readme.md</code></p>
2025-11-27 15:06:27 -05:00
<h2><a class="anchor" id="autotoc_md37"></a>
2025-07-24 11:10:45 -04:00
Engine Views</h2>
2025-07-31 10:54:31 -04:00
<p>The GridFire engine supports multiple engine view strategies to adapt or restrict network topology. Generally when extending GridFire the approach is likely to be one of adding new <code>EngineViews</code>.</p>
2025-07-24 11:10:45 -04:00
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">View Name </th><th class="markdownTableHeadNone">Purpose </th><th class="markdownTableHeadNone">Algorithm / Reference </th><th class="markdownTableHeadNone">When to Use </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">AdaptiveEngineView </td><td class="markdownTableBodyNone">Dynamically culls low-flow species and reactions during runtime </td><td class="markdownTableBodyNone">Iterative flux thresholding to remove reactions below a flow threshold </td><td class="markdownTableBodyNone">Large networks to reduce computational cost </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">DefinedEngineView </td><td class="markdownTableBodyNone">Restricts the network to a user-specified subset of species and reactions </td><td class="markdownTableBodyNone">Static network masking based on user-provided species/reaction lists </td><td class="markdownTableBodyNone">Targeted pathway studies or code-to-code comparisons </td></tr>
<tr class="markdownTableRowOdd">
2025-07-31 10:54:31 -04:00
<td class="markdownTableBodyNone">FileDefinedEngineView </td><td class="markdownTableBodyNone">Load a defined engine view from a file using some parser </td><td class="markdownTableBodyNone">Same as DefinedEngineView but loads from a file </td><td class="markdownTableBodyNone">Same as DefinedEngineView </td></tr>
2025-07-24 11:10:45 -04:00
<tr class="markdownTableRowEven">
2025-07-31 10:54:31 -04:00
<td class="markdownTableBodyNone">MultiscalePartitioningEngineView </td><td class="markdownTableBodyNone">Partitions the network into fast and slow subsets based on reaction timescales </td><td class="markdownTableBodyNone">Network partitioning following Hix &amp; Thielemann Silicon Burning I &amp; II (DOI:10.1086/177016,10.1086/306692) </td><td class="markdownTableBodyNone">Stiff, multi-scale networks requiring tailored integration </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">NetworkPrimingEngineView </td><td class="markdownTableBodyNone">Primes the network with an initial species or set of species for ignition studies </td><td class="markdownTableBodyNone">Single-species ignition and network priming </td><td class="markdownTableBodyNone">Investigations of ignition triggers or initial seed sensitivities </td></tr>
2025-07-24 11:10:45 -04:00
</table>
<p>These engine views implement the common Engine interface and may be composed in any order to build complex network pipelines. New view types can be added by deriving from the <code>EngineView</code> base class, and linked into the composition chain without modifying core engine code.</p>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md38"></a>
2025-07-31 10:54:31 -04:00
A Note about composability</h3>
2025-07-31 15:41:27 -04:00
<p>There are certain functions for which it is expected that a call to an engine view will propagate the result down the chain of engine views, eventually reaching the base engine (e.g. <code>DynamicEngine::update</code>). We do not strongly enforce this as it is not hard to contrive a situation where that is not the mose useful behavior; however, we do strongly encourage developers to think carefully about passing along calls to base engine methods when implementing new views.</p>
2025-11-27 15:06:27 -05:00
<h2><a class="anchor" id="autotoc_md39"></a>
2025-07-24 11:10:45 -04:00
Numerical Solver Strategies</h2>
<p>GridFire defines a flexible solver architecture through the <code>networkfire::solver::NetworkSolverStrategy</code> interface, enabling multiple ODE integration algorithms to be used interchangeably with any engine that implements the <code>Engine</code> or <code>DynamicEngine</code> contract.</p>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md40"></a>
2025-07-31 10:54:31 -04:00
NetworkSolverStrategy&lt;EngineT&gt;:</h3>
2025-07-31 15:41:27 -04:00
<p>All GridFire solvers implement the abstract strategy templated by <code>NetworkSolverStrategy</code> which enforces only that there is some <code>evaluate</code> method with the following signature</p>
2025-07-31 10:54:31 -04:00
<div class="fragment"><div class="line">NetOut evaluate(<span class="keyword">const</span> NetIn&amp; netIn);</div>
</div><!-- fragment --><p> Which is intended to integrate some network over some time and returns updated abundances, temperature, density, and diagnostics.</p>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md41"></a>
2025-07-31 10:54:31 -04:00
NetIn and NetOut</h3>
2025-07-31 15:41:27 -04:00
<p>GridFire solvers use a unified input and output type for their public interface (though as developers will quickly learn, internally these are immediately broken down into simpler data structures). All solvers expect a <code>NetIn</code> struct for the input type to the <code>evaluate</code> method and return a <code>NetOut</code> struct.</p>
2025-11-27 15:06:27 -05:00
<h4><a class="anchor" id="autotoc_md42"></a>
2025-07-31 10:54:31 -04:00
NetIn</h4>
<p>A <code>NetIn</code> struct contains</p><ul>
<li>The composition to start the timestep at. (<code>NetIn::composition</code>)</li>
<li>The temperature in Kelvin (<code>NetIn::temperature</code>)</li>
<li>The density in g/cm^3 (<code>NetIn::density</code>)</li>
2025-11-25 14:31:59 -05:00
<li>The max time to evolve the network to in seconds (<code>NetIn::tMax</code>)</li>
2025-07-31 10:54:31 -04:00
<li>The initial timestep to use in seconds (<code>NetIn::dt0</code>)</li>
<li>The initial energy in the system in ergs (<code>NetIn::energy</code>)</li>
</ul>
2025-07-31 15:41:27 -04:00
<p>&gt;<b>Note:</b> It is often useful to set <code>NetIn::dt0</code> to something <em>very</em> small and &gt;let an iterative time stepper push the timestep up. Often for main sequence &gt;burning I use ~1e-12 for dt0</p>
<p>&gt;<b>Note:</b> The composition must be a <code>fourdst::composition::Composition</code> &gt;object. This is made available through the <code>foursdt</code> library and the &gt;<code>fourdst/composition/Composition.h</code> header. <code>fourdst</code> is installed &gt;automatically with GridFire</p>
2025-07-31 10:54:31 -04:00
<p>&gt;<b>Note:</b> In Python composition comes from <code>fourdst.composition.Composition</code> &gt;and similarly is installed automatically when building GridFire python &gt;bindings.</p>
2025-11-27 15:06:27 -05:00
<h4><a class="anchor" id="autotoc_md43"></a>
2025-07-31 10:54:31 -04:00
NetOut</h4>
<p>A <code>NetOut</code> struct contains</p><ul>
<li>The final composition after evolving to <code>tMax</code> (<code>NetOut::composition</code>)</li>
<li>The number of steps the solver took to evolve to <code>tmax</code> (<code>NetOut::num_steps</code>)</li>
2025-11-27 15:06:27 -05:00
<li>The final specific energy generated by the network while evolving to <code>tMax</code> (<code>NetOut::energy</code>) [erg/g]</li>
<li>The derivative of energy with respect to temperature at the end of the evolution (<code>NetOut::dEps_dT</code>)</li>
<li>The derivative of energy with respect to density at the end of the evolution (<code>NetOut::dEps_dRho</code>)</li>
<li>The total specific energy lost to neutrinos while evolving to <code>tMax</code> (<code>NetOut::total_neutrino_loss</code>) [erg/g]</li>
<li>The total flux of neutrinos while evolving to <code>tMax</code> (<code>NetOut::total_neutrino_flux</code>)</li>
2025-07-31 10:54:31 -04:00
</ul>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md44"></a>
2025-11-25 14:31:59 -05:00
CVODESolverStrategy</h3>
<p>We use the CVODE module from <a href="https://computing.llnl.gov/projects/sundials/cvode">SUNDIALS</a> as our primary numerical solver. Specifically we use the BDF linear multistep method from that which includes advanced adaptive timestepping.</p>
<p>Further, we use a trigger system to periodically repartition the network as the state of the network changes. This keeps the stiffness of the network tractable. The algorithm we use for that is</p>
2025-07-24 11:10:45 -04:00
<ol type="1">
2025-11-25 14:31:59 -05:00
<li>Trigger every 1000th time that the simulation time exceeds the simulationTimeInterval</li>
<li>OR if any off-diagonal Jacobian entry exceeds the offDiagonalThreshold</li>
<li>OR every 10th time that the timestep growth exceeds the timestepGrowthThreshold (relative or absolute)</li>
<li>OR if the number of convergence failures grows more than 100% from one step to the next or exceeds 5 at any given step.</li>
2025-07-24 11:10:45 -04:00
</ol>
2025-11-25 14:31:59 -05:00
<p>Moreover, callback functions can be registered in either python or C++ which will take a <code>const CVODESolverStrategy::TimestepContext&amp;</code> struct as argument. This allows for more complex logging logic. Note that callbacks <b>do not</b> let you reach inside the solver and adjust the state of the network. They are only intended for investigation not extension of physics. If you wish to extend the physics this must be implemented at the engine or engine view level.</p>
2025-11-27 15:06:27 -05:00
<h2><a class="anchor" id="autotoc_md45"></a>
2025-07-31 10:54:31 -04:00
Python Extensibility</h2>
<p>Through the Python bindings, users can subclass engine view classes directly in Python, override methods like <code>evaluate</code> or <code>generateStoichiometryMatrix</code>, and pass instances back into C++ solvers. This enables rapid prototyping of custom view strategies without touching C++ sources.</p>
2025-11-27 15:06:27 -05:00
<h1><a class="anchor" id="autotoc_md46"></a>
2025-07-31 10:54:31 -04:00
Usage Examples</h1>
2025-11-27 15:06:27 -05:00
<h2><a class="anchor" id="autotoc_md47"></a>
2025-07-31 10:54:31 -04:00
C++</h2>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md48"></a>
2025-07-31 10:54:31 -04:00
GraphEngine Initialization</h3>
2025-07-24 11:10:45 -04:00
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="engine__graph_8h.html">gridfire/engine/engine_graph.h</a>&quot;</span></div>
<div class="line"><span class="preprocessor">#include &quot;fourdst/composition/composition.h&quot;</span></div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> main(){</div>
<div class="line"> <span class="comment">// Define a composition and initialize the engine</span></div>
<div class="line"> fourdst::composition::Composition comp;</div>
2025-11-24 09:08:28 -05:00
<div class="line"> gridfire::GraphEngine engine(comp);</div>
<div class="line">}</div>
2025-07-24 11:10:45 -04:00
<div class="ttc" id="aengine__graph_8h_html"><div class="ttname"><a href="engine__graph_8h.html">engine_graph.h</a></div></div>
2025-11-27 15:06:27 -05:00
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md49"></a>
2025-07-31 10:54:31 -04:00
Adaptive Network View</h3>
2025-07-24 11:10:45 -04:00
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="engine__adaptive_8h.html">gridfire/engine/views/engine_adaptive.h</a>&quot;</span></div>
<div class="line"><span class="preprocessor">#include &quot;<a class="code" href="engine__graph_8h.html">gridfire/engine/engine_graph.h</a>&quot;</span></div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> main(){</div>
<div class="line"> fourdst::composition::Composition comp;</div>
2025-11-24 09:08:28 -05:00
<div class="line"> gridfire::GraphEngine baseEngine(comp);</div>
<div class="line"> <span class="comment">// Dynamically adapt network topology based on reaction flows</span></div>
2025-11-24 09:08:28 -05:00
<div class="line"> gridfire::AdaptiveEngineView adaptiveView(baseEngine);</div>
<div class="line">}</div>
2025-07-24 11:10:45 -04:00
<div class="ttc" id="aengine__adaptive_8h_html"><div class="ttname"><a href="engine__adaptive_8h.html">engine_adaptive.h</a></div></div>
2025-11-27 15:06:27 -05:00
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md50"></a>
2025-07-31 10:54:31 -04:00
Composition Initialization</h3>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;fourdst/composition/composition.h&quot;</span></div>
2025-11-25 14:31:59 -05:00
<div class="line"><span class="preprocessor">#include &quot;fourdst/composition/utils.h&quot;</span> <span class="comment">// for buildCompositionFromMassFractions</span></div>
2025-07-31 10:54:31 -04:00
<div class="line"><span class="preprocessor">#include &lt;vector&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;string&gt;</span></div>
<div class="line"> </div>
2025-07-31 10:54:31 -04:00
<div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> main() {</div>
2025-07-31 10:54:31 -04:00
<div class="line"> </div>
<div class="line"> std::vector&lt;std::string&gt; symbols = {<span class="stringliteral">&quot;H-1&quot;</span>, <span class="stringliteral">&quot;He-4&quot;</span>, <span class="stringliteral">&quot;C-12&quot;</span>};</div>
<div class="line"> std::vector&lt;double&gt; massFractions = {0.7, 0.29, 0.01};</div>
2025-11-25 14:31:59 -05:00
<div class="line"> </div>
<div class="line"> <span class="keyword">const</span> fourdst::composition::Composition comp = fourdst::composition::buildCompositionFromMassFractions(symbols, massFractions);</div>
<div class="line"> </div>
<div class="line"> std::cout &lt;&lt; comp &lt;&lt; std::endl;</div>
<div class="line">}</div>
2025-11-27 15:06:27 -05:00
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md51"></a>
2025-07-31 10:54:31 -04:00
Common Workflow Example</h3>
2025-07-24 11:10:45 -04:00
<p>A representative workflow often composes multiple engine views to balance accuracy, stability, and performance when integrating stiff nuclear networks:</p>
2025-11-25 14:31:59 -05:00
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="gridfire_8h.html">gridfire/gridfire.h</a>&quot;</span> <span class="comment">// Unified header for real usage</span></div>
<div class="line"> </div>
2025-07-24 11:10:45 -04:00
<div class="line"><span class="preprocessor">#include &quot;fourdst/composition/composition.h&quot;</span></div>
2025-11-25 14:31:59 -05:00
<div class="line"><span class="preprocessor">#include &quot;fourdst/composition/utils.h&quot;</span> <span class="comment">// for buildCompositionFromMassFractions</span></div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> main(){</div>
<div class="line"> <span class="comment">// 1. Define initial composition</span></div>
2025-11-25 14:31:59 -05:00
<div class="line"> std::unordered_map&lt;std::string, double&gt; initialMassFractions = {</div>
<div class="line"> {<span class="stringliteral">&quot;H-1&quot;</span>, 0.7},</div>
<div class="line"> {<span class="stringliteral">&quot;He-4&quot;</span>, 0.29},</div>
<div class="line"> {<span class="stringliteral">&quot;C-12&quot;</span>, 0.01}</div>
<div class="line"> };</div>
<div class="line"> <span class="keyword">const</span> fourdst::composition::Composition composition = fourdst::composition::buildCompositionFromMassFractions(initialMassFractions);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// In this example we will not use the policy module (for sake of demonstration of what is happening under the hood)</span></div>
<div class="line"> <span class="comment">// however, for end users we **strongly** recommend using the policy module to construct engines. It will</span></div>
<div class="line"> <span class="comment">// ensure that you are not missing important reactions or seed species.</span></div>
2025-07-31 10:54:31 -04:00
<div class="line"> </div>
<div class="line"> <span class="comment">// 2. Create base network engine (full reaction graph)</span></div>
2025-11-24 09:08:28 -05:00
<div class="line"> gridfire::GraphEngine baseEngine(comp, NetworkBuildDepth::SecondOrder)</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// 3. Partition network into fast/slow subsets (reduces stiffness)</span></div>
2025-11-24 09:08:28 -05:00
<div class="line"> gridfire::MultiscalePartitioningEngineView msView(baseEngine);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// 4. Adaptively cull negligible flux pathways (reduces dimension &amp; stiffness)</span></div>
2025-11-24 09:08:28 -05:00
<div class="line"> gridfire::AdaptiveEngineView adaptView(msView);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// 5. Construct implicit solver (handles remaining stiffness)</span></div>
2025-11-25 14:31:59 -05:00
<div class="line"> gridfire::CVODESolverStrategey solver(adaptView);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// 6. Prepare input conditions</span></div>
<div class="line"> NetIn input{</div>
<div class="line"> comp, <span class="comment">// composition</span></div>
<div class="line"> 1.5e7, <span class="comment">// temperature [K]</span></div>
<div class="line"> 1.5e2, <span class="comment">// density [g/cm^3]</span></div>
<div class="line"> 1e-12, <span class="comment">// initial timestep [s]</span></div>
<div class="line"> 3e17 <span class="comment">// integration end time [s]</span></div>
<div class="line"> };</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// 7. Execute integration</span></div>
<div class="line"> NetOut output = solver.evaluate(input);</div>
<div class="line"> std::cout &lt;&lt; <span class="stringliteral">&quot;Final results are: &quot;</span> &lt;&lt; output &lt;&lt; std::endl;</div>
<div class="line">}</div>
2025-11-25 14:31:59 -05:00
<div class="ttc" id="agridfire_8h_html"><div class="ttname"><a href="gridfire_8h.html">gridfire.h</a></div></div>
2025-11-27 15:06:27 -05:00
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md52"></a>
2025-11-25 14:31:59 -05:00
Callback and Policy Example</h3>
2025-07-31 15:41:27 -04:00
<p>Custom callback functions can be registered with any solver. Because it might make sense for each solver to provide different context to the callback function, you should use the struct <code><a class="el" href="namespacegridfire_1_1solver.html">gridfire::solver</a>::&lt;SolverName&gt;::TimestepContext</code> as the argument type for the callback function. This struct contains all the information provided by that solver to the callback function.</p>
2025-11-25 14:31:59 -05:00
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="gridfire_8h.html">gridfire/gridfire.h</a>&quot;</span> <span class="comment">// Unified header for real usage</span></div>
<div class="line"> </div>
<div class="line"><span class="preprocessor">#include &quot;fourdst/composition/composition.h&quot;</span> <span class="comment">// for Composition</span></div>
<div class="line"><span class="preprocessor">#include &quot;fourdst/composition/utils.h&quot;</span> <span class="comment">// for buildCompositionFromMassFractions</span></div>
<div class="line"><span class="preprocessor">#include &quot;fourdst/atomic/species.h&quot;</span> <span class="comment">// For strongly typed species</span></div>
<div class="line"> </div>
<div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div>
<div class="line"> </div>
2025-11-25 14:31:59 -05:00
<div class="line"><span class="keywordtype">void</span> callback(<span class="keyword">const</span> <a class="code hl_struct" href="structgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_1_1_timestep_context.html">gridfire::solver::CVODESolverStrategy::TimestepContext</a>&amp; context) {</div>
<div class="line"> <span class="keywordtype">int</span> H1Index = context.<a class="code hl_variable" href="structgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_1_1_timestep_context.html#a5a457651dcb9d4a66ed219ddf7095313">engine</a>.<a class="code hl_function" href="classgridfire_1_1engine_1_1_dynamic_engine.html#ac0f40017603e8e6887b75dc7360d7c5e">getSpeciesIndex</a>(fourdst::atomic::H_1);</div>
<div class="line"> <span class="keywordtype">int</span> He4Index = context.<a class="code hl_variable" href="structgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_1_1_timestep_context.html#a5a457651dcb9d4a66ed219ddf7095313">engine</a>.<a class="code hl_function" href="classgridfire_1_1engine_1_1_dynamic_engine.html#ac0f40017603e8e6887b75dc7360d7c5e">getSpeciesIndex</a>(fourdst::atomic::He_4);</div>
<div class="line"> </div>
2025-11-25 14:31:59 -05:00
<div class="line"> std::cout &lt;&lt; context.<a class="code hl_variable" href="structgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_1_1_timestep_context.html#a0b39f0d207181840efacb64417b492ae">t</a> &lt;&lt; <span class="stringliteral">&quot;,&quot;</span> &lt;&lt; context.<a class="code hl_variable" href="structgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_1_1_timestep_context.html#aaae3c42b9172be4d501f022e67f5a6f6">state</a>(H1Index) &lt;&lt; <span class="stringliteral">&quot;,&quot;</span> &lt;&lt; context.<a class="code hl_variable" href="structgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_1_1_timestep_context.html#aaae3c42b9172be4d501f022e67f5a6f6">state</a>(He4Index) &lt;&lt; <span class="stringliteral">&quot;\n&quot;</span>;</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> main(){</div>
<div class="line"> std::vector&lt;std::string&gt; symbols = {<span class="stringliteral">&quot;H-1&quot;</span>, <span class="stringliteral">&quot;He-4&quot;</span>, <span class="stringliteral">&quot;C-12&quot;</span>};</div>
2025-11-25 14:31:59 -05:00
<div class="line"> std::vector&lt;double&gt; X = {0.7, 0.29, 0.01};</div>
<div class="line"> </div>
<div class="line"> </div>
2025-11-25 14:31:59 -05:00
<div class="line"> <span class="keyword">const</span> fourdst::composition::Composition composition = fourdst::composition::buildCompositionFromMassFractions(symbols, X);</div>
<div class="line"> <a class="code hl_class" href="classgridfire_1_1policy_1_1_main_sequence_policy.html">gridfire::policy::MainSequencePolicy</a> stellarPolicy(netIn.composition);</div>
<div class="line"> <a class="code hl_class" href="classgridfire_1_1engine_1_1_dynamic_engine.html">gridfire::engine::DynamicEngine</a>&amp; engine = stellarPolicy.construct();</div>
<div class="line"> </div>
<div class="line"> <a class="code hl_class" href="classgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy.html">gridfire::solver::CVODESolverStrategy</a> solver(adaptView);</div>
<div class="line"> solver.set_callback(callback);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// 6. Prepare input conditions</span></div>
2025-11-25 14:31:59 -05:00
<div class="line"> <a class="code hl_struct" href="structgridfire_1_1_net_in.html">gridfire::NetIn</a> input{</div>
<div class="line"> comp, <span class="comment">// composition</span></div>
<div class="line"> 1.5e7, <span class="comment">// temperature [K]</span></div>
<div class="line"> 1.5e2, <span class="comment">// density [g/cm^3]</span></div>
<div class="line"> 1e-12, <span class="comment">// initial timestep [s]</span></div>
<div class="line"> 3e17 <span class="comment">// integration end time [s]</span></div>
<div class="line"> };</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// 7. Execute integration</span></div>
2025-11-25 14:31:59 -05:00
<div class="line"> <a class="code hl_struct" href="structgridfire_1_1_net_out.html">gridfire::NetOut</a> output = solver.evaluate(input);</div>
<div class="line"> std::cout &lt;&lt; <span class="stringliteral">&quot;Final results are: &quot;</span> &lt;&lt; output &lt;&lt; std::endl;</div>
<div class="line">}</div>
2025-11-27 15:06:27 -05:00
<div class="ttc" id="aclassgridfire_1_1engine_1_1_dynamic_engine_html"><div class="ttname"><a href="classgridfire_1_1engine_1_1_dynamic_engine.html">gridfire::engine::DynamicEngine</a></div><div class="ttdoc">Abstract class for engines supporting Jacobian and stoichiometry operations.</div><div class="ttdef"><b>Definition</b> engine_abstract.h:175</div></div>
2025-11-25 14:31:59 -05:00
<div class="ttc" id="aclassgridfire_1_1engine_1_1_dynamic_engine_html_ac0f40017603e8e6887b75dc7360d7c5e"><div class="ttname"><a href="classgridfire_1_1engine_1_1_dynamic_engine.html#ac0f40017603e8e6887b75dc7360d7c5e">gridfire::engine::DynamicEngine::getSpeciesIndex</a></div><div class="ttdeci">virtual size_t getSpeciesIndex(const fourdst::atomic::Species &amp;species) const =0</div><div class="ttdoc">Get the index of a species in the network.</div></div>
<div class="ttc" id="aclassgridfire_1_1policy_1_1_main_sequence_policy_html"><div class="ttname"><a href="classgridfire_1_1policy_1_1_main_sequence_policy.html">gridfire::policy::MainSequencePolicy</a></div><div class="ttdoc">A NetworkPolicy for building reaction networks suitable for low-mass main-sequence stars.</div><div class="ttdef"><b>Definition</b> stellar_policy.h:60</div></div>
<div class="ttc" id="aclassgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_html"><div class="ttname"><a href="classgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy.html">gridfire::solver::CVODESolverStrategy</a></div><div class="ttdoc">Stiff ODE integrator backed by SUNDIALS CVODE (BDF) for network + energy.</div><div class="ttdef"><b>Definition</b> CVODE_solver_strategy.h:81</div></div>
<div class="ttc" id="astructgridfire_1_1_net_in_html"><div class="ttname"><a href="structgridfire_1_1_net_in.html">gridfire::NetIn</a></div><div class="ttdef"><b>Definition</b> types.h:27</div></div>
<div class="ttc" id="astructgridfire_1_1_net_out_html"><div class="ttname"><a href="structgridfire_1_1_net_out.html">gridfire::NetOut</a></div><div class="ttdef"><b>Definition</b> types.h:37</div></div>
<div class="ttc" id="astructgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_1_1_timestep_context_html"><div class="ttname"><a href="structgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_1_1_timestep_context.html">gridfire::solver::CVODESolverStrategy::TimestepContext</a></div><div class="ttdoc">Immutable view of the current integration state passed to callbacks.</div><div class="ttdef"><b>Definition</b> CVODE_solver_strategy.h:173</div></div>
<div class="ttc" id="astructgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_1_1_timestep_context_html_a0b39f0d207181840efacb64417b492ae"><div class="ttname"><a href="structgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_1_1_timestep_context.html#a0b39f0d207181840efacb64417b492ae">gridfire::solver::CVODESolverStrategy::TimestepContext::t</a></div><div class="ttdeci">const double t</div><div class="ttdoc">Current integration time [s].</div><div class="ttdef"><b>Definition</b> CVODE_solver_strategy.h:175</div></div>
<div class="ttc" id="astructgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_1_1_timestep_context_html_a5a457651dcb9d4a66ed219ddf7095313"><div class="ttname"><a href="structgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_1_1_timestep_context.html#a5a457651dcb9d4a66ed219ddf7095313">gridfire::solver::CVODESolverStrategy::TimestepContext::engine</a></div><div class="ttdeci">const engine::DynamicEngine &amp; engine</div><div class="ttdoc">Reference to the engine.</div><div class="ttdef"><b>Definition</b> CVODE_solver_strategy.h:182</div></div>
<div class="ttc" id="astructgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_1_1_timestep_context_html_aaae3c42b9172be4d501f022e67f5a6f6"><div class="ttname"><a href="structgridfire_1_1solver_1_1_c_v_o_d_e_solver_strategy_1_1_timestep_context.html#aaae3c42b9172be4d501f022e67f5a6f6">gridfire::solver::CVODESolverStrategy::TimestepContext::state</a></div><div class="ttdeci">const N_Vector &amp; state</div><div class="ttdoc">Current CVODE state vector (N_Vector).</div><div class="ttdef"><b>Definition</b> CVODE_solver_strategy.h:176</div></div>
</div><!-- fragment --><p> &gt;<b>Note:</b> If you want to see exactly why each repartitioning stage was triggered in a human readable manner add the flag True to <code>solver.evaluate</code> (<code>solver.evaluate(input, true)</code>).</p>
<p>&gt;<b>Note:</b> A fully detailed list of all available information in the TimestepContext struct is available in the API documentation.</p>
<p>&gt;<b>Note:</b> The order of species in the boost state vector (<code>ctx.state</code>) is <b>not guaranteed</b> to be any particular order run over run. Therefore, in order to reliably extract </p><blockquote class="doxtable">
<p>values from it, you <b>must</b> use the <code>getSpeciesIndex</code> method of the engine to get the index of the species you are interested in (these will always be in the same order). </p>
</blockquote>
2025-11-25 14:31:59 -05:00
<p>If you wish to know what is provided by a solver context without investigating the code you can simply do</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> callback(<span class="keyword">const</span> <a class="code hl_struct" href="classgridfire_1_1solver_1_1_solver_context_base.html">gridfire::solver::SolverContextBase</a>&amp; context) {</div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keyword">auto</span>&amp; [parameterName, description] : context.<a class="code hl_function" href="classgridfire_1_1solver_1_1_solver_context_base.html#a9cbef3cabc8524e542613ee50d8860c6">describe</a>()) {</div>
<div class="line"> std::cout &lt;&lt; parameterName &lt;&lt; <span class="stringliteral">&quot;: &quot;</span> &lt;&lt; description &lt;&lt; <span class="stringliteral">&quot;\n&quot;</span>;</div>
<div class="line"> }</div>
<div class="line"> std::cout &lt;&lt; std::flush();</div>
<div class="line"> exit(0);</div>
<div class="line">}</div>
<div class="ttc" id="aclassgridfire_1_1solver_1_1_solver_context_base_html"><div class="ttname"><a href="classgridfire_1_1solver_1_1_solver_context_base.html">gridfire::solver::SolverContextBase</a></div><div class="ttdoc">Base class for solver callback contexts.</div><div class="ttdef"><b>Definition</b> strategy_abstract.h:21</div></div>
<div class="ttc" id="aclassgridfire_1_1solver_1_1_solver_context_base_html_a9cbef3cabc8524e542613ee50d8860c6"><div class="ttname"><a href="classgridfire_1_1solver_1_1_solver_context_base.html#a9cbef3cabc8524e542613ee50d8860c6">gridfire::solver::SolverContextBase::describe</a></div><div class="ttdeci">virtual std::vector&lt; std::tuple&lt; std::string, std::string &gt; &gt; describe() const =0</div><div class="ttdoc">Describe the context for callback functions.</div></div>
</div><!-- fragment --><p>If you set this as the callback (to any solver strategy) it will print out the available parameters and what they are and then close the code. This is useful when writing new callbacks.</p>
2025-11-27 15:06:27 -05:00
<h4><a class="anchor" id="autotoc_md53"></a>
2025-07-31 15:41:27 -04:00
Callback Context</h4>
<p>Since each solver may provide different context to the callback function, and it may be frustrating to refer to the documentation every time, we also enforce that all solvers must implement a <code>descripe_callback_context</code> method which returns a vector of tuples&lt;string, string&gt; where the first element is the name of the field and the second is its datatype. It is on the developer to ensure that this information is accurate.</p>
<div class="fragment"><div class="line">...</div>
<div class="line">std::cout &lt;&lt; solver.describe_callback_context() &lt;&lt; std::endl;</div>
2025-11-27 15:06:27 -05:00
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md54"></a>
2025-07-31 10:54:31 -04:00
Python</h2>
<p>The python bindings intentionally look <b>very</b> similar to the C++ code. Generally all examples can be adapted to python by replacing includes of paths with imports of modules such that</p>
2025-11-24 09:08:28 -05:00
<p><code>#include "gridfire/engine/GraphEngine.h"</code> becomes <code>import <a class="el" href="classgridfire_1_1engine_1_1_graph_engine.html" title="A reaction network engine that uses a graph-based representation.">gridfire.engine.GraphEngine</a></code></p>
<p>All GridFire C++ types have been bound and can be passed around as one would expect.</p>
2025-11-27 15:06:27 -05:00
<h3><a class="anchor" id="autotoc_md55"></a>
2025-11-25 14:31:59 -05:00
Python Example for End Users</h3>
<p>The syntax for registration is very similar to C++. There are a few things to note about this more robust example</p>
<ol type="1">
<li>Note how I use a callback and a log object to store the state of the simulation at each timestep.</li>
<li>If you have tools such as mypy installed you will see that the python bindings are strongly typed. This is intentional to help users avoid mistakes when writing code. <div class="fragment"><div class="line"><span class="keyword">from</span> fourdst.composition <span class="keyword">import</span> Composition</div>
<div class="line"><span class="keyword">from</span> gridfire.type <span class="keyword">import</span> NetIn</div>
2025-11-25 14:31:59 -05:00
<div class="line"><span class="keyword">from</span> <a class="code hl_namespace" href="namespacegridfire_1_1policy.html">gridfire.policy</a> <span class="keyword">import</span> MainSequencePolicy</div>
<div class="line"><span class="keyword">from</span> <a class="code hl_namespace" href="namespacegridfire_1_1solver.html">gridfire.solver</a> <span class="keyword">import</span> CVODESolverStrategy</div>
<div class="line"><span class="keyword">from</span> enum <span class="keyword">import</span> Enum</div>
<div class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> Dict, Union, SupportsFloat</div>
<div class="line"><span class="keyword">import</span> json</div>
<div class="line"><span class="keyword">import</span> dicttoxml</div>
<div class="line"> </div>
<div class="line"><span class="keyword">def </span>init_composition() -&gt; Composition:</div>
<div class="line"> Y = [7.0262E-01, 9.7479E-06, 6.8955E-02, 2.5000E-04, 7.8554E-05, 6.0144E-04, 8.1031E-05, 2.1513E-05] <span class="comment"># Note these are molar abundances</span></div>
<div class="line"> S = [<span class="stringliteral">&quot;H-1&quot;</span>, <span class="stringliteral">&quot;He-3&quot;</span>, <span class="stringliteral">&quot;He-4&quot;</span>, <span class="stringliteral">&quot;C-12&quot;</span>, <span class="stringliteral">&quot;N-14&quot;</span>, <span class="stringliteral">&quot;O-16&quot;</span>, <span class="stringliteral">&quot;Ne-20&quot;</span>, <span class="stringliteral">&quot;Mg-24&quot;</span>]</div>
<div class="line"> <span class="keywordflow">return</span> Composition(S, Y)</div>
<div class="line"> </div>
<div class="line"><span class="keyword">def </span>init_netIn(temp: float, rho: float, time: float, comp: Composition) -&gt; NetIn:</div>
<div class="line"> netIn = NetIn()</div>
<div class="line"> netIn.temperature = temp</div>
<div class="line"> netIn.density = rho</div>
<div class="line"> netIn.tMax = time</div>
<div class="line"> netIn.dt0 = 1e-12</div>
<div class="line"> netIn.composition = comp</div>
<div class="line"> <span class="keywordflow">return</span> netIn</div>
<div class="line"> </div>
<div class="line"><span class="keyword">class </span>StepData(Enum):</div>
<div class="line"> TIME = 0</div>
<div class="line"> DT = 1</div>
<div class="line"> COMP = 2</div>
<div class="line"> CONTRIB = 3</div>
<div class="line"> </div>
<div class="line"> </div>
<div class="line"><span class="keyword">class </span>StepLogger:</div>
<div class="line"> <span class="keyword">def </span>__init__(self):</div>
<div class="line"> self.num_steps: int = 0</div>
<div class="line"> self.step_data: Dict[int, Dict[StepData, Union[SupportsFloat, Dict[str, SupportsFloat]]]] = {}</div>
<div class="line"> </div>
<div class="line"> <span class="keyword">def </span>log_step(self, context):</div>
<div class="line"> engine = context.engine</div>
<div class="line"> self.step_data[self.num_steps] = {}</div>
<div class="line"> self.step_data[self.num_steps][StepData.TIME] = context.t</div>
<div class="line"> self.step_data[self.num_steps][StepData.DT] = context.dt</div>
<div class="line"> comp_data: Dict[str, SupportsFloat] = {}</div>
<div class="line"> <span class="keywordflow">for</span> species <span class="keywordflow">in</span> engine.getNetworkSpecies():</div>
<div class="line"> sid = engine.getSpeciesIndex(species)</div>
<div class="line"> comp_data[species.name()] = context.state[sid]</div>
<div class="line"> self.step_data[self.num_steps][StepData.COMP] = comp_data</div>
<div class="line"> self.num_steps += 1</div>
<div class="line"> </div>
<div class="line"> <span class="keyword">def </span>to_json (self, filename: str):</div>
<div class="line"> serializable_data = {</div>
<div class="line"> stepNum: {</div>
<div class="line"> StepData.TIME.name: step[StepData.TIME],</div>
<div class="line"> StepData.DT.name: step[StepData.DT],</div>
<div class="line"> StepData.COMP.name: step[StepData.COMP],</div>
<div class="line"> }</div>
<div class="line"> <span class="keywordflow">for</span> stepNum, step <span class="keywordflow">in</span> self.step_data.items()</div>
<div class="line"> }</div>
<div class="line"> <span class="keyword">with</span> open(filename, <span class="stringliteral">&#39;w&#39;</span>) <span class="keyword">as</span> f:</div>
<div class="line"> json.dump(serializable_data, f, indent=4)</div>
<div class="line"> </div>
<div class="line"> <span class="keyword">def </span>to_xml(self, filename: str):</div>
<div class="line"> serializable_data = {</div>
<div class="line"> stepNum: {</div>
<div class="line"> StepData.TIME.name: step[StepData.TIME],</div>
<div class="line"> StepData.DT.name: step[StepData.DT],</div>
<div class="line"> StepData.COMP.name: step[StepData.COMP],</div>
<div class="line"> }</div>
<div class="line"> <span class="keywordflow">for</span> stepNum, step <span class="keywordflow">in</span> self.step_data.items()</div>
<div class="line"> }</div>
<div class="line"> xml_data = dicttoxml.dicttoxml(serializable_data, custom_root=<span class="stringliteral">&#39;StepLog&#39;</span>, attr_type=<span class="keyword">False</span>)</div>
<div class="line"> <span class="keyword">with</span> open(filename, <span class="stringliteral">&#39;wb&#39;</span>) <span class="keyword">as</span> f:</div>
<div class="line"> f.write(xml_data)</div>
<div class="line"> </div>
<div class="line"><span class="keyword">def </span>main(temp: float, rho: float, time: float):</div>
<div class="line"> comp = init_composition()</div>
<div class="line"> netIn = init_netIn(temp, rho, time, comp)</div>
<div class="line"> </div>
<div class="line"> policy = MainSequencePolicy(comp)</div>
<div class="line"> engine = policy.construct()</div>
<div class="line"> </div>
<div class="line"> solver = CVODESolverStrategy(engine)</div>
<div class="line"> </div>
<div class="line"> step_logger = StepLogger()</div>
<div class="line"> solver.set_callback(<span class="keyword">lambda</span> context: step_logger.log_step(context))</div>
<div class="line"> </div>
<div class="line"> solver.evaluate(netIn, <span class="keyword">False</span>)</div>
<div class="line"> step_logger.to_xml(<span class="stringliteral">&quot;log_data.xml&quot;</span>)</div>
<div class="line"> </div>
<div class="line"><span class="keywordflow">if</span> __name__ == <span class="stringliteral">&quot;__main__&quot;</span>:</div>
<div class="line"> <span class="keyword">import</span> argparse</div>
<div class="line"> parser = argparse.ArgumentParser(description=<span class="stringliteral">&quot;Simple python example of GridFire usage&quot;</span>)</div>
<div class="line"> parser.add_argument(<span class="stringliteral">&quot;-t&quot;</span>, <span class="stringliteral">&quot;--temp&quot;</span>, type=float, help=<span class="stringliteral">&quot;Temperature in K&quot;</span>, default=1.5e7)</div>
<div class="line"> parser.add_argument(<span class="stringliteral">&quot;-r&quot;</span>, <span class="stringliteral">&quot;--rho&quot;</span>, type=float, help=<span class="stringliteral">&quot;Density in g/cm^3&quot;</span>, default=1.5e2)</div>
<div class="line"> parser.add_argument(<span class="stringliteral">&quot;--tMax&quot;</span>, type=float, help=<span class="stringliteral">&quot;Time in s&quot;</span>, default=3.1536 * 1e17)</div>
<div class="line"> args = parser.parse_args()</div>
<div class="line"> main(args.temp, args.rho, args.tMax)</div>
<div class="ttc" id="anamespacegridfire_1_1policy_html"><div class="ttname"><a href="namespacegridfire_1_1policy.html">gridfire::policy</a></div><div class="ttdef"><b>Definition</b> chains.h:25</div></div>
2025-11-24 09:08:28 -05:00
<div class="ttc" id="anamespacegridfire_1_1solver_html"><div class="ttname"><a href="namespacegridfire_1_1solver.html">gridfire::solver</a></div><div class="ttdef"><b>Definition</b> CVODE_solver_strategy.h:46</div></div>
2025-11-25 14:31:59 -05:00
</div><!-- fragment --></li>
</ol>
2025-11-27 15:06:27 -05:00
<h1><a class="anchor" id="autotoc_md56"></a>
External Usage</h1>
<p>C++ does not have a stable ABI nor does it make any strong guarantees about stl container layouts between compiler versions. Therefore, GridFire includes a set of stable C bindings which can be used to interface with a limited subset of GridFire functionality from other languages.</p>
<blockquote class="doxtable">
<p><b>Note:</b> These bindings are not intended to allow GridFire to be extended from other languages; rather, they are intended to allow GridFire to be used as a black-box library from other languages. </p>
</blockquote>
<blockquote class="doxtable">
<p><b>Note:</b> One assumption for external usage is that the ordering of the species list will not change. That is to say that whatever order the array used to register the species is will be assumed to always be the order used when passing abundance arrays to and from GridFire. </p>
</blockquote>
<blockquote class="doxtable">
<p><b>Note:</b> Because the C API does not pass the general Composition object a <code>mass_lost</code> output parameter has been added to the evolve calls, this tracks the total mass in species which have not been registered with the C API GridFire by the caller </p>
</blockquote>
<h2><a class="anchor" id="autotoc_md57"></a>
C API Overview</h2>
<p>In general when using the C API the workflow is to </p>
<ol type="1">
<li>create a <code>gf_context</code> pointer. This object holds the state of GridFire so that it does not need to be re-initialized for each call.</li>
<li>call initialization routines on the context to set up the engine and solver you wish to use.</li>
<li>call the <code>gf_evolve</code> function to evolve a network over some time.</li>
<li>At each state check the ret code of the function to ensure that no errors occurred. Valid ret-codes are 0 and 1. All other ret codes indicate an error.</li>
<li>Finally, call <code>gf_free</code> to free the context and all associated memory.</li>
</ol>
<h3><a class="anchor" id="autotoc_md58"></a>
C Example</h3>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="gridfire__extern_8h.html">gridfire/extern/gridfire_extern.h</a>&quot;</span></div>
<div class="line"><span class="preprocessor">#include &lt;stdio.h&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="preprocessor">#define NUM_SPECIES 8</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// Define a macro to check return codes</span></div>
<div class="line"><span class="preprocessor">#define GF_CHECK_RET_CODE(ret, ctx, msg) \</span></div>
<div class="line"><span class="preprocessor"> if (ret != 0 &amp;&amp; ret != 1) { \</span></div>
<div class="line"><span class="preprocessor"> printf(&quot;Error %s: %s\n&quot;, msg, gf_get_last_error_message(ctx)); \</span></div>
<div class="line"><span class="preprocessor"> gf_free(ctx); \</span></div>
<div class="line"><span class="preprocessor"> return ret; \</span></div>
<div class="line"><span class="preprocessor"> }</span></div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> main() {</div>
<div class="line"> <span class="keywordtype">void</span>* gf_context = <a class="code hl_function" href="gridfire__extern_8h.html#aa06d49e737afd147061f4f15e6e5afcc">gf_init</a>();</div>
<div class="line"> </div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">char</span>* species_names[NUM_SPECIES];</div>
<div class="line"> species_names[0] = <span class="stringliteral">&quot;H-1&quot;</span>;</div>
<div class="line"> species_names[1] = <span class="stringliteral">&quot;He-3&quot;</span>;</div>
<div class="line"> species_names[2] = <span class="stringliteral">&quot;He-4&quot;</span>;</div>
<div class="line"> species_names[3] = <span class="stringliteral">&quot;C-12&quot;</span>;</div>
<div class="line"> species_names[4] = <span class="stringliteral">&quot;N-14&quot;</span>;</div>
<div class="line"> species_names[5] = <span class="stringliteral">&quot;O-16&quot;</span>;</div>
<div class="line"> species_names[6] = <span class="stringliteral">&quot;Ne-20&quot;</span>;</div>
<div class="line"> species_names[7] = <span class="stringliteral">&quot;Mg-24&quot;</span>;</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">double</span> abundances[NUM_SPECIES] = {0.702616602672027, 9.74791583949078e-06, 0.06895512307276903, 0.00025, 7.855418029399437e-05, 0.0006014411598306529, 8.103062886768109e-05, 2.151340851063217e-05};</div>
<div class="line"> </div>
<div class="line"> <span class="keywordtype">int</span> ret = <a class="code hl_function" href="gridfire__extern_8h.html#af7e09bf5cf979211260e715faaa3a680">gf_register_species</a>(gf_context, NUM_SPECIES, species_names);</div>
<div class="line"> GF_CHECK_RET_CODE(ret, gf_context, <span class="stringliteral">&quot;Species Registration&quot;</span>);</div>
<div class="line"> </div>
<div class="line"> ret = <a class="code hl_function" href="gridfire__extern_8h.html#ae70b23310adcce0925900ca00a18a4a6">gf_construct_engine_from_policy</a>(gf_context, <span class="stringliteral">&quot;MAIN_SEQUENCE_POLICY&quot;</span>, abundances, NUM_SPECIES);</div>
<div class="line"> GF_CHECK_RET_CODE(ret, gf_context, <span class="stringliteral">&quot;Policy and Engine Construction&quot;</span>);</div>
<div class="line"> </div>
<div class="line"> ret = <a class="code hl_function" href="gridfire__extern_8h.html#a57d58696555e3402eddd043cea125f5e">gf_construct_solver_from_engine</a>(gf_context, <span class="stringliteral">&quot;CVODE&quot;</span>);</div>
<div class="line"> GF_CHECK_RET_CODE(ret, gf_context, <span class="stringliteral">&quot;Solver Construction&quot;</span>);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// When using the C API it is assumed that the caller will ensure that the output arrays are large enough to hold the results.</span></div>
<div class="line"> <span class="keywordtype">double</span> Y_out[NUM_SPECIES];</div>
<div class="line"> <span class="keywordtype">double</span> energy_out;</div>
<div class="line"> <span class="keywordtype">double</span> dEps_dT;</div>
<div class="line"> <span class="keywordtype">double</span> dEps_dRho;</div>
<div class="line"> <span class="keywordtype">double</span> neutrino_energy_loss;</div>
<div class="line"> <span class="keywordtype">double</span> neutrino_flux;</div>
<div class="line"> <span class="keywordtype">double</span> mass_lost;</div>
<div class="line"> </div>
<div class="line"> ret = <a class="code hl_function" href="gridfire__extern_8h.html#abde0ca38a62727d2f76f0bcd920bf124">gf_evolve</a>(</div>
<div class="line"> gf_context,</div>
<div class="line"> abundances,</div>
<div class="line"> NUM_SPECIES,</div>
<div class="line"> 1.5e7, <span class="comment">// Temperature in K</span></div>
<div class="line"> 1.5e2, <span class="comment">// Density in g/cm^3</span></div>
<div class="line"> 3e17, <span class="comment">// Time step in seconds</span></div>
<div class="line"> 1e-12, <span class="comment">// Initial time step in seconds</span></div>
<div class="line"> Y_out,</div>
<div class="line"> &amp;energy_out,</div>
<div class="line"> &amp;dEps_dT,</div>
<div class="line"> &amp;dEps_dRho,</div>
<div class="line"> &amp;neutrino_energy_loss,</div>
<div class="line"> &amp;neutrino_flux,</div>
<div class="line"> &amp;mass_lost</div>
<div class="line"> );</div>
<div class="line"> </div>
<div class="line"> GF_CHECK_RET_CODE(ret, gf_context, <span class="stringliteral">&quot;Evolution&quot;</span>);</div>
<div class="line"> </div>
<div class="line"> </div>
<div class="line"> printf(<span class="stringliteral">&quot;Evolved abundances:\n&quot;</span>);</div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i = 0; i &lt; NUM_SPECIES; i++) {</div>
<div class="line"> printf(<span class="stringliteral">&quot;Species %s: %e\n&quot;</span>, species_names[i], Y_out[i]);</div>
<div class="line"> }</div>
<div class="line"> printf(<span class="stringliteral">&quot;Energy output: %e\n&quot;</span>, energy_out);</div>
<div class="line"> printf(<span class="stringliteral">&quot;dEps/dT: %e\n&quot;</span>, dEps_dT);</div>
<div class="line"> printf(<span class="stringliteral">&quot;dEps/dRho: %e\n&quot;</span>, dEps_dRho);</div>
<div class="line"> printf(<span class="stringliteral">&quot;Mass lost: %e\n&quot;</span>, mass_lost);</div>
<div class="line"> </div>
<div class="line"> <a class="code hl_function" href="gridfire__extern_8h.html#a5ddf1a13fef574a435fd76a7fb1bb374">gf_free</a>(gf_context);</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">return</span> 0;</div>
<div class="line">}</div>
<div class="ttc" id="agridfire__extern_8h_html"><div class="ttname"><a href="gridfire__extern_8h.html">gridfire_extern.h</a></div></div>
<div class="ttc" id="agridfire__extern_8h_html_a57d58696555e3402eddd043cea125f5e"><div class="ttname"><a href="gridfire__extern_8h.html#a57d58696555e3402eddd043cea125f5e">gf_construct_solver_from_engine</a></div><div class="ttdeci">int gf_construct_solver_from_engine(void *ptr, const char *solver_name)</div><div class="ttdef"><b>Definition</b> gridfire_extern.cpp:70</div></div>
<div class="ttc" id="agridfire__extern_8h_html_a5ddf1a13fef574a435fd76a7fb1bb374"><div class="ttname"><a href="gridfire__extern_8h.html#a5ddf1a13fef574a435fd76a7fb1bb374">gf_free</a></div><div class="ttdeci">void gf_free(void *ctx)</div><div class="ttdef"><b>Definition</b> gridfire_extern.cpp:11</div></div>
<div class="ttc" id="agridfire__extern_8h_html_aa06d49e737afd147061f4f15e6e5afcc"><div class="ttname"><a href="gridfire__extern_8h.html#aa06d49e737afd147061f4f15e6e5afcc">gf_init</a></div><div class="ttdeci">void * gf_init()</div><div class="ttdef"><b>Definition</b> gridfire_extern.cpp:7</div></div>
<div class="ttc" id="agridfire__extern_8h_html_abde0ca38a62727d2f76f0bcd920bf124"><div class="ttname"><a href="gridfire__extern_8h.html#abde0ca38a62727d2f76f0bcd920bf124">gf_evolve</a></div><div class="ttdeci">int gf_evolve(void *ptr, const double *Y_in, size_t num_species, double T, double rho, double tMax, double dt0, double *Y_out, double *energy_out, double *dEps_dT, double *dEps_dRho, double *specific_neutrino_energy_loss, double *specific_neutrino_flux, double *mass_lost)</div><div class="ttdef"><b>Definition</b> gridfire_extern.cpp:87</div></div>
<div class="ttc" id="agridfire__extern_8h_html_ae70b23310adcce0925900ca00a18a4a6"><div class="ttname"><a href="gridfire__extern_8h.html#ae70b23310adcce0925900ca00a18a4a6">gf_construct_engine_from_policy</a></div><div class="ttdeci">int gf_construct_engine_from_policy(void *ptr, const char *policy_name, const double *abundances, size_t num_species)</div><div class="ttdef"><b>Definition</b> gridfire_extern.cpp:39</div></div>
<div class="ttc" id="agridfire__extern_8h_html_af7e09bf5cf979211260e715faaa3a680"><div class="ttname"><a href="gridfire__extern_8h.html#af7e09bf5cf979211260e715faaa3a680">gf_register_species</a></div><div class="ttdeci">int gf_register_species(void *ptr, const int num_species, const char **species_names)</div><div class="ttdef"><b>Definition</b> gridfire_extern.cpp:15</div></div>
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md59"></a>
Fortran API Overview</h2>
<p>GridFire makes use of the stable C API and Fortran 2003's <code>iso_c_bindings</code> to provide a Fortran interface for legacy code. The fortran interface is designed to be very similar to the C API and exposes the same functionality.</p>
<ol type="1">
<li><code>GridFiregff_init</code>: Initializes a GridFire context and returns a handle to it.</li>
<li><code>GridFireregister_species</code>: Registers species with the GridFire context.</li>
<li><code>GridFiresetup_policy</code>: Configures the engine using a specified policy and initial abundances.</li>
<li><code>GridFiresetup_solver</code>: Sets up the solver for the engine.</li>
<li><code>GridFireevolve</code>: Evolves the network over a specified time step.</li>
<li><code>GridFireget_last_error</code>: Retrieves the last error message from the GridFire context.</li>
<li><code>GridFiregff_free</code>: Frees the GridFire context and associated resources.</li>
</ol>
<blockquote class="doxtable">
<p><b>Note:</b> You must instantiate a <code>GridFire</code> type object to access these methods. </p>
</blockquote>
<blockquote class="doxtable">
<p><b>Note:</b> free and init have had the <code>gff_</code> prefix (GridFire Fortran) to avoid name clashes with common Fortran functions. </p>
</blockquote>
<p>When building GridFire a fortran module file <code>gridfire_mod.mod</code> is generated which contains all the necessary bindings to use GridFire from Fortran. You must also link your code against the C API library <code>libgridfire_extern</code>.</p>
<h3><a class="anchor" id="autotoc_md60"></a>
Fortran Example</h3>
<div class="fragment"><div class="line"><span class="keyword">program</span> main</div>
<div class="line"> <span class="keywordtype">use </span>iso_c_binding</div>
<div class="line"> <span class="keywordtype">use </span><a class="code hl_namespace" href="namespacegridfire__mod.html">gridfire_mod</a></div>
<div class="line"> <span class="keywordtype">implicit none</span></div>
<div class="line"> </div>
<div class="line"> <span class="keywordtype">type</span>(GridFire) :: net</div>
<div class="line"> <span class="keywordtype">integer(c_int)</span> :: ierr</div>
<div class="line"> <span class="keywordtype">integer</span> :: i</div>
<div class="line"> </div>
<div class="line"> <span class="comment">! --- 1. Define Species and Initial Conditions ---</span></div>
<div class="line"> <span class="comment">! Note: String lengths must match or exceed the longest name.</span></div>
<div class="line"> <span class="comment">! We pad with spaces, which &#39;trim&#39; handles inside the module.</span></div>
<div class="line"> <span class="keywordtype">character(len=5)</span>, <span class="keywordtype">dimension(8)</span> :: species_names = [ &amp;</div>
<div class="line"> <span class="stringliteral">&quot;H-1 &quot;</span>, &amp;</div>
<div class="line"> <span class="stringliteral">&quot;He-3 &quot;</span>, &amp;</div>
<div class="line"> <span class="stringliteral">&quot;He-4 &quot;</span>, &amp;</div>
<div class="line"> <span class="stringliteral">&quot;C-12 &quot;</span>, &amp;</div>
<div class="line"> <span class="stringliteral">&quot;N-14 &quot;</span>, &amp;</div>
<div class="line"> <span class="stringliteral">&quot;O-16 &quot;</span>, &amp;</div>
<div class="line"> <span class="stringliteral">&quot;Ne-20&quot;</span>, &amp;</div>
<div class="line"> <span class="stringliteral">&quot;Mg-24&quot;</span> &amp;</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> <span class="comment">! Initial Mass Fractions (converted to Molar Abundances Y = X/A)</span></div>
<div class="line"> <span class="comment">! Standard solar-ish composition</span></div>
<div class="line"><span class="keywordtype"> real</span>(c_double), <span class="keywordtype">dimension(8)</span> :: Y_in = [ &amp;</div>
<div class="line"> 0.702616602672027, &amp;</div>
<div class="line"> 9.74791583949078e-06, &amp;</div>
<div class="line"> 0.06895512307276903, &amp;</div>
<div class="line"> 0.00025, &amp;</div>
<div class="line"> 7.855418029399437e-05, &amp;</div>
<div class="line"> 0.0006014411598306529, &amp;</div>
<div class="line"> 8.103062886768109e-05, &amp;</div>
<div class="line"> 2.151340851063217e-05 &amp;</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> <span class="comment">! Output buffers</span></div>
<div class="line"><span class="keywordtype"> real</span>(c_double), <span class="keywordtype">dimension(8)</span> :: Y_out</div>
<div class="line"><span class="keywordtype"> real</span>(c_double) :: energy_out, dedt, dedrho, nu_E_loss, nu_flux, dmass</div>
<div class="line"> </div>
<div class="line"> <span class="comment">! Thermodynamic Conditions (Solar Core-ish)</span></div>
<div class="line"><span class="keywordtype"> real</span>(c_double) :: T = 1.5e7 <span class="comment">! 15 Million K</span></div>
<div class="line"><span class="keywordtype"> real</span>(c_double) :: rho = 150.0e0 <span class="comment">! 150 g/cm^3</span></div>
<div class="line"><span class="keywordtype"> real</span>(c_double) :: dt = 3.1536e17 <span class="comment">! ~10 Gyr timestep</span></div>
<div class="line"> </div>
<div class="line"> <span class="comment">! --- 2. Initialize GridFire ---</span></div>
<div class="line"> print *, <span class="stringliteral">&quot;Initializing GridFire...&quot;</span></div>
<div class="line"> <span class="keyword">call </span>net%gff_init()</div>
<div class="line"> </div>
<div class="line"> <span class="comment">! --- 3. Register Species ---</span></div>
<div class="line"> print *, <span class="stringliteral">&quot;Registering species...&quot;</span></div>
<div class="line"> <span class="keyword">call </span>net%register_species(species_names)</div>
<div class="line"> </div>
<div class="line"> <span class="comment">! --- 4. Configure Engine &amp; Solver ---</span></div>
<div class="line"> print *, <span class="stringliteral">&quot;Setting up Main Sequence Policy...&quot;</span></div>
<div class="line"> <span class="keyword">call </span>net%setup_policy(<span class="stringliteral">&quot;MAIN_SEQUENCE_POLICY&quot;</span>, y_in)</div>
<div class="line"> </div>
<div class="line"> print *, <span class="stringliteral">&quot;Setting up CVODE Solver...&quot;</span></div>
<div class="line"> <span class="keyword">call </span>net%setup_solver(<span class="stringliteral">&quot;CVODE&quot;</span>)</div>
<div class="line"> </div>
<div class="line"> <span class="comment">! --- 5. Evolve ---</span></div>
<div class="line"> print *, <span class="stringliteral">&quot;Evolving system (dt =&quot;</span>, dt, <span class="stringliteral">&quot;s)...&quot;</span></div>
<div class="line"> <span class="keyword">call </span>net%evolve(y_in, t, rho, dt, y_out, energy_out, dedt, dedrho, nu_e_loss, nu_flux, dmass, ierr)</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">if</span> (ierr /= 0) <span class="keywordflow">then</span></div>
<div class="line"> print *, <span class="stringliteral">&quot;Evolution Failed with error code: &quot;</span>, ierr</div>
<div class="line"> print *, <span class="stringliteral">&quot;Error Message: &quot;</span>, net%get_last_error()</div>
<div class="line"> <span class="keyword">call </span>net%gff_free() <span class="comment">! Always cleanup</span></div>
<div class="line"> stop</div>
<div class="line"><span class="keywordflow"> end if</span></div>
<div class="line"> </div>
<div class="line"> <span class="comment">! --- 6. Report Results ---</span></div>
<div class="line"> print *, <span class="stringliteral">&quot;&quot;</span></div>
<div class="line"> print *, <span class="stringliteral">&quot;--- Results ---&quot;</span></div>
<div class="line"> print <span class="stringliteral">&#39;(A, ES12.5, A)&#39;</span>, <span class="stringliteral">&quot;Energy Generation: &quot;</span>, energy_out, <span class="stringliteral">&quot; erg/g/s&quot;</span></div>
<div class="line"> print <span class="stringliteral">&#39;(A, ES12.5)&#39;</span>, <span class="stringliteral">&quot;dEps/dT: &quot;</span>, dedt</div>
<div class="line"> print <span class="stringliteral">&#39;(A, ES12.5)&#39;</span>, <span class="stringliteral">&quot;Mass Change: &quot;</span>, dmass</div>
<div class="line"> </div>
<div class="line"> print *, <span class="stringliteral">&quot;&quot;</span></div>
<div class="line"> print *, <span class="stringliteral">&quot;Abundances:&quot;</span></div>
<div class="line"> <span class="keywordflow">do</span> i = 1, <span class="keyword">size</span>(species_names)</div>
<div class="line"> print <span class="stringliteral">&#39;(A, &quot; : &quot;, ES12.5, &quot; -&gt; &quot;, ES12.5)&#39;</span>, &amp;</div>
<div class="line"> trim(species_names(i)), y_in(i), y_out(i)</div>
<div class="line"><span class="keywordflow"> end do</span></div>
<div class="line"> </div>
<div class="line"> <span class="comment">! --- 7. Cleanup ---</span></div>
<div class="line"> <span class="keyword">call </span>net%gff_free()</div>
<div class="line"> </div>
<div class="line"><span class="keyword">end program </span>main</div>
<div class="ttc" id="anamespacegridfire__mod_html"><div class="ttname"><a href="namespacegridfire__mod.html">gridfire_mod</a></div><div class="ttdef"><b>Definition</b> gridfire_mod.f90:1</div></div>
</div><!-- fragment --><h1><a class="anchor" id="autotoc_md61"></a>
Related Projects</h1>
<p>GridFire integrates with and builds upon several key 4D-STAR libraries:</p>
<ul>
<li><a href="https://github.com/4D-STAR/fourdst">fourdst</a>: hub module managing versioning of <code>libcomposition</code>, <code>libconfig</code>, <code>liblogging</code>, and <code>libconstants</code></li>
<li><a href="https://github.com/4D-STAR/libcomposition">libcomposition</a> (<a href="https://4d-star.github.io/libcomposition/">docs</a>): Composition management toolkit.</li>
<li><a href="https://github.com/4D-STAR/libconfig">libconfig</a>: Configuration file parsing utilities.</li>
<li><a href="https://github.com/4D-STAR/liblogging">liblogging</a>: Flexible logging framework.</li>
2025-11-27 15:06:27 -05:00
<li><a href="https://github.com/4D-STAR/libconstants">libconstants</a>: Physical constants</li>
<li><a href="https://github.com/4D-STAR/libplugin">libplugin</a>: Dynamically loadable plugin framework. </li>
</ul>
</div></div><!-- PageDoc -->
<a href="doxygen_crawl.html"></a>
</div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.13.2 </li>
</ul>
</div>
</body>
</html>