Geant4  10.01.p02
G4CascadeCheckBalance.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: G4CascadeCheckBalance.cc 71942 2013-06-28 19:08:11Z mkelsey $
27 //
28 // Verify and report four-momentum conservation for collision output; uses
29 // same interface as collision generators.
30 //
31 // 20100624 M. Kelsey -- Add baryon number, charge, and kinetic energy
32 // 20100624 M. Kelsey -- Bug fix: All checks should be |delta| !
33 // 20100627 M. Kelsey -- Always report violations on cerr, regardless of
34 // verbosity.
35 // 20100628 M. Kelsey -- Add interface to take list of particles directly,
36 // bug fix reporting of charge conservation error.
37 // 20100630 M. Kelsey -- for nuclei, include excitation energies in total.
38 // 20100701 M. Kelsey -- Undo previous change, handled by G4InuclNuclei.
39 // 20100711 M. Kelsey -- Use name of parent collider for reporting messages
40 // 20100713 M. kelsey -- Hide conservation errors behind verbosity
41 // 20100715 M. Kelsey -- Use new G4CollisionOutput totals instead of loops,
42 // move temporary buffer to be data member
43 // 20100719 M. Kelsey -- Change zero tolerance to 10 keV instead of 1 keV.
44 // 20100909 M. Kelsey -- Add interface for both kinds of particle lists
45 // 20101019 M. Kelsey -- CoVerity report: unitialized constructor
46 // 20110328 M. Kelsey -- Add default ctor and explicit limit setting
47 // 20110722 M. Kelsey -- For IntraNucleiCascader, take G4CollOut as argument
48 // 20120525 M. Kelsey -- Follow process-level checking: allow _either_ rel.
49 // or abs. to pass (instead of requiring both)
50 // 20121002 M. Kelsey -- Add strangeness check (useful for Omega- beam)
51 // 20130621 Add interface to take G4Fragment input instead of G4InuclNuclei.
52 // 20140930 Change name from "const char*" to "const G4String"
53 
54 #include "G4CascadeCheckBalance.hh"
55 #include "globals.hh"
56 #include "G4CascadParticle.hh"
58 #include "G4InuclNuclei.hh"
59 #include "G4InuclParticle.hh"
60 #include "G4CollisionOutput.hh"
61 #include "G4LorentzVector.hh"
62 #include <vector>
63 
64 
65 // Constructor sets acceptance limits
66 
67 const G4double G4CascadeCheckBalance::tolerance = 1e-6; // How small is zero?
68 
70  : G4VCascadeCollider(owner), relativeLimit(G4CascadeCheckBalance::tolerance),
71  absoluteLimit(G4CascadeCheckBalance::tolerance), initialBaryon(0),
72  finalBaryon(0), initialCharge(0), finalCharge(0), initialStrange(0),
73  finalStrange(0) {}
74 
76  G4double absolute,
77  const G4String& owner)
78  : G4VCascadeCollider(owner), relativeLimit(relative),
79  absoluteLimit(absolute), initialBaryon(0), finalBaryon(0),
80  initialCharge(0), finalCharge(0), initialStrange(0),
81  finalStrange(0) {}
82 
83 
84 // Pseudo-collision just computes input and output four-vectors
85 
87  G4InuclParticle* target,
88  G4CollisionOutput& output) {
89  if (verboseLevel)
90  G4cout << " >>> G4CascadeCheckBalance(" << theName << ")::collide"
91  << G4endl;
92 
93  initial *= 0.; // Fast reset; some colliders only have one pointer
94  if (bullet) initial += bullet->getMomentum();
95  if (target) initial += target->getMomentum();
96 
97  // Baryon number, charge and strangeness must be computed "by hand"
98  initialCharge = 0;
99  if (bullet) initialCharge += G4int(bullet->getCharge());
100  if (target) initialCharge += G4int(target->getCharge());
101 
102  G4InuclElementaryParticle* pbullet =
103  dynamic_cast<G4InuclElementaryParticle*>(bullet);
104  G4InuclElementaryParticle* ptarget =
105  dynamic_cast<G4InuclElementaryParticle*>(target);
106 
107  G4InuclNuclei* nbullet = dynamic_cast<G4InuclNuclei*>(bullet);
108  G4InuclNuclei* ntarget = dynamic_cast<G4InuclNuclei*>(target);
109 
110  initialBaryon =
111  ((pbullet ? pbullet->baryon() : nbullet ? nbullet->getA() : 0) +
112  (ptarget ? ptarget->baryon() : ntarget ? ntarget->getA() : 0) );
113 
114  // NOTE: Currently we ignore possibility of hypernucleus target
115  initialStrange = 0;
116  if (pbullet) initialStrange += pbullet->getStrangeness();
117  if (ptarget) initialStrange += ptarget->getStrangeness();
118 
119  // Final state totals are computed for us
120  final = output.getTotalOutputMomentum();
122  finalCharge = output.getTotalCharge();
124 
125  // Report results
126  if (verboseLevel) {
127  G4cout << " initial px " << initial.px() << " py " << initial.py()
128  << " pz " << initial.pz() << " E " << initial.e()
129  << " baryon " << initialBaryon << " charge " << initialCharge
130  << " strange " << initialStrange << G4endl
131  << " final px " << final.px() << " py " << final.py()
132  << " pz " << final.pz() << " E " << final.e()
133  << " baryon " << finalBaryon << " charge " << finalCharge
134  << " strange " << finalStrange << G4endl;
135  }
136 }
137 
138 // For de-excitation, take G4Fragment as initial state
140  G4CollisionOutput& output) {
141  if (verboseLevel)
142  G4cout << " >>> G4CascadeCheckBalance(" << theName << ")::collide(<FRAG>)"
143  << G4endl;
144 
145  // Copy initial state directly from fragment (no bullet/target sums)
146  initial = fragment.GetMomentum();
147  initialCharge = fragment.GetZ_asInt();
148  initialBaryon = fragment.GetA_asInt();
149  initialStrange = 0; // No hypernuclei at present
150 
151  // Final state totals are computed for us
152  final = output.getTotalOutputMomentum();
154  finalCharge = output.getTotalCharge();
156 
157  // Report results
158  if (verboseLevel) {
159  G4cout << " initial px " << initial.px() << " py " << initial.py()
160  << " pz " << initial.pz() << " E " << initial.e()
161  << " baryon " << initialBaryon << " charge " << initialCharge
162  << " strange " << initialStrange << G4endl
163  << " final px " << final.px() << " py " << final.py()
164  << " pz " << final.pz() << " E " << final.e()
165  << " baryon " << finalBaryon << " charge " << finalCharge
166  << " strange " << finalStrange << G4endl;
167  }
168 }
169 
170 
171 // Take list of output particles directly (e.g., from G4EPCollider internals)
172 
174  G4InuclParticle* target,
175  const std::vector<G4InuclElementaryParticle>& particles) {
176  if (verboseLevel)
177  G4cout << " >>> G4CascadeCheckBalance(" << theName << ")::collide(<vector>)"
178  << G4endl;
179 
180  tempOutput.reset(); // Buffer for processing
181  tempOutput.addOutgoingParticles(particles);
182  collide(bullet, target, tempOutput);
183 }
184 
186  const std::vector<G4InuclElementaryParticle>& particles) {
187  if (verboseLevel)
188  G4cout << " >>> G4CascadeCheckBalance(" << theName
189  << ")::collide(<FRAG>,<vector>)" << G4endl;
190 
191  tempOutput.reset(); // Buffer for processing
192  tempOutput.addOutgoingParticles(particles);
193  collide(target, tempOutput);
194 }
195 
196 
197 // Take list of nuclear fragments directly (e.g., from G4Fissioner internals)
198 
200  const std::vector<G4InuclNuclei>& fragments) {
201  if (verboseLevel)
202  G4cout << " >>> G4CascadeCheckBalance(" << theName << ")::collide(<vector>)"
203  << G4endl;
204 
205  tempOutput.reset(); // Buffer for processing
206  tempOutput.addOutgoingNuclei(fragments);
207  collide(target, tempOutput);
208 }
209 
210 
211 // Take list of "cparticles" (e.g., from G4NucleiModel internals)
212 
214  G4InuclParticle* target,
215  const std::vector<G4CascadParticle>& particles) {
216  if (verboseLevel)
217  G4cout << " >>> G4CascadeCheckBalance(" << theName
218  << ")::collide(<cparticles>)" << G4endl;
219 
220  tempOutput.reset(); // Buffer for processing
221  tempOutput.addOutgoingParticles(particles);
222  collide(bullet, target, tempOutput);
223 }
224 
225 
226 // Take lists of both G4InuclEP & G4CP (e.g., from G4IntraNucleiCascader)
227 
229  G4InuclParticle* target,
230  G4CollisionOutput& output,
231  const std::vector<G4CascadParticle>& cparticles) {
232  if (verboseLevel)
233  G4cout << " >>> G4CascadeCheckBalance(" << theName
234  << ")::collide(<EP>,<CP>)" << G4endl;
235 
236  tempOutput.reset(); // Buffer for processing
237  tempOutput.add(output);
238  tempOutput.addOutgoingParticles(cparticles);
239  collide(bullet, target, tempOutput);
240 }
241 
242 
243 // Compare relative and absolute violations to limits, and report
244 
246  G4bool relokay = (std::abs(relativeE()) < relativeLimit);
247  G4bool absokay = (std::abs(deltaE()) < absoluteLimit);
248 
249  if (verboseLevel && !(relokay || absokay)) {
250  G4cerr << theName << ": Energy conservation: relative " << relativeE()
251  << (relokay ? " conserved" : " VIOLATED")
252  << " absolute " << deltaE()
253  << (absokay ? " conserved" : " VIOLATED") << G4endl;
254  } else if (verboseLevel > 1) {
255  G4cout << theName << ": Energy conservation: relative " << relativeE()
256  << " conserved absolute " << deltaE() << " conserved" << G4endl;
257  }
258 
259  return (relokay && absokay);
260 }
261 
263  G4bool relokay = (std::abs(relativeKE()) < relativeLimit);
264  G4bool absokay = (std::abs(deltaKE()) < absoluteLimit);
265 
266  if (verboseLevel && !(relokay || absokay)) {
267  G4cerr << theName << ": Kinetic energy balance: relative "
268  << relativeKE() << (relokay ? " conserved" : " VIOLATED")
269  << " absolute " << deltaKE()
270  << (absokay ? " conserved" : " VIOLATED") << G4endl;
271  } else if (verboseLevel > 1) {
272  G4cout << theName << ": Kinetic energy balance: relative "
273  << relativeKE() << " conserved absolute " << deltaKE()
274  << " conserved" << G4endl;
275  }
276 
277  return (relokay && absokay);
278 }
279 
281  G4bool relokay = (std::abs(relativeP()) < relativeLimit);
282  G4bool absokay = (std::abs(deltaP()) < absoluteLimit);
283 
284  if (verboseLevel && !(relokay || absokay)) {
285  G4cerr << theName << ": Momentum conservation: relative " << relativeP()
286  << (relokay ? " conserved" : " VIOLATED")
287  << " absolute " << deltaP()
288  << (absokay ? " conserved" : " VIOLATED") << G4endl;
289  } else if (verboseLevel > 1) {
290  G4cout << theName << ": Momentum conservation: relative " << relativeP()
291  << " conserved absolute " << deltaP() << " conserved" << G4endl;
292  }
293 
294  return (relokay && absokay);
295 }
296 
298  G4bool bokay = (deltaB() == 0); // Must be perfect!
299 
300  if (verboseLevel && !bokay)
301  G4cerr << theName << ": Baryon number VIOLATED " << deltaB() << G4endl;
302 
303  return bokay;
304 }
305 
307  G4bool qokay = (deltaQ() == 0); // Must be perfect!
308 
309  if (verboseLevel && !qokay)
310  G4cerr << theName << ": Charge conservation VIOLATED " << deltaQ()
311  << G4endl;
312 
313  return qokay;
314 }
315 
317  G4bool sokay = (deltaS() == 0); // Must be perfect!
318 
319  if (verboseLevel && !sokay)
320  G4cerr << theName << ": Strangeness conservation VIOLATED " << deltaS()
321  << G4endl;
322 
323  return sokay;
324 }
void addOutgoingNuclei(const std::vector< G4InuclNuclei > &nuclea)
G4LorentzVector getMomentum() const
void collide(G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &output)
static const G4double tolerance
static const G4double tolerance
int G4int
Definition: G4Types.hh:78
G4LorentzVector getTotalOutputMomentum() const
void add(const G4CollisionOutput &right)
G4GLOB_DLL std::ostream G4cout
G4int GetA_asInt() const
Definition: G4Fragment.hh:243
G4int getA() const
bool G4bool
Definition: G4Types.hh:79
G4int getTotalStrangeness() const
G4CascadeCheckBalance(const G4String &owner="G4CascadeCheckBalance")
const G4LorentzVector & GetMomentum() const
Definition: G4Fragment.hh:276
void addOutgoingParticles(const std::vector< G4InuclElementaryParticle > &particles)
G4int getTotalBaryonNumber() const
G4int GetZ_asInt() const
Definition: G4Fragment.hh:248
G4int getTotalCharge() const
G4double getCharge() const
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
G4GLOB_DLL std::ostream G4cerr