Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4WHadronElasticProcess.cc
Go to the documentation of this file.
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$
27//
28// Geant4 Hadron Elastic Scattering Process
29//
30// Created 21 April 2006 V.Ivanchenko
31//
32// Modified:
33// 24.04.06 V.Ivanchenko add neutron scattering on hydrogen from CHIPS
34// 07.06.06 V.Ivanchenko fix problem of rotation of final state
35// 25.07.06 V.Ivanchenko add 19 MeV low energy for CHIPS
36// 26.09.06 V.Ivanchenko add lowestEnergy
37// 20.10.06 V.Ivanchenko initialise lowestEnergy=0 for neitrals, eV for charged
38// 23.01.07 V.Ivanchenko add cross section interfaces with Z and A
39// 02.05.07 V.Ivanchenko add He3
40// 13.01.10 M.Kosov: Commented not used G4QElasticCrossSection & G4QCHIPSWorld
41// 24.02.11 V.Ivanchenko use particle name in IfApplicable,
42// added anti particles for light ions
43// 07.09.11 M.Kelsey: Follow chanhe to G4HadFinalState interface
44// 14.09.12 M.Kelsey: Pass subType code to base ctor
45//
46
47#include <iostream>
48#include <typeinfo>
49
51#include "G4SystemOfUnits.hh"
52#include "G4Nucleus.hh"
53#include "G4ProcessManager.hh"
59
63 theNeutron = G4Neutron::Neutron();
64 lowestEnergy = 1.*keV;
65 lowestEnergyNeutron = 1.e-6*eV;
66 G4HadronicDeprecate("G4WHadronElasticProcess");
67}
68
70{}
71
73{
74 char* dirName = getenv("G4PhysListDocDir");
75 if (dirName) {
76 std::ofstream outFile;
77 G4String outFileName = GetProcessName() + ".html";
78 G4String pathName = G4String(dirName) + "/" + outFileName;
79 outFile.open(pathName);
80 outFile << "<html>\n";
81 outFile << "<head>\n";
82
83 outFile << "<title>Description of G4WHadronElasticProcess</title>\n";
84 outFile << "</head>\n";
85 outFile << "<body>\n";
86
87 outFile << "G4WHadronElasticProcess handles the elastic scattering of\n"
88 << "hadrons by invoking one or more hadronic models and one or\n"
89 << "more hadronic cross sections.\n";
90
91 outFile << "</body>\n";
92 outFile << "</html>\n";
93 outFile.close();
94 }
95}
96
97
100 const G4Step& /*step*/)
101{
104 G4double weight = track.GetWeight();
106
107 // For elastic scattering, _any_ result is considered an interaction
109
110 G4double kineticEnergy = track.GetKineticEnergy();
111 const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
112 const G4ParticleDefinition* part = dynParticle->GetDefinition();
113
114 // NOTE: Very low energy scatters were causing numerical (FPE) errors
115 // in earlier releases; these limits have not been changed since.
116 if (part == theNeutron) {
117 if(kineticEnergy <= lowestEnergyNeutron) return theTotalResult;
118 } else if(kineticEnergy <= lowestEnergy) return theTotalResult;
119
120 G4Material* material = track.GetMaterial();
121 G4Nucleus* targNucleus = GetTargetNucleusPointer();
122
123 // Select element
124 G4Element* elm = 0;
125 try
126 {
127 elm = GetCrossSectionDataStore()->SampleZandA(dynParticle, material,
128 *targNucleus);
129 }
130 catch(G4HadronicException & aR)
131 {
133 DumpState(track,"SampleZandA",ed);
134 ed << " PostStepDoIt failed on element selection" << G4endl;
135 G4Exception("G4WHadronElasticProcess::PostStepDoIt", "had003",
136 FatalException, ed);
137 }
138 G4HadronicInteraction* hadi = 0;
139 try
140 {
141 hadi = ChooseHadronicInteraction( kineticEnergy, material, elm );
142 }
143 catch(G4HadronicException & aE)
144 {
146 ed << "Target element "<< elm->GetName()<<" Z= "
147 << targNucleus->GetZ_asInt() << " A= "
148 << targNucleus->GetA_asInt() << G4endl;
149 DumpState(track,"ChooseHadronicInteraction",ed);
150 ed << " No HadronicInteraction found out" << G4endl;
151 G4Exception("G4WHadronElasticProcess::PostStepDoIt", "had005",
152 FatalException, ed);
153 }
154
155 size_t idx = track.GetMaterialCutsCouple()->GetIndex();
157 ->GetEnergyCutsVector(3)))[idx];
158 hadi->SetRecoilEnergyThreshold(tcut);
159
160 // Initialize the hadronic projectile from the track
161 // G4cout << "track " << track.GetDynamicParticle()->Get4Momentum()<<G4endl;
162 G4HadProjectile theProj(track);
163 if(verboseLevel>1) {
164 G4cout << "G4WHadronElasticProcess::PostStepDoIt for "
165 << part->GetParticleName()
166 << " in " << material->GetName()
167 << " Target Z= " << targNucleus->GetZ_asInt()
168 << " A= " << targNucleus->GetA_asInt() << G4endl;
169 }
170
171 G4HadFinalState* result = 0;
172 try
173 {
174 result = hadi->ApplyYourself( theProj, *targNucleus);
175 }
176 catch(G4HadronicException aR)
177 {
179 ed << "Call for " << hadi->GetModelName() << G4endl;
180 ed << "Target element "<< elm->GetName()<<" Z= "
181 << targNucleus->GetZ_asInt()
182 << " A= " << targNucleus->GetA_asInt() << G4endl;
183 DumpState(track,"ApplyYourself",ed);
184 ed << " ApplyYourself failed" << G4endl;
185 G4Exception("G4WHadronElasticProcess::PostStepDoIt", "had006",
186 FatalException, ed);
187 }
188
189 // Check the result for catastrophic energy non-conservation
190 // cannot be applied because is not guranteed that recoil
191 // nucleus is created
192 // result = CheckResult(theProj, targNucleus, result);
193
194 // directions
195 G4ThreeVector indir = track.GetMomentumDirection();
196 G4double phi = CLHEP::twopi*G4UniformRand();
197 G4ThreeVector it(0., 0., 1.);
198 G4ThreeVector outdir = result->GetMomentumChange();
199
200 if(verboseLevel>1) {
201 G4cout << "Efin= " << result->GetEnergyChange()
202 << " de= " << result->GetLocalEnergyDeposit()
203 << " nsec= " << result->GetNumberOfSecondaries()
204 << " dir= " << outdir
205 << G4endl;
206 }
207
208 // energies
209 G4double edep = result->GetLocalEnergyDeposit();
210 G4double efinal = result->GetEnergyChange();
211 if(efinal < 0.0) { efinal = 0.0; }
212 if(edep < 0.0) { edep = 0.0; }
213
214 // NOTE: Very low energy scatters were causing numerical (FPE) errors
215 // in earlier releases; these limits have not been changed since.
216 if((part == theNeutron && efinal <= lowestEnergyNeutron) ||
217 (part != theNeutron && efinal <= lowestEnergy)) {
218 edep += efinal;
219 efinal = 0.0;
220 }
221
222 // primary change
224
225 G4TrackStatus status = track.GetTrackStatus();
226 if(efinal > 0.0) {
227 outdir.rotate(phi, it);
228 outdir.rotateUz(indir);
230 } else {
231 if(part->GetProcessManager()->GetAtRestProcessVector()->size() > 0)
232 { status = fStopButAlive; }
233 else { status = fStopAndKill; }
235 }
236
237 //G4cout << "Efinal= " << efinal << " TrackStatus= " << status << G4endl;
238
240
241 // recoil
242 if(result->GetNumberOfSecondaries() > 0) {
243 G4DynamicParticle* p = result->GetSecondary(0)->GetParticle();
244
245 if(p->GetKineticEnergy() > lowestEnergy) {
248 // G4cout << "recoil " << pdir << G4endl;
249 //!! is not needed for models inheriting G4HadronElastic
250 pdir.rotate(phi, it);
251 pdir.rotateUz(indir);
252 // G4cout << "recoil rotated " << pdir << G4endl;
253 p->SetMomentumDirection(pdir);
254
255 // in elastic scattering time and weight are not changed
256 G4Track* t = new G4Track(p, track.GetGlobalTime(),
257 track.GetPosition());
258 t->SetWeight(weight);
261
262 } else {
263 edep += p->GetKineticEnergy();
264 delete p;
265 }
266 }
269 result->Clear();
270
271 return theTotalResult;
272}
@ FatalException
#define G4HadronicDeprecate(name)
@ fHadronElastic
G4TrackStatus
@ fStopAndKill
@ fStopButAlive
double G4double
Definition: G4Types.hh:64
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:72
Hep3Vector & rotate(double, const Hep3Vector &)
Definition: ThreeVectorR.cc:28
G4Element * SampleZandA(const G4DynamicParticle *, const G4Material *, G4Nucleus &target)
void SetMomentumDirection(const G4ThreeVector &aDirection)
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4String & GetName() const
Definition: G4Element.hh:127
G4double GetEnergyChange() const
G4double GetLocalEnergyDeposit() const
G4int GetNumberOfSecondaries() const
const G4ThreeVector & GetMomentumChange() const
G4HadSecondary * GetSecondary(size_t i)
G4DynamicParticle * GetParticle()
virtual G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &targetNucleus)=0
const G4String & GetModelName() const
void SetRecoilEnergyThreshold(G4double val)
G4Nucleus * GetTargetNucleusPointer()
G4ParticleChange * theTotalResult
void AddDataSet(G4VCrossSectionDataSet *aDataSet)
G4CrossSectionDataStore * GetCrossSectionDataStore()
G4HadronicInteraction * ChooseHadronicInteraction(G4double kineticEnergy, G4Material *aMaterial, G4Element *anElement)
void DumpState(const G4Track &, const G4String &, G4ExceptionDescription &)
const G4String & GetName() const
Definition: G4Material.hh:177
static G4Neutron * Neutron()
Definition: G4Neutron.cc:104
G4int GetA_asInt() const
Definition: G4Nucleus.hh:109
G4int GetZ_asInt() const
Definition: G4Nucleus.hh:115
void AddSecondary(G4Track *aSecondary)
void ProposeEnergy(G4double finalEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
virtual void Initialize(const G4Track &)
G4ProcessManager * GetProcessManager() const
const G4String & GetParticleName() const
G4ProcessVector * GetAtRestProcessVector(G4ProcessVectorTypeIndex typ=typeGPIL) const
G4int size() const
const std::vector< G4double > * GetEnergyCutsVector(size_t pcIdx) const
static G4ProductionCutsTable * GetProductionCutsTable()
Definition: G4Step.hh:78
G4TrackStatus GetTrackStatus() const
G4double GetWeight() const
void SetWeight(G4double aValue)
const G4ThreeVector & GetPosition() const
void SetTouchableHandle(const G4TouchableHandle &apValue)
G4double GetGlobalTime() const
G4Material * GetMaterial() const
const G4DynamicParticle * GetDynamicParticle() const
const G4TouchableHandle & GetTouchableHandle() const
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
const G4MaterialCutsCouple * GetMaterialCutsCouple() const
void ProposeTrackStatus(G4TrackStatus status)
void ProposeNonIonizingEnergyDeposit(G4double anEnergyPart)
void ProposeWeight(G4double finalWeight)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void SetNumberOfSecondaries(G4int totSecondaries)
void ClearNumberOfInteractionLengthLeft()
Definition: G4VProcess.hh:418
G4int verboseLevel
Definition: G4VProcess.hh:368
const G4String & GetProcessName() const
Definition: G4VProcess.hh:379
virtual G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
G4WHadronElasticProcess(const G4String &procName="hadElastic")
virtual void Description() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76