#include <G4QElastic.hh>
Inheritance diagram for G4QElastic:
Public Member Functions | |
G4QElastic (const G4String &processName="CHIPSElasticScattering") | |
~G4QElastic () | |
G4bool | IsApplicable (const G4ParticleDefinition &particle) |
G4double | GetMeanFreePath (const G4Track &aTrack, G4double previousStepSize, G4ForceCondition *condition) |
G4VParticleChange * | PostStepDoIt (const G4Track &aTrack, const G4Step &aStep) |
G4LorentzVector | GetEnegryMomentumConservation () |
G4int | GetNumberOfNeutronsInTarget () |
Definition at line 69 of file G4QElastic.hh.
G4QElastic::G4QElastic | ( | const G4String & | processName = "CHIPSElasticScattering" |
) |
Definition at line 56 of file G4QElastic.cc.
References G4cout, G4endl, G4HadronicDeprecate, G4VProcess::GetProcessName(), and G4VProcess::verboseLevel.
00056 : 00057 G4VDiscreteProcess(processName, fHadronic) 00058 { 00059 G4HadronicDeprecate("G4QElastic"); 00060 00061 #ifdef debug 00062 G4cout<<"G4QElastic::Constructor is called processName="<<processName<<G4endl; 00063 #endif 00064 if (verboseLevel>0) G4cout << GetProcessName() << " process is created "<< G4endl; 00065 //G4QCHIPSWorld::Get()->GetParticles(nPartCWorld); // Create CHIPS World (234 part. max) 00066 }
G4QElastic::~G4QElastic | ( | ) |
G4LorentzVector G4QElastic::GetEnegryMomentumConservation | ( | ) |
G4double G4QElastic::GetMeanFreePath | ( | const G4Track & | aTrack, | |
G4double | previousStepSize, | |||
G4ForceCondition * | condition | |||
) | [virtual] |
Implements G4VDiscreteProcess.
Definition at line 79 of file G4QElastic.cc.
References G4AntiLambda::AntiLambda(), G4AntiNeutron::AntiNeutron(), G4AntiOmegaMinus::AntiOmegaMinus(), G4AntiProton::AntiProton(), G4AntiSigmaMinus::AntiSigmaMinus(), G4AntiSigmaPlus::AntiSigmaPlus(), G4AntiSigmaZero::AntiSigmaZero(), G4AntiXiMinus::AntiXiMinus(), G4AntiXiZero::AntiXiZero(), DBL_MAX, G4cerr, G4cout, G4endl, G4QIsotope::Get(), G4VQCrossSection::GetCrossSection(), G4QIsotope::GetCSVector(), G4DynamicParticle::GetDefinition(), G4Track::GetDynamicParticle(), G4Material::GetElementVector(), G4DynamicParticle::GetKineticEnergy(), G4Track::GetMaterial(), G4QIsotope::GetMeanCrossSection(), G4Material::GetNumberOfElements(), G4ParticleDefinition::GetParticleName(), G4QAntiBaryonElasticCrossSection::GetPointer(), G4QHyperonElasticCrossSection::GetPointer(), G4QHyperonPlusElasticCrossSection::GetPointer(), G4QKaonMinusElasticCrossSection::GetPointer(), G4QKaonPlusElasticCrossSection::GetPointer(), G4QPionMinusElasticCrossSection::GetPointer(), G4QPionPlusElasticCrossSection::GetPointer(), G4QNeutronElasticCrossSection::GetPointer(), G4QProtonElasticCrossSection::GetPointer(), G4DynamicParticle::GetTotalMomentum(), G4Material::GetVecNbOfAtomsPerVolume(), G4QIsotope::InitElement(), IsApplicable(), G4QIsotope::IsDefined(), G4KaonMinus::KaonMinus(), G4KaonPlus::KaonPlus(), G4KaonZeroLong::KaonZeroLong(), G4KaonZeroShort::KaonZeroShort(), G4Lambda::Lambda(), G4Neutron::Neutron(), NotForced, G4OmegaMinus::OmegaMinus(), G4PionMinus::PionMinus(), G4PionPlus::PionPlus(), G4Proton::Proton(), G4SigmaMinus::SigmaMinus(), G4SigmaPlus::SigmaPlus(), G4SigmaZero::SigmaZero(), G4XiMinus::XiMinus(), and G4XiZero::XiZero().
Referenced by PostStepDoIt().
00080 { 00081 *Fc = NotForced; 00082 const G4DynamicParticle* incidentParticle = aTrack.GetDynamicParticle(); 00083 G4ParticleDefinition* incidentParticleDefinition=incidentParticle->GetDefinition(); 00084 if( !IsApplicable(*incidentParticleDefinition)) 00085 G4cout<<"*W*G4QElastic::GetMeanFreePath: is called for notImplementedParticle"<<G4endl; 00086 // Calculate the mean Cross Section for the set of Elements(*Isotopes) in the Material 00087 G4double Momentum = incidentParticle->GetTotalMomentum(); // 3-momentum of the Particle 00088 #ifdef debug 00089 G4double KinEn = incidentParticle->GetKineticEnergy(); 00090 G4cout<<"G4QElastic::GetMeanFreePath: kinE="<<KinEn<<",Mom="<<Momentum<<G4endl; // Result 00091 #endif 00092 const G4Material* material = aTrack.GetMaterial(); // Get the current material 00093 const G4double* NOfNucPerVolume = material->GetVecNbOfAtomsPerVolume(); 00094 const G4ElementVector* theElementVector = material->GetElementVector(); 00095 G4int nE=material->GetNumberOfElements(); 00096 G4int pPDG=0; 00097 if (incidentParticleDefinition == G4Proton::Proton() ) pPDG=2212; 00098 else if(incidentParticleDefinition == G4Neutron::Neutron() ) pPDG=2112; 00099 else if(incidentParticleDefinition == G4PionPlus::PionPlus() ) pPDG= 211; 00100 else if(incidentParticleDefinition == G4PionMinus::PionMinus() ) pPDG=-211; 00101 else if(incidentParticleDefinition == G4KaonPlus::KaonPlus() ) pPDG= 321; 00102 else if(incidentParticleDefinition == G4KaonMinus::KaonMinus() ) pPDG=-321; 00103 else if(incidentParticleDefinition == G4KaonZeroLong::KaonZeroLong() ) pPDG= 130; 00104 else if(incidentParticleDefinition == G4KaonZeroShort::KaonZeroShort() ) pPDG= 310; 00105 else if(incidentParticleDefinition == G4Lambda::Lambda() ) pPDG= 3122; 00106 else if(incidentParticleDefinition == G4SigmaPlus::SigmaPlus() ) pPDG= 3222; 00107 else if(incidentParticleDefinition == G4SigmaMinus::SigmaMinus() ) pPDG= 3112; 00108 else if(incidentParticleDefinition == G4SigmaZero::SigmaZero() ) pPDG= 3212; 00109 else if(incidentParticleDefinition == G4XiMinus::XiMinus() ) pPDG= 3312; 00110 else if(incidentParticleDefinition == G4XiZero::XiZero() ) pPDG= 3322; 00111 else if(incidentParticleDefinition == G4OmegaMinus::OmegaMinus() ) pPDG= 3334; 00112 else if(incidentParticleDefinition == G4AntiNeutron::AntiNeutron() ) pPDG=-2112; 00113 else if(incidentParticleDefinition == G4AntiProton::AntiProton() ) pPDG=-2212; 00114 else if(incidentParticleDefinition == G4AntiLambda::AntiLambda() ) pPDG=-3122; 00115 else if(incidentParticleDefinition == G4AntiSigmaPlus::AntiSigmaPlus() ) pPDG=-3222; 00116 else if(incidentParticleDefinition == G4AntiSigmaMinus::AntiSigmaMinus() ) pPDG=-3112; 00117 else if(incidentParticleDefinition == G4AntiSigmaZero::AntiSigmaZero() ) pPDG=-3212; 00118 else if(incidentParticleDefinition == G4AntiXiMinus::AntiXiMinus() ) pPDG=-3312; 00119 else if(incidentParticleDefinition == G4AntiXiZero::AntiXiZero() ) pPDG=-3322; 00120 else if(incidentParticleDefinition == G4AntiOmegaMinus::AntiOmegaMinus() ) pPDG=-3334; 00121 else G4cout<<"Warning-G4QElastic::GetMFP:"<<incidentParticleDefinition->GetParticleName() 00122 <<" isn't implemented (only SU(3) particles)"<<G4endl; 00123 #ifdef pdebug 00124 G4cout<<"G4QElastic::GetMeanFreePath:"<<nE<<" Elem's in theMaterial,proj="<<pPDG<<G4endl; 00125 #endif 00126 G4VQCrossSection* CSmanager=0; 00127 G4VQCrossSection* CSmanager2=0; 00128 if (pPDG==2212) CSmanager=G4QProtonElasticCrossSection::GetPointer(); 00129 else if(pPDG==2112) CSmanager=G4QNeutronElasticCrossSection::GetPointer(); 00130 else if(pPDG== 211) CSmanager=G4QPionPlusElasticCrossSection::GetPointer(); 00131 else if(pPDG==-211) CSmanager=G4QPionMinusElasticCrossSection::GetPointer(); 00132 else if(pPDG== 321) CSmanager=G4QKaonPlusElasticCrossSection::GetPointer(); 00133 else if(pPDG==-321) CSmanager=G4QKaonMinusElasticCrossSection::GetPointer(); 00134 else if(pPDG== 130 || pPDG== 310) 00135 { 00136 CSmanager=G4QKaonMinusElasticCrossSection::GetPointer(); 00137 CSmanager2=G4QKaonPlusElasticCrossSection::GetPointer(); 00138 } 00139 else if(pPDG==3222) CSmanager=G4QHyperonPlusElasticCrossSection::GetPointer(); 00140 else if(pPDG>3110 && pPDG<3335) CSmanager=G4QHyperonElasticCrossSection::GetPointer(); 00141 else if(pPDG>-3335&&pPDG<-1110) CSmanager=G4QAntiBaryonElasticCrossSection::GetPointer(); 00142 else G4cout<<"*Warning*G4QElastic::GetMeanFreePath: wrong PDG="<<pPDG<<G4endl; 00143 G4QIsotope* Isotopes = G4QIsotope::Get(); // Pointer to the G4QIsotopes singleton 00144 G4double sigma=0.; // Sums over elements for the material 00145 G4int IPIE=IsoProbInEl.size(); // How many old elements? 00146 if(IPIE) for(G4int ip=0; ip<IPIE; ++ip) // Clean up the SumProb's of Isotopes (SPI) 00147 { 00148 std::vector<G4double>* SPI=IsoProbInEl[ip]; // Pointer to the SPI vector 00149 SPI->clear(); 00150 delete SPI; 00151 std::vector<G4int>* IsN=ElIsoN[ip]; // Pointer to the N vector 00152 IsN->clear(); 00153 delete IsN; 00154 } 00155 ElProbInMat.clear(); // Clean up the SumProb's of Elements (SPE) 00156 ElementZ.clear(); // Clear the body vector for Z of Elements 00157 IsoProbInEl.clear(); // Clear the body vector for SPI 00158 ElIsoN.clear(); // Clear the body vector for N of Isotopes 00159 for(G4int i=0; i<nE; ++i) 00160 { 00161 G4Element* pElement=(*theElementVector)[i]; // Pointer to the current element 00162 G4int Z = static_cast<G4int>(pElement->GetZ()); // Z of the Element 00163 ElementZ.push_back(Z); // Remember Z of the Element 00164 G4int isoSize=0; // The default for the isoVectorLength is 0 00165 G4int indEl=0; // Index of non-natural element or 0(default) 00166 G4IsotopeVector* isoVector=pElement->GetIsotopeVector(); // Get the predefined IsoVect 00167 if(isoVector) isoSize=isoVector->size();// Get size of the existing isotopeVector 00168 #ifdef debug 00169 G4cout<<"G4QElastic::GetMeanFreePath: isovectorLength="<<isoSize<<G4endl; // Result 00170 #endif 00171 if(isoSize) // The Element has non-trivial abundance set 00172 { 00173 indEl=pElement->GetIndex()+1; // Index of the non-trivial element is an order 00174 #ifdef debug 00175 G4cout<<"G4QEl::GetMFP: iE="<<indEl<<", def="<<Isotopes->IsDefined(Z,indEl)<<G4endl; 00176 #endif 00177 if(!Isotopes->IsDefined(Z,indEl)) // This index is not defined for this Z: define 00178 { 00179 std::vector<std::pair<G4int,G4double>*>* newAbund = 00180 new std::vector<std::pair<G4int,G4double>*>; 00181 G4double* abuVector=pElement->GetRelativeAbundanceVector(); 00182 for(G4int j=0; j<isoSize; j++) // Calculation of abundance vector for isotopes 00183 { 00184 G4int N=pElement->GetIsotope(j)->GetN()-Z; // N means A=N+Z ! 00185 if(pElement->GetIsotope(j)->GetZ()!=Z)G4cerr<<"G4QElastic::GetMeanFreePath: Z=" 00186 <<pElement->GetIsotope(j)->GetZ()<<"#"<<Z<<G4endl; 00187 G4double abund=abuVector[j]; 00188 std::pair<G4int,G4double>* pr= new std::pair<G4int,G4double>(N,abund); 00189 #ifdef debug 00190 G4cout<<"G4QElastic::GetMeanFreePath:pair#="<<j<<",N="<<N<<",ab="<<abund<<G4endl; 00191 #endif 00192 newAbund->push_back(pr); 00193 } 00194 #ifdef debug 00195 G4cout<<"G4QElastic::GetMeanFreePath: pairVectorLength="<<newAbund->size()<<G4endl; 00196 #endif 00197 indEl=G4QIsotope::Get()->InitElement(Z,indEl,newAbund); // definition of the newInd 00198 for(G4int k=0; k<isoSize; k++) delete (*newAbund)[k]; // Cleaning temporary 00199 delete newAbund; // Was "new" in the beginning of the name space 00200 } 00201 } 00202 std::vector<std::pair<G4int,G4double>*>* cs= Isotopes->GetCSVector(Z,indEl);//CSPointer 00203 std::vector<G4double>* SPI = new std::vector<G4double>; // Pointer to the SPI vector 00204 IsoProbInEl.push_back(SPI); 00205 std::vector<G4int>* IsN = new std::vector<G4int>; // Pointer to the N vector 00206 ElIsoN.push_back(IsN); 00207 G4int nIs=cs->size(); // A#Of Isotopes in the Element 00208 #ifdef debug 00209 G4cout<<"G4QEl::GMFP:=***=>,#isot="<<nIs<<", Z="<<Z<<", indEl="<<indEl<<G4endl; 00210 #endif 00211 G4double susi=0.; // sum of CS over isotopes 00212 if(nIs) for(G4int j=0; j<nIs; j++) // Calculate CS for eachIsotope of El 00213 { 00214 std::pair<G4int,G4double>* curIs=(*cs)[j]; // A pointer, which is used twice 00215 G4int N=curIs->first; // #of Neuterons in the isotope j of El i 00216 IsN->push_back(N); // Remember Min N for the Element 00217 #ifdef debug 00218 G4cout<<"G4QEl::GMFP:*true*,P="<<Momentum<<",Z="<<Z<<",N="<<N<<",PDG="<<pPDG<<G4endl; 00219 #endif 00220 G4bool ccsf=true; 00221 if(Q==-27.) ccsf=false; 00222 #ifdef debug 00223 G4cout<<"G4QEl::GMFP: GetCS #1 j="<<j<<G4endl; 00224 #endif 00225 G4double CSI=0.; // Prototype of CS(j,i) for the isotope 00226 if(!CSmanager2) CSI=CSmanager->GetCrossSection(ccsf,Momentum,Z,N,pPDG); // CS(j,i) 00227 else CSI=(CSmanager->GetCrossSection(ccsf,Momentum,Z,N,-321)+ 00228 CSmanager2->GetCrossSection(ccsf,Momentum,Z,N,321) )/2.; // K0 00229 #ifdef debug 00230 G4cout<<"G4QEl::GMFP: jI="<<j<<", Zt="<<Z<<", Nt="<<N<<", Mom="<<Momentum<<", XSec=" 00231 <<CSI/millibarn<<G4endl; 00232 #endif 00233 curIs->second = CSI; 00234 susi+=CSI; // Make a sum per isotopes 00235 SPI->push_back(susi); // Remember summed cross-section 00236 } // End of temporary initialization of the cross sections in the G4QIsotope singeltone 00237 sigma+=Isotopes->GetMeanCrossSection(Z,indEl)*NOfNucPerVolume[i];//SUM(MeanCS*NOfNperV) 00238 #ifdef debug 00239 G4cout<<"G4QEl::GMFP: <S>="<<Isotopes->GetMeanCrossSection(Z,indEl)<<", AddToSigma=" 00240 <<Isotopes->GetMeanCrossSection(Z,indEl)*NOfNucPerVolume[i]<<G4endl; 00241 #endif 00242 ElProbInMat.push_back(sigma); 00243 } // End of LOOP over Elements 00244 // Check that cross section is not zero and return the mean free path 00245 #ifdef debug 00246 G4cout<<"G4QElastic::GetMeanFreePath: MeanFreePath="<<1./sigma<<G4endl; 00247 #endif 00248 if(sigma > 0.) return 1./sigma; // Mean path [distance] 00249 return DBL_MAX; 00250 }
G4int G4QElastic::GetNumberOfNeutronsInTarget | ( | ) |
G4bool G4QElastic::IsApplicable | ( | const G4ParticleDefinition & | particle | ) | [virtual] |
Reimplemented from G4VProcess.
Definition at line 253 of file G4QElastic.cc.
References G4AntiNeutrinoMu::AntiNeutrinoMu(), G4AntiNeutron::AntiNeutron(), G4AntiProton::AntiProton(), G4Electron::Electron(), G4cout, G4endl, G4Gamma::Gamma(), G4ParticleDefinition::GetPDGEncoding(), G4KaonMinus::KaonMinus(), G4KaonPlus::KaonPlus(), G4KaonZeroLong::KaonZeroLong(), G4KaonZeroShort::KaonZeroShort(), G4Lambda::Lambda(), G4MuonMinus::MuonMinus(), G4MuonPlus::MuonPlus(), G4NeutrinoMu::NeutrinoMu(), G4Neutron::Neutron(), G4OmegaMinus::OmegaMinus(), G4PionMinus::PionMinus(), G4PionPlus::PionPlus(), G4Positron::Positron(), G4Proton::Proton(), G4SigmaMinus::SigmaMinus(), G4SigmaPlus::SigmaPlus(), G4SigmaZero::SigmaZero(), G4TauMinus::TauMinus(), G4TauPlus::TauPlus(), G4XiMinus::XiMinus(), and G4XiZero::XiZero().
Referenced by GetMeanFreePath(), and PostStepDoIt().
00254 { 00255 if (particle == *( G4Proton::Proton() )) return true; 00256 else if (particle == *( G4Neutron::Neutron() )) return true; 00257 else if (particle == *( G4MuonMinus::MuonMinus() )) return true; 00258 else if (particle == *( G4TauPlus::TauPlus() )) return true; 00259 else if (particle == *( G4TauMinus::TauMinus() )) return true; 00260 else if (particle == *( G4Electron::Electron() )) return true; 00261 else if (particle == *( G4Positron::Positron() )) return true; 00262 else if (particle == *( G4Gamma::Gamma() )) return true; 00263 else if (particle == *( G4MuonPlus::MuonPlus() )) return true; 00264 else if (particle == *(G4AntiNeutrinoMu::AntiNeutrinoMu())) return true; 00265 else if (particle == *( G4NeutrinoMu::NeutrinoMu() )) return true; 00266 else if (particle == *( G4PionMinus::PionMinus() )) return true; 00267 else if (particle == *( G4PionPlus::PionPlus() )) return true; 00268 else if (particle == *( G4KaonPlus::KaonPlus() )) return true; 00269 else if (particle == *( G4KaonMinus::KaonMinus() )) return true; 00270 else if (particle == *( G4KaonZeroLong::KaonZeroLong() )) return true; 00271 else if (particle == *( G4KaonZeroShort::KaonZeroShort() )) return true; 00272 else if (particle == *( G4Lambda::Lambda() )) return true; 00273 else if (particle == *( G4SigmaPlus::SigmaPlus() )) return true; 00274 else if (particle == *( G4SigmaMinus::SigmaMinus() )) return true; 00275 else if (particle == *( G4SigmaZero::SigmaZero() )) return true; 00276 else if (particle == *( G4XiMinus::XiMinus() )) return true; 00277 else if (particle == *( G4XiZero::XiZero() )) return true; 00278 else if (particle == *( G4OmegaMinus::OmegaMinus() )) return true; 00279 else if (particle == *( G4AntiNeutron::AntiNeutron() )) return true; 00280 else if (particle == *( G4AntiProton::AntiProton() )) return true; 00281 #ifdef debug 00282 G4cout<<"***>>G4QElastic::IsApplicable: PDG="<<particle.GetPDGEncoding()<<G4endl; 00283 #endif 00284 return false; 00285 }
G4VParticleChange * G4QElastic::PostStepDoIt | ( | const G4Track & | aTrack, | |
const G4Step & | aStep | |||
) | [virtual] |
Reimplemented from G4VDiscreteProcess.
Definition at line 287 of file G4QElastic.cc.
References G4ParticleChange::AddSecondary(), G4AntiLambda::AntiLambda(), G4AntiNeutron::AntiNeutron(), G4AntiOmegaMinus::AntiOmegaMinus(), G4AntiProton::AntiProton(), G4AntiSigmaMinus::AntiSigmaMinus(), G4AntiSigmaPlus::AntiSigmaPlus(), G4AntiSigmaZero::AntiSigmaZero(), G4AntiXiMinus::AntiXiMinus(), G4AntiXiZero::AntiXiZero(), G4VProcess::aParticleChange, G4ParticleTable::FindIon(), fStopButAlive, G4cerr, G4cout, G4endl, G4UniformRand, G4QCHIPSWorld::Get(), G4DynamicParticle::Get4Momentum(), G4VQCrossSection::GetCrossSection(), G4DynamicParticle::GetDefinition(), G4Track::GetDynamicParticle(), G4Material::GetElementVector(), G4VQCrossSection::GetExchangeT(), G4Track::GetGlobalTime(), G4VQCrossSection::GetHMaxT(), G4DynamicParticle::GetKineticEnergy(), G4DynamicParticle::GetMass(), G4QPDGCode::GetMass(), G4Track::GetMaterial(), GetMeanFreePath(), G4DynamicParticle::GetMomentumDirection(), G4Material::GetNumberOfElements(), G4ParticleDefinition::GetParticleName(), G4QCHIPSWorld::GetParticles(), G4ParticleDefinition::GetParticleSubType(), G4ParticleTable::GetParticleTable(), G4ParticleDefinition::GetParticleType(), G4ParticleDefinition::GetPDGEncoding(), G4QAntiBaryonElasticCrossSection::GetPointer(), G4QHyperonElasticCrossSection::GetPointer(), G4QHyperonPlusElasticCrossSection::GetPointer(), G4QKaonMinusElasticCrossSection::GetPointer(), G4QKaonPlusElasticCrossSection::GetPointer(), G4QPionMinusElasticCrossSection::GetPointer(), G4QPionPlusElasticCrossSection::GetPointer(), G4QNeutronElasticCrossSection::GetPointer(), G4QProtonElasticCrossSection::GetPointer(), G4Track::GetPosition(), G4DynamicParticle::GetTotalMomentum(), G4Track::GetTouchableHandle(), G4Track::GetWeight(), G4Element::GetZ(), G4ParticleChange::Initialize(), IsApplicable(), G4KaonMinus::KaonMinus(), G4KaonPlus::KaonPlus(), G4KaonZeroLong::KaonZeroLong(), G4KaonZeroShort::KaonZeroShort(), G4Lambda::Lambda(), G4Neutron::Neutron(), NotForced, G4OmegaMinus::OmegaMinus(), G4PionMinus::PionMinus(), G4PionPlus::PionPlus(), position, G4VDiscreteProcess::PostStepDoIt(), G4ParticleChange::ProposeEnergy(), G4VParticleChange::ProposeLocalEnergyDeposit(), G4ParticleChange::ProposeMomentumDirection(), G4VParticleChange::ProposeTrackStatus(), G4Proton::Proton(), G4DynamicParticle::Set4Momentum(), G4DynamicParticle::SetDefinition(), G4Track::SetTouchableHandle(), G4Track::SetWeight(), G4SigmaMinus::SigmaMinus(), G4SigmaPlus::SigmaPlus(), G4SigmaZero::SigmaZero(), G4XiMinus::XiMinus(), and G4XiZero::XiZero().
00288 { 00289 //static const G4double mProt=G4Proton::Proton()->GetPDGMass()*GeV;// proton mass in GeV 00290 //static const G4double mProt= G4QPDGCode(2212).GetMass()*.001; // CHIPS m_p in GeV 00291 //static const G4double mP2=mProt*mProt; // squared proton mass 00292 // 00293 //------------------------------------------------------------------------------------- 00294 static G4bool CWinit = true; // CHIPS Warld needs to be initted 00295 if(CWinit) 00296 { 00297 CWinit=false; 00298 G4QCHIPSWorld::Get()->GetParticles(nPartCWorld); // Create CHIPS World (234 part.max) 00299 } 00300 //------------------------------------------------------------------------------------- 00301 const G4DynamicParticle* projHadron = track.GetDynamicParticle(); 00302 const G4ParticleDefinition* particle=projHadron->GetDefinition(); 00303 #ifdef debug 00304 G4cout<<"G4QElastic::PostStepDoIt: Before the GetMeanFreePath is called In4M=" 00305 <<projHadron->Get4Momentum()<<" of PDG="<<particle->GetPDGEncoding()<<", Type=" 00306 <<particle->GetParticleType()<<", Subtp="<<particle->GetParticleSubType()<<G4endl; 00307 #endif 00308 G4ForceCondition cond=NotForced; 00309 GetMeanFreePath(track, -27., &cond); // @@ ?? jus to update parameters? 00310 #ifdef debug 00311 G4cout<<"G4QElastic::PostStepDoIt: After the GetMeanFreePath is called"<<G4endl; 00312 #endif 00313 G4LorentzVector proj4M=(projHadron->Get4Momentum())/MeV; // Convert to MeV! 00314 G4LorentzVector scat4M=proj4M; // @@ Must be filled (?) 00315 G4double momentum = projHadron->GetTotalMomentum()/MeV; // 3-momentum of the Proj in MeV 00316 G4double Momentum = proj4M.rho(); // @@ Just for the test purposes 00317 if(std::fabs(Momentum-momentum)>.000001) 00318 G4cerr<<"*War*G4QElastic::PostStepDoIt:P(IU)="<<Momentum<<"#"<<momentum<<G4endl; 00319 G4double pM2=proj4M.m2(); // in MeV^2 00320 G4double pM=std::sqrt(pM2); // in MeV 00321 #ifdef debug 00322 G4cout<<"G4QElastic::PostStepDoIt: pP(IU)="<<Momentum<<"="<<momentum<<",pM="<<pM 00323 <<",scat4M="<<scat4M<<scat4M.m()<<G4endl; 00324 #endif 00325 if (!IsApplicable(*particle)) // Check applicability 00326 { 00327 G4cerr<<"G4QElastic::PostStepDoIt: Only NA elastic is implemented."<<G4endl; 00328 return 0; 00329 } 00330 const G4Material* material = track.GetMaterial(); // Get the current material 00331 const G4ElementVector* theElementVector = material->GetElementVector(); 00332 G4int nE=material->GetNumberOfElements(); 00333 #ifdef debug 00334 G4cout<<"G4QElastic::PostStepDoIt: "<<nE<<" elements in the material."<<G4endl; 00335 #endif 00336 G4int projPDG=0; // PDG Code prototype for the captured hadron 00337 // Not all these particles are implemented yet (see Is Applicable) 00338 if (particle == G4Proton::Proton() ) projPDG= 2212; 00339 else if (particle == G4Neutron::Neutron() ) projPDG= 2112; 00340 else if (particle == G4PionMinus::PionMinus() ) projPDG= -211; 00341 else if (particle == G4PionPlus::PionPlus() ) projPDG= 211; 00342 else if (particle == G4KaonPlus::KaonPlus() ) projPDG= 2112; 00343 else if (particle == G4KaonMinus::KaonMinus() ) projPDG= -321; 00344 else if (particle == G4KaonZeroLong::KaonZeroLong() ) projPDG= 130; 00345 else if (particle == G4KaonZeroShort::KaonZeroShort() ) projPDG= 310; 00346 //else if (particle == G4MuonPlus::MuonPlus() ) projPDG= -13; 00347 //else if (particle == G4MuonMinus::MuonMinus() ) projPDG= 13; 00348 //else if (particle == G4NeutrinoMu::NeutrinoMu() ) projPDG= 14; 00349 //else if (particle == G4AntiNeutrinoMu::AntiNeutrinoMu() ) projPDG= -14; 00350 //else if (particle == G4Electron::Electron() ) projPDG= 11; 00351 //else if (particle == G4Positron::Positron() ) projPDG= -11; 00352 //else if (particle == G4NeutrinoE::NeutrinoE() ) projPDG= 12; 00353 //else if (particle == G4AntiNeutrinoE::AntiNeutrinoE() ) projPDG= -12; 00354 //else if (particle == G4Gamma::Gamma() ) projPDG= 22; 00355 //else if (particle == G4TauPlus::TauPlus() ) projPDG= -15; 00356 //else if (particle == G4TauMinus::TauMinus() ) projPDG= 15; 00357 //else if (particle == G4NeutrinoTau::NeutrinoTau() ) projPDG= 16; 00358 //else if (particle == G4AntiNeutrinoTau::AntiNeutrinoTau()) projPDG= -16; 00359 else if (particle == G4Lambda::Lambda() ) projPDG= 3122; 00360 else if (particle == G4SigmaPlus::SigmaPlus() ) projPDG= 3222; 00361 else if (particle == G4SigmaMinus::SigmaMinus() ) projPDG= 3112; 00362 else if (particle == G4SigmaZero::SigmaZero() ) projPDG= 3212; 00363 else if (particle == G4XiMinus::XiMinus() ) projPDG= 3312; 00364 else if (particle == G4XiZero::XiZero() ) projPDG= 3322; 00365 else if (particle == G4OmegaMinus::OmegaMinus() ) projPDG= 3334; 00366 else if (particle == G4AntiNeutron::AntiNeutron() ) projPDG=-2112; 00367 else if (particle == G4AntiProton::AntiProton() ) projPDG=-2212; 00368 else if (particle == G4AntiLambda::AntiLambda() ) projPDG=-3122; 00369 else if (particle == G4AntiSigmaPlus::AntiSigmaPlus() ) projPDG=-3222; 00370 else if (particle == G4AntiSigmaMinus::AntiSigmaMinus() ) projPDG=-3112; 00371 else if (particle == G4AntiSigmaZero::AntiSigmaZero() ) projPDG=-3212; 00372 else if (particle == G4AntiXiMinus::AntiXiMinus() ) projPDG=-3312; 00373 else if (particle == G4AntiXiZero::AntiXiZero() ) projPDG=-3322; 00374 else if (particle == G4AntiOmegaMinus::AntiOmegaMinus() ) projPDG=-3334; 00375 #ifdef pdebug 00376 G4int prPDG=particle->GetPDGEncoding(); 00377 G4cout<<"G4QElastic::PostStepDoIt: projPDG="<<projPDG<<", stPDG="<<prPDG<<G4endl; 00378 #endif 00379 if(!projPDG) 00380 { 00381 G4cerr<<"*Warning*G4QElastic::PostStepDoIt: Undefined interacting hadron"<<G4endl; 00382 return 0; 00383 } 00384 G4int EPIM=ElProbInMat.size(); 00385 #ifdef debug 00386 G4cout<<"G4QElastic::PostStDoIt:m="<<EPIM<<",n="<<nE<<",T="<<ElProbInMat[EPIM-1]<<G4endl; 00387 #endif 00388 G4int i=0; 00389 if(EPIM>1) 00390 { 00391 G4double rnd = ElProbInMat[EPIM-1]*G4UniformRand(); 00392 for(i=0; i<nE; ++i) 00393 { 00394 #ifdef debug 00395 G4cout<<"G4QElastic::PostStepDoIt:EPM["<<i<<"]="<<ElProbInMat[i]<<",r="<<rnd<<G4endl; 00396 #endif 00397 if (rnd<ElProbInMat[i]) break; 00398 } 00399 if(i>=nE) i=nE-1; // Top limit for the Element 00400 } 00401 G4Element* pElement=(*theElementVector)[i]; 00402 G4int Z=static_cast<G4int>(pElement->GetZ()); 00403 #ifdef debug 00404 G4cout<<"G4QElastic::PostStepDoIt: i="<<i<<", Z(element)="<<Z<<G4endl; 00405 #endif 00406 if(Z<=0) 00407 { 00408 G4cerr<<"---Warning---G4QElastic::PostStepDoIt: Element with Z="<<Z<<G4endl; 00409 if(Z<0) return 0; 00410 } 00411 std::vector<G4double>* SPI = IsoProbInEl[i];// Vector of summedProbabilities for isotopes 00412 std::vector<G4int>* IsN = ElIsoN[i]; // Vector of "#of neutrons" in the isotope El[i] 00413 G4int nofIsot=SPI->size(); // #of isotopes in the element i 00414 #ifdef debug 00415 G4cout<<"G4QElastic::PosStDoIt: nI="<<nofIsot<<",T="<<(*SPI)[nofIsot-1]<<G4endl; 00416 #endif 00417 G4int j=0; 00418 if(nofIsot>1) 00419 { 00420 G4double rndI=(*SPI)[nofIsot-1]*G4UniformRand(); // Randomize the isotop of the Element 00421 for(j=0; j<nofIsot; ++j) 00422 { 00423 #ifdef debug 00424 G4cout<<"G4QElastic::PostStepDoIt: SP["<<j<<"]="<<(*SPI)[j]<<", r="<<rndI<<G4endl; 00425 #endif 00426 if(rndI < (*SPI)[j]) break; 00427 } 00428 if(j>=nofIsot) j=nofIsot-1; // Top limit for the isotope 00429 } 00430 G4int N =(*IsN)[j]; ; // Randomized number of neutrons 00431 #ifdef debug 00432 G4cout<<"G4QElastic::PostStepDoIt: j="<<i<<", N(isotope)="<<N<<", MeV="<<MeV<<G4endl; 00433 #endif 00434 if(N<0) 00435 { 00436 G4cerr<<"*Warning*G4QElastic::PostStepDoIt: Isotope with Z="<<Z<<", 0>N="<<N<<G4endl; 00437 return 0; 00438 } 00439 nOfNeutrons=N; // Remember it for the energy-momentum check 00440 #ifdef debug 00441 G4cout<<"G4QElastic::PostStepDoIt: N="<<N<<" for element with Z="<<Z<<G4endl; 00442 #endif 00443 aParticleChange.Initialize(track); 00444 #ifdef debug 00445 G4cout<<"G4QElastic::PostStepDoIt: track is initialized"<<G4endl; 00446 #endif 00447 G4double weight = track.GetWeight(); 00448 G4double localtime = track.GetGlobalTime(); 00449 G4ThreeVector position = track.GetPosition(); 00450 #ifdef debug 00451 G4cout<<"G4QElastic::PostStepDoIt: before Touchable extraction"<<G4endl; 00452 #endif 00453 G4TouchableHandle trTouchable = track.GetTouchableHandle(); 00454 #ifdef debug 00455 G4cout<<"G4QElastic::PostStepDoIt: Touchable is extracted"<<G4endl; 00456 #endif 00457 // 00458 G4int targPDG=90000000+Z*1000+N; // CHIPS PDG Code of the target nucleus 00459 G4QPDGCode targQPDG(targPDG); // @@ one can use G4Ion & get rid of CHIPSWorld 00460 G4double tM=targQPDG.GetMass(); // CHIPS target mass in MeV 00461 G4double kinEnergy= projHadron->GetKineticEnergy()*MeV; // Kin energy in MeV (Is *MeV n?) 00462 G4ParticleMomentum dir = projHadron->GetMomentumDirection();// It is a unit three-vector 00463 G4LorentzVector tot4M=proj4M+G4LorentzVector(0.,0.,0.,tM); // Total 4-mom of the reaction 00464 #ifdef debug 00465 G4cout<<"G4QElastic::PostStepDoIt: tM="<<tM<<", p4M="<<proj4M<<", t4M="<<tot4M<<G4endl; 00466 #endif 00467 EnMomConservation=tot4M; // Total 4-mom of reaction for E/M conservation 00468 G4VQCrossSection* CSmanager=0; 00469 G4VQCrossSection* CSmanager2=0; 00470 if (projPDG==2212) CSmanager=G4QProtonElasticCrossSection::GetPointer(); 00471 else if(projPDG==2112) CSmanager=G4QNeutronElasticCrossSection::GetPointer(); 00472 else if(projPDG== 211) CSmanager=G4QPionPlusElasticCrossSection::GetPointer(); 00473 else if(projPDG==-211) CSmanager=G4QPionMinusElasticCrossSection::GetPointer(); 00474 else if(projPDG== 321) CSmanager=G4QKaonPlusElasticCrossSection::GetPointer(); 00475 else if(projPDG==-321) CSmanager=G4QKaonMinusElasticCrossSection::GetPointer(); 00476 else if(projPDG== 130 || projPDG== 310) 00477 { 00478 CSmanager=G4QKaonMinusElasticCrossSection::GetPointer(); 00479 CSmanager2=G4QKaonPlusElasticCrossSection::GetPointer(); 00480 } 00481 else if(projPDG==3222) CSmanager=G4QHyperonPlusElasticCrossSection::GetPointer(); 00482 else if(projPDG>3110&&projPDG<3335)CSmanager=G4QHyperonElasticCrossSection::GetPointer(); 00483 else if(projPDG>-3335 && projPDG<-1110) 00484 CSmanager=G4QAntiBaryonElasticCrossSection::GetPointer(); 00485 else G4cout<<"*Warning*G4QElastic::PostStepDoIt: wrong PDG="<<projPDG<<G4endl; 00486 #ifdef debug 00487 G4cout<<"G4QElas::PSDI:false,P="<<Momentum<<",Z="<<Z<<",N="<<N<<",PDG="<<projPDG<<G4endl; 00488 #endif 00489 G4double xSec=0.; 00490 if(!CSmanager2) xSec=CSmanager->GetCrossSection(false,Momentum,Z,N,projPDG); //ReactionCS 00491 else xSec=(CSmanager->GetCrossSection(false,Momentum,Z,N,-321)+ 00492 CSmanager2->GetCrossSection(false,Momentum,Z,N,321) )/2.; // K0 00493 #ifdef debug 00494 G4cout<<"G4QElast::PSDI:pPDG="<<projPDG<<",P="<<Momentum<<",CS="<<xSec/millibarn<<G4endl; 00495 #endif 00496 #ifdef nandebug 00497 if(xSec>0. || xSec<0. || xSec==0); 00498 else G4cout<<"*Warning*G4QElastic::PostStDoIt: xSec="<<xSec/millibarn<<G4endl; 00499 #endif 00500 // @@ check a possibility to separate p, n, or alpha (!) 00501 if(xSec <= 0.) // The cross-section iz 0 -> Do Nothing 00502 { 00503 #ifdef debug 00504 G4cerr<<"*Warning*G4QElastic::PostStDoIt: *Zero cross-section* PDG="<<projPDG<<",tPDG=" 00505 <<targPDG<<",P="<<Momentum<<G4endl; 00506 #endif 00507 //Do Nothing Action insead of the reaction 00508 aParticleChange.ProposeEnergy(kinEnergy); 00509 aParticleChange.ProposeLocalEnergyDeposit(0.); 00510 aParticleChange.ProposeMomentumDirection(dir) ; 00511 return G4VDiscreteProcess::PostStepDoIt(track,step); 00512 } 00513 G4double mint=CSmanager->GetExchangeT(Z, N, projPDG); // functional rand -t(MeV^2) 00514 #ifdef debug 00515 G4cout<<"G4QElast::PSDI:pPDG="<<projPDG<<",tPDG="<<targPDG<<",P="<<Momentum<<",CS=" 00516 <<xSec<<",-t="<<mint<<G4endl; 00517 #endif 00518 #ifdef nandebug 00519 if(mint>-.0000001); 00520 else G4cout<<"*Warning*G4QElastic::PostStDoIt:-t="<<mint<<G4endl; 00521 #endif 00522 G4double maxt=CSmanager->GetHMaxT(); // max -t (MeV^2) 00523 G4double cost=1.-mint/maxt; // cos(theta) in CMS 00524 // 00525 #ifdef ppdebug 00526 G4cout<<"G4QElastic::PoStDoI:t="<<mint<<", maxt="<<maxt<<",Ek="<<kinEnergy<<",tM="<<tM 00527 <<",pM="<<pM<<",cost="<<cost<<G4endl; 00528 #endif 00529 if(cost>1. || cost<-1. || !(cost>-1. || cost<1.)) 00530 { 00531 if(cost>1.000001 || cost<-1.000001 || !(cost>-1. || cost<1.)) 00532 { 00533 G4double tM2=tM*tM; // Squared target mass 00534 G4double pEn=pM+kinEnergy; // tot projectile Energy in MeV 00535 G4double sM=(tM+tM)*pEn+tM2+pM2; // Mondelstam s 00536 G4double twop2cm=(tM2+tM2)*(pEn*pEn-pM2)/sM;// Max_t/2 (2*p^2_cm) 00537 G4cout<<"*Warning*G4QElastic::PostStepDoIt:cos="<<cost<<",t="<<mint<<",T="<<kinEnergy 00538 <<",tM="<<tM<<",tmax="<<2*kinEnergy*tM<<",p="<<projPDG<<",t="<<targPDG<<G4endl; 00539 G4cout<<"..G4QElastic::PoStDoI: dpcm2="<<twop2cm<<"="<<maxt<<G4endl; 00540 } 00541 if (cost>1.) cost=1.; 00542 else if(cost<-1.) cost=-1.; 00543 } 00544 G4LorentzVector reco4M=G4LorentzVector(0.,0.,0.,tM); // 4mom of the recoil target 00545 G4LorentzVector dir4M=tot4M-G4LorentzVector(0.,0.,0.,(tot4M.e()-tM-pM)*.01); 00546 if(!G4QHadron(tot4M).RelDecayIn2(scat4M, reco4M, dir4M, cost, cost)) 00547 { 00548 G4cerr<<"G4QElastic::PSD:t4M="<<tot4M<<",pM="<<pM<<",tM="<<tM<<",cost="<<cost<<G4endl; 00549 //G4Exception("G4QElastic::PostStepDoIt:","009",FatalException,"Decay of ElasticComp"); 00550 } 00551 #ifdef debug 00552 G4cout<<"G4QElastic::PoStDoIt:s4M="<<scat4M<<"+r4M="<<reco4M<<"="<<scat4M+reco4M<<G4endl; 00553 G4cout<<"G4QElastic::PoStDoIt: scatE="<<scat4M.e()-pM<<", recoE="<<reco4M.e()-tM<<",d4M=" 00554 <<tot4M-scat4M-reco4M<<G4endl; 00555 #endif 00556 // Update G4VParticleChange for the scattered projectile 00557 G4double finE=scat4M.e()-pM; // Final kinetic energy of the scattered proton 00558 if(finE>0.0) aParticleChange.ProposeEnergy(finE); 00559 else 00560 { 00561 if(finE<-1.e-8 || !(finE>-1.||finE<1.)) // NAN or negative 00562 G4cerr<<"*Warning*G4QElastic::PostStDoIt: Zero or negative scattered E="<<finE 00563 <<", s4M="<<scat4M<<", r4M="<<reco4M<<", d4M="<<tot4M-scat4M-reco4M<<G4endl; 00564 //G4Exception("G4QElastic::PostStDoIt()","009", FatalException," <0 or nan energy"); 00565 aParticleChange.ProposeEnergy(0.) ; 00566 aParticleChange.ProposeTrackStatus(fStopButAlive); 00567 } 00568 G4ThreeVector findir=scat4M.vect()/scat4M.rho(); // Unit vector in new direction 00569 aParticleChange.ProposeMomentumDirection(findir); // new direction for the scattered part 00570 EnMomConservation-=scat4M; // It must be initialized by (pE+tM,pP) 00571 // This is how in general the secondary should be identified 00572 G4DynamicParticle* theSec = new G4DynamicParticle; // A secondary for the recoil hadron 00573 G4int aA = Z+N; 00574 #ifdef debug 00575 G4cout<<"G4QElastic::PostStepDoIt: Ion Z="<<Z<<", A="<<aA<<G4endl; 00576 #endif 00577 G4ParticleDefinition* theDefinition=G4ParticleTable::GetParticleTable() 00578 ->FindIon(Z,aA,0,Z); 00579 if(!theDefinition)G4cout<<"*Warning*G4QElastic::PostStepDoIt:drop PDG="<<targPDG<<G4endl; 00580 #ifdef debug 00581 G4cout<<"G4QElastic::PostStepDoIt:RecoilName="<<theDefinition->GetParticleName()<<G4endl; 00582 #endif 00583 theSec->SetDefinition(theDefinition); 00584 00585 EnMomConservation-=reco4M; 00586 #ifdef tdebug 00587 G4cout<<"G4QElastic::PostSDoIt:"<<targPDG<<reco4M<<reco4M.m()<<EnMomConservation<<G4endl; 00588 #endif 00589 theSec->Set4Momentum(reco4M); 00590 #ifdef debug 00591 G4ThreeVector curD=theSec->GetMomentumDirection(); 00592 G4double curM=theSec->GetMass(); 00593 G4double curE=theSec->GetKineticEnergy()+curM; 00594 G4cout<<"G4QElastic::PSDoIt:p="<<curD<<curD.mag()<<",e="<<curE<<",m="<<curM<<G4endl; 00595 #endif 00596 // Make a recoil nucleus 00597 G4Track* aNewTrack = new G4Track(theSec, localtime, position ); 00598 aNewTrack->SetWeight(weight); // weighted 00599 aNewTrack->SetTouchableHandle(trTouchable); 00600 aParticleChange.AddSecondary( aNewTrack ); 00601 #ifdef debug 00602 G4cout<<"G4QElastic::PostStepDoIt: **** PostStepDoIt is done ****"<<G4endl; 00603 #endif 00604 return G4VDiscreteProcess::PostStepDoIt(track, step); 00605 }