00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "G4EnergyRangeManager.hh"
00037 #include "Randomize.hh"
00038 #include "G4HadronicException.hh"
00039
00040
00041 G4EnergyRangeManager::G4EnergyRangeManager()
00042 : theHadronicInteractionCounter(0)
00043 {
00044 for (G4int i = 0; i < G4EnergyRangeManager::MAX_NUMBER_OF_MODELS; i++)
00045 theHadronicInteraction[i] = 0;
00046 }
00047
00048
00049 G4EnergyRangeManager::G4EnergyRangeManager(const G4EnergyRangeManager& right)
00050 {
00051 if (this != &right) {
00052 for (G4int i=0; i<theHadronicInteractionCounter; ++i)
00053 theHadronicInteraction[i] = right.theHadronicInteraction[i];
00054 theHadronicInteractionCounter = right.theHadronicInteractionCounter;
00055 }
00056 }
00057
00058
00059 G4EnergyRangeManager&G4EnergyRangeManager::operator=(
00060 const G4EnergyRangeManager &right )
00061 {
00062 if (this != &right) {
00063 for (G4int i=0; i<theHadronicInteractionCounter; ++i)
00064 theHadronicInteraction[i] = right.theHadronicInteraction[i];
00065 theHadronicInteractionCounter = right.theHadronicInteractionCounter;
00066 }
00067 return *this;
00068 }
00069
00070
00071 void G4EnergyRangeManager::RegisterMe(G4HadronicInteraction* a)
00072 {
00073 if( theHadronicInteractionCounter+1 > MAX_NUMBER_OF_MODELS )
00074 {
00075 throw G4HadronicException(__FILE__, __LINE__,"RegisterMe: TOO MANY MODELS");
00076 }
00077 theHadronicInteraction[ theHadronicInteractionCounter++ ] = a;
00078 }
00079
00080
00081 G4HadronicInteraction*
00082 G4EnergyRangeManager::GetHadronicInteraction(
00083 const G4double kineticEnergy,
00084 const G4Material *aMaterial,
00085 const G4Element *anElement ) const
00086 {
00087 G4int counter = GetHadronicInteractionCounter();
00088 if( counter == 0 )
00089 throw G4HadronicException(__FILE__, __LINE__,
00090 "GetHadronicInteraction: NO MODELS STORED");
00091
00092 G4int cou = 0, memory = 0, memor2 = 0;
00093 G4double emi1 = 0.0, ema1 = 0.0, emi2 = 0.0, ema2 = 0.0;
00094 for( G4int i=0; i<counter; i++ )
00095 {
00096 G4double low = theHadronicInteraction[i]->GetMinEnergy( aMaterial, anElement );
00097
00098
00099 if (low == 0.) low = -DBL_MIN;
00100 G4double high = theHadronicInteraction[i]->GetMaxEnergy( aMaterial, anElement );
00101 if( low < kineticEnergy && high >= kineticEnergy )
00102 {
00103 ++cou;
00104 emi2 = emi1;
00105 ema2 = ema1;
00106 emi1 = low;
00107 ema1 = high;
00108 memor2 = memory;
00109 memory = i;
00110 }
00111 }
00112 G4int mem=-1;
00113 G4double rand;
00114 switch ( cou )
00115 {
00116 case 0:
00117 G4cout<<"G4EnergyRangeManager:GetHadronicInteraction: counter="<<counter<<", Ek="
00118 <<kineticEnergy<<", Material = "<<aMaterial->GetName()<<", Element = "
00119 <<anElement->GetName()<<G4endl;
00120 for( G4int j=0; j<counter; j++ )
00121 {
00122 G4HadronicInteraction* HInt=theHadronicInteraction[j];
00123 G4cout<<"*"<<j<<"* low=" <<HInt->GetMinEnergy(aMaterial,anElement)
00124 <<", high="<<HInt->GetMaxEnergy(aMaterial,anElement)<<G4endl;
00125 }
00126 throw G4HadronicException(__FILE__, __LINE__,
00127 "GetHadronicInteraction: No Model found");
00128 return 0;
00129 case 1:
00130 mem = memory;
00131 break;
00132 case 2:
00133 if( (emi2<=emi1 && ema2>=ema1) || (emi2>=emi1 && ema2<=ema1) )
00134 {
00135 G4cout<<"G4EnergyRangeManager:GetHadronicInteraction: counter="<<counter<<", Ek="
00136 <<kineticEnergy<<", Material = "<<aMaterial->GetName()<<", Element = "
00137 <<anElement->GetName()<<G4endl;
00138 if(counter) for( G4int j=0; j<counter; j++ )
00139 {
00140 G4HadronicInteraction* HInt=theHadronicInteraction[j];
00141 G4cout<<"*"<<j<<"* low=" <<HInt->GetMinEnergy(aMaterial,anElement)
00142 <<", high="<<HInt->GetMaxEnergy(aMaterial,anElement)<<G4endl;
00143 }
00144 throw G4HadronicException(__FILE__, __LINE__,
00145 "GetHadronicInteraction: Energy ranges of two models fully overlapping");
00146 }
00147 rand = G4UniformRand();
00148 if( emi1 < emi2 )
00149 {
00150 if( (ema1-kineticEnergy)/(ema1-emi2)<rand )
00151 mem = memor2;
00152 else
00153 mem = memory;
00154 } else {
00155 if( (ema2-kineticEnergy)/(ema2-emi1)<rand )
00156 mem = memory;
00157 else
00158 mem = memor2;
00159 }
00160 break;
00161 default:
00162 throw G4HadronicException(__FILE__, __LINE__,
00163 "GetHadronicInteraction: More than two competing models in this energy range");
00164 }
00165 return theHadronicInteraction[mem];
00166 }
00167
00168
00169