IAP GITLAB

Skip to content
Snippets Groups Projects
Commit 3b4369f7 authored by ralfulrich's avatar ralfulrich
Browse files

added a hash as member of NuclearComposition, so that it can be used as unique map-key etc.

parent 1d2fb269
No related branches found
No related tags found
No related merge requests found
......@@ -18,6 +18,8 @@
#include <stdexcept>
#include <vector>
namespace corsika::environment {
class NuclearComposition {
std::vector<float> const fNumberFractions; //!< relative fractions of number density
......@@ -26,6 +28,8 @@ namespace corsika::environment {
double const fAvgMassNumber;
std::size_t hash_;
template <class AConstIterator, class BConstIterator>
class WeightProviderIterator {
AConstIterator fAIter;
......@@ -77,6 +81,7 @@ namespace corsika::environment {
if (!(0.999f < sumFractions && sumFractions < 1.001f)) {
throw std::runtime_error("element fractions do not add up to 1");
}
updateHash();
}
template <typename TFunction>
......@@ -125,6 +130,25 @@ namespace corsika::environment {
auto const iChannel = channelDist(randomStream);
return fComponents[iChannel];
}
// Note: when this class ever modifies its internal data, the hash
// must be updated, too!
size_t hash() const { return hash_; }
private:
void updateHash() const {
std::vector<std::size_t> hashes;
for (float ifrac : GetFractions())
hashes.push_back(std::hash<float>{}(ifrac));
for (corsika::particles::Code icode : GetComponents())
hashes.push_back(std::hash<int>{}(static_cast<int>(icode)));
std::size_t h = std::hash<double>{}(GetAverageMassNumber());
for (std::size_t ih : hashes)
h = h ^ (ih<<1);
hash_ = h;
}
};
} // namespace corsika::environment
......@@ -30,14 +30,14 @@ namespace corsika::process::proposal {
// interpolate the crosssection for given media and energy cut. These may
// take some minutes if you have to build the tables and cannot read the
// from disk
auto c = p_cross->second(media.at(&comp), emCut_);
auto c = p_cross->second(media.at(comp.hash()), emCut_);
// Build displacement integral and scattering object and interpolate them too and
// saved in the calc map by a key build out of a hash of composed of the component and
// particle code.
auto disp = PROPOSAL::make_displacement(c, true);
auto scatter = PROPOSAL::make_scattering("highland", particle[code], media.at(&comp));
calc[std::make_pair(&comp, code)] =
auto scatter = PROPOSAL::make_scattering("highland", particle[code], media.at(comp.hash()));
calc[std::make_pair(comp.hash(), code)] =
std::make_tuple(std::move(disp), std::move(scatter));
}
......
......@@ -43,7 +43,7 @@ namespace corsika::process::proposal {
*frac_iter);
++frac_iter;
}
media[ncarg] = PROPOSAL::Medium(
media[ncarg->hash()] = PROPOSAL::Medium(
"Modified Air", PROPOSAL::Air().GetI(), PROPOSAL::Air().GetC(),
PROPOSAL::Air().GetA(), PROPOSAL::Air().GetM(), PROPOSAL::Air().GetX0(),
PROPOSAL::Air().GetX1(), PROPOSAL::Air().GetD0(), 1.0, comp_vec);
......@@ -64,10 +64,9 @@ namespace corsika::process::proposal {
"table directory. ");
}
}
size_t ProposalProcessBase::hash::operator()(const calc_key_t& p) const noexcept {
return std::hash<const environment::NuclearComposition*>{}(p.first) ^
std::hash<particles::Code>{}(p.second);
return p.first ^ std::hash<particles::Code>{}(p.second);
}
} // namespace corsika::process::proposal
......@@ -73,7 +73,7 @@ namespace corsika::process::proposal {
//!< will be handeled continuously.
corsika::random::RNG& fRNG; //!< random number generator used by proposal
std::unordered_map<const environment::NuclearComposition*, PROPOSAL::Medium>
std::unordered_map<std::size_t, PROPOSAL::Medium>
media; //!< maps nuclear composition from univers to media to produce
//!< crosssections, which requires further ionization constants.
......@@ -89,7 +89,7 @@ namespace corsika::process::proposal {
//!
bool CanInteract(particles::Code pcode) const;
using calc_key_t = std::pair<const environment::NuclearComposition*, particles::Code>;
using calc_key_t = std::pair<std::size_t, particles::Code>;
//!
//! Hash to store interpolation tables related to a pair of particle and nuclear
......@@ -112,8 +112,8 @@ namespace corsika::process::proposal {
//!
template <typename Particle, typename Calculators>
auto GetCalculator(Particle& vP, Calculators& calc) {
auto& comp = vP.GetNode()->GetModelProperties().GetNuclearComposition();
auto calc_it = calc.find(std::make_pair(&comp, vP.GetPID()));
const auto& comp = vP.GetNode()->GetModelProperties().GetNuclearComposition();
auto calc_it = calc.find(std::make_pair(comp.hash(), vP.GetPID()));
if (calc_it != calc.end()) return calc_it;
BuildCalculator(vP.GetPID(), comp);
return GetCalculator(vP, calc);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment