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
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"
62#include "G4Ions.hh"
63#include "G4IonTable.hh"
64#include "G4NucleiProperties.hh"
65#include "G4Nucleon.hh"
67#include "G4ParticleTable.hh"
68#include "G4V3DNucleus.hh"
69
70using namespace G4InuclSpecialFunctions;
71
72
73// Convert contents from (via constructor) and to G4Fragment
74
77 : G4InuclParticle() {
78 copy(aFragment, model);
79}
80
81void 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
114G4InuclNuclei::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
127void G4InuclNuclei::copy(G4V3DNucleus* a3DNucleus, Model model) {
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
140 if (nucl->GetParticleType() == G4Neutron::Definition())
141 theExitonConfiguration.neutronHoles++;
142 }
143 }
144 }
145}
146
147
148// Overwrite data structure (avoids creating/copying temporaries)
149
151 G4double exc, G4InuclParticle::Model model) {
153 setMomentum(mom);
156 setModel(model);
157}
158
162 setKineticEnergy(ekin);
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
276void 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}
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cerr
G4int GetNumberOfParticles() const
Definition: G4Fragment.hh:305
G4int GetNumberOfHoles() const
Definition: G4Fragment.hh:325
G4int GetNumberOfChargedHoles() const
Definition: G4Fragment.hh:330
G4double GetExcitationEnergy() const
Definition: G4Fragment.hh:235
const G4LorentzVector & GetMomentum() const
Definition: G4Fragment.hh:251
G4int GetZ_asInt() const
Definition: G4Fragment.hh:223
void SetNumberOfHoles(G4int valueTot, G4int valueP=0)
Definition: G4Fragment.hh:335
void SetNumberOfExcitedParticle(G4int valueTot, G4int valueP)
Definition: G4Fragment.hh:316
G4int GetNumberOfCharged() const
Definition: G4Fragment.hh:310
G4int GetA_asInt() const
Definition: G4Fragment.hh:218
G4Fragment makeG4Fragment() const
static G4ParticleDefinition * makeNuclearFragment(G4int a, G4int z)
static G4ParticleDefinition * makeDefinition(G4int a, G4int z)
void copy(const G4Fragment &aFragment, Model model=DefaultModel)
G4double getNucleiMass() const
void setExitationEnergy(G4double e)
G4InuclNuclei & operator=(const G4InuclNuclei &right)
G4int getZ() const
G4double getExitationEnergy() const
void fill(G4int a, G4int z, G4double exc=0., Model model=DefaultModel)
void clearExitonConfiguration()
G4int getA() const
virtual void print(std::ostream &os) const
void setMass(G4double mass)
G4ParticleDefinition * getDefinition() const
virtual void print(std::ostream &os) const
G4double getKineticEnergy() const
G4InuclParticle & operator=(const G4InuclParticle &right)
G4double getMass() const
G4LorentzVector getMomentum() const
void setKineticEnergy(G4double ekin)
void setMomentum(const G4LorentzVector &mom)
void setDefinition(G4ParticleDefinition *pd)
void setModel(Model model)
static G4int GetNucleusEncoding(G4int Z, G4int A, G4double E=0.0, G4int J=0)
Definition: G4IonTable.cc:446
Definition: G4Ions.hh:52
static G4Neutron * Definition()
Definition: G4Neutron.cc:54
static G4double GetNuclearMass(const G4double A, const G4double Z)
G4bool AreYouHit() const
Definition: G4Nucleon.hh:97
G4ParticleDefinition * GetParticleType() const
Definition: G4Nucleon.hh:84
void SetAntiPDGEncoding(G4int aEncoding)
const G4String & GetParticleName() const
static G4ParticleTable * GetParticleTable()
G4ParticleDefinition * GetIon(G4int atomicNumber, G4int atomicMass, G4double excitationEnergy)
static G4Proton * Definition()
Definition: G4Proton.cc:49
virtual G4Nucleon * GetNextNucleon()=0
virtual G4int GetCharge()=0
virtual G4bool StartLoop()=0
virtual G4int GetMassNumber()=0