63 SourcePosType =
"Point";
96 SourcePosType = PosType;
106 CentreCoords = coordsOfCentre;
113 if(verbosityLevel == 2)
117 GenerateRotationMatrices();
125 if(verbosityLevel == 2)
127 G4cout <<
"The vector in the x'-y' plane " << Roty <<
G4endl;
129 GenerateRotationMatrices();
188 void G4SPSPosDistribution::GenerateRotationMatrices()
196 Rotz = Rotx.
cross(Roty);
198 Roty = Rotz.
cross(Rotx);
200 if(verbosityLevel == 2)
202 G4cout <<
"The new axes, x', y', z' " << Rotx <<
" " << Roty <<
" " << Rotz <<
G4endl;
209 if(verbosityLevel == 2)
213 G4String theRequiredVolumeName = VolName;
217 if(verbosityLevel == 2)
219 while (!found && i<
G4int(PVStore->size())) {
220 tempPV = (*PVStore)[i];
221 found = tempPV->
GetName() == theRequiredVolumeName;
222 if(verbosityLevel == 2)
223 G4cout << i <<
" " <<
" " << tempPV->
GetName() <<
" " << theRequiredVolumeName <<
" " << found <<
G4endl;
230 if(verbosityLevel >= 1)
236 G4cout <<
" **** Error: Volume does not exist **** " <<
G4endl;
244 void G4SPSPosDistribution::GeneratePointSource()
247 if(SourcePosType ==
"Point")
248 particle_position = CentreCoords;
250 if(verbosityLevel >= 1)
251 G4cout <<
"Error SourcePosType is not set to Point" <<
G4endl;
254 void G4SPSPosDistribution::GeneratePointsInBeam()
263 if(Shape ==
"Circle")
267 while(std::sqrt((x*x) + (y*y)) > Radius)
272 x = (x*2.*Radius) - Radius;
273 y = (y*2.*Radius) - Radius;
283 x = (x*2.*halfx) - halfx;
284 y = (y*2.*halfy) - halfy;
290 if(verbosityLevel >= 2)
292 G4cout <<
"Raw position " << x <<
"," << y <<
"," << z <<
G4endl;
294 tempx = (x * Rotx.
x()) + (y * Roty.
x()) + (z * Rotz.
x());
295 tempy = (x * Rotx.
y()) + (y * Roty.
y()) + (z * Rotz.
y());
296 tempz = (x * Rotx.
z()) + (y * Roty.
z()) + (z * Rotz.
z());
303 particle_position = CentreCoords + RandPos;
304 if(verbosityLevel >= 1)
306 if(verbosityLevel >= 2)
310 G4cout <<
"Rotated and Translated position " << particle_position <<
G4endl;
314 void G4SPSPosDistribution::GeneratePointsInPlane()
322 if(SourcePosType !=
"Plane" && verbosityLevel >= 1)
323 G4cout <<
"Error: SourcePosType is not Plane" <<
G4endl;
326 if(Shape ==
"Circle")
330 while(std::sqrt((x*x) + (y*y)) > Radius)
335 x = (x*2.*Radius) - Radius;
336 y = (y*2.*Radius) - Radius;
339 else if(Shape ==
"Annulus")
343 while(std::sqrt((x*x) + (y*
y)) > Radius || std::sqrt((x*x) + (y*y)) < Radius0 )
348 x = (x*2.*Radius) - Radius;
349 y = (y*2.*Radius) - Radius;
352 else if(Shape ==
"Ellipse")
355 while(expression > 1.)
360 x = (x*2.*halfx) - halfx;
361 y = (y*2.*halfy) - halfy;
363 expression = ((x*
x)/(halfx*halfx)) + ((y*y)/(halfy*halfy));
366 else if(Shape ==
"Square")
370 x = (x*2.*halfx) - halfx;
371 y = (y*2.*halfy) - halfy;
373 else if(Shape ==
"Rectangle")
377 x = (x*2.*halfx) - halfx;
378 y = (y*2.*halfy) - halfy;
385 if(verbosityLevel == 2)
387 G4cout <<
"Raw position " << x <<
"," << y <<
"," << z <<
G4endl;
389 tempx = (x * Rotx.
x()) + (y * Roty.
x()) + (z * Rotz.
x());
390 tempy = (x * Rotx.
y()) + (y * Roty.
y()) + (z * Rotz.
y());
391 tempz = (x * Rotx.
z()) + (y * Roty.
z()) + (z * Rotz.
z());
398 particle_position = CentreCoords + RandPos;
399 if(verbosityLevel >= 1)
401 if(verbosityLevel == 2)
405 G4cout <<
"Rotated and Translated position " << particle_position <<
G4endl;
414 if((CentreCoords.
x() > 0. && Rotz.
x() < 0.)
415 || (CentreCoords.
x() < 0. && Rotz.
x() > 0.)
416 || (CentreCoords.
y() > 0. && Rotz.
y() < 0.)
417 || (CentreCoords.
y() < 0. && Rotz.
y() > 0.)
418 || (CentreCoords.
z() > 0. && Rotz.
z() < 0.)
419 || (CentreCoords.
z() < 0. && Rotz.
z() > 0.))
422 SideRefVec2 = -SideRefVec2;
423 SideRefVec3 = -SideRefVec3;
425 if(verbosityLevel == 2)
427 G4cout <<
"Reference vectors for cosine-law " << SideRefVec1 <<
" " << SideRefVec2 <<
" " << SideRefVec3 <<
G4endl;
431 void G4SPSPosDistribution::GeneratePointsOnSurface()
440 if(SourcePosType !=
"Surface" && verbosityLevel >= 1)
443 if(Shape ==
"Sphere")
448 theta = std::acos(1. - 2.*theta);
452 x = Radius * std::sin(theta) * std::cos(phi);
453 y = Radius * std::sin(theta) * std::sin(phi);
454 z = Radius * std::cos(theta);
462 zdash = zdash.unit();
465 SideRefVec1 = xdash.
unit();
466 SideRefVec2 = ydash.
unit();
467 SideRefVec3 = zdash.
unit();
469 else if(Shape ==
"Ellipsoid")
474 constant =
pi/(halfx*halfx) +
pi/(halfy*halfy) +
481 theta = std::acos(1. - 2.*theta);
484 while(maxphi-minphi > 0.)
486 middlephi = (maxphi+minphi)/2.;
487 answer = (1./(halfx*halfx))*(middlephi/2. + std::sin(2*middlephi)/4.)
488 + (1./(halfy*halfy))*(middlephi/2. - std::sin(2*middlephi)/4.)
489 + middlephi/(halfz*halfz);
490 answer = answer/constant;
491 if(answer > phi) maxphi = middlephi;
492 if(answer < phi) minphi = middlephi;
493 if(std::fabs(answer-phi) <= 0.00001)
500 x = std::sin(theta)*std::cos(phi);
501 y = std::sin(theta)*std::sin(phi);
509 tempxvar= 1./(halfx*halfx)+(numYinX*numYinX)/(halfy*halfy)
510 + (numZinX*numZinX)/(halfz*halfz);
512 tempxvar = 1./tempxvar;
513 G4double coordx = std::sqrt(tempxvar);
519 tempyvar=(numXinY*numXinY)/(halfx*halfx)+1./(halfy*halfy)
520 +(numZinY*numZinY)/(halfz*halfz);
521 tempyvar = 1./tempyvar;
522 G4double coordy = std::sqrt(tempyvar);
528 tempzvar=(numXinZ*numXinZ)/(halfx*halfx)
529 +(numYinZ*numYinZ)/(halfy*halfy)+1./(halfz*halfz);
530 tempzvar = 1./tempzvar;
531 G4double coordz = std::sqrt(tempzvar);
533 lhs = std::sqrt((coordx*coordx)/(halfx*halfx) +
534 (coordy*coordy)/(halfy*halfy) +
535 (coordz*coordz)/(halfz*halfz));
537 if(std::fabs(lhs-1.) > 0.001 && verbosityLevel >= 1)
538 G4cout <<
"Error: theta, phi not really on ellipsoid" <<
G4endl;
542 if(TestRandVar > 0.5)
547 if(TestRandVar > 0.5)
552 if(TestRandVar > 0.5)
557 RandPos.
setX(coordx);
558 RandPos.
setY(coordy);
559 RandPos.
setZ(coordz);
563 zdash = zdash.unit();
566 SideRefVec1 = xdash.
unit();
567 SideRefVec2 = ydash.
unit();
568 SideRefVec3 = zdash.
unit();
570 else if(Shape ==
"Cylinder")
573 G4double AreaTotal, prob1, prob2, prob3;
580 AreaTop =
pi * Radius * Radius;
582 AreaLat = 2. *
pi * Radius * 2. * halfz;
583 AreaTotal = AreaTop + AreaBot + AreaLat;
585 prob1 = AreaTop / AreaTotal;
586 prob2 = AreaBot / AreaTotal;
587 prob3 = 1.00 - prob1 - prob2;
588 if(std::fabs(prob3 - (AreaLat/AreaTotal)) >= 0.001)
590 if(verbosityLevel >= 1)
598 if(testrand <= prob1)
604 while(((x*x)+(y*y)) > (Radius*Radius))
619 else if((testrand > prob1) && (testrand <= (prob1 + prob2)))
625 while(((x*x)+(y*y)) > (Radius*Radius))
640 else if(testrand > (prob1+prob2))
646 rand = rand * 2. *
pi;
648 x = Radius * std::cos(rand);
649 y = Radius * std::sin(rand);
658 zdash = zdash.unit();
661 SideRefVec1 = xdash.
unit();
662 SideRefVec2 = ydash.
unit();
663 SideRefVec3 = zdash.
unit();
673 else if(Shape ==
"Para")
682 G4double AreaX = halfy * halfz * 4.;
683 G4double AreaY = halfx * halfz * 4.;
684 G4double AreaZ = halfx * halfy * 4.;
685 G4double AreaTotal = 2*(AreaX + AreaY + AreaZ);
687 Probs[0] = AreaX/AreaTotal;
688 Probs[1] = Probs[0] + AreaX/AreaTotal;
689 Probs[2] = Probs[1] + AreaY/AreaTotal;
690 Probs[3] = Probs[2] + AreaY/AreaTotal;
691 Probs[4] = Probs[3] + AreaZ/AreaTotal;
692 Probs[5] = Probs[4] + AreaZ/AreaTotal;
705 if(testrand < Probs[0])
708 x = halfx + z*std::tan(ParTheta)*std::cos(ParPhi) + y*std::tan(ParAlpha);
709 y = y + z*std::tan(ParTheta)*std::sin(ParPhi);
712 G4ThreeVector xdash(halfz*std::tan(ParTheta)*std::cos(ParPhi),
713 halfz*std::tan(ParTheta)*std::sin(ParPhi),
714 halfz/std::cos(ParPhi));
716 xdash = xdash.
unit();
717 ydash = ydash.
unit();
719 SideRefVec1 = xdash.
unit();
720 SideRefVec2 = ydash.
unit();
721 SideRefVec3 = zdash.
unit();
723 else if(testrand >= Probs[0] && testrand < Probs[1])
726 x = -halfx + z*std::tan(ParTheta)*std::cos(ParPhi) + y*std::tan(ParAlpha);
727 y = y + z*std::tan(ParTheta)*std::sin(ParPhi);
730 G4ThreeVector xdash(halfz*std::tan(ParTheta)*std::cos(ParPhi),
731 halfz*std::tan(ParTheta)*std::sin(ParPhi),
732 halfz/std::cos(ParPhi));
734 xdash = xdash.
unit();
735 ydash = ydash.
unit();
737 SideRefVec1 = xdash.
unit();
738 SideRefVec2 = ydash.
unit();
739 SideRefVec3 = zdash.
unit();
741 else if(testrand >= Probs[1] && testrand < Probs[2])
744 x = x + z*std::tan(ParTheta)*std::cos(ParPhi) + halfy*std::tan(ParAlpha);
745 y = halfy + z*std::tan(ParTheta)*std::sin(ParPhi);
748 G4ThreeVector ydash(halfz*std::tan(ParTheta)*std::cos(ParPhi),
749 halfz*std::tan(ParTheta)*std::sin(ParPhi),
750 halfz/std::cos(ParPhi));
751 ydash = ydash.
unit();
754 SideRefVec1 = xdash.
unit();
755 SideRefVec2 = -ydash.
unit();
756 SideRefVec3 = -zdash.
unit();
758 else if(testrand >= Probs[2] && testrand < Probs[3])
761 x = x + z*std::tan(ParTheta)*std::cos(ParPhi) - halfy*std::tan(ParAlpha);
762 y = -halfy + z*std::tan(ParTheta)*std::sin(ParPhi);
765 G4ThreeVector ydash(halfz*std::tan(ParTheta)*std::cos(ParPhi),
766 halfz*std::tan(ParTheta)*std::sin(ParPhi),
767 halfz/std::cos(ParPhi));
768 ydash = ydash.
unit();
771 SideRefVec1 = xdash.
unit();
772 SideRefVec2 = ydash.
unit();
773 SideRefVec3 = zdash.
unit();
775 else if(testrand >= Probs[3] && testrand < Probs[4])
779 y = y + halfz*std::sin(ParPhi)*std::tan(ParTheta);
780 x = x + halfz*std::cos(ParPhi)*std::tan(ParTheta) + y*std::tan(ParAlpha);
786 else if(testrand >= Probs[4] && testrand < Probs[5])
790 y = y - halfz*std::sin(ParPhi)*std::tan(ParTheta);
791 x = x - halfz*std::cos(ParPhi)*std::tan(ParTheta) + y*std::tan(ParAlpha);
800 if(verbosityLevel >= 1)
801 G4cout <<
"testrand=" << testrand <<
" Probs[5]=" << Probs[5] <<
G4endl;
811 if(verbosityLevel == 2)
814 x=(RandPos.
x()*Rotx.
x())+(RandPos.
y()*Roty.
x())+(RandPos.
z()*Rotz.
x());
815 y=(RandPos.
x()*Rotx.
y())+(RandPos.
y()*Roty.
y())+(RandPos.
z()*Rotz.
y());
816 z=(RandPos.
x()*Rotx.
z())+(RandPos.
y()*Roty.
z())+(RandPos.
z()*Rotz.
z());
823 particle_position = CentreCoords + RandPos;
825 if(verbosityLevel >= 1)
827 if(verbosityLevel == 2)
829 G4cout <<
"Rotated and translated position " << particle_position <<
G4endl;
831 if(verbosityLevel == 2)
833 G4cout <<
"Reference vectors for cosine-law " << SideRefVec1 <<
" " << SideRefVec2 <<
" " << SideRefVec3 <<
G4endl;
837 void G4SPSPosDistribution::GeneratePointsInVolume()
843 if(SourcePosType !=
"Volume" && verbosityLevel >= 1)
846 if(Shape ==
"Sphere")
851 while(((x*x)+(y*y)+(z*z)) > (Radius*Radius))
857 x = (x*2.*Radius) - Radius;
858 y = (y*2.*Radius) - Radius;
859 z = (z*2.*Radius) - Radius;
862 else if(Shape ==
"Ellipsoid")
872 x = (x*2.*halfx) - halfx;
873 y = (y*2.*halfy) - halfy;
874 z = (z*2.*halfz) - halfz;
876 temp = ((x*
x)/(halfx*halfx)) + ((y*y)/(halfy*halfy))
877 + ((z*
z)/(halfz*halfz));
880 else if(Shape ==
"Cylinder")
884 while(((x*x)+(y*
y)) > (Radius*Radius))
890 x = (x*2.*Radius) - Radius;
891 y = (y*2.*Radius) - Radius;
892 z = (z*2.*halfz) - halfz;
895 else if(Shape ==
"Para")
900 x = (x*2.*halfx) - halfx;
901 y = (y*2.*halfy) - halfy;
902 z = (z*2.*halfz) - halfz;
903 x = x + z*std::tan(ParTheta)*std::cos(ParPhi) + y*std::tan(ParAlpha);
904 y = y + z*std::tan(ParTheta)*std::sin(ParPhi);
916 tempx = (x * Rotx.
x()) + (y * Roty.
x()) + (z * Rotz.
x());
917 tempy = (x * Rotx.
y()) + (y * Roty.
y()) + (z * Rotz.
y());
918 tempz = (x * Rotx.
z()) + (y * Roty.
z()) + (z * Rotz.
z());
925 particle_position = CentreCoords + RandPos;
927 if(verbosityLevel == 2)
929 G4cout <<
"Raw position " << x <<
"," << y <<
"," << z <<
G4endl;
932 if(verbosityLevel >= 1)
933 G4cout <<
"Rotated and translated position " << particle_position <<
G4endl;
937 zdash = zdash.
unit();
940 SideRefVec1 = xdash.
unit();
941 SideRefVec2 = ydash.
unit();
942 SideRefVec3 = zdash.
unit();
944 if(verbosityLevel == 2)
946 G4cout <<
"Reference vectors for cosine-law " << SideRefVec1 <<
" " << SideRefVec2 <<
" " << SideRefVec3 <<
G4endl;
950 G4bool G4SPSPosDistribution::IsSourceConfined()
964 if(theVolName == VolName)
966 if(verbosityLevel >= 1)
967 G4cout <<
"Particle is in volume " << VolName <<
G4endl;
979 while(srcconf ==
false)
981 if(SourcePosType ==
"Point")
982 GeneratePointSource();
983 else if(SourcePosType ==
"Beam")
984 GeneratePointsInBeam();
985 else if(SourcePosType ==
"Plane")
986 GeneratePointsInPlane();
987 else if(SourcePosType ==
"Surface")
988 GeneratePointsOnSurface();
989 else if(SourcePosType ==
"Volume")
990 GeneratePointsInVolume();
995 GeneratePointSource();
999 srcconf = IsSourceConfined();
1003 else if(Confine ==
false)
1006 if(LoopCount == 100000)
1008 G4cout <<
"*************************************" <<
G4endl;
1010 G4cout <<
"Either the source distribution >> confinement" <<
G4endl;
1011 G4cout <<
"or any confining volume may not overlap with" <<
G4endl;
1012 G4cout <<
"the source distribution or any confining volumes" <<
G4endl;
1014 G4cout <<
"If you have set confine then this will be ignored" <<
G4endl;
1016 G4cout <<
"*************************************" <<
G4endl;
1020 return particle_position;
ThreeVector shoot(const G4int Ap, const G4int Af)
DLL_API const Hep3Vector HepZHat
void SetPosDisType(G4String)
void SetParTheta(G4double)
void SetBeamSigmaInX(G4double)
CLHEP::Hep3Vector G4ThreeVector
G4Navigator * GetNavigatorForTracking() const
void SetParAlpha(G4double)
static G4PhysicalVolumeStore * GetInstance()
G4GLOB_DLL std::ostream G4cout
void SetCentreCoords(G4ThreeVector)
void SetBeamSigmaInR(G4double)
const G4String & GetName() const
void SetPosRot1(G4ThreeVector)
void SetPosDisShape(G4String)
DLL_API const Hep3Vector HepYHat
static G4TransportationManager * GetTransportationManager()
DLL_API const Hep3Vector HepXHat
void SetPosRot2(G4ThreeVector)
virtual G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=0, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true)
Hep3Vector cross(const Hep3Vector &) const
G4double GenRandPosTheta()
void ConfineSourceToVolume(G4String)
G4ThreeVector GenerateOne()
void SetRadius0(G4double)
void SetBeamSigmaInY(G4double)