Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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$
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 
53 #include <assert.h>
54 #include <sstream>
55 #include <map>
56 
57 #include "G4InuclNuclei.hh"
58 #include "G4SystemOfUnits.hh"
59 #include "G4Fragment.hh"
60 #include "G4HadronicException.hh"
62 #include "G4Ions.hh"
63 #include "G4IonTable.hh"
64 #include "G4NucleiProperties.hh"
65 #include "G4Nucleon.hh"
66 #include "G4ParticleDefinition.hh"
67 #include "G4ParticleTable.hh"
68 #include "G4V3DNucleus.hh"
69 
70 using namespace G4InuclSpecialFunctions;
71 
72 
73 // Convert contents from (via constructor) and to G4Fragment
74 
77  : G4InuclParticle() {
78  copy(aFragment, model);
79 }
80 
81 void G4InuclNuclei::copy(const G4Fragment& aFragment, Model model) {
82  fill(aFragment.GetMomentum()/GeV, aFragment.GetA_asInt(),
83  aFragment.GetZ_asInt(), aFragment.GetExcitationEnergy(), model);
84 
85  // Exciton configuration must be set by hand
86  theExitonConfiguration.protonQuasiParticles = aFragment.GetNumberOfCharged();
87 
88  theExitonConfiguration.neutronQuasiParticles =
89  aFragment.GetNumberOfParticles() - aFragment.GetNumberOfCharged();
90 
91  theExitonConfiguration.protonHoles = aFragment.GetNumberOfChargedHoles();
92 
93  theExitonConfiguration.neutronHoles =
94  aFragment.GetNumberOfHoles() - theExitonConfiguration.protonHoles;
95 }
96 
97 
98 // FIXME: Should we have a local buffer and return by const-reference instead?
100  G4Fragment frag(getA(), getZ(), getMomentum()*GeV); // From Bertini units
101 
102  // Note: exciton configuration has to be set piece by piece
103  frag.SetNumberOfHoles(theExitonConfiguration.protonHoles
104  + theExitonConfiguration.neutronHoles,
105  theExitonConfiguration.protonHoles);
106 
107  frag.SetNumberOfExcitedParticle(theExitonConfiguration.protonQuasiParticles
108  + theExitonConfiguration.neutronQuasiParticles,
109  theExitonConfiguration.protonQuasiParticles);
110 
111  return frag;
112 }
113 
114 G4InuclNuclei::operator G4Fragment() const {
115  return makeG4Fragment();
116 }
117 
118 
119 // Convert contents from (via constructor) G4V3DNucleus
120 
123  : G4InuclParticle() {
124  copy(a3DNucleus, model);
125 }
126 
128  if (!a3DNucleus) return; // Null pointer means no action
129 
130  fill(0., a3DNucleus->GetMassNumber(), a3DNucleus->GetCharge(), 0., model);
131 
132  // Convert every hit nucleon into an exciton hole
133  if (a3DNucleus->StartLoop()) {
134  G4Nucleon* nucl = 0;
135  while ((nucl = a3DNucleus->GetNextNucleon())) {
136  if (nucl->AreYouHit()) { // Found previously interacted nucleon
137  if (nucl->GetParticleType() == G4Proton::Definition())
138  theExitonConfiguration.protonHoles++;
139 
141  theExitonConfiguration.neutronHoles++;
142  }
143  }
144  }
145 }
146 
147 
148 // Overwrite data structure (avoids creating/copying temporaries)
149 
153  setMomentum(mom);
154  setExitationEnergy(exc);
156  setModel(model);
157 }
158 
162  setKineticEnergy(ekin);
163  setExitationEnergy(exc);
165  setModel(model);
166 }
167 
169  setDefinition(0);
172 }
173 
174 
175 // Change excitation energy while keeping momentum vector constant
176 
178  G4double ekin = getKineticEnergy(); // Current kinetic energy
179 
180  G4double emass = getNucleiMass() + e*MeV/GeV; // From Bertini to G4 units
181 
182  // Directly compute new kinetic energy from old
183  G4double ekin_new = std::sqrt(emass*emass + ekin*(2.*getMass()+ekin)) - emass;
184 
185  setMass(emass); // Momentum is computed from mass and Ekin
186  setKineticEnergy(ekin_new);
187 }
188 
189 
190 // Convert nuclear configuration to standard GEANT4 pointer
191 
192 // WARNING: Opposite conventions! G4InuclNuclei uses (A,Z) everywhere, while
193 // G4ParticleTable::GetIon() uses (Z,A)!
194 
196  // SPECIAL CASE: (0,0) means create dummy without definition
197  if (0 == a && 0 == z) return 0;
198 
200  G4ParticleDefinition *pd = pTable->GetIon(z, a, 0.);
201 
202  // SPECIAL CASE: Non-physical nuclear fragment, for final-state return
203  if (!pd) pd = makeNuclearFragment(a,z);
204 
205  return pd; // This could return a null pointer if above fails
206 }
207 
208 // Creates a non-standard excited nucleus
209 
210 // Creates a non-physical pseudo-nucleus, for return as final-state fragment
211 // from G4IntraNuclearCascader
212 
215  if (a<=0 || z<0 || a<z) {
216  G4cerr << " >>> G4InuclNuclei::makeNuclearFragment() called with"
217  << " impossible arguments A=" << a << " Z=" << z << G4endl;
218  throw G4HadronicException(__FILE__, __LINE__,
219  "G4InuclNuclei impossible A/Z arguments");
220  }
221 
223 
224  // Use local lookup table (see G4IonTable.hh) to maintain singletons
225  // NOTE: G4ParticleDefinitions don't need to be explicitly deleted
226  // (see comments in G4IonTable.cc::~G4IonTable)
227 
228  // If correct nucleus already created return it
229  static std::map<G4int, G4ParticleDefinition*> fragmentList;
230  if (fragmentList.find(code) != fragmentList.end()) return fragmentList[code];
231 
232  // Name string follows format in G4IonTable.cc::GetIonName(Z,A,E)
233  std::stringstream zstr, astr;
234  zstr << z;
235  astr << a;
236 
237  G4String name = "Z" + zstr.str() + "A" + astr.str();
238 
239  G4double mass = getNucleiMass(a,z) *GeV/MeV; // From Bertini to GEANT4 units
240 
241  // Arguments for constructor are as follows
242  // name mass width charge
243  // 2*spin parity C-conjugation
244  // 2*Isospin 2*Isospin3 G-parity
245  // type lepton number baryon number PDG encoding
246  // stable lifetime decay table
247  // shortlived subType anti_encoding Excitation-energy
248 
249  G4Ions* fragPD = new G4Ions(name, mass, 0., z*eplus,
250  0, +1, 0,
251  0, 0, 0,
252  "nucleus", 0, a, code,
253  true, 0., 0,
254  true, "generic", 0, 0.);
255  fragPD->SetAntiPDGEncoding(0);
256 
257  return (fragmentList[code] = fragPD); // Store in table for next lookup
258 }
259 
261  // Simple minded mass calculation use constants in CLHEP (all in MeV)
263 
264  return mass*MeV/GeV; // Convert from GEANT4 to Bertini units
265 }
266 
267 // Assignment operator for use with std::sort()
269  theExitonConfiguration = right.theExitonConfiguration;
271  return *this;
272 }
273 
274 // Dump particle properties for diagnostics
275 
276 void G4InuclNuclei::print(std::ostream& os) const {
278  os << G4endl << " Nucleus: " << getDefinition()->GetParticleName()
279  << " A " << getA() << " Z " << getZ() << " mass " << getMass()
280  << " Eex (MeV) " << getExitationEnergy();
281 
282  if (!theExitonConfiguration.empty())
283  os << G4endl << " " << theExitonConfiguration;
284 }