CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
CMSSIMPInelasticProcess.cc
Go to the documentation of this file.
1 
5 
6 #include "G4Types.hh"
7 #include "G4SystemOfUnits.hh"
8 #include "G4HadProjectile.hh"
9 #include "G4ElementVector.hh"
10 #include "G4Track.hh"
11 #include "G4Step.hh"
12 #include "G4Element.hh"
13 #include "G4ParticleChange.hh"
14 #include "G4NucleiProperties.hh"
15 #include "G4Nucleus.hh"
16 
17 #include "G4HadronicException.hh"
18 #include "G4HadronicProcessStore.hh"
19 #include "G4HadronicInteraction.hh"
20 
21 #include "G4ParticleDefinition.hh"
22 
25  : G4HadronicProcess(processName, fHadronic) {
26  AddDataSet(new CMSSIMPInelasticXS());
28 }
29 
31 
32 G4bool CMSSIMPInelasticProcess::IsApplicable(const G4ParticleDefinition& aP) {
33  return theParticle->GetParticleType() == aP.GetParticleType();
34 }
35 
36 G4VParticleChange* CMSSIMPInelasticProcess::PostStepDoIt(const G4Track& aTrack, const G4Step&) {
37  // if primary is not Alive then do nothing
38  theTotalResult->Clear();
39  theTotalResult->Initialize(aTrack);
40  theTotalResult->ProposeWeight(aTrack.GetWeight());
41  if (aTrack.GetTrackStatus() != fAlive) {
42  return theTotalResult;
43  }
44 
45  // Find cross section at end of step and check if <= 0
46  //
47  G4DynamicParticle* aParticle = const_cast<G4DynamicParticle*>(aTrack.GetDynamicParticle());
48 
49  // change this SIMP particle in a neutron
50  aParticle->SetPDGcode(2112);
51  aParticle->SetDefinition(G4Neutron::Neutron());
52 
53  G4Nucleus* target = GetTargetNucleusPointer();
54  const G4Material* aMaterial = aTrack.GetMaterial();
55  const G4Element* anElement = GetCrossSectionDataStore()->SampleZandA(aParticle, aMaterial, *target);
56 
57  // Next check for illegal track status
58  //
59  if (aTrack.GetTrackStatus() != fAlive && aTrack.GetTrackStatus() != fSuspend) {
60  if (aTrack.GetTrackStatus() == fStopAndKill || aTrack.GetTrackStatus() == fKillTrackAndSecondaries ||
61  aTrack.GetTrackStatus() == fPostponeToNextEvent) {
62  G4ExceptionDescription ed;
63  ed << "CMSSIMPInelasticProcess: track in unusable state - " << aTrack.GetTrackStatus() << G4endl;
64  ed << "CMSSIMPInelasticProcess: returning unchanged track " << G4endl;
65  DumpState(aTrack, "PostStepDoIt", ed);
66  G4Exception("CMSSIMPInelasticProcess::PostStepDoIt", "had004", JustWarning, ed);
67  }
68  // No warning for fStopButAlive which is a legal status here
69  return theTotalResult;
70  }
71 
72  // Initialize the hadronic projectile from the track
73  thePro.Initialise(aTrack);
74  G4HadronicInteraction* anInteraction = GetHadronicInteractionList()[0];
75 
76  G4HadFinalState* result = nullptr;
77  G4int reentryCount = 0;
78 
79  do {
80  try {
81  // Call the interaction
82  result = anInteraction->ApplyYourself(thePro, *target);
83  ++reentryCount;
84  } catch (G4HadronicException& aR) {
85  G4ExceptionDescription ed;
86  aR.Report(ed);
87  ed << "Call for " << anInteraction->GetModelName() << G4endl;
88  ed << "Target element " << anElement->GetName() << " Z= " << target->GetZ_asInt()
89  << " A= " << target->GetA_asInt() << G4endl;
90  DumpState(aTrack, "ApplyYourself", ed);
91  ed << " ApplyYourself failed" << G4endl;
92  G4Exception("CMSSIMPInelasticProcess::PostStepDoIt", "had006", FatalException, ed);
93  }
94 
95  // Check the result for catastrophic energy non-conservation
96  result = CheckResult(thePro, *target, result);
97  if (reentryCount > 100) {
98  G4ExceptionDescription ed;
99  ed << "Call for " << anInteraction->GetModelName() << G4endl;
100  ed << "Target element " << anElement->GetName() << " Z= " << target->GetZ_asInt()
101  << " A= " << target->GetA_asInt() << G4endl;
102  DumpState(aTrack, "ApplyYourself", ed);
103  ed << " ApplyYourself does not completed after 100 attempts" << G4endl;
104  G4Exception("CMSSIMPInelasticProcess::PostStepDoIt", "had006", FatalException, ed);
105  }
106  } while (!result);
107  // Check whether kaon0 or anti_kaon0 are present between the secondaries:
108  // if this is the case, transform them into either kaon0S or kaon0L,
109  // with equal, 50% probability, keeping their dynamical masses (and
110  // the other kinematical properties).
111  // When this happens - very rarely - a "JustWarning" exception is thrown.
112  G4int nSec = result->GetNumberOfSecondaries();
113  if (nSec > 0) {
114  for (G4int i = 0; i < nSec; ++i) {
115  G4DynamicParticle* dynamicParticle = result->GetSecondary(i)->GetParticle();
116  const G4ParticleDefinition* particleDefinition = dynamicParticle->GetParticleDefinition();
117  if (particleDefinition == G4KaonZero::Definition() || particleDefinition == G4AntiKaonZero::Definition()) {
118  G4ParticleDefinition* newPart;
119  if (G4UniformRand() > 0.5) {
120  newPart = G4KaonZeroShort::Definition();
121  } else {
122  newPart = G4KaonZeroLong::Definition();
123  }
124  dynamicParticle->SetDefinition(newPart);
125  G4ExceptionDescription ed;
126  ed << " Hadronic model " << anInteraction->GetModelName() << G4endl;
127  ed << " created " << particleDefinition->GetParticleName() << G4endl;
128  ed << " -> forced to be " << newPart->GetParticleName() << G4endl;
129  G4Exception("G4HadronicProcess::PostStepDoIt", "had007", JustWarning, ed);
130  }
131  }
132  }
133 
134  result->SetTrafoToLab(thePro.GetTrafoToLab());
135 
136  ClearNumberOfInteractionLengthLeft();
137 
138  FillResult(result, aTrack);
139 
140  return theTotalResult;
141 }
G4ParticleDefinition * theParticle
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep) override
tuple result
Definition: mps_fire.py:311
static CMSSIMP * SIMP()
Definition: CMSSIMP.cc:39
CMSSIMPInelasticProcess(const G4String &processName="SIMPInelastic")
G4bool IsApplicable(const G4ParticleDefinition &aParticleType) override