CMS 3D CMS Logo

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