69 fGammaCutInKineticEnergy(0),
75 fAngleForEnergyTable(0)
104 fPlasmaCof = 4.0*pi*fine_structure_const*hbarc*hbarc*hbarc/electron_mass_c2;
106 fCofTR = fine_structure_const/pi;
112 G4cout<<
"### G4VXTRenergyLoss: the number of TR radiator plates = "
116 G4Exception(
"G4VXTRenergyLoss::G4VXTRenergyLoss()",
"VXTRELoss01",
196 G4double lambda, sigma, kinEnergy, mass, gamma;
197 G4double charge, chargeSq, massRatio, TkinScaled;
208 gamma = 1.0 + kinEnergy/mass;
214 if ( std::fabs( gamma -
fGamma ) < 0.05*gamma ) lambda =
fLambda;
218 chargeSq = charge*charge;
219 massRatio = proton_mass_c2/mass;
220 TkinScaled = kinEnergy*massRatio;
222 for(iTkin = 0; iTkin <
fTotBin; iTkin++)
224 if( TkinScaled < fProtonEnergyVector->GetLowEdgeEnergy(iTkin))
break;
228 if(iTkin == 0) lambda =
DBL_MAX;
233 sigma = (*(*fEnergyDistrTable)(iPlace))(0)*chargeSq;
240 W1 = (E2 - TkinScaled)*W;
241 W2 = (TkinScaled - E1)*W;
242 sigma = ( (*(*fEnergyDistrTable)(iPlace ))(0)*W1 +
247 else lambda = 1./sigma;
269 "XTR initialisation for neutral particle ?!" );
277 G4cout<<
"Build angle for energy distribution according the current radiator"
291 G4int iTkin, iTR, iPlace;
317 G4cout<<
"Lorentz Factor"<<
"\t"<<
"XTR photon number"<<
G4endl;
320 for( iTkin = 0; iTkin <
fTotBin; iTkin++ )
327 GetLowEdgeEnergy(iTkin)/proton_mass_c2);
340 for( iTR =
fBinTR - 2; iTR >= 0; iTR-- )
344 energySum += radiatorCof*
fCofTR*integral.Legendre10(
370 G4cout<<
"total time for build X-ray TR energy loss tables = "
415 for( iTkin = 0; iTkin <
fTotBin; iTkin++ )
419 GetLowEdgeEnergy(iTkin)/proton_mass_c2);
430 for( iTR = 0; iTR <
fBinTR; iTR++ )
440 for( i =
fBinTR - 2; i >= 0; i-- )
444 angleSum += integral.Legendre10(
449 angleVector ->
PutValue(i, angleSum);
460 G4cout<<
"total time for build X-ray TR angle for energy loss tables = "
493 G4cout<<
"Lorentz Factor"<<
"\t"<<
"XTR photon number"<<
G4endl;
496 for( iTkin = 0; iTkin <
fTotBin; iTkin++ )
500 GetLowEdgeEnergy(iTkin)/proton_mass_c2);
514 for( iTR = 0; iTR <
fBinTR; iTR++ )
533 G4cout<<
"total time for build XTR angle for given energy tables = "
547 G4double theta=0., result, tmp=0., cof1, cof2, cofMin, cofPHC, angleSum = 0.;
548 G4int iTheta, k, kMin;
561 kMin =
G4int(cofMin);
562 if (cofMin > kMin) kMin++;
568 G4cout<<
"n-1 = "<<n-1<<
"; theta = "
571 <<
"; angleSum = "<<angleSum<<
G4endl;
575 for( iTheta = n - 1; iTheta >= 1; iTheta-- )
578 k = iTheta- 1 + kMin;
582 result = (k - cof1)*(k - cof1)*(k + cof2)*(k + cof2);
584 tmp = std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
586 if( k == kMin && kMin ==
G4int(cofMin) )
590 else if(iTheta == n-1);
599 G4cout<<
"iTheta = "<<iTheta<<
"; k = "<<k<<
"; theta = "
600 <<std::sqrt(theta)*
fGamma<<
"; tmp = "
602 <<
"; angleSum = "<<angleSum<<
G4endl;
604 angleVector->
PutValue( iTheta, theta, angleSum );
613 G4cout<<
"iTheta = "<<iTheta<<
"; theta = "
614 <<std::sqrt(theta)*
fGamma<<
"; tmp = "
616 <<
"; angleSum = "<<angleSum<<
G4endl;
618 angleVector->
PutValue( iTheta, theta, angleSum );
629 G4int iTkin, iTR, iPlace;
649 G4cout<<
"Lorentz Factor"<<
"\t"<<
"XTR photon number"<<
G4endl;
652 for( iTkin = 0; iTkin <
fTotBin; iTkin++ )
656 GetLowEdgeEnergy(iTkin)/proton_mass_c2);
678 for( iTR =
fBinTR - 2; iTR >= 0; iTR-- )
681 angleSum += radiatorCof*
fCofTR*integral.Legendre96(
686 angleVector ->
PutValue(iTR,angleSum);
704 G4cout<<
"total time for build X-ray TR angle tables = "
722 G4double energyTR, theta,theta2, phi, dirX, dirY, dirZ;
729 G4cout<<
"Start of G4VXTRenergyLoss::PostStepDoIt "<<
G4endl;
730 G4cout<<
"name of current material = "
737 G4cout<<
"Go out from G4VXTRenergyLoss::PostStepDoIt: wrong volume "<<
G4endl;
750 G4double gamma = 1.0 + kinEnergy/mass;
756 G4double massRatio = proton_mass_c2/mass;
757 G4double TkinScaled = kinEnergy*massRatio;
762 for( iTkin = 0; iTkin <
fTotBin; iTkin++ )
764 if(TkinScaled < fProtonEnergyVector->GetLowEdgeEnergy(iTkin))
break;
772 G4cout<<
"Go out from G4VXTRenergyLoss::PostStepDoIt:iTkin = "<<iTkin<<
G4endl;
790 if(theta2 > 0.) theta = std::sqrt(theta2);
793 else theta = std::fabs(G4RandGauss::shoot(0.0,pi/gamma));
797 if( theta >= 0.1 ) theta = 0.1;
803 dirX = std::sin(theta)*std::cos(phi);
804 dirY = std::sin(theta)*std::sin(phi);
805 dirZ = std::cos(theta);
812 directionTR, energyTR);
830 G4cout<<
"distance to exit = "<<distance/mm<<
" mm"<<
G4endl;
833 startTime += distance/c_light;
866 * (varAngle*energy/hbarc/hbarc);
880 if(result < 0.0) result = 0.0;
893 G4double lim[8] = { 0.0, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0 };
919 for( i = 0; i < iMax-1; i++ )
938 if(result < 0) result = 0.0;
951 G4double sum = 0., tmp1, tmp2, tmp=0., cof1, cof2, cofMin, cofPHC, energy1, energy2;
952 G4int k, kMax, kMin, i;
954 cofPHC = twopi*hbarc;
961 cofMin = std::sqrt(cof1*cof2);
964 kMin =
G4int(cofMin);
965 if (cofMin > kMin) kMin++;
971 for( k = kMin; k <= kMax; k++ )
974 tmp2 = std::sqrt(tmp1*tmp1-cof1*cof2);
975 energy1 = (tmp1+tmp2)/cof1;
976 energy2 = (tmp1-tmp2)/cof1;
978 for(i = 0; i < 2; i++)
985 tmp2 = std::sin(tmp1);
986 tmp = energy1*tmp2*tmp2;
989 tmp *= (tmp1-tmp2)*(tmp1-tmp2);
990 tmp1 = cof1/(4*hbarc) - cof2/(4*hbarc*energy1*energy1);
991 tmp2 = std::abs(tmp1);
992 if(tmp2 > 0.) tmp /= tmp2;
1000 tmp2 = std::sin(tmp1);
1001 tmp = energy2*tmp2*tmp2;
1004 tmp *= (tmp1-tmp2)*(tmp1-tmp2);
1005 tmp1 = cof1/(4*hbarc) - cof2/(4*hbarc*energy2*energy2);
1006 tmp2 = std::abs(tmp1);
1007 if(tmp2 > 0.) tmp /= tmp2;
1016 result /= hbarc*hbarc;
1038 lambda = 1.0/gamma/gamma + varAngle +
fSigma1/omega/omega;
1039 cof = 2.0*hbarc/omega/lambda;
1051 G4double cof, length,delta, real_v, image_v;
1055 cof = 1.0/(1.0 + delta*delta);
1057 real_v = length*cof;
1058 image_v = real_v*delta;
1090 omega2 = omega*omega;
1091 omega3 = omega2*omega;
1092 omega4 = omega2*omega2;
1095 G4double cross = SandiaCof[0]/omega + SandiaCof[1]/omega2 +
1096 SandiaCof[2]/omega3 + SandiaCof[3]/omega4;
1110 lambda = 1.0/gamma/gamma + varAngle +
fSigma2/omega/omega;
1111 cof = 2.0*hbarc/omega/lambda;
1124 G4double cof, length,delta, real_v, image_v;
1128 cof = 1.0/(1.0 + delta*delta);
1130 real_v = length*cof;
1131 image_v = real_v*delta;
1161 omega2 = omega*omega;
1162 omega3 = omega2*omega;
1163 omega4 = omega2*omega2;
1166 G4double cross = SandiaCof[0]/omega + SandiaCof[1]/omega2 +
1167 SandiaCof[2]/omega3 + SandiaCof[3]/omega4;
1191 std::ofstream outPlate(
"plateZmu.dat", std::ios::out );
1192 outPlate.setf( std::ios::scientific, std::ios::floatfield );
1197 varAngle = 1/gamma/gamma;
1202 omega = (1.0 + i)*keV;
1229 std::ofstream outGas(
"gasZmu.dat", std::ios::out );
1230 outGas.setf( std::ios::scientific, std::ios::floatfield );
1234 varAngle = 1/gamma/gamma;
1239 omega = (1.0 + i)*keV;
1254 G4int i, numberOfElements;
1255 G4double xSection = 0., nowZ, sumZ = 0.;
1258 numberOfElements = (*theMaterialTable)[
fMatIndex1]->GetNumberOfElements();
1260 for( i = 0; i < numberOfElements; i++ )
1262 nowZ = (*theMaterialTable)[
fMatIndex1]->GetElement(i)->GetZ();
1267 xSection *= (*theMaterialTable)[
fMatIndex1]->GetElectronDensity();
1278 G4int i, numberOfElements;
1279 G4double xSection = 0., nowZ, sumZ = 0.;
1282 numberOfElements = (*theMaterialTable)[
fMatIndex2]->GetNumberOfElements();
1284 for( i = 0; i < numberOfElements; i++ )
1286 nowZ = (*theMaterialTable)[
fMatIndex2]->GetElement(i)->GetZ();
1291 xSection *= (*theMaterialTable)[
fMatIndex2]->GetElectronDensity();
1303 if ( Z < 0.9999 )
return CrossSection;
1304 if ( GammaEnergy < 0.1*keV )
return CrossSection;
1305 if ( GammaEnergy > (100.*GeV/Z) )
return CrossSection;
1307 static const G4double a = 20.0 , b = 230.0 , c = 440.0;
1310 d1= 2.7965e-1*barn, d2=-1.8300e-1*barn, d3= 6.7527 *barn, d4=-1.9798e+1*barn,
1311 e1= 1.9756e-5*barn, e2=-1.0205e-2*barn, e3=-7.3913e-2*barn, e4= 2.7079e-2*barn,
1312 f1=-3.9178e-7*barn, f2= 6.8241e-5*barn, f3= 6.0480e-5*barn, f4= 3.0274e-4*barn;
1314 G4double p1Z = Z*(d1 + e1*Z + f1*Z*Z), p2Z = Z*(d2 + e2*Z + f2*Z*Z),
1315 p3Z = Z*(d3 + e3*Z + f3*Z*Z), p4Z = Z*(d4 + e4*Z + f4*Z*Z);
1318 if (Z < 1.5) T0 = 40.0*keV;
1320 G4double X = std::max(GammaEnergy, T0) / electron_mass_c2;
1321 CrossSection = p1Z*std::log(1.+2.*X)/X
1322 + (p2Z + p3Z*X + p4Z*X*X)/(1. + a*X + b*X*X + c*X*X*X);
1326 if (GammaEnergy < T0)
1329 X = (T0+dT0) / electron_mass_c2;
1330 G4double sigma = p1Z*std::log(1.+2*X)/X
1331 + (p2Z + p3Z*X + p4Z*X*X)/(1. + a*X + b*X*X + c*X*X*X);
1332 G4double c1 = -T0*(sigma-CrossSection)/(CrossSection*dT0);
1334 if (Z > 1.5) c2 = 0.375-0.0556*std::log(Z);
1335 G4double y = std::log(GammaEnergy/T0);
1336 CrossSection *= std::exp(-y*(c1+c2*y));
1339 return CrossSection;
1357 G4double formationLength1, formationLength2;
1358 formationLength1 = 1.0/
1362 formationLength2 = 1.0/
1366 return (varAngle/energy)*(formationLength1 - formationLength2)
1367 *(formationLength1 - formationLength2);
1437 std::ofstream outEn(
"numberE.dat", std::ios::out );
1438 outEn.setf( std::ios::scientific, std::ios::floatfield );
1440 std::ofstream outAng(
"numberAng.dat", std::ios::out );
1441 outAng.setf( std::ios::scientific, std::ios::floatfield );
1443 for(iTkin=0;iTkin<
fTotBin;iTkin++)
1446 GetLowEdgeEnergy(iTkin)/proton_mass_c2);
1447 numberE = (*(*fEnergyDistrTable)(iTkin))(0);
1450 G4cout<<gamma<<
"\t\t"<<numberE<<
"\t"
1453 outEn<<gamma<<
"\t\t"<<numberE<<
G4endl;
1465 G4int iTransfer, iPlace;
1476 for(iTransfer=0;;iTransfer++)
1487 W1 = (E2 - scaledTkin)*W;
1488 W2 = (scaledTkin - E1)*W;
1490 position =( (*(*fEnergyDistrTable)(iPlace))(0)*W1 +
1495 for(iTransfer=0;;iTransfer++)
1505 if(transfer < 0.0 ) transfer = 0.0;
1522 result = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer);
1526 y1 = (*(*fEnergyDistrTable)(iPlace))(iTransfer-1);
1527 y2 = (*(*fEnergyDistrTable)(iPlace))(iTransfer);
1529 x1 = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer-1);
1530 x2 = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer);
1532 if ( x1 == x2 ) result = x2;
1555 if (iTkin ==
fTotBin) iTkin--;
1559 for( iTR = 0; iTR <
fBinTR; iTR++ )
1561 if( energyXTR < fXTREnergyVector->GetLowEdgeEnergy(iTR) )
break;
1563 if (iTR ==
fBinTR) iTR--;
1567 for(iAngle = 0;;iAngle++)
1588 result = (*fAngleForEnergyTable)(iPlace)->GetLowEdgeEnergy(iTransfer);
1592 y1 = (*(*fAngleForEnergyTable)(iPlace))(iTransfer-1);
1593 y2 = (*(*fAngleForEnergyTable)(iPlace))(iTransfer);
1595 x1 = (*fAngleForEnergyTable)(iPlace)->GetLowEdgeEnergy(iTransfer-1);
1596 x2 = (*fAngleForEnergyTable)(iPlace)->GetLowEdgeEnergy(iTransfer);
1598 if ( x1 == x2 ) result = x2;
1604 result = x1 + (
position - y1)*(x2 - x1)/(y2 - y1);
G4double condition(const G4ErrorSymMatrix &m)
std::vector< G4Material * > G4MaterialTable
std::complex< G4double > G4complex
G4DLLIMPORT std::ostream G4cout
Hep3Vector & rotateUz(const Hep3Vector &)
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
G4VSolid * GetSolid() const
G4Material * GetMaterial() const
static const G4MaterialTable * GetMaterialTable()
G4SandiaTable * GetSandiaTable() const
G4double GetElectronDensity() const
const G4String & GetName() const
void AddSecondary(G4Track *aSecondary)
void ProposeEnergy(G4double finalEnergy)
virtual void Initialize(const G4Track &)
G4double GetPDGMass() const
G4double GetPDGCharge() const
void PutValue(size_t binNumber, G4double binValue, G4double dataValue)
void insertAt(size_t, G4PhysicsVector *)
virtual G4double GetLowEdgeEnergy(size_t binNumber) const
void PutValue(size_t index, G4double theValue)
G4double GetSandiaCofForMaterial(G4int, G4int)
const G4VTouchable * GetTouchable() const
G4double GetGlobalTime() const
const G4ThreeVector & GetPosition() const
const G4TouchableHandle & GetTouchableHandle() const
G4StepPoint * GetPostStepPoint() const
G4double GetUserElapsed() const
G4VPhysicalVolume * GetVolume() const
void SetTouchableHandle(const G4TouchableHandle &apValue)
const G4DynamicParticle * GetDynamicParticle() const
void SetParentID(const G4int aValue)
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
void SetNumberOfSecondaries(G4int totSecondaries)
G4LogicalVolume * GetLogicalVolume() const
G4VParticleChange * pParticleChange
const G4String & GetProcessName() const
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const =0
virtual const G4ThreeVector & GetTranslation(G4int depth=0) const =0
virtual const G4RotationMatrix * GetRotation(G4int depth=0) const =0
G4double GetPlateLinearPhotoAbs(G4double)
G4double AngleSpectralXTRdEdx(G4double energy)
G4double XTRNAngleDensity(G4double varAngle)
G4PhysicsTable * fEnergyDistrTable
void ComputeGasPhotoAbsCof()
G4double GetAngleXTR(G4int iTR, G4double position, G4int iAngle)
G4PhysicsTable * fAngleForEnergyTable
G4PhysicsLogVector * fProtonEnergyVector
G4PhysicsLogVector * fXTREnergyVector
G4double GetGasFormationZone(G4double, G4double, G4double)
G4SandiaTable * fPlatePhotoAbsCof
G4double OneBoundaryXTRNdensity(G4double energy, G4double gamma, G4double varAngle) const
G4PhysicsFreeVector * GetAngleVector(G4double energy, G4int n)
G4double GetMeanFreePath(const G4Track &aTrack, G4double previousStepSize, G4ForceCondition *condition)
G4PhysicsTable * fAngleDistrTable
G4double GetRandomAngle(G4double energyXTR, G4int iTkin)
G4complex GetPlateComplexFZ(G4double, G4double, G4double)
G4complex OneInterfaceXTRdEdx(G4double energy, G4double gamma, G4double varAngle)
G4double GetXTRenergy(G4int iPlace, G4double position, G4int iTransfer)
G4VXTRenergyLoss(G4LogicalVolume *anEnvelope, G4Material *, G4Material *, G4double, G4double, G4int, const G4String &processName="XTRenergyLoss", G4ProcessType type=fElectromagnetic)
void BuildGlobalAngleTable()
G4double XTRNAngleSpectralDensity(G4double energy)
G4double SpectralAngleXTRdEdx(G4double varAngle)
G4double GetXTRrandomEnergy(G4double scaledTkin, G4int iTkin)
G4SandiaTable * fGasPhotoAbsCof
void BuildPhysicsTable(const G4ParticleDefinition &)
void GetPlateZmuProduct()
void BuildAngleForEnergyBank()
G4LogicalVolume * fEnvelope
std::vector< G4PhysicsTable * > fAngleBank
virtual ~G4VXTRenergyLoss()
virtual G4double SpectralXTRdEdx(G4double energy)
G4double GetComptonPerAtom(G4double, G4double)
void GetNumberOfPhotons()
G4double GetGasCompton(G4double)
G4double XTRNSpectralAngleDensity(G4double varAngle)
void ComputePlatePhotoAbsCof()
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
G4double GetPlateFormationZone(G4double, G4double, G4double)
G4double GetGasLinearPhotoAbs(G4double)
G4double XTRNSpectralDensity(G4double energy)
virtual G4double GetStackFactor(G4double energy, G4double gamma, G4double varAngle)
G4ParticleDefinition * fPtrGamma
G4ParticleChange fParticleChange
G4complex GetGasComplexFZ(G4double, G4double, G4double)
G4double GetPlateCompton(G4double)
G4bool IsApplicable(const G4ParticleDefinition &)
G4double AngleXTRdEdx(G4double varAngle)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)