Import Geant4 11.1.0.beta source tree
This commit is contained in:
@@ -705,49 +705,84 @@ G4double G4Ellipsoid::GetCubicVolume()
|
||||
|
||||
G4double G4Ellipsoid::LateralSurfaceArea() const
|
||||
{
|
||||
const G4int Nphi = 100;
|
||||
const G4int Nz = 200;
|
||||
G4double rho[Nz + 1];
|
||||
constexpr G4int NPHI = 1000.;
|
||||
constexpr G4double dPhi = CLHEP::halfpi/NPHI;
|
||||
constexpr G4double eps = 4.*DBL_EPSILON;
|
||||
|
||||
// Set array of rho
|
||||
G4double zbot = fZBottomCut / fDz;
|
||||
G4double ztop = fZTopCut / fDz;
|
||||
G4double dz = (ztop - zbot) / Nz;
|
||||
for (G4int iz = 0; iz < Nz; ++iz)
|
||||
{
|
||||
G4double z = zbot + iz * dz;
|
||||
rho[iz] = std::sqrt((1. + z) * (1. - z));
|
||||
}
|
||||
rho[Nz] = std::sqrt((1. + ztop) * (1. - ztop));
|
||||
|
||||
// Compute area
|
||||
zbot = fZBottomCut;
|
||||
ztop = fZTopCut;
|
||||
dz = (ztop - zbot) / Nz;
|
||||
G4double aa = fDx*fDx;
|
||||
G4double bb = fDy*fDy;
|
||||
G4double cc = fDz*fDz;
|
||||
G4double ab = fDx*fDy;
|
||||
G4double cc_aa = cc/aa;
|
||||
G4double cc_bb = cc/bb;
|
||||
G4double zmax = std::min(fZTopCut, fDz);
|
||||
G4double zmin = std::max(fZBottomCut,-fDz);
|
||||
G4double zmax_c = zmax/fDz;
|
||||
G4double zmin_c = zmin/fDz;
|
||||
G4double area = 0.;
|
||||
G4double dphi = CLHEP::halfpi / Nphi;
|
||||
for (G4int iphi = 0; iphi < Nphi; ++iphi)
|
||||
|
||||
if (aa == bb) // spheroid, use analytical expression
|
||||
{
|
||||
G4double phi1 = iphi * dphi;
|
||||
G4double phi2 = (iphi == Nphi - 1) ? CLHEP::halfpi : phi1 + dphi;
|
||||
G4double cos1 = std::cos(phi1) * fDx;
|
||||
G4double cos2 = std::cos(phi2) * fDx;
|
||||
G4double sin1 = std::sin(phi1) * fDy;
|
||||
G4double sin2 = std::sin(phi2) * fDy;
|
||||
for (G4int iz = 0; iz < Nz; ++iz)
|
||||
G4double k = fDz/fDx;
|
||||
G4double kk = k*k;
|
||||
if (kk < 1. - eps)
|
||||
{
|
||||
G4double z1 = zbot + iz * dz;
|
||||
G4double z2 = (iz == Nz - 1) ? ztop : z1 + dz;
|
||||
G4double rho1 = rho[iz];
|
||||
G4double rho2 = rho[iz + 1];
|
||||
G4ThreeVector p1(rho1 * cos1, rho1 * sin1, z1);
|
||||
G4ThreeVector p2(rho1 * cos2, rho1 * sin2, z1);
|
||||
G4ThreeVector p3(rho2 * cos1, rho2 * sin1, z2);
|
||||
G4ThreeVector p4(rho2 * cos2, rho2 * sin2, z2);
|
||||
area += ((p4 - p1).cross(p3 - p2)).mag();
|
||||
G4double invk = fDx/fDz;
|
||||
G4double root = std::sqrt(1. - kk);
|
||||
G4double tmax = zmax_c*root;
|
||||
G4double tmin = zmin_c*root;
|
||||
area = CLHEP::pi*ab*
|
||||
((zmax_c*std::sqrt(kk + tmax*tmax) - zmin_c*std::sqrt(kk + tmin*tmin)) +
|
||||
(std::asinh(tmax*invk) - std::asinh(tmin*invk))*kk/root);
|
||||
}
|
||||
else if (kk > 1. + eps)
|
||||
{
|
||||
G4double invk = fDx/fDz;
|
||||
G4double root = std::sqrt(kk - 1.);
|
||||
G4double tmax = zmax_c*root;
|
||||
G4double tmin = zmin_c*root;
|
||||
area = CLHEP::pi*ab*
|
||||
((zmax_c*std::sqrt(kk - tmax*tmax) - zmin_c*std::sqrt(kk - tmin*tmin)) +
|
||||
(std::asin(tmax*invk) - std::asin(tmin*invk))*kk/root);
|
||||
}
|
||||
else
|
||||
{
|
||||
area = CLHEP::twopi*fDx*(zmax - zmin);
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
// ellipsoid, integration along phi
|
||||
for (G4int i = 0; i < NPHI; ++i)
|
||||
{
|
||||
G4double sinPhi = std::sin(dPhi*(i + 0.5));
|
||||
G4double kk = cc_aa + (cc_bb - cc_aa)*sinPhi*sinPhi;
|
||||
if (kk < 1. - eps)
|
||||
{
|
||||
G4double root = std::sqrt(1. - kk);
|
||||
G4double tmax = zmax_c*root;
|
||||
G4double tmin = zmin_c*root;
|
||||
G4double invk = 1./std::sqrt(kk);
|
||||
area += 2.*ab*dPhi*
|
||||
((zmax_c*std::sqrt(kk + tmax*tmax) - zmin_c*std::sqrt(kk + tmin*tmin)) +
|
||||
(std::asinh(tmax*invk) - std::asinh(tmin*invk))*kk/root);
|
||||
}
|
||||
else if (kk > 1. + eps)
|
||||
{
|
||||
G4double root = std::sqrt(kk - 1.);
|
||||
G4double tmax = zmax_c*root;
|
||||
G4double tmin = zmin_c*root;
|
||||
G4double invk = 1./std::sqrt(kk);
|
||||
area += 2.*ab*dPhi*
|
||||
((zmax_c*std::sqrt(kk - tmax*tmax) - zmin_c*std::sqrt(kk - tmin*tmin)) +
|
||||
(std::asin(tmax*invk) - std::asin(tmin*invk))*kk/root);
|
||||
}
|
||||
else
|
||||
{
|
||||
area += 4.*ab*dPhi*(zmax_c - zmin_c);
|
||||
}
|
||||
}
|
||||
return 2. * area;
|
||||
return area;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
|
||||
#include "G4VGraphicsScene.hh"
|
||||
#include "G4Polyhedron.hh"
|
||||
#include "G4PolyhedronArbitrary.hh"
|
||||
#include "G4VisExtent.hh"
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
@@ -1318,20 +1317,19 @@ G4ThreeVector G4GenericTrap::GetPointOnSurface() const
|
||||
vertices.push_back(G4ThreeVector(fVertices[i].x(),fVertices[i].y(),fDz));
|
||||
}
|
||||
|
||||
// Surface Area of Planes(only estimation for twisted)
|
||||
// Surface Area of Planes
|
||||
//
|
||||
G4double Surface0=GetFaceSurfaceArea(vertices[0],vertices[1],
|
||||
vertices[2],vertices[3]);//-fDz plane
|
||||
G4double Surface1=GetFaceSurfaceArea(vertices[0],vertices[1],
|
||||
vertices[5],vertices[4]);// Lat plane
|
||||
G4double Surface2=GetFaceSurfaceArea(vertices[3],vertices[0],
|
||||
vertices[4],vertices[7]);// Lat plane
|
||||
G4double Surface3=GetFaceSurfaceArea(vertices[2],vertices[3],
|
||||
vertices[7],vertices[6]);// Lat plane
|
||||
G4double Surface4=GetFaceSurfaceArea(vertices[2],vertices[1],
|
||||
vertices[5],vertices[6]);// Lat plane
|
||||
G4double Surface5=GetFaceSurfaceArea(vertices[4],vertices[5],
|
||||
vertices[6],vertices[7]);// fDz plane
|
||||
G4TwoVector A = fVertices[3] - fVertices[1];
|
||||
G4TwoVector B = fVertices[2] - fVertices[0];
|
||||
G4TwoVector C = fVertices[7] - fVertices[5];
|
||||
G4TwoVector D = fVertices[6] - fVertices[4];
|
||||
G4double Surface0 = 0.5*(A.x()*B.y() - A.y()*B.x()); //-fDz plane
|
||||
G4double Surface1 = GetLateralFaceArea(0);
|
||||
G4double Surface2 = GetLateralFaceArea(1);
|
||||
G4double Surface3 = GetLateralFaceArea(2);
|
||||
G4double Surface4 = GetLateralFaceArea(3);
|
||||
G4double Surface5 = 0.5*(C.x()*D.y() - C.y()*D.x()); // fDz plane
|
||||
|
||||
rand = G4UniformRand();
|
||||
area = Surface0+Surface1+Surface2+Surface3+Surface4+Surface5;
|
||||
chose = rand*area;
|
||||
@@ -1381,130 +1379,109 @@ G4ThreeVector G4GenericTrap::GetPointOnSurface() const
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
G4double G4GenericTrap::GetSurfaceArea()
|
||||
{
|
||||
// Set vertices
|
||||
G4ThreeVector v0(fVertices[0].x(),fVertices[0].y(),-fDz);
|
||||
G4ThreeVector v1(fVertices[1].x(),fVertices[1].y(),-fDz);
|
||||
G4ThreeVector v2(fVertices[2].x(),fVertices[2].y(),-fDz);
|
||||
G4ThreeVector v3(fVertices[3].x(),fVertices[3].y(),-fDz);
|
||||
G4ThreeVector v4(fVertices[4].x(),fVertices[4].y(), fDz);
|
||||
G4ThreeVector v5(fVertices[5].x(),fVertices[5].y(), fDz);
|
||||
G4ThreeVector v6(fVertices[6].x(),fVertices[6].y(), fDz);
|
||||
G4ThreeVector v7(fVertices[7].x(),fVertices[7].y(), fDz);
|
||||
|
||||
// Find Surface Area
|
||||
if (fSurfaceArea == 0.0)
|
||||
{
|
||||
if(fIsTwisted)
|
||||
{
|
||||
fSurfaceArea = GetFaceSurfaceArea(v0,v1,v2,v3) // -fDz plane
|
||||
+ GetTwistedFaceSurfaceArea(v1,v0,v4,v5) // Lat plane
|
||||
+ GetTwistedFaceSurfaceArea(v2,v1,v5,v6) // Lat plane
|
||||
+ GetTwistedFaceSurfaceArea(v3,v2,v6,v7) // Lat plane
|
||||
+ GetTwistedFaceSurfaceArea(v0,v3,v7,v4) // Lat plane
|
||||
+ GetFaceSurfaceArea(v7,v6,v5,v4); // +fDz plane
|
||||
}
|
||||
else
|
||||
{
|
||||
fSurfaceArea = GetFaceSurfaceArea(v0,v1,v2,v3) // -fDz plane
|
||||
+ GetFaceSurfaceArea(v1,v0,v4,v5) // Lat plane
|
||||
+ GetFaceSurfaceArea(v2,v1,v5,v6) // Lat plane
|
||||
+ GetFaceSurfaceArea(v3,v2,v6,v7) // Lat plane
|
||||
+ GetFaceSurfaceArea(v0,v3,v7,v4) // Lat plane
|
||||
+ GetFaceSurfaceArea(v7,v6,v5,v4); // +fDz plane
|
||||
}
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
G4double G4GenericTrap::GetCubicVolume()
|
||||
{
|
||||
if (fCubicVolume == 0.0)
|
||||
{
|
||||
if(fIsTwisted)
|
||||
{
|
||||
fCubicVolume = G4VSolid::GetCubicVolume();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set vertices
|
||||
G4ThreeVector v0(fVertices[0].x(),fVertices[0].y(),-fDz);
|
||||
G4ThreeVector v1(fVertices[1].x(),fVertices[1].y(),-fDz);
|
||||
G4ThreeVector v2(fVertices[2].x(),fVertices[2].y(),-fDz);
|
||||
G4ThreeVector v3(fVertices[3].x(),fVertices[3].y(),-fDz);
|
||||
G4ThreeVector v4(fVertices[4].x(),fVertices[4].y(), fDz);
|
||||
G4ThreeVector v5(fVertices[5].x(),fVertices[5].y(), fDz);
|
||||
G4ThreeVector v6(fVertices[6].x(),fVertices[6].y(), fDz);
|
||||
G4ThreeVector v7(fVertices[7].x(),fVertices[7].y(), fDz);
|
||||
// diagonals
|
||||
G4TwoVector A = fVertices[3] - fVertices[1];
|
||||
G4TwoVector B = fVertices[2] - fVertices[0];
|
||||
G4TwoVector C = fVertices[7] - fVertices[5];
|
||||
G4TwoVector D = fVertices[6] - fVertices[4];
|
||||
|
||||
// Find Cubic Volume
|
||||
fCubicVolume = GetFaceCubicVolume(v0,v1,v2,v3) // -fDz plane
|
||||
+ GetFaceCubicVolume(v1,v0,v4,v5) // Lat plane
|
||||
+ GetFaceCubicVolume(v2,v1,v5,v6) // Lat plane
|
||||
+ GetFaceCubicVolume(v3,v2,v6,v7) // Lat plane
|
||||
+ GetFaceCubicVolume(v0,v3,v7,v4) // Lat plane
|
||||
+ GetFaceCubicVolume(v7,v6,v5,v4); // +fDz plane
|
||||
}
|
||||
// kross products
|
||||
G4double AB = A.x()*B.y() - A.y()*B.x();
|
||||
G4double CD = C.x()*D.y() - C.y()*D.x();
|
||||
G4double AD = A.x()*D.y() - A.y()*D.x();
|
||||
G4double CB = C.x()*B.y() - C.y()*B.x();
|
||||
|
||||
fCubicVolume = ((AB + CD)/3. + (AD + CB)/6.)*fDz;
|
||||
}
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
G4double G4GenericTrap::GetFaceSurfaceArea(const G4ThreeVector& p0,
|
||||
const G4ThreeVector& p1,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3) const
|
||||
G4double G4GenericTrap::GetLateralFaceArea(G4int iface) const
|
||||
{
|
||||
// Returns area of the facet
|
||||
return 0.5*((p2-p0).cross(p3-p1)).mag();
|
||||
}
|
||||
constexpr G4int NSTEP = 250;
|
||||
constexpr G4double dt = 1./NSTEP;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int i1 = iface, i2 = (iface + 1)%4;
|
||||
G4int i3 = i1 + 4, i4 = i2 + 4;
|
||||
|
||||
G4double
|
||||
G4GenericTrap::GetTwistedFaceSurfaceArea(const G4ThreeVector& p0,
|
||||
const G4ThreeVector& p1,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3) const
|
||||
{
|
||||
G4int nstep = 100;
|
||||
G4ThreeVector dels1 = (p1 - p0)/nstep;
|
||||
G4ThreeVector dels2 = (p2 - p3)/nstep;
|
||||
G4double area = 0;
|
||||
for (G4int is = 0; is < nstep; ++is)
|
||||
G4double x21 = fVertices[i2].x() - fVertices[i1].x();
|
||||
G4double y21 = fVertices[i2].y() - fVertices[i1].y();
|
||||
G4double x31 = fVertices[i3].x() - fVertices[i1].x();
|
||||
G4double y31 = fVertices[i3].y() - fVertices[i1].y();
|
||||
G4double x42 = fVertices[i4].x() - fVertices[i2].x();
|
||||
G4double y42 = fVertices[i4].y() - fVertices[i2].y();
|
||||
G4double x43 = fVertices[i4].x() - fVertices[i3].x();
|
||||
G4double y43 = fVertices[i4].y() - fVertices[i3].y();
|
||||
|
||||
G4double A = x21*y43 - y21*x43;
|
||||
G4double lmax = std::max(std::max(std::abs(x21),std::abs(y21)),
|
||||
std::max(std::abs(x43),std::abs(y43)));
|
||||
G4double eps = lmax*kCarTolerance;
|
||||
if (std::abs(A) < eps) // plane face
|
||||
{
|
||||
G4ThreeVector s0 = p0 + dels1*is;
|
||||
G4ThreeVector s1 = s0 + dels1;
|
||||
G4ThreeVector s3 = p3 + dels2*is;
|
||||
G4ThreeVector s2 = s3 + dels2;
|
||||
G4ThreeVector delt1 = (s3 - s0)/nstep;
|
||||
G4ThreeVector delt2 = (s2 - s1)/nstep;
|
||||
for (G4int it = 0; it < nstep; ++it)
|
||||
{
|
||||
G4ThreeVector t0 = s0 + delt1*it;
|
||||
G4ThreeVector t1 = t0 + delt1;
|
||||
G4ThreeVector t3 = s1 + delt2*it;
|
||||
G4ThreeVector t2 = t3 + delt2;
|
||||
area += 0.5*((t2-t0).cross(t3-t1)).mag();
|
||||
}
|
||||
G4ThreeVector p1(fVertices[i1].x(), fVertices[i1].y(),-fDz);
|
||||
G4ThreeVector p2(fVertices[i2].x(), fVertices[i2].y(),-fDz);
|
||||
G4ThreeVector p3(fVertices[i3].x(), fVertices[i3].y(), fDz);
|
||||
G4ThreeVector p4(fVertices[i4].x(), fVertices[i4].y(), fDz);
|
||||
return ((p4 - p1).cross(p3 - p2)).mag()*0.5;
|
||||
}
|
||||
return area;
|
||||
|
||||
// twisted face
|
||||
G4double B0 = x21*y31 - y21*x31;
|
||||
G4double B1 = x42*y31 - y42*x31;
|
||||
G4double HH = 4*fDz*fDz;
|
||||
G4double invAA = 1./(A*A);
|
||||
G4double sqrtAA = 2.*std::abs(A);
|
||||
G4double invSqrtAA = 1./sqrtAA;
|
||||
|
||||
G4double area = 0.;
|
||||
for (G4int i = 0; i < NSTEP; ++i)
|
||||
{
|
||||
G4double t = (i + 0.5)*dt;
|
||||
G4double I = y21 + (y43 - y21)*t;
|
||||
G4double J = x21 + (x43 - x21)*t;
|
||||
G4double IIJJ = HH*(I*I + J*J);
|
||||
G4double B = B1*t + B0;
|
||||
|
||||
G4double aa = A*A;
|
||||
G4double bb = 2.*A*B;
|
||||
G4double cc = IIJJ + B*B;
|
||||
|
||||
G4double R1 = std::sqrt(aa + bb + cc);
|
||||
G4double R0 = std::sqrt(cc);
|
||||
G4double log1 = std::log(std::abs(sqrtAA*R1 + 2.*aa + bb));
|
||||
G4double log0 = std::log(std::abs(sqrtAA*R0 + bb));
|
||||
|
||||
area += 0.5*R1 + 0.25*bb*invAA*(R1 - R0) + IIJJ*invSqrtAA*(log1 - log0);
|
||||
}
|
||||
return area*dt;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
G4double G4GenericTrap::GetFaceCubicVolume(const G4ThreeVector& p0,
|
||||
const G4ThreeVector& p1,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3) const
|
||||
G4double G4GenericTrap::GetSurfaceArea()
|
||||
{
|
||||
// Returns contribution of the facet to the volume of the solid.
|
||||
// Orientation of the facet is important, normal should point to outside.
|
||||
return (((p2-p0).cross(p3-p1)).dot(p0)) / 6.;
|
||||
if (fSurfaceArea == 0.0)
|
||||
{
|
||||
G4TwoVector A = fVertices[3] - fVertices[1];
|
||||
G4TwoVector B = fVertices[2] - fVertices[0];
|
||||
G4TwoVector C = fVertices[7] - fVertices[5];
|
||||
G4TwoVector D = fVertices[6] - fVertices[4];
|
||||
G4double S_bot = 0.5*(A.x()*B.y() - A.y()*B.x());
|
||||
G4double S_top = 0.5*(C.x()*D.y() - C.y()*D.x());
|
||||
fSurfaceArea = S_bot + S_top +
|
||||
GetLateralFaceArea(0) +
|
||||
GetLateralFaceArea(1) +
|
||||
GetLateralFaceArea(2) +
|
||||
GetLateralFaceArea(3);
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -2047,89 +2024,91 @@ G4Polyhedron* G4GenericTrap::CreatePolyhedron() const
|
||||
return fTessellatedSolid->CreatePolyhedron();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Approximation of Twisted Side
|
||||
// Construct extra Points, if Twisted Side
|
||||
//
|
||||
G4PolyhedronArbitrary* polyhedron;
|
||||
G4Polyhedron* polyhedron;
|
||||
size_t nVertices, nFacets;
|
||||
|
||||
G4int subdivisions=0;
|
||||
G4int i;
|
||||
if(fIsTwisted)
|
||||
G4int subdivisions = 0;
|
||||
if (fIsTwisted)
|
||||
{
|
||||
if ( GetVisSubdivisions()!= 0 )
|
||||
if (GetVisSubdivisions() != 0)
|
||||
{
|
||||
subdivisions=GetVisSubdivisions();
|
||||
subdivisions = GetVisSubdivisions();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Estimation of Number of Subdivisions for smooth visualisation
|
||||
//
|
||||
G4double maxTwist=0.;
|
||||
for(i=0; i<4; ++i)
|
||||
G4double maxTwist = 0.;
|
||||
for(G4int i = 0; i < 4; ++i)
|
||||
{
|
||||
if(GetTwistAngle(i)>maxTwist) { maxTwist=GetTwistAngle(i); }
|
||||
if (GetTwistAngle(i) > maxTwist) { maxTwist = GetTwistAngle(i); }
|
||||
}
|
||||
|
||||
// Computes bounding vectors for the shape
|
||||
//
|
||||
G4double Dx,Dy;
|
||||
G4double Dx, Dy;
|
||||
G4ThreeVector minVec = GetMinimumBBox();
|
||||
G4ThreeVector maxVec = GetMaximumBBox();
|
||||
Dx = 0.5*(maxVec.x()- minVec.y());
|
||||
Dy = 0.5*(maxVec.y()- minVec.y());
|
||||
if (Dy > Dx) { Dx=Dy; }
|
||||
|
||||
subdivisions=8*G4int(maxTwist/(Dx*Dx*Dx)*fDz);
|
||||
if (subdivisions<4) { subdivisions=4; }
|
||||
if (subdivisions>30) { subdivisions=30; }
|
||||
Dx = 0.5*(maxVec.x() - minVec.y());
|
||||
Dy = 0.5*(maxVec.y() - minVec.y());
|
||||
if (Dy > Dx) { Dx = Dy; }
|
||||
|
||||
subdivisions = 8*G4int(maxTwist/(Dx*Dx*Dx)*fDz);
|
||||
if (subdivisions < 4) { subdivisions = 4; }
|
||||
if (subdivisions > 30) { subdivisions = 30; }
|
||||
}
|
||||
}
|
||||
G4int sub4=4*subdivisions;
|
||||
nVertices = 8+subdivisions*4;
|
||||
nFacets = 6+subdivisions*4;
|
||||
G4double cf=1./(subdivisions+1);
|
||||
polyhedron = new G4PolyhedronArbitrary (nVertices, nFacets);
|
||||
G4int sub4 = 4*subdivisions;
|
||||
nVertices = 8 + subdivisions*4;
|
||||
nFacets = 6 + subdivisions*4;
|
||||
G4double cf = 1./(subdivisions + 1);
|
||||
polyhedron = new G4Polyhedron(nVertices, nFacets);
|
||||
|
||||
// Add Vertex
|
||||
// Set vertices
|
||||
//
|
||||
for (i=0; i<4; ++i)
|
||||
G4int icur = 0;
|
||||
for (G4int i = 0; i < 4; ++i)
|
||||
{
|
||||
polyhedron->AddVertex(G4ThreeVector(fVertices[i].x(),
|
||||
fVertices[i].y(),-fDz));
|
||||
G4ThreeVector v(fVertices[i].x(),fVertices[i].y(),-fDz);
|
||||
polyhedron->SetVertex(++icur, v);
|
||||
}
|
||||
for( i=0; i<subdivisions; ++i)
|
||||
for (G4int i = 0; i < subdivisions; ++i)
|
||||
{
|
||||
for(G4int j=0;j<4;j++)
|
||||
for (G4int j = 0; j < 4; ++j)
|
||||
{
|
||||
G4TwoVector u=fVertices[j]+cf*(i+1)*( fVertices[j+4]-fVertices[j]);
|
||||
polyhedron->AddVertex(G4ThreeVector(u.x(),u.y(),-fDz+cf*2*fDz*(i+1)));
|
||||
}
|
||||
G4TwoVector u = fVertices[j]+cf*(i+1)*(fVertices[j+4]-fVertices[j]);
|
||||
G4ThreeVector v(u.x(),u.y(),-fDz+cf*2*fDz*(i+1));
|
||||
polyhedron->SetVertex(++icur, v);
|
||||
}
|
||||
}
|
||||
for (i=4; i<8; ++i)
|
||||
for (G4int i = 4; i < 8; ++i)
|
||||
{
|
||||
polyhedron->AddVertex(G4ThreeVector(fVertices[i].x(),
|
||||
fVertices[i].y(),fDz));
|
||||
G4ThreeVector v(fVertices[i].x(),fVertices[i].y(),fDz);
|
||||
polyhedron->SetVertex(++icur, v);
|
||||
}
|
||||
|
||||
// Add Facets
|
||||
// Set facets
|
||||
//
|
||||
polyhedron->AddFacet(1,4,3,2); //Z-plane
|
||||
for (i=0; i<subdivisions+1; ++i)
|
||||
icur = 0;
|
||||
polyhedron->SetFacet(++icur, 1, 4, 3, 2); // Z-plane
|
||||
for (G4int i = 0; i < subdivisions + 1; ++i)
|
||||
{
|
||||
G4int is=i*4;
|
||||
polyhedron->AddFacet(5+is,8+is,4+is,1+is);
|
||||
polyhedron->AddFacet(8+is,7+is,3+is,4+is);
|
||||
polyhedron->AddFacet(7+is,6+is,2+is,3+is);
|
||||
polyhedron->AddFacet(6+is,5+is,1+is,2+is);
|
||||
G4int is = i*4;
|
||||
polyhedron->SetFacet(++icur, 5+is, 8+is, 4+is, 1+is);
|
||||
polyhedron->SetFacet(++icur, 8+is, 7+is, 3+is, 4+is);
|
||||
polyhedron->SetFacet(++icur, 7+is, 6+is, 2+is, 3+is);
|
||||
polyhedron->SetFacet(++icur, 6+is, 5+is, 1+is, 2+is);
|
||||
}
|
||||
polyhedron->AddFacet(5+sub4,6+sub4,7+sub4,8+sub4); //Z-plane
|
||||
polyhedron->SetFacet(++icur, 5+sub4, 6+sub4, 7+sub4, 8+sub4); // Z-plane
|
||||
|
||||
polyhedron->SetReferences();
|
||||
polyhedron->InvertFacets();
|
||||
|
||||
return (G4Polyhedron*) polyhedron;
|
||||
return polyhedron;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -1080,8 +1080,11 @@ G4VSolid* G4Hype::Clone() const
|
||||
//
|
||||
G4double G4Hype::GetCubicVolume()
|
||||
{
|
||||
if(fCubicVolume != 0.) {;}
|
||||
else { fCubicVolume = G4VSolid::GetCubicVolume(); }
|
||||
if (fCubicVolume == 0.)
|
||||
{
|
||||
fCubicVolume = CLHEP::twopi*halfLenZ*
|
||||
(2.*(outerRadius2 - innerRadius2) + endOuterRadius2 - endInnerRadius2)/3.;
|
||||
}
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
@@ -1089,8 +1092,33 @@ G4double G4Hype::GetCubicVolume()
|
||||
//
|
||||
G4double G4Hype::GetSurfaceArea()
|
||||
{
|
||||
if(fSurfaceArea != 0.) {;}
|
||||
else { fSurfaceArea = G4VSolid::GetSurfaceArea(); }
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
G4double h = halfLenZ;
|
||||
G4double innS = 2.*h*innerRadius;
|
||||
if (std::abs(endInnerRadius - innerRadius) > kCarTolerance)
|
||||
{
|
||||
G4double A = innerRadius;
|
||||
G4double AA = innerRadius2;
|
||||
G4double RR = endInnerRadius2;
|
||||
G4double CC = AA*h*h/(RR - AA);
|
||||
G4double K = std::sqrt(AA + CC)/CC;
|
||||
G4double Kh = K*h;
|
||||
innS = A*(h*std::sqrt(1. + Kh*Kh) + std::asinh(Kh)/K);
|
||||
}
|
||||
G4double outS = 2.*h*outerRadius;
|
||||
if (std::abs(endOuterRadius - outerRadius) > kCarTolerance)
|
||||
{
|
||||
G4double A = outerRadius;
|
||||
G4double AA = outerRadius2;
|
||||
G4double RR = endOuterRadius2;
|
||||
G4double CC = AA*h*h/(RR - AA);
|
||||
G4double K = std::sqrt(AA + CC)/CC;
|
||||
G4double Kh = K*h;
|
||||
outS = A*(h*std::sqrt(1. + Kh*Kh) + std::asinh(Kh)/K);
|
||||
}
|
||||
fSurfaceArea = CLHEP::twopi*(endOuterRadius2 - endInnerRadius2 + innS + outS);
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
|
||||
#include "G4PolyhedronArbitrary.hh"
|
||||
#include "G4VGraphicsScene.hh"
|
||||
#include "G4VisExtent.hh"
|
||||
|
||||
@@ -1925,34 +1924,31 @@ void G4TessellatedSolid::DescribeYourselfTo (G4VGraphicsScene& scene) const
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4Polyhedron *G4TessellatedSolid::CreatePolyhedron () const
|
||||
G4Polyhedron* G4TessellatedSolid::CreatePolyhedron () const
|
||||
{
|
||||
G4int nVertices = fVertexList.size();
|
||||
G4int nFacets = fFacets.size();
|
||||
G4PolyhedronArbitrary* polyhedron =
|
||||
new G4PolyhedronArbitrary (nVertices, nFacets);
|
||||
for (auto v= fVertexList.cbegin(); v!=fVertexList.cend(); ++v)
|
||||
G4int nFacets = fFacets.size();
|
||||
G4Polyhedron* polyhedron = new G4Polyhedron(nVertices, nFacets);
|
||||
for (G4int i = 0; i < nVertices; ++i)
|
||||
{
|
||||
polyhedron->AddVertex(*v);
|
||||
polyhedron->SetVertex(i+1, fVertexList[i]);
|
||||
}
|
||||
|
||||
G4int size = fFacets.size();
|
||||
for (G4int i = 0; i < size; ++i)
|
||||
for (G4int i = 0; i < nFacets; ++i)
|
||||
{
|
||||
G4VFacet* facet = fFacets[i];
|
||||
G4int v[4] = {0};
|
||||
G4int n = facet->GetNumberOfVertices();
|
||||
if (n > 4) n = 4;
|
||||
for (G4int j=0; j<n; ++j)
|
||||
for (G4int j = 0; j < n; ++j)
|
||||
{
|
||||
G4int k = facet->GetVertexIndex(j);
|
||||
v[j] = k+1;
|
||||
v[j] = facet->GetVertexIndex(j) + 1;
|
||||
}
|
||||
polyhedron->AddFacet(v[0],v[1],v[2],v[3]);
|
||||
polyhedron->SetFacet(i+1, v[0], v[1], v[2], v[3]);
|
||||
}
|
||||
polyhedron->SetReferences();
|
||||
|
||||
return (G4Polyhedron*) polyhedron;
|
||||
return polyhedron;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
|
||||
G4TwistedBox::G4TwistedBox( const G4String& pName,
|
||||
G4double pPhiTwist,
|
||||
G4double pDx,
|
||||
G4double pDy,
|
||||
G4double pDx,
|
||||
G4double pDy,
|
||||
G4double pDz )
|
||||
: G4VTwistedFaceted( pName, pPhiTwist,pDz,0.,0.,
|
||||
pDy, pDx, pDx, pDy, pDx, pDx,0. )
|
||||
@@ -73,7 +73,7 @@ G4TwistedBox::G4TwistedBox(const G4TwistedBox& rhs)
|
||||
//=====================================================================
|
||||
//* Assignment operator -----------------------------------------------
|
||||
|
||||
G4TwistedBox& G4TwistedBox::operator = (const G4TwistedBox& rhs)
|
||||
G4TwistedBox& G4TwistedBox::operator = (const G4TwistedBox& rhs)
|
||||
{
|
||||
// Check assignment to self
|
||||
//
|
||||
@@ -103,7 +103,7 @@ std::ostream& G4TwistedBox::StreamInfo(std::ostream& os) const
|
||||
<< " pDx = " << GetXHalfLength()/cm << " cm" << G4endl
|
||||
<< " pDy = " << GetYHalfLength()/cm << " cm" << G4endl
|
||||
<< " pDz = " << GetZHalfLength()/cm << " cm" << G4endl
|
||||
<< " pPhiTwist = " << GetPhiTwist()/degree << " deg" << G4endl
|
||||
<< " pPhiTwist = " << GetPhiTwist()/degree << " deg" << G4endl
|
||||
<< "-----------------------------------------------------------\n";
|
||||
|
||||
return os;
|
||||
@@ -124,3 +124,44 @@ G4VSolid* G4TwistedBox::Clone() const
|
||||
{
|
||||
return new G4TwistedBox(*this);
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetCubicVolume ----------------------------------------------------
|
||||
|
||||
double G4TwistedBox::GetCubicVolume()
|
||||
{
|
||||
if (fCubicVolume == 0.)
|
||||
{
|
||||
fCubicVolume = 8.*GetXHalfLength()*GetYHalfLength()*GetZHalfLength();
|
||||
}
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetSurfaceArea ----------------------------------------------------
|
||||
|
||||
double G4TwistedBox::GetSurfaceArea()
|
||||
{
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
G4double ang = GetPhiTwist();
|
||||
G4double dx = GetXHalfLength();
|
||||
G4double dy = GetYHalfLength();
|
||||
G4double dz = GetZHalfLength();
|
||||
if (ang == 0.)
|
||||
{
|
||||
fSurfaceArea = 8.*(dx*dy + dx*dz + dy*dz);
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double h = 2.*dz;
|
||||
G4double hh = h*h;
|
||||
G4double dxang = dx*ang;
|
||||
G4double dyang = dy*ang;
|
||||
fSurfaceArea = 8.*dx*dy +
|
||||
2.*(dx*std::sqrt(hh + dxang*dxang) + hh*std::asinh(dxang/h)/ang) +
|
||||
2.*(dy*std::sqrt(hh + dyang*dyang) + hh*std::asinh(dyang/h)/ang);
|
||||
}
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
//* Constructor -------------------------------------------------------
|
||||
|
||||
G4TwistedTrd::G4TwistedTrd( const G4String& pName,
|
||||
G4double pDx1,
|
||||
G4double pDx1,
|
||||
G4double pDx2,
|
||||
G4double pDy1,
|
||||
G4double pDy1,
|
||||
G4double pDy2,
|
||||
G4double pDz,
|
||||
G4double pPhiTwist )
|
||||
@@ -75,7 +75,7 @@ G4TwistedTrd::G4TwistedTrd(const G4TwistedTrd& rhs)
|
||||
//=====================================================================
|
||||
//* Assignment operator -----------------------------------------------
|
||||
|
||||
G4TwistedTrd& G4TwistedTrd::operator = (const G4TwistedTrd& rhs)
|
||||
G4TwistedTrd& G4TwistedTrd::operator = (const G4TwistedTrd& rhs)
|
||||
{
|
||||
// Check assignment to self
|
||||
//
|
||||
@@ -107,7 +107,7 @@ std::ostream& G4TwistedTrd::StreamInfo(std::ostream& os) const
|
||||
<< " pDy1 = " << GetY1HalfLength()/cm << " cm" << G4endl
|
||||
<< " pDy2 = " << GetY2HalfLength()/cm << " cm" << G4endl
|
||||
<< " pDz = " << GetZHalfLength()/cm << " cm" << G4endl
|
||||
<< " pPhiTwist = " << GetPhiTwist()/degree << " deg" << G4endl
|
||||
<< " pPhiTwist = " << GetPhiTwist()/degree << " deg" << G4endl
|
||||
<< "-----------------------------------------------------------\n";
|
||||
|
||||
return os;
|
||||
@@ -128,3 +128,101 @@ G4VSolid* G4TwistedTrd::Clone() const
|
||||
{
|
||||
return new G4TwistedTrd(*this);
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetCubicVolume ----------------------------------------------------
|
||||
|
||||
double G4TwistedTrd::GetCubicVolume()
|
||||
{
|
||||
if (fCubicVolume == 0.)
|
||||
{
|
||||
G4double x1 = GetX1HalfLength();
|
||||
G4double x2 = GetX2HalfLength();
|
||||
G4double y1 = GetY1HalfLength();
|
||||
G4double y2 = GetY2HalfLength();
|
||||
G4double h = 2.*GetZHalfLength();
|
||||
fCubicVolume = h*((x1 + x2)*(y1 + y2) + (x2 - x1)*(y2 - y1)/3.);
|
||||
}
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetSurfaceArea ----------------------------------------------------
|
||||
|
||||
double G4TwistedTrd::GetSurfaceArea()
|
||||
{
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
G4double ang = GetPhiTwist();
|
||||
G4double x1 = GetX1HalfLength();
|
||||
G4double x2 = GetX2HalfLength();
|
||||
G4double y1 = GetY1HalfLength();
|
||||
G4double y2 = GetY2HalfLength();
|
||||
G4double h = 2.*GetZHalfLength();
|
||||
G4double hh = h*h;
|
||||
G4double delX = x2 - x1;
|
||||
G4double delY = y2 - y1;
|
||||
if (ang == 0.)
|
||||
{
|
||||
G4double hx = std::sqrt(delY*delY + hh);
|
||||
G4double hy = std::sqrt(delX*delX + hh);
|
||||
return fSurfaceArea =
|
||||
2.*(x1 + x2)*hx + 2.*(y1 + y2)*hy + 4.*(x1*y1 + x2*y2);
|
||||
}
|
||||
|
||||
// compute area of x-faces
|
||||
G4double U1, U2, V1, V2;
|
||||
G4double areaX = 0.;
|
||||
U1 = delY + x1*ang;
|
||||
U2 = delY + x2*ang;
|
||||
V1 = delY - x1*ang;
|
||||
V2 = delY - x2*ang;
|
||||
if (std::abs(delX) < kCarTolerance) // case x1 == x2
|
||||
{
|
||||
areaX = (U1*std::sqrt(hh + U1*U1) + hh*std::asinh(U1/h) -
|
||||
V1*std::sqrt(hh + V1*V1) - hh*std::asinh(V1/h))/ang;
|
||||
}
|
||||
else
|
||||
{
|
||||
// U contribution
|
||||
areaX += ((hh + U2*U2)*std::sqrt(hh + U2*U2) -
|
||||
(hh + U1*U1)*std::sqrt(hh + U1*U1))/3.
|
||||
+ hh*(U2*std::asinh(U2/h) - U1*std::asinh(U1/h))
|
||||
- hh*(std::sqrt(hh + U2*U2) - std::sqrt(hh + U1*U1));
|
||||
// V contribution
|
||||
areaX += ((hh + V2*V2)*std::sqrt(hh + V2*V2) -
|
||||
(hh + V1*V1)*std::sqrt(hh + V1*V1))/3.
|
||||
+ hh*(V2*std::asinh(V2/h) - V1*std::asinh(V1/h))
|
||||
- hh*(std::sqrt(hh + V2*V2) - std::sqrt(hh + V1*V1));
|
||||
areaX /= delX*ang*ang;
|
||||
}
|
||||
|
||||
// compute area of y-faces
|
||||
G4double areaY = 0.;
|
||||
U1 = delX + y1*ang;
|
||||
U2 = delX + y2*ang;
|
||||
V1 = delX - y1*ang;
|
||||
V2 = delX - y2*ang;
|
||||
if (std::abs(delY) < kCarTolerance) // case y1 == y2
|
||||
{
|
||||
areaY = (U1*std::sqrt(hh + U1*U1) + hh*std::asinh(U1/h) -
|
||||
V1*std::sqrt(hh + V1*V1) - hh*std::asinh(V1/h))/ang;
|
||||
}
|
||||
else
|
||||
{
|
||||
// U contribution
|
||||
areaY += ((hh + U2*U2)*std::sqrt(hh + U2*U2) -
|
||||
(hh + U1*U1)*std::sqrt(hh + U1*U1))/3.
|
||||
+ hh*(U2*std::asinh(U2/h) - U1*std::asinh(U1/h))
|
||||
- hh*(std::sqrt(hh + U2*U2) - std::sqrt(hh + U1*U1));
|
||||
// V contribution
|
||||
areaY += ((hh + V2*V2)*std::sqrt(hh + V2*V2) -
|
||||
(hh + V1*V1)*std::sqrt(hh + V1*V1))/3.
|
||||
+ hh*(V2*std::asinh(V2/h) - V1*std::asinh(V1/h))
|
||||
- hh*(std::sqrt(hh + V2*V2) - std::sqrt(hh + V1*V1));
|
||||
areaY /= delY*ang*ang;
|
||||
}
|
||||
fSurfaceArea = areaX + areaY + 4.*(x1*y1 + x2*y2);
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
@@ -1050,12 +1050,94 @@ G4double G4TwistedTubs::GetCubicVolume()
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetLateralArea ----------------------------------------------------
|
||||
|
||||
G4double
|
||||
G4TwistedTubs::GetLateralArea(G4double a, G4double r, G4double z) const
|
||||
{
|
||||
if (z == 0) return 0.;
|
||||
G4double h = std::abs(z);
|
||||
G4double area = h*a;
|
||||
if (std::abs(a - r) > kCarTolerance)
|
||||
{
|
||||
G4double aa = a*a;
|
||||
G4double hh = h*h;
|
||||
G4double rr = r*r;
|
||||
G4double cc = aa*hh/(rr - aa);
|
||||
G4double k = std::sqrt(aa + cc)/cc;
|
||||
G4double kh = k*h;
|
||||
area = 0.5*a*(h*std::sqrt(1. + kh*kh) + std::asinh(kh)/k);
|
||||
}
|
||||
return GetDPhi()*area;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetPhiCutArea -----------------------------------------------------
|
||||
|
||||
G4double
|
||||
G4TwistedTubs::GetPhiCutArea(G4double a, G4double r, G4double z) const
|
||||
{
|
||||
if (GetDPhi() >= CLHEP::twopi || r <= 0 || z == 0) return 0.;
|
||||
G4double h = std::abs(z);
|
||||
G4double area = h*a;
|
||||
if (GetPhiTwist() > kCarTolerance)
|
||||
{
|
||||
G4double sinw = std::sin(0.5*GetPhiTwist())*h/GetZHalfLength();
|
||||
G4double p = sinw*r/h;
|
||||
G4double q = sinw*r/a;
|
||||
G4double pp = p*p;
|
||||
G4double qq = q*q;
|
||||
G4double pq = p*q;
|
||||
G4double sqroot = std::sqrt(pp + qq + 1);
|
||||
area = (pq*sqroot +
|
||||
0.5*p*(pp + 3.)*std::atanh(q/sqroot) +
|
||||
0.5*q*(qq + 3.)*std::atanh(p/sqroot) +
|
||||
std::atan(sqroot/(pq)) - CLHEP::halfpi)*h*a/(3.*pq);
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetSurfaceArea ----------------------------------------------------
|
||||
|
||||
G4double G4TwistedTubs::GetSurfaceArea()
|
||||
{
|
||||
if (fSurfaceArea == 0.) fSurfaceArea = G4VSolid::GetSurfaceArea();
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
G4double dphi = GetDPhi();
|
||||
G4double Ainn = GetInnerRadius();
|
||||
G4double Aout = GetOuterRadius();
|
||||
G4double Rinn0 = GetEndInnerRadius(0);
|
||||
G4double Rout0 = GetEndOuterRadius(0);
|
||||
G4double Rinn1 = GetEndInnerRadius(1);
|
||||
G4double Rout1 = GetEndOuterRadius(1);
|
||||
G4double z0 = GetEndZ(0);
|
||||
G4double z1 = GetEndZ(1);
|
||||
|
||||
G4double base0 = 0.5*dphi*(Rout0*Rout0 - Rinn0*Rinn0); // lower base
|
||||
G4double inner0 = GetLateralArea(Ainn, Rinn0, z0); // lower inner surface
|
||||
G4double outer0 = GetLateralArea(Aout, Rout0, z0); // lower outer surface
|
||||
G4double cut0 = // lower phi cut
|
||||
GetPhiCutArea(Aout, Rout0, z0) - GetPhiCutArea(Ainn, Rinn0, z0);
|
||||
|
||||
G4double base1 = base0;
|
||||
G4double inner1 = inner0;
|
||||
G4double outer1 = outer0;
|
||||
G4double cut1 = cut0;
|
||||
if (std::abs(z0) != std::abs(z1))
|
||||
{
|
||||
base1 = 0.5*dphi*(Rout1*Rout1 - Rinn1*Rinn1); // upper base
|
||||
inner1 = GetLateralArea(Ainn, Rinn1, z1); // upper inner surface
|
||||
outer1 = GetLateralArea(Aout, Rout1, z1); // upper outer surface
|
||||
cut1 = // upper phi cut
|
||||
GetPhiCutArea(Aout, Rout1, z1) - GetPhiCutArea(Ainn, Rinn1, z1);
|
||||
}
|
||||
fSurfaceArea = base0 + base1 +
|
||||
((z0*z1 < 0) ?
|
||||
(inner0 + inner1 + outer0 + outer1 + 2.*(cut0 + cut1)) :
|
||||
std::abs(inner0 - inner1 + outer0 - outer1 + 2.*(cut0 - cut1)));
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,8 +37,6 @@
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
|
||||
#include "G4PolyhedronArbitrary.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructors
|
||||
@@ -382,14 +380,13 @@ G4Polyhedron* G4UExtrudedSolid::CreatePolyhedron () const
|
||||
unsigned int nFacets = Base_t::GetStruct().fTslHelper.fFacets.size();
|
||||
unsigned int nVertices = Base_t::GetStruct().fTslHelper.fVertices.size();
|
||||
|
||||
G4PolyhedronArbitrary* polyhedron =
|
||||
new G4PolyhedronArbitrary (nVertices, nFacets);
|
||||
G4Polyhedron* polyhedron = new G4Polyhedron(nVertices, nFacets);
|
||||
|
||||
// Copy vertices
|
||||
for (unsigned int i = 0; i < nVertices; ++i)
|
||||
{
|
||||
U3Vector v = Base_t::GetStruct().fTslHelper.fVertices[i];
|
||||
polyhedron->AddVertex(G4ThreeVector(v.x(), v.y(), v.z()));
|
||||
polyhedron->SetVertex(i+1, G4ThreeVector(v.x(), v.y(), v.z()));
|
||||
}
|
||||
|
||||
// Copy facets
|
||||
@@ -399,11 +396,11 @@ G4Polyhedron* G4UExtrudedSolid::CreatePolyhedron () const
|
||||
G4int i1 = Base_t::GetStruct().fTslHelper.fFacets[i]->fIndices[0] + 1;
|
||||
G4int i2 = Base_t::GetStruct().fTslHelper.fFacets[i]->fIndices[1] + 1;
|
||||
G4int i3 = Base_t::GetStruct().fTslHelper.fFacets[i]->fIndices[2] + 1;
|
||||
polyhedron->AddFacet(i1, i2, i3);
|
||||
polyhedron->SetFacet(i+1, i1, i2, i3);
|
||||
}
|
||||
polyhedron->SetReferences();
|
||||
|
||||
return (G4Polyhedron*) polyhedron;
|
||||
return polyhedron;
|
||||
}
|
||||
|
||||
#endif // G4GEOM_USE_USOLIDS
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
|
||||
#include "G4Polyhedron.hh"
|
||||
#include "G4PolyhedronArbitrary.hh"
|
||||
|
||||
using namespace CLHEP;
|
||||
|
||||
@@ -256,86 +255,88 @@ G4Polyhedron* G4UGenericTrap::CreatePolyhedron() const
|
||||
// Approximation of Twisted Side
|
||||
// Construct extra Points, if Twisted Side
|
||||
//
|
||||
G4PolyhedronArbitrary* polyhedron;
|
||||
G4Polyhedron* polyhedron;
|
||||
size_t nVertices, nFacets;
|
||||
G4double fDz = GetZHalfLength();
|
||||
|
||||
G4int subdivisions=0;
|
||||
G4int i;
|
||||
if(IsTwisted())
|
||||
G4int subdivisions = 0;
|
||||
if (IsTwisted())
|
||||
{
|
||||
if ( GetVisSubdivisions() != 0 )
|
||||
if (GetVisSubdivisions() != 0)
|
||||
{
|
||||
subdivisions=GetVisSubdivisions();
|
||||
subdivisions = GetVisSubdivisions();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Estimation of Number of Subdivisions for smooth visualisation
|
||||
//
|
||||
G4double maxTwist=0.;
|
||||
for(i=0; i<4; ++i)
|
||||
G4double maxTwist = 0.;
|
||||
for(G4int i = 0; i < 4; ++i)
|
||||
{
|
||||
if(GetTwistAngle(i)>maxTwist) { maxTwist=GetTwistAngle(i); }
|
||||
if (GetTwistAngle(i) > maxTwist) { maxTwist = GetTwistAngle(i); }
|
||||
}
|
||||
|
||||
// Computes bounding vectors for the shape
|
||||
//
|
||||
G4double Dx,Dy;
|
||||
G4double Dx, Dy;
|
||||
G4ThreeVector minVec, maxVec;
|
||||
BoundingLimits(minVec,maxVec);
|
||||
Dx = 0.5*(maxVec.x()- minVec.y());
|
||||
Dy = 0.5*(maxVec.y()- minVec.y());
|
||||
if (Dy > Dx) { Dx=Dy; }
|
||||
|
||||
subdivisions=8*G4int(maxTwist/(Dx*Dx*Dx)*fDz);
|
||||
if (subdivisions<4) { subdivisions=4; }
|
||||
if (subdivisions>30) { subdivisions=30; }
|
||||
BoundingLimits(minVec, maxVec);
|
||||
Dx = 0.5*(maxVec.x() - minVec.y());
|
||||
Dy = 0.5*(maxVec.y() - minVec.y());
|
||||
if (Dy > Dx) { Dx = Dy; }
|
||||
|
||||
subdivisions = 8*G4int(maxTwist/(Dx*Dx*Dx)*fDz);
|
||||
if (subdivisions < 4) { subdivisions = 4; }
|
||||
if (subdivisions > 30) { subdivisions = 30; }
|
||||
}
|
||||
}
|
||||
G4int sub4=4*subdivisions;
|
||||
nVertices = 8+subdivisions*4;
|
||||
nFacets = 6+subdivisions*4;
|
||||
G4double cf=1./(subdivisions+1);
|
||||
polyhedron = new G4PolyhedronArbitrary (nVertices, nFacets);
|
||||
G4int sub4 = 4*subdivisions;
|
||||
nVertices = 8 + subdivisions*4;
|
||||
nFacets = 6 + subdivisions*4;
|
||||
G4double cf = 1./(subdivisions + 1);
|
||||
polyhedron = new G4Polyhedron(nVertices, nFacets);
|
||||
|
||||
// Add Vertex
|
||||
// Set vertices
|
||||
//
|
||||
for (i=0; i<4; ++i)
|
||||
G4int icur = 0;
|
||||
for (G4int i = 0; i < 4; ++i)
|
||||
{
|
||||
polyhedron->AddVertex(G4ThreeVector(GetVertex(i).x(),
|
||||
GetVertex(i).y(),-fDz));
|
||||
G4ThreeVector v(GetVertex(i).x(),GetVertex(i).y(),-fDz);
|
||||
polyhedron->SetVertex(++icur, v);
|
||||
}
|
||||
for(i=0; i<subdivisions; ++i)
|
||||
for (G4int i = 0; i < subdivisions; ++i)
|
||||
{
|
||||
for(G4int j=0; j<4 ; ++j)
|
||||
for (G4int j = 0; j < 4; ++j)
|
||||
{
|
||||
G4TwoVector u=GetVertex(j)+cf*(i+1)*( GetVertex(j+4)-GetVertex(j));
|
||||
polyhedron->AddVertex(G4ThreeVector(u.x(),u.y(),-fDz+cf*2*fDz*(i+1)));
|
||||
}
|
||||
G4TwoVector u = GetVertex(j)+cf*(i+1)*( GetVertex(j+4)-GetVertex(j));
|
||||
G4ThreeVector v(u.x(),u.y(),-fDz+cf*2*fDz*(i+1));
|
||||
polyhedron->SetVertex(++icur, v);
|
||||
}
|
||||
}
|
||||
for (i=4; i<8; ++i)
|
||||
for (G4int i = 4; i < 8; ++i)
|
||||
{
|
||||
polyhedron->AddVertex(G4ThreeVector(GetVertex(i).x(),
|
||||
GetVertex(i).y(),fDz));
|
||||
G4ThreeVector v(GetVertex(i).x(),GetVertex(i).y(),fDz);
|
||||
polyhedron->SetVertex(++icur, v);
|
||||
}
|
||||
|
||||
// Add Facets
|
||||
// Set facets
|
||||
//
|
||||
polyhedron->AddFacet(1,4,3,2); //Z-plane
|
||||
for (i=0; i<subdivisions+1; ++i)
|
||||
icur = 0;
|
||||
polyhedron->SetFacet(++icur, 1, 4, 3, 2); // Z-plane
|
||||
for (G4int i = 0; i < subdivisions + 1; ++i)
|
||||
{
|
||||
G4int is=i*4;
|
||||
polyhedron->AddFacet(5+is,8+is,4+is,1+is);
|
||||
polyhedron->AddFacet(8+is,7+is,3+is,4+is);
|
||||
polyhedron->AddFacet(7+is,6+is,2+is,3+is);
|
||||
polyhedron->AddFacet(6+is,5+is,1+is,2+is);
|
||||
G4int is = i*4;
|
||||
polyhedron->SetFacet(++icur, 5+is, 8+is, 4+is, 1+is);
|
||||
polyhedron->SetFacet(++icur, 8+is, 7+is, 3+is, 4+is);
|
||||
polyhedron->SetFacet(++icur, 7+is, 6+is, 2+is, 3+is);
|
||||
polyhedron->SetFacet(++icur, 6+is, 5+is, 1+is, 2+is);
|
||||
}
|
||||
polyhedron->AddFacet(5+sub4,6+sub4,7+sub4,8+sub4); //Z-plane
|
||||
polyhedron->SetFacet(++icur, 5+sub4, 6+sub4, 7+sub4, 8+sub4); // Z-plane
|
||||
|
||||
polyhedron->SetReferences();
|
||||
polyhedron->InvertFacets();
|
||||
|
||||
return (G4Polyhedron*) polyhedron;
|
||||
return polyhedron;
|
||||
}
|
||||
|
||||
#endif // G4GEOM_USE_USOLIDS
|
||||
|
||||
@@ -40,8 +40,6 @@
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
|
||||
#include "G4PolyhedronArbitrary.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructors
|
||||
@@ -382,27 +380,26 @@ G4UTessellatedSolid::CalculateExtent(const EAxis pAxis,
|
||||
G4Polyhedron* G4UTessellatedSolid::CreatePolyhedron () const
|
||||
{
|
||||
G4int nVertices = fVertexList.size();
|
||||
G4int nFacets = fFacets.size();
|
||||
G4PolyhedronArbitrary *polyhedron = new G4PolyhedronArbitrary (nVertices,
|
||||
nFacets);
|
||||
for (G4int j = 0; j < nVertices; ++j)
|
||||
G4int nFacets = fFacets.size();
|
||||
G4Polyhedron* polyhedron = new G4Polyhedron(nVertices, nFacets);
|
||||
for (G4int i = 0; i < nVertices; ++i)
|
||||
{
|
||||
polyhedron->AddVertex(fVertexList[j]);
|
||||
polyhedron->SetVertex(i+1, fVertexList[i]);
|
||||
}
|
||||
|
||||
for (G4int i = 0; i < nFacets; ++i)
|
||||
{
|
||||
G4int v[3]; // Only facets with 3 vertices are defined in VecGeom
|
||||
G4VFacet* facet = GetFacet(i);
|
||||
for (G4int j=0; j<3; ++j) // Retrieve indexing directly from VecGeom
|
||||
for (G4int j = 0; j < 3; ++j) // Retrieve indexing directly from VecGeom
|
||||
{
|
||||
v[j] = facet->GetVertexIndex(j) + 1;
|
||||
}
|
||||
polyhedron->AddFacet(v[0],v[1],v[2]);
|
||||
polyhedron->SetFacet(i+1, v[0], v[1], v[2]);
|
||||
}
|
||||
polyhedron->SetReferences();
|
||||
|
||||
return (G4Polyhedron*) polyhedron;
|
||||
return polyhedron;
|
||||
}
|
||||
|
||||
#endif // G4GEOM_USE_USOLIDS
|
||||
|
||||
@@ -985,6 +985,118 @@ void G4VTwistedFaceted::CreateSurfaces()
|
||||
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetCubicVolume ----------------------------------------------------
|
||||
|
||||
G4double G4VTwistedFaceted::GetCubicVolume()
|
||||
{
|
||||
if(fCubicVolume == 0.)
|
||||
{
|
||||
fCubicVolume = ((fDx1 + fDx2 + fDx3 + fDx4)*(fDy1 + fDy2) +
|
||||
(fDx4 + fDx3 - fDx2 - fDx1)*(fDy2 - fDy1)/3)*fDz;
|
||||
}
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetLateralFaceArea ------------------------------------------------
|
||||
|
||||
G4double
|
||||
G4VTwistedFaceted::GetLateralFaceArea(const G4TwoVector& p1,
|
||||
const G4TwoVector& p2,
|
||||
const G4TwoVector& p3,
|
||||
const G4TwoVector& p4) const
|
||||
{
|
||||
constexpr G4int NSTEP = 100;
|
||||
constexpr G4double dt = 1./NSTEP;
|
||||
|
||||
G4double h = 2.*fDz;
|
||||
G4double hh = h*h;
|
||||
G4double hTanTheta = h*std::tan(fTheta);
|
||||
G4double x1 = p1.x();
|
||||
G4double y1 = p1.y();
|
||||
G4double x21 = p2.x() - p1.x();
|
||||
G4double y21 = p2.y() - p1.y();
|
||||
G4double x31 = p3.x() - p1.x();
|
||||
G4double y31 = p3.y() - p1.y();
|
||||
G4double x42 = p4.x() - p2.x();
|
||||
G4double y42 = p4.y() - p2.y();
|
||||
G4double x43 = p4.x() - p3.x();
|
||||
G4double y43 = p4.y() - p3.y();
|
||||
|
||||
// check if face is plane (just in case)
|
||||
G4double lmax = std::max(std::max(std::abs(x21),std::abs(y21)),
|
||||
std::max(std::abs(x43),std::abs(y43)));
|
||||
G4double eps = lmax*kCarTolerance;
|
||||
if (std::abs(fPhiTwist) < kCarTolerance &&
|
||||
std::abs(x21*y43 - y21*x43) < eps)
|
||||
{
|
||||
G4double x0 = hTanTheta*std::cos(fPhi);
|
||||
G4double y0 = hTanTheta*std::sin(fPhi);
|
||||
G4ThreeVector A(p4.x() - p1.x() + x0, p4.y() - p1.y() + y0, h);
|
||||
G4ThreeVector B(p3.x() - p2.x() + x0, p3.y() - p2.y() + y0, h);
|
||||
return (A.cross(B)).mag()*0.5;
|
||||
}
|
||||
|
||||
// twisted face
|
||||
G4double area = 0.;
|
||||
for (G4int i = 0; i < NSTEP; ++i)
|
||||
{
|
||||
G4double t = (i + 0.5)*dt;
|
||||
G4double I = x21 + (x42 - x31)*t;
|
||||
G4double J = y21 + (y42 - y31)*t;
|
||||
G4double II = I*I;
|
||||
G4double JJ = J*J;
|
||||
G4double IIJJ = hh*(I*I + J*J);
|
||||
|
||||
G4double ang = fPhi + fPhiTwist*(0.5 - t);
|
||||
G4double A = fPhiTwist*(II + JJ) + x21*y43 - x43*y21;
|
||||
G4double B = fPhiTwist*(I*(x1 + x31*t) + J*(y1 + y31*t)) +
|
||||
hTanTheta*(I*std::sin(ang) - J*std::cos(ang)) +
|
||||
(I*y31 - J*x31);
|
||||
|
||||
G4double invAA = 1./(A*A);
|
||||
G4double sqrtAA = 2.*std::abs(A);
|
||||
G4double invSqrtAA = 1./sqrtAA;
|
||||
|
||||
G4double aa = A*A;
|
||||
G4double bb = 2.*A*B;
|
||||
G4double cc = IIJJ + B*B;
|
||||
|
||||
G4double R1 = std::sqrt(aa + bb + cc);
|
||||
G4double R0 = std::sqrt(cc);
|
||||
G4double log1 = std::log(std::abs(sqrtAA*R1 + 2.*aa + bb));
|
||||
G4double log0 = std::log(std::abs(sqrtAA*R0 + bb));
|
||||
|
||||
area += 0.5*R1 + 0.25*bb*invAA*(R1 - R0) + IIJJ*invSqrtAA*(log1 - log0);
|
||||
}
|
||||
return area*dt;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetSurfaceArea ----------------------------------------------------
|
||||
|
||||
G4double G4VTwistedFaceted::GetSurfaceArea()
|
||||
{
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
G4TwoVector vv[8];
|
||||
vv[0] = G4TwoVector(-fDx1 - fDy1*fTAlph,-fDy1);
|
||||
vv[1] = G4TwoVector( fDx1 - fDy1*fTAlph,-fDy1);
|
||||
vv[2] = G4TwoVector(-fDx2 + fDy1*fTAlph, fDy1);
|
||||
vv[3] = G4TwoVector( fDx2 + fDy1*fTAlph, fDy1);
|
||||
vv[4] = G4TwoVector(-fDx3 - fDy2*fTAlph,-fDy2);
|
||||
vv[5] = G4TwoVector( fDx3 - fDy2*fTAlph,-fDy2);
|
||||
vv[6] = G4TwoVector(-fDx4 + fDy2*fTAlph, fDy2);
|
||||
vv[7] = G4TwoVector( fDx4 + fDy2*fTAlph, fDy2);
|
||||
fSurfaceArea = 2.*(fDy1*(fDx1 + fDx2) + fDy2*(fDx3 + fDx4)) +
|
||||
GetLateralFaceArea(vv[0], vv[1], vv[4], vv[5]) +
|
||||
GetLateralFaceArea(vv[1], vv[3], vv[5], vv[7]) +
|
||||
GetLateralFaceArea(vv[3], vv[2], vv[7], vv[6]) +
|
||||
GetLateralFaceArea(vv[2], vv[0], vv[6], vv[4]);
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetEntityType -----------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user