IAP GITLAB

Skip to content
Snippets Groups Projects
Commit ee7c2a06 authored by Antonio Augusto Alves Junior's avatar Antonio Augusto Alves Junior Committed by ralfulrich
Browse files

[refactory-2020] stack implementations: more cleaning up. Moving...

[refactory-2020] stack implementations: more cleaning up. Moving implemententations to inl. NuclearStackExtension.hpp
parent 35e30593
No related branches found
No related tags found
No related merge requests found
/*
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*/
#pragma once
#include <corsika/framework/core/ParticleProperties.hpp>
#include <corsika/framework/core/PhysicalUnits.hpp>
#include <corsika/framework/stack/Stack.hpp>
#include <corsika/framework/geometry/Point.hpp>
#include <corsika/framework/geometry/Vector.hpp>
#include <corsika/stack/SuperStupidStack.hpp>
#include <algorithm>
#include <tuple>
#include <vector>
namespace corsika::nuclear_stack {
template <template <typename> class InnerParticleInterface,
typename StackIteratorInterface>
void NuclearParticleInterface< InnerParticleInterface,StackIteratorInterface>::setParticleData(particle_data_type const& v)
{
if (std::get<0>(v) == Code::Nucleus) {
std::ostringstream err;
err << "NuclearStackExtension: no A and Z specified for new Nucleus!";
throw std::runtime_error(err.str());
}
super_type::setParticleData(v);
setNucleusRef(-1); // this is not a nucleus
}
template <template <typename> class InnerParticleInterface,
typename StackIteratorInterface>
void NuclearParticleInterface< InnerParticleInterface,StackIteratorInterface>::setParticleData(altenative_particle_data_type const& v)
{
const unsigned short A = std::get<5>(v);
const unsigned short Z = std::get<6>(v);
if (std::get<0>(v) != Code::Nucleus || A == 0 || Z == 0) {
std::ostringstream err;
err << "NuclearStackExtension: no A and Z specified for new Nucleus!";
throw std::runtime_error(err.str());
}
setNucleusRef(
super_type::getStackData().getNucleusNextRef()); // store this nucleus data ref
setNuclearA(A);
setNuclearZ(Z);
super_type::setParticleData(particle_data_type{std::get<0>(v), std::get<1>(v),
std::get<2>(v), std::get<3>(v),
std::get<4>(v)});
}
template <template <typename> class InnerParticleInterface,
typename StackIteratorInterface>
void NuclearParticleInterface< InnerParticleInterface,StackIteratorInterface>::setParticleData(super_type& p, particle_data_type const& v) {
if (std::get<0>(v) == Code::Nucleus) {
std::ostringstream err;
err << "NuclearStackExtension: no A and Z specified for new Nucleus!";
throw std::runtime_error(err.str());
}
super_type::setParticleData(
p, particle_data_type{std::get<0>(v), std::get<1>(v), std::get<2>(v),
std::get<3>(v), std::get<4>(v)});
setNucleusRef(-1); // this is not a nucleus
}
template <template <typename> class InnerParticleInterface,
typename StackIteratorInterface>
void NuclearParticleInterface< InnerParticleInterface,StackIteratorInterface>::setParticleData(super_type& p, altenative_particle_data_type const& v) {
const unsigned short A = std::get<5>(v);
const unsigned short Z = std::get<6>(v);
if (std::get<0>(v) != Code::Nucleus || A == 0 || Z == 0) {
std::ostringstream err;
err << "NuclearStackExtension: no A and Z specified for new Nucleus!";
throw std::runtime_error(err.str());
}
setNucleusRef(
super_type::getStackData().getNucleusNextRef()); // store this nucleus data ref
setNuclearA(A);
setNuclearZ(Z);
super_type::setParticleData(
p, particle_data_type{std::get<0>(v), std::get<1>(v), std::get<2>(v),
std::get<3>(v), std::get<4>(v)});
}
template <template <typename> class InnerParticleInterface,
typename StackIteratorInterface>
std::string NuclearParticleInterface< InnerParticleInterface,StackIteratorInterface>::as_string() const {
return fmt::format(
"{}, nuc({})", super_type::as_string(),
(isNucleus() ? fmt::format("A={}, Z={}", getNuclearA(), getNuclearZ())
: "n/a"));
}
template <template <typename> class InnerParticleInterface,
typename StackIteratorInterface>
HEPMassType NuclearParticleInterface< InnerParticleInterface,StackIteratorInterface>::getMass() const {
if (super_type::getPID() == Code::Nucleus)
return getNucleusMass(getNuclearA(), getNuclearZ());
return super_type::getMass();
}
template <template <typename> class InnerParticleInterface,
typename StackIteratorInterface>
int16_t NuclearParticleInterface< InnerParticleInterface,StackIteratorInterface>::getChargeNumber() const {
if (super_type::getPID() == Code::Nucleus) return getNuclearZ();
return super_type::getChargeNumber();
}
template <typename InnerStackImpl>
int NuclearStackExtensionImpl<InnerStackImpl>::getNucleusNextRef(){
nuclearA_.push_back(0);
nuclearZ_.push_back(0);
return nuclearA_.size() - 1;
}
template <typename InnerStackImpl>
int NuclearStackExtensionImpl<InnerStackImpl>::getNucleusRef(const unsigned int i) const {
if (nucleusRef_[i] >= 0) return nucleusRef_[i];
std::ostringstream err;
err << "NuclearStackExtension: no nucleus at ref=" << i;
throw std::runtime_error(err.str());
}
template <typename InnerStackImpl>
void NuclearStackExtensionImpl<InnerStackImpl>::copy(const unsigned int i1, const unsigned int i2) {
// index range check
if (i1 >= getSize() || i2 >= getSize()) {
std::ostringstream err;
err << "NuclearStackExtension: trying to access data beyond size of stack!";
throw std::runtime_error(err.str());
}
// copy internal particle data p[i2] = p[i1]
super_type::copy(i1, i2);
// check if any of p[i1] or p[i2] was a Code::Nucleus
const int ref1 = nucleusRef_[i1];
const int ref2 = nucleusRef_[i2];
if (ref2 < 0) {
if (ref1 >= 0) {
// i1 is nucleus, i2 is not
nucleusRef_[i2] = getNucleusNextRef();
nuclearA_[nucleusRef_[i2]] = nuclearA_[ref1];
nuclearZ_[nucleusRef_[i2]] = nuclearZ_[ref1];
} else {
// neither i1 nor i2 are nuclei
}
} else {
if (ref1 >= 0) {
// both are nuclei, i2 is overwritten with nucleus i1
// fNucleusRef stays the same, but A and Z data is overwritten
nuclearA_[ref2] = nuclearA_[ref1];
nuclearZ_[ref2] = nuclearZ_[ref1];
} else {
// i2 is overwritten with non-nucleus i1
nucleusRef_[i2] = -1; // flag as non-nucleus
nuclearA_.erase(nuclearA_.cbegin() + ref2); // remove data for i2
nuclearZ_.erase(nuclearZ_.cbegin() + ref2); // remove data for i2
const int n = nucleusRef_.size(); // update fNucleusRef: indices above ref2
// must be decremented by 1
for (int i = 0; i < n; ++i) {
if (nucleusRef_[i] > ref2) { nucleusRef_[i] -= 1; }
}
}
}
}
template <typename InnerStackImpl>
void NuclearStackExtensionImpl<InnerStackImpl>::clear() {
super_type::clear();
nucleusRef_.clear();
nuclearA_.clear();
nuclearZ_.clear();
}
template <typename InnerStackImpl>
void NuclearStackExtensionImpl<InnerStackImpl>::swap(const unsigned int i1, const unsigned int i2) {
// index range check
if (i1 >= getSize() || i2 >= getSize()) {
std::ostringstream err;
err << "NuclearStackExtension: trying to access data beyond size of stack!";
throw std::runtime_error(err.str());
}
// swap original particle data
super_type::swap(i1, i2);
// swap corresponding nuclear reference data
std::swap(nucleusRef_[i2], nucleusRef_[i1]);
}
template <typename InnerStackImpl>
void NuclearStackExtensionImpl<InnerStackImpl>::incrementSize() {
super_type::incrementSize();
nucleusRef_.push_back(-1);
}
template <typename InnerStackImpl>
void NuclearStackExtensionImpl<InnerStackImpl>::decrementSize() {
super_type::decrementSize();
if (nucleusRef_.size() > 0) {
const int ref = nucleusRef_.back();
nucleusRef_.pop_back();
if (ref >= 0) {
nuclearA_.erase(nuclearA_.begin() + ref);
nuclearZ_.erase(nuclearZ_.begin() + ref);
const int n = nucleusRef_.size();
for (int i = 0; i < n; ++i) {
if (nucleusRef_[i] >= ref) { nucleusRef_[i] -= 1; }
}
}
}
}
} // namespace corsika::nuclear_stack
......@@ -53,75 +53,15 @@ namespace corsika::nuclear_stack {
unsigned short, unsigned short>
altenative_particle_data_type;
void setParticleData(particle_data_type const& v) {
void setParticleData(particle_data_type const& v) ;
if (std::get<0>(v) == Code::Nucleus) {
std::ostringstream err;
err << "NuclearStackExtension: no A and Z specified for new Nucleus!";
throw std::runtime_error(err.str());
}
void setParticleData(altenative_particle_data_type const& v);
super_type::setParticleData(v);
setNucleusRef(-1); // this is not a nucleus
}
void setParticleData(altenative_particle_data_type const& v) {
const unsigned short A = std::get<5>(v);
const unsigned short Z = std::get<6>(v);
if (std::get<0>(v) != Code::Nucleus || A == 0 || Z == 0) {
std::ostringstream err;
err << "NuclearStackExtension: no A and Z specified for new Nucleus!";
throw std::runtime_error(err.str());
}
setNucleusRef(
super_type::getStackData().getNucleusNextRef()); // store this nucleus data ref
setNuclearA(A);
setNuclearZ(Z);
super_type::setParticleData(particle_data_type{std::get<0>(v), std::get<1>(v),
std::get<2>(v), std::get<3>(v),
std::get<4>(v)});
}
void setParticleData(super_type& p, particle_data_type const& v) {
if (std::get<0>(v) == Code::Nucleus) {
std::ostringstream err;
err << "NuclearStackExtension: no A and Z specified for new Nucleus!";
throw std::runtime_error(err.str());
}
super_type::setParticleData(
p, particle_data_type{std::get<0>(v), std::get<1>(v), std::get<2>(v),
std::get<3>(v), std::get<4>(v)});
setNucleusRef(-1); // this is not a nucleus
}
void setParticleData(super_type& p, altenative_particle_data_type const& v) {
const unsigned short A = std::get<5>(v);
const unsigned short Z = std::get<6>(v);
void setParticleData(super_type& p, particle_data_type const& v);
if (std::get<0>(v) != Code::Nucleus || A == 0 || Z == 0) {
std::ostringstream err;
err << "NuclearStackExtension: no A and Z specified for new Nucleus!";
throw std::runtime_error(err.str());
}
void setParticleData(super_type& p, altenative_particle_data_type const& v);
setNucleusRef(
super_type::getStackData().getNucleusNextRef()); // store this nucleus data ref
setNuclearA(A);
setNuclearZ(Z);
super_type::setParticleData(
p, particle_data_type{std::get<0>(v), std::get<1>(v), std::get<2>(v),
std::get<3>(v), std::get<4>(v)});
}
std::string as_string() const {
return fmt::format(
"{}, nuc({})", super_type::as_string(),
(isNucleus() ? fmt::format("A={}, Z={}", getNuclearA(), getNuclearZ())
: "n/a"));
}
std::string as_string() const;
/**
* @name individual setters
......@@ -150,18 +90,11 @@ namespace corsika::nuclear_stack {
/**
* Overwrite normal getParticleMass function with nuclear version
*/
HEPMassType getMass() const {
if (super_type::getPID() == Code::Nucleus)
return getNucleusMass(getNuclearA(), getNuclearZ());
return super_type::getMass();
}
HEPMassType getMass() const;
/**
* Overwirte normal getChargeNumber function with nuclear version
**/
int16_t getChargeNumber() const {
if (super_type::getPID() == Code::Nucleus) return getNuclearZ();
return super_type::getChargeNumber();
}
int16_t getChargeNumber() const;
int getNucleusRef() const {
return super_type::getStackData().getNucleusRef(super_type::getIndex());
......@@ -215,12 +148,7 @@ namespace corsika::nuclear_stack {
void dump() { super_type::dump(); }
void clear() {
super_type::clear();
nucleusRef_.clear();
nuclearA_.clear();
nuclearZ_.clear();
}
void clear();
unsigned int getSize() const { return nucleusRef_.size(); }
......@@ -241,101 +169,24 @@ namespace corsika::nuclear_stack {
int getNuclearZ(const unsigned int i) const { return nuclearZ_[getNucleusRef(i)]; }
// this function will create new storage for Nuclear Properties, and return the
// reference to it
int getNucleusNextRef() {
nuclearA_.push_back(0);
nuclearZ_.push_back(0);
return nuclearA_.size() - 1;
}
int getNucleusNextRef() ;
int getNucleusRef(const unsigned int i) const {
if (nucleusRef_[i] >= 0) return nucleusRef_[i];
std::ostringstream err;
err << "NuclearStackExtension: no nucleus at ref=" << i;
throw std::runtime_error(err.str());
}
int getNucleusRef(const unsigned int i) const;
bool isNucleus(const unsigned int i) const { return nucleusRef_[i] >= 0; }
/**
* Function to copy particle at location i1 in stack to i2
*/
void copy(const unsigned int i1, const unsigned int i2) {
// index range check
if (i1 >= getSize() || i2 >= getSize()) {
std::ostringstream err;
err << "NuclearStackExtension: trying to access data beyond size of stack!";
throw std::runtime_error(err.str());
}
// copy internal particle data p[i2] = p[i1]
super_type::copy(i1, i2);
// check if any of p[i1] or p[i2] was a Code::Nucleus
const int ref1 = nucleusRef_[i1];
const int ref2 = nucleusRef_[i2];
if (ref2 < 0) {
if (ref1 >= 0) {
// i1 is nucleus, i2 is not
nucleusRef_[i2] = getNucleusNextRef();
nuclearA_[nucleusRef_[i2]] = nuclearA_[ref1];
nuclearZ_[nucleusRef_[i2]] = nuclearZ_[ref1];
} else {
// neither i1 nor i2 are nuclei
}
} else {
if (ref1 >= 0) {
// both are nuclei, i2 is overwritten with nucleus i1
// fNucleusRef stays the same, but A and Z data is overwritten
nuclearA_[ref2] = nuclearA_[ref1];
nuclearZ_[ref2] = nuclearZ_[ref1];
} else {
// i2 is overwritten with non-nucleus i1
nucleusRef_[i2] = -1; // flag as non-nucleus
nuclearA_.erase(nuclearA_.cbegin() + ref2); // remove data for i2
nuclearZ_.erase(nuclearZ_.cbegin() + ref2); // remove data for i2
const int n = nucleusRef_.size(); // update fNucleusRef: indices above ref2
// must be decremented by 1
for (int i = 0; i < n; ++i) {
if (nucleusRef_[i] > ref2) { nucleusRef_[i] -= 1; }
}
}
}
}
void copy(const unsigned int i1, const unsigned int i2) ;
/**
* Function to copy particle at location i2 in stack to i1
*/
void swap(const unsigned int i1, const unsigned int i2) {
// index range check
if (i1 >= getSize() || i2 >= getSize()) {
std::ostringstream err;
err << "NuclearStackExtension: trying to access data beyond size of stack!";
throw std::runtime_error(err.str());
}
// swap original particle data
super_type::swap(i1, i2);
// swap corresponding nuclear reference data
std::swap(nucleusRef_[i2], nucleusRef_[i1]);
}
void swap(const unsigned int i1, const unsigned int i2) ;
void incrementSize() {
super_type::incrementSize();
nucleusRef_.push_back(-1);
}
void incrementSize() ;
void decrementSize() {
super_type::decrementSize();
if (nucleusRef_.size() > 0) {
const int ref = nucleusRef_.back();
nucleusRef_.pop_back();
if (ref >= 0) {
nuclearA_.erase(nuclearA_.begin() + ref);
nuclearZ_.erase(nuclearZ_.begin() + ref);
const int n = nucleusRef_.size();
for (int i = 0; i < n; ++i) {
if (nucleusRef_[i] >= ref) { nucleusRef_[i] -= 1; }
}
}
}
}
void decrementSize() ;
private:
/// the actual memory to store particle data
......@@ -361,3 +212,5 @@ namespace corsika::nuclear_stack {
ExtendedParticleInterfaceType>;
} // namespace corsika::nuclear_stack
#include <corsika/detail/stack/NuclearStackExtension.inl>
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