CMS 3D CMS Logo

Polyhedra.cc
Go to the documentation of this file.
3 
4 #include <cmath>
5 
10 
11 using DDI::Polyhedra;
12 
13 using std::fabs;
14 using std::cos;
15 using std::sin;
16 using namespace geant_units;
17 using namespace geant_units::operators;
18 
19 Polyhedra::Polyhedra( int sides, double startPhi, double deltaPhi,
20  const std::vector<double> & z,
21  const std::vector<double> & rmin,
22  const std::vector<double> & rmax)
24 {
25  p_.emplace_back(sides);
26  p_.emplace_back(startPhi);
27  p_.emplace_back(deltaPhi);
28  if((z.size()!=rmin.size()) || (z.size()!=rmax.size()) )
29  {
30  throw cms::Exception("DDException") << "Polyhedra(..): std::vectors z,rmin,rmax not of same length";
31  }
32  else
33  {
34  for(unsigned int i=0;i<z.size(); ++i)
35  {
36  p_.emplace_back(z[i]);
37  p_.emplace_back(rmin[i]);
38  p_.emplace_back(rmax[i]);
39  }
40  }
41 }
42 
43 Polyhedra::Polyhedra( int sides, double startPhi, double deltaPhi,
44  const std::vector<double> & z,
45  const std::vector<double> & r) : Solid(DDSolidShape::ddpolyhedra_rz)
46 {
47  p_.emplace_back(sides);
48  p_.emplace_back(startPhi);
49  p_.emplace_back(deltaPhi);
50  if(z.size()!=r.size())
51  {
52  throw cms::Exception("DDException") << "Polyhedra(..): std::vectors z,rmin,rmax not of same length";
53  }
54  else
55  {
56  for(unsigned int i=0;i<z.size(); ++i)
57  {
58  p_.emplace_back(z[i]);
59  p_.emplace_back(r[i]);
60  }
61  }
62 }
63 
64 double Polyhedra::volume() const
65 {
66  double volume = 0;
67  /* the following assumption is made:
68  there are at least 3 eaqual sides
69  if there is a complete circle (this has to be done,
70  otherwise you can not define a polygon in a circle */
71 
72  /* the calculation for the volume is similar as in
73  the case of the polycone. However, the rotation
74  is not defined as part of a circle, but as sides
75  in a regular polygon (specified by parameter "sides").
76  The sides are defined betwee startPhi and endPhi and
77  form triangles within the circle they are defined in.
78  First we need to determine the aread of side.
79  let alpha |startPhi-endPhi|.
80  the half the angle of 1 side is beta=0.5*(alph/sides).
81  If r is the raddius of the circle in which the regular polygon is defined,
82  the are of such a side will be
83  0.5*(height side)*(base side)=0.5*(cos(beta)*r)*(2*sin(beta)*r)= cos(beta)sin(beta)*r*r.
84  r is the radius that varies if we "walk" over the boundaries of
85  the polygon that is described by the z and r values
86  (this yields the same integral primitive as used with the Polycone.
87  Read Polycone documentation in code first if you do not understand this */
88 
89  //FIXME: rz, rrz !!
91  {
92  int loop = (p_.size()-3)/3 -1;
93  double sec=0;
94  double a = 0.5*fabs(p_[2] / p_[0]);
95  int i=3;
96  for (int j=3; j<(loop+3); ++j)
97  {
98  double dz= fabs(p_[i]-p_[i+3]);
99  /*
100  double ai, aii;
101  ai = (p_[i+2]*p_[i+2] - p_[i+1]*p_[i+1]);
102  aii = (p_[i+5]*p_[i+5] - p_[i+4]*p_[i+4]);
103  //double s = dz/3.*(ai*bi + 0.5*(ai*bii + bi*aii) + aii*bii);
104  double s = dz/3.*sin(a)*cos(a)*(ai + aii + 0.5*(ai+aii));
105  */
106  double z=dz/2.;
107 
108  double H1=(p_[i+2]-p_[i+1])*cos(a);
109  double Bl1=p_[i+1]*sin(a);
110  double Tl1=p_[i+2]*sin(a);
111 
112  double H2=(p_[i+5]-p_[i+4])*cos(a);
113  double Bl2=p_[i+4]*sin(a);
114  double Tl2=p_[i+5]*sin(a);
115 
116  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;
117  s = s*p_[0];
118  sec += s;
119  i+=3;
120  }
121  volume=sec;
122  return volume;
123  }
124  int sides=int(p_[0]);
125  //double phiFrom=p_[1]/rad;
126  double phiDelta=p_[2];
127 
128  double zBegin=0;
129  double zEnd=0;
130  double rBegin=0;
131  double rEnd=0;
132  double z=0;
133  double alpha=0;
134  double beta=0;
135  unsigned int i=3;
136 
137  alpha=fabs(phiDelta);
138  beta=0.5*(alpha/sides);
139 
140  while(i<(p_.size()-2))
141  {
142  zBegin=p_[i];
143  zEnd=p_[i+2];
144  rBegin=p_[i+1];
145  rEnd=p_[i+3];
146  z=zBegin-zEnd;
147 
148  /* volume for 1 side (we multiplie by cos(beta)sin(beta)sides later*/
149  double volume1=(rEnd*rEnd+rBegin*rBegin+rBegin*rEnd)*z/3;
150 
151  volume=volume+volume1;
152 
153  i=i+2;
154  }
155 
156  /* last line (goes from last z/r value to first */
157 
158  i=p_.size()-2;
159  zBegin=p_[i];
160  zEnd=p_[3];
161  rBegin=p_[i+1];
162  rEnd=p_[4];
163  z=zBegin-zEnd;
164 
165  double volume2=(rEnd*rEnd+rBegin*rBegin+rBegin*rEnd)*z/3;
166 
167  volume=volume+volume2;
168 
169  volume=fabs(sides*cos(beta)*sin(beta)*volume);
170 
171  return volume;
172 }
173 
174 void DDI::Polyhedra::stream(std::ostream & os) const
175 {
176  os << " sides=" << p_[0]
177  << " startPhi[deg]=" << convertRadToDeg( p_[1] )
178  << " dPhi[deg]=" << convertRadToDeg( p_[2] )
179  << " Sizes[cm]=";
180  for (unsigned k=3; k<p_.size(); ++k)
181  os << convertMmToCm( p_[k] ) << " ";
182 }
void stream(std::ostream &) const override
Definition: Polyhedra.cc:174
float alpha
Definition: AMPTWrapper.h:95
double volume() const override
Definition: Polyhedra.cc:64
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
DDSolidShape
Definition: DDSolidShapes.h:6
constexpr NumType convertRadToDeg(NumType radians)
Definition: GeantUnits.h:98
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
int k[5][pyjets_maxn]
Polyhedra(int sides, double startPhi, double deltaPhi, const std::vector< double > &z, const std::vector< double > &rmin, const std::vector< double > &rmax)
Definition: Polyhedra.cc:19
double a
Definition: hdecay.h:121
std::vector< double > p_
Definition: Solid.h:32
constexpr NumType convertMmToCm(NumType millimeters)
Definition: GeantUnits.h:110
DDSolidShape shape() const
Definition: Solid.h:24