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
1 merge request!245Include proposal process rebase
Pipeline #2307 failed
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
namespace corsika::environment { namespace corsika::environment {
class NuclearComposition { class NuclearComposition {
std::vector<float> const fNumberFractions; //!< relative fractions of number density std::vector<float> const fNumberFractions; //!< relative fractions of number density
...@@ -26,6 +28,8 @@ namespace corsika::environment { ...@@ -26,6 +28,8 @@ namespace corsika::environment {
double const fAvgMassNumber; double const fAvgMassNumber;
std::size_t hash_;
template <class AConstIterator, class BConstIterator> template <class AConstIterator, class BConstIterator>
class WeightProviderIterator { class WeightProviderIterator {
AConstIterator fAIter; AConstIterator fAIter;
...@@ -77,6 +81,7 @@ namespace corsika::environment { ...@@ -77,6 +81,7 @@ namespace corsika::environment {
if (!(0.999f < sumFractions && sumFractions < 1.001f)) { if (!(0.999f < sumFractions && sumFractions < 1.001f)) {
throw std::runtime_error("element fractions do not add up to 1"); throw std::runtime_error("element fractions do not add up to 1");
} }
updateHash();
} }
template <typename TFunction> template <typename TFunction>
...@@ -125,6 +130,25 @@ namespace corsika::environment { ...@@ -125,6 +130,25 @@ namespace corsika::environment {
auto const iChannel = channelDist(randomStream); auto const iChannel = channelDist(randomStream);
return fComponents[iChannel]; 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 } // namespace corsika::environment
...@@ -30,14 +30,14 @@ namespace corsika::process::proposal { ...@@ -30,14 +30,14 @@ namespace corsika::process::proposal {
// interpolate the crosssection for given media and energy cut. These may // 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 // take some minutes if you have to build the tables and cannot read the
// from disk // 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 // 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 // saved in the calc map by a key build out of a hash of composed of the component and
// particle code. // particle code.
auto disp = PROPOSAL::make_displacement(c, true); auto disp = PROPOSAL::make_displacement(c, true);
auto scatter = PROPOSAL::make_scattering("highland", particle[code], media.at(&comp)); auto scatter = PROPOSAL::make_scattering("highland", particle[code], media.at(comp.hash()));
calc[std::make_pair(&comp, code)] = calc[std::make_pair(comp.hash(), code)] =
std::make_tuple(std::move(disp), std::move(scatter)); std::make_tuple(std::move(disp), std::move(scatter));
} }
......
...@@ -43,7 +43,7 @@ namespace corsika::process::proposal { ...@@ -43,7 +43,7 @@ namespace corsika::process::proposal {
*frac_iter); *frac_iter);
++frac_iter; ++frac_iter;
} }
media[ncarg] = PROPOSAL::Medium( media[ncarg->hash()] = PROPOSAL::Medium(
"Modified Air", PROPOSAL::Air().GetI(), PROPOSAL::Air().GetC(), "Modified Air", PROPOSAL::Air().GetI(), PROPOSAL::Air().GetC(),
PROPOSAL::Air().GetA(), PROPOSAL::Air().GetM(), PROPOSAL::Air().GetX0(), PROPOSAL::Air().GetA(), PROPOSAL::Air().GetM(), PROPOSAL::Air().GetX0(),
PROPOSAL::Air().GetX1(), PROPOSAL::Air().GetD0(), 1.0, comp_vec); PROPOSAL::Air().GetX1(), PROPOSAL::Air().GetD0(), 1.0, comp_vec);
...@@ -64,10 +64,9 @@ namespace corsika::process::proposal { ...@@ -64,10 +64,9 @@ namespace corsika::process::proposal {
"table directory. "); "table directory. ");
} }
} }
size_t ProposalProcessBase::hash::operator()(const calc_key_t& p) const noexcept { size_t ProposalProcessBase::hash::operator()(const calc_key_t& p) const noexcept {
return std::hash<const environment::NuclearComposition*>{}(p.first) ^ return p.first ^ std::hash<particles::Code>{}(p.second);
std::hash<particles::Code>{}(p.second);
} }
} // namespace corsika::process::proposal } // namespace corsika::process::proposal
...@@ -73,7 +73,7 @@ namespace corsika::process::proposal { ...@@ -73,7 +73,7 @@ namespace corsika::process::proposal {
//!< will be handeled continuously. //!< will be handeled continuously.
corsika::random::RNG& fRNG; //!< random number generator used by proposal 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 media; //!< maps nuclear composition from univers to media to produce
//!< crosssections, which requires further ionization constants. //!< crosssections, which requires further ionization constants.
...@@ -89,7 +89,7 @@ namespace corsika::process::proposal { ...@@ -89,7 +89,7 @@ namespace corsika::process::proposal {
//! //!
bool CanInteract(particles::Code pcode) const; 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 //! Hash to store interpolation tables related to a pair of particle and nuclear
...@@ -112,8 +112,8 @@ namespace corsika::process::proposal { ...@@ -112,8 +112,8 @@ namespace corsika::process::proposal {
//! //!
template <typename Particle, typename Calculators> template <typename Particle, typename Calculators>
auto GetCalculator(Particle& vP, Calculators& calc) { auto GetCalculator(Particle& vP, Calculators& calc) {
auto& comp = vP.GetNode()->GetModelProperties().GetNuclearComposition(); const auto& comp = vP.GetNode()->GetModelProperties().GetNuclearComposition();
auto calc_it = calc.find(std::make_pair(&comp, vP.GetPID())); auto calc_it = calc.find(std::make_pair(comp.hash(), vP.GetPID()));
if (calc_it != calc.end()) return calc_it; if (calc_it != calc.end()) return calc_it;
BuildCalculator(vP.GetPID(), comp); BuildCalculator(vP.GetPID(), comp);
return GetCalculator(vP, calc); 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