59 G4SPSPosDistribution::thread_data_t::thread_data_t()
 
   69   SourcePosType = 
"Point";
 
   99     SourcePosType = PosType;
 
  109   CentreCoords = coordsOfCentre;
 
  116   if(verbosityLevel == 2)
 
  120   GenerateRotationMatrices();
 
  128   if(verbosityLevel == 2)
 
  130       G4cout << 
"The vector in the x'-y' plane " << Roty << 
G4endl;
 
  132   GenerateRotationMatrices();
 
  193     return SourcePosType;
 
  238     return SourcePosType;
 
  242     return ThreadData.
Get().CParticlePos;
 
  246     return ThreadData.
Get().CSideRefVec1;
 
  250     return ThreadData.
Get().CSideRefVec2;
 
  254   return ThreadData.
Get().CSideRefVec3;
 
  257 void G4SPSPosDistribution::GenerateRotationMatrices()
 
  265   Rotz = Rotx.
cross(Roty); 
 
  267   Roty =Rotz.
cross(Rotx); 
 
  269   if(verbosityLevel == 2)
 
  271       G4cout << 
"The new axes, x', y', z' " << Rotx << 
" " << Roty << 
" " << Rotz << 
G4endl;
 
  278   if(verbosityLevel == 2)
 
  282   G4String theRequiredVolumeName = VolName;
 
  286   if(verbosityLevel == 2)
 
  288   while (!found && i<
G4int(PVStore->size())) {
 
  289     tempPV = (*PVStore)[i];
 
  290     found  = tempPV->
GetName() == theRequiredVolumeName;
 
  291     if(verbosityLevel == 2)
 
  292       G4cout << i << 
" " << 
" " << tempPV->
GetName() << 
" " << theRequiredVolumeName << 
" " << found << 
G4endl;
 
  299       if(verbosityLevel >= 1)
 
  305       G4cout << 
" **** Error: Volume does not exist **** " << 
G4endl;
 
  316   if(SourcePosType == 
"Point")
 
  319     if(verbosityLevel >= 1)
 
  320       G4cerr << 
"Error SourcePosType is not set to Point" << 
G4endl;
 
  323 void G4SPSPosDistribution::GeneratePointsInBeam(
G4ThreeVector& pos)
 
  332   if(Shape == 
"Circle")
 
  336       while(std::sqrt((x*x) + (y*y)) > Radius)
 
  341       x = (x*2.*Radius) - Radius;
 
  342       y = (y*2.*Radius) - Radius;
 
  352       x = (x*2.*halfx) - halfx;
 
  353       y = (y*2.*halfy) - halfy;
 
  359   if(verbosityLevel >= 2)
 
  361       G4cout << 
"Raw position " << x << 
"," << y << 
"," << z << 
G4endl;
 
  363   tempx = (x * Rotx.
x()) + (y * Roty.
x()) + (z * Rotz.
x());
 
  364   tempy = (x * Rotx.
y()) + (y * Roty.
y()) + (z * Rotz.
y());
 
  365   tempz = (x * Rotx.
z()) + (y * Roty.
z()) + (z * Rotz.
z());
 
  372   pos = CentreCoords + RandPos;
 
  373   if(verbosityLevel >= 1)
 
  375       if(verbosityLevel >= 2)
 
  379       G4cout << 
"Rotated and Translated position " << pos << 
G4endl;
 
  383 void G4SPSPosDistribution::GeneratePointsInPlane(
G4ThreeVector& pos)
 
  390   thread_data_t& td = ThreadData.
Get();
 
  391   if(SourcePosType != 
"Plane" && verbosityLevel >= 1)
 
  392     G4cerr << 
"Error: SourcePosType is not Plane" << 
G4endl;
 
  395   if(Shape == 
"Circle")
 
  399       while(std::sqrt((x*x) + (y*y)) > Radius)
 
  404       x = (x*2.*Radius) - Radius;
 
  405       y = (y*2.*Radius) - Radius;
 
  408   else if(Shape == 
"Annulus")
 
  412       while(std::sqrt((x*x) + (y*y)) > Radius || std::sqrt((x*x) + (y*y)) < Radius0 )
 
  417       x = (x*2.*Radius) - Radius;
 
  418       y = (y*2.*Radius) - Radius;
 
  421   else if(Shape == 
"Ellipse")
 
  424       while(expression > 1.)
 
  429       x = (x*2.*halfx) - halfx;
 
  430       y = (y*2.*halfy) - halfy;
 
  432       expression = ((x*x)/(halfx*halfx)) + ((y*y)/(halfy*halfy));
 
  435   else if(Shape == 
"Square")
 
  439       x = (x*2.*halfx) - halfx;
 
  440       y = (y*2.*halfy) - halfy;
 
  442   else if(Shape == 
"Rectangle")
 
  446       x = (x*2.*halfx) - halfx;
 
  447       y = (y*2.*halfy) - halfy;
 
  454   if(verbosityLevel == 2)
 
  456       G4cout << 
"Raw position " << x << 
"," << y << 
"," << z << 
G4endl;
 
  458   tempx = (x * Rotx.
x()) + (y * Roty.
x()) + (z * Rotz.
x());
 
  459   tempy = (x * Rotx.
y()) + (y * Roty.
y()) + (z * Rotz.
y());
 
  460   tempz = (x * Rotx.
z()) + (y * Roty.
z()) + (z * Rotz.
z());
 
  467   pos = CentreCoords + RandPos;
 
  468   if(verbosityLevel >= 1)
 
  470       if(verbosityLevel == 2)
 
  474       G4cout << 
"Rotated and Translated position " << pos << 
G4endl;
 
  479   td.CSideRefVec1 = Rotx;
 
  480   td.CSideRefVec2 = Roty;
 
  481   td.CSideRefVec3 = Rotz;
 
  485   if((CentreCoords.
x() > 0. && Rotz.
x() < 0.)
 
  486      || (CentreCoords.
x() < 0. && Rotz.
x() > 0.)
 
  487      || (CentreCoords.
y() > 0. && Rotz.
y() < 0.)
 
  488      || (CentreCoords.
y() < 0. && Rotz.
y() > 0.)
 
  489      || (CentreCoords.
z() > 0. && Rotz.
z() < 0.)
 
  490      || (CentreCoords.
z() < 0. && Rotz.
z() > 0.))
 
  493       td.CSideRefVec2 = - td.CSideRefVec2;
 
  494       td.CSideRefVec3 = - td.CSideRefVec3;
 
  497   if(verbosityLevel == 2)
 
  499       G4cout << 
"Reference vectors for cosine-law " << td.CSideRefVec1<< 
" " << td.CSideRefVec2<< 
" " << td.CSideRefVec3<< 
G4endl;
 
  503 void G4SPSPosDistribution::GeneratePointsOnSurface(
G4ThreeVector& pos)
 
  511   thread_data_t& td = ThreadData.
Get();
 
  512   if(SourcePosType != 
"Surface" && verbosityLevel >= 1)
 
  515   if(Shape == 
"Sphere")
 
  520       theta = std::acos(1. - 2.*theta); 
 
  524       x = Radius * std::sin(theta) * std::cos(phi);
 
  525       y = Radius * std::sin(theta) * std::sin(phi);
 
  526       z = Radius * std::cos(theta);
 
  534       zdash = zdash.unit();
 
  537       td.CSideRefVec1 = xdash.
unit();
 
  538       td.CSideRefVec2 = ydash.
unit();
 
  539       td.CSideRefVec3 = zdash.
unit();
 
  542   else if(Shape == 
"Ellipsoid")
 
  547       constant = 
pi/(halfx*halfx) + 
pi/(halfy*halfy) +
 
  554       theta = std::acos(1. - 2.*theta);
 
  557       while(maxphi-minphi > 0.)
 
  559       middlephi = (maxphi+minphi)/2.;
 
  560       answer = (1./(halfx*halfx))*(middlephi/2. + std::sin(2*middlephi)/4.)
 
  561         + (1./(halfy*halfy))*(middlephi/2. - std::sin(2*middlephi)/4.)
 
  562            + middlephi/(halfz*halfz);
 
  563       answer = answer/constant;
 
  564       if(answer > phi) maxphi = middlephi;
 
  565       if(answer < phi) minphi = middlephi;
 
  566       if(std::fabs(answer-phi) <= 0.00001)
 
  573       x = std::sin(theta)*std::cos(phi);
 
  574       y = std::sin(theta)*std::sin(phi);
 
  582       tempxvar= 1./(halfx*halfx)+(numYinX*numYinX)/(halfy*halfy)
 
  583     + (numZinX*numZinX)/(halfz*halfz);
 
  585       tempxvar = 1./tempxvar;
 
  586       G4double coordx = std::sqrt(tempxvar);
 
  592       tempyvar=(numXinY*numXinY)/(halfx*halfx)+1./(halfy*halfy)
 
  593     +(numZinY*numZinY)/(halfz*halfz);
 
  594       tempyvar = 1./tempyvar;
 
  595       G4double coordy = std::sqrt(tempyvar);
 
  601       tempzvar=(numXinZ*numXinZ)/(halfx*halfx)
 
  602     +(numYinZ*numYinZ)/(halfy*halfy)+1./(halfz*halfz);
 
  603       tempzvar = 1./tempzvar;
 
  604       G4double coordz = std::sqrt(tempzvar);
 
  606       lhs = std::sqrt((coordx*coordx)/(halfx*halfx) +
 
  607          (coordy*coordy)/(halfy*halfy) +
 
  608          (coordz*coordz)/(halfz*halfz));
 
  610       if(std::fabs(lhs-1.) > 0.001 && verbosityLevel >= 1)
 
  611     G4cout << 
"Error: theta, phi not really on ellipsoid" << 
G4endl;
 
  615       if(TestRandVar > 0.5)
 
  620       if(TestRandVar > 0.5)
 
  625       if(TestRandVar > 0.5)
 
  630       RandPos.
setX(coordx);
 
  631       RandPos.
setY(coordy);
 
  632       RandPos.
setZ(coordz);
 
  636       zdash = zdash.unit();
 
  639       td.CSideRefVec1 = xdash.
unit();
 
  640       td.CSideRefVec2 = ydash.
unit();
 
  641       td.CSideRefVec3 = zdash.
unit();
 
  643   else if(Shape == 
"Cylinder")
 
  646       G4double AreaTotal, prob1, prob2, prob3;
 
  653       AreaTop = 
pi * Radius * Radius;
 
  655       AreaLat = 2. * 
pi * Radius * 2. * halfz;
 
  656       AreaTotal = AreaTop + AreaBot + AreaLat;
 
  658       prob1 = AreaTop / AreaTotal;
 
  659       prob2 = AreaBot / AreaTotal;
 
  660       prob3 = 1.00 - prob1 - prob2;
 
  661       if(std::fabs(prob3 - (AreaLat/AreaTotal)) >= 0.001)
 
  663       if(verbosityLevel >= 1)
 
  671       if(testrand <= prob1)
 
  677       while(((x*x)+(y*y)) > (Radius*Radius))
 
  688       td.CSideRefVec1 = Rotx;
 
  689       td.CSideRefVec2 = Roty;
 
  690       td.CSideRefVec3 = Rotz;
 
  692       else if((testrand > prob1) && (testrand <= (prob1 + prob2)))
 
  698       while(((x*x)+(y*y)) > (Radius*Radius))
 
  709       td.CSideRefVec1 = Rotx;
 
  710       td.CSideRefVec2 = -Roty;
 
  711       td.CSideRefVec3 = -Rotz;
 
  713       else if(testrand > (prob1+prob2))
 
  719       rand = rand * 2. * 
pi;
 
  721       x = Radius * std::cos(rand);
 
  722       y = Radius * std::sin(rand);
 
  731       zdash = zdash.unit();
 
  734       td.CSideRefVec1 = xdash.
unit();
 
  735       td.CSideRefVec2 = ydash.
unit();
 
  736       td.CSideRefVec3 = zdash.
unit();
 
  746   else if(Shape == 
"Para")
 
  755       G4double AreaX = halfy * halfz * 4.;
 
  756       G4double AreaY = halfx * halfz * 4.;
 
  757       G4double AreaZ = halfx * halfy * 4.;
 
  758       G4double AreaTotal = 2*(AreaX + AreaY + AreaZ);
 
  760       Probs[0] = AreaX/AreaTotal;
 
  761       Probs[1] = Probs[0] + AreaX/AreaTotal;
 
  762       Probs[2] = Probs[1] + AreaY/AreaTotal;
 
  763       Probs[3] = Probs[2] + AreaY/AreaTotal;
 
  764       Probs[4] = Probs[3] + AreaZ/AreaTotal;
 
  765       Probs[5] = Probs[4] + AreaZ/AreaTotal;
 
  778       if(testrand < Probs[0])
 
  781       x = halfx + z*std::tan(ParTheta)*std::cos(ParPhi) + y*std::tan(ParAlpha);
 
  782       y = y + z*std::tan(ParTheta)*std::sin(ParPhi);
 
  785       G4ThreeVector xdash(halfz*std::tan(ParTheta)*std::cos(ParPhi),
 
  786           halfz*std::tan(ParTheta)*std::sin(ParPhi),
 
  787           halfz/std::cos(ParPhi));
 
  789       xdash = xdash.
unit();
 
  790       ydash = ydash.
unit();
 
  792       td.CSideRefVec1 = xdash.
unit();
 
  793       td.CSideRefVec2 = ydash.
unit();
 
  794       td.CSideRefVec3 = zdash.
unit();
 
  796       else if(testrand >= Probs[0] && testrand < Probs[1])
 
  799       x = -halfx + z*std::tan(ParTheta)*std::cos(ParPhi) + y*std::tan(ParAlpha);
 
  800       y = y + z*std::tan(ParTheta)*std::sin(ParPhi);
 
  803       G4ThreeVector xdash(halfz*std::tan(ParTheta)*std::cos(ParPhi),
 
  804           halfz*std::tan(ParTheta)*std::sin(ParPhi),
 
  805           halfz/std::cos(ParPhi));
 
  807       xdash = xdash.
unit();
 
  808       ydash = ydash.
unit();
 
  810       td.CSideRefVec1 = xdash.
unit();
 
  811       td.CSideRefVec2 = ydash.
unit();
 
  812       td.CSideRefVec3 = zdash.
unit();
 
  814       else if(testrand >= Probs[1] && testrand < Probs[2])
 
  817       x = x + z*std::tan(ParTheta)*std::cos(ParPhi) + halfy*std::tan(ParAlpha);
 
  818       y = halfy + z*std::tan(ParTheta)*std::sin(ParPhi);
 
  821       G4ThreeVector ydash(halfz*std::tan(ParTheta)*std::cos(ParPhi),
 
  822           halfz*std::tan(ParTheta)*std::sin(ParPhi),
 
  823           halfz/std::cos(ParPhi));
 
  824       ydash = ydash.
unit();
 
  827       td.CSideRefVec1 = xdash.
unit();
 
  828       td.CSideRefVec2 = -ydash.
unit();
 
  829       td.CSideRefVec3 = -zdash.
unit();
 
  831       else if(testrand >= Probs[2] && testrand < Probs[3])
 
  834       x = x + z*std::tan(ParTheta)*std::cos(ParPhi) - halfy*std::tan(ParAlpha);
 
  835       y = -halfy + z*std::tan(ParTheta)*std::sin(ParPhi);
 
  838       G4ThreeVector ydash(halfz*std::tan(ParTheta)*std::cos(ParPhi),
 
  839           halfz*std::tan(ParTheta)*std::sin(ParPhi),
 
  840           halfz/std::cos(ParPhi));
 
  841       ydash = ydash.
unit();
 
  844       td.CSideRefVec1 = xdash.
unit();
 
  845       td.CSideRefVec2 = ydash.
unit();
 
  846       td.CSideRefVec3 = zdash.
unit();
 
  848       else if(testrand >= Probs[3] && testrand < Probs[4])
 
  852       y = y + halfz*std::sin(ParPhi)*std::tan(ParTheta);
 
  853       x = x + halfz*std::cos(ParPhi)*std::tan(ParTheta) + y*std::tan(ParAlpha);
 
  855       td.CSideRefVec1 = Rotx;
 
  856       td.CSideRefVec2 = Roty;
 
  857       td.CSideRefVec3 = Rotz;
 
  859       else if(testrand >= Probs[4] && testrand < Probs[5])
 
  863       y = y - halfz*std::sin(ParPhi)*std::tan(ParTheta);
 
  864       x = x - halfz*std::cos(ParPhi)*std::tan(ParTheta) + y*std::tan(ParAlpha);
 
  866       td.CSideRefVec1 = Rotx;
 
  867       td.CSideRefVec2 = -Roty;
 
  868       td.CSideRefVec3 = -Rotz;
 
  873       if(verbosityLevel >= 1)
 
  874         G4cout << 
"testrand=" << testrand << 
" Probs[5]=" << Probs[5] <<
G4endl;
 
  884   if(verbosityLevel == 2)
 
  887   x=(RandPos.
x()*Rotx.
x())+(RandPos.
y()*Roty.
x())+(RandPos.
z()*Rotz.
x());
 
  888   y=(RandPos.
x()*Rotx.
y())+(RandPos.
y()*Roty.
y())+(RandPos.
z()*Rotz.
y());
 
  889   z=(RandPos.
x()*Rotx.
z())+(RandPos.
y()*Roty.
z())+(RandPos.
z()*Rotz.
z());
 
  896   pos = CentreCoords + RandPos;
 
  898   if(verbosityLevel >= 1)
 
  900       if(verbosityLevel == 2)
 
  902       G4cout << 
"Rotated and translated position " << pos << 
G4endl;
 
  904   if(verbosityLevel == 2)
 
  906       G4cout << 
"Reference vectors for cosine-law " << td.CSideRefVec1 << 
" " << td.CSideRefVec2 << 
" " << td.CSideRefVec3 << 
G4endl;
 
  910 void G4SPSPosDistribution::GeneratePointsInVolume(
G4ThreeVector& pos)
 
  916   if(SourcePosType != 
"Volume" && verbosityLevel >= 1)
 
  919   if(Shape == 
"Sphere")
 
  924       while(((x*x)+(y*y)+(z*z)) > (Radius*Radius))
 
  930       x = (x*2.*Radius) - Radius;
 
  931       y = (y*2.*Radius) - Radius;
 
  932       z = (z*2.*Radius) - Radius;
 
  935   else if(Shape == 
"Ellipsoid")
 
  945       x = (x*2.*halfx) - halfx;
 
  946       y = (y*2.*halfy) - halfy;
 
  947       z = (z*2.*halfz) - halfz;
 
  949       temp = ((x*x)/(halfx*halfx)) + ((y*y)/(halfy*halfy))
 
  950         + ((z*z)/(halfz*halfz));
 
  953   else if(Shape == 
"Cylinder")
 
  957       while(((x*x)+(y*y)) > (Radius*Radius))
 
  963       x = (x*2.*Radius) - Radius;
 
  964       y = (y*2.*Radius) - Radius;
 
  965       z = (z*2.*halfz) - halfz;
 
  968   else if(Shape == 
"Para")
 
  973       x = (x*2.*halfx) - halfx;
 
  974       y = (y*2.*halfy) - halfy;
 
  975       z = (z*2.*halfz) - halfz;
 
  976       x = x + z*std::tan(ParTheta)*std::cos(ParPhi) + y*std::tan(ParAlpha);
 
  977       y = y + z*std::tan(ParTheta)*std::sin(ParPhi);
 
  989   tempx = (x * Rotx.
x()) + (y * Roty.
x()) + (z * Rotz.
x());
 
  990   tempy = (x * Rotx.
y()) + (y * Roty.
y()) + (z * Rotz.
y());
 
  991   tempz = (x * Rotx.
z()) + (y * Roty.
z()) + (z * Rotz.
z());
 
  998   pos = CentreCoords + RandPos;
 
 1000   if(verbosityLevel == 2)
 
 1002       G4cout << 
"Raw position " << x << 
"," << y << 
"," << z << 
G4endl;
 
 1005   if(verbosityLevel >= 1)
 
 1006     G4cout << 
"Rotated and translated position " << pos << 
G4endl;
 
 1010   zdash = zdash.
unit();
 
 1013   thread_data_t& td = ThreadData.
Get();
 
 1014   td.CSideRefVec1 = xdash.
unit();
 
 1015   td.CSideRefVec2 = ydash.
unit();
 
 1016   td.CSideRefVec3 = zdash.
unit();
 
 1017   if(verbosityLevel == 2)
 
 1019       G4cout << 
"Reference vectors for cosine-law " << td.CSideRefVec1 << 
" " << td.CSideRefVec2 << 
" " << td.CSideRefVec3 << 
G4endl;
 
 1026   if(Confine == 
false)
 
 1037   if(!theVolume) 
return(
false);
 
 1039   if(theVolName == VolName)
 
 1041       if(verbosityLevel >= 1)
 
 1042     G4cout << 
"Particle is in volume " << VolName << 
G4endl;
 
 1054   G4int LoopCount = 0;
 
 1055   while(srcconf == 
false)
 
 1057       if(SourcePosType == 
"Point")
 
 1058           GeneratePointSource(localP);
 
 1059       else if(SourcePosType == 
"Beam")
 
 1060           GeneratePointsInBeam(localP);
 
 1061       else if(SourcePosType == 
"Plane")
 
 1062           GeneratePointsInPlane(localP);
 
 1063       else if(SourcePosType == 
"Surface")
 
 1064           GeneratePointsOnSurface(localP);
 
 1065       else if(SourcePosType == 
"Volume")
 
 1066           GeneratePointsInVolume(localP);
 
 1070           msg << 
"Error: SourcePosType undefined\n";
 
 1071           msg << 
"Generating point source\n";
 
 1073           GeneratePointSource(localP);
 
 1077           srcconf = IsSourceConfined(localP);
 
 1081       else if(Confine == 
false)
 
 1084       if(LoopCount == 100000)
 
 1087           msg << 
"LoopCount = 100000\n";
 
 1088           msg << 
"Either the source distribution >> confinement\n";
 
 1089           msg << 
"or any confining volume may not overlap with\n";
 
 1090           msg << 
"the source distribution or any confining volumes\n";
 
 1091           msg << 
"may not exist\n"<< 
G4endl;
 
 1092           msg << 
"If you have set confine then this will be ignored\n";
 
 1093           msg << 
"for this event.\n" << 
G4endl;
 
 1098   ThreadData.
Get().CParticlePos=localP;
 
ThreeVector shoot(const G4int Ap, const G4int Af)
 
DLL_API const Hep3Vector HepZHat
 
G4ThreeVector GetSideRefVec2() const 
 
void SetBiasRndm(G4SPSRandomGenerator *a)
 
void SetPosDisType(G4String)
 
void SetParTheta(G4double)
 
std::ostringstream G4ExceptionDescription
 
void SetBeamSigmaInX(G4double)
 
CLHEP::Hep3Vector G4ThreeVector
 
G4String GetPosDisShape() const 
 
G4Navigator * GetNavigatorForTracking() const 
 
#define G4MUTEXINIT(mutex)
 
void SetParAlpha(G4double)
 
G4double GetRadius() const 
 
static constexpr double twopi
 
static G4PhysicalVolumeStore * GetInstance()
 
G4double GetHalfY() const 
 
G4GLOB_DLL std::ostream G4cout
 
void SetCentreCoords(G4ThreeVector)
 
void SetBeamSigmaInR(G4double)
 
const G4String & GetName() const 
 
G4ThreeVector GetCentreCoords() const 
 
void SetPosRot1(G4ThreeVector)
 
void SetPosDisShape(G4String)
 
DLL_API const Hep3Vector HepYHat
 
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
 
G4ThreeVector GetSideRefVec3() const 
 
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)
 
G4ThreeVector GetSideRefVec1() const 
 
G4String GetPosDisType() const 
 
G4ThreeVector GetParticlePos() const 
 
static constexpr double pi
 
Hep3Vector cross(const Hep3Vector &) const 
 
G4double GetHalfX() const 
 
G4double GenRandPosTheta()
 
void ConfineSourceToVolume(G4String)
 
G4String GetSourcePosType() const 
 
#define G4MUTEXDESTROY(mutex)
 
G4ThreeVector GenerateOne()
 
void SetRadius0(G4double)
 
static const G4double pos
 
void SetBeamSigmaInY(G4double)
 
void SetVerbosity(G4int a)
 
G4GLOB_DLL std::ostream G4cerr
 
G4double GetHalfZ() const