69 fGammaCutInKineticEnergy(nullptr),
71 fAngleDistrTable(nullptr),
72 fEnergyDistrTable(nullptr),
73 fPlatePhotoAbsCof(nullptr),
74 fGasPhotoAbsCof(nullptr),
75 fAngleForEnergyTable(nullptr)
115 G4cout<<
"### G4VXTRenergyLoss: the number of TR radiator plates = "
119 G4Exception(
"G4VXTRenergyLoss::G4VXTRenergyLoss()",
"VXTRELoss01",
220 gamma = 1.0 + kinEnergy/
mass;
226 if ( std::fabs( gamma -
fGamma ) < 0.05*gamma ) lambda =
fLambda;
232 TkinScaled = kinEnergy*massRatio;
234 for(iTkin = 0; iTkin <
fTotBin; iTkin++)
236 if( TkinScaled < fProtonEnergyVector->GetLowEdgeEnergy(iTkin))
break;
240 if(iTkin == 0) lambda =
DBL_MAX;
245 sigma = (*(*fEnergyDistrTable)(iPlace))(0)*chargeSq;
252 W1 = (E2 - TkinScaled)*W;
253 W2 = (TkinScaled - E1)*W;
254 sigma = ( (*(*fEnergyDistrTable)(iPlace ))(0)*W1 +
259 else lambda = 1./sigma;
281 "XTR initialisation for neutral particle ?!" );
289 G4cout<<
"Build angle for energy distribution according the current radiator"
303 G4int iTkin, iTR, iPlace;
329 G4cout<<
"Lorentz Factor"<<
"\t"<<
"XTR photon number"<<
G4endl;
332 for( iTkin = 0; iTkin <
fTotBin; iTkin++ )
352 for( iTR =
fBinTR - 2; iTR >= 0; iTR-- )
382 G4cout<<
"total time for build X-ray TR energy loss tables = "
427 for( iTkin = 0; iTkin <
fTotBin; iTkin++ )
442 for( iTR = 0; iTR <
fBinTR; iTR++ )
450 angleVector ->
PutValue(fBinTR - 1, angleSum);
452 for( i = fBinTR - 2; i >= 0; i-- )
461 angleVector ->
PutValue(i, angleSum);
472 G4cout<<
"total time for build X-ray TR angle for energy loss tables = "
505 G4cout<<
"Lorentz Factor"<<
"\t"<<
"XTR photon number"<<
G4endl;
508 for( iTkin = 0; iTkin <
fTotBin; iTkin++ )
526 for( iTR = 0; iTR <
fBinTR; iTR++ )
545 G4cout<<
"total time for build XTR angle for given energy tables = "
559 G4double theta=0., result,
tmp=0., cof1, cof2, cofMin, cofPHC, angleSum = 0.;
573 kMin =
G4int(cofMin);
574 if (cofMin > kMin) kMin++;
580 G4cout<<
"n-1 = "<<n-1<<
"; theta = "
583 <<
"; angleSum = "<<angleSum<<
G4endl;
587 for( iTheta = n - 1; iTheta >= 1; iTheta-- )
590 k = iTheta - 1 +
kMin;
594 result = (k - cof1)*(k - cof1)*(k + cof2)*(k + cof2);
596 tmp = std::sin(tmp)*std::sin(tmp)*
std::abs(k-cofMin)/result;
598 if( k == kMin && kMin ==
G4int(cofMin) )
602 else if(iTheta == n-1);
611 G4cout<<
"iTheta = "<<iTheta<<
"; k = "<<k<<
"; theta = "
612 <<std::sqrt(theta)*
fGamma<<
"; tmp = "
614 <<
"; angleSum = "<<angleSum<<
G4endl;
616 angleVector->
PutValue( iTheta, theta, angleSum );
625 G4cout<<
"iTheta = "<<iTheta<<
"; theta = "
626 <<std::sqrt(theta)*
fGamma<<
"; tmp = "
628 <<
"; angleSum = "<<angleSum<<
G4endl;
630 angleVector->
PutValue( iTheta, theta, angleSum );
641 G4int iTkin, iTR, iPlace;
661 G4cout<<
"Lorentz Factor"<<
"\t"<<
"XTR photon number"<<
G4endl;
664 for( iTkin = 0; iTkin <
fTotBin; iTkin++ )
690 for( iTR =
fBinTR - 2; iTR >= 0; iTR-- )
698 angleVector ->
PutValue(iTR,angleSum);
716 G4cout<<
"total time for build X-ray TR angle tables = "
741 G4cout<<
"Start of G4VXTRenergyLoss::PostStepDoIt "<<
G4endl;
742 G4cout<<
"name of current material = "
749 G4cout<<
"Go out from G4VXTRenergyLoss::PostStepDoIt: wrong volume "<<
G4endl;
769 G4double TkinScaled = kinEnergy*massRatio;
774 for( iTkin = 0; iTkin <
fTotBin; iTkin++ )
776 if(TkinScaled < fProtonEnergyVector->GetLowEdgeEnergy(iTkin))
break;
784 G4cout<<
"Go out from G4VXTRenergyLoss::PostStepDoIt:iTkin = "<<iTkin<<
G4endl;
804 if( theta2 > 0.) theta = std::sqrt(theta2);
811 if( theta >= 0.1 ) theta = 0.1;
817 dirX = std::sin(theta)*std::cos(phi);
818 dirY = std::sin(theta)*std::sin(phi);
819 dirZ = std::cos(theta);
826 directionTR, energyTR);
846 position += distance*directionTR;
850 startTime, position );
894 if(result < 0.0) result = 0.0;
907 G4double lim[8] = { 0.0, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0 };
933 for( i = 0; i < iMax-1; i++ )
952 if(result < 0) result = 0.0;
975 cofMin = std::sqrt(cof1*cof2);
978 kMin =
G4int(cofMin);
979 if (cofMin > kMin) kMin++;
985 for( k = kMin; k <=
kMax; k++ )
988 tmp2 = std::sqrt(
tmp1*
tmp1-cof1*cof2);
992 for(i = 0; i < 2; i++)
1000 tmp2 = std::sin(
tmp1);
1001 tmp = energy1*tmp2*
tmp2;
1003 tmp1 = hbarc*energy1/( energy1*energy1*(1./
fGamma/
fGamma + varAngle) + fSigma2 );
1005 tmp1 = cof1/(4.*
hbarc) - cof2/(4.*hbarc*energy1*energy1);
1008 if(tmp2 > 0.) tmp /=
tmp2;
1017 tmp2 = std::sin(
tmp1);
1018 tmp = energy2*tmp2*
tmp2;
1020 tmp1 = hbarc*energy2/( energy2*energy2*(1./
fGamma/
fGamma + varAngle) + fSigma2 );
1022 tmp1 = cof1/(4.*
hbarc) - cof2/(4.*hbarc*energy2*energy2);
1025 if(tmp2 > 0.) tmp /=
tmp2;
1034 result /= hbarc*
hbarc;
1056 lambda = 1.0/gamma/gamma + varAngle +
fSigma1/omega/omega;
1073 cof = 1.0/(1.0 + delta*
delta);
1075 real_v = length*cof;
1076 image_v = real_v*
delta;
1108 omega2 = omega*omega;
1109 omega3 = omega2*omega;
1110 omega4 = omega2*omega2;
1114 SandiaCof[2]/omega3 + SandiaCof[3]/omega4;
1128 lambda = 1.0/gamma/gamma + varAngle +
fSigma2/omega/omega;
1146 cof = 1.0/(1.0 + delta*
delta);
1148 real_v = length*cof;
1149 image_v = real_v*
delta;
1179 omega2 = omega*omega;
1180 omega3 = omega2*omega;
1181 omega4 = omega2*omega2;
1185 SandiaCof[2]/omega3 + SandiaCof[3]/omega4;
1209 std::ofstream outPlate(
"plateZmu.dat", std::ios::out );
1210 outPlate.setf( std::ios::scientific, std::ios::floatfield );
1215 varAngle = 1/gamma/gamma;
1220 omega = (1.0 + i)*
keV;
1247 std::ofstream outGas(
"gasZmu.dat", std::ios::out );
1248 outGas.setf( std::ios::scientific, std::ios::floatfield );
1252 varAngle = 1/gamma/gamma;
1257 omega = (1.0 + i)*
keV;
1272 G4int i, numberOfElements;
1273 G4double xSection = 0., nowZ, sumZ = 0.;
1276 numberOfElements = (*theMaterialTable)[
fMatIndex1]->GetNumberOfElements();
1278 for( i = 0; i < numberOfElements; i++ )
1280 nowZ = (*theMaterialTable)[
fMatIndex1]->GetElement(i)->GetZ();
1285 xSection *= (*theMaterialTable)[
fMatIndex1]->GetElectronDensity();
1296 G4int i, numberOfElements;
1297 G4double xSection = 0., nowZ, sumZ = 0.;
1300 numberOfElements = (*theMaterialTable)[
fMatIndex2]->GetNumberOfElements();
1302 for( i = 0; i < numberOfElements; i++ )
1304 nowZ = (*theMaterialTable)[
fMatIndex2]->GetElement(i)->GetZ();
1309 xSection *= (*theMaterialTable)[
fMatIndex2]->GetElectronDensity();
1321 if ( Z < 0.9999 )
return CrossSection;
1322 if ( GammaEnergy < 0.1*
keV )
return CrossSection;
1323 if ( GammaEnergy > (100.*
GeV/Z) )
return CrossSection;
1325 static const G4double a = 20.0 ,
b = 230.0 ,
c = 440.0;
1332 G4double p1Z = Z*(d1 + e1*Z + f1*Z*
Z), p2Z = Z*(d2 + e2*Z + f2*Z*Z),
1333 p3Z = Z*(d3 + e3*Z + f3*Z*
Z), p4Z = Z*(d4 + e4*Z + f4*Z*Z);
1336 if (Z < 1.5) T0 = 40.0*
keV;
1339 CrossSection = p1Z*std::log(1.+2.*X)/X
1340 + (p2Z + p3Z*X + p4Z*X*
X)/(1. + a*X +
b*X*X +
c*X*X*X);
1344 if (GammaEnergy < T0)
1348 G4double sigma = p1Z*std::log(1.+2.*X)/X
1349 + (p2Z + p3Z*X + p4Z*X*
X)/(1. + a*X +
b*X*X +
c*X*X*X);
1350 G4double c1 = -T0*(sigma-CrossSection)/(CrossSection*dT0);
1352 if (Z > 1.5) c2 = 0.375-0.0556*std::log(Z);
1354 CrossSection *= std::exp(-y*(c1+c2*y));
1357 return CrossSection;
1375 G4double formationLength1, formationLength2;
1376 formationLength1 = 1.0/
1380 formationLength2 = 1.0/
1384 return (varAngle/energy)*(formationLength1 - formationLength2)
1385 *(formationLength1 - formationLength2);
1455 std::ofstream outEn(
"numberE.dat", std::ios::out );
1456 outEn.setf( std::ios::scientific, std::ios::floatfield );
1458 std::ofstream outAng(
"numberAng.dat", std::ios::out );
1459 outAng.setf( std::ios::scientific, std::ios::floatfield );
1461 for(iTkin=0;iTkin<
fTotBin;iTkin++)
1465 numberE = (*(*fEnergyDistrTable)(iTkin))(0);
1468 G4cout<<gamma<<
"\t\t"<<numberE<<
"\t"
1471 outEn<<gamma<<
"\t\t"<<numberE<<
G4endl;
1483 G4int iTransfer, iPlace;
1494 for(iTransfer=0;;iTransfer++)
1505 W1 = (E2 - scaledTkin)*W;
1506 W2 = (scaledTkin - E1)*W;
1508 position =( (*(*fEnergyDistrTable)(iPlace))(0)*W1 +
1513 for(iTransfer=0;;iTransfer++)
1523 if(transfer < 0.0 ) transfer = 0.0;
1540 result = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer);
1544 y1 = (*(*fEnergyDistrTable)(iPlace))(iTransfer-1);
1545 y2 = (*(*fEnergyDistrTable)(iPlace))(iTransfer);
1547 x1 = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer-1);
1548 x2 = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer);
1550 if ( x1 == x2 ) result =
x2;
1573 if (iTkin ==
fTotBin) iTkin--;
1577 for( iTR = 0; iTR <
fBinTR; iTR++ )
1579 if( energyXTR < fXTREnergyVector->GetLowEdgeEnergy(iTR) )
break;
1581 if (iTR == fBinTR) iTR--;
1583 position = (*(*fAngleForEnergyTable)(iTR))(0)*
G4UniformRand();
1585 for( iAngle = 0;; iAngle++)
1604 if( iTransfer == 0 )
1606 result = (*fAngleForEnergyTable)(iPlace)->GetLowEdgeEnergy(iTransfer);
1610 y1 = (*(*fAngleForEnergyTable)(iPlace))(iTransfer-1);
1611 y2 = (*(*fAngleForEnergyTable)(iPlace))(iTransfer);
1613 x1 = (*fAngleForEnergyTable)(iPlace)->GetLowEdgeEnergy(iTransfer-1);
1614 x2 = (*fAngleForEnergyTable)(iPlace)->GetLowEdgeEnergy(iTransfer);
1616 if ( x1 == x2 ) result =
x2;
1622 result = x1 + (position -
y1)*(x2 - x1)/(y2 -
y1);