Geant4 Cross Reference |
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 // particle_hp -- source file 27 // J.P. Wellisch, Nov-1996 28 // A prototype of the low energy neutron transport model. 29 // 30 // 080718 As for secondary photons, if its mean value has a value of integer, 31 // then a sampling of multiplicity that based on Poisson Distribution 32 // is not carried out and the mean is used as a multiplicity. 33 // modified by T. Koi. 34 // 080721 Using ClearHistories() methodl for limiting the sum of secondary energies 35 // modified by T. Koi. 36 // 080901 bug fix of too many secnodaries production in nd reactinos by T. Koi 37 // 38 // P. Arce, June-2014 Conversion neutron_hp to particle_hp 39 // V. Ivanchenko, May-2023 Basic revision of particle HP classes 40 // 41 #include "G4ParticleHPProduct.hh" 42 #include "G4ParticleHPManager.hh" 43 #include "G4HadronicParameters.hh" 44 #include "G4HadronicException.hh" 45 #include "G4ParticleHPContEnergyAngular.hh" 46 #include "G4ParticleHPDiscreteTwoBody.hh" 47 #include "G4ParticleHPIsotropic.hh" 48 #include "G4ParticleHPLabAngularEnergy.hh" 49 #include "G4ParticleHPNBodyPhaseSpace.hh" 50 #include "Randomize.hh" 51 #include "G4Poisson.hh" 52 #include "G4Proton.hh" 53 54 G4ParticleHPProduct::G4ParticleHPProduct() 55 { 56 toBeCached val; 57 fCache.Put(val); 58 59 if (G4ParticleHPManager::GetInstance()->GetPHCUsePoisson()) { 60 theMultiplicityMethod = G4HPMultiPoisson; 61 } else { 62 theMultiplicityMethod = G4HPMultiBetweenInts; 63 } 64 } 65 66 G4ParticleHPProduct::~G4ParticleHPProduct() 67 { 68 delete theDist; 69 } 70 71 void G4ParticleHPProduct::Init(std::istream& aDataFile, const G4ParticleDefinition* projectile) 72 { 73 aDataFile >> theMassCode >> theMass >> theIsomerFlag >> theDistLaw >> theGroundStateQValue 74 >> theActualStateQValue; 75 theGroundStateQValue *= CLHEP::eV; 76 theActualStateQValue *= CLHEP::eV; 77 theYield.Init(aDataFile, CLHEP::eV); 78 theYield.Hash(); 79 if (theDistLaw == 0) { 80 // distribution not known, use E-independent, isotropic 81 // angular distribution 82 theDist = new G4ParticleHPIsotropic; 83 } 84 else if (theDistLaw == 1) { 85 // Continuum energy-angular distribution 86 theDist = new G4ParticleHPContEnergyAngular(projectile); 87 } 88 else if (theDistLaw == 2) { 89 // Discrete 2-body scattering 90 theDist = new G4ParticleHPDiscreteTwoBody; 91 } 92 else if (theDistLaw == 3) { 93 // Isotropic emission 94 theDist = new G4ParticleHPIsotropic; 95 } 96 else if (theDistLaw == 4) { 97 // Discrete 2-body recoil modification not used for now. 98 // theDist = new G4ParticleHPDiscreteTwoBody; 99 // the above is only temporary; 100 // recoils need to be addressed properly 101 } 102 // else if(theDistLaw == 5) 103 // { 104 // charged particles only, to be used in a later stage. @@@@ 105 // } 106 else if (theDistLaw == 6) { 107 // N-Body phase space 108 theDist = new G4ParticleHPNBodyPhaseSpace; 109 } 110 else if (theDistLaw == 7) { 111 // Laboratory angular energy paraetrisation 112 theDist = new G4ParticleHPLabAngularEnergy; 113 } 114 else { 115 throw G4HadronicException(__FILE__, __LINE__, 116 "distribution law unknown to G4ParticleHPProduct"); 117 } 118 if (theDist != nullptr) { 119 theDist->SetQValue(theActualStateQValue); 120 theDist->Init(aDataFile); 121 } 122 } 123 124 G4int G4ParticleHPProduct::GetMultiplicity(G4double anEnergy) 125 { 126 if (theDist == nullptr) { 127 fCache.Get().theCurrentMultiplicity = 0; 128 return 0; 129 } 130 131 G4double mean = theYield.GetY(anEnergy); 132 if (mean <= 0.) { 133 fCache.Get().theCurrentMultiplicity = 0; 134 return 0; 135 } 136 G4int multi = (theMultiplicityMethod == G4HPMultiPoisson) ? 137 (G4int)G4Poisson(mean) : G4lrint(mean); 138 139 #ifdef G4VERBOSE 140 if (G4ParticleHPManager::GetInstance()->GetDEBUG()) 141 G4cout << "G4ParticleHPProduct::GetMultiplicity code=" << theMassCode << " M=" << theMass 142 << " multi=" << multi << " mean=" << mean << G4endl; 143 #endif 144 fCache.Get().theCurrentMultiplicity = multi; 145 146 return multi; 147 } 148 149 G4ReactionProductVector* G4ParticleHPProduct::Sample(G4double anEnergy, G4int multi) 150 { 151 if (theDist == nullptr) { 152 return nullptr; 153 } 154 auto result = new G4ReactionProductVector; 155 156 theDist->SetTarget(fCache.Get().theTarget); 157 theDist->SetProjectileRP(fCache.Get().theProjectileRP); 158 G4ReactionProduct* tmp; 159 theDist->ClearHistories(); 160 161 for (G4int i = 0; i < multi; ++i) { 162 tmp = theDist->Sample(anEnergy, theMassCode, theMass); 163 if (tmp != nullptr) { 164 result->push_back(tmp); 165 #ifdef G4VERBOSE 166 if (G4ParticleHPManager::GetInstance()->GetDEBUG()) 167 G4cout << "multi=" << multi << " i=" << i << " G4ParticleHPProduct::Sample " 168 << tmp->GetDefinition()->GetParticleName() << " E=" << tmp->GetKineticEnergy() 169 << G4endl; 170 #endif 171 } 172 } 173 if (multi == 0) { 174 tmp = theDist->Sample(anEnergy, theMassCode, theMass); 175 delete tmp; 176 } 177 return result; 178 } 179