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
G4CascadeRecoilMaker.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// Collects generated cascade data (using Collider::collide() interface)
29// and computes the nuclear recoil kinematics needed to balance the event.
30//
31// 20100909 M. Kelsey -- Inspired by G4CascadeCheckBalance
32// 20100909 M. Kelsey -- Move G4IntraNucleiCascader::goodCase() here, add
33// tolerance for "almost zero" excitation energy
34// 20100910 M. Kelsey -- Drop getRecoilFragment() in favor of user calling
35// makeRecoilFragment() with returned non-const pointer. Drop
36// handling of excitons.
37// 20100921 M. Kelsey -- Return G4InuclNuclei using "makeRecoilNuclei()".
38// Repurpose "makeRecoilFragment()" to return G4Fragment.
39// 20100924 M. Kelsey -- Remove unusable G4Fragment::SetExcitationEnergy().
40// Add deltaM to compute mass difference, use excitationEnergy
41// to force G4Fragment four-vector to match.
42// 20110214 M. Kelsey -- Follow G4InuclParticle::Model enumerator migration
43// 20110303 M. Kelsey -- Add diagnostic messages to goodNucleus().
44// 20110308 M. Kelsey -- Follow new G4Fragment interface for hole types
45// 20110722 M. Kelsey -- For IntraNucleiCascader, take G4CollOut as argument
46
47#include <vector>
48
50#include "globals.hh"
51#include "G4SystemOfUnits.hh"
52#include "G4CascadParticle.hh"
54#include "G4CollisionOutput.hh"
55#include "G4Fragment.hh"
57#include "G4InuclNuclei.hh"
58#include "G4InuclParticle.hh"
60#include "G4LorentzVector.hh"
61
62using namespace G4InuclSpecialFunctions;
63
64
65// Constructor and destructor
66
68 : G4VCascadeCollider("G4CascadeRecoilMaker"),
69 excTolerance(tolerance), inputEkin(0.),
70 recoilA(0), recoilZ(0), excitationEnergy(0.) {
71 balance = new G4CascadeCheckBalance(tolerance, tolerance, theName);
72}
73
75 delete balance;
76}
77
78
79// Standard Collider interface (non-const output "buffer")
80
82 G4InuclParticle* target,
83 G4CollisionOutput& output) {
84 if (verboseLevel > 1)
85 G4cout << " >>> G4CascadeRecoilMaker::collide" << G4endl;
86
87 // Available energy needed for "goodNucleus()" test at end
88 inputEkin = bullet ? bullet->getKineticEnergy() : 0.;
89
91 balance->collide(bullet, target, output);
92 fillRecoil();
93}
94
95// This is for use with G4IntraNucleiCascader
96
98 G4InuclParticle* target,
99 G4CollisionOutput& output,
100 const std::vector<G4CascadParticle>& cparticles) {
101 if (verboseLevel > 1)
102 G4cout << " >>> G4CascadeRecoilMaker::collide(<EP>,<CP>)" << G4endl;
103
104 // Available energy needed for "goodNucleus()" test at end
105 inputEkin = bullet ? bullet->getKineticEnergy() : 0.;
106
108 balance->collide(bullet, target, output, cparticles);
109 fillRecoil();
110}
111
112
113// Used current event configuration to construct recoil nucleus
114// NOTE: CheckBalance uses "final-initial", we want "initial-final"
115
117 recoilZ = -(balance->deltaQ()); // Charge "non-conservation"
118 recoilA = -(balance->deltaB()); // Baryon "non-conservation"
119 recoilMomentum = -(balance->deltaLV());
120
121 theExcitons.clear(); // Discard previous exciton configuraiton
122
123 // Bertini uses MeV for excitation energy
124 if (!goodFragment()) excitationEnergy = 0.;
125 else excitationEnergy = deltaM() * GeV;
126
127 // Allow for very small negative mass difference, and round to zero
128 if (std::abs(excitationEnergy) < excTolerance) excitationEnergy = 0.;
129
130 if (verboseLevel > 2) {
131 G4cout << " recoil px " << recoilMomentum.px()
132 << " py " << recoilMomentum.py() << " pz " << recoilMomentum.pz()
133 << " E " << recoilMomentum.e() << " baryon " << recoilA
134 << " charge " << recoilZ
135 << "\n recoil mass " << recoilMomentum.m()
136 << " 'excitation' energy " << excitationEnergy << G4endl;
137 }
138}
139
140
141// Construct physical nucleus from recoil parameters, if reasonable
142
145 if (verboseLevel > 1)
146 G4cout << " >>> G4CascadeRecoilMaker::makeRecoilNuclei" << G4endl;
147
148 if (!goodRecoil()) {
149 if (verboseLevel > 2 && !wholeEvent())
150 G4cout << theName << ": event recoil is not a physical nucleus" << G4endl;
151
152 return 0; // Null pointer means no fragment
153 }
154
155 theRecoilNuclei.fill(recoilMomentum, recoilA, recoilZ,
156 excitationEnergy, model);
157 theRecoilNuclei.setExitonConfiguration(theExcitons);
158
159 return &theRecoilNuclei;
160}
161
162
163// Construct pre-compound nuclear fragment from recoil parameters
164
166 if (verboseLevel > 1)
167 G4cout << " >>> G4CascadeRecoilMaker::makeRecoilFragment" << G4endl;
168
169 if (!goodRecoil()) {
170 if (verboseLevel > 2 && !wholeEvent())
171 G4cout << theName << ": event recoil is not a physical nucleus" << G4endl;
172
173 return 0; // Null pointer means no fragment
174 }
175
176 theRecoilFragment.SetZandA_asInt(recoilZ, recoilA); // Note convention!
177
178 // User may have overridden excitation energy; force four-momentum to match
179 G4double fragMass =
180 G4InuclNuclei::getNucleiMass(recoilA,recoilZ) + excitationEnergy/GeV;
181
182 G4LorentzVector fragMom; fragMom.setVectM(recoilMomentum.vect(), fragMass);
183 theRecoilFragment.SetMomentum(fragMom*GeV); // Bertini uses GeV!
184
185 // Note: exciton configuration has to be set piece by piece
186 // (arguments are Ntotal,Nproton in both cases)
187 G4int nholes = theExcitons.protonHoles+theExcitons.neutronHoles;
188 theRecoilFragment.SetNumberOfHoles(nholes, theExcitons.protonHoles);
189
190 G4int nexcit = (theExcitons.protonQuasiParticles
191 + theExcitons.neutronQuasiParticles);
192 theRecoilFragment.SetNumberOfExcitedParticle(nexcit,
193 theExcitons.protonQuasiParticles);
194
195 return &theRecoilFragment;
196}
197
198
199// Compute raw mass difference from recoil parameters
200
202 G4double nucMass = G4InuclNuclei::getNucleiMass(recoilA,recoilZ);
203 return (recoilMomentum.m() - nucMass);
204}
205
206
207// Data quality checks
208
210 return (recoilA>0 && recoilZ>=0 && recoilA >= recoilZ);
211}
212
214 return (goodFragment() && excitationEnergy > -excTolerance);
215}
216
218 if (verboseLevel > 2) {
219 G4cout << " >>> G4CascadeRecoilMaker::wholeEvent:"
220 << " A " << recoilA << " Z " << recoilZ
221 << " P " << recoilMomentum.rho() << " E " << recoilMomentum.e()
222 << "\n wholeEvent returns "
223 << (recoilA==0 && recoilZ==0 &&
224 recoilMomentum.rho() < excTolerance/GeV &&
225 std::abs(recoilMomentum.e()) < excTolerance/GeV) << G4endl;
226 }
227
228 return (recoilA==0 && recoilZ==0 &&
229 recoilMomentum.rho() < excTolerance/GeV &&
230 std::abs(recoilMomentum.e()) < excTolerance/GeV);
231}
232
233// Determine whether desired nuclear fragment is constructable outcome
234
236 if (verboseLevel > 2) {
237 G4cout << " >>> G4CascadeRecoilMaker::goodNucleus" << G4endl;
238 }
239
240 const G4double minExcitation = 0.1*keV;
241 const G4double reasonableExcitation = 7.0; // Multiple of binding energy
242 const G4double fractionalExcitation = 0.2; // Fraction of input to excite
243
244 if (!goodRecoil()) {
245 if (verboseLevel>2) {
246 if (!goodFragment()) G4cerr << " goodNucleus: invalid A/Z" << G4endl;
247 else if (excitationEnergy < -excTolerance)
248 G4cerr << " goodNucleus: negative excitation" << G4endl;
249 }
250 return false; // Not a sensible nucleus
251 }
252
253 if (excitationEnergy <= minExcitation) return true; // Effectively zero
254
255 // Maximum possible excitation energy determined by initial energy
256 G4double dm = bindingEnergy(recoilA,recoilZ);
257 G4double exc_max0z = fractionalExcitation * inputEkin*GeV;
258 G4double exc_dm = reasonableExcitation * dm;
259 G4double exc_max = (exc_max0z > exc_dm) ? exc_max0z : exc_dm;
260
261 if (verboseLevel > 3) {
262 G4cout << " eexs " << excitationEnergy << " max " << exc_max
263 << " dm " << dm << G4endl;
264 }
265
266 if (verboseLevel > 2 && excitationEnergy >= exc_max)
267 G4cerr << " goodNucleus: too much excitation" << G4endl;
268
269 return (excitationEnergy < exc_max); // Below maximum possible
270}
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
void setVectM(const Hep3Vector &spatial, double mass)
Hep3Vector vect() const
void collide(G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &output)
G4LorentzVector deltaLV() const
void collide(G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &output)
G4InuclNuclei * makeRecoilNuclei(G4InuclParticle::Model model=G4InuclParticle::DefaultModel)
G4Fragment * makeRecoilFragment()
G4CascadeRecoilMaker(G4double tolerance=0.001 *CLHEP::MeV)
void SetNumberOfHoles(G4int valueTot, G4int valueP=0)
Definition: G4Fragment.hh:335
void SetMomentum(const G4LorentzVector &value)
Definition: G4Fragment.hh:256
void SetNumberOfExcitedParticle(G4int valueTot, G4int valueP)
Definition: G4Fragment.hh:316
void SetZandA_asInt(G4int Znew, G4int Anew)
Definition: G4Fragment.hh:228
void setExitonConfiguration(const G4ExitonConfiguration &config)
G4double getNucleiMass() const
void fill(G4int a, G4int z, G4double exc=0., Model model=DefaultModel)
G4double getKineticEnergy() const
virtual void setVerboseLevel(G4int verbose=0)
G4double bindingEnergy(G4int A, G4int Z)