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 #include "G4PenelopeIonisationXSHandler.hh"
00036 #include "G4PhysicalConstants.hh"
00037 #include "G4SystemOfUnits.hh"
00038 #include "G4ParticleDefinition.hh"
00039 #include "G4Electron.hh"
00040 #include "G4Positron.hh"
00041 #include "G4PenelopeOscillatorManager.hh"
00042 #include "G4PenelopeOscillator.hh"
00043 #include "G4PenelopeCrossSection.hh"
00044 #include "G4PhysicsFreeVector.hh"
00045 #include "G4PhysicsLogVector.hh"
00046
00047 G4PenelopeIonisationXSHandler::G4PenelopeIonisationXSHandler(size_t nb)
00048 :XSTableElectron(0),XSTablePositron(0),
00049 theDeltaTable(0),energyGrid(0)
00050 {
00051 nBins = nb;
00052 G4double LowEnergyLimit = 100.0*eV;
00053 G4double HighEnergyLimit = 100.0*GeV;
00054 oscManager = G4PenelopeOscillatorManager::GetOscillatorManager();
00055 XSTableElectron = new
00056 std::map< std::pair<const G4Material*,G4double>, G4PenelopeCrossSection*>;
00057 XSTablePositron = new
00058 std::map< std::pair<const G4Material*,G4double>, G4PenelopeCrossSection*>;
00059
00060 theDeltaTable = new std::map<const G4Material*,G4PhysicsFreeVector*>;
00061 energyGrid = new G4PhysicsLogVector(LowEnergyLimit,
00062 HighEnergyLimit,
00063 nBins-1);
00064
00065 verboseLevel = 0;
00066 }
00067
00068
00069
00070 G4PenelopeIonisationXSHandler::~G4PenelopeIonisationXSHandler()
00071 {
00072 std::map< std::pair<const G4Material*,G4double>, G4PenelopeCrossSection*>::iterator i;
00073 if (XSTableElectron)
00074 {
00075 for (i=XSTableElectron->begin(); i != XSTableElectron->end(); i++)
00076 {
00077 G4PenelopeCrossSection* tab = i->second;
00078 delete tab;
00079 }
00080 delete XSTableElectron;
00081 XSTableElectron = 0;
00082 }
00083
00084 if (XSTablePositron)
00085 {
00086 for (i=XSTablePositron->begin(); i != XSTablePositron->end(); i++)
00087 {
00088 G4PenelopeCrossSection* tab = i->second;
00089 delete tab;
00090 }
00091 delete XSTablePositron;
00092 XSTablePositron = 0;
00093 }
00094
00095 std::map<const G4Material*,G4PhysicsFreeVector*>::iterator k;
00096 if (theDeltaTable)
00097 {
00098 for (k=theDeltaTable->begin();k!=theDeltaTable->end();k++)
00099 delete k->second;
00100 delete theDeltaTable;
00101 theDeltaTable = 0;
00102 }
00103
00104 if (energyGrid)
00105 delete energyGrid;
00106
00107 if (verboseLevel > 2)
00108 G4cout << "G4PenelopeIonisationXSHandler. Tables have been cleared"
00109 << G4endl;
00110 }
00111
00112
00113
00114 G4PenelopeCrossSection*
00115 G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple(const G4ParticleDefinition* part,
00116 const G4Material* mat,
00117 G4double cut)
00118 {
00119 if (part != G4Electron::Electron() && part != G4Positron::Positron())
00120 {
00121 G4ExceptionDescription ed;
00122 ed << "Invalid particle: " << part->GetParticleName() << G4endl;
00123 G4Exception("G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
00124 "em0001",FatalException,ed);
00125 return NULL;
00126 }
00127
00128 if (part == G4Electron::Electron())
00129 {
00130 if (!XSTableElectron)
00131 {
00132 G4Exception("G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
00133 "em0028",FatalException,
00134 "The Cross Section Table for e- was not initialized correctly!");
00135 return NULL;
00136 }
00137 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
00138 if (XSTableElectron->count(theKey))
00139 return XSTableElectron->find(theKey)->second;
00140 else
00141 {
00142 BuildXSTable(mat,cut,part);
00143 if (XSTableElectron->count(theKey))
00144 return XSTableElectron->find(theKey)->second;
00145 else
00146 {
00147 G4ExceptionDescription ed;
00148 ed << "Unable to build e- table for " << mat->GetName() << G4endl;
00149 G4Exception("G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
00150 "em0029",FatalException,ed);
00151 }
00152 }
00153 }
00154
00155 if (part == G4Positron::Positron())
00156 {
00157 if (!XSTablePositron)
00158 {
00159 G4Exception("G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
00160 "em0028",FatalException,
00161 "The Cross Section Table for e+ was not initialized correctly!");
00162 return NULL;
00163 }
00164 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
00165 if (XSTablePositron->count(theKey))
00166 return XSTablePositron->find(theKey)->second;
00167 else
00168 {
00169 BuildXSTable(mat,cut,part);
00170 if (XSTablePositron->count(theKey))
00171 return XSTablePositron->find(theKey)->second;
00172 else
00173 {
00174 G4ExceptionDescription ed;
00175 ed << "Unable to build e+ table for " << mat->GetName() << G4endl;
00176 G4Exception("G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
00177 "em0029",FatalException,ed);
00178 }
00179 }
00180 }
00181 return NULL;
00182 }
00183
00184
00185
00186 void G4PenelopeIonisationXSHandler::BuildXSTable(const G4Material* mat,G4double cut,
00187 const G4ParticleDefinition* part)
00188 {
00189
00190
00191
00192
00193
00194
00195 if (verboseLevel > 2)
00196 {
00197 G4cout << "G4PenelopeIonisationXSHandler: going to build cross section table " << G4endl;
00198 G4cout << "for " << part->GetParticleName() << " in " << mat->GetName() << G4endl;
00199 }
00200
00201
00202 G4PenelopeOscillatorTable* theTable = oscManager->GetOscillatorTableIonisation(mat);
00203 size_t numberOfOscillators = theTable->size();
00204
00205 if (energyGrid->GetVectorLength() != nBins)
00206 {
00207 G4ExceptionDescription ed;
00208 ed << "Energy Grid looks not initialized" << G4endl;
00209 ed << nBins << " " << energyGrid->GetVectorLength() << G4endl;
00210 G4Exception("G4PenelopeIonisationXSHandler::BuildXSTable()",
00211 "em2030",FatalException,ed);
00212 }
00213
00214 G4PenelopeCrossSection* XSEntry = new G4PenelopeCrossSection(nBins,numberOfOscillators);
00215
00216
00217 for (size_t bin=0;bin<nBins;bin++)
00218 {
00219 G4double energy = energyGrid->GetLowEdgeEnergy(bin);
00220 G4double XH0=0, XH1=0, XH2=0;
00221 G4double XS0=0, XS1=0, XS2=0;
00222
00223
00224 for (size_t iosc=0;iosc<numberOfOscillators;iosc++)
00225 {
00226 G4DataVector* tempStorage = 0;
00227
00228 G4PenelopeOscillator* theOsc = (*theTable)[iosc];
00229 G4double delta = GetDensityCorrection(mat,energy);
00230 if (part == G4Electron::Electron())
00231 tempStorage = ComputeShellCrossSectionsElectron(theOsc,energy,cut,delta);
00232 else if (part == G4Positron::Positron())
00233 tempStorage = ComputeShellCrossSectionsPositron(theOsc,energy,cut,delta);
00234
00235 if (!tempStorage)
00236 {
00237 G4ExceptionDescription ed;
00238 ed << "Problem in calculating the shell XS for shell # "
00239 << iosc << G4endl;
00240 G4Exception("G4PenelopeIonisationXSHandler::BuildXSTable()",
00241 "em2031",FatalException,ed);
00242 delete XSEntry;
00243 return;
00244 }
00245 if (tempStorage->size() != 6)
00246 {
00247 G4ExceptionDescription ed;
00248 ed << "Problem in calculating the shell XS " << G4endl;
00249 ed << "Result has dimension " << tempStorage->size() << " instead of 6" << G4endl;
00250 G4Exception("G4PenelopeIonisationXSHandler::BuildXSTable()",
00251 "em2031",FatalException,ed);
00252 }
00253 G4double stre = theOsc->GetOscillatorStrength();
00254
00255 XH0 += stre*(*tempStorage)[0];
00256 XH1 += stre*(*tempStorage)[1];
00257 XH2 += stre*(*tempStorage)[2];
00258 XS0 += stre*(*tempStorage)[3];
00259 XS1 += stre*(*tempStorage)[4];
00260 XS2 += stre*(*tempStorage)[5];
00261 XSEntry->AddShellCrossSectionPoint(bin,iosc,energy,stre*(*tempStorage)[0]);
00262 if (tempStorage)
00263 {
00264 delete tempStorage;
00265 tempStorage = 0;
00266 }
00267 }
00268 XSEntry->AddCrossSectionPoint(bin,energy,XH0,XH1,XH2,XS0,XS1,XS2);
00269 }
00270
00271
00272 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
00273 if (part == G4Electron::Electron())
00274 XSTableElectron->insert(std::make_pair(theKey,XSEntry));
00275 else if (part == G4Positron::Positron())
00276 XSTablePositron->insert(std::make_pair(theKey,XSEntry));
00277 else
00278 delete XSEntry;
00279
00280 return;
00281 }
00282
00283
00284
00285
00286 G4double G4PenelopeIonisationXSHandler::GetDensityCorrection(const G4Material* mat,
00287 G4double energy)
00288 {
00289 G4double result = 0;
00290 if (!theDeltaTable)
00291 {
00292 G4Exception("G4PenelopeIonisationXSHandler::GetDensityCorrection()",
00293 "em2032",FatalException,
00294 "Delta Table not initialized. Was Initialise() run?");
00295 return 0;
00296 }
00297 if (energy <= 0*eV)
00298 {
00299 G4cout << "G4PenelopeIonisationXSHandler::GetDensityCorrection()" << G4endl;
00300 G4cout << "Invalid energy " << energy/eV << " eV " << G4endl;
00301 return 0;
00302 }
00303 G4double logene = std::log(energy);
00304
00305
00306 if (!(theDeltaTable->count(mat)))
00307 BuildDeltaTable(mat);
00308
00309 if (theDeltaTable->count(mat))
00310 {
00311 G4PhysicsFreeVector* vec = theDeltaTable->find(mat)->second;
00312 result = vec->Value(logene);
00313 }
00314 else
00315 {
00316 G4ExceptionDescription ed;
00317 ed << "Unable to build table for " << mat->GetName() << G4endl;
00318 G4Exception("G4PenelopeIonisationXSHandler::GetDensityCorrection()",
00319 "em2033",FatalException,ed);
00320 }
00321
00322 return result;
00323 }
00324
00325
00326
00327 void G4PenelopeIonisationXSHandler::BuildDeltaTable(const G4Material* mat)
00328 {
00329 G4PenelopeOscillatorTable* theTable = oscManager->GetOscillatorTableIonisation(mat);
00330 G4double plasmaSq = oscManager->GetPlasmaEnergySquared(mat);
00331 G4double totalZ = oscManager->GetTotalZ(mat);
00332 size_t numberOfOscillators = theTable->size();
00333
00334 if (energyGrid->GetVectorLength() != nBins)
00335 {
00336 G4ExceptionDescription ed;
00337 ed << "Energy Grid for Delta table looks not initialized" << G4endl;
00338 ed << nBins << " " << energyGrid->GetVectorLength() << G4endl;
00339 G4Exception("G4PenelopeIonisationXSHandler::BuildDeltaTable()",
00340 "em2030",FatalException,ed);
00341 }
00342
00343 G4PhysicsFreeVector* theVector = new G4PhysicsFreeVector(nBins);
00344
00345
00346 for (size_t bin=0;bin<nBins;bin++)
00347 {
00348 G4double delta = 0.;
00349 G4double energy = energyGrid->GetLowEdgeEnergy(bin);
00350
00351
00352 G4double gam = 1.0+(energy/electron_mass_c2);
00353 G4double gamSq = gam*gam;
00354
00355 G4double TST = totalZ/(gamSq*plasmaSq);
00356 G4double wl2 = 0;
00357 G4double fdel = 0;
00358
00359
00360 for (size_t i=0;i<numberOfOscillators;i++)
00361 {
00362 G4PenelopeOscillator* theOsc = (*theTable)[i];
00363 G4double wri = theOsc->GetResonanceEnergy();
00364 fdel += theOsc->GetOscillatorStrength()/(wri*wri+wl2);
00365 }
00366 if (fdel >= TST)
00367 {
00368
00369 G4PenelopeOscillator* theOsc = (*theTable)[numberOfOscillators-1];
00370 wl2 = theOsc->GetResonanceEnergy()*theOsc->GetResonanceEnergy();
00371
00372
00373 G4bool loopAgain = false;
00374 do
00375 {
00376 loopAgain = false;
00377 wl2 += wl2;
00378 fdel = 0.;
00379 for (size_t i=0;i<numberOfOscillators;i++)
00380 {
00381 G4PenelopeOscillator* theOscLocal1 = (*theTable)[i];
00382 G4double wri = theOscLocal1->GetResonanceEnergy();
00383 fdel += theOscLocal1->GetOscillatorStrength()/(wri*wri+wl2);
00384 }
00385 if (fdel > TST)
00386 loopAgain = true;
00387 }while(loopAgain);
00388
00389 G4double wl2l = 0;
00390 G4double wl2u = wl2;
00391
00392 do
00393 {
00394 loopAgain = false;
00395 wl2 = 0.5*(wl2l+wl2u);
00396 fdel = 0;
00397 for (size_t i=0;i<numberOfOscillators;i++)
00398 {
00399 G4PenelopeOscillator* theOscLocal2 = (*theTable)[i];
00400 G4double wri = theOscLocal2->GetResonanceEnergy();
00401 fdel += theOscLocal2->GetOscillatorStrength()/(wri*wri+wl2);
00402 }
00403 if (fdel > TST)
00404 wl2l = wl2;
00405 else
00406 wl2u = wl2;
00407 if ((wl2u-wl2l)>1e-12*wl2)
00408 loopAgain = true;
00409 }while(loopAgain);
00410
00411
00412 delta = 0.;
00413 for (size_t i=0;i<numberOfOscillators;i++)
00414 {
00415 G4PenelopeOscillator* theOscLocal3 = (*theTable)[i];
00416 G4double wri = theOscLocal3->GetResonanceEnergy();
00417 delta += theOscLocal3->GetOscillatorStrength()*
00418 std::log(1.0+(wl2/(wri*wri)));
00419 }
00420 delta = (delta/totalZ)-wl2/(gamSq*plasmaSq);
00421 }
00422 energy = std::max(1e-9*eV,energy);
00423 theVector->PutValue(bin,std::log(energy),delta);
00424 }
00425 theDeltaTable->insert(std::make_pair(mat,theVector));
00426 return;
00427 }
00428
00429
00430 G4DataVector* G4PenelopeIonisationXSHandler::ComputeShellCrossSectionsElectron(G4PenelopeOscillator* theOsc,
00431 G4double energy,
00432 G4double cut,
00433 G4double delta)
00434 {
00435
00436
00437
00438
00439
00440
00441
00442
00443 G4DataVector* result = new G4DataVector();
00444 for (size_t i=0;i<6;i++)
00445 result->push_back(0.);
00446 G4double ionEnergy = theOsc->GetIonisationEnergy();
00447
00448
00449 if (energy < ionEnergy)
00450 return result;
00451
00452 G4double H0=0.,H1=0.,H2=0.;
00453 G4double S0=0.,S1=0.,S2=0.;
00454
00455
00456 G4double gamma = 1.0+energy/electron_mass_c2;
00457 G4double gammaSq = gamma*gamma;
00458 G4double beta = (gammaSq-1.0)/gammaSq;
00459 G4double pielr2 = pi*classic_electr_radius*classic_electr_radius;
00460 G4double constant = pielr2*2.0*electron_mass_c2/beta;
00461 G4double XHDT0 = std::log(gammaSq)-beta;
00462
00463 G4double cpSq = energy*(energy+2.0*electron_mass_c2);
00464 G4double cp = std::sqrt(cpSq);
00465 G4double amol = (energy/(energy+electron_mass_c2))*(energy/(energy+electron_mass_c2));
00466
00467
00468
00469
00470 G4double resEne = theOsc->GetResonanceEnergy();
00471 G4double cutoffEne = theOsc->GetCutoffRecoilResonantEnergy();
00472 if (energy > resEne)
00473 {
00474 G4double cp1Sq = (energy-resEne)*(energy-resEne+2.0*electron_mass_c2);
00475 G4double cp1 = std::sqrt(cp1Sq);
00476
00477
00478 G4double QM = 0;
00479 if (resEne > 1e-6*energy)
00480 QM = std::sqrt((cp-cp1)*(cp-cp1)+electron_mass_c2*electron_mass_c2)-electron_mass_c2;
00481 else
00482 {
00483 QM = resEne*resEne/(beta*2.0*electron_mass_c2);
00484 QM = QM*(1.0-0.5*QM/electron_mass_c2);
00485 }
00486 G4double SDL1 = 0;
00487 if (QM < cutoffEne)
00488 SDL1 = std::log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)));
00489
00490
00491 if (SDL1)
00492 {
00493 G4double SDT1 = std::max(XHDT0-delta,0.0);
00494 G4double SD1 = SDL1+SDT1;
00495 if (cut > resEne)
00496 {
00497 S1 = SD1;
00498 S0 = SD1/resEne;
00499 S2 = SD1*resEne;
00500 }
00501 else
00502 {
00503 H1 = SD1;
00504 H0 = SD1/resEne;
00505 H2 = SD1*resEne;
00506 }
00507 }
00508 }
00509
00510
00511
00512 G4double wl = std::max(cut,cutoffEne);
00513 G4double ee = energy + ionEnergy;
00514 G4double wu = 0.5*ee;
00515 if (wl < wu-(1e-5*eV))
00516 {
00517 H0 += (1.0/(ee-wu)) - (1.0/(ee-wl)) - (1.0/wu) + (1.0/wl) +
00518 (1.0-amol)*std::log(((ee-wu)*wl)/((ee-wl)*wu))/ee +
00519 amol*(wu-wl)/(ee*ee);
00520 H1 += std::log(wu/wl)+(ee/(ee-wu))-(ee/(ee-wl)) +
00521 (2.0-amol)*std::log((ee-wu)/(ee-wl)) +
00522 amol*(wu*wu-wl*wl)/(2.0*ee*ee);
00523 H2 += (2.0-amol)*(wu-wl)+(wu*(2.0*ee-wu)/(ee-wu)) -
00524 (wl*(2.0*ee-wl)/(ee-wl)) +
00525 (3.0-amol)*ee*std::log((ee-wu)/(ee-wl)) +
00526 amol*(wu*wu*wu-wl*wl*wl)/(3.0*ee*ee);
00527 wu = wl;
00528 }
00529 wl = cutoffEne;
00530
00531 if (wl > wu-(1e-5*eV))
00532 {
00533 (*result)[0] = constant*H0;
00534 (*result)[1] = constant*H1;
00535 (*result)[2] = constant*H2;
00536 (*result)[3] = constant*S0;
00537 (*result)[4] = constant*S1;
00538 (*result)[5] = constant*S2;
00539 return result;
00540 }
00541
00542 S0 += (1.0/(ee-wu))-(1.0/(ee-wl)) - (1.0/wu) + (1.0/wl) +
00543 (1.0-amol)*std::log(((ee-wu)*wl)/((ee-wl)*wu))/ee +
00544 amol*(wu-wl)/(ee*ee);
00545 S1 += std::log(wu/wl)+(ee/(ee-wu))-(ee/(ee-wl)) +
00546 (2.0-amol)*std::log((ee-wu)/(ee-wl)) +
00547 amol*(wu*wu-wl*wl)/(2.0*ee*ee);
00548 S2 += (2.0-amol)*(wu-wl)+(wu*(2.0*ee-wu)/(ee-wu)) -
00549 (wl*(2.0*ee-wl)/(ee-wl)) +
00550 (3.0-amol)*ee*std::log((ee-wu)/(ee-wl)) +
00551 amol*(wu*wu*wu-wl*wl*wl)/(3.0*ee*ee);
00552
00553 (*result)[0] = constant*H0;
00554 (*result)[1] = constant*H1;
00555 (*result)[2] = constant*H2;
00556 (*result)[3] = constant*S0;
00557 (*result)[4] = constant*S1;
00558 (*result)[5] = constant*S2;
00559 return result;
00560 }
00561
00562 G4DataVector* G4PenelopeIonisationXSHandler::ComputeShellCrossSectionsPositron(G4PenelopeOscillator* theOsc,
00563 G4double energy,
00564 G4double cut,
00565 G4double delta)
00566 {
00567
00568
00569
00570
00571
00572
00573
00574
00575 G4DataVector* result = new G4DataVector();
00576 for (size_t i=0;i<6;i++)
00577 result->push_back(0.);
00578 G4double ionEnergy = theOsc->GetIonisationEnergy();
00579
00580
00581 if (energy < ionEnergy)
00582 return result;
00583
00584 G4double H0=0.,H1=0.,H2=0.;
00585 G4double S0=0.,S1=0.,S2=0.;
00586
00587
00588 G4double gamma = 1.0+energy/electron_mass_c2;
00589 G4double gammaSq = gamma*gamma;
00590 G4double beta = (gammaSq-1.0)/gammaSq;
00591 G4double pielr2 = pi*classic_electr_radius*classic_electr_radius;
00592 G4double constant = pielr2*2.0*electron_mass_c2/beta;
00593 G4double XHDT0 = std::log(gammaSq)-beta;
00594
00595 G4double cpSq = energy*(energy+2.0*electron_mass_c2);
00596 G4double cp = std::sqrt(cpSq);
00597 G4double amol = (energy/(energy+electron_mass_c2))*(energy/(energy+electron_mass_c2));
00598 G4double g12 = (gamma+1.0)*(gamma+1.0);
00599
00600 G4double bha1 = amol*(2.0*g12-1.0)/(gammaSq-1.0);
00601 G4double bha2 = amol*(3.0+1.0/g12);
00602 G4double bha3 = amol*2.0*gamma*(gamma-1.0)/g12;
00603 G4double bha4 = amol*(gamma-1.0)*(gamma-1.0)/g12;
00604
00605
00606
00607
00608 G4double resEne = theOsc->GetResonanceEnergy();
00609 G4double cutoffEne = theOsc->GetCutoffRecoilResonantEnergy();
00610 if (energy > resEne)
00611 {
00612 G4double cp1Sq = (energy-resEne)*(energy-resEne+2.0*electron_mass_c2);
00613 G4double cp1 = std::sqrt(cp1Sq);
00614
00615
00616 G4double QM = 0;
00617 if (resEne > 1e-6*energy)
00618 QM = std::sqrt((cp-cp1)*(cp-cp1)+electron_mass_c2*electron_mass_c2)-electron_mass_c2;
00619 else
00620 {
00621 QM = resEne*resEne/(beta*2.0*electron_mass_c2);
00622 QM = QM*(1.0-0.5*QM/electron_mass_c2);
00623 }
00624 G4double SDL1 = 0;
00625 if (QM < cutoffEne)
00626 SDL1 = std::log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)));
00627
00628
00629 if (SDL1)
00630 {
00631 G4double SDT1 = std::max(XHDT0-delta,0.0);
00632 G4double SD1 = SDL1+SDT1;
00633 if (cut > resEne)
00634 {
00635 S1 = SD1;
00636 S0 = SD1/resEne;
00637 S2 = SD1*resEne;
00638 }
00639 else
00640 {
00641 H1 = SD1;
00642 H0 = SD1/resEne;
00643 H2 = SD1*resEne;
00644 }
00645 }
00646 }
00647
00648
00649
00650
00651 G4double wl = std::max(cut,cutoffEne);
00652 G4double wu = energy;
00653 G4double energySq = energy*energy;
00654 if (wl < wu-(1e-5*eV))
00655 {
00656 G4double wlSq = wl*wl;
00657 G4double wuSq = wu*wu;
00658 H0 += (1.0/wl) - (1.0/wu)- bha1*std::log(wu/wl)/energy
00659 + bha2*(wu-wl)/energySq
00660 - bha3*(wuSq-wlSq)/(2.0*energySq*energy)
00661 + bha4*(wuSq*wu-wlSq*wl)/(3.0*energySq*energySq);
00662 H1 += std::log(wu/wl) - bha1*(wu-wl)/energy
00663 + bha2*(wuSq-wlSq)/(2.0*energySq)
00664 - bha3*(wuSq*wu-wlSq*wl)/(3.0*energySq*energy)
00665 + bha4*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energySq);
00666 H2 += wu - wl - bha1*(wuSq-wlSq)/(2.0*energy)
00667 + bha2*(wuSq*wu-wlSq*wl)/(3.0*energySq)
00668 - bha3*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energy)
00669 + bha4*(wuSq*wuSq*wu-wlSq*wlSq*wl)/(5.0*energySq*energySq);
00670 wu = wl;
00671 }
00672 wl = cutoffEne;
00673
00674 if (wl > wu-(1e-5*eV))
00675 {
00676 (*result)[0] = constant*H0;
00677 (*result)[1] = constant*H1;
00678 (*result)[2] = constant*H2;
00679 (*result)[3] = constant*S0;
00680 (*result)[4] = constant*S1;
00681 (*result)[5] = constant*S2;
00682 return result;
00683 }
00684
00685 G4double wlSq = wl*wl;
00686 G4double wuSq = wu*wu;
00687
00688 S0 += (1.0/wl) - (1.0/wu) - bha1*std::log(wu/wl)/energy
00689 + bha2*(wu-wl)/energySq
00690 - bha3*(wuSq-wlSq)/(2.0*energySq*energy)
00691 + bha4*(wuSq*wu-wlSq*wl)/(3.0*energySq*energySq);
00692
00693 S1 += std::log(wu/wl) - bha1*(wu-wl)/energy
00694 + bha2*(wuSq-wlSq)/(2.0*energySq)
00695 - bha3*(wuSq*wu-wlSq*wl)/(3.0*energySq*energy)
00696 + bha4*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energySq);
00697
00698 S2 += wu - wl - bha1*(wuSq-wlSq)/(2.0*energy)
00699 + bha2*(wuSq*wu-wlSq*wl)/(3.0*energySq)
00700 - bha3*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energy)
00701 + bha4*(wuSq*wuSq*wu-wlSq*wlSq*wl)/(5.0*energySq*energySq);
00702
00703 (*result)[0] = constant*H0;
00704 (*result)[1] = constant*H1;
00705 (*result)[2] = constant*H2;
00706 (*result)[3] = constant*S0;
00707 (*result)[4] = constant*S1;
00708 (*result)[5] = constant*S2;
00709
00710 return result;
00711 }