71 using namespace CLHEP;
90 std::ostringstream message;
91 message <<
"Solid must have at least one side - " <<
GetName() <<
G4endl
92 <<
" No sides specified !";
93 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
102 { phiTotal =
twopi; }
103 G4double convertRad = std::cos(0.5*phiTotal/theNumSide);
119 for (i=0; i<numZPlanes; i++)
121 if (( i < numZPlanes-1) && ( zPlane[i] == zPlane[i+1] ))
123 if( (rInner[i] > rOuter[i+1])
124 ||(rInner[i+1] > rOuter[i]) )
127 std::ostringstream message;
128 message <<
"Cannot create a Polyhedra with no contiguous segments."
130 <<
" Segments are not contiguous !" <<
G4endl
131 <<
" rMin[" << i <<
"] = " << rInner[i]
132 <<
" -- rMax[" << i+1 <<
"] = " << rOuter[i+1] <<
G4endl
133 <<
" rMin[" << i+1 <<
"] = " << rInner[i+1]
134 <<
" -- rMax[" << i <<
"] = " << rOuter[i];
135 G4Exception(
"G4Polyhedra::G4Polyhedra()",
"GeomSolids0002",
150 rz->
ScaleA( 1/convertRad );
155 Create( phiStart, phiTotal, theNumSide, rz );
175 Create( phiStart, phiTotal, theNumSide, rz );
199 if (rz->
Amin() < 0.0)
201 std::ostringstream message;
202 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
203 <<
" All R values must be >= 0 !";
204 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
214 std::ostringstream message;
215 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
216 <<
" R/Z cross section is zero or near zero: " << rzArea;
217 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
224 std::ostringstream message;
225 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
226 <<
" Too few unique R/Z values !";
227 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
233 std::ostringstream message;
234 message <<
"Illegal input parameters - " <<
GetName() <<
G4endl
235 <<
" R/Z segments cross !";
236 G4Exception(
"G4Polyhedra::Create()",
"GeomSolids0002",
261 endPhi = phiStart+phiTotal;
284 next->
r = iterRZ.
GetA();
285 next->
z = iterRZ.
GetB();
286 }
while( ++next, iterRZ.
Next() );
313 if (corner->
r < 1/kInfinity && next->
r < 1/kInfinity)
continue;
338 }
while( prev=corner, corner=next, corner >
corners );
368 phiIsOpen(false), genericPgon(false), numCorner(0), corners(0),
369 original_parameters(0), enclosingCylinder(0)
401 if (
this == &source)
return *
this;
469 std::ostringstream message;
470 message <<
"Solid " <<
GetName() <<
" built using generic construct."
471 <<
G4endl <<
"Not applicable to the generic construct !";
472 G4Exception(
"G4Polyhedra::Reset()",
"GeomSolids1001",
586 G4int oldprc = os.precision(16);
587 os <<
"-----------------------------------------------------------\n"
588 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
589 <<
" ===================================================\n"
590 <<
" Solid type: G4Polyhedra\n"
593 <<
" ending phi angle : " <<
endPhi/
degree <<
" degrees \n";
598 os <<
" number of Z planes: " << numPlanes <<
"\n"
600 for (i=0; i<numPlanes; i++)
602 os <<
" Z plane " << i <<
": "
605 os <<
" Tangent distances to inner surface (Rmin): \n";
606 for (i=0; i<numPlanes; i++)
608 os <<
" Z plane " << i <<
": "
611 os <<
" Tangent distances to outer surface (Rmax): \n";
612 for (i=0; i<numPlanes; i++)
614 os <<
" Z plane " << i <<
": "
618 os <<
" number of RZ points: " <<
numCorner <<
"\n"
619 <<
" RZ values (corners): \n";
625 os <<
"-----------------------------------------------------------\n";
626 os.precision(oldprc);
640 G4double lambda1, lambda2, chose,aOne,aTwo;
650 chose = RandFlat::shoot(0.,aOne+aTwo);
651 if( (chose>=0.) && (chose < aOne) )
653 lambda1 = RandFlat::shoot(0.,1.);
654 lambda2 = RandFlat::shoot(0.,lambda1);
655 return (p2+lambda1*v+lambda2*w);
658 lambda1 = RandFlat::shoot(0.,1.);
659 lambda2 = RandFlat::shoot(0.,lambda1);
660 return (p0+lambda1*t+lambda2*u);
676 lambda1 = RandFlat::shoot(0.,1.);
677 lambda2 = RandFlat::shoot(0.,lambda1);
679 return (p2 + lambda1*w + lambda2*v);
691 G4double chose, totArea=0., Achose1, Achose2,
692 rad1, rad2, sinphi1, sinphi2, cosphi1, cosphi2;
694 area, aTop=0., aBottom=0., zVal=0.;
697 std::vector<G4double> aVector1;
698 std::vector<G4double> aVector2;
699 std::vector<G4double> aVector3;
707 for(j=0; j<numPlanes-1; j++)
713 area = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+
b)*cosksi;
714 aVector1.push_back(area);
717 for(j=0; j<numPlanes-1; j++)
723 area = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+
b)*cosksi;
724 aVector2.push_back(area);
727 for(j=0; j<numPlanes-1; j++)
738 else { aVector3.push_back(0.); }
741 for(j=0; j<numPlanes-1; j++)
743 totArea +=
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
753 aTop = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+
b)*cosksi;
761 aBottom = std::sqrt(l2-
sqr((a-b)*cosksi))*(a+
b)*cosksi;
765 Achose2 =
numSide*(aVector1[0]+aVector2[0])+2.*aVector3[0];
767 chose = RandFlat::shoot(0.,totArea+aTop+aBottom);
768 if( (chose >= 0.) && (chose < aTop + aBottom) )
771 rang = std::floor((chose-
startPhi)/ksi-0.01);
772 if(rang<0) { rang=0; }
773 rang = std::fabs(rang);
774 sinphi1 = std::sin(
startPhi+rang*ksi);
775 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
776 cosphi1 = std::cos(
startPhi+rang*ksi);
777 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
778 chose = RandFlat::shoot(0., aTop + aBottom);
779 if(chose>=0. && chose<aTop)
799 for (j=0; j<numPlanes-1; j++)
801 if( ((chose >= Achose1) && (chose < Achose2)) || (j == numPlanes-2) )
805 Achose1 +=
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
806 Achose2 = Achose1 +
numSide*(aVector1[j+1]+aVector2[j+1])
816 totArea =
numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
817 chose = RandFlat::shoot(0.,totArea);
819 if( (chose>=0.) && (chose<
numSide*aVector1[j]) )
822 rang = std::floor((chose-
startPhi)/ksi-0.01);
823 if(rang<0) { rang=0; }
824 rang = std::fabs(rang);
827 sinphi1 = std::sin(
startPhi+rang*ksi);
828 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
829 cosphi1 = std::cos(
startPhi+rang*ksi);
830 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
842 else if ( (chose >=
numSide*aVector1[j])
843 && (chose <=
numSide*(aVector1[j]+aVector2[j])) )
846 rang = std::floor((chose-
startPhi)/ksi-0.01);
847 if(rang<0) { rang=0; }
848 rang = std::fabs(rang);
851 sinphi1 = std::sin(
startPhi+rang*ksi);
852 sinphi2 = std::sin(
startPhi+(rang+1)*ksi);
853 cosphi1 = std::cos(
startPhi+rang*ksi);
854 cosphi2 = std::cos(
startPhi+(rang+1)*ksi);
867 chose = RandFlat::shoot(0.,2.2);
868 if( (chose>=0.) && (chose < 1.) )
943 typedef G4int int4[4];
950 std::vector<G4bool> chopped(
numCorner,
false);
951 std::vector<G4int*> triQuads;
954 while (remaining >= 3)
958 G4int A = -1, B = -1, C = -1;
959 G4int iStepper = iStarter;
962 if (A < 0) { A = iStepper; }
963 else if (B < 0) { B = iStepper; }
964 else if (C < 0) { C = iStepper; }
967 if (++iStepper >=
numCorner) iStepper = 0;
969 while (chopped[iStepper]);
971 while (C < 0 && iStepper != iStarter);
986 triQuads.push_back(tq);
994 if (++iStarter >=
numCorner) { iStarter = 0; }
996 while (chopped[iStarter]);
1004 faces_vec =
new int4[nFaces];
1008 for (
G4int iEnd = 0; iEnd < 2; ++iEnd)
1010 for (
size_t i = 0; i < triQuads.size(); ++i)
1023 a = triQuads[i][0] + addition;
1024 b = triQuads[i][2] + addition;
1025 c = triQuads[i][1] + addition;
1027 G4int ab = std::abs(b - a);
1028 G4int bc = std::abs(c - b);
1029 G4int ca = std::abs(a - c);
1030 faces_vec[iface][0] = (ab == 1 || ab ==
d)? a: -a;
1031 faces_vec[iface][1] = (bc == 1 || bc ==
d)? b: -b;
1032 faces_vec[iface][2] = (ca == 1 || ca ==
d)? c: -c;
1033 faces_vec[iface][3] = 0;
1040 xyz =
new double3[nNodes];
1048 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1049 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1051 if (iCorner < numCorner - 1)
1053 faces_vec[iface][0] = ixyz + 1;
1054 faces_vec[iface][1] = ixyz + numCorner + 1;
1055 faces_vec[iface][2] = ixyz + numCorner + 2;
1056 faces_vec[iface][3] = ixyz + 2;
1060 faces_vec[iface][0] = ixyz + 1;
1061 faces_vec[iface][1] = ixyz + numCorner + 1;
1062 faces_vec[iface][2] = ixyz + 2;
1063 faces_vec[iface][3] = ixyz - numCorner + 2;
1075 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1076 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1085 xyz =
new double3[nNodes];
1086 faces_vec =
new int4[nFaces];
1090 G4int ixyz = 0, iface = 0;
1095 xyz[ixyz][0] =
corners[iCorner].
r * std::cos(phi);
1096 xyz[ixyz][1] =
corners[iCorner].
r * std::sin(phi);
1098 if (iSide < numSide - 1)
1100 if (iCorner < numCorner - 1)
1102 faces_vec[iface][0] = ixyz + 1;
1103 faces_vec[iface][1] = ixyz + numCorner + 1;
1104 faces_vec[iface][2] = ixyz + numCorner + 2;
1105 faces_vec[iface][3] = ixyz + 2;
1109 faces_vec[iface][0] = ixyz + 1;
1110 faces_vec[iface][1] = ixyz + numCorner + 1;
1111 faces_vec[iface][2] = ixyz + 2;
1112 faces_vec[iface][3] = ixyz - numCorner + 2;
1117 if (iCorner < numCorner - 1)
1119 faces_vec[iface][0] = ixyz + 1;
1120 faces_vec[iface][1] = ixyz + numCorner - nFaces + 1;
1121 faces_vec[iface][2] = ixyz + numCorner - nFaces + 2;
1122 faces_vec[iface][3] = ixyz + 2;
1126 faces_vec[iface][0] = ixyz + 1;
1127 faces_vec[iface][1] = ixyz - nFaces + numCorner + 1;
1128 faces_vec[iface][2] = ixyz - nFaces + 2;
1129 faces_vec[iface][3] = ixyz - numCorner + 2;
1140 delete [] faces_vec;
1144 std::ostringstream message;
1145 message <<
"Problem creating G4Polyhedron for: " <<
GetName();
1146 G4Exception(
"G4Polyhedra::CreatePolyhedron()",
"GeomSolids1002",
1171 : Start_angle(0.), Opening_angle(0.), numSide(0), Num_z_planes(0),
1172 Z_values(0), Rmin(0), Rmax(0)
1206 if ( &right ==
this )
return *
this;