CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/DetectorDescription/Core/src/Polyhedra.cc

Go to the documentation of this file.
00001 #include "DetectorDescription/Core/src/Polyhedra.h" 
00002 #include <string>
00003 
00004 #include "DetectorDescription/Base/interface/DDdebug.h"
00005 #include "DetectorDescription/Base/interface/DDException.h"
00006 #include "CLHEP/Units/GlobalSystemOfUnits.h"
00007 #include<cmath>
00008 
00009 using DDI::Polyhedra;
00010 
00011 using std::fabs;
00012 using std::cos;
00013 using std::sin;
00014 
00015 Polyhedra::Polyhedra ( int sides, double startPhi, double deltaPhi,
00016               const std::vector<double> & z,
00017               const std::vector<double> & rmin,
00018               const std::vector<double> & rmax)
00019  : Solid(ddpolyhedra_rrz)             
00020 {
00021   p_.push_back(sides);
00022   p_.push_back(startPhi);
00023   p_.push_back(deltaPhi);
00024   if((z.size()!=rmin.size()) || (z.size()!=rmax.size()) )
00025   {
00026     std::string s=std::string("Polyhedra(..): std::vectors z,rmin,rmax not of same length");
00027     throw DDException(s);
00028   } 
00029   else
00030   {
00031     for(unsigned int i=0;i<z.size(); ++i)
00032     {
00033       p_.push_back(z[i]);
00034       p_.push_back(rmin[i]);
00035       p_.push_back(rmax[i]);
00036     }
00037   }
00038 }             
00039 
00040 
00041 Polyhedra::Polyhedra ( int sides, double startPhi, double deltaPhi,
00042               const std::vector<double> & z,
00043               const std::vector<double> & r)
00044  : Solid(ddpolyhedra_rz)              
00045 {
00046   p_.push_back(sides);
00047   p_.push_back(startPhi);
00048   p_.push_back(deltaPhi);
00049   if(z.size()!=r.size())
00050   {
00051     std::string s=std::string("Polyhedra(..): std::vectors z,rmin,rmax not of same length");
00052     throw DDException(s);
00053   } 
00054   else
00055   {
00056     for(unsigned int i=0;i<z.size(); ++i)
00057     {
00058       p_.push_back(z[i]);
00059       p_.push_back(r[i]);
00060     }
00061   }
00062 }            
00063  
00064 double Polyhedra::volume() const
00065 {
00066   double volume=0;
00067   /* the following assumption is made: there are at least 3 eaqual sides if there is a complete circle (this has to be done, otherwise you can not define a polygon in a circle */
00068 
00069   /* the calculation for the volume is similar as in the case of the polycone. However, the rotation is not defined as part of a circle, but as sides in a regular polygon (specified by parameter "sides"). The sides are defined betwee startPhi and endPhi and form triangles within the circle they are defined in. First we need to determine the aread of side. let alpha |startPhi-endPhi|. the half the angle of 1 side is beta=0.5*(alph/sides). If r is the raddius of the circle in which the regular polygon is defined, the are of such a side will be 0.5*(height side)*(base side)=0.5*(cos(beta)*r)*(2*sin(beta)*r)= cos(beta)sin(beta)*r*r. r is the radius that varies if we "walk" over the boundaries of the polygon that is described by the z and r values (this yields the same integral primitive as used with the Polycone. Read Polycone documentation in code first if you do not understand this */
00070 
00071   //FIXME: rz, rrz !!
00072   if (shape()==ddpolyhedra_rrz) {
00073     int loop = (p_.size()-3)/3 -1;
00074     double sec=0;
00075     double a = 0.5*fabs(p_[2]/rad / p_[0]);
00076     DCOUT('V',"Polyhedra::volume(), loop=" << loop << " alph[deg]=" << a/deg);
00077     int i=3;
00078     for (int j=3; j<(loop+3); ++j) {
00079       double dz= fabs(p_[i]-p_[i+3]);
00080       DCOUT('v', "  dz[m] =" << dz/m);
00081       /*
00082       double ai,  aii;
00083       ai  = (p_[i+2]*p_[i+2] - p_[i+1]*p_[i+1]);
00084       aii = (p_[i+5]*p_[i+5] - p_[i+4]*p_[i+4]);
00085       DCOUT('v', "  rx_i[m] =" << p_[i+2]/m << " rm_i[m] =" << p_[i+1]/m);
00086       DCOUT('v', "  rx_ii[m]=" << p_[i+5]/m << " rm_ii[m]=" << p_[i+4]/m);
00087       //double s = dz/3.*(ai*bi + 0.5*(ai*bii + bi*aii) + aii*bii);
00088       double s = dz/3.*sin(a)*cos(a)*(ai + aii + 0.5*(ai+aii));
00089       */
00090       double z=dz/2.;
00091       
00092       double H1=(p_[i+2]-p_[i+1])*cos(a);
00093       double Bl1=p_[i+1]*sin(a);
00094       double Tl1=p_[i+2]*sin(a);
00095       
00096       double H2=(p_[i+5]-p_[i+4])*cos(a);
00097       double Bl2=p_[i+4]*sin(a);
00098       double Tl2=p_[i+5]*sin(a);
00099       
00100       double s = (2*H1*Bl1+2*H1*Tl1)*z+(H1*Bl2-2*H1*Bl1+H1*Tl2-2*H1*Tl1+H2*Bl1+H2*Tl1+H2*Tl2-H2*Tl1)*z+(2/3)*(H2*Bl2-H2*Bl1-H1*Bl2+H1*Bl1-H1*Tl2+H1*Tl1)*z; 
00101       s = s*p_[0];
00102       sec += s;
00103       i+=3;
00104     }
00105     volume=sec;
00106     return volume;
00107   }  
00108  int sides=int(p_[0]);
00109  //double phiFrom=p_[1]/rad;
00110  double phiDelta=p_[2]/rad;
00111  
00112  double zBegin=0;
00113  double zEnd=0;
00114  double rBegin=0;
00115  double rEnd=0;
00116  double z=0;
00117  double alpha=0;
00118  double beta=0;
00119  unsigned int i=3;
00120 
00121  alpha=fabs(phiDelta);
00122  beta=0.5*(alpha/sides);
00123 
00124  while(i<(p_.size()-2))
00125  {
00126    zBegin=p_[i];
00127    zEnd=p_[i+2];
00128    rBegin=p_[i+1];
00129    rEnd=p_[i+3];
00130    z=zBegin-zEnd;
00131 
00132    /* volume for 1 side (we multiplie by cos(beta)sin(beta)sides later*/
00133    double volume1=(rEnd*rEnd+rBegin*rBegin+rBegin*rEnd)*z/3;
00134 
00135    volume=volume+volume1;
00136    
00137    i=i+2;
00138   }
00139 
00140   /* last line (goes from last z/r value to first */
00141 
00142   i=p_.size()-2;
00143   zBegin=p_[i];
00144   zEnd=p_[3];
00145   rBegin=p_[i+1];
00146   rEnd=p_[4];
00147   z=zBegin-zEnd;
00148 
00149   double volume2=(rEnd*rEnd+rBegin*rBegin+rBegin*rEnd)*z/3;
00150   
00151   volume=volume+volume2;
00152 
00153   volume=fabs(sides*cos(beta)*sin(beta)*volume);
00154 
00155   return volume;
00156 
00157 
00158 
00159 }