60 #include "G4PhysicalConstants.hh"
61 #include "G4SystemOfUnits.hh"
62 #include "Randomize.hh"
63 #include "G4ParticleChangeForMSC.hh"
64 #include "G4PhysicsTableHelper.hh"
65 #include "G4ElementVector.hh"
66 #include "G4ProductionCutsTable.hh"
67 #include "G4LossTableManager.hh"
81 singleScatteringMode(false)
91 wokvi =
new G4WentzelOKandVIxSection();
114 const G4DataVector& cuts)
137 const G4ParticleDefinition* p,
139 G4double Z, G4double,
140 G4double cutEnergy, G4double)
142 G4double cross = 0.0;
145 if(!CurrentCouple()) {
146 G4Exception(
"QweakSimWentzelVIModel::ComputeCrossSectionPerAtom",
"em0011",
147 FatalException,
" G4MaterialCutsCouple is not defined");
153 G4double cut = cutEnergy;
178 const G4Track& track,
179 G4double& currentMinimalStep)
181 G4double tlimit = currentMinimalStep;
182 const G4DynamicParticle* dp = track.GetDynamicParticle();
183 G4StepPoint* sp = track.GetStep()->GetPreStepPoint();
184 G4StepStatus stepStatus = sp->GetStepStatus();
190 if(strcmp(track.GetParticleDefinition()->GetParticleName().data() ,
"e-") == 0)
191 if(strcmp(track.GetMaterial()->GetName(),
"PBA") == 0){
192 if(track.GetPolarization().getR() >= 0.1)
debugPrint=
true;
193 if(sqrt(pow(track.GetPolarization().getX(),2)+pow(track.GetPolarization().getY(),2))>0.01){
196 eEnergy=track.GetTotalEnergy();
222 return ConvertTrueToGeom(tlimit, currentMinimalStep);
226 G4double presafety = sp->GetSafety();
230 return ConvertTrueToGeom(tlimit, currentMinimalStep);
235 if(stepStatus != fGeomBoundary && presafety <
tlimitminfix) {
236 presafety = ComputeSafety(sp->GetPosition(), tlimit);
239 return ConvertTrueToGeom(tlimit, currentMinimalStep);
257 rlimit = std::min(rlimit, facsafety*presafety);
261 G4double rcut =
currentCouple->GetProductionCuts()->GetProductionCut(1);
265 if(rcut > rlimit) { rlimit = std::min(rlimit, rcut*sqrt(rlimit/rcut)); }
267 if(rlimit < tlimit) { tlimit = rlimit; }
275 if (steppingAlgorithm == fUseDistanceToBoundary
276 && stepStatus == fGeomBoundary) {
278 G4double geomlimit = ComputeGeomLimit(track, presafety, currentRange);
279 tlimit = std::min(tlimit, geomlimit/facgeom);
288 return ConvertTrueToGeom(tlimit, currentMinimalStep);
345 static const G4double singleScatLimit = 1.0e-7;
393 }
else if(
xtsec > 0.0) {
424 fDisplacement.set(0.0,0.0,0.0);
430 {
return fDisplacement; }
432 G4double invlambda = 0.0;
448 G4double z0 = x0*invlambda;
454 static const G4double zzmin = 0.05;
460 if(z0 > zzmin) { zzz = G4Exp(-1.0/z0); }
465 if(0.0 <
xtsec) { x1 = -G4Log(G4UniformRand())/
xtsec; }
469 {
return fDisplacement; }
471 const G4ElementVector* theElementVector =
476 G4double sint, cost, phi;
477 G4ThreeVector temp(0.0,0.0,1.0);
482 G4ThreeVector dir(0.0,0.0,1.0);
514 fDisplacement += step*mscfac*dir;
521 G4double qsec = G4UniformRand()*
xtsec;
522 for (; i<nelm; ++i) {
if(
xsecn[i] >= qsec) {
break; } }
525 wokvi->SetupTarget(G4lrint((*theElementVector)[i]->GetZ()), cut);
531 cost=cos(temp.getTheta());
532 sint = sqrt((1.0 - cost)*(1.0 + cost));
535 if(
debugPrint) G4cout<<
" ~~sc~~ "<<nMscSteps<<G4endl;
536 G4double _prob=G4UniformRand();
537 G4double _amplitude=1.0/
eEnergy * sint *
539 if(_amplitude > 1 ) _amplitude=1;
540 if( _prob < _amplitude * sin(phi-pi) )
543 if(phi<0) phi+=twopi;
544 else if(phi>twopi) phi=fmod(phi,twopi);
545 G4double vx1 = sint*cos(phi);
546 G4double vy1 = sint*sin(phi);
547 temp.set(vx1,vy1,cost);
557 x1 = -G4Log(G4UniformRand())/
xtsec;
567 z = -z0*G4Log(1.0 - (1.0 - zzz)*G4UniformRand());
570 if(cost > 1.0) { cost = 1.0; }
571 else if(cost < -1.0) { cost =-1.0; }
572 sint = sqrt((1.0 - cost)*(1.0 + cost));
573 phi = twopi*G4UniformRand();
576 if(
debugPrint) G4cout<<
" ~~msc~~ "<<nMscSteps<<G4endl;
577 G4double _prob=G4UniformRand();
578 G4double _amplitude=1.0/
eEnergy * sint*
580 if(_amplitude > 1 ) _amplitude=1;
581 if( _prob < _amplitude * sin(phi-pi) )
584 if(phi<0) phi+=twopi;
585 else if(phi>twopi) phi=fmod(phi,twopi);
588 G4double vx1 = sint*cos(phi);
589 G4double vy1 = sint*sin(phi);
594 G4double r = x0*mscfac;
595 G4double dx = r*(0.5*vx1 + rms*G4RandGauss::shoot(0.0,1.0));
596 G4double dy = r*(0.5*vy1 + rms*G4RandGauss::shoot(0.0,1.0));
598 G4double d = r*r - dx*dx - dy*dy;
605 fDisplacement += temp;
609 temp.set(vx1,vy1,cost);
613 }
while (0 < nMscSteps);
615 dir.rotateUz(oldDirection);
619 G4cout<<
" WentzelMS cth, th, phi old.angle(new)" << cost <<
" " << acos(cost) <<
" " << phi <<
" " <<oldDirection.angle(dir) << G4endl;
620 G4cout<<
" WentzelMS old dir: R th phi "<<oldDirection.getR()<<
" "<<oldDirection.getTheta()<<
" "<<oldDirection.getPhi()<<G4endl;
621 G4cout<<
" WentzelMS new dir: R th phi "<<dir.getR()<<
" "<<dir.getTheta()<<
" "<<dir.getPhi()<<G4endl;
631 fDisplacement.rotateUz(oldDirection);
645 return fDisplacement;
653 const G4ElementVector* theElementVector =
currentMaterial->GetElementVector();
654 const G4double* theAtomNumDensityVector =
672 for (G4int i=0; i<nelm; ++i) {
674 wokvi->SetupTarget(G4lrint((*theElementVector)[i]->GetZ()), cut);
675 G4double density = theAtomNumDensityVector[i];
688 if(nucsec > 0.0) { esec /= nucsec; }
689 xtsec += nucsec*density;
virtual G4ThreeVector & SampleScattering(const G4ThreeVector &, G4double safety)
virtual G4double ComputeTruePathLengthLimit(const G4Track &track, G4double ¤tMinimalStep)
G4double ComputeXSectionPerVolume()
std::vector< G4double > prob
void StartTracking(G4Track *)
G4int currentMaterialIndex
virtual G4double ComputeGeomPathLength(G4double truePathLength)
const G4DataVector * currentCuts
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double KineticEnergy, G4double AtomicNumber, G4double AtomicWeight=0., G4double cut=DBL_MAX, G4double emax=DBL_MAX)
G4LossTableManager * theManager
virtual G4double ComputeTrueStepLength(G4double geomStepLength)
const G4MaterialCutsCouple * currentCouple
std::vector< G4double > xsecn
G4bool singleScatteringMode
void SetupParticle(const G4ParticleDefinition *)
G4ThreeVector polarization
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
const G4Material * currentMaterial
void DefineMaterial(const G4MaterialCutsCouple *)
const G4ParticleDefinition * particle
virtual ~QweakSimWentzelVIModel()
G4ParticleChangeForMSC * fParticleChange
QweakSimWentzelVIModel(const G4String &nam="WentzelVIUni")
G4WentzelOKandVIxSection * wokvi