Source code for pynucastro.networks.simple_cxx_network
"""A simple C++ reaction network for integrating into other C++ codes"""
from pathlib import Path
from pynucastro.networks.base_cxx_network import BaseCxxNetwork
from pynucastro.screening import get_screening_map
[docs]
class SimpleCxxNetwork(BaseCxxNetwork):
def __init__(self, *args, **kwargs):
# Initialize BaseCxxNetwork parent class
super().__init__(*args, **kwargs)
self.function_specifier = "inline"
self.dtype = "Real"
self.array_namespace = ""
def _get_template_files(self):
path = self.pynucastro_dir/"templates/simple-cxx-network"
return path.glob("*.template")
def _compute_screening_factors(self, n_indent, of):
if not self.do_screening:
screening_map = []
else:
screening_map = get_screening_map(self.get_rates(),
symmetric_screening=self.symmetric_screening)
for i, scr in enumerate(screening_map):
nuc1_info = f'{float(scr.n1.Z)}_rt, {float(scr.n1.A)}_rt'
nuc2_info = f'{float(scr.n2.Z)}_rt, {float(scr.n2.A)}_rt'
if not (scr.n1.dummy or scr.n2.dummy):
# Scope the screening calculation to avoid multiple definitions of scn_fac.
of.write(f'\n{self.indent*n_indent}' + '{\n')
of.write(f'{self.indent*(n_indent+1)}auto scn_fac = scrn::calculate_screen_factor({nuc1_info}, {nuc2_info});\n')
of.write(f'{self.indent*(n_indent+1)}actual_screen(pstate, scn_fac, scor);\n')
of.write(f'{self.indent*n_indent}' + '}\n')
if scr.name == "He4_He4_He4":
# we don't need to do anything here, but we want to avoid immediately applying the screening
pass
elif scr.name == "He4_He4_He4_dummy":
# make sure the previous iteration was the first part of 3-alpha
assert screening_map[i - 1].name == "He4_He4_He4"
# handle the second part of the screening for 3-alpha
of.write(f'\n{self.indent*n_indent}' + '{\n')
of.write(f'{self.indent*(n_indent+1)}auto scn_fac2 = scrn::calculate_screen_factor({nuc1_info}, {nuc2_info});\n')
of.write(f'{self.indent*(n_indent+1)}actual_screen(pstate, scn_fac2, scor2);\n')
of.write(f'{self.indent*n_indent}' + '}\n')
# there might be both the forward and reverse 3-alpha
# if we are doing symmetric screening
of.write('\n')
for rr in scr.rates:
of.write(f'{self.indent*n_indent}rate_eval.screened_rates(k_{rr.cname()}) *= scor * scor2;\n')
else:
# there might be several rates that have the same
# reactants and therefore the same screening applies
# -- handle them all now
of.write('\n')
for rr in scr.rates:
of.write(f'{self.indent*n_indent}rate_eval.screened_rates(k_{rr.cname()}) *= scor;\n')
of.write('\n')
def _write_network(self, odir=None):
"""
This writes the RHS, jacobian and ancillary files for the system of ODEs that
this network describes, using the template files.
"""
# at the moment, we don't support TabularRates
assert len(self.tabular_rates) == 0, "SimpleCxxNetwork does not support tabular rates"
super()._write_network(odir=odir)
if odir is None:
odir = Path.cwd()
# create a header file with the nuclei properties
with open(Path(odir, "network_properties.H"), "w") as of:
of.write("#ifndef NETWORK_PROPERTIES_H\n")
of.write("#define NETWORK_PROPERTIES_H\n")
of.write("#include <vector>\n")
of.write("#include <string>\n")
of.write("#include <amrex_bridge.H>\n\n")
of.write(f"constexpr int NumSpec = {len(self.unique_nuclei)};\n\n")
of.write("constexpr Real aion[NumSpec] = {\n")
for n, nuc in enumerate(self.unique_nuclei):
of.write(f" {nuc.A:6.1f}, // {n}\n")
of.write(" };\n\n")
of.write("constexpr Real aion_inv[NumSpec] = {\n")
for n, nuc in enumerate(self.unique_nuclei):
of.write(f" 1.0/{nuc.A:6.1f}, // {n}\n")
of.write(" };\n\n")
of.write("constexpr Real zion[NumSpec] = {\n")
for n, nuc in enumerate(self.unique_nuclei):
of.write(f" {nuc.Z:6.1f}, // {n}\n")
of.write(" };\n\n")
of.write("static const std::vector<std::string> spec_names = {\n")
for n, nuc in enumerate(self.unique_nuclei):
of.write(f" \"{nuc.short_spec_name.capitalize()}\", // {n}\n")
of.write(" };\n\n")
of.write("namespace Species {\n")
of.write(" enum NetworkSpecies {\n")
for n, nuc in enumerate(self.unique_nuclei):
if n == 0:
of.write(f" {nuc.short_spec_name.capitalize()}=1,\n")
else:
of.write(f" {nuc.short_spec_name.capitalize()},\n")
of.write(" };\n")
of.write("}\n\n")
of.write("#endif\n")