Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4HadronStoppingProcess.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//
27//---------------------------------------------------------------------
28//
29// GEANT4 Class
30//
31// File name: G4HadronStoppingProcess
32//
33// Author V.Ivanchenko 21 April 2012
34//
35//
36// Class Description:
37//
38// Base process class for nuclear capture of negatively charged particles
39//
40// Modifications:
41//
42// 20120522 M. Kelsey -- Set enableAtRestDoIt flag for G4ProcessManager
43// 20120914 M. Kelsey -- Pass subType in base ctor, remove enable flags
44// 20121004 K. Genser -- use G4HadronicProcessType in the constructor
45// 20121016 K. Genser -- Reverting to use one argument c'tor
46// 20140818 K. Genser -- Labeled tracks using G4PhysicsModelCatalog
47//
48//------------------------------------------------------------------------
49
53#include "G4EmCaptureCascade.hh"
54#include "G4Nucleus.hh"
55#include "G4HadFinalState.hh"
56#include "G4HadProjectile.hh"
57#include "G4HadSecondary.hh"
58#include "G4Material.hh"
59#include "G4Element.hh"
60
61//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
62
65 fElementSelector(new G4ElementSelector()),
66 fEmCascade(new G4EmCaptureCascade()), // Owned by InteractionRegistry
67 fBoundDecay(0),
68 emcID(-1),
69 ncID(-1),
70 dioID(-1)
71{
72 // Modify G4VProcess flags to emulate G4VRest instead of G4VDiscrete
73 enableAtRestDoIt = true;
74 enablePostStepDoIt = false;
75
77}
78
79//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
80
82{
83 //G4HadronicProcessStore::Instance()->DeRegisterExtraProcess(this);
84 delete fElementSelector;
85 // NOTE: fEmCascade and fEmBoundDecay owned by registry, not locally
86}
87
88//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
89
91{
92 return (p.GetPDGCharge() < 0.0);
93}
94
95//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
96
97void
99{
101 emcID = G4PhysicsModelCatalog::GetModelID(G4String("model_" + (GetProcessName() + "_EMCascade")));
102 ncID = G4PhysicsModelCatalog::GetModelID(G4String("model_" + (GetProcessName() + "_NuclearCapture")));
103 dioID = G4PhysicsModelCatalog::GetModelID(G4String("model_" + (GetProcessName() + "_DIO")));
104}
105
106//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
107
109{
111}
112
113//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
114
117{
119 return 0.0;
120}
121
122//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
123
126{
128 return DBL_MAX;
129}
130
131//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
132
134 const G4Step&)
135{
136 // if primary is not Alive then do nothing
138
140 const G4Element* elm = fElementSelector->SelectZandA(track, nucleus);
141
142 G4HadFinalState* result = 0;
143 thePro.Initialise(track);
144
145 // save track time an dstart capture from zero time
147 G4double time0 = track.GetGlobalTime();
148
149 G4bool nuclearCapture = true;
150
151 // Do the electromagnetic cascade in the nuclear field.
152 // EM cascade should keep G4HadFinalState object,
153 // because it will not be deleted at the end of this method
154 //
155 result = fEmCascade->ApplyYourself(thePro, *nucleus);
156 G4double ebound = result->GetLocalEnergyDeposit();
157 G4double edep = 0.0;
158 G4int nSecondaries = (G4int)result->GetNumberOfSecondaries();
159 G4int nEmCascadeSec = nSecondaries;
160
161 // Try decay from bound level
162 // For mu- the time of projectile should be changed.
163 // Decay should keep G4HadFinalState object,
164 // because it will not be deleted at the end of this method.
165 //
166 thePro.SetBoundEnergy(ebound);
167 if(fBoundDecay) {
168 G4HadFinalState* resultDecay =
169 fBoundDecay->ApplyYourself(thePro, *nucleus);
170 G4int n = (G4int)resultDecay->GetNumberOfSecondaries();
171 if(0 < n) {
172 nSecondaries += n;
173 result->AddSecondaries(resultDecay);
174 }
175 if(resultDecay->GetStatusChange() == stopAndKill) {
176 nuclearCapture = false;
177 }
178 resultDecay->Clear();
179 }
180
181 if(nuclearCapture) {
182
183 // delay of capture
184 G4double capTime = thePro.GetGlobalTime();
186
187 // select model
188 G4HadronicInteraction* model = 0;
189 try {
190 model = ChooseHadronicInteraction(thePro, *nucleus,
191 track.GetMaterial(), elm);
192 }
193 catch(G4HadronicException & aE) {
195 ed << "Target element "<<elm->GetName()<<" Z= "
196 << nucleus->GetZ_asInt() << " A= "
197 << nucleus->GetA_asInt() << G4endl;
198 DumpState(track,"ChooseHadronicInteraction",ed);
199 ed << " No HadronicInteraction found out" << G4endl;
200 G4Exception("G4HadronStoppingProcess::AtRestDoIt", "had005",
201 FatalException, ed);
202 }
203
204 G4HadFinalState* resultNuc = 0;
205 G4int reentryCount = 0;
206 do {
207 // sample final state
208 // nuclear interaction should keep G4HadFinalState object
209 // model should define time of each secondary particle
210 try {
211 resultNuc = model->ApplyYourself(thePro, *nucleus);
212 ++reentryCount;
213 }
214 catch(G4HadronicException & aR) {
216 ed << "Call for " << model->GetModelName() << G4endl;
217 ed << "Target element "<<elm->GetName()<<" Z= "
218 << nucleus->GetZ_asInt()
219 << " A= " << nucleus->GetA_asInt() << G4endl;
220 DumpState(track,"ApplyYourself",ed);
221 ed << " ApplyYourself failed" << G4endl;
222 G4Exception("G4HadronStoppingProcess::AtRestDoIt", "had006",
223 FatalException, ed);
224 }
225
226 // Check the result for catastrophic energy non-conservation
227 resultNuc = CheckResult(thePro, *nucleus, resultNuc);
228
229 if(reentryCount>100) {
231 ed << "Call for " << model->GetModelName() << G4endl;
232 ed << "Target element "<<elm->GetName()<<" Z= "
233 << nucleus->GetZ_asInt()
234 << " A= " << nucleus->GetA_asInt() << G4endl;
235 DumpState(track,"ApplyYourself",ed);
236 ed << " ApplyYourself does not completed after 100 attempts" << G4endl;
237 G4Exception("G4HadronStoppingProcess::AtRestDoIt", "had006",
238 FatalException, ed);
239 }
240 // Loop checking, 06-Aug-2015, Vladimir Ivanchenko
241 } while(!resultNuc);
242
243 edep = resultNuc->GetLocalEnergyDeposit();
244 std::size_t nnuc = resultNuc->GetNumberOfSecondaries();
245
246 // add delay time of capture
247 for(std::size_t i=0; i<nnuc; ++i) {
248 G4HadSecondary* sec = resultNuc->GetSecondary(i);
249 sec->SetTime(capTime + sec->GetTime());
250 }
251
252 nSecondaries += nnuc;
253 result->AddSecondaries(resultNuc);
254 resultNuc->Clear();
255 }
256
257 // Fill results
258 //
262 G4double w = track.GetWeight();
264 for(G4int i=0; i<nSecondaries; ++i) {
265 G4HadSecondary* sec = result->GetSecondary(i);
266
267 // add track global time to the reaction time
268 G4double time = sec->GetTime();
269 if(time < 0.0) { time = 0.0; }
270 time += time0;
271
272 // create secondary track
273 G4Track* t = new G4Track(sec->GetParticle(),
274 time,
275 track.GetPosition());
276 t->SetWeight(w*sec->GetWeight());
277
278 // use SetCreatorModelID to "label" the track
279 if (i<nEmCascadeSec) {
280 t->SetCreatorModelID(emcID);
281 } else if (nuclearCapture) {
282 t->SetCreatorModelID(ncID);
283 } else {
284 t->SetCreatorModelID(dioID);
285 }
286
289 }
290 result->Clear();
291
292 if (epReportLevel != 0) {
293 CheckEnergyMomentumConservation(track, *nucleus);
294 }
295 return theTotalResult;
296}
297
298//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
299
300void G4HadronStoppingProcess::ProcessDescription(std::ostream& outFile) const
301{
302 outFile << "Base process for negatively charged particle capture at rest.\n";
303}
304
305//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double condition(const G4ErrorSymMatrix &m)
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
G4ForceCondition
@ NotForced
@ stopAndKill
@ fHadronAtRest
@ fStopAndKill
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
virtual const G4Element * SelectZandA(const G4Track &track, G4Nucleus *)
const G4String & GetName() const
Definition: G4Element.hh:127
G4HadFinalStateStatus GetStatusChange() const
G4double GetLocalEnergyDeposit() const
void AddSecondaries(const std::vector< G4HadSecondary > &addSecs)
std::size_t GetNumberOfSecondaries() const
G4HadSecondary * GetSecondary(size_t i)
void Initialise(const G4Track &aT)
void SetGlobalTime(G4double t)
void SetBoundEnergy(G4double e)
G4double GetGlobalTime() const
G4DynamicParticle * GetParticle()
G4double GetWeight() const
void SetTime(G4double aT)
G4double GetTime() const
virtual G4bool IsApplicable(const G4ParticleDefinition &)
virtual void ProcessDescription(std::ostream &outFile) const
virtual void BuildPhysicsTable(const G4ParticleDefinition &)
G4HadronStoppingProcess(const G4String &name="hadronCaptureAtRest")
virtual G4double AtRestGetPhysicalInteractionLength(const G4Track &track, G4ForceCondition *condition)
virtual void PreparePhysicsTable(const G4ParticleDefinition &)
virtual G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition)
virtual G4VParticleChange * AtRestDoIt(const G4Track &, const G4Step &)
virtual G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &targetNucleus)
const G4String & GetModelName() const
void RegisterExtraProcess(G4VProcess *)
void RegisterParticleForExtraProcess(G4VProcess *, const G4ParticleDefinition *)
static G4HadronicProcessStore * Instance()
void PrintInfo(const G4ParticleDefinition *)
G4HadProjectile thePro
G4Nucleus * GetTargetNucleusPointer()
G4HadFinalState * CheckResult(const G4HadProjectile &thePro, const G4Nucleus &targetNucleus, G4HadFinalState *result)
G4ParticleChange * theTotalResult
G4HadronicInteraction * ChooseHadronicInteraction(const G4HadProjectile &aHadProjectile, G4Nucleus &aTargetNucleus, const G4Material *aMaterial, const G4Element *anElement)
void CheckEnergyMomentumConservation(const G4Track &, const G4Nucleus &)
void DumpState(const G4Track &, const G4String &, G4ExceptionDescription &)
G4int GetA_asInt() const
Definition: G4Nucleus.hh:99
G4int GetZ_asInt() const
Definition: G4Nucleus.hh:105
void AddSecondary(G4Track *aSecondary)
void Initialize(const G4Track &) override
G4double GetPDGCharge() const
static G4int GetModelID(const G4int modelIndex)
Definition: G4Step.hh:62
G4double GetWeight() const
void SetWeight(G4double aValue)
const G4ThreeVector & GetPosition() const
void SetTouchableHandle(const G4TouchableHandle &apValue)
G4double GetGlobalTime() const
G4Material * GetMaterial() const
const G4TouchableHandle & GetTouchableHandle() const
void SetCreatorModelID(const G4int id)
void ProposeTrackStatus(G4TrackStatus status)
void ProposeWeight(G4double finalWeight)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void SetNumberOfSecondaries(G4int totSecondaries)
G4bool enableAtRestDoIt
Definition: G4VProcess.hh:363
G4bool enablePostStepDoIt
Definition: G4VProcess.hh:365
const G4String & GetProcessName() const
Definition: G4VProcess.hh:386
#define DBL_MAX
Definition: templates.hh:62