G4InuclNuclei.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 // $Id$
00027 //
00028 // 20100301  M. Kelsey -- Add function to create unphysical nuclei for use
00029 //           as temporary final-state fragments.
00030 // 20100319  M. Kelsey -- Add information message to makeNuclearFragment().
00031 //           Use new GetBindingEnergy() function instead of bindingEnergy().
00032 // 20100622  M. Kelsey -- Use local "bindingEnergy()" function to call through.
00033 // 20100627  M. Kelsey -- Test for non-physical fragments and abort job.
00034 // 20100630  M. Kelsey -- Use excitation energy in G4Ions
00035 // 20100714  M. Kelsey -- Use G4DynamicParticle::theDynamicalMass to deal with
00036 //           excitation energy without instantianting "infinite" G4PartDefns.
00037 // 20100719  M. Kelsey -- Change excitation energy without altering momentum
00038 // 20100906  M. Kelsey -- Add fill() functions to rewrite contents
00039 // 20100910  M. Kelsey -- Add clearExitonConfiguration() to fill() functions
00040 // 20100914  M. Kelsey -- Make printout symmetric with G4InuclElemPart,
00041 //              migrate to integer A and Z
00042 // 20100924  M. Kelsey -- Add constructor to copy G4Fragment input, and output
00043 //              functions to create G4Fragment
00044 // 20110214  M. Kelsey -- Replace integer "model" with enum
00045 // 20110308  M. Kelsey -- Follow new G4Fragment interface for hole types
00046 // 20110427  M. Kelsey -- Remove PDG-code warning
00047 // 20110721  M. Kelsey -- Follow base-class ctor change to pass model directly
00048 // 20110829  M. Kelsey -- Add constructor to copy G4V3DNucleus input
00049 // 20110919  M. Kelsey -- Special case:  Allow fill(A=0,Z=0) to make dummy
00050 // 20110922  M. Kelsey -- Add stream argument to printParticle() => print()
00051 // 20121009  M. Kelsey -- Add report of excitons if non-empty
00052 
00053 #include <assert.h>
00054 #include <sstream>
00055 #include <map>
00056 
00057 #include "G4InuclNuclei.hh"
00058 #include "G4SystemOfUnits.hh"
00059 #include "G4Fragment.hh"
00060 #include "G4HadronicException.hh"
00061 #include "G4InuclSpecialFunctions.hh"
00062 #include "G4Ions.hh"
00063 #include "G4IonTable.hh"
00064 #include "G4NucleiProperties.hh"
00065 #include "G4Nucleon.hh"
00066 #include "G4ParticleDefinition.hh"
00067 #include "G4ParticleTable.hh"
00068 #include "G4V3DNucleus.hh"
00069 
00070 using namespace G4InuclSpecialFunctions;
00071 
00072 
00073 // Convert contents from (via constructor) and to G4Fragment
00074 
00075 G4InuclNuclei::G4InuclNuclei(const G4Fragment& aFragment,
00076                              G4InuclParticle::Model model)
00077   : G4InuclParticle() {
00078   copy(aFragment, model);
00079 }
00080 
00081 void G4InuclNuclei::copy(const G4Fragment& aFragment, Model model) {
00082   fill(aFragment.GetMomentum()/GeV, aFragment.GetA_asInt(),
00083        aFragment.GetZ_asInt(), aFragment.GetExcitationEnergy(), model);
00084 
00085   // Exciton configuration must be set by hand
00086   theExitonConfiguration.protonQuasiParticles = aFragment.GetNumberOfCharged();
00087 
00088   theExitonConfiguration.neutronQuasiParticles =
00089     aFragment.GetNumberOfParticles() - aFragment.GetNumberOfCharged();
00090 
00091   theExitonConfiguration.protonHoles = aFragment.GetNumberOfChargedHoles();
00092 
00093   theExitonConfiguration.neutronHoles =
00094     aFragment.GetNumberOfHoles() - theExitonConfiguration.protonHoles;
00095 }
00096 
00097 
00098 // FIXME:  Should we have a local buffer and return by const-reference instead?
00099 G4Fragment G4InuclNuclei::makeG4Fragment() const {
00100   G4Fragment frag(getA(), getZ(), getMomentum()*GeV);   // From Bertini units
00101 
00102   // Note:  exciton configuration has to be set piece by piece
00103   frag.SetNumberOfHoles(theExitonConfiguration.protonHoles
00104                         + theExitonConfiguration.neutronHoles,
00105                         theExitonConfiguration.protonHoles);
00106 
00107   frag.SetNumberOfExcitedParticle(theExitonConfiguration.protonQuasiParticles 
00108                   + theExitonConfiguration.neutronQuasiParticles,
00109                   theExitonConfiguration.protonQuasiParticles);
00110 
00111   return frag;
00112 }
00113 
00114 G4InuclNuclei::operator G4Fragment() const {
00115   return makeG4Fragment();
00116 }
00117 
00118 
00119 // Convert contents from (via constructor) G4V3DNucleus
00120 
00121 G4InuclNuclei::G4InuclNuclei(G4V3DNucleus* a3DNucleus,
00122                              G4InuclParticle::Model model)
00123   : G4InuclParticle() {
00124   copy(a3DNucleus, model);
00125 }
00126 
00127 void G4InuclNuclei::copy(G4V3DNucleus* a3DNucleus, Model model) {
00128   if (!a3DNucleus) return;              // Null pointer means no action
00129 
00130   fill(0., a3DNucleus->GetMassNumber(), a3DNucleus->GetCharge(), 0., model);
00131 
00132   // Convert every hit nucleon into an exciton hole
00133   if (a3DNucleus->StartLoop()) {
00134     G4Nucleon* nucl = 0;
00135     while ((nucl = a3DNucleus->GetNextNucleon())) {
00136       if (nucl->AreYouHit()) {  // Found previously interacted nucleon
00137         if (nucl->GetParticleType() == G4Proton::Definition())
00138           theExitonConfiguration.protonHoles++;
00139 
00140         if (nucl->GetParticleType() == G4Neutron::Definition())
00141           theExitonConfiguration.neutronHoles++;
00142       }
00143     }
00144   }
00145 }
00146 
00147 
00148 // Overwrite data structure (avoids creating/copying temporaries)
00149 
00150 void G4InuclNuclei::fill(const G4LorentzVector& mom, G4int a, G4int z,
00151                          G4double exc, G4InuclParticle::Model model) {
00152   setDefinition(makeDefinition(a,z));
00153   setMomentum(mom);
00154   setExitationEnergy(exc);
00155   clearExitonConfiguration();
00156   setModel(model);
00157 }
00158 
00159 void G4InuclNuclei::fill(G4double ekin, G4int a, G4int z, G4double exc,
00160                          G4InuclParticle::Model model) {
00161   setDefinition(makeDefinition(a,z));
00162   setKineticEnergy(ekin);
00163   setExitationEnergy(exc);
00164   clearExitonConfiguration();
00165   setModel(model);
00166 }
00167 
00168 void G4InuclNuclei::clear() {
00169   setDefinition(0);
00170   clearExitonConfiguration();
00171   setModel(G4InuclParticle::DefaultModel);
00172 }
00173 
00174 
00175 // Change excitation energy while keeping momentum vector constant
00176 
00177 void G4InuclNuclei::setExitationEnergy(G4double e) {
00178   G4double ekin = getKineticEnergy();           // Current kinetic energy
00179 
00180   G4double emass = getNucleiMass() + e*MeV/GeV; // From Bertini to G4 units
00181 
00182   // Directly compute new kinetic energy from old
00183   G4double ekin_new = std::sqrt(emass*emass + ekin*(2.*getMass()+ekin)) - emass;
00184 
00185   setMass(emass);              // Momentum is computed from mass and Ekin
00186   setKineticEnergy(ekin_new);
00187 }
00188 
00189 
00190 // Convert nuclear configuration to standard GEANT4 pointer
00191 
00192 // WARNING:  Opposite conventions!  G4InuclNuclei uses (A,Z) everywhere, while
00193 //        G4ParticleTable::GetIon() uses (Z,A)!
00194 
00195 G4ParticleDefinition* G4InuclNuclei::makeDefinition(G4int a, G4int z) {
00196   // SPECIAL CASE:  (0,0) means create dummy without definition
00197   if (0 == a && 0 == z) return 0;
00198 
00199   G4ParticleTable* pTable = G4ParticleTable::GetParticleTable();
00200   G4ParticleDefinition *pd = pTable->GetIon(z, a, 0.);
00201 
00202   // SPECIAL CASE:  Non-physical nuclear fragment, for final-state return
00203   if (!pd) pd = makeNuclearFragment(a,z);
00204 
00205   return pd;            // This could return a null pointer if above fails
00206 }
00207 
00208 // Creates a non-standard excited nucleus
00209 
00210 // Creates a non-physical pseudo-nucleus, for return as final-state fragment
00211 // from G4IntraNuclearCascader
00212 
00213 G4ParticleDefinition* 
00214 G4InuclNuclei::makeNuclearFragment(G4int a, G4int z) {
00215   if (a<=0 || z<0 || a<z) {
00216     G4cerr << " >>> G4InuclNuclei::makeNuclearFragment() called with"
00217            << " impossible arguments A=" << a << " Z=" << z << G4endl;
00218     throw G4HadronicException(__FILE__, __LINE__,
00219                               "G4InuclNuclei impossible A/Z arguments");
00220   }
00221 
00222   G4int code = G4IonTable::GetNucleusEncoding(z, a);
00223 
00224   // Use local lookup table (see G4IonTable.hh) to maintain singletons
00225   // NOTE:  G4ParticleDefinitions don't need to be explicitly deleted
00226   //        (see comments in G4IonTable.cc::~G4IonTable)
00227 
00228   // If correct nucleus already created return it
00229   static std::map<G4int, G4ParticleDefinition*> fragmentList;
00230   if (fragmentList.find(code) != fragmentList.end()) return fragmentList[code];
00231 
00232   // Name string follows format in G4IonTable.cc::GetIonName(Z,A,E)
00233   std::stringstream zstr, astr;
00234   zstr << z;
00235   astr << a;
00236   
00237   G4String name = "Z" + zstr.str() + "A" + astr.str();
00238   
00239   G4double mass = getNucleiMass(a,z) *GeV/MeV;  // From Bertini to GEANT4 units
00240   
00241   //    Arguments for constructor are as follows
00242   //               name             mass          width         charge
00243   //             2*spin           parity  C-conjugation
00244   //          2*Isospin       2*Isospin3       G-parity
00245   //               type    lepton number  baryon number   PDG encoding
00246   //             stable         lifetime    decay table
00247   //             shortlived      subType    anti_encoding Excitation-energy
00248   
00249   G4Ions* fragPD = new G4Ions(name,       mass, 0., z*eplus,
00250                               0,          +1,   0,
00251                               0,          0,    0,
00252                               "nucleus",  0,    a, code,
00253                               true,       0.,   0,
00254                               true, "generic",  0,  0.);
00255   fragPD->SetAntiPDGEncoding(0);
00256 
00257   return (fragmentList[code] = fragPD);     // Store in table for next lookup
00258 }
00259 
00260 G4double G4InuclNuclei::getNucleiMass(G4int a, G4int z, G4double exc) {
00261   // Simple minded mass calculation use constants in CLHEP (all in MeV)
00262   G4double mass = G4NucleiProperties::GetNuclearMass(a,z) + exc;
00263 
00264   return mass*MeV/GeV;          // Convert from GEANT4 to Bertini units
00265 }
00266 
00267 // Assignment operator for use with std::sort()
00268 G4InuclNuclei& G4InuclNuclei::operator=(const G4InuclNuclei& right) {
00269   theExitonConfiguration = right.theExitonConfiguration;
00270   G4InuclParticle::operator=(right);
00271   return *this;
00272 }
00273 
00274 // Dump particle properties for diagnostics
00275 
00276 void G4InuclNuclei::print(std::ostream& os) const {
00277   G4InuclParticle::print(os);
00278   os << G4endl << " Nucleus: " << getDefinition()->GetParticleName() 
00279      << " A " << getA() << " Z " << getZ() << " mass " << getMass()
00280      << " Eex (MeV) " << getExitationEnergy();
00281 
00282   if (!theExitonConfiguration.empty())
00283     os << G4endl << "         " << theExitonConfiguration;
00284 }

Generated on Mon May 27 17:48:38 2013 for Geant4 by  doxygen 1.4.7