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
G4HadronElasticProcess.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 26 July 2012 V.Ivanchenko from G4WHadronElasticProcess
31//
32// Modified:
33// 14-Sep-12 M.Kelsey -- Pass subType code to base ctor
34
35#include <iostream>
36#include <typeinfo>
37
39#include "G4SystemOfUnits.hh"
40#include "G4Nucleus.hh"
41#include "G4ProcessManager.hh"
47
49 : G4HadronicProcess(pName, fHadronElastic), isInitialised(false)
50{
52 lowestEnergy = 1.*keV;
53}
54
56{}
57
59{
60 char* dirName = getenv("G4PhysListDocDir");
61 if (dirName) {
62 std::ofstream outFile;
63 G4String outFileName = GetProcessName() + ".html";
64 G4String pathName = G4String(dirName) + "/" + outFileName;
65 outFile.open(pathName);
66 outFile << "<html>\n";
67 outFile << "<head>\n";
68
69 outFile << "<title>Description of G4HadronElasticProcess</title>\n";
70 outFile << "</head>\n";
71 outFile << "<body>\n";
72
73 outFile << "G4HadronElasticProcess handles the elastic scattering of\n"
74 << "hadrons by invoking one or more hadronic models and one or\n"
75 << "more hadronic cross sections.\n";
76
77 outFile << "</body>\n";
78 outFile << "</html>\n";
79 outFile.close();
80 }
81}
82
85 const G4Step& /*step*/)
86{
89 G4double weight = track.GetWeight();
91
92 // For elastic scattering, _any_ result is considered an interaction
94
95 G4double kineticEnergy = track.GetKineticEnergy();
96 const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
97 const G4ParticleDefinition* part = dynParticle->GetDefinition();
98
99 // NOTE: Very low energy scatters were causing numerical (FPE) errors
100 // in earlier releases; these limits have not been changed since.
101 if (kineticEnergy <= lowestEnergy) return theTotalResult;
102
103 G4Material* material = track.GetMaterial();
104 G4Nucleus* targNucleus = GetTargetNucleusPointer();
105
106 // Select element
107 G4Element* elm = 0;
108 try
109 {
110 elm = GetCrossSectionDataStore()->SampleZandA(dynParticle, material,
111 *targNucleus);
112 }
113 catch(G4HadronicException & aR)
114 {
116 DumpState(track,"SampleZandA",ed);
117 ed << " PostStepDoIt failed on element selection" << G4endl;
118 G4Exception("G4HadronElasticProcess::PostStepDoIt", "had003",
119 FatalException, ed);
120 }
121 G4HadronicInteraction* hadi = 0;
122 try
123 {
124 hadi = ChooseHadronicInteraction( kineticEnergy, material, elm );
125 }
126 catch(G4HadronicException & aE)
127 {
129 ed << "Target element "<< elm->GetName()<<" Z= "
130 << targNucleus->GetZ_asInt() << " A= "
131 << targNucleus->GetA_asInt() << G4endl;
132 DumpState(track,"ChooseHadronicInteraction",ed);
133 ed << " No HadronicInteraction found out" << G4endl;
134 G4Exception("G4HadronElasticProcess::PostStepDoIt", "had005",
135 FatalException, ed);
136 }
137
138 size_t idx = track.GetMaterialCutsCouple()->GetIndex();
140 ->GetEnergyCutsVector(3)))[idx];
141 hadi->SetRecoilEnergyThreshold(tcut);
142
143 // Initialize the hadronic projectile from the track
144 // G4cout << "track " << track.GetDynamicParticle()->Get4Momentum()<<G4endl;
145 G4HadProjectile theProj(track);
146 if(verboseLevel>1) {
147 G4cout << "G4HadronElasticProcess::PostStepDoIt for "
148 << part->GetParticleName()
149 << " in " << material->GetName()
150 << " Target Z= " << targNucleus->GetZ_asInt()
151 << " A= " << targNucleus->GetA_asInt() << G4endl;
152 }
153
154 G4HadFinalState* result = 0;
155 try
156 {
157 result = hadi->ApplyYourself( theProj, *targNucleus);
158 }
159 catch(G4HadronicException aR)
160 {
162 ed << "Call for " << hadi->GetModelName() << G4endl;
163 ed << "Target element "<< elm->GetName()<<" Z= "
164 << targNucleus->GetZ_asInt()
165 << " A= " << targNucleus->GetA_asInt() << G4endl;
166 DumpState(track,"ApplyYourself",ed);
167 ed << " ApplyYourself failed" << G4endl;
168 G4Exception("G4HadronElasticProcess::PostStepDoIt", "had006",
169 FatalException, ed);
170 }
171
172 // Check the result for catastrophic energy non-conservation
173 // cannot be applied because is not guranteed that recoil
174 // nucleus is created
175 // result = CheckResult(theProj, targNucleus, result);
176
177 // directions
178 G4ThreeVector indir = track.GetMomentumDirection();
179 G4double phi = CLHEP::twopi*G4UniformRand();
180 G4ThreeVector it(0., 0., 1.);
181 G4ThreeVector outdir = result->GetMomentumChange();
182
183 if(verboseLevel>1) {
184 G4cout << "Efin= " << result->GetEnergyChange()
185 << " de= " << result->GetLocalEnergyDeposit()
186 << " nsec= " << result->GetNumberOfSecondaries()
187 << " dir= " << outdir
188 << G4endl;
189 }
190
191 // energies
192 G4double edep = result->GetLocalEnergyDeposit();
193 G4double efinal = result->GetEnergyChange();
194 if(efinal < 0.0) { efinal = 0.0; }
195 if(edep < 0.0) { edep = 0.0; }
196
197 // NOTE: Very low energy scatters were causing numerical (FPE) errors
198 // in earlier releases; these limits have not been changed since.
199 if(efinal <= lowestEnergy) {
200 edep += efinal;
201 efinal = 0.0;
202 }
203
204 // primary change
206
207 G4TrackStatus status = track.GetTrackStatus();
208 if(efinal > 0.0) {
209 outdir.rotate(phi, it);
210 outdir.rotateUz(indir);
212 } else {
213 if(part->GetProcessManager()->GetAtRestProcessVector()->size() > 0)
214 { status = fStopButAlive; }
215 else { status = fStopAndKill; }
217 }
218
219 //G4cout << "Efinal= " << efinal << " TrackStatus= " << status << G4endl;
220
222
223 // recoil
224 if(result->GetNumberOfSecondaries() > 0) {
225 G4DynamicParticle* p = result->GetSecondary(0)->GetParticle();
226
227 if(p->GetKineticEnergy() > tcut) {
230 // G4cout << "recoil " << pdir << G4endl;
231 //!! is not needed for models inheriting G4HadronElastic
232 pdir.rotate(phi, it);
233 pdir.rotateUz(indir);
234 // G4cout << "recoil rotated " << pdir << G4endl;
235 p->SetMomentumDirection(pdir);
236
237 // in elastic scattering time and weight are not changed
238 G4Track* t = new G4Track(p, track.GetGlobalTime(),
239 track.GetPosition());
240 t->SetWeight(weight);
243
244 } else {
245 edep += p->GetKineticEnergy();
246 delete p;
247 }
248 }
251 result->Clear();
252
253 return theTotalResult;
254}
255
256void
258{
259 if(!isInitialised) {
260 isInitialised = true;
261 if(G4Neutron::Neutron() == &part) { lowestEnergy = 1.e-6*eV; }
262 }
264}
265
267{
268 lowestEnergy = val;
269}
270
271void
273{
274 lowestEnergy = val;
275 G4HadronicDeprecate("G4HadronElasticProcess::SetLowestEnergyNeutron()");
276}
277
@ 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 void Description() const
virtual void PreparePhysicsTable(const G4ParticleDefinition &)
virtual G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
G4HadronElasticProcess(const G4String &procName="hadElastic")
virtual void SetLowestEnergy(G4double)
virtual void SetLowestEnergyNeutron(G4double)
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 &)
virtual void PreparePhysicsTable(const G4ParticleDefinition &)
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
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76