fix(python): added temporary patch to let python bindings work on mac

Mirroring what was done in fourdst (see fourdst/tree/v0.8.5) we have added a temporary patch to let python bindings work on mac while the meson-python folks resolve the duplicate rpath issue in the shared object file
This commit is contained in:
2025-11-03 15:10:03 -05:00
parent 0adc340767
commit 3c80ccc77f
15 changed files with 1437 additions and 184 deletions

View File

@@ -0,0 +1,95 @@
#!/usr/bin/env python3
import os
import sys
import glob
import subprocess
from collections import OrderedDict
def get_rpaths(binary_path):
"""Uses otool to extract a list of all LC_RPATH entries."""
print(f"--- Checking rpaths for: {binary_path}")
rpaths = []
try:
proc = subprocess.run(
['otool', '-l', binary_path],
capture_output=True,
text=True,
check=True
)
lines = proc.stdout.splitlines()
for i, line in enumerate(lines):
if "cmd LC_RPATH" in line.strip():
if i + 2 < len(lines):
path_line = lines[i + 2].strip()
if path_line.startswith("path "):
# Extract the path, e.g., "path /foo/bar (offset 12)"
rpath = path_line.split(" ")[1]
rpaths.append(rpath)
except (subprocess.CalledProcessError, FileNotFoundError) as e:
print(f"Error running otool: {e}")
return []
return rpaths
def fix_rpaths(binary_path):
all_rpaths = get_rpaths(binary_path)
if not all_rpaths:
print("--- No rpaths found or otool failed.")
return
unique_rpaths = list(OrderedDict.fromkeys(all_rpaths))
for rpath in unique_rpaths:
print(f" - RPATH: {rpath}")
if len(all_rpaths) == len(unique_rpaths):
print("--- No duplicate rpaths found. Nothing to do.")
return
print(f"--- Found {len(all_rpaths)} rpaths; {len(unique_rpaths)} are unique.")
print(f"--- Fixing duplicates in: {binary_path}")
try:
for rpath in all_rpaths:
subprocess.run(
['install_name_tool', '-delete_rpath', rpath, binary_path],
check=True,
capture_output=True
)
for rpath in unique_rpaths:
subprocess.run(
['install_name_tool', '-add_rpath', rpath, binary_path],
check=True,
capture_output=True
)
print("--- Successfully fixed rpaths.")
except (subprocess.CalledProcessError, FileNotFoundError) as e:
print(f"--- Error running install_name_tool: {e}")
if e.stderr:
print(f"STDERR: {e.stderr.decode()}")
if e.stdout:
print(f"STDOUT: {e.stdout.decode()}")
sys.exit(1) # Fail the install if we can't fix it
def main():
if len(sys.argv) != 2:
print(f"--- Error: Expected one argument (path to .so file), got {sys.argv}", file=sys.stderr)
sys.exit(1)
# Get the file path directly from the command line argument
so_file_path = sys.argv[1]
if not os.path.exists(so_file_path):
print(f"--- Error: File not found at {so_file_path}", file=sys.stderr)
sys.exit(1)
print(f"--- Fixing rpaths for built file: {so_file_path}")
fix_rpaths(so_file_path)
if __name__ == "__main__":
main()

View File

