Import Geant4 11.1.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2022-07-01 10:44:02 +02:00
parent b3bf75a2a1
commit c07cea1fe0
2172 changed files with 183300 additions and 123938 deletions
@@ -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;
}
// --------------------------------------------------------------------
+32 -4
View File
@@ -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 -----------------------------------------------------