// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // $Id: G4QLowEnergy.cc,v 1.5 2010/06/14 16:11:27 mkossov Exp $ // GEANT4 tag $Name: hadr-chips-V09-03-08 $ // // ---------------- G4QLowEnergy class ----------------- // by Mikhail Kossov, Aug 2007. // G4QLowEnergy class of the CHIPS Simulation Branch in GEANT4 // --------------------------------------------------------------- // Short description: This is a fast low energy algorithm for the // inelastic interactions of nucleons and nuclei (ions) with nuclei. // This is a fase-space algorithm, but not quark level. Provides // nuclear fragments upto alpha only. Never was tumed (but can be). // --------------------------------------------------------------- //#define debug //#define pdebug //#define edebug //#define tdebug //#define nandebug //#define ppdebug #include "G4QLowEnergy.hh" // Initialization of static vectors G4int G4QLowEnergy::nPartCWorld=152; // #of particles initialized in CHIPS std::vector G4QLowEnergy::ElementZ; // Z of element(i) in theLastCalc std::vector G4QLowEnergy::ElProbInMat; // SumProbOfElem in Material std::vector*> G4QLowEnergy::ElIsoN;// N of isotope(j), E(i) std::vector*>G4QLowEnergy::IsoProbInEl;//SumProbIsotE(i) // Constructor G4QLowEnergy::G4QLowEnergy(const G4String& processName): G4VDiscreteProcess(processName, fHadronic), evaporate(true) { #ifdef debug G4cout<<"G4QLowEnergy::Constructor is called processName="<0) G4cout<GetParticles(nPartCWorld); // Create CHIPS World (234 part. max) } // Destructor G4QLowEnergy::~G4QLowEnergy() {} G4LorentzVector G4QLowEnergy::GetEnegryMomentumConservation(){return EnMomConservation;} G4int G4QLowEnergy::GetNumberOfNeutronsInTarget() {return nOfNeutrons;} // output of the function must be in units of length! L=1/sig_V,sig_V=SUM(n(j,i)*sig(j,i)), // where n(i,j) is a number of nuclei of the isotop j of the element i in V=1(lengtUnit^3) // ********** All CHIPS cross sections are calculated in the surface units ************ G4double G4QLowEnergy::GetMeanFreePath(const G4Track&Track, G4double, G4ForceCondition*F) { *F = NotForced; const G4DynamicParticle* incidentParticle = Track.GetDynamicParticle(); G4ParticleDefinition* incidentParticleDefinition=incidentParticle->GetDefinition(); if( !IsApplicable(*incidentParticleDefinition)) G4cout<<"-Warning-G4QLowEnergy::GetMeanFreePath for notImplemented Particle"<GetTotalMomentum(); // 3-momentum of the Particle #ifdef debug G4double KinEn = incidentParticle->GetKineticEnergy(); G4cout<<"G4QLowEnergy::GetMeanFreePath:Prpj, kinE="<(incidentParticleDefinition->GetPDGCharge()); G4int A=incidentParticleDefinition->GetBaryonNumber(); if ( incidentParticleDefinition == G4Proton::Proton() ) pPDG = 2212; else if ( incidentParticleDefinition == G4Deuteron::Deuteron() ) pPDG = 1000010020; else if ( incidentParticleDefinition == G4Alpha::Alpha() ) pPDG = 1000020040; else if ( incidentParticleDefinition == G4Triton::Triton() ) pPDG = 1000010030; else if ( incidentParticleDefinition == G4He3::He3() ) pPDG = 1000020030; else if ( incidentParticleDefinition == G4GenericIon::GenericIon() || (Z > 0 && A > 0)) { pPDG=incidentParticleDefinition->GetPDGEncoding(); #ifdef debug G4int prPDG=1000000000+10000*A+10*Z; G4cout<<"G4QIonIonElastic::GetMeanFreePath: PDG="<GetBaryonNumber(); // Divide Mom by projectile A G4QIsotope* Isotopes = G4QIsotope::Get(); // Pointer to the G4QIsotopes singleton G4double sigma=0.; // Sums over elements for the material G4int IPIE=IsoProbInEl.size(); // How many old elements? if(IPIE) for(G4int ip=0; ip* SPI=IsoProbInEl[ip]; // Pointer to the SPI vector SPI->clear(); delete SPI; std::vector* IsN=ElIsoN[ip]; // Pointer to the N vector IsN->clear(); delete IsN; } ElProbInMat.clear(); // Clean up the SumProb's of Elements (SPE) ElementZ.clear(); // Clear the body vector for Z of Elements IsoProbInEl.clear(); // Clear the body vector for SPI ElIsoN.clear(); // Clear the body vector for N of Isotopes for(G4int i=0; i(pElement->GetZ()); // Z of the Element ElementZ.push_back(Z); // Remember Z of the Element G4int isoSize=0; // The default for the isoVectorLength is 0 G4int indEl=0; // Index of non-natural element or 0(default) G4IsotopeVector* isoVector=pElement->GetIsotopeVector(); // Get the predefined IsoVect if(isoVector) isoSize=isoVector->size();// Get size of the existing isotopeVector #ifdef debug G4cout<<"G4QLowEnergy::GetMeanFreePath: isovector Length="<GetIndex()+1; // Index of the non-trivial element is an order #ifdef debug G4cout<<"G4QLowEn::GetMFP:iE="<IsDefined(Z,indEl)<IsDefined(Z,indEl)) // This index is not defined for this Z: define { std::vector*>* newAbund = new std::vector*>; G4double* abuVector=pElement->GetRelativeAbundanceVector(); for(G4int j=0; jGetIsotope(j)->GetN()-Z; // N means A=N+Z ! if(pElement->GetIsotope(j)->GetZ()!=Z)G4cerr<<"G4QDiffract::GetMeanFreePath: Z=" <GetIsotope(j)->GetZ()<<"#"<* pr= new std::pair(N,abund); #ifdef debug G4cout<<"G4QLowEnergy::GetMeanFreePath:pair#"<push_back(pr); } #ifdef debug G4cout<<"G4QLowEnergy::GetMeanFreePath: pairVectLength="<size()<InitElement(Z,indEl,newAbund); // definition of the newInd for(G4int k=0; k*>* cs= Isotopes->GetCSVector(Z,indEl);//CSPointer std::vector* SPI = new std::vector; // Pointer to the SPI vector IsoProbInEl.push_back(SPI); std::vector* IsN = new std::vector; // Pointer to the N vector ElIsoN.push_back(IsN); G4int nIs=cs->size(); // A#Of Isotopes in the Element #ifdef debug G4cout<<"G4QLowEnergy::GetMFP:***=>,#isot="<="<GetMeanCrossSection(Z,indEl) <<",AddSigm="<GetMeanCrossSection(Z,indEl)*NOfNucPerVolume[i]<>G4QLowEnergy::IsApplicable: projPDG="< result; G4LorentzVector proj4M=(projHadron->Get4Momentum())/MeV; // Convert to MeV! G4double momentum = projHadron->GetTotalMomentum()/MeV; // 3-momentum of the Proj in MeV G4double Momentum = proj4M.rho(); // @@ Just for the test purposes if(std::fabs(Momentum-momentum)>.000001) G4cerr<<"-Warning-G4QLowEnergy::PostStepDoIt:P_IU="<GetElementVector(); G4int nE=material->GetNumberOfElements(); #ifdef debug G4cout<<"G4QLowEnergy::PostStepDoIt: "<(particle->GetPDGCharge()); G4int A=particle->GetBaryonNumber(); if (particle == G4Proton::Proton() ) projPDG= 2212; else if (particle == G4Neutron::Neutron() ) projPDG= 2112; else if (particle == G4Deuteron::Deuteron() ) projPDG= 1000010020; else if (particle == G4Alpha::Alpha() ) projPDG= 1000020040; else if (particle == G4Triton::Triton() ) projPDG= 1000010030; else if (particle == G4He3::He3() ) projPDG= 1000020030; else if (particle == G4GenericIon::GenericIon() || (Z > 0 && A > 0)) { projPDG=particle->GetPDGEncoding(); #ifdef debug G4int prPDG=1000000000+10000*Z+10*A; G4cout<<"G4QLowEnergy::PostStepDoIt: PDG="<GetPDGEncoding(); G4cout<<"G4QLowEnergy::PostStepDoIt: projPDG="<ret 0"<size(); // #of isotopes in the element i #ifdef debug G4cout<<"G4QLowEnergy::PostStepDoIt: nI="<N="<GetQuarkContent(3)-particle->GetAntiQuarkContent(3); // Strangeness G4int pZ=static_cast(particle->GetPDGCharge()); // Charge of the projectile G4int pN=particle->GetBaryonNumber()-pZ-pL;// #of neutrons in projectile G4double pM=targQPDG.GetNuclMass(pZ,pN,0); // CHIPS projectile nucleus mass in MeV G4double cosp=-14*Momentum*(tM-pM)/tM/pM; // Asymmetry power for angular distribution #ifdef debug G4cout<<"G4QLowEnergy::PoStDoIt: Proj("<G4QLEn::PSDI:#"<ProjQFSA="<SetWeight(weight); // weighted aNucTrack->SetTouchableHandle(trTouchable); #ifdef pdebug G4cout<<"G4QLowEn::PSDI:-->TgQFNPDG="<A+A,t="<? 2*MAlpha="<<2*mAlph<SetWeight(weight); // weighted aFraTrack->SetTouchableHandle(trTouchable); #ifdef pdebug G4cout<<"G4QLowEn::PSDI:-->TgRQFA4M="<N+A,t="<? MA+MN="<SetWeight(weight); // weighted aFraTrack->SetTouchableHandle(trTouchable); #ifdef pdebug G4cout<<"G4QLowEn::PSDI:-->TgQFRN4M="<FindIon(tZ,tB,0,tZ); ++nSec; #ifdef pdebug G4cout<<"G4QLowEn::PSDI:-->PQF_nSec="<SetWeight(weight); // weighted aResTrack->SetTouchableHandle(trTouchable); #ifdef pdebug G4cout<<"G4QLowEn::PSDI:-->TgR4M="<TargQFSA="<SetWeight(weight); // weighted aNucTrack->SetTouchableHandle(trTouchable); #ifdef pdebug G4cout<<"G4QLowEn::PSDI:-->PrQFNPDG="<A+A,t="<? 2*MAlpha="<<2*mAlph<SetWeight(weight); // weighted aFraTrack->SetTouchableHandle(trTouchable); #ifdef pdebug G4cout<<"G4QLowEn::PSDI:-->PrRQFA4M="<N+A,t="<? MA+MN="<SetWeight(weight); // weighted aFraTrack->SetTouchableHandle(trTouchable); #ifdef pdebug G4cout<<"G4QLowEn::PSDI:-->PrQFRN4M="<FindIon(pZ,pB,0,pZ); ++nSec; #ifdef pdebug G4cout<<"G4QLowEn::PSDI:-->TQF_nSec="<SetWeight(weight); // weighted aResTrack->SetTouchableHandle(trTouchable); #ifdef pdebug G4cout<<"G4QLowEn::PSDI:-->TgR4M="<n+n,nn="<? 2*MNeutron="<<2*mNeutron<n+n,t="<? 2*Neutron="<<2*mAlph<SetWeight(weight); // weighted aFraPTrack->SetTouchableHandle(trTouchable); tt4M-=f4M; #ifdef edebug totBaN-=2; tch4M -=f4M; G4cout<<">>G4QLEn::PSDI:n,tZ="<ProjSpectA4M="<2 && rpZ==0) // Z=0 decay { theDefinition = aNeutron; G4LorentzVector f4M=rp4M/rpA; // 4mom of 1st neutron #ifdef pdebug G4cout<<"G4QLE::CPS->Nn,M="<? N*MNeutron="<SetWeight(weight); // weighted aNTrack->SetTouchableHandle(trTouchable); result.push_back(aNTrack); } G4int nesc = rpA-1; tt4M-=f4M*nesc; #ifdef edebug totBaN-=nesc; tch4M -=f4M*nesc; G4cout<<">G4QLEn::PSDI:Nn,tZ="<ProjSpectA4M="<A+A,mBe8="<? 2*MAlpha="<<2*mAlph<A+A,t="<? 2*MAlpha="<<2*mAlph<SetWeight(weight); // weighted aFraPTrack->SetTouchableHandle(trTouchable); tt4M-=f4M; #ifdef edebug totChg-=2; totBaN-=4; tch4M -=f4M; G4cout<<">>G4QLEn::PSDI:1,tZ="<ProjSpectA4M="<N+A, tM5="<? MA+MN="<N+A,t="<? MA+MN="<SetWeight(weight); // weighted aFraPTrack->SetTouchableHandle(trTouchable); tt4M-=f4M; #ifdef edebug if(theDefinition == aProton) totChg-=1; totBaN-=1; tch4M -=f4M; G4cout<<">>G4QLEn::PSDI:2,tZ="<ProjSpectN4M="<FindIon(rpZ,rpA,0,rpZ); if(!theDefinition) G4cout<<"-Warning-G4QLowEn::PSDI: pDef=0, Z="<>G4QLEn::PSDI:3, tZ="<ProjSpectR4M="<A+A,mBe8="<? 2*MAlpha="<<2*mAlph<A+A,t="<? 2*MAlpha="<<2*mAlph<SetWeight(weight); // weighted aFraTTrack->SetTouchableHandle(trTouchable); tt4M-=f4M; #ifdef edebug totChg-=2; totBaN-=4; tch4M -=f4M; G4cout<<">>G4QLEn::PSDI:4,tZ="<TargSpectA4M="<N+A, tM5="<? MA+MN="<N+A,t="<? MA+MN="<SetWeight(weight); // weighted aFraTTrack->SetTouchableHandle(trTouchable); tt4M-=f4M; #ifdef edebug if(theDefinition == aProton) totChg-=1; totBaN-=1; tch4M -=f4M; G4cout<<">>G4QLEn::PSDI:5,tZ="<TargSpectN4M="<FindIon(rtZ,rtA,0,rtZ); if(!theDefinition) G4cout<<"-Warning-G4QLowEn::PSDI: tDef=0, Z="<>G4QLEn::PSDI:6, tZ="<TargSpectR4M="<>>G4QLEn::PSDI: dZ="<0) prL=pL/pA; G4double qval[nCh]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0., 0.,0.,0.,0.,0.,0.}; qval[ 0] = (totM - mass[ 0])/137./137.; qval[ 1] = (totM - mass[ 1] - mNeut)*prN/137.; qval[ 2] = (totM - mass[ 2] - mProt)*prZ/137.; qval[ 3] = (totM - mass[ 3] - mDeut)*prD/3./137.; qval[ 4] = (totM - mass[ 4] - mTrit)*prT/6./137.; qval[ 5] = (totM - mass[ 5] - mHel3)*prH/fhe3/137.; qval[ 6] = (totM - mass[ 6] - mAlph)*prA/9./137.; qval[ 7] = (totM - mass[ 7] - mNeut - mNeut)*prN*prN; qval[ 8] = (totM - mass[ 8] - mNeut - mProt)*prD; qval[ 9] = (totM - mass[ 9] - mProt - mProt)*prZ*prZ; qval[10] = (totM - mass[10] - mProt - mDeut)*prH/3.; qval[11] = (totM - mass[11] - mNeut - mDeut)*prT/3.; qval[12] = (totM - mass[12] - mDeut - mDeut)*prA/3./3.; qval[13] = (totM - mass[13] - mProt - mTrit)*prA/6.; qval[14] = (totM - mass[14] - mNeut - mTrit)*prT*prN/6.; qval[15] = (totM - mass[15] - mProt - mHel3)*prH*prZ/fhe3; qval[16] = (totM - mass[16] - mNeut - mHel3)*prA/fhe3; qval[17] = (totM - mass[17] - mProt - mAlph)*prZ*prA/9.; qval[18] = (totM - mass[18] - mNeut - mAlph)*prN*prA/9.; if(pZ>0) { qval[19] = (totM - mass[19] - mLamb)*prL; qval[20] = (totM - mass[20] - mProt - mLamb)*prL*prZ; qval[21] = (totM - mass[21] - mNeut - mLamb)*prL*prN; qval[22] = (totM - mass[22] - mDeut - mLamb)*prL*prD/2.; qval[23] = (totM - mass[23] - mTrit - mLamb)*prL*prT/3.; qval[24] = (totM - mass[24] - mHel3 - mLamb)*prL*prH/fhe3; qval[25] = (totM - mass[25] - mAlph - mLamb)*prL*prA/4; } #ifdef debug G4cout<<"G4QLowEn::PSDI: Q-values are calculated, tgA="<M1="<