Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // >> 26 // $Id: G4EnergyRangeManager.cc 83772 2014-09-15 07:18:08Z gcosmo $ 26 // 27 // 27 // Hadronic Process: Energy Range Manager 28 // Hadronic Process: Energy Range Manager 28 // original by H.P. Wellisch 29 // original by H.P. Wellisch 29 // modified by J.L. Chuma, TRIUMF, 22-Nov-199 30 // modified by J.L. Chuma, TRIUMF, 22-Nov-1996 30 // Last modified: 24-Mar-1997 31 // Last modified: 24-Mar-1997 31 // fix in the counter-hndling: H.P. Wellisch 32 // fix in the counter-hndling: H.P. Wellisch 04-Apr-97 32 // throw an exception if no model found: J.L 33 // throw an exception if no model found: J.L. Chuma 04-Apr-97 33 34 34 #include "G4EnergyRangeManager.hh" 35 #include "G4EnergyRangeManager.hh" 35 #include "Randomize.hh" 36 #include "Randomize.hh" 36 #include "G4HadronicException.hh" 37 #include "G4HadronicException.hh" 37 #include "G4SystemOfUnits.hh" << 38 38 39 G4EnergyRangeManager::G4EnergyRangeManager() 39 G4EnergyRangeManager::G4EnergyRangeManager() 40 : theHadronicInteractionCounter(0) 40 : theHadronicInteractionCounter(0) 41 {} 41 {} 42 42 43 G4EnergyRangeManager::~G4EnergyRangeManager() 43 G4EnergyRangeManager::~G4EnergyRangeManager() 44 {} 44 {} 45 45 >> 46 G4EnergyRangeManager::G4EnergyRangeManager(const G4EnergyRangeManager& right) >> 47 { >> 48 if (this != &right) { >> 49 theHadronicInteractionCounter = right.theHadronicInteractionCounter; >> 50 theHadronicInteraction = right.theHadronicInteraction; >> 51 } >> 52 } >> 53 >> 54 G4EnergyRangeManager& G4EnergyRangeManager::operator=( >> 55 const G4EnergyRangeManager& right) >> 56 { >> 57 if (this != &right) { >> 58 theHadronicInteractionCounter = right.theHadronicInteractionCounter; >> 59 theHadronicInteraction = right.theHadronicInteraction; >> 60 } >> 61 return *this; >> 62 } >> 63 46 void G4EnergyRangeManager::RegisterMe(G4Hadron 64 void G4EnergyRangeManager::RegisterMe(G4HadronicInteraction* a) 47 { 65 { 48 if(!a) { return; } 66 if(!a) { return; } 49 if(0 < theHadronicInteractionCounter) { 67 if(0 < theHadronicInteractionCounter) { 50 for(G4int i=0; i<theHadronicInteractionCou 68 for(G4int i=0; i<theHadronicInteractionCounter; ++i) { 51 if(a == theHadronicInteraction[i]) { ret 69 if(a == theHadronicInteraction[i]) { return; } 52 } 70 } 53 } 71 } 54 theHadronicInteraction.push_back(a); 72 theHadronicInteraction.push_back(a); 55 ++theHadronicInteractionCounter; 73 ++theHadronicInteractionCounter; 56 } 74 } 57 75 >> 76 58 G4HadronicInteraction* 77 G4HadronicInteraction* 59 G4EnergyRangeManager::GetHadronicInteraction(c 78 G4EnergyRangeManager::GetHadronicInteraction(const G4HadProjectile & aHadProjectile, 60 G 79 G4Nucleus & aTargetNucleus, 61 c 80 const G4Material* aMaterial, 62 c 81 const G4Element* anElement) const 63 { 82 { 64 // VI shortcut: if only one interaction is r << 83 if(0 == theHadronicInteractionCounter) { 65 if(1 == theHadronicInteractionCounter) { ret << 84 throw G4HadronicException(__FILE__, __LINE__, 66 else if(0 == theHadronicInteractionCounter) << 85 "GetHadronicInteraction: NO MODELS STORED"); 67 G4cout << "G4EnergyRangeManager::GetHadron << 68 << "no models defined for a process" << G << 69 return nullptr; << 70 } 86 } 71 87 72 G4double kineticEnergy = aHadProjectile.GetK 88 G4double kineticEnergy = aHadProjectile.GetKineticEnergy(); 73 // For ions, get kinetic energy per nucleon 89 // For ions, get kinetic energy per nucleon 74 if ( std::abs( aHadProjectile.GetDefinition( << 90 if ( aHadProjectile.GetDefinition()->GetBaryonNumber() > 1.5 ) { 75 kineticEnergy /= static_cast< G4double >( << 91 kineticEnergy /= aHadProjectile.GetDefinition()->GetBaryonNumber(); 76 } 92 } 77 93 78 G4int cou = 0, memory = 0, memor2 = 0; 94 G4int cou = 0, memory = 0, memor2 = 0; 79 G4double emi1 = 0.0, ema1 = 0.0, emi2 = 0.0, 95 G4double emi1 = 0.0, ema1 = 0.0, emi2 = 0.0, ema2 = 0.0; 80 96 81 for (G4int i = 0; i<theHadronicInteractionCo 97 for (G4int i = 0; i<theHadronicInteractionCounter; ++i) { 82 if ( theHadronicInteraction[i]->IsApplicab 98 if ( theHadronicInteraction[i]->IsApplicable( aHadProjectile, aTargetNucleus ) ) { 83 G4double low = theHadronicInteraction[i 99 G4double low = theHadronicInteraction[i]->GetMinEnergy( aMaterial, anElement ); >> 100 // Work-around for particles with 0 kinetic energy, which still >> 101 // require a model to return a ParticleChange >> 102 //if (low == 0.) low = -DBL_MIN; 84 G4double high = theHadronicInteraction[i 103 G4double high = theHadronicInteraction[i]->GetMaxEnergy( aMaterial, anElement ); 85 if (low <= kineticEnergy && high >= kine << 104 if (low <= kineticEnergy && high > kineticEnergy) { 86 ++cou; 105 ++cou; 87 emi2 = emi1; 106 emi2 = emi1; 88 ema2 = ema1; 107 ema2 = ema1; 89 emi1 = low; 108 emi1 = low; 90 ema1 = high; 109 ema1 = high; 91 memor2 = memory; 110 memor2 = memory; 92 memory = i; 111 memory = i; 93 } 112 } 94 } 113 } 95 } 114 } 96 115 97 G4HadronicInteraction* hi = nullptr; << 116 G4int mem = -1; >> 117 G4double rand; 98 switch (cou) { 118 switch (cou) { 99 case 0: 119 case 0: 100 G4cout << "No model found out of " << th << 120 G4cout<<"G4EnergyRangeManager:GetHadronicInteraction: counter=" 101 for( G4int j=0; j<theHadronicInteraction << 121 <<theHadronicInteractionCounter<<", Ek=" 102 G4HadronicInteraction* hint=theHadronicInter << 122 <<kineticEnergy<<", Material = "<<aMaterial->GetName() 103 G4cout << " "<< j << ". Elow= " << hint-> << 123 <<", Element = " 104 <<", Ehigh= " << hint->GetMaxEnergy(a << 124 <<anElement->GetName()<<G4endl; 105 <<" " << hint->GetModelName() << G4 << 125 for( G4int j=0; j<theHadronicInteractionCounter; ++j) 106 } << 126 { 107 break; << 127 G4HadronicInteraction* HInt=theHadronicInteraction[j]; 108 << 128 G4cout<<"*"<<j<<"* low=" <<HInt->GetMinEnergy(aMaterial,anElement) >> 129 <<", high="<<HInt->GetMaxEnergy(aMaterial,anElement)<<G4endl; >> 130 } >> 131 throw G4HadronicException(__FILE__, __LINE__, >> 132 "GetHadronicInteraction: No Model found"); >> 133 return 0; 109 case 1: 134 case 1: 110 hi = theHadronicInteraction[memory]; << 135 mem = memory; 111 break; << 136 break; 112 << 113 case 2: 137 case 2: 114 if( (emi2<=emi1 && ema2>=ema1) || (emi2> << 138 if( (emi2<=emi1 && ema2>=ema1) || (emi2>=emi1 && ema2<=ema1) ) 115 G4cout << "Energy ranges of two models fully << 139 { 116 for( G4int j=0; j<theHadronicInteractionCoun << 140 G4cout<<"G4EnergyRangeManager:GetHadronicInteraction: counter=" 117 G4HadronicInteraction* hint=theHadronicInt << 141 <<theHadronicInteractionCounter<<", Ek=" 118 G4cout << " "<< j << ". Elow= " << hint << 142 <<kineticEnergy<<", Material = "<<aMaterial->GetName() 119 <<", Ehigh= " << hint->GetMaxEnergy(aMate << 143 <<", Element = " 120 <<" " << hint->GetModelName() << G4endl << 144 <<anElement->GetName()<<G4endl; 121 } << 145 for( G4int j=0; j<theHadronicInteractionCounter; ++j) 122 } else { << 146 { 123 G4double rand = G4UniformRand(); << 147 G4HadronicInteraction* HInt=theHadronicInteraction[j]; 124 G4int mem; << 148 G4cout<<"*"<<j<<"* low=" <<HInt->GetMinEnergy(aMaterial,anElement) 125 if( emi1 < emi2 ) { << 149 <<", high="<<HInt->GetMaxEnergy(aMaterial,anElement)<<G4endl; 126 if( (ema1-kineticEnergy) < rand*(ema1-emi2 << 150 } 127 mem = memor2; << 151 throw G4HadronicException(__FILE__, __LINE__, 128 } else { << 152 "GetHadronicInteraction: Energy ranges of two models fully overlapping"); 129 mem = memory; << 153 } 130 } << 154 rand = G4UniformRand(); 131 } else { << 155 if( emi1 < emi2 ) 132 if( (ema2-kineticEnergy) < rand*(ema2-emi1 << 156 { 133 mem = memory; << 157 if( (ema1-kineticEnergy) < rand*(ema1-emi2) ) { 134 } else { << 158 mem = memor2; 135 mem = memor2; << 159 } else { 136 } << 160 mem = memory; 137 } << 161 } 138 hi = theHadronicInteraction[mem]; << 162 } else { 139 } << 163 if( (ema2-kineticEnergy) < rand*(ema2-emi1) ) { 140 break; << 164 mem = memory; >> 165 } else { >> 166 mem = memor2; >> 167 } >> 168 } >> 169 break; >> 170 default: >> 171 throw G4HadronicException(__FILE__, __LINE__, >> 172 "GetHadronicInteraction: More than two competing models in this energy range"); >> 173 } >> 174 >> 175 return theHadronicInteraction[mem]; >> 176 } >> 177 >> 178 >> 179 G4HadronicInteraction* >> 180 G4EnergyRangeManager::GetHadronicInteraction(const G4double kineticEnergy, >> 181 const G4Material* aMaterial, >> 182 const G4Element* anElement) const >> 183 { >> 184 if(0 == theHadronicInteractionCounter) { >> 185 throw G4HadronicException(__FILE__, __LINE__, >> 186 "GetHadronicInteraction: NO MODELS STORED"); >> 187 } >> 188 G4int cou = 0, memory = 0, memor2 = 0; >> 189 G4double emi1 = 0.0, ema1 = 0.0, emi2 = 0.0, ema2 = 0.0; >> 190 >> 191 for (G4int i = 0; i<theHadronicInteractionCounter; ++i) { >> 192 G4double low = theHadronicInteraction[i]->GetMinEnergy( aMaterial, anElement ); >> 193 // Work-around for particles with 0 kinetic energy, which still >> 194 // require a model to return a ParticleChange >> 195 //if (low == 0.) low = -DBL_MIN; >> 196 G4double high = theHadronicInteraction[i]->GetMaxEnergy( aMaterial, anElement ); >> 197 if (low <= kineticEnergy && high > kineticEnergy) { >> 198 ++cou; >> 199 emi2 = emi1; >> 200 ema2 = ema1; >> 201 emi1 = low; >> 202 ema1 = high; >> 203 memor2 = memory; >> 204 memory = i; >> 205 } >> 206 } 141 207 >> 208 G4int mem = -1; >> 209 G4double rand; >> 210 switch (cou) { >> 211 case 0: >> 212 G4cout<<"G4EnergyRangeManager:GetHadronicInteraction: counter=" >> 213 <<theHadronicInteractionCounter<<", Ek=" >> 214 <<kineticEnergy<<", Material = "<<aMaterial->GetName() >> 215 <<", Element = " >> 216 <<anElement->GetName()<<G4endl; >> 217 for( G4int j=0; j<theHadronicInteractionCounter; ++j) >> 218 { >> 219 G4HadronicInteraction* HInt=theHadronicInteraction[j]; >> 220 G4cout<<"*"<<j<<"* low=" <<HInt->GetMinEnergy(aMaterial,anElement) >> 221 <<", high="<<HInt->GetMaxEnergy(aMaterial,anElement)<<G4endl; >> 222 } >> 223 throw G4HadronicException(__FILE__, __LINE__, >> 224 "GetHadronicInteraction: No Model found"); >> 225 return 0; >> 226 case 1: >> 227 mem = memory; >> 228 break; >> 229 case 2: >> 230 if( (emi2<=emi1 && ema2>=ema1) || (emi2>=emi1 && ema2<=ema1) ) >> 231 { >> 232 G4cout<<"G4EnergyRangeManager:GetHadronicInteraction: counter=" >> 233 <<theHadronicInteractionCounter<<", Ek=" >> 234 <<kineticEnergy<<", Material = "<<aMaterial->GetName() >> 235 <<", Element = " >> 236 <<anElement->GetName()<<G4endl; >> 237 for( G4int j=0; j<theHadronicInteractionCounter; ++j) >> 238 { >> 239 G4HadronicInteraction* HInt=theHadronicInteraction[j]; >> 240 G4cout<<"*"<<j<<"* low=" <<HInt->GetMinEnergy(aMaterial,anElement) >> 241 <<", high="<<HInt->GetMaxEnergy(aMaterial,anElement)<<G4endl; >> 242 } >> 243 throw G4HadronicException(__FILE__, __LINE__, >> 244 "GetHadronicInteraction: Energy ranges of two models fully overlapping"); >> 245 } >> 246 rand = G4UniformRand(); >> 247 if( emi1 < emi2 ) >> 248 { >> 249 if( (ema1-kineticEnergy) < rand*(ema1-emi2) ) { >> 250 mem = memor2; >> 251 } else { >> 252 mem = memory; >> 253 } >> 254 } else { >> 255 if( (ema2-kineticEnergy) < rand*(ema2-emi1) ) { >> 256 mem = memory; >> 257 } else { >> 258 mem = memor2; >> 259 } >> 260 } >> 261 break; 142 default: 262 default: 143 G4cout << "More than two competing model << 263 throw G4HadronicException(__FILE__, __LINE__, 144 for( G4int j=0; j<theHadronicInteraction << 264 "GetHadronicInteraction: More than two competing models in this energy range"); 145 G4HadronicInteraction* hint=theHadronicInter << 146 G4cout << " "<< j << ". Elow= " << hint-> << 147 <<", Ehigh= " << hint->GetMaxEnergy(a << 148 <<" " << hint->GetModelName() << G4 << 149 } << 150 break; << 151 } 265 } 152 return hi; << 266 >> 267 return theHadronicInteraction[mem]; 153 } 268 } 154 269 155 std::vector<G4HadronicInteraction*>& 270 std::vector<G4HadronicInteraction*>& 156 G4EnergyRangeManager::GetHadronicInteractionLi 271 G4EnergyRangeManager::GetHadronicInteractionList() 157 { 272 { 158 return theHadronicInteraction; 273 return theHadronicInteraction; 159 } 274 } 160 275 >> 276 #include "G4SystemOfUnits.hh" 161 void G4EnergyRangeManager::Dump( G4int verbose 277 void G4EnergyRangeManager::Dump( G4int verbose ) 162 { 278 { 163 G4cout << "G4EnergyRangeManager " << this << 279 G4cout << "G4EnergyRangeManager " << this << G4endl; 164 for (G4int i = 0 ; i < theHadronicInteractio 280 for (G4int i = 0 ; i < theHadronicInteractionCounter; i++) { 165 G4cout << " HadronicModel " << i <<":" 281 G4cout << " HadronicModel " << i <<":" 166 << theHadronicInteraction[i]->GetMo 282 << theHadronicInteraction[i]->GetModelName() << G4endl; 167 if (verbose > 0) { 283 if (verbose > 0) { 168 G4cout << " Minimum Energy " 284 G4cout << " Minimum Energy " 169 << theHadronicInteraction[i]->GetMinEne 285 << theHadronicInteraction[i]->GetMinEnergy()/GeV << " [GeV], " 170 << "Maximum Energy " 286 << "Maximum Energy " 171 << theHadronicInteraction[i]->GetMaxEne 287 << theHadronicInteraction[i]->GetMaxEnergy()/GeV << " [GeV]" 172 << G4endl; 288 << G4endl; 173 } 289 } 174 } 290 } 175 } 291 } 176 292 177 void 293 void 178 G4EnergyRangeManager::BuildPhysicsTable(const 294 G4EnergyRangeManager::BuildPhysicsTable(const G4ParticleDefinition& aParticleType) 179 { 295 { 180 for (auto & hadi : theHadronicInteraction) { << 296 for ( std::vector<G4HadronicInteraction*>::iterator 181 hadi->BuildPhysicsTable( aParticleType ); << 297 it = theHadronicInteraction.begin() ; it != theHadronicInteraction.end() ; it++ ) { 182 } << 298 (*it)->BuildPhysicsTable( aParticleType ); >> 299 } 183 } 300 } 184 << 301 /* end of file */ 185 302 186 303