source: trunk/source/processes/hadronic/models/chiral_inv_phase_space/interface/src/G4QElastic.cc @ 1055

Last change on this file since 1055 was 1055, checked in by garnier, 15 years ago

maj sur la beta de geant 4.9.3

File size: 28.1 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26// $Id: G4QElastic.cc,v 1.28 2009/02/23 09:49:24 mkossov Exp $
27// GEANT4 tag $Name: geant4-09-03-beta-cand-01 $
28//
29//      ---------------- G4QElastic class -----------------
30//                 by Mikhail Kossov, December 2003.
31// G4QElastic class of the CHIPS Simulation Branch in GEANT4
32// --------------------------------------------------------------------
33// Short description: At present this is a process for nucleon-nucleus
34// elastic scattering. Mesons and hyperons exist only for the Hydrogen
35// target (see G4QuasiFreeRatios).
36// --------------------------------------------------------------------
37
38//#define debug
39//#define pdebug
40//#define tdebug
41//#define nandebug
42//#define ppdebug
43
44#include "G4QElastic.hh"
45
46// Initialization of static vectors
47G4int    G4QElastic::nPartCWorld=152;        // The#of particles initialized in CHIPS World
48std::vector<G4int> G4QElastic::ElementZ;              // Z of the element(i) in theLastCalc
49std::vector<G4double> G4QElastic::ElProbInMat;        // SumProbabilityElements in Material
50std::vector<std::vector<G4int>*> G4QElastic::ElIsoN;       // N of isotope(j) of Element(i)
51std::vector<std::vector<G4double>*>G4QElastic::IsoProbInEl;//SumProbabIsotopes inElementI
52
53// Constructor
54G4QElastic::G4QElastic(const G4String& processName): 
55 G4VDiscreteProcess(processName, fHadronic)
56{
57#ifdef debug
58  G4cout<<"G4QElastic::Constructor is called processName="<<processName<<G4endl;
59#endif
60  if (verboseLevel>0) G4cout << GetProcessName() << " process is created "<< G4endl;
61  SetProcessSubType(fHadronElastic);
62  //G4QCHIPSWorld::Get()->GetParticles(nPartCWorld); // Create CHIPS World (234 part. max)
63}
64
65// Destructor
66G4QElastic::~G4QElastic() {}
67
68
69G4LorentzVector G4QElastic::GetEnegryMomentumConservation() {return EnMomConservation;}
70
71G4int G4QElastic::GetNumberOfNeutronsInTarget() {return nOfNeutrons;}
72
73// output of the function must be in units of length! L=1/sig_V,sig_V=SUM(n(j,i)*sig(j,i)),
74// where n(i,j) is a number of nuclei of the isotop j of the element i in V=1(lengtUnit^3)
75// ********** All CHIPS cross sections are calculated in the surface units ************
76G4double G4QElastic::GetMeanFreePath(const G4Track& aTrack,G4double Q,G4ForceCondition* Fc)
77{
78  *Fc = NotForced;
79  const G4DynamicParticle* incidentParticle = aTrack.GetDynamicParticle();
80  G4ParticleDefinition* incidentParticleDefinition=incidentParticle->GetDefinition();
81  if( !IsApplicable(*incidentParticleDefinition))
82    G4cout<<"*W*G4QElastic::GetMeanFreePath: is called for notImplementedParticle"<<G4endl;
83  // Calculate the mean Cross Section for the set of Elements(*Isotopes) in the Material
84  G4double Momentum = incidentParticle->GetTotalMomentum(); // 3-momentum of the Particle
85#ifdef debug
86  G4double KinEn = incidentParticle->GetKineticEnergy();
87  G4cout<<"G4QElastic::GetMeanFreePath: kinE="<<KinEn<<",Mom="<<Momentum<<G4endl; // Result
88#endif
89  const G4Material* material = aTrack.GetMaterial();        // Get the current material
90  const G4double* NOfNucPerVolume = material->GetVecNbOfAtomsPerVolume();
91  const G4ElementVector* theElementVector = material->GetElementVector();
92  G4int nE=material->GetNumberOfElements();
93#ifdef debug
94  G4cout<<"G4QElastic::GetMeanFreePath:"<<nE<<" Elem's in theMaterial"<<G4endl;
95#endif
96  G4VQCrossSection* CSmanager=G4QElasticCrossSection::GetPointer();
97  G4int pPDG=0;
98
99  if     (incidentParticleDefinition == G4Proton::Proton()  ) pPDG=2212;
100  else if(incidentParticleDefinition == G4Neutron::Neutron()) pPDG=2112;
101  else G4cout<<"G4QElastic::GetMeanFreePath:only nA & pA are implemented in CHIPS"<<G4endl;
102 
103  G4QIsotope* Isotopes = G4QIsotope::Get(); // Pointer to the G4QIsotopes singleton
104  G4double sigma=0.;                        // Sums over elements for the material
105  G4int IPIE=IsoProbInEl.size();            // How many old elements?
106  if(IPIE) for(G4int ip=0; ip<IPIE; ++ip)   // Clean up the SumProb's of Isotopes (SPI)
107  {
108    std::vector<G4double>* SPI=IsoProbInEl[ip]; // Pointer to the SPI vector
109    SPI->clear();
110    delete SPI;
111    std::vector<G4int>* IsN=ElIsoN[ip];     // Pointer to the N vector
112    IsN->clear();
113    delete IsN;
114  }
115  ElProbInMat.clear();                      // Clean up the SumProb's of Elements (SPE)
116  ElementZ.clear();                         // Clear the body vector for Z of Elements
117  IsoProbInEl.clear();                      // Clear the body vector for SPI
118  ElIsoN.clear();                           // Clear the body vector for N of Isotopes
119  for(G4int i=0; i<nE; ++i)
120  {
121    G4Element* pElement=(*theElementVector)[i]; // Pointer to the current element
122    G4int Z = static_cast<G4int>(pElement->GetZ()); // Z of the Element
123    ElementZ.push_back(Z);                  // Remember Z of the Element
124    G4int isoSize=0;                        // The default for the isoVectorLength is 0
125    G4int indEl=0;                          // Index of non-natural element or 0(default)
126    G4IsotopeVector* isoVector=pElement->GetIsotopeVector(); // Get the predefined IsoVect
127    if(isoVector) isoSize=isoVector->size();// Get size of the existing isotopeVector
128#ifdef debug
129    G4cout<<"G4QElastic::GetMeanFreePath: isovectorLength="<<isoSize<<G4endl; // Result
130#endif
131    if(isoSize)                             // The Element has non-trivial abundance set
132    {
133      indEl=pElement->GetIndex()+1;         // Index of the non-trivial element is an order
134#ifdef debug
135      G4cout<<"G4QEl::GetMFP: iE="<<indEl<<", def="<<Isotopes->IsDefined(Z,indEl)<<G4endl;
136#endif
137      if(!Isotopes->IsDefined(Z,indEl))     // This index is not defined for this Z: define
138      {
139        std::vector<std::pair<G4int,G4double>*>* newAbund =
140                                               new std::vector<std::pair<G4int,G4double>*>;
141        G4double* abuVector=pElement->GetRelativeAbundanceVector();
142        for(G4int j=0; j<isoSize; j++)      // Calculation of abundance vector for isotopes
143        {
144          G4int N=pElement->GetIsotope(j)->GetN()-Z; // N means A=N+Z !
145          if(pElement->GetIsotope(j)->GetZ()!=Z)G4cerr<<"G4QElastic::GetMeanFreePath: Z="
146                                         <<pElement->GetIsotope(j)->GetZ()<<"#"<<Z<<G4endl;
147          G4double abund=abuVector[j];
148          std::pair<G4int,G4double>* pr= new std::pair<G4int,G4double>(N,abund);
149#ifdef debug
150          G4cout<<"G4QElastic::GetMeanFreePath:pair#="<<j<<",N="<<N<<",ab="<<abund<<G4endl;
151#endif
152          newAbund->push_back(pr);
153        }
154#ifdef debug
155        G4cout<<"G4QElastic::GetMeanFreePath: pairVectorLength="<<newAbund->size()<<G4endl;
156#endif
157        indEl=G4QIsotope::Get()->InitElement(Z,indEl,newAbund); // definition of the newInd
158        for(G4int k=0; k<isoSize; k++) delete (*newAbund)[k];   // Cleaning temporary
159        delete newAbund; // Was "new" in the beginning of the name space
160      }
161    }
162    std::vector<std::pair<G4int,G4double>*>* cs= Isotopes->GetCSVector(Z,indEl);//CSPointer
163    std::vector<G4double>* SPI = new std::vector<G4double>; // Pointer to the SPI vector
164    IsoProbInEl.push_back(SPI);
165    std::vector<G4int>* IsN = new std::vector<G4int>; // Pointer to the N vector
166    ElIsoN.push_back(IsN);
167    G4int nIs=cs->size();                   // A#Of Isotopes in the Element
168#ifdef debug
169    G4cout<<"G4QEl::GMFP:=***=>,#isot="<<nIs<<", Z="<<Z<<", indEl="<<indEl<<G4endl;
170#endif
171    G4double susi=0.;                       // sum of CS over isotopes
172    if(nIs) for(G4int j=0; j<nIs; j++)      // Calculate CS for eachIsotope of El
173    {
174      std::pair<G4int,G4double>* curIs=(*cs)[j]; // A pointer, which is used twice
175      G4int N=curIs->first;                 // #of Neuterons in the isotope j of El i
176      IsN->push_back(N);                    // Remember Min N for the Element
177#ifdef debug
178      G4cout<<"G4QEl::GMFP:*true*,P="<<Momentum<<",Z="<<Z<<",N="<<N<<",PDG="<<pPDG<<G4endl;
179#endif
180      G4bool ccsf=true;
181      if(Q==-27.) ccsf=false;
182#ifdef debug
183      G4cout<<"G4QEl::GMFP: GetCS #1 j="<<j<<G4endl;
184#endif
185      G4double CSI=CSmanager->GetCrossSection(ccsf,Momentum,Z,N,pPDG);//CS(j,i) for isotope
186
187#ifdef debug
188      G4cout<<"G4QEl::GMFP: jI="<<j<<", Zt="<<Z<<", Nt="<<N<<", Mom="<<Momentum<<", XSec="
189            <<CSI/millibarn<<G4endl;
190#endif
191      curIs->second = CSI;
192      susi+=CSI;                            // Make a sum per isotopes
193      SPI->push_back(susi);                 // Remember summed cross-section
194    } // End of temporary initialization of the cross sections in the G4QIsotope singeltone
195    sigma+=Isotopes->GetMeanCrossSection(Z,indEl)*NOfNucPerVolume[i];//SUM(MeanCS*NOfNperV)
196#ifdef debug
197    G4cout<<"G4QEl::GMFP: <S>="<<Isotopes->GetMeanCrossSection(Z,indEl)<<", AddToSigma="
198          <<Isotopes->GetMeanCrossSection(Z,indEl)*NOfNucPerVolume[i]<<G4endl;
199#endif
200    ElProbInMat.push_back(sigma);
201  } // End of LOOP over Elements
202  // Check that cross section is not zero and return the mean free path
203#ifdef debug
204  G4cout<<"G4QElastic::GetMeanFreePath: MeanFreePath="<<1./sigma<<G4endl;
205#endif
206  if(sigma > 0.) return 1./sigma;                 // Mean path [distance]
207  return DBL_MAX;
208}
209
210
211G4bool G4QElastic::IsApplicable(const G4ParticleDefinition& particle) 
212{
213  if      (particle == *(        G4Proton::Proton()        )) return true;
214  else if (particle == *(       G4Neutron::Neutron()       )) return true;
215  //else if (particle == *(     G4MuonMinus::MuonMinus()     )) return true;
216  //else if (particle == *(       G4TauPlus::TauPlus()       )) return true;
217  //else if (particle == *(      G4TauMinus::TauMinus()      )) return true;
218  //else if (particle == *(      G4Electron::Electron()      )) return true;
219  //else if (particle == *(      G4Positron::Positron()      )) return true;
220  //else if (particle == *(         G4Gamma::Gamma()         )) return true;
221  //else if (particle == *(      G4MuonPlus::MuonPlus()      )) return true;
222  //else if (particle == *(G4AntiNeutrinoMu::AntiNeutrinoMu())) return true;
223  //else if (particle == *(   G4NeutrinoMu::NeutrinoMu()   )) return true;
224  //else if (particle == *(     G4PionMinus::PionMinus()     )) return true;
225  //else if (particle == *(      G4PionPlus::PionPlus()      )) return true;
226  //else if (particle == *(      G4KaonPlus::KaonPlus()      )) return true;
227  //else if (particle == *(     G4KaonMinus::KaonMinus()     )) return true;
228  //else if (particle == *(  G4KaonZeroLong::KaonZeroLong()  )) return true;
229  //else if (particle == *( G4KaonZeroShort::KaonZeroShort() )) return true;
230  //else if (particle == *(        G4Lambda::Lambda()        )) return true;
231  //else if (particle == *(     G4SigmaPlus::SigmaPlus()     )) return true;
232  //else if (particle == *(    G4SigmaMinus::SigmaMinus()    )) return true;
233  //else if (particle == *(     G4SigmaZero::SigmaZero()     )) return true;
234  //else if (particle == *(       G4XiMinus::XiMinus()       )) return true;
235  //else if (particle == *(        G4XiZero::XiZero()        )) return true;
236  //else if (particle == *(    G4OmegaMinus::OmegaMinus()    )) return true;
237  //else if (particle == *(   G4AntiNeutron::AntiNeutron()   )) return true;
238  //else if (particle == *(    G4AntiProton::AntiProton()    )) return true;
239#ifdef debug
240  G4cout<<"***>>G4QElastic::IsApplicable: PDG="<<particle.GetPDGEncoding()<<G4endl;
241#endif
242  return false;
243}
244
245G4VParticleChange* G4QElastic::PostStepDoIt(const G4Track& track, const G4Step& step)
246{
247  //static const G4double mProt=G4Proton::Proton()->GetPDGMass()*GeV;// proton mass in GeV
248  //static const G4double mProt= G4QPDGCode(2212).GetMass()*.001;    // CHIPS m_p in GeV
249  //static const G4double mP2=mProt*mProt;                           // squared proton mass
250  //
251  //-------------------------------------------------------------------------------------
252  static G4bool CWinit = true;                       // CHIPS Warld needs to be initted
253  if(CWinit)
254  {
255    CWinit=false;
256    G4QCHIPSWorld::Get()->GetParticles(nPartCWorld); // Create CHIPS World (234 part.max)
257  }
258  //-------------------------------------------------------------------------------------
259  const G4DynamicParticle* projHadron = track.GetDynamicParticle();
260  const G4ParticleDefinition* particle=projHadron->GetDefinition();
261#ifdef debug
262  G4cout<<"G4QElastic::PostStepDoIt: Before the GetMeanFreePath is called In4M="
263        <<projHadron->Get4Momentum()<<" of PDG="<<particle->GetPDGEncoding()<<", Type="
264        <<particle->GetParticleType()<<", Subtp="<<particle->GetParticleSubType()<<G4endl;
265#endif
266  G4ForceCondition cond=NotForced;
267  GetMeanFreePath(track, -27., &cond);                  // @@ ?? jus to update parameters?
268#ifdef debug
269  G4cout<<"G4QElastic::PostStepDoIt: After the GetMeanFreePath is called"<<G4endl;
270#endif
271  G4LorentzVector proj4M=(projHadron->Get4Momentum())/MeV; // Convert to MeV!
272  G4LorentzVector scat4M=proj4M;                      // @@ Must be filled (?)
273  G4double momentum = projHadron->GetTotalMomentum()/MeV; // 3-momentum of the Proj in MeV
274  G4double Momentum = proj4M.rho();                   // @@ Just for the test purposes
275  if(std::fabs(Momentum-momentum)>.000001)
276           G4cerr<<"*War*G4QElastic::PostStepDoIt:P(IU)="<<Momentum<<"#"<<momentum<<G4endl;
277  G4double pM2=proj4M.m2();        // in MeV^2
278  G4double pM=std::sqrt(pM2);      // in MeV
279#ifdef pdebug
280  G4cout<<"G4QElastic::PostStepDoIt: pP(IU)="<<Momentum<<"="<<momentum<<",pM="<<pM
281        <<",scat4M="<<scat4M<<scat4M.m()<<G4endl;
282#endif
283  if (!IsApplicable(*particle))  // Check applicability
284  {
285    G4cerr<<"G4QElastic::PostStepDoIt: Only NA elastic is implemented."<<G4endl;
286    return 0;
287  }
288  const G4Material* material = track.GetMaterial();      // Get the current material
289  G4int Z=0;
290  const G4ElementVector* theElementVector = material->GetElementVector();
291  G4int nE=material->GetNumberOfElements();
292#ifdef debug
293  G4cout<<"G4QElastic::PostStepDoIt: "<<nE<<" elements in the material."<<G4endl;
294#endif
295  G4int projPDG=0;                           // PDG Code prototype for the captured hadron
296  // Not all these particles are implemented yet (see Is Applicable)
297  if      (particle ==          G4Proton::Proton()         ) projPDG= 2212;
298  else if (particle ==         G4Neutron::Neutron()        ) projPDG= 2112;
299  //else if (particle ==       G4PionMinus::PionMinus()      ) projPDG= -211;
300  //else if (particle ==        G4PionPlus::PionPlus()       ) projPDG=  211;
301  //else if (particle ==        G4KaonPlus::KaonPlus()       ) projPDG= 2112;
302  //else if (particle ==       G4KaonMinus::KaonMinus()      ) projPDG= -321;
303  //else if (particle ==    G4KaonZeroLong::KaonZeroLong()   ) projPDG=  130;
304  //else if (particle ==   G4KaonZeroShort::KaonZeroShort()  ) projPDG=  310;
305  //else if (particle ==        G4MuonPlus::MuonPlus()       ) projPDG=  -13;
306  //else if (particle ==       G4MuonMinus::MuonMinus()      ) projPDG=   13;
307  //else if (particle ==      G4NeutrinoMu::NeutrinoMu()     ) projPDG=   14;
308  //else if (particle ==  G4AntiNeutrinoMu::AntiNeutrinoMu() ) projPDG=  -14;
309  //else if (particle ==        G4Electron::Electron()       ) projPDG=   11;
310  //else if (particle ==        G4Positron::Positron()       ) projPDG=  -11;
311  //else if (particle ==       G4NeutrinoE::NeutrinoE()      ) projPDG=   12;
312  //else if (particle ==   G4AntiNeutrinoE::AntiNeutrinoE()  ) projPDG=  -12;
313  //else if (particle ==           G4Gamma::Gamma()          ) projPDG=   22;
314  //else if (particle ==         G4TauPlus::TauPlus()        ) projPDG=  -15;
315  //else if (particle ==        G4TauMinus::TauMinus()       ) projPDG=   15;
316  //else if (particle ==     G4NeutrinoTau::NeutrinoTau()    ) projPDG=   16;
317  //else if (particle == G4AntiNeutrinoTau::AntiNeutrinoTau()) projPDG=  -16;
318  //else if (particle ==          G4Lambda::Lambda()         ) projPDG= 3122;
319  //else if (particle ==       G4SigmaPlus::SigmaPlus()      ) projPDG= 3222;
320  //else if (particle ==      G4SigmaMinus::SigmaMinus()     ) projPDG= 3112;
321  //else if (particle ==       G4SigmaZero::SigmaZero()      ) projPDG= 3212;
322  //else if (particle ==         G4XiMinus::XiMinus()        ) projPDG= 3312;
323  //else if (particle ==          G4XiZero::XiZero()         ) projPDG= 3322;
324  //else if (particle ==      G4OmegaMinus::OmegaMinus()     ) projPDG= 3334;
325  //else if (particle ==     G4AntiNeutron::AntiNeutron()    ) projPDG=-2112;
326  //else if (particle ==      G4AntiProton::AntiProton()     ) projPDG=-2212;
327#ifdef debug
328  G4int prPDG=particle->GetPDGEncoding();
329  G4cout<<"G4QElastic::PostStepDoIt: projPDG="<<projPDG<<", stPDG="<<prPDG<<G4endl;
330#endif
331  if(!projPDG)
332  {
333    G4cerr<<"*Warning*G4QElastic::PostStepDoIt: Undefined interacting hadron"<<G4endl;
334    return 0;
335  }
336  G4int EPIM=ElProbInMat.size();
337#ifdef debug
338  G4cout<<"G4QElastic::PostStDoIt:m="<<EPIM<<",n="<<nE<<",T="<<ElProbInMat[EPIM-1]<<G4endl;
339#endif
340  G4int i=0;
341  if(EPIM>1)
342  {
343    G4double rnd = ElProbInMat[EPIM-1]*G4UniformRand();
344    for(i=0; i<nE; ++i)
345    {
346#ifdef debug
347      G4cout<<"G4QElastic::PostStepDoIt:EPM["<<i<<"]="<<ElProbInMat[i]<<",r="<<rnd<<G4endl;
348#endif
349      if (rnd<ElProbInMat[i]) break;
350    }
351    if(i>=nE) i=nE-1;                        // Top limit for the Element
352  }
353  G4Element* pElement=(*theElementVector)[i];
354  Z=static_cast<G4int>(pElement->GetZ());
355#ifdef debug
356    G4cout<<"G4QElastic::PostStepDoIt: i="<<i<<", Z(element)="<<Z<<G4endl;
357#endif
358  if(Z<=0)
359  {
360    G4cerr<<"---Warning---G4QElastic::PostStepDoIt: Element with Z="<<Z<<G4endl;
361    if(Z<0) return 0;
362  }
363  std::vector<G4double>* SPI = IsoProbInEl[i];// Vector of summedProbabilities for isotopes
364  std::vector<G4int>* IsN = ElIsoN[i];     // Vector of "#of neutrons" in the isotope El[i]
365  G4int nofIsot=SPI->size();               // #of isotopes in the element i
366#ifdef debug
367  G4cout<<"G4QElastic::PosStDoIt: nI="<<nofIsot<<",T="<<(*SPI)[nofIsot-1]<<G4endl;
368#endif
369  G4int j=0;
370  if(nofIsot>1)
371  {
372    G4double rndI=(*SPI)[nofIsot-1]*G4UniformRand(); // Randomize the isotop of the Element
373    for(j=0; j<nofIsot; ++j)
374    {
375#ifdef debug
376      G4cout<<"G4QElastic::PostStepDoIt: SP["<<j<<"]="<<(*SPI)[j]<<", r="<<rndI<<G4endl;
377#endif
378      if(rndI < (*SPI)[j]) break;
379    }
380    if(j>=nofIsot) j=nofIsot-1;            // Top limit for the isotope
381  }
382  G4int N =(*IsN)[j]; ;                    // Randomized number of neutrons
383#ifdef debug
384  G4cout<<"G4QElastic::PostStepDoIt: j="<<i<<", N(isotope)="<<N<<", MeV="<<MeV<<G4endl;
385#endif
386  if(N<0)
387  {
388    G4cerr<<"*Warning*G4QElastic::PostStepDoIt: Isotope with Z="<<Z<<", 0>N="<<N<<G4endl;
389    return 0;
390  }
391  nOfNeutrons=N;                           // Remember it for the energy-momentum check
392#ifdef debug
393  G4cout<<"G4QElastic::PostStepDoIt: N="<<N<<" for element with Z="<<Z<<G4endl;
394#endif
395  if(N<0)
396  {
397    G4cerr<<"*Warning*G4QElastic::PostStepDoIt:Element with N="<<N<< G4endl;
398    return 0;
399  }
400  aParticleChange.Initialize(track);
401#ifdef debug
402  G4cout<<"G4QElastic::PostStepDoIt: track is initialized"<<G4endl;
403#endif
404  G4double weight        = track.GetWeight();
405  G4double localtime     = track.GetGlobalTime();
406  G4ThreeVector position = track.GetPosition();
407#ifdef debug
408  G4cout<<"G4QElastic::PostStepDoIt: before Touchable extraction"<<G4endl;
409#endif
410  G4TouchableHandle trTouchable = track.GetTouchableHandle();
411#ifdef debug
412  G4cout<<"G4QElastic::PostStepDoIt: Touchable is extracted"<<G4endl;
413#endif
414  //
415  G4int targPDG=90000000+Z*1000+N;         // CHIPS PDG Code of the target nucleus
416  G4QPDGCode targQPDG(targPDG);         // @@ one can use G4Ion and get rid of CHIPS World
417  G4double tM=targQPDG.GetMass();          // CHIPS target mass in MeV
418  G4double kinEnergy= projHadron->GetKineticEnergy()*MeV; // Kin energy in MeV (Is *MeV n?)
419  G4ParticleMomentum dir = projHadron->GetMomentumDirection();// It is a unit three-vector
420  G4LorentzVector tot4M=proj4M+G4LorentzVector(0.,0.,0.,tM); // Total 4-mom of the reaction
421#ifdef debug
422  G4cout<<"G4QElastic::PostStepDoIt: tM="<<tM<<", p4M="<<proj4M<<", t4M="<<tot4M<<G4endl;
423#endif
424  EnMomConservation=tot4M;                 // Total 4-mom of reaction for E/M conservation
425  G4VQCrossSection* CSmanager=G4QElasticCrossSection::GetPointer();
426  // @@ Probably this is not necessary any more
427#ifdef debug
428  G4cout<<"G4QElas::PSDI:false,P="<<Momentum<<",Z="<<Z<<",N="<<N<<",PDG="<<projPDG<<G4endl;
429#endif
430  G4double xSec=CSmanager->GetCrossSection(false, Momentum, Z, N, projPDG);// Rec.CrossSect
431#ifdef debug
432  G4cout<<"G4QElast::PSDI:pPDG="<<projPDG<<",P="<<Momentum<<",CS="<<xSec/millibarn<<G4endl;
433#endif
434#ifdef nandebug
435  if(xSec>0. || xSec<0. || xSec==0);
436  else  G4cout<<"*Warning*G4QElastic::PostStDoIt: xSec="<<xSec/millibarn<<G4endl;
437#endif
438  // @@ check a possibility to separate p, n, or alpha (!)
439  if(xSec <= 0.) // The cross-section iz 0 -> Do Nothing
440  {
441#ifdef pdebug
442    G4cerr<<"*Warning*G4QElastic::PostStDoIt: *Zero cross-section* PDG="<<projPDG<<",tPDG="
443          <<targPDG<<",P="<<Momentum<<G4endl;
444#endif
445    //Do Nothing Action insead of the reaction
446    aParticleChange.ProposeEnergy(kinEnergy);
447    aParticleChange.ProposeLocalEnergyDeposit(0.);
448    aParticleChange.ProposeMomentumDirection(dir) ;
449    return G4VDiscreteProcess::PostStepDoIt(track,step);
450  }
451  G4double mint=CSmanager->GetExchangeT(Z,N,projPDG); // functional randomized -t in MeV^2
452#ifdef pdebug
453  G4cout<<"G4QElast::PSDI:pPDG="<<projPDG<<",tPDG="<<targPDG<<",P="<<Momentum<<",CS="
454        <<xSec<<",-t="<<mint<<G4endl;
455#endif
456#ifdef nandebug
457  if(mint>-.0000001);
458  else  G4cout<<"*Warning*G4QElastic::PostStDoIt:-t="<<mint<<G4endl;
459#endif
460  //G4double cost=1.-mint/twop2cm;              // cos(theta) in CMS
461  G4double cost=1.-mint/CSmanager->GetHMaxT();// cos(theta) in CMS
462  //
463#ifdef ppdebug
464  G4cout<<"G4QElastic::PoStDoI:t="<<mint<<",dpcm2="<<CSmanager->GetHMaxT()<<",Ek="
465        <<kinEnergy<<",tM="<<tM<<",pM="<<pM<<",cost="<<cost<<G4endl;
466#endif
467  if(cost>1. || cost<-1. || !(cost>-1. || cost<1.))
468  {
469    if(cost>1.000001 || cost<-1.000001 || !(cost>-1. || cost<1.))
470    {
471      G4double tM2=tM*tM;                         // Squared target mass
472      G4double pEn=pM+kinEnergy;                  // tot projectile Energy in MeV
473      G4double sM=(tM+tM)*pEn+tM2+pM2;            // Mondelstam s
474      G4double twop2cm=(tM2+tM2)*(pEn*pEn-pM2)/sM;// Max_t/2 (2*p^2_cm)
475      G4cout<<"*Warning*G4QElastic::PostStepDoIt:cos="<<cost<<",t="<<mint<<",T="<<kinEnergy
476            <<",tM="<<tM<<",tmax="<<2*kinEnergy*tM<<",p="<<projPDG<<",t="<<targPDG<<G4endl;
477      G4cout<<"..G4QElastic::PoStDoI: dpcm2="<<twop2cm<<"="<<CSmanager->GetHMaxT()<<G4endl;
478    }
479    if     (cost>1.)  cost=1.;
480    else if(cost<-1.) cost=-1.;
481  }
482  G4LorentzVector reco4M=G4LorentzVector(0.,0.,0.,tM);      // 4mom of the recoil target
483  G4LorentzVector dir4M=tot4M-G4LorentzVector(0.,0.,0.,(tot4M.e()-tM-pM)*.01);
484  if(!G4QHadron(tot4M).RelDecayIn2(scat4M, reco4M, dir4M, cost, cost))
485  {
486    G4cerr<<"G4QElastic::PSD:t4M="<<tot4M<<",pM="<<pM<<",tM="<<tM<<",cost="<<cost<<G4endl;
487    //G4Exception("G4QElastic::PostStepDoIt:","009",FatalException,"Decay of ElasticComp");
488  }
489#ifdef debug
490  G4cout<<"G4QElastic::PoStDoIt:s4M="<<scat4M<<"+r4M="<<reco4M<<"="<<scat4M+reco4M<<G4endl;
491  G4cout<<"G4QElastic::PoStDoIt: scatE="<<scat4M.e()-pM<<", recoE="<<reco4M.e()-tM<<",d4M="
492        <<tot4M-scat4M-reco4M<<G4endl;
493#endif
494  // Update G4VParticleChange for the scattered projectile
495  G4double finE=scat4M.e()-pM;             // Final kinetic energy of the scattered proton
496  if(finE>0.0) aParticleChange.ProposeEnergy(finE);
497  else
498  {
499    if(finE<-1.e-8 || !(finE>-1.||finE<1.)) // NAN or negative
500      G4cerr<<"*Warning*G4QElastic::PostStDoIt: Zero or negative scattered E="<<finE
501            <<", s4M="<<scat4M<<", r4M="<<reco4M<<", d4M="<<tot4M-scat4M-reco4M<<G4endl;
502    //G4Exception("G4QElastic::PostStDoIt()","009", FatalException," <0 or nan energy");
503    aParticleChange.ProposeEnergy(0.) ;
504    aParticleChange.ProposeTrackStatus(fStopButAlive);
505  }
506  G4ThreeVector findir=scat4M.vect()/scat4M.rho();  // Unit vector in new direction
507  aParticleChange.ProposeMomentumDirection(findir); // new direction for the scattered part
508  EnMomConservation-=scat4M;                        // It must be initialized by (pE+tM,pP)
509  // This is how in general the secondary should be identified
510  G4DynamicParticle* theSec = new G4DynamicParticle; // A secondary for the recoil hadron
511  //G4int targPDG=2212;                      // PDG for the recoil proton @@only for p targ
512  //G4ParticleDefinition* theDefinition=G4Proton::Proton(); // @@ only for p target
513  G4int aA = Z+N;
514#ifdef pdebug
515  G4cout<<"G4QElastic::PostStepDoIt: Ion Z="<<Z<<", A="<<aA<<G4endl;
516#endif
517  G4ParticleDefinition* theDefinition=G4ParticleTable::GetParticleTable()
518                                                                       ->FindIon(Z,aA,0,Z);
519  if(!theDefinition)G4cout<<"*Warning*G4QElastic::PostStepDoIt:drop PDG="<<targPDG<<G4endl;
520#ifdef pdebug
521  G4cout<<"G4QElastic::PostStepDoIt:RecoilName="<<theDefinition->GetParticleName()<<G4endl;
522#endif
523  theSec->SetDefinition(theDefinition);
524
525  EnMomConservation-=reco4M;
526#ifdef tdebug
527  G4cout<<"G4QElastic::PostSDoIt:"<<targPDG<<reco4M<<reco4M.m()<<EnMomConservation<<G4endl;
528#endif
529  theSec->Set4Momentum(reco4M);
530#ifdef debug
531  G4ThreeVector curD=theSec->GetMomentumDirection();
532  G4double curM=theSec->GetMass();
533  G4double curE=theSec->GetKineticEnergy()+curM;
534  G4cout<<"G4QElastic::PSDoIt:p="<<curD<<curD.mag()<<",e="<<curE<<",m="<<curM<<G4endl;
535#endif
536  // Make a recoil nucleus
537  G4Track* aNewTrack = new G4Track(theSec, localtime, position );
538  aNewTrack->SetWeight(weight);                                   //    weighted
539  aNewTrack->SetTouchableHandle(trTouchable);
540  aParticleChange.AddSecondary( aNewTrack );
541#ifdef debug
542    G4cout<<"G4QElastic::PostStepDoIt: **** PostStepDoIt is done ****"<<G4endl;
543#endif
544  return G4VDiscreteProcess::PostStepDoIt(track, step);
545}
546
547// @@ For future improvement @@
548G4double G4QElastic::CalculateXSt(G4bool oxs, G4bool xst, G4double p, G4int Z, G4int N,
549                                  G4int pPDG) 
550{
551  static G4bool init=false;
552  static G4bool first=true;
553  static G4VQCrossSection* CSmanager;
554  if(first)                              // Connection with a singletone
555  {
556    CSmanager=G4QElasticCrossSection::GetPointer();
557    first=false;
558  }
559  G4double res=0.;
560  if(oxs && xst)                         // Only the Cross-Section can be returened
561  {
562    res=CSmanager->GetCrossSection(true, p, Z, N, pPDG); // XS for isotope
563  }
564  else if(!oxs && xst)                   // Calculate Cross-Section & prepare differential
565  {
566    res=CSmanager->GetCrossSection(false, p, Z, N, pPDG);// XS for isotope + init t-distr.
567    // The XS for the nucleus must be calculated the last
568    init=true;
569  }
570  else if(init)                          // Return t-value for scattering (=G4QElastic)
571  {
572    if(oxs) res=CSmanager->GetHMaxT();   // Calculate the max_t value
573    else res=CSmanager->GetExchangeT(Z, N, pPDG); // functionally randomized -t in MeV^2
574  }
575  else G4cout<<"*Warning*G4QElastic::CalculateXSt:*NotInitiatedScattering"<<G4endl;
576  return res;
577}
Note: See TracBrowser for help on using the repository browser.