@@ -14,20 +14,20 @@ py_mod = py_installation.extension_module(
sources: [
meson.project_source_root() + '/src/python/bindings.cpp',
meson.project_source_root() + '/src/python/types/bindings.cpp',
# meson.project_source_root() + '/src/python/expectations/bindings.cpp',
# meson.project_source_root() + '/src/python/partition/bindings.cpp',
# meson.project_source_root() + '/src/python/partition/trampoline/py_partition.cpp',
# meson.project_source_root() + '/src/python/reaction/bindings.cpp',
# meson.project_source_root() + '/src/python/screening/bindings.cpp',
# meson.project_source_root() + '/src/python/screening/trampoline/py_screening.cpp',
# meson.project_source_root() + '/src/python/io/bindings.cpp',
# meson.project_source_root() + '/src/python/io/trampoline/py_io.cpp',
# meson.project_source_root() + '/src/python/exceptions/bindings.cpp',
# meson.project_source_root() + '/src/python/engine/bindings.cpp',
# meson.project_source_root() + '/src/python/engine/trampoline/py_engine.cpp',
# meson.project_source_root() + '/src/python/solver/bindings.cpp',
# meson.project_source_root() + '/src/python/solver/trampoline/py_solver.cpp',
# meson.project_source_root() + '/src/python/utils/bindings.cpp',
meson.project_source_root() + '/src/python/expectations/bindings.cpp',
meson.project_source_root() + '/src/python/partition/bindings.cpp',
meson.project_source_root() + '/src/python/partition/trampoline/py_partition.cpp',
meson.project_source_root() + '/src/python/reaction/bindings.cpp',
meson.project_source_root() + '/src/python/screening/bindings.cpp',
meson.project_source_root() + '/src/python/screening/trampoline/py_screening.cpp',
meson.project_source_root() + '/src/python/io/bindings.cpp',
meson.project_source_root() + '/src/python/io/trampoline/py_io.cpp',
meson.project_source_root() + '/src/python/exceptions/bindings.cpp',
meson.project_source_root() + '/src/python/engine/bindings.cpp',
meson.project_source_root() + '/src/python/engine/trampoline/py_engine.cpp',
meson.project_source_root() + '/src/python/solver/bindings.cpp',
meson.project_source_root() + '/src/python/solver/trampoline/py_solver.cpp',
meson.project_source_root() + '/src/python/utils/bindings.cpp',
],
dependencies : gridfire_py_deps,
cpp_args : ['-UNDEBUG'], # Example: Ensure assertions are enabled if needed

143
pip_install_mac_patch.sh Executable file
View File

@@ -0,0 +1,143 @@
#!/bin/bash
# pip_install_mac.sh - Temporary workaround for meson-python duplicate RPATH bug on macOS
set -e
# Color codes for output
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
echo -e "${YELLOW}"
echo "========================================================================="
echo " TEMPORARY INSTALLATION WORKAROUND"
echo "========================================================================="
echo -e "${NC}"
echo ""
echo -e "${YELLOW}WARNING:${NC} This script applies a temporary patch to fix a known issue with"
echo "meson-python that causes duplicate RPATH entries in built Python extensions"
echo "on macOS, preventing module imports."
echo ""
echo "This workaround will:"
echo " 1. Install fourdst using pip"
echo " 2. Locate the installed extension module"
echo " 3. Remove duplicate RPATH entries using install_name_tool"
echo ""
echo "This is a temporary solution while the meson-python team resolves the"
echo "duplicate RPATH bug. For more information, see:"
echo " https://github.com/mesonbuild/meson-python/issues/813"
echo ""
echo -e "${YELLOW}Do you understand and wish to continue? [y/N]${NC} "
read -r response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo -e "${RED}Installation cancelled.${NC}"
exit 1
fi
echo ""
echo -e "${GREEN}Step 1: Finding current Python environment...${NC}"
# Get the current Python executable
PYTHON_BIN=$(which python3)
if [ -z "$PYTHON_BIN" ]; then
echo -e "${RED}Error: python3 not found in PATH${NC}"
exit 1
fi
echo "Using Python: $PYTHON_BIN"
PYTHON_VERSION=$($PYTHON_BIN --version)
echo "Python version: $PYTHON_VERSION"
# Get site-packages directory
SITE_PACKAGES=$($PYTHON_BIN -c "import site; print(site.getsitepackages()[0])")
echo "Site packages: $SITE_PACKAGES"
echo ""
echo -e "${GREEN}Step 2: Installing fourdst with pip...${NC}"
$PYTHON_BIN -m pip install . -v
if [ $? -ne 0 ]; then
echo -e "${RED}Error: pip install failed${NC}"
exit 1
fi
echo ""
echo -e "${GREEN}Step 3: Locating installed gridfire extension module...${NC}"
# Find the .so file
SO_FILE=$(find "$SITE_PACKAGES" -name "gridfire.cpython-*-darwin.so" 2>/dev/null | head -n 1)
if [ -z "$SO_FILE" ]; then
echo -e "${RED}Error: Could not find gridfire.cpython-*-darwin.so in $SITE_PACKAGES/gridfire${NC}"
echo "Installation may have failed or the file is in an unexpected location."
exit 1
fi
echo "Found gridfire extension module: $SO_FILE"
echo ""
echo -e "${GREEN}Step 4: Running RPATH fix script for gridfire extension module...${NC}"
# Check if fix_rpath.py exists
FIX_SCRIPT="build-python/fix_rpaths.py"
if [ ! -f "$FIX_SCRIPT" ]; then
echo -e "${RED}Error: $FIX_SCRIPT not found${NC}"
echo "Please ensure you're running this script from the project root directory."
exit 1
fi
# Run the fix script
$PYTHON_BIN "$FIX_SCRIPT" "$SO_FILE"
if [ $? -ne 0 ]; then
echo -e "${RED}Error: RPATH fix script failed for gridfire extension module${NC}"
exit 1
fi
echo -e "${GREEN}Step 5: Locating installed fourdst extension module...${NC}"
# Find the .so file
SO_FILE=$(find "$SITE_PACKAGES/fourdst" -name "_phys.cpython-*-darwin.so" 2>/dev/null | head -n 1)
if [ -z "$SO_FILE" ]; then
echo -e "${RED}Error: Could not find _phys.cpython-*-darwin.so in $SITE_PACKAGES/fourdst${NC}"
echo "Installation may have failed or the file is in an unexpected location."
exit 1
fi
echo "Found fourdst extension module: $SO_FILE"
echo ""
echo -e "${GREEN}Step 6: Running RPATH fix script for fourdst extension module...${NC}"
# Check if fix_rpath.py exists
FIX_SCRIPT="build-python/fix_rpaths.py"
if [ ! -f "$FIX_SCRIPT" ]; then
echo -e "${RED}Error: $FIX_SCRIPT not found${NC}"
echo "Please ensure you're running this script from the project root directory."
exit 1
fi
# Run the fix script
$PYTHON_BIN "$FIX_SCRIPT" "$SO_FILE"
if [ $? -ne 0 ]; then
echo -e "${RED}Error: RPATH fix script failed for fourdst extension module${NC}"
exit 1
fi
echo ""
echo -e "${GREEN}=========================================================================${NC}"
echo -e "${GREEN} Installation Complete!${NC}"
echo -e "${GREEN}=========================================================================${NC}"
echo ""
echo "You can now use fourdst in your Python environment."
echo ""
echo "Test the installation with:"
echo " $PYTHON_BIN -c 'import gridfire; print(gridfire.__version__)'"
echo ""
echo -e "${YELLOW}Note:${NC} If you reinstall or upgrade fourdst, you will need to run this"
echo "script again to apply the RPATH fix."
echo ""

View File

@@ -22,9 +22,13 @@ namespace gridfire {
ELECTRON_CAPTURE = 1 << 3, // 8
POSITRON_CAPTURE = 1 << 4, // 16
WEAK = BETA_MINUS | BETA_PLUS | ELECTRON_CAPTURE | POSITRON_CAPTURE,
DEFAULT = STRONG,
ALL = STRONG | WEAK
REACLIB_WEAK = 1 << 5,
WRL_WEAK = BETA_MINUS | BETA_PLUS | ELECTRON_CAPTURE | POSITRON_CAPTURE,
REACLIB = STRONG | REACLIB_WEAK,
DEFAULT = REACLIB,
ALL = STRONG | WRL_WEAK
};
constexpr auto to_underlying(NetworkConstructionFlags f) noexcept {
@@ -45,12 +49,13 @@ namespace gridfire {
inline std::string NetworkConstructionFlagsToString(NetworkConstructionFlags flags) {
std::stringstream ss;
constexpr std::array<NetworkConstructionFlags, 5> bases_flags_array = {
constexpr std::array<NetworkConstructionFlags, 6> bases_flags_array = {
NetworkConstructionFlags::STRONG,
NetworkConstructionFlags::BETA_MINUS,
NetworkConstructionFlags::BETA_PLUS,
NetworkConstructionFlags::ELECTRON_CAPTURE,
NetworkConstructionFlags::POSITRON_CAPTURE
NetworkConstructionFlags::POSITRON_CAPTURE,
NetworkConstructionFlags::REACLIB_WEAK
};
const std::unordered_map<NetworkConstructionFlags, std::string> bases_string_map = {
@@ -58,7 +63,8 @@ namespace gridfire {
{NetworkConstructionFlags::BETA_MINUS, "BetaMinus"},
{NetworkConstructionFlags::BETA_PLUS, "BetaPlus"},
{NetworkConstructionFlags::ELECTRON_CAPTURE, "ElectronCapture"},
{NetworkConstructionFlags::POSITRON_CAPTURE, "PositronCapture"}
{NetworkConstructionFlags::POSITRON_CAPTURE, "PositronCapture"},
{NetworkConstructionFlags::REACLIB_WEAK, "ReaclibWeak"}
};
size_t i = 0;

View File

@@ -44,7 +44,7 @@ namespace {
const gridfire::NetworkConstructionFlags reactionTypes
) {
gridfire::reaction::ReactionSet weak_reaction_pool;
if (!has_flag(reactionTypes, gridfire::NetworkConstructionFlags::WEAK)) {
if (!has_flag(reactionTypes, gridfire::NetworkConstructionFlags::WRL_WEAK)) {
return weak_reaction_pool;
}
@@ -109,13 +109,38 @@ namespace {
if (has_flag(reaction_types, gridfire::NetworkConstructionFlags::STRONG)) {
const auto& allReaclibReactions = gridfire::reaclib::get_all_reaclib_reactions();
for (const auto& reaction : allReaclibReactions) {
if (!reaction->is_reverse() && !reaclib_reaction_is_weak(*reaction)) { // Only add reactions of the correct direction and which are not weak. Weak reactions are handled from the WRL separately which provides much higher quality weak reactions than reaclib does
const bool isWeakReaction = reaclib_reaction_is_weak(*reaction);
const bool okayToUseReaclibWeakReaction = has_flag(reaction_types, gridfire::NetworkConstructionFlags::REACLIB_WEAK);
const bool reaclibWeakOkay = !isWeakReaction || okayToUseReaclibWeakReaction;
if (!reaction->is_reverse() && reaclibWeakOkay) {
strong_reaction_pool.add_reaction(reaction->clone());
}
}
}
return strong_reaction_pool;
}
bool validate_unique_weak_set(gridfire::NetworkConstructionFlags flag) {
// This method ensures that weak reactions will only be fetched from either reaclib or the weak reaction library (WRL)
// but not both
std::array<gridfire::NetworkConstructionFlags, 4> WRL_Flags = {
gridfire::NetworkConstructionFlags::BETA_PLUS,
gridfire::NetworkConstructionFlags::ELECTRON_CAPTURE,
gridfire::NetworkConstructionFlags::POSITRON_CAPTURE,
gridfire::NetworkConstructionFlags::BETA_MINUS
};
if (!has_flag(flag, gridfire::NetworkConstructionFlags::REACLIB_WEAK)) {
return true;
}
for (const auto& WRLReactionType : WRL_Flags) {
if (has_flag(flag, WRLReactionType)) {
return false;
}
}
return true;
}
}
namespace gridfire {
@@ -131,6 +156,11 @@ namespace gridfire {
NetworkConstructionFlags ReactionTypes
) {
auto logger = fourdst::logging::LogManager::getInstance().getLogger("log");
if (!validate_unique_weak_set(ReactionTypes)) {
std::string msg = "Cannot construct network since weak reactions from both reaclib and WRL were requested. Only one weak rate source may be used. In network construction this likely means that the flag NetworkConstructionFlags::REACLIB_WEAK was used along with one of the weak flags (BETA_PLUS, BETA_MINUS, ELECTRON_CAPTURE, POSITRON_CAPTURE). These flags are for WRL rates and may not be used in conjunction with reaclib weak rates.";
LOG_ERROR(logger, "{}", msg);
throw std::logic_error(msg);
}
LOG_INFO(logger, "Constructing network topology from reaction types : {}", NetworkConstructionFlagsToString(ReactionTypes));
if (ReactionTypes == NetworkConstructionFlags::NONE) {

View File

@@ -23,30 +23,30 @@ PYBIND11_MODULE(gridfire, m) {
auto typeMod = m.def_submodule("type", "GridFire type bindings");
register_type_bindings(typeMod);
// auto partitionMod = m.def_submodule("partition", "GridFire partition function bindings");
// register_partition_bindings(partitionMod);
//
// auto expectationMod = m.def_submodule("expectations", "GridFire expectations bindings");
// register_expectation_bindings(expectationMod);
//
// auto reactionMod = m.def_submodule("reaction", "GridFire reaction bindings");
// register_reaction_bindings(reactionMod);
//
// auto screeningMod = m.def_submodule("screening", "GridFire plasma screening bindings");
// register_screening_bindings(screeningMod);
//
// auto ioMod = m.def_submodule("io", "GridFire io bindings");
// register_io_bindings(ioMod);
//
// auto exceptionMod = m.def_submodule("exceptions", "GridFire exceptions bindings");
// register_exception_bindings(exceptionMod);
//
// auto engineMod = m.def_submodule("engine", "Engine and Engine View bindings");
// register_engine_bindings(engineMod);
//
// auto solverMod = m.def_submodule("solver", "GridFire numerical solver bindings");
// register_solver_bindings(solverMod);
//
// auto utilsMod = m.def_submodule("utils", "GridFire utility method bindings");
// register_utils_bindings(utilsMod);
auto partitionMod = m.def_submodule("partition", "GridFire partition function bindings");
register_partition_bindings(partitionMod);
auto expectationMod = m.def_submodule("expectations", "GridFire expectations bindings");
register_expectation_bindings(expectationMod);
auto reactionMod = m.def_submodule("reaction", "GridFire reaction bindings");
register_reaction_bindings(reactionMod);
auto screeningMod = m.def_submodule("screening", "GridFire plasma screening bindings");
register_screening_bindings(screeningMod);
auto ioMod = m.def_submodule("io", "GridFire io bindings");
register_io_bindings(ioMod);
auto exceptionMod = m.def_submodule("exceptions", "GridFire exceptions bindings");
register_exception_bindings(exceptionMod);
auto engineMod = m.def_submodule("engine", "Engine and Engine View bindings");
register_engine_bindings(engineMod);
auto solverMod = m.def_submodule("solver", "GridFire numerical solver bindings");
register_solver_bindings(solverMod);
auto utilsMod = m.def_submodule("utils", "GridFire utility method bindings");
register_utils_bindings(utilsMod);
}

View File

@@ -197,11 +197,11 @@ namespace {
}
void register_engine_bindings(py::module &m) {
register_engine_type_bindings(m);
register_engine_procedural_bindings(m);
register_base_engine_bindings(m);
register_engine_view_bindings(m);
register_engine_diagnostic_bindings(m);
register_engine_procedural_bindings(m);
register_engine_type_bindings(m);
}
void register_base_engine_bindings(const pybind11::module &m) {

View File

@@ -45,14 +45,10 @@ void register_exception_bindings(const py::module &m) {
py::register_exception<gridfire::exceptions::JacobianError>(m, "JacobianError", m.attr("GridFireEngineError"));
py::register_exception<gridfire::exceptions::StaleJacobianError>(m, "StaleJacobianError", m.attr("JacobianEngineError"));
py::register_exception<gridfire::exceptions::UninitializedJacobianError>(m, "UninitializedJacobianError", m.attr("JacobianEngineError"));
py::register_exception<gridfire::exceptions::UnknownJacobianError>(m, "UnknownJacobianError", m.attr("JacobianEngineError"));
py::register_exception<gridfire::exceptions::StaleJacobianError>(m, "StaleJacobianError", m.attr("JacobianError"));
py::register_exception<gridfire::exceptions::UninitializedJacobianError>(m, "UninitializedJacobianError", m.attr("JacobianError"));
py::register_exception<gridfire::exceptions::UnknownJacobianError>(m, "UnknownJacobianError", m.attr("JacobianError"));
py::register_exception<gridfire::exceptions::UtilityError>(m, "UtilityError");
py::register_exception<gridfire::exceptions::HashingError>(m, "HashingError", m.attr("UtilityError"));
}

View File

@@ -1,10 +1,10 @@
subdir('types')
#subdir('utils')
#subdir('expectations')
#subdir('exceptions')
#subdir('io')
#subdir('partition')
#subdir('reaction')
#subdir('screening')
#subdir('engine')
#subdir('solver')
subdir('utils')
subdir('expectations')
subdir('exceptions')
subdir('io')
subdir('partition')
subdir('reaction')
subdir('screening')
subdir('engine')
subdir('solver')

View File

@@ -1,4 +1,5 @@
#include <pybind11/pybind11.h>
#include <pybind11/functional.h> // needed for std::function
#include <pybind11/stl.h> // Needed for vectors, maps, sets, strings
#include <pybind11/stl_bind.h> // Needed for binding std::vector, std::map etc. if needed directly
#include <pybind11/numpy.h>

View File

@@ -1,4 +1,4 @@
[wrap-git]
url = https://github.com/4D-STAR/fourdst
revision = v0.8.4
revision = v0.8.5
depth = 1

View File

@@ -115,7 +115,7 @@ int main(int argc, char* argv[]){
// netIn.tMax = 1e-14;
netIn.dt0 = 1e-12;
GraphEngine ReaclibEngine(composition, partitionFunction, NetworkBuildDepth::SecondOrder, NetworkConstructionFlags::STRONG );
GraphEngine ReaclibEngine(composition, partitionFunction, NetworkBuildDepth::SecondOrder, NetworkConstructionFlags::DEFAULT);
ReaclibEngine.setPrecomputation(true);
ReaclibEngine.setUseReverseReactions(false);

View File

@@ -1,46 +1,46 @@
import numpy as np
from scipy.integrate import solve_ivp
import pp_chain_robust as network
T = 1.5e7
rho = 1.5e2
Y0 = np.zeros(network.nnuc)
Y0[network.jp] = 0.702583
Y0[network.jhe3] = 9.74903e-6
Y0[network.jhe4] = 0.068963
Y0[network.jc12] = 0.000250029
Y0[network.jn14] = 7.85632e-5
Y0[network.jo16] = 0.00060151
Y0[network.jne20] = 8.10399e-5
Y0[network.jmg24] = 2.15159e-5
t_start = 0.0
t_end = 3.14e17
t_span = (t_start, t_end)
sol = solve_ivp(
network.rhs,
t_span=t_span,
y0=Y0,
method='Radau',
jac=network.jacobian,
args=(rho, T),
dense_output=True,
rtol=1e-8,
atol=1e-8
)
with open("pynucastro_results.csv", 'w') as f:
f.write("t,h1,h2,he3,he4,c12,n14,o16,ne20,mg24\n")
for (t,h1,h2,he3,he4,c12,n14,o16,ne20,mg24) in zip(sol.t, sol.y[network.jp, :], sol.y[network.jd, :], sol.y[network.jhe3, :], sol.y[network.jhe4, :], sol.y[network.jc12, :], sol.y[network.jn14, :], sol.y[network.jo16, :], sol.y[network.jne20, :], sol.y[network.jmg24, :]):
f.write(f"{t},{h1},{h2},{he3},{he4},{c12},{n14},{o16},{ne20},{mg24}\n")
# import numpy as np
# from scipy.integrate import solve_ivp
#
# import pp_chain_robust as network
#
#
# T = 1e7
# rho = 1.5e2
#
# Y0 = np.zeros(network.nnuc)
# Y0[network.jp] = 0.702583
# Y0[network.jhe3] = 9.74903e-6
# Y0[network.jhe4] = 0.068963
# Y0[network.jc12] = 0.000250029
# Y0[network.jn14] = 7.85632e-5
# Y0[network.jo16] = 0.00060151
# Y0[network.jne20] = 8.10399e-5
# Y0[network.jmg24] = 2.15159e-5
#
# t_start = 0.0
# t_end = 3.14e17
# t_span = (t_start, t_end)
#
# sol = solve_ivp(
# network.rhs,
# t_span=t_span,
# y0=Y0,
# method='Radau',
# jac=network.jacobian,
# args=(rho, T),
# dense_output=True,
# rtol=1e-8,
# atol=1e-8
# )
#
#
# with open("pynucastro_results.csv", 'w') as f:
# f.write("t,h1,h2,he3,he4,c12,n14,o16,ne20,mg24\n")
# for (t,h1,h2,he3,he4,c12,n14,o16,ne20,mg24) in zip(sol.t, sol.y[network.jp, :], sol.y[network.jd, :], sol.y[network.jhe3, :], sol.y[network.jhe4, :], sol.y[network.jc12, :], sol.y[network.jn14, :], sol.y[network.jo16, :], sol.y[network.jne20, :], sol.y[network.jmg24, :]):
# f.write(f"{t},{h1},{h2},{he3},{he4},{c12},{n14},{o16},{ne20},{mg24}\n")
from gridfire.engine import GraphEngine, MultiscalePartitioningEngineView, AdaptiveEngineView
from gridfire.solver import DirectNetworkSolver
from gridfire.solver import CVODESolverStrategy
from gridfire.type import NetIn
from fourdst.composition import Composition
@@ -61,7 +61,7 @@ netIn = NetIn()
netIn.composition = comp
netIn.temperature = 1.5e7
netIn.density = 1.6e2
netIn.tMax = 3.14e17
netIn.tMax = 3.14e16
netIn.dt0 = 1e-12
baseEngine = GraphEngine(netIn.composition, 2)
@@ -71,7 +71,7 @@ qseEngine = MultiscalePartitioningEngineView(baseEngine)
adaptiveEngine = AdaptiveEngineView(qseEngine)
solver = DirectNetworkSolver(adaptiveEngine)
solver = CVODESolverStrategy(adaptiveEngine)
data = []
def callback(context):
@@ -98,10 +98,10 @@ def callback(context):
solver.set_callback(callback)
results = solver.evaluate(netIn)
results = solver.evaluate(netIn, False)
with open("gridfire_results.csv", 'w') as f:
f.write("t,h1,h2,he3,he4,c12,n14,o16,ne20,mg24\n")
for row in data:
rowStr = ','.join([str(x) for x in row])
f.write(f"{rowStr}\n")
# with open("gridfire_results.csv", 'w') as f:
# f.write("t,h1,h2,he3,he4,c12,n14,o16,ne20,mg24\n")
# for row in data:
# rowStr = ','.join([str(x) for x in row])
# f.write(f"{rowStr}\n")

View File

@@ -1,7 +1,6 @@
import pynucastro as pyna
from gridfire.engine import GraphEngine, MultiscalePartitioningEngineView, AdaptiveEngineView
from gridfire.solver import DirectNetworkSolver
from gridfire.type import NetIn
from fourdst.composition import Composition
@@ -19,7 +18,7 @@ print(f"Initial H-1 mass fraction {comp.getMassFraction("H-1")}")
netIn = NetIn()
netIn.composition = comp
netIn.temperature = 1.5e7
netIn.temperature = 1e7
netIn.density = 1.6e2
netIn.tMax = 1e-9
netIn.dt0 = 1e-12

File diff suppressed because it is too large Load Diff