/* EnergyLoss.cpp Code for calculating the energy loss of a charged, massive particle through an arbitrary medium. Based on code written by D.W. Visser at Yale for the original SPANC. Uses energy loss calulations described by Ziegler in various SRIM textbooks. Written by G.W. McCann Aug. 2020 */ #include "Eloss_Tables.h" #include "EnergyLoss.h" #include "KinematicsExceptions.h" #include EnergyLoss::EnergyLoss() { comp_denom = 0; ZP = -1; } EnergyLoss::~EnergyLoss() {} /*Targets are defined by their atomic number, total number of nucleons, and their stoichiometry within the target compound*/ void EnergyLoss::SetTargetComponents(std::vector& Zt, std::vector& At, std::vector& Stoich) { comp_denom = 0; ZT = Zt; AT = At; for(unsigned int i=0; i MAX_Z) { throw ELossException(); } } targ_composition.resize(Stoich.size()); for(unsigned int i=0; i MAX_FRACTIONAL_STEP && depth < MAX_DEPTH) { depth++; x_step *= 0.5; e_step = GetTotalStoppingPower(e_final)*x_step/1000.0; } else if((x_step + x_traversed) >= thickness) { //last chunk go = false; x_step = thickness - x_traversed; //get valid portion of last chunk e_final -= GetTotalStoppingPower(e_final)*x_step/1000.0; if(depth > 20)std::cout<<"depth: "< MAX_FRACTIONAL_STEP) { x_step *= 0.5; e_step = GetTotalStoppingPower(e_initial)*x_step/1000.0; } else if (x_traversed+x_step > thickness) { go = false; x_step = thickness - x_traversed; e_initial += GetTotalStoppingPower(e_initial)*x_step/1000.0; } else { x_traversed += x_step; e_step = GetTotalStoppingPower(e_initial)*x_step/1000.0; e_initial += e_step; } } return e_initial-e_final; } /* Returns units of keV/(ug/cm^2) Calculates Electronic stopping power by first calculating SE for hydrogen through the target and then using corrections to calculate SE for projectile of interest */ double EnergyLoss::GetElectronicStoppingPower(double energy) { //Wants in units of keV energy *= 1000.0; double e_per_u = energy/MP; std::vector values; if(e_per_u > MAX_H_E_PER_U) { throw ELossException(); } else if (e_per_u > 1000.0) { for(auto& z: ZT) { values.push_back(Hydrogen_dEdx_High(e_per_u, energy, z)); } } else if (e_per_u > 10.0) { for(auto& z: ZT) { values.push_back(Hydrogen_dEdx_Med(e_per_u, z)); } } else if (e_per_u > 0.0) { for(auto& z: ZT) { values.push_back(Hydrogen_dEdx_Low(e_per_u, z)); } } else { throw ELossException(); } if(values.size() == 0) { throw ELossException(); } if(ZP > 1) { //not hydrogen, need to account for effective charge for(unsigned int i=0; i