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 98067 2016-07-01 16:33:54Z 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 theHadronicInteractionCounter = right.theHadronicInteractionCounter; >> 49 theHadronicInteraction = right.theHadronicInteraction; >> 50 } >> 51 >> 52 G4EnergyRangeManager& G4EnergyRangeManager::operator=( >> 53 const G4EnergyRangeManager& right) >> 54 { >> 55 if (this != &right) { >> 56 theHadronicInteractionCounter = right.theHadronicInteractionCounter; >> 57 theHadronicInteraction = right.theHadronicInteraction; >> 58 } >> 59 return *this; >> 60 } >> 61 46 void G4EnergyRangeManager::RegisterMe(G4Hadron 62 void G4EnergyRangeManager::RegisterMe(G4HadronicInteraction* a) 47 { 63 { 48 if(!a) { return; } 64 if(!a) { return; } 49 if(0 < theHadronicInteractionCounter) { 65 if(0 < theHadronicInteractionCounter) { 50 for(G4int i=0; i<theHadronicInteractionCou 66 for(G4int i=0; i<theHadronicInteractionCounter; ++i) { 51 if(a == theHadronicInteraction[i]) { ret 67 if(a == theHadronicInteraction[i]) { return; } 52 } 68 } 53 } 69 } 54 theHadronicInteraction.push_back(a); 70 theHadronicInteraction.push_back(a); 55 ++theHadronicInteractionCounter; 71 ++theHadronicInteractionCounter; 56 } 72 } 57 73 >> 74 58 G4HadronicInteraction* 75 G4HadronicInteraction* 59 G4EnergyRangeManager::GetHadronicInteraction(c 76 G4EnergyRangeManager::GetHadronicInteraction(const G4HadProjectile & aHadProjectile, 60 G 77 G4Nucleus & aTargetNucleus, 61 c 78 const G4Material* aMaterial, 62 c 79 const G4Element* anElement) const 63 { 80 { 64 // VI shortcut: if only one interaction is r << 81 if(0 == theHadronicInteractionCounter) { 65 if(1 == theHadronicInteractionCounter) { ret << 82 throw G4HadronicException(__FILE__, __LINE__, 66 else if(0 == theHadronicInteractionCounter) << 83 "GetHadronicInteraction: NO MODELS STORED"); 67 G4cout << "G4EnergyRangeManager::GetHadron << 68 << "no models defined for a process" << G << 69 return nullptr; << 70 } 84 } 71 85 72 G4double kineticEnergy = aHadProjectile.GetK 86 G4double kineticEnergy = aHadProjectile.GetKineticEnergy(); 73 // For ions, get kinetic energy per nucleon 87 // For ions, get kinetic energy per nucleon 74 if ( std::abs( aHadProjectile.GetDefinition( << 88 if ( aHadProjectile.GetDefinition()->GetBaryonNumber() > 1.5 ) { 75 kineticEnergy /= static_cast< G4double >( << 89 kineticEnergy /= aHadProjectile.GetDefinition()->GetBaryonNumber(); 76 } 90 } 77 91 78 G4int cou = 0, memory = 0, memor2 = 0; 92 G4int cou = 0, memory = 0, memor2 = 0; 79 G4double emi1 = 0.0, ema1 = 0.0, emi2 = 0.0, 93 G4double emi1 = 0.0, ema1 = 0.0, emi2 = 0.0, ema2 = 0.0; 80 94 81 for (G4int i = 0; i<theHadronicInteractionCo 95 for (G4int i = 0; i<theHadronicInteractionCounter; ++i) { 82 if ( theHadronicInteraction[i]->IsApplicab 96 if ( theHadronicInteraction[i]->IsApplicable( aHadProjectile, aTargetNucleus ) ) { 83 G4double low = theHadronicInteraction[i 97 G4double low = theHadronicInteraction[i]->GetMinEnergy( aMaterial, anElement ); >> 98 // Work-around for particles with 0 kinetic energy, which still >> 99 // require a model to return a ParticleChange >> 100 //if (low == 0.) low = -DBL_MIN; 84 G4double high = theHadronicInteraction[i 101 G4double high = theHadronicInteraction[i]->GetMaxEnergy( aMaterial, anElement ); 85 if (low <= kineticEnergy && high >= kine << 102 if (low <= kineticEnergy && high > kineticEnergy) { 86 ++cou; 103 ++cou; 87 emi2 = emi1; 104 emi2 = emi1; 88 ema2 = ema1; 105 ema2 = ema1; 89 emi1 = low; 106 emi1 = low; 90 ema1 = high; 107 ema1 = high; 91 memor2 = memory; 108 memor2 = memory; 92 memory = i; 109 memory = i; 93 } 110 } 94 } 111 } 95 } 112 } 96 113 97 G4HadronicInteraction* hi = nullptr; << 114 G4int mem = -1; >> 115 G4double rand; 98 switch (cou) { 116 switch (cou) { 99 case 0: 117 case 0: 100 G4cout << "No model found out of " << th << 118 G4cout<<"G4EnergyRangeManager:GetHadronicInteraction: counter=" 101 for( G4int j=0; j<theHadronicInteraction << 119 <<theHadronicInteractionCounter<<", Ek=" 102 G4HadronicInteraction* hint=theHadronicInter << 120 <<kineticEnergy<<", Material = "<<aMaterial->GetName() 103 G4cout << " "<< j << ". Elow= " << hint-> << 121 <<", Element = " 104 <<", Ehigh= " << hint->GetMaxEnergy(a << 122 <<anElement->GetName()<<G4endl; 105 <<" " << hint->GetModelName() << G4 << 123 for( G4int j=0; j<theHadronicInteractionCounter; ++j) 106 } << 124 { 107 break; << 125 G4HadronicInteraction* HInt=theHadronicInteraction[j]; 108 << 126 G4cout<<"*"<<j<<"* low=" <<HInt->GetMinEnergy(aMaterial,anElement) >> 127 <<", high="<<HInt->GetMaxEnergy(aMaterial,anElement)<<G4endl; >> 128 } >> 129 throw G4HadronicException(__FILE__, __LINE__, >> 130 "GetHadronicInteraction: No Model found"); >> 131 return 0; 109 case 1: 132 case 1: 110 hi = theHadronicInteraction[memory]; << 133 mem = memory; 111 break; << 134 break; 112 << 113 case 2: 135 case 2: 114 if( (emi2<=emi1 && ema2>=ema1) || (emi2> << 136 if( (emi2<=emi1 && ema2>=ema1) || (emi2>=emi1 && ema2<=ema1) ) 115 G4cout << "Energy ranges of two models fully << 137 { 116 for( G4int j=0; j<theHadronicInteractionCoun << 138 G4cout<<"G4EnergyRangeManager:GetHadronicInteraction: counter=" 117 G4HadronicInteraction* hint=theHadronicInt << 139 <<theHadronicInteractionCounter<<", Ek=" 118 G4cout << " "<< j << ". Elow= " << hint << 140 <<kineticEnergy<<", Material = "<<aMaterial->GetName() 119 <<", Ehigh= " << hint->GetMaxEnergy(aMate << 141 <<", Element = " 120 <<" " << hint->GetModelName() << G4endl << 142 <<anElement->GetName()<<G4endl; 121 } << 143 for( G4int j=0; j<theHadronicInteractionCounter; ++j) 122 } else { << 144 { 123 G4double rand = G4UniformRand(); << 145 G4HadronicInteraction* HInt=theHadronicInteraction[j]; 124 G4int mem; << 146 G4cout<<"*"<<j<<"* low=" <<HInt->GetMinEnergy(aMaterial,anElement) 125 if( emi1 < emi2 ) { << 147 <<", high="<<HInt->GetMaxEnergy(aMaterial,anElement)<<G4endl; 126 if( (ema1-kineticEnergy) < rand*(ema1-emi2 << 148 } 127 mem = memor2; << 149 throw G4HadronicException(__FILE__, __LINE__, 128 } else { << 150 "GetHadronicInteraction: Energy ranges of two models fully overlapping"); 129 mem = memory; << 151 } 130 } << 152 rand = G4UniformRand(); 131 } else { << 153 if( emi1 < emi2 ) 132 if( (ema2-kineticEnergy) < rand*(ema2-emi1 << 154 { 133 mem = memory; << 155 if( (ema1-kineticEnergy) < rand*(ema1-emi2) ) { 134 } else { << 156 mem = memor2; 135 mem = memor2; << 157 } else { 136 } << 158 mem = memory; 137 } << 159 } 138 hi = theHadronicInteraction[mem]; << 160 } else { 139 } << 161 if( (ema2-kineticEnergy) < rand*(ema2-emi1) ) { 140 break; << 162 mem = memory; >> 163 } else { >> 164 mem = memor2; >> 165 } >> 166 } >> 167 break; >> 168 default: >> 169 throw G4HadronicException(__FILE__, __LINE__, >> 170 "GetHadronicInteraction: More than two competing models in this energy range"); >> 171 } 141 172 >> 173 return theHadronicInteraction[mem]; >> 174 } >> 175 >> 176 >> 177 G4HadronicInteraction* >> 178 G4EnergyRangeManager::GetHadronicInteraction(const G4double kineticEnergy, >> 179 const G4Material* aMaterial, >> 180 const G4Element* anElement) const >> 181 { >> 182 if(0 == theHadronicInteractionCounter) { >> 183 throw G4HadronicException(__FILE__, __LINE__, >> 184 "GetHadronicInteraction: NO MODELS STORED"); >> 185 } >> 186 G4int cou = 0, memory = 0, memor2 = 0; >> 187 G4double emi1 = 0.0, ema1 = 0.0, emi2 = 0.0, ema2 = 0.0; >> 188 >> 189 for (G4int i = 0; i<theHadronicInteractionCounter; ++i) { >> 190 G4double low = theHadronicInteraction[i]->GetMinEnergy( aMaterial, anElement ); >> 191 // Work-around for particles with 0 kinetic energy, which still >> 192 // require a model to return a ParticleChange >> 193 //if (low == 0.) low = -DBL_MIN; >> 194 G4double high = theHadronicInteraction[i]->GetMaxEnergy( aMaterial, anElement ); >> 195 if (low <= kineticEnergy && high > kineticEnergy) { >> 196 ++cou; >> 197 emi2 = emi1; >> 198 ema2 = ema1; >> 199 emi1 = low; >> 200 ema1 = high; >> 201 memor2 = memory; >> 202 memory = i; >> 203 } >> 204 } >> 205 >> 206 G4int mem = -1; >> 207 G4double rand; >> 208 switch (cou) { >> 209 case 0: >> 210 G4cout<<"G4EnergyRangeManager:GetHadronicInteraction: counter=" >> 211 <<theHadronicInteractionCounter<<", Ek=" >> 212 <<kineticEnergy<<", Material = "<<aMaterial->GetName() >> 213 <<", Element = " >> 214 <<anElement->GetName()<<G4endl; >> 215 for( G4int j=0; j<theHadronicInteractionCounter; ++j) >> 216 { >> 217 G4HadronicInteraction* HInt=theHadronicInteraction[j]; >> 218 G4cout<<"*"<<j<<"* low=" <<HInt->GetMinEnergy(aMaterial,anElement) >> 219 <<", high="<<HInt->GetMaxEnergy(aMaterial,anElement)<<G4endl; >> 220 } >> 221 throw G4HadronicException(__FILE__, __LINE__, >> 222 "GetHadronicInteraction: No Model found"); >> 223 return 0; >> 224 case 1: >> 225 mem = memory; >> 226 break; >> 227 case 2: >> 228 if( (emi2<=emi1 && ema2>=ema1) || (emi2>=emi1 && ema2<=ema1) ) >> 229 { >> 230 G4cout<<"G4EnergyRangeManager:GetHadronicInteraction: counter=" >> 231 <<theHadronicInteractionCounter<<", Ek=" >> 232 <<kineticEnergy<<", Material = "<<aMaterial->GetName() >> 233 <<", Element = " >> 234 <<anElement->GetName()<<G4endl; >> 235 for( G4int j=0; j<theHadronicInteractionCounter; ++j) >> 236 { >> 237 G4HadronicInteraction* HInt=theHadronicInteraction[j]; >> 238 G4cout<<"*"<<j<<"* low=" <<HInt->GetMinEnergy(aMaterial,anElement) >> 239 <<", high="<<HInt->GetMaxEnergy(aMaterial,anElement)<<G4endl; >> 240 } >> 241 throw G4HadronicException(__FILE__, __LINE__, >> 242 "GetHadronicInteraction: Energy ranges of two models fully overlapping"); >> 243 } >> 244 rand = G4UniformRand(); >> 245 if( emi1 < emi2 ) >> 246 { >> 247 if( (ema1-kineticEnergy) < rand*(ema1-emi2) ) { >> 248 mem = memor2; >> 249 } else { >> 250 mem = memory; >> 251 } >> 252 } else { >> 253 if( (ema2-kineticEnergy) < rand*(ema2-emi1) ) { >> 254 mem = memory; >> 255 } else { >> 256 mem = memor2; >> 257 } >> 258 } >> 259 break; 142 default: 260 default: 143 G4cout << "More than two competing model << 261 throw G4HadronicException(__FILE__, __LINE__, 144 for( G4int j=0; j<theHadronicInteraction << 262 "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 } 263 } 152 return hi; << 264 >> 265 return theHadronicInteraction[mem]; 153 } 266 } 154 267 155 std::vector<G4HadronicInteraction*>& 268 std::vector<G4HadronicInteraction*>& 156 G4EnergyRangeManager::GetHadronicInteractionLi 269 G4EnergyRangeManager::GetHadronicInteractionList() 157 { 270 { 158 return theHadronicInteraction; 271 return theHadronicInteraction; 159 } 272 } 160 273 >> 274 #include "G4SystemOfUnits.hh" 161 void G4EnergyRangeManager::Dump( G4int verbose 275 void G4EnergyRangeManager::Dump( G4int verbose ) 162 { 276 { 163 G4cout << "G4EnergyRangeManager " << this << 277 G4cout << "G4EnergyRangeManager " << this << G4endl; 164 for (G4int i = 0 ; i < theHadronicInteractio 278 for (G4int i = 0 ; i < theHadronicInteractionCounter; i++) { 165 G4cout << " HadronicModel " << i <<":" 279 G4cout << " HadronicModel " << i <<":" 166 << theHadronicInteraction[i]->GetMo 280 << theHadronicInteraction[i]->GetModelName() << G4endl; 167 if (verbose > 0) { 281 if (verbose > 0) { 168 G4cout << " Minimum Energy " 282 G4cout << " Minimum Energy " 169 << theHadronicInteraction[i]->GetMinEne 283 << theHadronicInteraction[i]->GetMinEnergy()/GeV << " [GeV], " 170 << "Maximum Energy " 284 << "Maximum Energy " 171 << theHadronicInteraction[i]->GetMaxEne 285 << theHadronicInteraction[i]->GetMaxEnergy()/GeV << " [GeV]" 172 << G4endl; 286 << G4endl; 173 } 287 } 174 } 288 } 175 } 289 } 176 290 177 void 291 void 178 G4EnergyRangeManager::BuildPhysicsTable(const 292 G4EnergyRangeManager::BuildPhysicsTable(const G4ParticleDefinition& aParticleType) 179 { 293 { 180 for (auto & hadi : theHadronicInteraction) { << 294 for ( std::vector<G4HadronicInteraction*>::iterator 181 hadi->BuildPhysicsTable( aParticleType ); << 295 it = theHadronicInteraction.begin() ; it != theHadronicInteraction.end() ; it++ ) { 182 } << 296 (*it)->BuildPhysicsTable( aParticleType ); >> 297 } 183 } 298 } 184 << 299 /* end of file */ 185 300 186 301