Geant4  10.01.p01
G4InuclNuclei.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: G4InuclNuclei.cc 71719 2013-06-21 00:01:54Z mkelsey $
27 //
28 // 20100301 M. Kelsey -- Add function to create unphysical nuclei for use
29 // as temporary final-state fragments.
30 // 20100319 M. Kelsey -- Add information message to makeNuclearFragment().
31 // Use new GetBindingEnergy() function instead of bindingEnergy().
32 // 20100622 M. Kelsey -- Use local "bindingEnergy()" function to call through.
33 // 20100627 M. Kelsey -- Test for non-physical fragments and abort job.
34 // 20100630 M. Kelsey -- Use excitation energy in G4Ions
35 // 20100714 M. Kelsey -- Use G4DynamicParticle::theDynamicalMass to deal with
36 // excitation energy without instantianting "infinite" G4PartDefns.
37 // 20100719 M. Kelsey -- Change excitation energy without altering momentum
38 // 20100906 M. Kelsey -- Add fill() functions to rewrite contents
39 // 20100910 M. Kelsey -- Add clearExitonConfiguration() to fill() functions
40 // 20100914 M. Kelsey -- Make printout symmetric with G4InuclElemPart,
41 // migrate to integer A and Z
42 // 20100924 M. Kelsey -- Add constructor to copy G4Fragment input, and output
43 // functions to create G4Fragment
44 // 20110214 M. Kelsey -- Replace integer "model" with enum
45 // 20110308 M. Kelsey -- Follow new G4Fragment interface for hole types
46 // 20110427 M. Kelsey -- Remove PDG-code warning
47 // 20110721 M. Kelsey -- Follow base-class ctor change to pass model directly
48 // 20110829 M. Kelsey -- Add constructor to copy G4V3DNucleus input
49 // 20110919 M. Kelsey -- Special case: Allow fill(A=0,Z=0) to make dummy
50 // 20110922 M. Kelsey -- Add stream argument to printParticle() => print()
51 // 20121009 M. Kelsey -- Add report of excitons if non-empty
52 // 20130314 M. Kelsey -- Use G4IonList typedef for fragment map, encapsulate
53 // it in a static function with mutexes.
54 // 20130620 M. Kelsey -- Address Coverity #37503, check self in op=()
55 // 20140523 M. Kelsey -- Avoid FPE in setExcitationEnergy() for zero Ekin
56 
57 #include "G4InuclNuclei.hh"
58 #include "G4AutoLock.hh"
59 #include "G4Fragment.hh"
60 #include "G4HadronicException.hh"
62 #include "G4IonTable.hh"
63 #include "G4Ions.hh"
64 #include "G4NucleiProperties.hh"
65 #include "G4Nucleon.hh"
66 #include "G4ParticleDefinition.hh"
67 #include "G4ParticleTable.hh"
68 #include "G4SystemOfUnits.hh"
69 #include "G4Threading.hh"
70 #include "G4V3DNucleus.hh"
71 
72 #include <assert.h>
73 #include <sstream>
74 #include <map>
75 
76 using namespace G4InuclSpecialFunctions;
77 
78 
79 // Convert contents from (via constructor) and to G4Fragment
80 
83  : G4InuclParticle() {
84  copy(aFragment, model);
85 }
86 
87 void G4InuclNuclei::copy(const G4Fragment& aFragment, Model model) {
88  fill(aFragment.GetMomentum()/GeV, aFragment.GetA_asInt(),
89  aFragment.GetZ_asInt(), aFragment.GetExcitationEnergy(), model);
90 
91  // Exciton configuration must be set by hand
93 
95  aFragment.GetNumberOfParticles() - aFragment.GetNumberOfCharged();
96 
98 
101 }
102 
103 
104 // FIXME: Should we have a local buffer and return by const-reference instead?
106  G4Fragment frag(getA(), getZ(), getMomentum()*GeV); // From Bertini units
107 
108  // Note: exciton configuration has to be set piece by piece
112 
116 
117  return frag;
118 }
119 
120 G4InuclNuclei::operator G4Fragment() const {
121  return makeG4Fragment();
122 }
123 
124 
125 // Convert contents from (via constructor) G4V3DNucleus
126 
129  : G4InuclParticle() {
130  copy(a3DNucleus, model);
131 }
132 
133 void G4InuclNuclei::copy(G4V3DNucleus* a3DNucleus, Model model) {
134  if (!a3DNucleus) return; // Null pointer means no action
135 
136  fill(0., a3DNucleus->GetMassNumber(), a3DNucleus->GetCharge(), 0., model);
137 
138  // Convert every hit nucleon into an exciton hole
139  if (a3DNucleus->StartLoop()) {
140  G4Nucleon* nucl = 0;
141  while ((nucl = a3DNucleus->GetNextNucleon())) {
142  if (nucl->AreYouHit()) { // Found previously interacted nucleon
143  if (nucl->GetParticleType() == G4Proton::Definition())
145 
146  if (nucl->GetParticleType() == G4Neutron::Definition())
148  }
149  }
150  }
151 }
152 
153 
154 // Overwrite data structure (avoids creating/copying temporaries)
155 
157  G4double exc, G4InuclParticle::Model model) {
159  setMomentum(mom);
160  setExitationEnergy(exc);
162  setModel(model);
163 }
164 
166  G4InuclParticle::Model model) {
168  setKineticEnergy(ekin);
169  setExitationEnergy(exc);
171  setModel(model);
172 }
173 
175  setDefinition(0);
178 }
179 
180 
181 // Change excitation energy while keeping momentum vector constant
182 
184  G4double ekin = getKineticEnergy(); // Current kinetic energy
185 
186  G4double emass = getNucleiMass() + e*MeV/GeV; // From Bertini to G4 units
187 
188  // Safety check -- if zero energy, don't do computation
189  G4double ekin_new = (ekin == 0.) ? 0.
190  : std::sqrt(emass*emass + ekin*(2.*getMass()+ekin)) - emass;
191 
192  setMass(emass); // Momentum is computed from mass and Ekin
193  setKineticEnergy(ekin_new);
194 }
195 
196 
197 // Convert nuclear configuration to standard GEANT4 pointer
198 
199 // WARNING: Opposite conventions! G4InuclNuclei uses (A,Z) everywhere, while
200 // G4ParticleTable::GetIon() uses (Z,A)!
201 
203  // SPECIAL CASE: (0,0) means create dummy without definition
204  if (0 == a && 0 == z) return 0;
205 
207  G4ParticleDefinition *pd = pTable->GetIonTable()->GetIon(z, a, 0);
208 
209  // SPECIAL CASE: Non-physical nuclear fragment, for final-state return
210  if (!pd) pd = makeNuclearFragment(a,z);
211 
212  return pd; // This could return a null pointer if above fails
213 }
214 
215 
216 // Shared buffer of nuclear fragments created below, to avoid memory leaks
217 
218 namespace {
219  static std::map<G4int,G4ParticleDefinition*> fragmentList;
220  G4Mutex fragListMutex = G4MUTEX_INITIALIZER;
221 }
222 
223 // Creates a non-physical pseudo-nucleus, for return as final-state fragment
224 // from G4IntraNuclearCascader
225 
228  if (a<=0 || z<0 || a<z) {
229  G4cerr << " >>> G4InuclNuclei::makeNuclearFragment() called with"
230  << " impossible arguments A=" << a << " Z=" << z << G4endl;
231  throw G4HadronicException(__FILE__, __LINE__,
232  "G4InuclNuclei impossible A/Z arguments");
233  }
234 
236 
237  // Use local lookup table (see above) to maintain singletons
238  // NOTE: G4ParticleDefinitions don't need to be explicitly deleted
239  // (see comments in G4IonTable.cc::~G4IonTable)
240 
241  G4AutoLock fragListLock(&fragListMutex);
242  if (fragmentList.find(code) != fragmentList.end()) return fragmentList[code];
243  fragListLock.unlock();
244 
245  // Name string follows format in G4IonTable.cc::GetIonName(Z,A,E)
246  std::stringstream zstr, astr;
247  zstr << z;
248  astr << a;
249 
250  G4String name = "Z" + zstr.str() + "A" + astr.str();
251 
252  G4double mass = getNucleiMass(a,z) *GeV/MeV; // From Bertini to GEANT4 units
253 
254  // Arguments for constructor are as follows
255  // name mass width charge
256  // 2*spin parity C-conjugation
257  // 2*Isospin 2*Isospin3 G-parity
258  // type lepton number baryon number PDG encoding
259  // stable lifetime decay table
260  // shortlived subType anti_encoding Excitation-energy
261 
262  G4Ions* fragPD = new G4Ions(name, mass, 0., z*eplus,
263  0, +1, 0,
264  0, 0, 0,
265  "nucleus", 0, a, code,
266  true, 0., 0,
267  true, "generic", 0, 0.);
268  fragPD->SetAntiPDGEncoding(0);
269 
270  fragListLock.lock(); // Protect before saving new fragment
271  return (fragmentList[code] = fragPD); // Store in table for next lookup
272 }
273 
275  // Simple minded mass calculation use constants in CLHEP (all in MeV)
277 
278  return mass*MeV/GeV; // Convert from GEANT4 to Bertini units
279 }
280 
281 // Assignment operator for use with std::sort()
283  if (this != &right) {
286  }
287  return *this;
288 }
289 
290 // Dump particle properties for diagnostics
291 
292 void G4InuclNuclei::print(std::ostream& os) const {
294  os << G4endl << " Nucleus: " << getDefinition()->GetParticleName()
295  << " A " << getA() << " Z " << getZ() << " mass " << getMass()
296  << " Eex (MeV) " << getExitationEnergy();
297 
299  os << G4endl << " " << theExitonConfiguration;
300 }
void fill(G4int a, G4int z, G4double exc=0., Model model=DefaultModel)
static const double MeV
Definition: G4SIunits.hh:193
const G4ParticleDefinition * GetParticleType() const
Definition: G4Nucleon.hh:84
static G4double GetNuclearMass(const G4double A, const G4double Z)
G4int getZ() const
virtual G4int GetCharge()=0
void SetAntiPDGEncoding(G4int aEncoding)
G4LorentzVector getMomentum() const
virtual G4bool StartLoop()=0
G4double z
Definition: TRTMaterials.hh:39
G4InuclNuclei & operator=(const G4InuclNuclei &right)
G4String name
Definition: TRTMaterials.hh:40
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
Definition: G4IonTable.cc:463
virtual G4int GetMassNumber()=0
const G4ParticleDefinition * getDefinition() const
void SetNumberOfHoles(G4int valueTot, G4int valueP=0)
Definition: G4Fragment.hh:360
static G4int GetNucleusEncoding(G4int Z, G4int A, G4double E=0.0, G4int lvl=0)
Definition: G4IonTable.cc:868
void setDefinition(const G4ParticleDefinition *pd)
G4int GetNumberOfParticles() const
Definition: G4Fragment.hh:330
G4double a
Definition: TRTMaterials.hh:39
int G4int
Definition: G4Types.hh:78
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:171
const G4String & GetParticleName() const
G4double getKineticEnergy() const
static G4Proton * Definition()
Definition: G4Proton.cc:49
void setExitationEnergy(G4double e)
G4int GetNumberOfHoles() const
Definition: G4Fragment.hh:350
void SetNumberOfExcitedParticle(G4int valueTot, G4int valueP)
Definition: G4Fragment.hh:341
G4IonTable * GetIonTable() const
G4int GetA_asInt() const
Definition: G4Fragment.hh:243
virtual void print(std::ostream &os) const
G4int getA() const
Definition: G4Ions.hh:51
const G4LorentzVector & GetMomentum() const
Definition: G4Fragment.hh:276
G4bool AreYouHit() const
Definition: G4Nucleon.hh:97
G4double getNucleiMass() const
void copy(const G4Fragment &aFragment, Model model=DefaultModel)
G4double getExitationEnergy() const
static const double GeV
Definition: G4SIunits.hh:196
virtual void print(std::ostream &os) const
G4int G4Mutex
Definition: G4Threading.hh:169
static G4ParticleTable * GetParticleTable()
G4Fragment makeG4Fragment() const
void clearExitonConfiguration()
static G4Neutron * Definition()
Definition: G4Neutron.cc:54
G4int GetZ_asInt() const
Definition: G4Fragment.hh:248
G4InuclParticle & operator=(const G4InuclParticle &right)
void setMass(G4double mass)
void setModel(Model model)
#define G4endl
Definition: G4ios.hh:61
G4int GetNumberOfChargedHoles() const
Definition: G4Fragment.hh:355
virtual G4Nucleon * GetNextNucleon()=0
void setKineticEnergy(G4double ekin)
static G4ParticleDefinition * makeDefinition(G4int a, G4int z)
void setMomentum(const G4LorentzVector &mom)
double G4double
Definition: G4Types.hh:76
G4ExitonConfiguration theExitonConfiguration
static const double eplus
Definition: G4SIunits.hh:178
static G4ParticleDefinition * makeNuclearFragment(G4int a, G4int z)
G4int GetNumberOfCharged() const
Definition: G4Fragment.hh:335
G4double GetExcitationEnergy() const
Definition: G4Fragment.hh:260
G4GLOB_DLL std::ostream G4cerr
G4double getMass() const
CLHEP::HepLorentzVector G4LorentzVector