Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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 @@ -77,27 +77,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 @@ -127,10 +130,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 @@ -141,10 +143,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 @@ -157,10 +158,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 @@ -171,10 +171,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 @@ -187,10 +186,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 @@ -202,10 +200,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 @@ -216,10 +213,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 @@ -231,10 +227,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 @@ -246,10 +241,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 @@ -261,10 +255,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 @@ -278,38 +271,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
19 changes: 11 additions & 8 deletions src/clib/support/FrozenKeyIdxBiMap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ struct FrozenKeyIdxBiMap {
BiMapMode mode;
};

// ugh, it's unfortunate that we need to make this... but for now its useful.
// Ideally, we would refactor so that we can get rid of this function.
inline FrozenKeyIdxBiMap mk_invalid_FrozenKeyIdxBiMap() {
return FrozenKeyIdxBiMap{-1, nullptr, BiMapMode::REFS_KEYDATA};
}

/// Constructs a new FrozenKeyIdxBiMap
///
/// @param[in] keys Sequence of 1 or more unique strings. Each string must
Expand All @@ -126,9 +132,6 @@ struct FrozenKeyIdxBiMap {
/// std::optional or converting this type to a simple C++ class.
inline FrozenKeyIdxBiMap new_FrozenKeyIdxBiMap(const char* const keys[],
int key_count, BiMapMode mode) {
// this will be returned if there is an error
FrozenKeyIdxBiMap erroneous_obj{-1, nullptr, BiMapMode::REFS_KEYDATA};

if (keys == nullptr && key_count == 0) {
return FrozenKeyIdxBiMap{0, nullptr, mode};
}
Expand All @@ -137,10 +140,10 @@ inline FrozenKeyIdxBiMap new_FrozenKeyIdxBiMap(const char* const keys[],
int max_keys = static_cast<int>(std::numeric_limits<uint16_t>::max());
if (key_count < 1 || key_count > max_keys) {
GrPrintErrMsg("key_count must be positive & can't exceed %d", max_keys);
return erroneous_obj;
return mk_invalid_FrozenKeyIdxBiMap();
} else if (keys == nullptr) {
GrPrintErrMsg("keys must not be a nullptr");
return erroneous_obj;
return mk_invalid_FrozenKeyIdxBiMap();
}
for (int i = 0; i < key_count; i++) {
GR_INTERNAL_REQUIRE(keys[i] != nullptr, "Can't specify a nullptr key");
Expand All @@ -151,13 +154,13 @@ inline FrozenKeyIdxBiMap new_FrozenKeyIdxBiMap(const char* const keys[],
"calling strlen on \"%s\", the key @ index %d, yields 0 or a length "
"exceeding %d",
keys[i], i, bimap_detail::KEYLEN_MAX);
return erroneous_obj;
return mk_invalid_FrozenKeyIdxBiMap();
}
// check uniqueness
for (int j = 0; j < i; j++) {
if (strcmp(keys[i], keys[j]) == 0) {
GrPrintErrMsg("\"%s\" key repeats", keys[i]);
return erroneous_obj;
return mk_invalid_FrozenKeyIdxBiMap();
}
}
}
Expand All @@ -184,7 +187,7 @@ inline FrozenKeyIdxBiMap new_FrozenKeyIdxBiMap(const char* const keys[],
}
default: {
GrPrintErrMsg("unknown mode");
return erroneous_obj;
return mk_invalid_FrozenKeyIdxBiMap();
}
}

Expand Down
Loading