/home/cern/BDSIM_new/src/BDSGen5Shell.cc

00001 /* BDSIM code.    Version 1.0
00002    Author: Grahame A. Blair, Royal Holloway, Univ. of London.
00003    Last modified 24.7.2002
00004    Copyright (c) 2002 by G.A.Blair.  ALL RIGHTS RESERVED. 
00005 */
00006 // G A Blair 24.6.02
00007 // Routine to generate a random point in an n-dimensional spherical shell
00008 
00009 
00010 #include "BDSGen5Shell.hh"
00011 
00012 
00013 
00014 BDSGen5Shell::BDSGen5Shell(G4double InnerRad, G4double OuterRad):
00015   ShellInnerRadius(InnerRad),ShellOuterRadius(OuterRad)
00016 {
00017   if(ShellInnerRadius>ShellOuterRadius)
00018     G4Exception("BDSGen5Shell: Outer Radius smaller than Inner one!");
00019 
00020   // generate area of approximate function for sin^2 theta
00021   area2=1./3. +   2.*(pi/2-1)     + 1./3;
00022 
00023   // generate area of approximate function for sin^3 theta
00024   area3=1./4. +   2.*(pi/2-1)     + 1./4;
00025 
00026   Gen2Lower=1./3.;
00027   Gen2Upper=area2-1./3.;
00028   Gen3Lower=0.25;
00029   Gen3Upper=area3-1./4.;
00030 
00031   // radial area
00032   areaR=0;
00033   GenRLower=0;
00034   if(ShellInnerRadius<ShellOuterRadius)
00035     {
00036       GenRLower=pow(ShellInnerRadius,5)/5.;
00037       areaR=pow(ShellOuterRadius,5)/5.-GenRLower;
00038     }   
00039 }
00040 
00041 BDSGen5Shell::~BDSGen5Shell()
00042 {
00043   delete[] itsVec;
00044 }
00045 
00046 
00047 G4double* BDSGen5Shell::GenPoint()
00048 {
00049 
00050   Theta0=GenSin3();
00051 
00052   Theta1=GenSin2();
00053 
00054   Theta2=acos(2*G4UniformRand()-1);
00055 
00056   Theta3=G4UniformRand()*twopi;
00057 
00058   G4double s0=sin(Theta0);
00059   G4double c0=cos(Theta0);
00060   G4double s1=sin(Theta1);
00061   G4double c1=cos(Theta1);
00062   G4double s2=sin(Theta2);
00063   G4double c2=cos(Theta2);
00064   G4double s3=sin(Theta3);
00065   G4double c3=cos(Theta3);
00066 
00067   itsVec[0]=c0;
00068   itsVec[1]=s0*c1;
00069   itsVec[2]=s0*s1*c2;
00070   itsVec[3]=s0*s1*s2*c3;
00071   itsVec[4]=s0*s1*s2*s3;
00072 
00073   G4double R;
00074   if(ShellInnerRadius==ShellOuterRadius)
00075     R=ShellInnerRadius;
00076   else
00077     R=GenRadius();
00078 
00079   for(G4int i=0;i<5;i++) itsVec[i]*=R;
00080 
00081   return itsVec;
00082 }
00083 
00084 G4double BDSGen5Shell::GenSin2()
00085 {
00086   // generate theta according to a sin^2 distribution
00087   G4double theta,trial;
00088   G4bool lok=false;
00089 
00090   //split up the region into three, for more efficient MC:
00091   do
00092     {
00093       trial=area2*G4UniformRand();
00094       
00095       if(trial>=Gen2Upper)
00096         {
00097           theta=pi-pow(1-3*(area2-trial),1./3.);
00098           if(G4UniformRand()*pow(pi-theta,2)<=pow(sin(theta),2))lok=true;
00099         }
00100       else 
00101         {
00102           if (trial>Gen2Lower)
00103             {
00104               theta=1+trial-1./3.;
00105               if(G4UniformRand()<pow(sin(theta),2))lok=true;
00106             }
00107           else
00108             {
00109               theta=pow(3*trial,1./3.);
00110               if(G4UniformRand()*pow(theta,2)<=pow(sin(theta),2))lok=true;
00111             }
00112         }
00113     }while(lok==false);
00114 
00115   return theta;
00116 }
00117 
00118 G4double BDSGen5Shell::GenSin3()
00119 {
00120   // generate theta according to a sin^2 distribution
00121   G4double theta,trial;
00122   G4bool lok=false;
00123 
00124   //split up the region into three, for more efficient MC:
00125   do
00126     {
00127       trial=area3*G4UniformRand();
00128       
00129       if(trial>=Gen3Upper)
00130         {
00131           theta=pi-pow(1-4*(area3-trial),1./4.);
00132           if(G4UniformRand()*pow(pi-theta,3)<=pow(sin(theta),3))lok=true;
00133         }
00134       else 
00135         {
00136           if (trial>Gen3Lower)
00137             {
00138               theta=1+trial-1/4.;
00139               if(G4UniformRand()<pow(sin(theta),3))lok=true;
00140             }
00141           else
00142             {
00143               theta=pow(4*trial,1./4.);
00144               if(G4UniformRand()*pow(theta,3)<=pow(sin(theta),3))lok=true;
00145             }
00146         }
00147     }while(lok==false);
00148 
00149   return theta;
00150 }
00151 
00152 G4double BDSGen5Shell::GenRadius()
00153 {
00154   // generate r^4 dr distribution
00155   G4double rad;
00156   G4double trial=areaR*G4UniformRand();
00157   rad=pow(5.*(GenRLower+trial),1./5.);
00158 
00159   return rad;
00160 }

Generated on Wed Mar 5 17:25:22 2008 for BDSIM by  doxygen 1.5.3