Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
723067f
introduce FrozenKeyIdxBiMap data structure
mabruzzo Nov 19, 2025
cdecbb5
address clang-tidy issues
mabruzzo Nov 19, 2025
ce3c404
a few minor tweaks
mabruzzo Nov 19, 2025
660431f
Refactor for consistency with other internal types
mabruzzo Nov 19, 2025
1f42941
restore clang-tidy setting from a few commits back
mabruzzo Nov 19, 2025
a6aa793
apply clang-format
mabruzzo Nov 19, 2025
19d4f7e
a minor tweak to rerun CI
mabruzzo Nov 19, 2025
6f913fa
Merge branch 'ncc/FrozenKeyIdxBiMap' into ncc/refactor-GrainSpeciesInfo
mabruzzo Dec 9, 2025
18020b6
use FrozenKeyIdxBiMap within GrainSpeciesInfo (1/3)
mabruzzo Dec 10, 2025
00865dd
use FrozenKeyIdxBiMap within GrainSpeciesInfo (2/3)
mabruzzo Dec 10, 2025
fa08c26
use FrozenKeyIdxBiMap within GrainSpeciesInfo (3/3)
mabruzzo Dec 10, 2025
721d1a0
fix a few typos
mabruzzo Dec 10, 2025
dbb6b5d
move FrozenKeyIdxBiMap to support subdirectory
mabruzzo Dec 12, 2025
070509e
Merge branch 'ncc/FrozenKeyIdxBiMap' into ncc/refactor-GrainSpeciesInfo
mabruzzo Dec 12, 2025
b9261c3
fixing some paths
mabruzzo Dec 12, 2025
c287fa6
Add support for a map with 0 entries
mabruzzo Jan 5, 2026
0a8c9db
added a nice example illustrating how FrozenKeyIdxBiMap works
mabruzzo Jan 5, 2026
967a3e6
more rigorously tested empty bimaps and fixed bugs
mabruzzo Jan 5, 2026
b287370
Merge branch 'ncc/FrozenKeyIdxBiMap' into ncc/refactor-GrainSpeciesInfo
mabruzzo Jan 5, 2026
dab91b8
Merge branch 'newchem-cpp' into ncc/FrozenKeyIdxBiMap
mabruzzo Jan 6, 2026
f515c26
a bunch of assorted changes
mabruzzo Jan 6, 2026
f92ea3d
Merge branch 'ncc/FrozenKeyIdxBiMap' into ncc/refactor-GrainSpeciesInfo
mabruzzo Jan 6, 2026
547251d
introduce FNV1a hash function
mabruzzo Jan 6, 2026
1a3fb00
Overhaul the FrozenKeyIdxBiMap
mabruzzo Jan 6, 2026
8f66736
rename grackle::impl::{bimap->bimap_detail} & capitalize constant names
mabruzzo Jan 7, 2026
c30a4d3
intermediate commit
mabruzzo Jan 7, 2026
13b956f
shift to using AccessRslt
mabruzzo Jan 7, 2026
76b91eb
some slight renaming
mabruzzo Jan 7, 2026
3791553
some final cleanup
mabruzzo Jan 7, 2026
b75dddb
Merge branch 'ncc/FrozenKeyIdxBiMap' into ncc/refactor-GrainSpeciesInfo
mabruzzo Jan 7, 2026
4bc65e8
Merge branch 'ncc/refactor-GrainSpeciesInfo' into ncc/better-FrozenKe…
mabruzzo Jan 7, 2026
1d645e2
another few tweaks
mabruzzo Jan 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"cacheVariables" : {
"CMAKE_COMPILE_WARNING_AS_ERROR": "ON",
"CMAKE_C_FLAGS": "-Wall -Wpedantic -Wextra -Wno-error=unused-variable -Wno-error=newline-eof -Wno-unused-parameter",
"CMAKE_CXX_FLAGS": "-Wall -Wpedantic -Wno-c++17-attribute-extensions -Wno-unused-parameter"
"CMAKE_CXX_FLAGS": "-Wall -Wpedantic -Wno-c++17-attribute-extensions -Wno-unused-parameter -Wno-error=self-assign"
}
},
{
Expand Down
3 changes: 3 additions & 0 deletions src/clib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ add_library(Grackle_Grackle
solve_rate_cool_g-cpp.cpp solve_rate_cool_g-cpp.h
step_rate_gauss_seidel.hpp
step_rate_newton_raphson.hpp
support/FrozenKeyIdxBiMap.hpp
support/FrozenKeyIdxBiMap_detail.hpp
support/fnv1a_hash.hpp
time_deriv_0d.hpp
utils-cpp.cpp utils-cpp.hpp
utils-field.hpp
Expand Down
101 changes: 50 additions & 51 deletions src/clib/dust/grain_species_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "LUT.hpp"
#include "grain_species_info.hpp"
#include "../support/FrozenKeyIdxBiMap.hpp"

// The following logic effectively does 2 (related things):
// 1. it serves as a human-readable registry of all known grain species and
Expand Down Expand Up @@ -51,9 +52,8 @@ namespace { // stuff inside an anonymous namespace is local to this file
/// - the ingredient list in the returned instance is **NOT** terminated by
/// the sentinel
grackle::impl::GrainSpeciesInfoEntry mk_gsp_info_entry_helper_(
int species_idx, int onlygrainsp_idx, const char* name,
bool h2dust_uses_carbonaceous_table, double sublimation_temperature,
double bulk_density_cgs,
int species_idx, bool h2dust_uses_carbonaceous_table,
double sublimation_temperature, double bulk_density_cgs,
const grackle::impl::GrainGrowthIngredient* growth_ingredients) {
using grackle::impl::GrainGrowthIngredient;

Expand All @@ -76,27 +76,30 @@ grackle::impl::GrainSpeciesInfoEntry mk_gsp_info_entry_helper_(
}

return grackle::impl::GrainSpeciesInfoEntry{species_idx,
onlygrainsp_idx,
name,
h2dust_uses_carbonaceous_table,
sublimation_temperature,
bulk_density_cgs,
n_ingredients,
out_ingredient_ptr};
}

// ugh, I don't like this...
grackle::impl::GrainSpeciesInfo mk_invalid_GrainSpeciesInfo() {
return {-1, nullptr, grackle::impl::mk_invalid_FrozenKeyIdxBiMap()};
}

} // anonymous namespace

grackle::impl::GrainSpeciesInfo grackle::impl::new_GrainSpeciesInfo(
int dust_species_parameter) {
GrainSpeciesInfo out{-1, nullptr}; // indicates an error
out.n_species = get_n_grain_species(dust_species_parameter);

if (out.n_species <= 0) {
return out;
int n_species = get_n_grain_species(dust_species_parameter);
if (n_species <= 0) {
return mk_invalid_GrainSpeciesInfo();
}

out.species_info = new GrainSpeciesInfoEntry[out.n_species];
// names is allocated with the max number of known grain species
const char* names[OnlyGrainSpLUT::NUM_ENTRIES];
GrainSpeciesInfoEntry* species_info = new GrainSpeciesInfoEntry[n_species];

// At the time of writing:
// - we **only** use h2rate_carbonaceous_coef_table for the AC_dust
Expand Down Expand Up @@ -126,10 +129,9 @@ grackle::impl::GrainSpeciesInfo grackle::impl::new_GrainSpeciesInfo(
{1, SpLUT::SiOI, 44.},
{2, SpLUT::H2O, 18.},
GRIMPL_INGREDIENT_LIST_SENTINEL};
out.species_info[0] = mk_gsp_info_entry_helper_(
names[0] = "MgSiO3_dust";
species_info[0] = mk_gsp_info_entry_helper_(
/* species_idx = */ SpLUT::MgSiO3_dust,
/* onlygrainsp_idx = */ OnlyGrainSpLUT::MgSiO3_dust,
/* name = */ "MgSiO3_dust",
/* h2dust_uses_carbonaceous_table = */ false,
/* sublimation_temperature = */ 1222.0,
/* bulk_density_cgs = */ 3.20185,
Expand All @@ -140,10 +142,9 @@ grackle::impl::GrainSpeciesInfo grackle::impl::new_GrainSpeciesInfo(
// {coef, species_idx, particle mass}
{1, SpLUT::CI, 12.},
GRIMPL_INGREDIENT_LIST_SENTINEL};
out.species_info[1] = mk_gsp_info_entry_helper_(
names[1] = "AC_dust";
species_info[1] = mk_gsp_info_entry_helper_(
/* species_idx = */ SpLUT::AC_dust,
/* onlygrainsp_idx = */ OnlyGrainSpLUT::AC_dust,
/* name = */ "AC_dust",
/* h2dust_uses_carbonaceous_table = */ true,
/* sublimation_temperature = */ 1800.0,
/* bulk_density_cgs = */ 2.27949,
Expand All @@ -156,10 +157,9 @@ grackle::impl::GrainSpeciesInfo grackle::impl::new_GrainSpeciesInfo(
// {coef, species_idx, particle mass}
{1, SpLUT::SiI, 28.},
GRIMPL_INGREDIENT_LIST_SENTINEL};
out.species_info[2] = mk_gsp_info_entry_helper_(
names[2] = "SiM_dust";
species_info[2] = mk_gsp_info_entry_helper_(
/* species_idx = */ SpLUT::SiM_dust,
/* onlygrainsp_idx = */ OnlyGrainSpLUT::SiM_dust,
/* name = */ "SiM_dust",
/* h2dust_uses_carbonaceous_table = */ false,
/* sublimation_temperature = */ 1500.0,
/* bulk_density_cgs = */ 2.34118,
Expand All @@ -170,10 +170,9 @@ grackle::impl::GrainSpeciesInfo grackle::impl::new_GrainSpeciesInfo(
// {coef, species_idx, particle mass}
{1, SpLUT::Fe, 56.},
GRIMPL_INGREDIENT_LIST_SENTINEL};
out.species_info[3] = mk_gsp_info_entry_helper_(
names[3] = "FeM_dust";
species_info[3] = mk_gsp_info_entry_helper_(
/* species_idx = */ SpLUT::FeM_dust,
/* onlygrainsp_idx = */ OnlyGrainSpLUT::FeM_dust,
/* name = */ "FeM_dust",
/* h2dust_uses_carbonaceous_table = */ false,
/* sublimation_temperature = */ 1500.0,
/* bulk_density_cgs = */ 7.95995,
Expand All @@ -186,10 +185,9 @@ grackle::impl::GrainSpeciesInfo grackle::impl::new_GrainSpeciesInfo(
{1, SpLUT::SiOI, 44.},
{3, SpLUT::H2O, 18.},
GRIMPL_INGREDIENT_LIST_SENTINEL};
out.species_info[4] = mk_gsp_info_entry_helper_(
names[4] = "Mg2SiO4_dust";
species_info[4] = mk_gsp_info_entry_helper_(
/* species_idx = */ SpLUT::Mg2SiO4_dust,
/* onlygrainsp_idx = */ OnlyGrainSpLUT::Mg2SiO4_dust,
/* name = */ "Mg2SiO4_dust",
/* h2dust_uses_carbonaceous_table = */ false,
/* sublimation_temperature = */ 1277.0,
/* bulk_density_cgs = */ 3.22133,
Expand All @@ -201,10 +199,9 @@ grackle::impl::GrainSpeciesInfo grackle::impl::new_GrainSpeciesInfo(
{3, SpLUT::Fe, 56.},
{4, SpLUT::H2O, 18.},
GRIMPL_INGREDIENT_LIST_SENTINEL};
out.species_info[5] = mk_gsp_info_entry_helper_(
names[5] = "Fe3O4_dust";
species_info[5] = mk_gsp_info_entry_helper_(
/* species_idx = */ SpLUT::Fe3O4_dust,
/* onlygrainsp_idx = */ OnlyGrainSpLUT::Fe3O4_dust,
/* name = */ "Fe3O4_dust",
/* h2dust_uses_carbonaceous_table = */ false,
/* sublimation_temperature = */ 1500.0,
/* bulk_density_cgs = */ 5.25096,
Expand All @@ -215,10 +212,9 @@ grackle::impl::GrainSpeciesInfo grackle::impl::new_GrainSpeciesInfo(
// {coef, species_idx, particle mass}
{1, SpLUT::SiO2I, 60.},
GRIMPL_INGREDIENT_LIST_SENTINEL};
out.species_info[6] = mk_gsp_info_entry_helper_(
names[6] = "SiO2_dust";
species_info[6] = mk_gsp_info_entry_helper_(
/* species_idx = */ SpLUT::SiO2_dust,
/* onlygrainsp_idx = */ OnlyGrainSpLUT::SiO2_dust,
/* name = */ "SiO2_dust",
/* h2dust_uses_carbonaceous_table = */ false,
/* sublimation_temperature = */ 1500.0,
/* bulk_density_cgs = */ 2.66235,
Expand All @@ -230,10 +226,9 @@ grackle::impl::GrainSpeciesInfo grackle::impl::new_GrainSpeciesInfo(
{1, SpLUT::Mg, 24.},
{1, SpLUT::H2O, 18.},
GRIMPL_INGREDIENT_LIST_SENTINEL};
out.species_info[7] = mk_gsp_info_entry_helper_(
names[7] = "MgO_dust";
species_info[7] = mk_gsp_info_entry_helper_(
/* species_idx = */ SpLUT::MgO_dust,
/* onlygrainsp_idx = */ OnlyGrainSpLUT::MgO_dust,
/* name = */ "MgO_dust",
/* h2dust_uses_carbonaceous_table = */ false,
/* sublimation_temperature = */ 1500.0,
/* bulk_density_cgs = */ 3.58157,
Expand All @@ -245,10 +240,9 @@ grackle::impl::GrainSpeciesInfo grackle::impl::new_GrainSpeciesInfo(
{1, SpLUT::Fe, 56.},
{1, SpLUT::S, 32.},
GRIMPL_INGREDIENT_LIST_SENTINEL};
out.species_info[8] = mk_gsp_info_entry_helper_(
names[8] = "FeS_dust";
species_info[8] = mk_gsp_info_entry_helper_(
/* species_idx = */ SpLUT::FeS_dust,
/* onlygrainsp_idx = */ OnlyGrainSpLUT::FeS_dust,
/* name = */ "FeS_dust",
/* h2dust_uses_carbonaceous_table = */ false,
/* sublimation_temperature = */ 680.0,
/* bulk_density_cgs = */ 4.87265,
Expand All @@ -260,10 +254,9 @@ grackle::impl::GrainSpeciesInfo grackle::impl::new_GrainSpeciesInfo(
{2, SpLUT::Al, 27.},
{3, SpLUT::H2O, 18.},
GRIMPL_INGREDIENT_LIST_SENTINEL};
out.species_info[9] = mk_gsp_info_entry_helper_(
names[9] = "Al2O3_dust";
species_info[9] = mk_gsp_info_entry_helper_(
/* species_idx = */ SpLUT::Al2O3_dust,
/* onlygrainsp_idx = */ OnlyGrainSpLUT::Al2O3_dust,
/* name = */ "Al2O3_dust",
/* h2dust_uses_carbonaceous_table = */ false,
/* sublimation_temperature = */ 1500.0,
/* bulk_density_cgs = */ 4.01610,
Expand All @@ -277,38 +270,44 @@ grackle::impl::GrainSpeciesInfo grackle::impl::new_GrainSpeciesInfo(

// nominal growth rxn: "0.5CO + 0.5CH2 + 1.2N -> ref_org_dust"
// nuclide ratios: C:H:O:N = 1:1:0.5:1.2
out.species_info[10] = mk_gsp_info_entry_helper_(
names[10] = "ref_org_dust";
species_info[10] = mk_gsp_info_entry_helper_(
/* species_idx = */ SpLUT::ref_org_dust,
/* onlygrainsp_idx = */ OnlyGrainSpLUT::ref_org_dust,
/* name = */ "ref_org_dust",
/* h2dust_uses_carbonaceous_table = */ false,
/* sublimation_temperature = */ 575.0,
/* bulk_density_cgs = */ 1.5,
/* growth_ingredients = */ nullptr);

// nominal growth rxn: "CO + 2H2I -> vol_org_dust"
// effective formula: CH3OH
out.species_info[11] = mk_gsp_info_entry_helper_(
names[11] = "vol_org_dust";
species_info[11] = mk_gsp_info_entry_helper_(
/* species_idx = */ SpLUT::vol_org_dust,
/* onlygrainsp_idx = */ OnlyGrainSpLUT::vol_org_dust,
/* name = */ "vol_org_dust",
/* h2dust_uses_carbonaceous_table = */ false,
/* sublimation_temperature = */ 375.0,
/* bulk_density_cgs = */ 1.0,
/* growth_ingredients = */ nullptr);

// nominal growth rxn: "H2O -> H2O_ice_dust"
out.species_info[12] = mk_gsp_info_entry_helper_(
names[12] = "H2O_ice_dust";
species_info[12] = mk_gsp_info_entry_helper_(
/* species_idx = */ SpLUT::H2O_ice_dust,
/* onlygrainsp_idx = */ OnlyGrainSpLUT::H2O_ice_dust,
/* name = */ "H2O_ice_dust",
/* h2dust_uses_carbonaceous_table = */ false,
/* sublimation_temperature = */ 153.0,
/* bulk_density_cgs = */ 0.92,
/* growth_ingredients = */ nullptr);
}

return out;
GrainSpeciesInfo out{
n_species, species_info,
new_FrozenKeyIdxBiMap(names, n_species, BiMapMode::COPIES_KEYDATA)};

if (FrozenKeyIdxBiMap_is_ok(&out.name_map)) {
return out;
} else {
drop_GrainSpeciesInfo(&out);
return mk_invalid_GrainSpeciesInfo();
}
}

#undef GRIMPL_INGREDIENT_LIST_SENTINEL
37 changes: 18 additions & 19 deletions src/clib/dust/grain_species_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#ifndef GRAIN_SPECIES_INFO_HPP
#define GRAIN_SPECIES_INFO_HPP

#include "../support/FrozenKeyIdxBiMap.hpp"

namespace grackle::impl {

/// holds information about a single gas species that is an ingredient for
Expand All @@ -39,19 +41,6 @@ struct GrainSpeciesInfoEntry {
/// the species index of the grain in the #GrainSpLUT lookup table
int species_idx;

/// the species index of the grain in the #OnlyGrainSpLUT lookup table
///
/// @note
/// It's frankly a little redundant to track this information (since an
/// instance of this struct is found at this index of an out.species_infoay)
int onlygrainsp_idx;

/// name of the dust species
///
/// @note
/// This primarily exists for debuging purposes
const char* name;

/// indicates whether to use the carbonaceous or silicate coefficient table
/// to computing contributions of the grain species to the total h2dust rate
/// (or the rate of H2 formation)
Expand Down Expand Up @@ -92,17 +81,17 @@ struct GrainSpeciesInfoEntry {
/// Relationship with OnlyGrainSpLUT
/// --------------------------------
/// In the short term, the index of each species in the
/// @ref GrainSpeciesInfo::species_info out.species_infoay is dictated by the
/// @ref GrainSpeciesInfo::species_info out.species_info is dictated by the
/// order of enumerators in the OnlyGrainSpLUT enumeration.
///
/// In the medium term, we plan to entirely eliminate the OnlyGrainSpLUT
/// enumeration because all of the grain species can be treated very uniformly
/// uniformly. At the time of writing, just about every place where we would
/// use OnlyGrainSpLUT corresponds to a location where would enumerate every
/// enumeration because all of the grain species can be treated very uniformly.
/// At the time of writing, just about every place where we would use
/// OnlyGrainSpLUT corresponds to a location where we would enumerate every
/// possible grain species and perform nearly identical operations on each
/// species. In each case, it is straight-forward to replace these blocks of
/// logic with for-loops (we just need to encode species-specific variations in
/// the calculations in out.species_infoays that have the same ordering as the
/// the calculations in out.species_info that have the same ordering as the
/// species). To phrase it another way, in nearly all of the places where we
/// would use OnlyGrainSpLUT, we don't need to know the grain species identity.
///
Expand All @@ -113,9 +102,18 @@ struct GrainSpeciesInfo {
/// number of grain species considered for the current Grackle configuration
int n_species;

/// an out.species_infoay of length of length @ref n_species where each entry
/// an out.species_info of length of length @ref n_species where each entry
/// holds info about a separate grain species
GrainSpeciesInfoEntry* species_info;

/// maps between grain species names and the associated index. The mapping is
/// **ALWAYS** consistent with ``OnlyGrainSpLUT``.
///
/// @note
/// An argument could be made for storing this separately from the rest of
/// the struct since the core grackle calculations don't (or at least
/// shouldn't) use this data structure during the calculation.
FrozenKeyIdxBiMap name_map;
};

/// return the number of grain species
Expand Down Expand Up @@ -164,6 +162,7 @@ inline void drop_GrainSpeciesInfo(GrainSpeciesInfo* ptr) {
}
}
delete[] ptr->species_info;
drop_FrozenKeyIdxBiMap(&ptr->name_map);
// the following 2 lines are not strictly necessary, but they may help us
// avoid a double-free and a dangling pointer
ptr->n_species = 0;
Expand Down
Loading