Import Geant4 10.7.0 source tree
This commit is contained in:
@@ -16,6 +16,28 @@ committal in the CVS repository !
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
|
||||
November 12, 2020 E.Tcherniaev geom-csg-V10-06-05
|
||||
- G4Sphere::InitializeThetaTrigonometry(): tan() replaced with sin()/cos(),
|
||||
it addresses problem report #2289
|
||||
|
||||
October 08, 2020 E.Tcherniaev geom-csg-V10-06-04
|
||||
- G4Box: Migration to G4QuickRand in GetPointOnSurface();
|
||||
- G4Trd: Added two precalculated values fHx, fHy for fast calculation
|
||||
of lateral areas; Revision of GetPointOnSurface();
|
||||
- G4Trap: Added array fAreas[6] with precalculated face areas;
|
||||
Added SetCachedValues() method; Revision of GetPointOnSurface();
|
||||
- G4Tubs: Revision of GetPointOnSurface();
|
||||
- G4CSGSolid: Explicit implementation of G4RandomRadiusInRing(rmin,rmax)
|
||||
based on G4QuickRand
|
||||
|
||||
October 06, 2020 E.Tcherniaev geom-csg-V10-06-03
|
||||
- Improved G4CutTubs:
|
||||
o Implemented GetCubicVolume(), GetSurfaceArea();
|
||||
o Reimplemented GetPointOnSurface(), it's now faster and uniform;
|
||||
o Reimplemented IsCrossingCutPlanes(), it now reports a problem
|
||||
only in case if cut planes are crossing inside the lateral surface;
|
||||
o Removed GetMaxMinZ() as obsolete;
|
||||
|
||||
April 30, 2020 G.Cosmo geom-csg-V10-06-02
|
||||
- Adopt new convention for location of headers in VecGeom for all wrappers.
|
||||
|
||||
|
||||
@@ -99,8 +99,8 @@ class G4CutTubs : public G4CSGSolid
|
||||
|
||||
// Methods for solid
|
||||
|
||||
inline G4double GetCubicVolume();
|
||||
inline G4double GetSurfaceArea();
|
||||
G4double GetCubicVolume();
|
||||
G4double GetSurfaceArea();
|
||||
|
||||
void BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const;
|
||||
|
||||
@@ -182,17 +182,14 @@ class G4CutTubs : public G4CSGSolid
|
||||
G4double GetCutZ(const G4ThreeVector& p) const;
|
||||
// Get Z value of the point on Cutted Plane
|
||||
|
||||
void GetMaxMinZ(G4double& zmin,G4double& zmax)const;
|
||||
// Get Max and Min values of Z on Cutted Plane,
|
||||
// Used for Calculate BoundingLimits()
|
||||
|
||||
private:
|
||||
|
||||
G4double kRadTolerance, kAngTolerance;
|
||||
//
|
||||
// Radial and angular tolerances
|
||||
|
||||
G4double fRMin, fRMax, fDz, fSPhi, fDPhi;
|
||||
G4double fRMin, fRMax, fDz, fSPhi, fDPhi;
|
||||
mutable G4double fZMin, fZMax;
|
||||
//
|
||||
// Radial and angular dimensions
|
||||
|
||||
|
||||
@@ -95,6 +95,8 @@ G4ThreeVector G4CutTubs::GetHighNorm () const
|
||||
inline
|
||||
void G4CutTubs::Initialize()
|
||||
{
|
||||
fZMin = 0.;
|
||||
fZMax = 0.;
|
||||
fCubicVolume = 0.;
|
||||
fSurfaceArea = 0.;
|
||||
fRebuildPolyhedron = true;
|
||||
@@ -272,15 +274,3 @@ G4double G4CutTubs::GetDPhi () const
|
||||
{
|
||||
return GetDeltaPhiAngle();
|
||||
}
|
||||
|
||||
inline G4double G4CutTubs::GetCubicVolume()
|
||||
{
|
||||
if (fCubicVolume == 0.) { fCubicVolume = G4VSolid::GetCubicVolume(); }
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
inline G4double G4CutTubs::GetSurfaceArea()
|
||||
{
|
||||
if (fSurfaceArea == 0.) { fSurfaceArea = G4VSolid::GetSurfaceArea(); }
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
@@ -151,9 +151,9 @@ void G4Sphere::InitializeThetaTrigonometry()
|
||||
sinETheta = std::sin(eTheta);
|
||||
cosETheta = std::cos(eTheta);
|
||||
|
||||
tanSTheta = std::tan(fSTheta);
|
||||
tanSTheta = sinSTheta/cosSTheta;
|
||||
tanSTheta2 = tanSTheta*tanSTheta;
|
||||
tanETheta = std::tan(eTheta);
|
||||
tanETheta = sinETheta/cosETheta;
|
||||
tanETheta2 = tanETheta*tanETheta;
|
||||
}
|
||||
|
||||
|
||||
@@ -252,6 +252,7 @@ class G4Trap : public G4CSGSolid
|
||||
const G4ThreeVector& p3,
|
||||
const G4ThreeVector& p4,
|
||||
TrapSidePlane& plane ) ;
|
||||
void SetCachedValues();
|
||||
|
||||
private:
|
||||
|
||||
@@ -272,6 +273,7 @@ class G4Trap : public G4CSGSolid
|
||||
G4double fDy1,fDx1,fDx2,fTalpha1;
|
||||
G4double fDy2,fDx3,fDx4,fTalpha2;
|
||||
TrapSidePlane fPlanes[4];
|
||||
G4double fAreas[6];
|
||||
G4int fTrapType;
|
||||
};
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ class G4Trd : public G4CSGSolid
|
||||
private:
|
||||
|
||||
G4double halfCarTolerance;
|
||||
G4double fDx1,fDx2,fDy1,fDy2,fDz;
|
||||
G4double fDx1,fDx2,fDy1,fDy2,fDz,fHx,fHy;
|
||||
struct { G4double a,b,c,d; } fPlanes[4];
|
||||
};
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "G4VoxelLimits.hh"
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4QuickRand.hh"
|
||||
|
||||
#include "G4VPVParameterisation.hh"
|
||||
|
||||
@@ -140,13 +140,13 @@ void G4Box::SetXHalfLength(G4double dx)
|
||||
fCubicVolume = 0.;
|
||||
fSurfaceArea = 0.;
|
||||
fRebuildPolyhedron = true;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set Y dimension
|
||||
|
||||
void G4Box::SetYHalfLength(G4double dy)
|
||||
void G4Box::SetYHalfLength(G4double dy)
|
||||
{
|
||||
if(dy > 2*kCarTolerance) // limit to thickness of surfaces
|
||||
{
|
||||
@@ -163,7 +163,7 @@ void G4Box::SetYHalfLength(G4double dy)
|
||||
fCubicVolume = 0.;
|
||||
fSurfaceArea = 0.;
|
||||
fRebuildPolyhedron = true;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -186,7 +186,7 @@ void G4Box::SetZHalfLength(G4double dz)
|
||||
fCubicVolume = 0.;
|
||||
fSurfaceArea = 0.;
|
||||
fRebuildPolyhedron = true;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -252,8 +252,8 @@ EInside G4Box::Inside(const G4ThreeVector& p) const
|
||||
std::abs(p.x())-fDx,
|
||||
std::abs(p.y())-fDy),
|
||||
std::abs(p.z())-fDz);
|
||||
if (dist > delta) return kOutside;
|
||||
return (dist > -delta) ? kSurface : kInside;
|
||||
return (dist > delta) ? kOutside :
|
||||
((dist > -delta) ? kSurface : kInside);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -278,7 +278,7 @@ G4ThreeVector G4Box::SurfaceNormal( const G4ThreeVector& p) const
|
||||
else
|
||||
{
|
||||
// Point is not on the surface
|
||||
//
|
||||
//
|
||||
#ifdef G4CSGDEBUG
|
||||
std::ostringstream message;
|
||||
G4int oldprc = message.precision(16);
|
||||
@@ -353,7 +353,7 @@ G4double G4Box::DistanceToIn(const G4ThreeVector& p,
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
// Appoximate distance to box.
|
||||
// Returns largest perpendicular distance to the closest x/y/z sides of
|
||||
// the box, which is the most fast estimation of the shortest distance to box
|
||||
@@ -361,9 +361,10 @@ G4double G4Box::DistanceToIn(const G4ThreeVector& p,
|
||||
|
||||
G4double G4Box::DistanceToIn(const G4ThreeVector& p) const
|
||||
{
|
||||
G4double dist = std::max(std::max(std::abs(p.x())-fDx,
|
||||
std::abs(p.y())-fDy),
|
||||
std::abs(p.z())-fDz);
|
||||
G4double dist = std::max(std::max(
|
||||
std::abs(p.x())-fDx,
|
||||
std::abs(p.y())-fDy),
|
||||
std::abs(p.z())-fDz);
|
||||
return (dist > 0) ? dist : 0.;
|
||||
}
|
||||
|
||||
@@ -456,9 +457,10 @@ G4double G4Box::DistanceToOut(const G4ThreeVector& p) const
|
||||
DumpInfo();
|
||||
}
|
||||
#endif
|
||||
G4double dist = std::min(std::min(fDx-std::abs(p.x()),
|
||||
fDy-std::abs(p.y())),
|
||||
fDz-std::abs(p.z()));
|
||||
G4double dist = std::min(std::min(
|
||||
fDx-std::abs(p.x()),
|
||||
fDy-std::abs(p.y())),
|
||||
fDz-std::abs(p.z()));
|
||||
return (dist > 0) ? dist : 0.;
|
||||
}
|
||||
|
||||
@@ -493,29 +495,27 @@ std::ostream& G4Box::StreamInfo(std::ostream& os) const
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GetPointOnSurface
|
||||
//
|
||||
// Return a point (G4ThreeVector) randomly and uniformly selected
|
||||
// on the solid surface
|
||||
// Return a point randomly and uniformly selected on the surface
|
||||
|
||||
G4ThreeVector G4Box::GetPointOnSurface() const
|
||||
{
|
||||
G4double sxy = fDx*fDy, sxz = fDx*fDz, syz = fDy*fDz;
|
||||
G4double select = (sxy + sxz + syz)*G4UniformRand();
|
||||
G4double select = (sxy + sxz + syz)*G4QuickRand();
|
||||
G4double u = 2.*G4QuickRand() - 1.;
|
||||
G4double v = 2.*G4QuickRand() - 1.;
|
||||
|
||||
if (select < sxy)
|
||||
return G4ThreeVector((2.*G4UniformRand() - 1.)*fDx,
|
||||
(2.*G4UniformRand() - 1.)*fDy,
|
||||
(select < 0.5*sxy) ? -fDz : fDz);
|
||||
|
||||
if (select < sxy + sxz)
|
||||
return G4ThreeVector((2.*G4UniformRand() - 1.)*fDx,
|
||||
(select < sxy + 0.5*sxz) ? -fDy : fDy,
|
||||
(2.*G4UniformRand() - 1.)*fDz);
|
||||
return G4ThreeVector(u*fDx,
|
||||
v*fDy,
|
||||
((select < 0.5*sxy) ? -fDz : fDz));
|
||||
else if (select < sxy + sxz)
|
||||
return G4ThreeVector(u*fDx,
|
||||
((select < sxy + 0.5*sxz) ? -fDy : fDy),
|
||||
v*fDz);
|
||||
else
|
||||
return G4ThreeVector((select < sxy + sxz + 0.5*syz) ? -fDx : fDx,
|
||||
(2.*G4UniformRand() - 1.)*fDy,
|
||||
(2.*G4UniformRand() - 1.)*fDz);
|
||||
return G4ThreeVector(((select < sxy + sxz + 0.5*syz) ? -fDx : fDx),
|
||||
u*fDy,
|
||||
v*fDz);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
#include <cmath>
|
||||
|
||||
#include "G4CSGSolid.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4RandomTools.hh"
|
||||
#include "G4QuickRand.hh"
|
||||
#include "G4Polyhedron.hh"
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
@@ -45,7 +44,7 @@ namespace
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor
|
||||
// - Base class constructor
|
||||
// - Base class constructor
|
||||
|
||||
G4CSGSolid::G4CSGSolid(const G4String& name) :
|
||||
G4VSolid(name)
|
||||
@@ -67,7 +66,7 @@ G4CSGSolid::G4CSGSolid( __void__& a )
|
||||
// Destructor
|
||||
//
|
||||
|
||||
G4CSGSolid::~G4CSGSolid()
|
||||
G4CSGSolid::~G4CSGSolid()
|
||||
{
|
||||
delete fpPolyhedron; fpPolyhedron = nullptr;
|
||||
}
|
||||
@@ -87,7 +86,7 @@ G4CSGSolid::G4CSGSolid(const G4CSGSolid& rhs)
|
||||
//
|
||||
// Assignment operator
|
||||
|
||||
G4CSGSolid& G4CSGSolid::operator = (const G4CSGSolid& rhs)
|
||||
G4CSGSolid& G4CSGSolid::operator = (const G4CSGSolid& rhs)
|
||||
{
|
||||
// Check assignment to self
|
||||
//
|
||||
@@ -105,11 +104,13 @@ G4CSGSolid& G4CSGSolid::operator = (const G4CSGSolid& rhs)
|
||||
delete fpPolyhedron; fpPolyhedron = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4CSGSolid::GetRadiusInRing(G4double rmin, G4double rmax) const
|
||||
{
|
||||
return G4RandomRadiusInRing(rmin, rmax);
|
||||
G4double k = G4QuickRand();
|
||||
return (rmin <= 0) ? rmax*std::sqrt(k)
|
||||
: std::sqrt(k*rmax*rmax + (1. - k)*rmin*rmin);
|
||||
}
|
||||
|
||||
std::ostream& G4CSGSolid::StreamInfo(std::ostream& os) const
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,7 +28,7 @@
|
||||
// 21.03.95 P.Kent: Modified for `tolerant' geometry
|
||||
// 09.09.96 V.Grichine: Final modifications before to commit
|
||||
// 08.12.97 J.Allison: Added "nominal" constructor and method SetAllParameters
|
||||
// 28.04.05 V.Grichine: new SurfaceNormal according to J.Apostolakis proposal
|
||||
// 28.04.05 V.Grichine: new SurfaceNormal according to J.Apostolakis proposal
|
||||
// 18.04.17 E.Tcherniaev: complete revision, speed-up
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
#include "G4VPVParameterisation.hh"
|
||||
|
||||
#include "Randomize.hh"
|
||||
#include "G4QuickRand.hh"
|
||||
|
||||
#include "G4VGraphicsScene.hh"
|
||||
#include "G4Polyhedron.hh"
|
||||
@@ -54,7 +54,7 @@ using namespace CLHEP;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor - check and set half-widths as well as angles:
|
||||
// Constructor - check and set half-widths as well as angles:
|
||||
// final check of coplanarity
|
||||
|
||||
G4Trap::G4Trap( const G4String& pName,
|
||||
@@ -79,8 +79,8 @@ G4Trap::G4Trap( const G4String& pName,
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor - Design of trapezoid based on 8 G4ThreeVector parameters,
|
||||
// which are its vertices. Checking of planarity with preparation of
|
||||
// Constructor - Design of trapezoid based on 8 G4ThreeVector parameters,
|
||||
// which are its vertices. Checking of planarity with preparation of
|
||||
// fPlanes[] and than calculation of other members
|
||||
|
||||
G4Trap::G4Trap( const G4String& pName,
|
||||
@@ -116,11 +116,11 @@ G4Trap::G4Trap( const G4String& pName,
|
||||
G4Exception("G4Trap::G4Trap()", "GeomSolids0002",
|
||||
FatalException, message);
|
||||
}
|
||||
|
||||
|
||||
// Set parameters
|
||||
//
|
||||
fDz = (pt[7]).z();
|
||||
|
||||
|
||||
fDy1 = ((pt[2]).y()-(pt[1]).y())*0.5;
|
||||
fDx1 = ((pt[1]).x()-(pt[0]).x())*0.5;
|
||||
fDx2 = ((pt[3]).x()-(pt[2]).x())*0.5;
|
||||
@@ -244,6 +244,7 @@ G4Trap::G4Trap(const G4Trap& rhs)
|
||||
fDy2(rhs.fDy2), fDx3(rhs.fDx3), fDx4(rhs.fDx4), fTalpha2(rhs.fTalpha2)
|
||||
{
|
||||
for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
|
||||
for (G4int i=0; i<6; ++i) { fAreas[i] = rhs.fAreas[i]; }
|
||||
fTrapType = rhs.fTrapType;
|
||||
}
|
||||
|
||||
@@ -251,7 +252,7 @@ G4Trap::G4Trap(const G4Trap& rhs)
|
||||
//
|
||||
// Assignment operator
|
||||
|
||||
G4Trap& G4Trap::operator = (const G4Trap& rhs)
|
||||
G4Trap& G4Trap::operator = (const G4Trap& rhs)
|
||||
{
|
||||
// Check assignment to self
|
||||
//
|
||||
@@ -268,6 +269,7 @@ G4Trap& G4Trap::operator = (const G4Trap& rhs)
|
||||
fDy1 = rhs.fDy1; fDx1 = rhs.fDx1; fDx2 = rhs.fDx2; fTalpha1 = rhs.fTalpha1;
|
||||
fDy2 = rhs.fDy2; fDx3 = rhs.fDx3; fDx4 = rhs.fDx4; fTalpha2 = rhs.fTalpha2;
|
||||
for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
|
||||
for (G4int i=0; i<6; ++i) { fAreas[i] = rhs.fAreas[i]; }
|
||||
fTrapType = rhs.fTrapType;
|
||||
return *this;
|
||||
}
|
||||
@@ -358,8 +360,8 @@ void G4Trap::MakePlanes()
|
||||
|
||||
void G4Trap::MakePlanes(const G4ThreeVector pt[8])
|
||||
{
|
||||
G4int iface[4][4] = { {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3} };
|
||||
G4String side[4] = { "~-Y", "~+Y", "~-X", "~+X" };
|
||||
constexpr G4int iface[4][4] = { {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3} };
|
||||
const static G4String side[4] = { "~-Y", "~+Y", "~-X", "~+X" };
|
||||
|
||||
for (G4int i=0; i<4; ++i)
|
||||
{
|
||||
@@ -385,6 +387,70 @@ void G4Trap::MakePlanes(const G4ThreeVector pt[8])
|
||||
FatalException, message);
|
||||
}
|
||||
|
||||
// Re-compute parameters
|
||||
SetCachedValues();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate the coef's of the plane p1->p2->p3->p4->p1
|
||||
// where the ThreeVectors 1-4 are in anti-clockwise order when viewed
|
||||
// from infront of the plane (i.e. from normal direction).
|
||||
//
|
||||
// Return true if the points are coplanar, false otherwise
|
||||
|
||||
G4bool G4Trap::MakePlane( const G4ThreeVector& p1,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3,
|
||||
const G4ThreeVector& p4,
|
||||
TrapSidePlane& plane )
|
||||
{
|
||||
G4ThreeVector normal = ((p4 - p2).cross(p3 - p1)).unit();
|
||||
if (std::abs(normal.x()) < DBL_EPSILON) normal.setX(0);
|
||||
if (std::abs(normal.y()) < DBL_EPSILON) normal.setY(0);
|
||||
if (std::abs(normal.z()) < DBL_EPSILON) normal.setZ(0);
|
||||
normal = normal.unit();
|
||||
|
||||
G4ThreeVector centre = (p1 + p2 + p3 + p4)*0.25;
|
||||
plane.a = normal.x();
|
||||
plane.b = normal.y();
|
||||
plane.c = normal.z();
|
||||
plane.d = -normal.dot(centre);
|
||||
|
||||
// compute distances and check planarity
|
||||
G4double d1 = std::abs(normal.dot(p1) + plane.d);
|
||||
G4double d2 = std::abs(normal.dot(p2) + plane.d);
|
||||
G4double d3 = std::abs(normal.dot(p3) + plane.d);
|
||||
G4double d4 = std::abs(normal.dot(p4) + plane.d);
|
||||
G4double dmax = std::max(std::max(std::max(d1,d2),d3),d4);
|
||||
|
||||
return (dmax > 1000 * kCarTolerance) ? false : true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Recompute parameters using planes
|
||||
|
||||
void G4Trap::SetCachedValues()
|
||||
{
|
||||
// Set indeces
|
||||
constexpr G4int iface[6][4] =
|
||||
{ {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3}, {4,6,7,5} };
|
||||
|
||||
// Get vertices
|
||||
G4ThreeVector pt[8];
|
||||
GetVertices(pt);
|
||||
|
||||
// Set face areas
|
||||
for (G4int i=0; i<6; ++i)
|
||||
{
|
||||
fAreas[i] = G4GeomTools::QuadAreaNormal(pt[iface[i][0]],
|
||||
pt[iface[i][1]],
|
||||
pt[iface[i][2]],
|
||||
pt[iface[i][3]]).mag();
|
||||
}
|
||||
for (G4int i=1; i<6; ++i) { fAreas[i] += fAreas[i - 1]; }
|
||||
|
||||
// Define type of trapezoid
|
||||
fTrapType = 0;
|
||||
if (fPlanes[0].b == -1 && fPlanes[1].b == 1 &&
|
||||
@@ -415,43 +481,7 @@ void G4Trap::MakePlanes(const G4ThreeVector pt[8])
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate the coef's of the plane p1->p2->p3->p4->p1
|
||||
// where the ThreeVectors 1-4 are in anti-clockwise order when viewed
|
||||
// from infront of the plane (i.e. from normal direction).
|
||||
//
|
||||
// Return true if the points are coplanar, false otherwise
|
||||
|
||||
G4bool G4Trap::MakePlane( const G4ThreeVector& p1,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3,
|
||||
const G4ThreeVector& p4,
|
||||
TrapSidePlane& plane )
|
||||
{
|
||||
G4ThreeVector normal = ((p4 - p2).cross(p3 - p1)).unit();
|
||||
if (std::abs(normal.x()) < DBL_EPSILON) normal.setX(0);
|
||||
if (std::abs(normal.y()) < DBL_EPSILON) normal.setY(0);
|
||||
if (std::abs(normal.z()) < DBL_EPSILON) normal.setZ(0);
|
||||
normal = normal.unit();
|
||||
|
||||
G4ThreeVector centre = (p1 + p2 + p3 + p4)*0.25;
|
||||
plane.a = normal.x();
|
||||
plane.b = normal.y();
|
||||
plane.c = normal.z();
|
||||
plane.d = -normal.dot(centre);
|
||||
|
||||
// compute distances and check planarity
|
||||
G4double d1 = std::abs(normal.dot(p1) + plane.d);
|
||||
G4double d2 = std::abs(normal.dot(p2) + plane.d);
|
||||
G4double d3 = std::abs(normal.dot(p3) + plane.d);
|
||||
G4double d4 = std::abs(normal.dot(p4) + plane.d);
|
||||
G4double dmax = std::max(std::max(std::max(d1,d2),d3),d4);
|
||||
|
||||
return (dmax > 1000 * kCarTolerance) ? false : true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get volume
|
||||
|
||||
@@ -461,7 +491,7 @@ G4double G4Trap::GetCubicVolume()
|
||||
{
|
||||
G4ThreeVector pt[8];
|
||||
GetVertices(pt);
|
||||
|
||||
|
||||
G4double dz = pt[4].z() - pt[0].z();
|
||||
G4double dy1 = pt[2].y() - pt[0].y();
|
||||
G4double dx1 = pt[1].x() - pt[0].x();
|
||||
@@ -476,7 +506,7 @@ G4double G4Trap::GetCubicVolume()
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get surface area
|
||||
|
||||
@@ -500,7 +530,7 @@ G4double G4Trap::GetSurfaceArea()
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dispatch to parameterisation for replication mechanism dimension
|
||||
// computation & modification.
|
||||
@@ -512,7 +542,7 @@ void G4Trap::ComputeDimensions( G4VPVParameterisation* p,
|
||||
p->ComputeDimensions(*this,n,pRep);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get bounding box
|
||||
|
||||
@@ -552,7 +582,7 @@ void G4Trap::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate extent under transform and specified limit
|
||||
|
||||
@@ -601,7 +631,7 @@ G4bool G4Trap::CalculateExtent( const EAxis pAxis,
|
||||
return exist;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Return whether point is inside/outside/on_surface
|
||||
|
||||
@@ -661,10 +691,10 @@ EInside G4Trap::Inside( const G4ThreeVector& p ) const
|
||||
((dist > -halfCarTolerance) ? kSurface : kInside);
|
||||
}
|
||||
}
|
||||
return kOutside;
|
||||
return kOutside;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Determine side, and return corresponding normal
|
||||
|
||||
@@ -765,7 +795,7 @@ G4ThreeVector G4Trap::SurfaceNormal( const G4ThreeVector& p ) const
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Algorithm for SurfaceNormal() following the original specification
|
||||
// for points not on the surface
|
||||
@@ -789,7 +819,7 @@ G4ThreeVector G4Trap::ApproxSurfaceNormal( const G4ThreeVector& p ) const
|
||||
return G4ThreeVector(0, 0, (p.z() < 0) ? -1 : 1);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate distance to shape from outside
|
||||
// - return kInfinity if no intersection
|
||||
@@ -802,7 +832,7 @@ G4double G4Trap::DistanceToIn(const G4ThreeVector& p,
|
||||
if ((std::abs(p.z()) - fDz) >= -halfCarTolerance && p.z()*v.z() >= 0)
|
||||
return kInfinity;
|
||||
G4double invz = (-v.z() == 0) ? DBL_MAX : -1./v.z();
|
||||
G4double dz = (invz < 0) ? fDz : -fDz;
|
||||
G4double dz = (invz < 0) ? fDz : -fDz;
|
||||
G4double tzmin = (p.z() + dz)*invz;
|
||||
G4double tzmax = (p.z() - dz)*invz;
|
||||
|
||||
@@ -811,7 +841,7 @@ G4double G4Trap::DistanceToIn(const G4ThreeVector& p,
|
||||
G4double tymin = 0, tymax = DBL_MAX;
|
||||
G4int i = 0;
|
||||
for ( ; i<2; ++i)
|
||||
{
|
||||
{
|
||||
G4double cosa = fPlanes[i].b*v.y() + fPlanes[i].c*v.z();
|
||||
G4double dist = fPlanes[i].b*p.y() + fPlanes[i].c*p.z() + fPlanes[i].d;
|
||||
if (dist >= -halfCarTolerance)
|
||||
@@ -824,14 +854,14 @@ G4double G4Trap::DistanceToIn(const G4ThreeVector& p,
|
||||
{
|
||||
G4double tmp = -dist/cosa;
|
||||
if (tymax > tmp) tymax = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Z intersections
|
||||
//
|
||||
G4double txmin = 0, txmax = DBL_MAX;
|
||||
for ( ; i<4; ++i)
|
||||
{
|
||||
{
|
||||
G4double cosa = fPlanes[i].a*v.x()+fPlanes[i].b*v.y()+fPlanes[i].c*v.z();
|
||||
G4double dist = fPlanes[i].a*p.x()+fPlanes[i].b*p.y()+fPlanes[i].c*p.z() +
|
||||
fPlanes[i].d;
|
||||
@@ -845,19 +875,19 @@ G4double G4Trap::DistanceToIn(const G4ThreeVector& p,
|
||||
{
|
||||
G4double tmp = -dist/cosa;
|
||||
if (txmax > tmp) txmax = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find distance
|
||||
//
|
||||
G4double tmin = std::max(std::max(txmin,tymin),tzmin);
|
||||
G4double tmax = std::min(std::min(txmax,tymax),tzmax);
|
||||
|
||||
|
||||
if (tmax <= tmin + halfCarTolerance) return kInfinity; // touch or no hit
|
||||
return (tmin < halfCarTolerance ) ? 0. : tmin;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate exact shortest distance to any boundary from outside
|
||||
// This is the best fast estimation of the shortest distance to trap
|
||||
@@ -914,7 +944,7 @@ G4double G4Trap::DistanceToIn( const G4ThreeVector& p ) const
|
||||
return 0.;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate distance to surface of shape from inside and
|
||||
// find normal at exit point, if required
|
||||
@@ -987,7 +1017,7 @@ G4double G4Trap::DistanceToOut(const G4ThreeVector& p, const G4ThreeVector& v,
|
||||
|
||||
// Set normal, if required, and return distance
|
||||
//
|
||||
if (calcNorm)
|
||||
if (calcNorm)
|
||||
{
|
||||
*validNorm = true;
|
||||
if (iside < 0)
|
||||
@@ -998,7 +1028,7 @@ G4double G4Trap::DistanceToOut(const G4ThreeVector& p, const G4ThreeVector& v,
|
||||
return tmax;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate exact shortest distance to any boundary from inside
|
||||
// - Returns 0 is ThreeVector outside
|
||||
@@ -1015,7 +1045,7 @@ G4double G4Trap::DistanceToOut( const G4ThreeVector& p ) const
|
||||
message << " p.x() = " << p.x()/mm << " mm\n";
|
||||
message << " p.y() = " << p.y()/mm << " mm\n";
|
||||
message << " p.z() = " << p.z()/mm << " mm";
|
||||
G4cout.precision(oldprc) ;
|
||||
G4cout.precision(oldprc);
|
||||
G4Exception("G4Trap::DistanceToOut(p)", "GeomSolids1002",
|
||||
JustWarning, message );
|
||||
DumpInfo();
|
||||
@@ -1070,7 +1100,7 @@ G4double G4Trap::DistanceToOut( const G4ThreeVector& p ) const
|
||||
return 0.;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GetEntityType
|
||||
|
||||
@@ -1099,7 +1129,7 @@ std::ostream& G4Trap::StreamInfo( std::ostream& os ) const
|
||||
+fTthetaSphi*fTthetaSphi));
|
||||
G4double alpha1 = std::atan(fTalpha1);
|
||||
G4double alpha2 = std::atan(fTalpha2);
|
||||
G4String signDegree = "\u00B0";
|
||||
G4String signDegree = "\u00B0";
|
||||
|
||||
G4int oldprc = os.precision(16);
|
||||
os << "-----------------------------------------------------------\n"
|
||||
@@ -1142,38 +1172,29 @@ void G4Trap::GetVertices(G4ThreeVector pt[8]) const
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generate random point on the surface
|
||||
|
||||
G4ThreeVector G4Trap::GetPointOnSurface() const
|
||||
{
|
||||
G4ThreeVector pt[8];
|
||||
G4int iface [6][4] =
|
||||
{ {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3}, {4,6,7,5} };
|
||||
G4double sface[6];
|
||||
// Set indeces
|
||||
constexpr G4int iface [6][4] =
|
||||
{ {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3}, {4,6,7,5} };
|
||||
|
||||
// Set vertices
|
||||
G4ThreeVector pt[8];
|
||||
GetVertices(pt);
|
||||
G4double stotal = 0;
|
||||
for (G4int i=0; i<6; ++i)
|
||||
{
|
||||
G4double ss = G4GeomTools::QuadAreaNormal(pt[iface[i][0]],
|
||||
pt[iface[i][1]],
|
||||
pt[iface[i][2]],
|
||||
pt[iface[i][3]]).mag();
|
||||
stotal += ss;
|
||||
sface[i] = stotal;
|
||||
}
|
||||
|
||||
// Select face
|
||||
//
|
||||
G4double select = stotal*G4UniformRand();
|
||||
G4double select = fAreas[5]*G4QuickRand();
|
||||
G4int k = 5;
|
||||
if (select <= sface[4]) k = 4;
|
||||
if (select <= sface[3]) k = 3;
|
||||
if (select <= sface[2]) k = 2;
|
||||
if (select <= sface[1]) k = 1;
|
||||
if (select <= sface[0]) k = 0;
|
||||
k -= (select <= fAreas[4]);
|
||||
k -= (select <= fAreas[3]);
|
||||
k -= (select <= fAreas[2]);
|
||||
k -= (select <= fAreas[1]);
|
||||
k -= (select <= fAreas[0]);
|
||||
|
||||
// Select sub-triangle
|
||||
//
|
||||
@@ -1181,14 +1202,13 @@ G4ThreeVector G4Trap::GetPointOnSurface() const
|
||||
G4int i1 = iface[k][1];
|
||||
G4int i2 = iface[k][2];
|
||||
G4int i3 = iface[k][3];
|
||||
G4double s1 = G4GeomTools::TriangleAreaNormal(pt[i0],pt[i1],pt[i3]).mag();
|
||||
G4double s2 = G4GeomTools::TriangleAreaNormal(pt[i2],pt[i1],pt[i3]).mag();
|
||||
if ((s1+s2)*G4UniformRand() > s1) i0 = i2;
|
||||
if (select > fAreas[k] - s2) i0 = i2;
|
||||
|
||||
// Generate point
|
||||
//
|
||||
G4double u = G4UniformRand();
|
||||
G4double v = G4UniformRand();
|
||||
G4double u = G4QuickRand();
|
||||
G4double v = G4QuickRand();
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
return (1.-u-v)*pt[i0] + u*pt[i1] + v*pt[i3];
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
// Implementation for G4Trd class
|
||||
//
|
||||
// 12.01.95 P.Kent: First version
|
||||
// 28.04.05 V.Grichine: new SurfaceNormal according to J.Apostolakis proposal
|
||||
// 28.04.05 V.Grichine: new SurfaceNormal according to J.Apostolakis proposal
|
||||
// 25.05.17 E.Tcherniaev: complete revision, speed-up
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include "G4VoxelLimits.hh"
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4QuickRand.hh"
|
||||
|
||||
#include "G4VPVParameterisation.hh"
|
||||
|
||||
@@ -89,7 +89,8 @@ G4Trd::~G4Trd()
|
||||
G4Trd::G4Trd(const G4Trd& rhs)
|
||||
: G4CSGSolid(rhs), halfCarTolerance(rhs.halfCarTolerance),
|
||||
fDx1(rhs.fDx1), fDx2(rhs.fDx2),
|
||||
fDy1(rhs.fDy1), fDy2(rhs.fDy2), fDz(rhs.fDz)
|
||||
fDy1(rhs.fDy1), fDy2(rhs.fDy2), fDz(rhs.fDz),
|
||||
fHx(rhs.fHx), fHy(rhs.fHy)
|
||||
{
|
||||
for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
|
||||
}
|
||||
@@ -114,6 +115,7 @@ G4Trd& G4Trd::operator = (const G4Trd& rhs)
|
||||
fDx1 = rhs.fDx1; fDx2 = rhs.fDx2;
|
||||
fDy1 = rhs.fDy1; fDy2 = rhs.fDy2;
|
||||
fDz = rhs.fDz;
|
||||
fHx = rhs.fHx; fHy = rhs.fHy;
|
||||
for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
|
||||
|
||||
return *this;
|
||||
@@ -171,14 +173,14 @@ void G4Trd::MakePlanes()
|
||||
G4double dx = fDx1 - fDx2;
|
||||
G4double dy = fDy1 - fDy2;
|
||||
G4double dz = 2*fDz;
|
||||
G4double magx = std::sqrt(dx*dx + dz*dz);
|
||||
G4double magy = std::sqrt(dy*dy + dz*dz);
|
||||
fHx = std::sqrt(dy*dy + dz*dz);
|
||||
fHy = std::sqrt(dx*dx + dz*dz);
|
||||
|
||||
// Set -Y & +Y planes
|
||||
// Set X planes at -Y & +Y
|
||||
//
|
||||
fPlanes[0].a = 0.;
|
||||
fPlanes[0].b = -dz/magy;
|
||||
fPlanes[0].c = dy/magy;
|
||||
fPlanes[0].b = -dz/fHx;
|
||||
fPlanes[0].c = dy/fHx;
|
||||
fPlanes[0].d = fPlanes[0].b*fDy1 + fPlanes[0].c*fDz;
|
||||
|
||||
fPlanes[1].a = fPlanes[0].a;
|
||||
@@ -186,11 +188,11 @@ void G4Trd::MakePlanes()
|
||||
fPlanes[1].c = fPlanes[0].c;
|
||||
fPlanes[1].d = fPlanes[0].d;
|
||||
|
||||
// Set -X & +X planes
|
||||
// Set Y planes at -X & +X
|
||||
//
|
||||
fPlanes[2].a = -dz/magx;
|
||||
fPlanes[2].a = -dz/fHy;
|
||||
fPlanes[2].b = 0.;
|
||||
fPlanes[2].c = dx/magx;
|
||||
fPlanes[2].c = dx/fHy;
|
||||
fPlanes[2].d = fPlanes[2].a*fDx1 + fPlanes[2].c*fDz;
|
||||
|
||||
fPlanes[3].a = -fPlanes[2].a;
|
||||
@@ -222,9 +224,7 @@ G4double G4Trd::GetSurfaceArea()
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
fSurfaceArea =
|
||||
4*(fDx1*fDy1+fDx2*fDy2) +
|
||||
2*(fDy1+fDy2)*std::hypot(fDx1-fDx2,2*fDz) +
|
||||
2*(fDx1+fDx2)*std::hypot(fDy1-fDy2,2*fDz);
|
||||
4*(fDx1*fDy1 + fDx2*fDy2) + 2*(fDx1+fDx2)*fHx + 2*(fDy1+fDy2)*fHy;
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
@@ -328,7 +328,7 @@ G4bool G4Trd::CalculateExtent( const EAxis pAxis,
|
||||
// Return whether point inside/outside/on surface, using tolerance
|
||||
|
||||
EInside G4Trd::Inside( const G4ThreeVector& p ) const
|
||||
{
|
||||
{
|
||||
G4double dx = fPlanes[3].a*std::abs(p.x())+fPlanes[3].c*p.z()+fPlanes[3].d;
|
||||
G4double dy = fPlanes[1].b*std::abs(p.y())+fPlanes[1].c*p.z()+fPlanes[1].d;
|
||||
G4double dxy = std::max(dx,dy);
|
||||
@@ -336,8 +336,8 @@ EInside G4Trd::Inside( const G4ThreeVector& p ) const
|
||||
G4double dz = std::abs(p.z())-fDz;
|
||||
G4double dist = std::max(dz,dxy);
|
||||
|
||||
if (dist > halfCarTolerance) return kOutside;
|
||||
return (dist > -halfCarTolerance) ? kSurface : kInside;
|
||||
return (dist > halfCarTolerance) ? kOutside :
|
||||
((dist > -halfCarTolerance) ? kSurface : kInside);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -457,7 +457,7 @@ G4double G4Trd::DistanceToIn(const G4ThreeVector& p,
|
||||
if ((std::abs(p.z()) - fDz) >= -halfCarTolerance && p.z()*v.z() >= 0)
|
||||
return kInfinity;
|
||||
G4double invz = (-v.z() == 0) ? DBL_MAX : -1./v.z();
|
||||
G4double dz = (invz < 0) ? fDz : -fDz;
|
||||
G4double dz = (invz < 0) ? fDz : -fDz;
|
||||
G4double tzmin = (p.z() + dz)*invz;
|
||||
G4double tzmax = (p.z() - dz)*invz;
|
||||
|
||||
@@ -626,7 +626,7 @@ G4double G4Trd::DistanceToOut(const G4ThreeVector& p, const G4ThreeVector& v,
|
||||
|
||||
// Set normal, if required, and return distance
|
||||
//
|
||||
if (calcNorm)
|
||||
if (calcNorm)
|
||||
{
|
||||
*validNorm = true;
|
||||
if (iside < 0)
|
||||
@@ -654,7 +654,7 @@ G4double G4Trd::DistanceToOut( const G4ThreeVector& p ) const
|
||||
message << " p.x() = " << p.x()/mm << " mm\n";
|
||||
message << " p.y() = " << p.y()/mm << " mm\n";
|
||||
message << " p.z() = " << p.z()/mm << " mm";
|
||||
G4cout.precision(oldprc) ;
|
||||
G4cout.precision(oldprc);
|
||||
G4Exception("G4Trd::DistanceToOut(p)", "GeomSolids1002",
|
||||
JustWarning, message );
|
||||
DumpInfo();
|
||||
@@ -666,7 +666,7 @@ G4double G4Trd::DistanceToOut( const G4ThreeVector& p ) const
|
||||
|
||||
G4double dz = std::abs(p.z())-fDz;
|
||||
G4double dist = std::max(dz,dxy);
|
||||
|
||||
|
||||
return (dist < 0) ? -dist : 0.;
|
||||
}
|
||||
|
||||
@@ -717,56 +717,79 @@ std::ostream& G4Trd::StreamInfo( std::ostream& os ) const
|
||||
|
||||
G4ThreeVector G4Trd::GetPointOnSurface() const
|
||||
{
|
||||
// Set vertices
|
||||
//
|
||||
G4ThreeVector pt[8];
|
||||
pt[0].set(-fDx1,-fDy1,-fDz);
|
||||
pt[1].set( fDx1,-fDy1,-fDz);
|
||||
pt[2].set(-fDx1, fDy1,-fDz);
|
||||
pt[3].set( fDx1, fDy1,-fDz);
|
||||
pt[4].set(-fDx2,-fDy2, fDz);
|
||||
pt[5].set( fDx2,-fDy2, fDz);
|
||||
pt[6].set(-fDx2, fDy2, fDz);
|
||||
pt[7].set( fDx2, fDy2, fDz);
|
||||
|
||||
// Set faces (-Z, -Y, +Y, -X, +X, +Z)
|
||||
//
|
||||
G4int iface [6][4] =
|
||||
{ {0,1,3,2}, {0,4,5,1}, {2,3,7,6}, {0,2,6,4}, {1,5,7,3}, {4,6,7,5} };
|
||||
|
||||
// Set areas
|
||||
//
|
||||
G4double sxz = (fDy1 + fDy2)*std::hypot(fDx1 - fDx2, 2*fDz);
|
||||
G4double syz = (fDx1 + fDx2)*std::hypot(fDy1 - fDy2, 2*fDz);
|
||||
G4double sface[6] = { 4*fDx1*fDy1, syz, syz, sxz, sxz, 4*fDx2*fDy2 };
|
||||
for (G4int i=1; i<6; ++i) { sface[i] += sface[i-1]; }
|
||||
//
|
||||
G4double sxz = (fDx1 + fDx2)*fHx;
|
||||
G4double syz = (fDy1 + fDy2)*fHy;
|
||||
G4double ssurf[6] = { 4.*fDx1*fDy1, sxz, sxz, syz, syz, 4.*fDx2*fDy2 };
|
||||
ssurf[1] += ssurf[0];
|
||||
ssurf[2] += ssurf[1];
|
||||
ssurf[3] += ssurf[2];
|
||||
ssurf[4] += ssurf[3];
|
||||
ssurf[5] += ssurf[4];
|
||||
|
||||
// Select face
|
||||
//
|
||||
G4double select = sface[5]*G4UniformRand();
|
||||
G4double select = ssurf[5]*G4QuickRand();
|
||||
G4int k = 5;
|
||||
if (select <= sface[4]) k = 4;
|
||||
if (select <= sface[3]) k = 3;
|
||||
if (select <= sface[2]) k = 2;
|
||||
if (select <= sface[1]) k = 1;
|
||||
if (select <= sface[0]) k = 0;
|
||||
k -= (select <= ssurf[4]);
|
||||
k -= (select <= ssurf[3]);
|
||||
k -= (select <= ssurf[2]);
|
||||
k -= (select <= ssurf[1]);
|
||||
k -= (select <= ssurf[0]);
|
||||
|
||||
// Select sub-triangle
|
||||
// Generate point on selected surface
|
||||
//
|
||||
G4int i0 = iface[k][0];
|
||||
G4int i1 = iface[k][1];
|
||||
G4int i2 = iface[k][2];
|
||||
G4int i3 = iface[k][3];
|
||||
G4double s1 = G4GeomTools::TriangleAreaNormal(pt[i0],pt[i1],pt[i3]).mag();
|
||||
G4double s2 = G4GeomTools::TriangleAreaNormal(pt[i2],pt[i1],pt[i3]).mag();
|
||||
if ((s1+s2)*G4UniformRand() > s1) i0 = i2;
|
||||
|
||||
// Generate point
|
||||
//
|
||||
G4double u = G4UniformRand();
|
||||
G4double v = G4UniformRand();
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
return (1.-u-v)*pt[i0] + u*pt[i1] + v*pt[i3];
|
||||
G4double u = G4QuickRand();
|
||||
G4double v = G4QuickRand();
|
||||
switch(k)
|
||||
{
|
||||
case 0: // base at -Z
|
||||
{
|
||||
return G4ThreeVector((2.*u - 1.)*fDx1, (2.*v - 1.)*fDy1, -fDz);
|
||||
}
|
||||
case 1: // X face at -Y
|
||||
{
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
G4ThreeVector p0(-fDx1,-fDy1,-fDz);
|
||||
G4ThreeVector p1( fDx2,-fDy2, fDz);
|
||||
return (select <= ssurf[0] + fDx1*fHx) ?
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector( fDx1,-fDy1,-fDz) :
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector(-fDx2,-fDy2, fDz);
|
||||
}
|
||||
case 2: // X face at +Y
|
||||
{
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
G4ThreeVector p0( fDx1, fDy1,-fDz);
|
||||
G4ThreeVector p1(-fDx2, fDy2, fDz);
|
||||
return (select <= ssurf[1] + fDx1*fHx) ?
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector(-fDx1, fDy1,-fDz) :
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector( fDx2, fDy2, fDz);
|
||||
}
|
||||
case 3: // Y face at -X
|
||||
{
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
G4ThreeVector p0(-fDx1, fDy1,-fDz);
|
||||
G4ThreeVector p1(-fDx2,-fDy2, fDz);
|
||||
return (select <= ssurf[2] + fDy1*fHy) ?
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector(-fDx1,-fDy1,-fDz) :
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector(-fDx2, fDy2, fDz);
|
||||
}
|
||||
case 4: // Y face at +X
|
||||
{
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
G4ThreeVector p0( fDx1,-fDy1,-fDz);
|
||||
G4ThreeVector p1( fDx2, fDy2, fDz);
|
||||
return (select <= ssurf[3] + fDy1*fHy) ?
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector( fDx1, fDy1,-fDz) :
|
||||
(1. - u - v)*p0 + u*p1 + v*G4ThreeVector( fDx2,-fDy2, fDz);
|
||||
}
|
||||
case 5: // base at +Z
|
||||
{
|
||||
return G4ThreeVector((2.*u - 1.)*fDx2, (2.*v - 1.)*fDy2, fDz);
|
||||
}
|
||||
}
|
||||
return G4ThreeVector(0., 0., 0.);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -43,12 +43,10 @@
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
|
||||
#include "G4VPVParameterisation.hh"
|
||||
|
||||
#include "Randomize.hh"
|
||||
|
||||
#include "meshdefs.hh"
|
||||
#include "G4QuickRand.hh"
|
||||
|
||||
#include "G4VGraphicsScene.hh"
|
||||
#include "G4Polyhedron.hh"
|
||||
|
||||
using namespace CLHEP;
|
||||
|
||||
@@ -103,7 +101,7 @@ G4Tubs::G4Tubs( __void__& a )
|
||||
fRMin(0.), fRMax(0.), fDz(0.), fSPhi(0.), fDPhi(0.),
|
||||
sinCPhi(0.), cosCPhi(0.), cosHDPhi(0.), cosHDPhiOT(0.), cosHDPhiIT(0.),
|
||||
sinSPhi(0.), cosSPhi(0.), sinEPhi(0.), cosEPhi(0.),
|
||||
fPhiFullTube(false), fInvRmax(0.), fInvRmin(0.),
|
||||
fPhiFullTube(false), fInvRmax(0.), fInvRmin(0.),
|
||||
halfCarTolerance(0.), halfRadTolerance(0.),
|
||||
halfAngTolerance(0.)
|
||||
{
|
||||
@@ -141,7 +139,7 @@ G4Tubs::G4Tubs(const G4Tubs& rhs)
|
||||
//
|
||||
// Assignment operator
|
||||
|
||||
G4Tubs& G4Tubs::operator = (const G4Tubs& rhs)
|
||||
G4Tubs& G4Tubs::operator = (const G4Tubs& rhs)
|
||||
{
|
||||
// Check assignment to self
|
||||
//
|
||||
@@ -232,7 +230,7 @@ void G4Tubs::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
|
||||
G4bool G4Tubs::CalculateExtent( const EAxis pAxis,
|
||||
const G4VoxelLimits& pVoxelLimit,
|
||||
const G4AffineTransform& pTransform,
|
||||
G4double& pMin,
|
||||
G4double& pMin,
|
||||
G4double& pMax ) const
|
||||
{
|
||||
G4ThreeVector bmin, bmax;
|
||||
@@ -352,7 +350,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
|
||||
else { tolRMin = 0 ; }
|
||||
|
||||
tolRMax = fRMax - halfRadTolerance ;
|
||||
|
||||
|
||||
if ((r2 >= tolRMin*tolRMin) && (r2 <= tolRMax*tolRMax))
|
||||
{
|
||||
if ( fPhiFullTube )
|
||||
@@ -378,7 +376,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
|
||||
{
|
||||
if ( (std::fabs(pPhi) < halfAngTolerance)
|
||||
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
|
||||
{
|
||||
{
|
||||
pPhi += twopi ; // 0 <= pPhi < 2pi
|
||||
}
|
||||
if ( (pPhi >= fSPhi + halfAngTolerance)
|
||||
@@ -406,7 +404,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
|
||||
in = kInside ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Try generous boundaries
|
||||
@@ -431,7 +429,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
|
||||
{
|
||||
if ( (std::fabs(pPhi) < halfAngTolerance)
|
||||
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
|
||||
{
|
||||
{
|
||||
pPhi += twopi ; // 0 <= pPhi < 2pi
|
||||
}
|
||||
if ( (pPhi >= fSPhi - halfAngTolerance)
|
||||
@@ -476,7 +474,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
|
||||
{
|
||||
if ( (std::fabs(pPhi) < halfAngTolerance)
|
||||
&& (std::fabs(fSPhi + fDPhi - twopi) < halfAngTolerance) )
|
||||
{
|
||||
{
|
||||
pPhi += twopi ; // 0 <= pPhi < 2pi
|
||||
}
|
||||
if ( (pPhi >= fSPhi - halfAngTolerance)
|
||||
@@ -493,7 +491,7 @@ EInside G4Tubs::Inside( const G4ThreeVector& p ) const
|
||||
{
|
||||
in = kSurface ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,22 +521,22 @@ G4ThreeVector G4Tubs::SurfaceNormal( const G4ThreeVector& p ) const
|
||||
distRMax = std::fabs(rho - fRMax);
|
||||
distZ = std::fabs(std::fabs(p.z()) - fDz);
|
||||
|
||||
if (!fPhiFullTube) // Protected against (0,0,z)
|
||||
if (!fPhiFullTube) // Protected against (0,0,z)
|
||||
{
|
||||
if ( rho > halfCarTolerance )
|
||||
{
|
||||
pPhi = std::atan2(p.y(),p.x());
|
||||
|
||||
|
||||
if (pPhi < fSPhi-halfCarTolerance) { pPhi += twopi; }
|
||||
else if (pPhi > fSPhi+fDPhi+halfCarTolerance) { pPhi -= twopi; }
|
||||
|
||||
distSPhi = std::fabs( pPhi - fSPhi );
|
||||
distEPhi = std::fabs( pPhi - fSPhi - fDPhi );
|
||||
distSPhi = std::fabs( pPhi - fSPhi );
|
||||
distEPhi = std::fabs( pPhi - fSPhi - fDPhi );
|
||||
}
|
||||
else if ( !fRMin )
|
||||
{
|
||||
distSPhi = 0.;
|
||||
distEPhi = 0.;
|
||||
distSPhi = 0.;
|
||||
distEPhi = 0.;
|
||||
}
|
||||
nPs = G4ThreeVector( sinSPhi, -cosSPhi, 0 );
|
||||
nPe = G4ThreeVector( -sinEPhi, cosEPhi, 0 );
|
||||
@@ -555,20 +553,20 @@ G4ThreeVector G4Tubs::SurfaceNormal( const G4ThreeVector& p ) const
|
||||
++noSurfaces;
|
||||
sumnorm -= nR;
|
||||
}
|
||||
if( fDPhi < twopi )
|
||||
if( fDPhi < twopi )
|
||||
{
|
||||
if (distSPhi <= halfAngTolerance)
|
||||
if (distSPhi <= halfAngTolerance)
|
||||
{
|
||||
++noSurfaces;
|
||||
sumnorm += nPs;
|
||||
}
|
||||
if (distEPhi <= halfAngTolerance)
|
||||
if (distEPhi <= halfAngTolerance)
|
||||
{
|
||||
++noSurfaces;
|
||||
sumnorm += nPe;
|
||||
}
|
||||
}
|
||||
if (distZ <= halfCarTolerance)
|
||||
if (distZ <= halfCarTolerance)
|
||||
{
|
||||
++noSurfaces;
|
||||
if ( p.z() >= 0.) { sumnorm += nZ; }
|
||||
@@ -583,7 +581,7 @@ G4ThreeVector G4Tubs::SurfaceNormal( const G4ThreeVector& p ) const
|
||||
G4cout<< "G4Tubs::SN ( "<<p.x()<<", "<<p.y()<<", "<<p.z()<<" ); "
|
||||
<< G4endl << G4endl;
|
||||
G4cout.precision(oldprc) ;
|
||||
#endif
|
||||
#endif
|
||||
norm = ApproxSurfaceNormal(p);
|
||||
}
|
||||
else if ( noSurfaces == 1 ) { norm = sumnorm; }
|
||||
@@ -635,8 +633,8 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
|
||||
distMin = distRMax ;
|
||||
side = kNRMax ;
|
||||
}
|
||||
}
|
||||
if (!fPhiFullTube && rho ) // Protected against (0,0,z)
|
||||
}
|
||||
if (!fPhiFullTube && rho ) // Protected against (0,0,z)
|
||||
{
|
||||
phi = std::atan2(p.y(),p.x()) ;
|
||||
|
||||
@@ -651,7 +649,7 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
|
||||
distSPhi = std::fabs(phi - fSPhi)*rho ;
|
||||
}
|
||||
distEPhi = std::fabs(phi - fSPhi - fDPhi)*rho ;
|
||||
|
||||
|
||||
if (distSPhi < distEPhi) // Find new minimum
|
||||
{
|
||||
if ( distSPhi < distMin )
|
||||
@@ -666,21 +664,21 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
|
||||
side = kNEPhi ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
switch ( side )
|
||||
{
|
||||
case kNRMin : // Inner radius
|
||||
{
|
||||
{
|
||||
norm = G4ThreeVector(-p.x()/rho, -p.y()/rho, 0) ;
|
||||
break ;
|
||||
}
|
||||
case kNRMax : // Outer radius
|
||||
{
|
||||
{
|
||||
norm = G4ThreeVector(p.x()/rho, p.y()/rho, 0) ;
|
||||
break ;
|
||||
}
|
||||
case kNZ : // + or - dz
|
||||
{
|
||||
{
|
||||
if ( p.z() > 0 ) { norm = G4ThreeVector(0,0,1) ; }
|
||||
else { norm = G4ThreeVector(0,0,-1); }
|
||||
break ;
|
||||
@@ -702,8 +700,8 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
|
||||
"GeomSolids1002", JustWarning,
|
||||
"Undefined side for valid surface normal to solid.");
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return norm;
|
||||
}
|
||||
|
||||
@@ -713,7 +711,7 @@ G4ThreeVector G4Tubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
|
||||
// Calculate distance to shape from outside, along normalised vector
|
||||
// - return kInfinity if no intersection, or intersection distance <= tolerance
|
||||
//
|
||||
// - Compute the intersection with the z planes
|
||||
// - Compute the intersection with the z planes
|
||||
// - if at valid r, phi, return
|
||||
//
|
||||
// -> If point is outer outer radius, compute intersection with rmax
|
||||
@@ -740,8 +738,8 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
// Intersection point variables
|
||||
//
|
||||
G4double Dist, sd, xi, yi, zi, rho2, inum, iden, cosPsi, Comp ;
|
||||
G4double t1, t2, t3, b, c, d ; // Quadratic solver variables
|
||||
|
||||
G4double t1, t2, t3, b, c, d ; // Quadratic solver variables
|
||||
|
||||
// Calculate tolerant rmin and rmax
|
||||
|
||||
if (fRMin > kRadTolerance)
|
||||
@@ -837,7 +835,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
{ // 64 bits systems. Split long distances and recompute
|
||||
G4double fTerm = sd-std::fmod(sd,dRmax);
|
||||
sd = fTerm + DistanceToIn(p+fTerm*v,v);
|
||||
}
|
||||
}
|
||||
// Check z intersection
|
||||
//
|
||||
zi = p.z() + sd*v.z() ;
|
||||
@@ -860,7 +858,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
} // end if (sd>=0)
|
||||
} // end if (d>=0)
|
||||
} // end if (r>=fRMax)
|
||||
else
|
||||
else
|
||||
{
|
||||
// Inside outer radius :
|
||||
// check not inside, and heading through tubs (-> 0 to in)
|
||||
@@ -878,11 +876,11 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
{
|
||||
// In the old version, the small negative tangent for the point
|
||||
// on surface was not taken in account, and returning 0.0 ...
|
||||
// New version: check the tangent for the point on surface and
|
||||
// New version: check the tangent for the point on surface and
|
||||
// if no intersection, return kInfinity, if intersection instead
|
||||
// return sd.
|
||||
//
|
||||
c = t3-fRMax*fRMax;
|
||||
c = t3-fRMax*fRMax;
|
||||
if ( c<=0.0 )
|
||||
{
|
||||
return 0.0;
|
||||
@@ -894,26 +892,26 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
if ( d>=0.0 )
|
||||
{
|
||||
snxt = c/(-b+std::sqrt(d)); // using safe solution
|
||||
// for quadratic equation
|
||||
// for quadratic equation
|
||||
if ( snxt < halfCarTolerance ) { snxt=0; }
|
||||
return snxt ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return kInfinity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
// In the old version, the small negative tangent for the point
|
||||
// on surface was not taken in account, and returning 0.0 ...
|
||||
// New version: check the tangent for the point on surface and
|
||||
// New version: check the tangent for the point on surface and
|
||||
// if no intersection, return kInfinity, if intersection instead
|
||||
// return sd.
|
||||
//
|
||||
c = t3 - fRMax*fRMax;
|
||||
c = t3 - fRMax*fRMax;
|
||||
if ( c<=0.0 )
|
||||
{
|
||||
return 0.0;
|
||||
@@ -925,10 +923,10 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
if ( d>=0.0 )
|
||||
{
|
||||
snxt= c/(-b+std::sqrt(d)); // using safe solution
|
||||
// for quadratic equation
|
||||
// for quadratic equation
|
||||
if ( snxt < halfCarTolerance ) { snxt=0; }
|
||||
return snxt ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return kInfinity;
|
||||
@@ -936,7 +934,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
}
|
||||
} // end if (!fPhiFullTube)
|
||||
} // end if (t3>tolIRMin2)
|
||||
} // end if (Inside Outer Radius)
|
||||
} // end if (Inside Outer Radius)
|
||||
if ( fRMin ) // Try inner cylinder intersection
|
||||
{
|
||||
c = (t3 - fRMin*fRMin)/t1 ;
|
||||
@@ -956,7 +954,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
{ // 64 bits systems. Split long distances and recompute
|
||||
G4double fTerm = sd-std::fmod(sd,dRmax);
|
||||
sd = fTerm + DistanceToIn(p+fTerm*v,v);
|
||||
}
|
||||
}
|
||||
zi = p.z() + sd*v.z() ;
|
||||
if (std::fabs(zi) <= tolODz)
|
||||
{
|
||||
@@ -964,7 +962,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
//
|
||||
if ( fPhiFullTube )
|
||||
{
|
||||
return sd ;
|
||||
return sd ;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -999,7 +997,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
// First phi surface (Starting phi)
|
||||
//
|
||||
Comp = v.x()*sinSPhi - v.y()*cosSPhi ;
|
||||
|
||||
|
||||
if ( Comp < 0 ) // Component in outwards normal dirn
|
||||
{
|
||||
Dist = (p.y()*cosSPhi - p.x()*sinSPhi) ;
|
||||
@@ -1033,13 +1031,13 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Second phi surface (Ending phi)
|
||||
|
||||
Comp = -(v.x()*sinEPhi - v.y()*cosEPhi) ;
|
||||
|
||||
|
||||
if (Comp < 0 ) // Component in outwards normal dirn
|
||||
{
|
||||
Dist = -(p.y()*cosEPhi - p.x()*sinEPhi) ;
|
||||
@@ -1074,17 +1072,17 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p,
|
||||
}
|
||||
}
|
||||
} // Comp < 0
|
||||
} // !fPhiFullTube
|
||||
} // !fPhiFullTube
|
||||
if ( snxt<halfCarTolerance ) { snxt=0; }
|
||||
return snxt ;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate distance to shape from outside, along normalised vector
|
||||
// - return kInfinity if no intersection, or intersection distance <= tolerance
|
||||
//
|
||||
// - Compute the intersection with the z planes
|
||||
// - Compute the intersection with the z planes
|
||||
// - if at valid r, phi, return
|
||||
//
|
||||
// -> If point is outer outer radius, compute intersection with rmax
|
||||
@@ -1124,7 +1122,7 @@ G4double G4Tubs::DistanceToIn( const G4ThreeVector& p ) const
|
||||
// Psi=angle from central phi to point
|
||||
//
|
||||
cosPsi = (p.x()*cosCPhi + p.y()*sinCPhi)/rho ;
|
||||
|
||||
|
||||
if ( cosPsi < cosHDPhi )
|
||||
{
|
||||
// Point lies outside phi range
|
||||
@@ -1158,11 +1156,11 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
ESide side=kNull , sider=kNull, sidephi=kNull ;
|
||||
G4double snxt, srd=kInfinity, sphi=kInfinity, pdist ;
|
||||
G4double deltaR, t1, t2, t3, b, c, d2, roMin2 ;
|
||||
|
||||
|
||||
// Vars for phi intersection:
|
||||
|
||||
G4double pDistS, compS, pDistE, compE, sphi2, xi, yi, vphi, roi2 ;
|
||||
|
||||
|
||||
// Z plane intersection
|
||||
|
||||
if (v.z() > 0 )
|
||||
@@ -1229,7 +1227,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
if ( t1 > 0 ) // Check not parallel
|
||||
{
|
||||
// Calculate srd, r exit distance
|
||||
|
||||
|
||||
if ( (t2 >= 0.0) && (roi2 > fRMax*(fRMax + kRadTolerance)) )
|
||||
{
|
||||
// Delta r not negative => leaving via rmax
|
||||
@@ -1253,7 +1251,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
// On tolerant boundary & heading outwards (or perpendicular to)
|
||||
// outer radial surface -> leaving immediately
|
||||
|
||||
if ( calcNorm )
|
||||
if ( calcNorm )
|
||||
{
|
||||
G4double invRho = FastInverseRxy( p, fInvRmax, kNormTolerance );
|
||||
*n = G4ThreeVector(p.x()*invRho,p.y()*invRho,0) ;
|
||||
@@ -1261,10 +1259,10 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
}
|
||||
return snxt = 0 ; // Leaving by rmax immediately
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( t2 < 0. ) // i.e. t2 < 0; Possible rmin intersection
|
||||
{
|
||||
roMin2 = t3 - t2*t2/t1 ; // min ro2 of the plane of movement
|
||||
roMin2 = t3 - t2*t2/t1 ; // min ro2 of the plane of movement
|
||||
|
||||
if ( fRMin && (roMin2 < fRMin*(fRMin - kRadTolerance)) )
|
||||
{
|
||||
@@ -1280,7 +1278,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
|
||||
if (deltaR > kRadTolerance*fRMin)
|
||||
{
|
||||
srd = c/(-b+std::sqrt(d2));
|
||||
srd = c/(-b+std::sqrt(d2));
|
||||
sider = kRMin ;
|
||||
}
|
||||
else
|
||||
@@ -1307,7 +1305,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
if (calcNorm)
|
||||
{
|
||||
G4double invRho = FastInverseRxy( p, fInvRmax, kNormTolerance );
|
||||
*n = G4ThreeVector(p.x()*invRho,p.y()*invRho,0) ;
|
||||
*n = G4ThreeVector(p.x()*invRho,p.y()*invRho,0) ;
|
||||
*validNorm = true ;
|
||||
}
|
||||
return snxt = 0.0;
|
||||
@@ -1339,16 +1337,16 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Phi Intersection
|
||||
|
||||
if ( !fPhiFullTube )
|
||||
{
|
||||
// add angle calculation with correction
|
||||
// add angle calculation with correction
|
||||
// of the difference in domain of atan2 and Sphi
|
||||
//
|
||||
vphi = std::atan2(v.y(),v.x()) ;
|
||||
|
||||
|
||||
if ( vphi < fSPhi - halfAngTolerance ) { vphi += twopi; }
|
||||
else if ( vphi > fSPhi + fDPhi + halfAngTolerance ) { vphi -= twopi; }
|
||||
|
||||
@@ -1364,25 +1362,25 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
|
||||
compS = -sinSPhi*v.x() + cosSPhi*v.y() ;
|
||||
compE = sinEPhi*v.x() - cosEPhi*v.y() ;
|
||||
|
||||
|
||||
sidephi = kNull;
|
||||
|
||||
|
||||
if( ( (fDPhi <= pi) && ( (pDistS <= halfCarTolerance)
|
||||
&& (pDistE <= halfCarTolerance) ) )
|
||||
|| ( (fDPhi > pi) && !((pDistS > halfCarTolerance)
|
||||
&& (pDistE > halfCarTolerance) ) ) )
|
||||
{
|
||||
// Inside both phi *full* planes
|
||||
|
||||
|
||||
if ( compS < 0 )
|
||||
{
|
||||
sphi = pDistS/compS ;
|
||||
|
||||
|
||||
if (sphi >= -halfCarTolerance)
|
||||
{
|
||||
xi = p.x() + sphi*v.x() ;
|
||||
yi = p.y() + sphi*v.y() ;
|
||||
|
||||
|
||||
// Check intersecting with correct half-plane
|
||||
// (if not -> no intersect)
|
||||
//
|
||||
@@ -1405,8 +1403,8 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
if ( pDistS > -halfCarTolerance )
|
||||
{
|
||||
sphi = 0.0 ; // Leave by sphi immediately
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1421,14 +1419,14 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
if ( compE < 0 )
|
||||
{
|
||||
sphi2 = pDistE/compE ;
|
||||
|
||||
|
||||
// Only check further if < starting phi intersection
|
||||
//
|
||||
if ( (sphi2 > -halfCarTolerance) && (sphi2 < sphi) )
|
||||
{
|
||||
xi = p.x() + sphi2*v.x() ;
|
||||
yi = p.y() + sphi2*v.y() ;
|
||||
|
||||
|
||||
if((std::fabs(xi)<=kCarTolerance)&&(std::fabs(yi)<=kCarTolerance))
|
||||
{
|
||||
// Leaving via ending phi
|
||||
@@ -1440,8 +1438,8 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
if ( pDistE <= -halfCarTolerance ) { sphi = sphi2 ; }
|
||||
else { sphi = 0.0 ; }
|
||||
}
|
||||
}
|
||||
else // Check intersecting with correct half-plane
|
||||
}
|
||||
else // Check intersecting with correct half-plane
|
||||
|
||||
if ( (yi*cosCPhi-xi*sinCPhi) >= 0)
|
||||
{
|
||||
@@ -1463,7 +1461,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
{
|
||||
// On z axis + travel not || to z axis -> if phi of vector direction
|
||||
// within phi of shape, Step limited by rmax, else Step =0
|
||||
|
||||
|
||||
if ( (fSPhi - halfAngTolerance <= vphi)
|
||||
&& (vphi <= fSPhi + fDPhi + halfAngTolerance ) )
|
||||
{
|
||||
@@ -1471,7 +1469,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p,
|
||||
}
|
||||
else
|
||||
{
|
||||
sidephi = kSPhi ; // arbitrary
|
||||
sidephi = kSPhi ; // arbitrary
|
||||
sphi = 0.0 ;
|
||||
}
|
||||
}
|
||||
@@ -1596,7 +1594,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p ) const
|
||||
{
|
||||
safeR1 = rho - fRMin ;
|
||||
safeR2 = fRMax - rho ;
|
||||
|
||||
|
||||
if ( safeR1 < safeR2 ) { safe = safeR1 ; }
|
||||
else { safe = safeR2 ; }
|
||||
}
|
||||
@@ -1624,7 +1622,7 @@ G4double G4Tubs::DistanceToOut( const G4ThreeVector& p ) const
|
||||
}
|
||||
if ( safe < 0 ) { safe = 0 ; }
|
||||
|
||||
return safe ;
|
||||
return safe ;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -1674,80 +1672,91 @@ std::ostream& G4Tubs::StreamInfo( std::ostream& os ) const
|
||||
|
||||
G4ThreeVector G4Tubs::GetPointOnSurface() const
|
||||
{
|
||||
G4double xRand, yRand, zRand, phi, cosphi, sinphi, chose,
|
||||
aOne, aTwo, aThr, aFou;
|
||||
G4double rRand;
|
||||
G4double Rmax = fRMax;
|
||||
G4double Rmin = fRMin;
|
||||
G4double hz = 2.*fDz; // height
|
||||
G4double lext = fDPhi*Rmax; // length of external circular arc
|
||||
G4double lint = fDPhi*Rmin; // length of internal circular arc
|
||||
|
||||
aOne = 2.*fDz*fDPhi*fRMax;
|
||||
aTwo = 2.*fDz*fDPhi*fRMin;
|
||||
aThr = 0.5*fDPhi*(fRMax*fRMax-fRMin*fRMin);
|
||||
aFou = 2.*fDz*(fRMax-fRMin);
|
||||
// Set array of surface areas
|
||||
//
|
||||
G4double RRmax = Rmax * Rmax;
|
||||
G4double RRmin = Rmin * Rmin;
|
||||
G4double sbase = 0.5*fDPhi*(RRmax - RRmin);
|
||||
G4double scut = (fDPhi == twopi) ? 0. : hz*(Rmax - Rmin);
|
||||
G4double ssurf[6] = { scut, scut, sbase, sbase, hz*lext, hz*lint };
|
||||
ssurf[1] += ssurf[0];
|
||||
ssurf[2] += ssurf[1];
|
||||
ssurf[3] += ssurf[2];
|
||||
ssurf[4] += ssurf[3];
|
||||
ssurf[5] += ssurf[4];
|
||||
|
||||
phi = G4RandFlat::shoot(fSPhi, fSPhi+fDPhi);
|
||||
cosphi = std::cos(phi);
|
||||
sinphi = std::sin(phi);
|
||||
// Select surface
|
||||
//
|
||||
G4double select = ssurf[5]*G4QuickRand();
|
||||
G4int k = 5;
|
||||
k -= (select <= ssurf[4]);
|
||||
k -= (select <= ssurf[3]);
|
||||
k -= (select <= ssurf[2]);
|
||||
k -= (select <= ssurf[1]);
|
||||
k -= (select <= ssurf[0]);
|
||||
|
||||
rRand = GetRadiusInRing(fRMin,fRMax);
|
||||
|
||||
if( (fSPhi == 0) && (fDPhi == twopi) ) { aFou = 0; }
|
||||
|
||||
chose = G4RandFlat::shoot(0.,aOne+aTwo+2.*aThr+2.*aFou);
|
||||
|
||||
if( (chose >=0) && (chose < aOne) )
|
||||
// Generate point on selected surface
|
||||
//
|
||||
switch(k)
|
||||
{
|
||||
xRand = fRMax*cosphi;
|
||||
yRand = fRMax*sinphi;
|
||||
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
|
||||
return G4ThreeVector (xRand, yRand, zRand);
|
||||
}
|
||||
else if( (chose >= aOne) && (chose < aOne + aTwo) )
|
||||
{
|
||||
xRand = fRMin*cosphi;
|
||||
yRand = fRMin*sinphi;
|
||||
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
|
||||
return G4ThreeVector (xRand, yRand, zRand);
|
||||
}
|
||||
else if( (chose >= aOne + aTwo) && (chose < aOne + aTwo + aThr) )
|
||||
{
|
||||
xRand = rRand*cosphi;
|
||||
yRand = rRand*sinphi;
|
||||
zRand = fDz;
|
||||
return G4ThreeVector (xRand, yRand, zRand);
|
||||
}
|
||||
else if( (chose >= aOne + aTwo + aThr) && (chose < aOne + aTwo + 2.*aThr) )
|
||||
{
|
||||
xRand = rRand*cosphi;
|
||||
yRand = rRand*sinphi;
|
||||
zRand = -1.*fDz;
|
||||
return G4ThreeVector (xRand, yRand, zRand);
|
||||
}
|
||||
else if( (chose >= aOne + aTwo + 2.*aThr)
|
||||
&& (chose < aOne + aTwo + 2.*aThr + aFou) )
|
||||
{
|
||||
xRand = rRand*cosSPhi;
|
||||
yRand = rRand*sinSPhi;
|
||||
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
|
||||
return G4ThreeVector (xRand, yRand, zRand);
|
||||
}
|
||||
else
|
||||
{
|
||||
xRand = rRand*cosEPhi;
|
||||
yRand = rRand*sinEPhi;
|
||||
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
|
||||
return G4ThreeVector (xRand, yRand, zRand);
|
||||
case 0: // start phi cut
|
||||
{
|
||||
G4double r = Rmin + (Rmax - Rmin)*G4QuickRand();
|
||||
return G4ThreeVector(r*cosSPhi, r*sinSPhi, hz*G4QuickRand() - fDz);
|
||||
}
|
||||
case 1: // end phi cut
|
||||
{
|
||||
G4double r = Rmin + (Rmax - Rmin)*G4QuickRand();
|
||||
return G4ThreeVector(r*cosEPhi, r*sinEPhi, hz*G4QuickRand() - fDz);
|
||||
}
|
||||
case 2: // base at -dz
|
||||
{
|
||||
G4double r = std::sqrt(RRmin + (RRmax - RRmin)*G4QuickRand());
|
||||
G4double phi = fSPhi + fDPhi*G4QuickRand();
|
||||
return G4ThreeVector(r*std::cos(phi), r*std::sin(phi), -fDz);
|
||||
}
|
||||
case 3: // base at +dz
|
||||
{
|
||||
G4double r = std::sqrt(RRmin + (RRmax - RRmin)*G4QuickRand());
|
||||
G4double phi = fSPhi + fDPhi*G4QuickRand();
|
||||
return G4ThreeVector(r*std::cos(phi), r*std::sin(phi), fDz);
|
||||
}
|
||||
case 4: // external lateral surface
|
||||
{
|
||||
G4double phi = fSPhi + fDPhi*G4QuickRand();
|
||||
G4double z = hz*G4QuickRand() - fDz;
|
||||
G4double x = Rmax*std::cos(phi);
|
||||
G4double y = Rmax*std::sin(phi);
|
||||
return G4ThreeVector(x,y,z);
|
||||
}
|
||||
case 5: // internal lateral surface
|
||||
{
|
||||
G4double phi = fSPhi + fDPhi*G4QuickRand();
|
||||
G4double z = hz*G4QuickRand() - fDz;
|
||||
G4double x = Rmin*std::cos(phi);
|
||||
G4double y = Rmin*std::sin(phi);
|
||||
return G4ThreeVector(x,y,z);
|
||||
}
|
||||
}
|
||||
return G4ThreeVector(0., 0., 0.);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Methods for visualisation
|
||||
|
||||
void G4Tubs::DescribeYourselfTo ( G4VGraphicsScene& scene ) const
|
||||
void G4Tubs::DescribeYourselfTo ( G4VGraphicsScene& scene ) const
|
||||
{
|
||||
scene.AddSolid (*this) ;
|
||||
}
|
||||
|
||||
G4Polyhedron* G4Tubs::CreatePolyhedron () const
|
||||
G4Polyhedron* G4Tubs::CreatePolyhedron () const
|
||||
{
|
||||
return new G4PolyhedronTubs (fRMin, fRMax, fDz, fSPhi, fDPhi) ;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,20 @@ committal in the source repository !
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
|
||||
30-October-2020 E.Tcherniaev (geom-specific-V10-06-10)
|
||||
- G4Polycone: Revised GetPointOnSurface();
|
||||
Added protected auxiliary method SetSurfaceElements();
|
||||
Removed GetPointOnCone(), GetPointOnTubs(), GetPointOnCut(), GetPointOnRing();
|
||||
- G4GenericPolycone: Revised GetPointOnSurface();
|
||||
Added protected auxiliary method SetSurfaceElements();
|
||||
- G4Polyhedra: Revised GetPointOnSurface();
|
||||
Added protected auxiliary method SetSurfaceElements();
|
||||
Removed GetPointOnPlane(), GetPointOnTriangle();
|
||||
|
||||
01-October-2020 E.Tcherniaev (geom-specific-V10-06-09)
|
||||
- G4Polycone, G4GenericPolycone, G4Polyhedra:
|
||||
implemented GetSurfaceArea(), GetCubicVolume().
|
||||
|
||||
May 21, 2020 Guilherme Lima (geom-specific-V10-06-08)
|
||||
----------------------------
|
||||
- Fix constructor signatures in G4UExtrudedSolid wrappers, to match those in G4 version.
|
||||
|
||||
@@ -88,6 +88,9 @@ class G4GenericPolycone : public G4VCSGfaceted
|
||||
const G4AffineTransform& pTransform,
|
||||
G4double& pmin, G4double& pmax) const;
|
||||
|
||||
G4double GetCubicVolume();
|
||||
G4double GetSurfaceArea();
|
||||
|
||||
G4ThreeVector GetPointOnSurface() const;
|
||||
|
||||
G4GeometryType GetEntityType() const;
|
||||
@@ -135,6 +138,8 @@ class G4GenericPolycone : public G4VCSGfaceted
|
||||
|
||||
// Methods for random point generation
|
||||
|
||||
void SetSurfaceElements() const;
|
||||
|
||||
protected: // without description
|
||||
|
||||
// Here are our parameters
|
||||
@@ -145,9 +150,10 @@ class G4GenericPolycone : public G4VCSGfaceted
|
||||
G4int numCorner; // number RZ points
|
||||
G4PolyconeSideRZ* corners = nullptr; // corner r,z points
|
||||
|
||||
// Our quick test
|
||||
G4EnclosingCylinder* enclosingCylinder = nullptr; // Our quick test
|
||||
|
||||
G4EnclosingCylinder* enclosingCylinder = nullptr;
|
||||
struct surface_element { G4double area = 0.; G4int i0 = 0, i1 = 0, i2 = 0; };
|
||||
mutable std::vector<surface_element>* fElements = nullptr;
|
||||
};
|
||||
|
||||
#include "G4GenericPolycone.icc"
|
||||
|
||||
@@ -106,6 +106,9 @@ class G4Polycone : public G4VCSGfaceted
|
||||
const G4AffineTransform& pTransform,
|
||||
G4double& pmin, G4double& pmax) const;
|
||||
|
||||
G4double GetCubicVolume();
|
||||
G4double GetSurfaceArea();
|
||||
|
||||
G4ThreeVector GetPointOnSurface() const;
|
||||
|
||||
void ComputeDimensions( G4VPVParameterisation* p,
|
||||
@@ -161,23 +164,7 @@ class G4Polycone : public G4VCSGfaceted
|
||||
|
||||
// Methods for random point generation
|
||||
|
||||
G4ThreeVector GetPointOnCone(G4double fRmin1, G4double fRmax1,
|
||||
G4double fRmin2, G4double fRmax2,
|
||||
G4double zOne, G4double zTwo,
|
||||
G4double& totArea) const;
|
||||
|
||||
G4ThreeVector GetPointOnTubs(G4double fRMin, G4double fRMax,
|
||||
G4double zOne, G4double zTwo,
|
||||
G4double& totArea) const;
|
||||
|
||||
G4ThreeVector GetPointOnCut(G4double fRMin1, G4double fRMax1,
|
||||
G4double fRMin2, G4double fRMax2,
|
||||
G4double zOne, G4double zTwo,
|
||||
G4double& totArea) const;
|
||||
|
||||
G4ThreeVector GetPointOnRing(G4double fRMin, G4double fRMax,
|
||||
G4double fRMin2, G4double fRMax2,
|
||||
G4double zOne) const;
|
||||
void SetSurfaceElements() const;
|
||||
|
||||
protected: // without description
|
||||
|
||||
@@ -190,10 +177,10 @@ class G4Polycone : public G4VCSGfaceted
|
||||
G4PolyconeSideRZ* corners = nullptr; // Corner r,z points
|
||||
G4PolyconeHistorical* original_parameters = nullptr; // Original input params
|
||||
|
||||
// Our quick test
|
||||
|
||||
G4EnclosingCylinder* enclosingCylinder = nullptr;
|
||||
G4EnclosingCylinder* enclosingCylinder = nullptr; // Our quick test
|
||||
|
||||
struct surface_element { G4double area = 0.; G4int i0 = 0, i1 = 0, i2 = 0; };
|
||||
mutable std::vector<surface_element>* fElements = nullptr;
|
||||
};
|
||||
|
||||
#include "G4Polycone.icc"
|
||||
|
||||
@@ -115,6 +115,9 @@ class G4Polyhedra : public G4VCSGfaceted
|
||||
|
||||
G4VSolid* Clone() const;
|
||||
|
||||
G4double GetCubicVolume();
|
||||
G4double GetSurfaceArea();
|
||||
|
||||
G4ThreeVector GetPointOnSurface() const;
|
||||
|
||||
std::ostream& StreamInfo( std::ostream& os ) const;
|
||||
@@ -172,11 +175,7 @@ class G4Polyhedra : public G4VCSGfaceted
|
||||
|
||||
// Methods for generation of random points on surface
|
||||
|
||||
G4ThreeVector GetPointOnPlane(G4ThreeVector p0, G4ThreeVector p1,
|
||||
G4ThreeVector p2, G4ThreeVector p3) const;
|
||||
G4ThreeVector GetPointOnTriangle(G4ThreeVector p0, G4ThreeVector p1,
|
||||
G4ThreeVector p2) const;
|
||||
G4ThreeVector GetPointOnSurfaceCorners() const;
|
||||
void SetSurfaceElements() const;
|
||||
|
||||
protected: // without description
|
||||
|
||||
@@ -190,6 +189,9 @@ class G4Polyhedra : public G4VCSGfaceted
|
||||
G4PolyhedraHistorical* original_parameters = nullptr; // original input params
|
||||
|
||||
G4EnclosingCylinder* enclosingCylinder = nullptr;
|
||||
|
||||
struct surface_element { G4double area = 0.; G4int i0 = 0, i1 = 0, i2 = 0; };
|
||||
mutable std::vector<surface_element>* fElements = nullptr;
|
||||
};
|
||||
|
||||
#include "G4Polyhedra.icc"
|
||||
|
||||
@@ -40,30 +40,35 @@
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
|
||||
#include "Randomize.hh"
|
||||
#include "G4QuickRand.hh"
|
||||
|
||||
#include "G4Polyhedron.hh"
|
||||
#include "G4EnclosingCylinder.hh"
|
||||
#include "G4ReduciblePolygon.hh"
|
||||
#include "G4VPVParameterisation.hh"
|
||||
|
||||
namespace
|
||||
{
|
||||
G4Mutex surface_elementsMutex = G4MUTEX_INITIALIZER;
|
||||
}
|
||||
|
||||
using namespace CLHEP;
|
||||
|
||||
// Constructor (generic parameters)
|
||||
//
|
||||
G4GenericPolycone::G4GenericPolycone( const G4String& name,
|
||||
G4GenericPolycone::G4GenericPolycone( const G4String& name,
|
||||
G4double phiStart,
|
||||
G4double phiTotal,
|
||||
G4int numRZ,
|
||||
const G4double r[],
|
||||
const G4double z[] )
|
||||
: G4VCSGfaceted( name )
|
||||
{
|
||||
|
||||
{
|
||||
|
||||
G4ReduciblePolygon *rz = new G4ReduciblePolygon( r, z, numRZ );
|
||||
|
||||
|
||||
Create( phiStart, phiTotal, rz );
|
||||
|
||||
|
||||
// Set original_parameters struct for consistency
|
||||
//
|
||||
//SetOriginalParameters(rz);
|
||||
@@ -91,7 +96,7 @@ void G4GenericPolycone::Create( G4double phiStart,
|
||||
G4Exception("G4GenericPolycone::Create()", "GeomSolids0002",
|
||||
FatalErrorInArgument, message);
|
||||
}
|
||||
|
||||
|
||||
G4double rzArea = rz->Area();
|
||||
if (rzArea < -kCarTolerance)
|
||||
{
|
||||
@@ -105,9 +110,9 @@ void G4GenericPolycone::Create( G4double phiStart,
|
||||
G4Exception("G4GenericPolycone::Create()", "GeomSolids0002",
|
||||
FatalErrorInArgument, message);
|
||||
}
|
||||
|
||||
|
||||
if ( (!rz->RemoveDuplicateVertices( kCarTolerance ))
|
||||
|| (!rz->RemoveRedundantVertices( kCarTolerance )) )
|
||||
|| (!rz->RemoveRedundantVertices( kCarTolerance )) )
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Illegal input parameters - " << GetName() << G4endl
|
||||
@@ -116,7 +121,7 @@ void G4GenericPolycone::Create( G4double phiStart,
|
||||
FatalErrorInArgument, message);
|
||||
}
|
||||
|
||||
if (rz->CrossesItself(1/kInfinity))
|
||||
if (rz->CrossesItself(1/kInfinity))
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Illegal input parameters - " << GetName() << G4endl
|
||||
@@ -140,21 +145,21 @@ void G4GenericPolycone::Create( G4double phiStart,
|
||||
else
|
||||
{
|
||||
phiIsOpen = true;
|
||||
|
||||
|
||||
//
|
||||
// Convert phi into our convention
|
||||
//
|
||||
startPhi = phiStart;
|
||||
while( startPhi < 0 ) // Loop checking, 13.08.2015, G.Cosmo
|
||||
startPhi += twopi;
|
||||
|
||||
|
||||
endPhi = phiStart+phiTotal;
|
||||
while( endPhi < startPhi ) // Loop checking, 13.08.2015, G.Cosmo
|
||||
endPhi += twopi;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Allocate corner array.
|
||||
// Allocate corner array.
|
||||
//
|
||||
corners = new G4PolyconeSideRZ[numCorner];
|
||||
|
||||
@@ -162,7 +167,7 @@ void G4GenericPolycone::Create( G4double phiStart,
|
||||
// Copy corners
|
||||
//
|
||||
G4ReduciblePolygonIterator iterRZ(rz);
|
||||
|
||||
|
||||
G4PolyconeSideRZ* next = corners;
|
||||
iterRZ.Begin();
|
||||
do // Loop checking, 13.08.2015, G.Cosmo
|
||||
@@ -170,13 +175,13 @@ void G4GenericPolycone::Create( G4double phiStart,
|
||||
next->r = iterRZ.GetA();
|
||||
next->z = iterRZ.GetB();
|
||||
} while( ++next, iterRZ.Next() );
|
||||
|
||||
|
||||
//
|
||||
// Allocate face pointer array
|
||||
//
|
||||
numFace = phiIsOpen ? numCorner+2 : numCorner;
|
||||
faces = new G4VCSGface*[numFace];
|
||||
|
||||
|
||||
//
|
||||
// Construct conical faces
|
||||
//
|
||||
@@ -192,9 +197,9 @@ void G4GenericPolycone::Create( G4double phiStart,
|
||||
if (next >= corners+numCorner) next = corners;
|
||||
nextNext = next+1;
|
||||
if (nextNext >= corners+numCorner) nextNext = corners;
|
||||
|
||||
|
||||
if (corner->r < 1/kInfinity && next->r < 1/kInfinity) continue;
|
||||
|
||||
|
||||
//
|
||||
// We must decide here if we can dare declare one of our faces
|
||||
// as having a "valid" normal (i.e. allBehind = true). This
|
||||
@@ -215,11 +220,11 @@ void G4GenericPolycone::Create( G4double phiStart,
|
||||
allBehind = !rz->BisectedBy( corner->r, corner->z,
|
||||
next->r, next->z, kCarTolerance );
|
||||
}
|
||||
|
||||
|
||||
*face++ = new G4PolyconeSide( prev, corner, next, nextNext,
|
||||
startPhi, endPhi-startPhi, phiIsOpen, allBehind );
|
||||
} while( prev=corner, corner=next, corner > corners );
|
||||
|
||||
|
||||
if (phiIsOpen)
|
||||
{
|
||||
//
|
||||
@@ -228,12 +233,12 @@ void G4GenericPolycone::Create( G4double phiStart,
|
||||
*face++ = new G4PolyPhiFace( rz, startPhi, 0, endPhi );
|
||||
*face++ = new G4PolyPhiFace( rz, endPhi, 0, startPhi );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// We might have dropped a face or two: recalculate numFace
|
||||
//
|
||||
numFace = face-faces;
|
||||
|
||||
|
||||
//
|
||||
// Make enclosingCylinder
|
||||
//
|
||||
@@ -255,6 +260,12 @@ G4GenericPolycone::~G4GenericPolycone()
|
||||
{
|
||||
delete [] corners;
|
||||
delete enclosingCylinder;
|
||||
delete fElements;
|
||||
delete fpPolyhedron;
|
||||
corners = nullptr;
|
||||
enclosingCylinder = nullptr;
|
||||
fElements = nullptr;
|
||||
fpPolyhedron = nullptr;
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
@@ -271,16 +282,16 @@ G4GenericPolycone&
|
||||
G4GenericPolycone::operator=( const G4GenericPolycone& source )
|
||||
{
|
||||
if (this == &source) return *this;
|
||||
|
||||
|
||||
G4VCSGfaceted::operator=( source );
|
||||
|
||||
|
||||
delete [] corners;
|
||||
// if (original_parameters) delete original_parameters;
|
||||
|
||||
|
||||
delete enclosingCylinder;
|
||||
|
||||
|
||||
CopyStuff( source );
|
||||
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -300,20 +311,29 @@ void G4GenericPolycone::CopyStuff( const G4GenericPolycone& source )
|
||||
// The corner array
|
||||
//
|
||||
corners = new G4PolyconeSideRZ[numCorner];
|
||||
|
||||
|
||||
G4PolyconeSideRZ *corn = corners,
|
||||
*sourceCorn = source.corners;
|
||||
do // Loop checking, 13.08.2015, G.Cosmo
|
||||
{
|
||||
*corn = *sourceCorn;
|
||||
} while( ++sourceCorn, ++corn < corners+numCorner );
|
||||
|
||||
|
||||
//
|
||||
// Enclosing cylinder
|
||||
//
|
||||
enclosingCylinder = new G4EnclosingCylinder( *source.enclosingCylinder );
|
||||
|
||||
//
|
||||
// Surface elements
|
||||
//
|
||||
delete fElements;
|
||||
fElements = nullptr;
|
||||
|
||||
// Polyhedron
|
||||
//
|
||||
fRebuildPolyhedron = false;
|
||||
delete fpPolyhedron;
|
||||
fpPolyhedron = nullptr;
|
||||
}
|
||||
|
||||
@@ -360,7 +380,7 @@ G4double G4GenericPolycone::DistanceToIn( const G4ThreeVector& p,
|
||||
//
|
||||
if (enclosingCylinder->ShouldMiss(p,v))
|
||||
return kInfinity;
|
||||
|
||||
|
||||
//
|
||||
// Long answer
|
||||
//
|
||||
@@ -595,7 +615,7 @@ std::ostream& G4GenericPolycone::StreamInfo( std::ostream& os ) const
|
||||
<< " starting phi angle : " << startPhi/degree << " degrees \n"
|
||||
<< " ending phi angle : " << endPhi/degree << " degrees \n";
|
||||
G4int i=0;
|
||||
|
||||
|
||||
os << " number of RZ points: " << numCorner << "\n"
|
||||
<< " RZ values (corners): \n";
|
||||
for (i=0; i<numCorner; i++)
|
||||
@@ -609,18 +629,201 @@ std::ostream& G4GenericPolycone::StreamInfo( std::ostream& os ) const
|
||||
return os;
|
||||
}
|
||||
|
||||
// GetPointOnSurface
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4ThreeVector G4GenericPolycone::GetPointOnSurface() const
|
||||
{
|
||||
return GetPointOnSurfaceGeneric();
|
||||
// Return volume
|
||||
|
||||
G4double G4GenericPolycone::GetCubicVolume()
|
||||
{
|
||||
if (fCubicVolume == 0.)
|
||||
{
|
||||
G4double total = 0.;
|
||||
G4int nrz = GetNumRZCorner();
|
||||
G4PolyconeSideRZ a = GetCorner(nrz - 1);
|
||||
for (G4int i=0; i<nrz; ++i)
|
||||
{
|
||||
G4PolyconeSideRZ b = GetCorner(i);
|
||||
total += (b.r*b.r + b.r*a.r + a.r*a.r)*(b.z - a.z);
|
||||
a = b;
|
||||
}
|
||||
fCubicVolume = std::abs(total)*(GetEndPhi() - GetStartPhi())/6.;
|
||||
}
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
// CreatePolyhedron
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Return surface area
|
||||
|
||||
G4double G4GenericPolycone::GetSurfaceArea()
|
||||
{
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
// phi cut area
|
||||
G4int nrz = GetNumRZCorner();
|
||||
G4double scut = 0.;
|
||||
if (IsOpen())
|
||||
{
|
||||
G4PolyconeSideRZ a = GetCorner(nrz - 1);
|
||||
for (G4int i=0; i<nrz; ++i)
|
||||
{
|
||||
G4PolyconeSideRZ b = GetCorner(i);
|
||||
scut += a.r*b.z - a.z*b.r;
|
||||
a = b;
|
||||
}
|
||||
scut = std::abs(scut);
|
||||
}
|
||||
// lateral surface area
|
||||
G4double slat = 0;
|
||||
G4PolyconeSideRZ a = GetCorner(nrz - 1);
|
||||
for (G4int i=0; i<nrz; ++i)
|
||||
{
|
||||
G4PolyconeSideRZ b = GetCorner(i);
|
||||
G4double h = std::sqrt((b.r - a.r)*(b.r - a.r) + (b.z - a.z)*(b.z - a.z));
|
||||
slat += (b.r + a.r)*h;
|
||||
a = b;
|
||||
}
|
||||
slat *= (GetEndPhi() - GetStartPhi())/2.;
|
||||
fSurfaceArea = scut + slat;
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set vector of surface elements, auxiliary method for sampling
|
||||
// random points on surface
|
||||
|
||||
void G4GenericPolycone::SetSurfaceElements() const
|
||||
{
|
||||
fElements = new std::vector<G4GenericPolycone::surface_element>;
|
||||
G4double sarea = 0.;
|
||||
G4int nrz = GetNumRZCorner();
|
||||
|
||||
// set lateral surface elements
|
||||
G4double dphi = GetEndPhi() - GetStartPhi();
|
||||
G4int ia = nrz - 1;
|
||||
for (G4int ib=0; ib<nrz; ++ib)
|
||||
{
|
||||
G4PolyconeSideRZ a = GetCorner(ia);
|
||||
G4PolyconeSideRZ b = GetCorner(ib);
|
||||
G4GenericPolycone::surface_element selem;
|
||||
selem.i0 = ia;
|
||||
selem.i1 = ib;
|
||||
selem.i2 = -1;
|
||||
ia = ib;
|
||||
if (a.r == 0. && b.r == 0.) continue;
|
||||
G4double h = std::sqrt((b.r - a.r)*(b.r - a.r) + (b.z - a.z)*(b.z - a.z));
|
||||
sarea += 0.5*dphi*(b.r + a.r)*h;
|
||||
selem.area = sarea;
|
||||
fElements->push_back(selem);
|
||||
}
|
||||
|
||||
// set elements for phi cuts
|
||||
if (IsOpen())
|
||||
{
|
||||
G4TwoVectorList contourRZ;
|
||||
std::vector<G4int> triangles;
|
||||
for (G4int i=0; i<nrz; ++i)
|
||||
{
|
||||
G4PolyconeSideRZ corner = GetCorner(i);
|
||||
contourRZ.push_back(G4TwoVector(corner.r, corner.z));
|
||||
}
|
||||
G4GeomTools::TriangulatePolygon(contourRZ, triangles);
|
||||
G4int ntria = triangles.size();
|
||||
for (G4int i=0; i<ntria; i+=3)
|
||||
{
|
||||
G4GenericPolycone::surface_element selem;
|
||||
selem.i0 = triangles[i];
|
||||
selem.i1 = triangles[i+1];
|
||||
selem.i2 = triangles[i+2];
|
||||
G4PolyconeSideRZ a = GetCorner(selem.i0);
|
||||
G4PolyconeSideRZ b = GetCorner(selem.i1);
|
||||
G4PolyconeSideRZ c = GetCorner(selem.i2);
|
||||
G4double stria =
|
||||
std::abs(G4GeomTools::TriangleArea(a.r, a.z, b.r, b.z, c.r, c.z));
|
||||
sarea += stria;
|
||||
selem.area = sarea;
|
||||
fElements->push_back(selem); // start phi
|
||||
sarea += stria;
|
||||
selem.area = sarea;
|
||||
selem.i0 += nrz;
|
||||
fElements->push_back(selem); // end phi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generate random point on surface
|
||||
|
||||
G4ThreeVector G4GenericPolycone::GetPointOnSurface() const
|
||||
{
|
||||
// Set surface elements
|
||||
if (!fElements)
|
||||
{
|
||||
G4AutoLock l(&surface_elementsMutex);
|
||||
SetSurfaceElements();
|
||||
l.unlock();
|
||||
}
|
||||
|
||||
// Select surface element
|
||||
G4GenericPolycone::surface_element selem;
|
||||
selem = fElements->back();
|
||||
G4double select = selem.area*G4QuickRand();
|
||||
auto it = std::lower_bound(fElements->begin(), fElements->end(), select,
|
||||
[](const G4GenericPolycone::surface_element& x, G4double val)
|
||||
-> G4bool { return x.area < val; });
|
||||
|
||||
// Generate random point
|
||||
G4double r = 0, z = 0, phi = 0;
|
||||
G4double u = G4QuickRand();
|
||||
G4double v = G4QuickRand();
|
||||
G4int i0 = (*it).i0;
|
||||
G4int i1 = (*it).i1;
|
||||
G4int i2 = (*it).i2;
|
||||
if (i2 < 0) // lateral surface
|
||||
{
|
||||
G4PolyconeSideRZ p0 = GetCorner(i0);
|
||||
G4PolyconeSideRZ p1 = GetCorner(i1);
|
||||
if (p1.r < p0.r)
|
||||
{
|
||||
p0 = GetCorner(i1);
|
||||
p1 = GetCorner(i0);
|
||||
}
|
||||
if (p1.r - p0.r < kCarTolerance) // cylindrical surface
|
||||
{
|
||||
r = (p1.r - p0.r)*u + p0.r;
|
||||
z = (p1.z - p0.z)*u + p0.z;
|
||||
}
|
||||
else // conical surface
|
||||
{
|
||||
r = std::sqrt(p1.r*p1.r*u + p0.r*p0.r*(1. - u));
|
||||
z = p0.z + (p1.z - p0.z)*(r - p0.r)/(p1.r - p0.r);
|
||||
}
|
||||
phi = (GetEndPhi() - GetStartPhi())*v + GetStartPhi();
|
||||
}
|
||||
else // phi cut
|
||||
{
|
||||
G4int nrz = GetNumRZCorner();
|
||||
phi = (i0 < nrz) ? GetStartPhi() : GetEndPhi();
|
||||
if (i0 >= nrz) { i0 -= nrz; }
|
||||
G4PolyconeSideRZ p0 = GetCorner(i0);
|
||||
G4PolyconeSideRZ p1 = GetCorner(i1);
|
||||
G4PolyconeSideRZ p2 = GetCorner(i2);
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
r = (p1.r - p0.r)*u + (p2.r - p0.r)*v + p0.r;
|
||||
z = (p1.z - p0.z)*u + (p2.z - p0.z)*v + p0.z;
|
||||
}
|
||||
return G4ThreeVector(r*std::cos(phi), r*std::sin(phi), z);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CreatePolyhedron
|
||||
|
||||
G4Polyhedron* G4GenericPolycone::CreatePolyhedron() const
|
||||
{
|
||||
{
|
||||
// The following code prepares for:
|
||||
// HepPolyhedron::createPolyhedron(int Nnodes, int Nfaces,
|
||||
// const double xyz[][3],
|
||||
@@ -635,8 +838,8 @@ G4Polyhedron* G4GenericPolycone::CreatePolyhedron() const
|
||||
* array starts from 1 (like in fortran). The indexes can be positive
|
||||
* or negative. Negative sign means that the corresponding edge is
|
||||
* invisible. The normal of the face should be directed to exterior
|
||||
* of the polyhedron.
|
||||
*
|
||||
* of the polyhedron.
|
||||
*
|
||||
* @param Nnodes number of nodes
|
||||
* @param Nfaces number of faces
|
||||
* @param xyz nodes
|
||||
|
||||
@@ -40,17 +40,22 @@
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
|
||||
#include "Randomize.hh"
|
||||
#include "G4QuickRand.hh"
|
||||
|
||||
#include "G4EnclosingCylinder.hh"
|
||||
#include "G4ReduciblePolygon.hh"
|
||||
#include "G4VPVParameterisation.hh"
|
||||
|
||||
namespace
|
||||
{
|
||||
G4Mutex surface_elementsMutex = G4MUTEX_INITIALIZER;
|
||||
}
|
||||
|
||||
using namespace CLHEP;
|
||||
|
||||
// Constructor (GEANT3 style parameters)
|
||||
//
|
||||
G4Polycone::G4Polycone( const G4String& name,
|
||||
//
|
||||
G4Polycone::G4Polycone( const G4String& name,
|
||||
G4double phiStart,
|
||||
G4double phiTotal,
|
||||
G4int numZPlanes,
|
||||
@@ -63,7 +68,7 @@ G4Polycone::G4Polycone( const G4String& name,
|
||||
// Some historical ugliness
|
||||
//
|
||||
original_parameters = new G4PolyconeHistorical();
|
||||
|
||||
|
||||
original_parameters->Start_angle = phiStart;
|
||||
original_parameters->Opening_angle = phiTotal;
|
||||
original_parameters->Num_z_planes = numZPlanes;
|
||||
@@ -72,7 +77,7 @@ G4Polycone::G4Polycone( const G4String& name,
|
||||
original_parameters->Rmax = new G4double[numZPlanes];
|
||||
|
||||
for (G4int i=0; i<numZPlanes; ++i)
|
||||
{
|
||||
{
|
||||
if(rInner[i]>rOuter[i])
|
||||
{
|
||||
DumpInfo();
|
||||
@@ -102,7 +107,7 @@ G4Polycone::G4Polycone( const G4String& name,
|
||||
G4Exception("G4Polycone::G4Polycone()", "GeomSolids0002",
|
||||
FatalErrorInArgument, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
original_parameters->Z_values[i] = zPlane[i];
|
||||
original_parameters->Rmin[i] = rInner[i];
|
||||
original_parameters->Rmax[i] = rOuter[i];
|
||||
@@ -113,33 +118,33 @@ G4Polycone::G4Polycone( const G4String& name,
|
||||
//
|
||||
G4ReduciblePolygon *rz =
|
||||
new G4ReduciblePolygon( rInner, rOuter, zPlane, numZPlanes );
|
||||
|
||||
|
||||
//
|
||||
// Do the real work
|
||||
//
|
||||
Create( phiStart, phiTotal, rz );
|
||||
|
||||
|
||||
delete rz;
|
||||
}
|
||||
|
||||
// Constructor (generic parameters)
|
||||
//
|
||||
G4Polycone::G4Polycone( const G4String& name,
|
||||
G4Polycone::G4Polycone( const G4String& name,
|
||||
G4double phiStart,
|
||||
G4double phiTotal,
|
||||
G4int numRZ,
|
||||
const G4double r[],
|
||||
const G4double z[] )
|
||||
: G4VCSGfaceted( name )
|
||||
{
|
||||
|
||||
{
|
||||
|
||||
G4ReduciblePolygon* rz = new G4ReduciblePolygon( r, z, numRZ );
|
||||
|
||||
|
||||
Create( phiStart, phiTotal, rz );
|
||||
|
||||
|
||||
// Set original_parameters struct for consistency
|
||||
//
|
||||
|
||||
|
||||
G4bool convertible = SetOriginalParameters(rz);
|
||||
|
||||
if(!convertible)
|
||||
@@ -179,7 +184,7 @@ void G4Polycone::Create( G4double phiStart,
|
||||
G4Exception("G4Polycone::Create()", "GeomSolids0002",
|
||||
FatalErrorInArgument, message);
|
||||
}
|
||||
|
||||
|
||||
G4double rzArea = rz->Area();
|
||||
if (rzArea < -kCarTolerance)
|
||||
{
|
||||
@@ -193,9 +198,9 @@ void G4Polycone::Create( G4double phiStart,
|
||||
G4Exception("G4Polycone::Create()", "GeomSolids0002",
|
||||
FatalErrorInArgument, message);
|
||||
}
|
||||
|
||||
|
||||
if ( (!rz->RemoveDuplicateVertices( kCarTolerance ))
|
||||
|| (!rz->RemoveRedundantVertices( kCarTolerance )) )
|
||||
|| (!rz->RemoveRedundantVertices( kCarTolerance )) )
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Illegal input parameters - " << GetName() << G4endl
|
||||
@@ -204,7 +209,7 @@ void G4Polycone::Create( G4double phiStart,
|
||||
FatalErrorInArgument, message);
|
||||
}
|
||||
|
||||
if (rz->CrossesItself(1/kInfinity))
|
||||
if (rz->CrossesItself(1/kInfinity))
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Illegal input parameters - " << GetName() << G4endl
|
||||
@@ -228,21 +233,21 @@ void G4Polycone::Create( G4double phiStart,
|
||||
else
|
||||
{
|
||||
phiIsOpen = true;
|
||||
|
||||
|
||||
//
|
||||
// Convert phi into our convention
|
||||
//
|
||||
startPhi = phiStart;
|
||||
while( startPhi < 0. ) // Loop checking, 13.08.2015, G.Cosmo
|
||||
startPhi += twopi;
|
||||
|
||||
|
||||
endPhi = phiStart+phiTotal;
|
||||
while( endPhi < startPhi ) // Loop checking, 13.08.2015, G.Cosmo
|
||||
endPhi += twopi;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Allocate corner array.
|
||||
// Allocate corner array.
|
||||
//
|
||||
corners = new G4PolyconeSideRZ[numCorner];
|
||||
|
||||
@@ -250,7 +255,7 @@ void G4Polycone::Create( G4double phiStart,
|
||||
// Copy corners
|
||||
//
|
||||
G4ReduciblePolygonIterator iterRZ(rz);
|
||||
|
||||
|
||||
G4PolyconeSideRZ *next = corners;
|
||||
iterRZ.Begin();
|
||||
do // Loop checking, 13.08.2015, G.Cosmo
|
||||
@@ -258,13 +263,13 @@ void G4Polycone::Create( G4double phiStart,
|
||||
next->r = iterRZ.GetA();
|
||||
next->z = iterRZ.GetB();
|
||||
} while( ++next, iterRZ.Next() );
|
||||
|
||||
|
||||
//
|
||||
// Allocate face pointer array
|
||||
//
|
||||
numFace = phiIsOpen ? numCorner+2 : numCorner;
|
||||
faces = new G4VCSGface*[numFace];
|
||||
|
||||
|
||||
//
|
||||
// Construct conical faces
|
||||
//
|
||||
@@ -280,9 +285,9 @@ void G4Polycone::Create( G4double phiStart,
|
||||
if (next >= corners+numCorner) next = corners;
|
||||
nextNext = next+1;
|
||||
if (nextNext >= corners+numCorner) nextNext = corners;
|
||||
|
||||
|
||||
if (corner->r < 1/kInfinity && next->r < 1/kInfinity) continue;
|
||||
|
||||
|
||||
//
|
||||
// We must decide here if we can dare declare one of our faces
|
||||
// as having a "valid" normal (i.e. allBehind = true). This
|
||||
@@ -303,11 +308,11 @@ void G4Polycone::Create( G4double phiStart,
|
||||
allBehind = !rz->BisectedBy( corner->r, corner->z,
|
||||
next->r, next->z, kCarTolerance );
|
||||
}
|
||||
|
||||
|
||||
*face++ = new G4PolyconeSide( prev, corner, next, nextNext,
|
||||
startPhi, endPhi-startPhi, phiIsOpen, allBehind );
|
||||
} while( prev=corner, corner=next, corner > corners );
|
||||
|
||||
|
||||
if (phiIsOpen)
|
||||
{
|
||||
//
|
||||
@@ -316,12 +321,12 @@ void G4Polycone::Create( G4double phiStart,
|
||||
*face++ = new G4PolyPhiFace( rz, startPhi, 0, endPhi );
|
||||
*face++ = new G4PolyPhiFace( rz, endPhi, 0, startPhi );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// We might have dropped a face or two: recalculate numFace
|
||||
//
|
||||
numFace = face-faces;
|
||||
|
||||
|
||||
//
|
||||
// Make enclosingCylinder
|
||||
//
|
||||
@@ -346,6 +351,13 @@ G4Polycone::~G4Polycone()
|
||||
delete [] corners;
|
||||
delete original_parameters;
|
||||
delete enclosingCylinder;
|
||||
delete fElements;
|
||||
delete fpPolyhedron;
|
||||
corners = nullptr;
|
||||
original_parameters = nullptr;
|
||||
enclosingCylinder = nullptr;
|
||||
fElements = nullptr;
|
||||
fpPolyhedron = nullptr;
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
@@ -361,16 +373,16 @@ G4Polycone::G4Polycone( const G4Polycone& source )
|
||||
G4Polycone &G4Polycone::operator=( const G4Polycone& source )
|
||||
{
|
||||
if (this == &source) return *this;
|
||||
|
||||
|
||||
G4VCSGfaceted::operator=( source );
|
||||
|
||||
|
||||
delete [] corners;
|
||||
if (original_parameters) delete original_parameters;
|
||||
|
||||
|
||||
delete enclosingCylinder;
|
||||
|
||||
|
||||
CopyStuff( source );
|
||||
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -383,21 +395,21 @@ void G4Polycone::CopyStuff( const G4Polycone& source )
|
||||
//
|
||||
startPhi = source.startPhi;
|
||||
endPhi = source.endPhi;
|
||||
phiIsOpen = source.phiIsOpen;
|
||||
numCorner = source.numCorner;
|
||||
phiIsOpen = source.phiIsOpen;
|
||||
numCorner = source.numCorner;
|
||||
|
||||
//
|
||||
// The corner array
|
||||
//
|
||||
corners = new G4PolyconeSideRZ[numCorner];
|
||||
|
||||
|
||||
G4PolyconeSideRZ* corn = corners,
|
||||
* sourceCorn = source.corners;
|
||||
do // Loop checking, 13.08.2015, G.Cosmo
|
||||
{
|
||||
*corn = *sourceCorn;
|
||||
} while( ++sourceCorn, ++corn < corners+numCorner );
|
||||
|
||||
|
||||
//
|
||||
// Original parameters
|
||||
//
|
||||
@@ -406,13 +418,23 @@ void G4Polycone::CopyStuff( const G4Polycone& source )
|
||||
original_parameters =
|
||||
new G4PolyconeHistorical( *source.original_parameters );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Enclosing cylinder
|
||||
//
|
||||
enclosingCylinder = new G4EnclosingCylinder( *source.enclosingCylinder );
|
||||
|
||||
//
|
||||
// Surface elements
|
||||
//
|
||||
delete fElements;
|
||||
fElements = nullptr;
|
||||
|
||||
//
|
||||
// Polyhedron
|
||||
//
|
||||
fRebuildPolyhedron = false;
|
||||
delete fpPolyhedron;
|
||||
fpPolyhedron = nullptr;
|
||||
}
|
||||
|
||||
@@ -426,6 +448,10 @@ G4bool G4Polycone::Reset()
|
||||
G4VCSGfaceted::DeleteStuff();
|
||||
delete [] corners;
|
||||
delete enclosingCylinder;
|
||||
delete fElements;
|
||||
corners = nullptr;
|
||||
fElements = nullptr;
|
||||
enclosingCylinder = nullptr;
|
||||
|
||||
//
|
||||
// Rebuild polycone
|
||||
@@ -473,7 +499,7 @@ G4double G4Polycone::DistanceToIn( const G4ThreeVector& p,
|
||||
//
|
||||
if (enclosingCylinder->ShouldMiss(p,v))
|
||||
return kInfinity;
|
||||
|
||||
|
||||
//
|
||||
// Long answer
|
||||
//
|
||||
@@ -701,7 +727,7 @@ std::ostream& G4Polycone::StreamInfo( std::ostream& os ) const
|
||||
<< " starting phi angle : " << startPhi/degree << " degrees \n"
|
||||
<< " ending phi angle : " << endPhi/degree << " degrees \n";
|
||||
G4int i=0;
|
||||
|
||||
|
||||
G4int numPlanes = original_parameters->Num_z_planes;
|
||||
os << " number of Z planes: " << numPlanes << "\n"
|
||||
<< " Z values: \n";
|
||||
@@ -722,7 +748,7 @@ std::ostream& G4Polycone::StreamInfo( std::ostream& os ) const
|
||||
os << " Z plane " << i << ": "
|
||||
<< original_parameters->Rmax[i] << "\n";
|
||||
}
|
||||
|
||||
|
||||
os << " number of RZ points: " << numCorner << "\n"
|
||||
<< " RZ values (corners): \n";
|
||||
for (i=0; i<numCorner; ++i)
|
||||
@@ -736,311 +762,205 @@ std::ostream& G4Polycone::StreamInfo( std::ostream& os ) const
|
||||
return os;
|
||||
}
|
||||
|
||||
// GetPointOnCone
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Auxiliary method for Get Point On Surface
|
||||
//
|
||||
G4ThreeVector G4Polycone::GetPointOnCone(G4double fRmin1, G4double fRmax1,
|
||||
G4double fRmin2, G4double fRmax2,
|
||||
G4double zOne, G4double zTwo,
|
||||
G4double& totArea) const
|
||||
{
|
||||
// declare working variables
|
||||
//
|
||||
G4double Aone, Atwo, Afive, phi, zRand, fDPhi, cosu, sinu;
|
||||
G4double rRand1, rmin, rmax, chose, rone, rtwo, qone, qtwo;
|
||||
G4double fDz=(zTwo-zOne)/2., afDz=std::fabs(fDz);
|
||||
G4ThreeVector point, offset=G4ThreeVector(0.,0.,0.5*(zTwo+zOne));
|
||||
fDPhi = endPhi - startPhi;
|
||||
rone = (fRmax1-fRmax2)/(2.*fDz);
|
||||
rtwo = (fRmin1-fRmin2)/(2.*fDz);
|
||||
if(fRmax1==fRmax2){qone=0.;}
|
||||
else
|
||||
{
|
||||
qone = fDz*(fRmax1+fRmax2)/(fRmax1-fRmax2);
|
||||
}
|
||||
if(fRmin1==fRmin2){qtwo=0.;}
|
||||
else
|
||||
{
|
||||
qtwo = fDz*(fRmin1+fRmin2)/(fRmin1-fRmin2);
|
||||
}
|
||||
Aone = 0.5*fDPhi*(fRmax2 + fRmax1)*(sqr(fRmin1-fRmin2)+sqr(zTwo-zOne));
|
||||
Atwo = 0.5*fDPhi*(fRmin2 + fRmin1)*(sqr(fRmax1-fRmax2)+sqr(zTwo-zOne));
|
||||
Afive = fDz*(fRmax1-fRmin1+fRmax2-fRmin2);
|
||||
totArea = Aone+Atwo+2.*Afive;
|
||||
|
||||
phi = G4RandFlat::shoot(startPhi,endPhi);
|
||||
cosu = std::cos(phi);
|
||||
sinu = std::sin(phi);
|
||||
// Return volume
|
||||
|
||||
|
||||
if( (startPhi == 0.) && (endPhi == twopi) ) { Afive = 0.; }
|
||||
chose = G4RandFlat::shoot(0.,Aone+Atwo+2.*Afive);
|
||||
if( (chose >= 0.) && (chose < Aone) )
|
||||
{
|
||||
if(fRmax1 != fRmax2)
|
||||
{
|
||||
zRand = G4RandFlat::shoot(-1.*afDz,afDz);
|
||||
point = G4ThreeVector (rone*cosu*(qone-zRand),
|
||||
rone*sinu*(qone-zRand), zRand);
|
||||
}
|
||||
else
|
||||
{
|
||||
point = G4ThreeVector(fRmax1*cosu, fRmax1*sinu,
|
||||
G4RandFlat::shoot(-1.*afDz,afDz));
|
||||
|
||||
}
|
||||
}
|
||||
else if(chose >= Aone && chose < Aone + Atwo)
|
||||
{
|
||||
if(fRmin1 != fRmin2)
|
||||
{
|
||||
zRand = G4RandFlat::shoot(-1.*afDz,afDz);
|
||||
point = G4ThreeVector (rtwo*cosu*(qtwo-zRand),
|
||||
rtwo*sinu*(qtwo-zRand), zRand);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
point = G4ThreeVector(fRmin1*cosu, fRmin1*sinu,
|
||||
G4RandFlat::shoot(-1.*afDz,afDz));
|
||||
}
|
||||
}
|
||||
else if( (chose >= Aone + Atwo + Afive) && (chose < Aone + Atwo + 2.*Afive) )
|
||||
{
|
||||
zRand = G4RandFlat::shoot(-1.*afDz,afDz);
|
||||
rmin = fRmin2-((zRand-fDz)/(2.*fDz))*(fRmin1-fRmin2);
|
||||
rmax = fRmax2-((zRand-fDz)/(2.*fDz))*(fRmax1-fRmax2);
|
||||
rRand1 = std::sqrt(G4RandFlat::shoot()*(sqr(rmax)-sqr(rmin))+sqr(rmin));
|
||||
point = G4ThreeVector (rRand1*std::cos(startPhi),
|
||||
rRand1*std::sin(startPhi), zRand);
|
||||
}
|
||||
else
|
||||
{
|
||||
zRand = G4RandFlat::shoot(-1.*afDz,afDz);
|
||||
rmin = fRmin2-((zRand-fDz)/(2.*fDz))*(fRmin1-fRmin2);
|
||||
rmax = fRmax2-((zRand-fDz)/(2.*fDz))*(fRmax1-fRmax2);
|
||||
rRand1 = std::sqrt(G4RandFlat::shoot()*(sqr(rmax)-sqr(rmin))+sqr(rmin));
|
||||
point = G4ThreeVector (rRand1*std::cos(endPhi),
|
||||
rRand1*std::sin(endPhi), zRand);
|
||||
|
||||
}
|
||||
|
||||
return point+offset;
|
||||
}
|
||||
|
||||
// GetPointOnTubs
|
||||
//
|
||||
// Auxiliary method for GetPoint On Surface
|
||||
//
|
||||
G4ThreeVector G4Polycone::GetPointOnTubs(G4double fRMin, G4double fRMax,
|
||||
G4double zOne, G4double zTwo,
|
||||
G4double& totArea) const
|
||||
{
|
||||
G4double xRand,yRand,zRand,phi,cosphi,sinphi,chose,
|
||||
aOne,aTwo,aFou,rRand,fDz,fSPhi,fDPhi;
|
||||
fDz = std::fabs(0.5*(zTwo-zOne));
|
||||
fSPhi = startPhi;
|
||||
fDPhi = endPhi-startPhi;
|
||||
|
||||
aOne = 2.*fDz*fDPhi*fRMax;
|
||||
aTwo = 2.*fDz*fDPhi*fRMin;
|
||||
aFou = 2.*fDz*(fRMax-fRMin);
|
||||
totArea = aOne+aTwo+2.*aFou;
|
||||
phi = G4RandFlat::shoot(startPhi,endPhi);
|
||||
cosphi = std::cos(phi);
|
||||
sinphi = std::sin(phi);
|
||||
rRand = fRMin + (fRMax-fRMin)*std::sqrt(G4RandFlat::shoot());
|
||||
|
||||
if(startPhi == 0. && endPhi == twopi)
|
||||
aFou = 0.;
|
||||
|
||||
chose = G4RandFlat::shoot(0.,aOne+aTwo+2.*aFou);
|
||||
if( (chose >= 0.) && (chose < aOne) )
|
||||
{
|
||||
xRand = fRMax*cosphi;
|
||||
yRand = fRMax*sinphi;
|
||||
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
|
||||
return G4ThreeVector(xRand, yRand, zRand+0.5*(zTwo+zOne));
|
||||
}
|
||||
else if( (chose >= aOne) && (chose < aOne + aTwo) )
|
||||
{
|
||||
xRand = fRMin*cosphi;
|
||||
yRand = fRMin*sinphi;
|
||||
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
|
||||
return G4ThreeVector(xRand, yRand, zRand+0.5*(zTwo+zOne));
|
||||
}
|
||||
else if( (chose >= aOne+aTwo) && (chose <aOne+aTwo+aFou) )
|
||||
{
|
||||
xRand = rRand*std::cos(fSPhi+fDPhi);
|
||||
yRand = rRand*std::sin(fSPhi+fDPhi);
|
||||
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
|
||||
return G4ThreeVector(xRand, yRand, zRand+0.5*(zTwo+zOne));
|
||||
}
|
||||
|
||||
// else
|
||||
|
||||
xRand = rRand*std::cos(fSPhi+fDPhi);
|
||||
yRand = rRand*std::sin(fSPhi+fDPhi);
|
||||
zRand = G4RandFlat::shoot(-1.*fDz,fDz);
|
||||
return G4ThreeVector(xRand, yRand, zRand+0.5*(zTwo+zOne));
|
||||
}
|
||||
|
||||
// GetPointOnRing
|
||||
//
|
||||
// Auxiliary method for GetPoint On Surface
|
||||
//
|
||||
G4ThreeVector G4Polycone::GetPointOnRing(G4double fRMin1, G4double fRMax1,
|
||||
G4double fRMin2,G4double fRMax2,
|
||||
G4double zOne) const
|
||||
G4double G4Polycone::GetCubicVolume()
|
||||
{
|
||||
G4double xRand,yRand,phi,cosphi,sinphi,rRand1,rRand2,A1,Atot,rCh;
|
||||
phi = G4RandFlat::shoot(startPhi,endPhi);
|
||||
cosphi = std::cos(phi);
|
||||
sinphi = std::sin(phi);
|
||||
|
||||
if(fRMin1==fRMin2)
|
||||
if (fCubicVolume == 0.)
|
||||
{
|
||||
rRand1 = fRMin1; A1=0.;
|
||||
G4double total = 0.;
|
||||
G4int nrz = GetNumRZCorner();
|
||||
G4PolyconeSideRZ a = GetCorner(nrz - 1);
|
||||
for (G4int i=0; i<nrz; ++i)
|
||||
{
|
||||
G4PolyconeSideRZ b = GetCorner(i);
|
||||
total += (b.r*b.r + b.r*a.r + a.r*a.r)*(b.z - a.z);
|
||||
a = b;
|
||||
}
|
||||
fCubicVolume = std::abs(total)*(GetEndPhi() - GetStartPhi())/6.;
|
||||
}
|
||||
else
|
||||
{
|
||||
rRand1 = G4RandFlat::shoot(fRMin1,fRMin2);
|
||||
A1=std::fabs(fRMin2*fRMin2-fRMin1*fRMin1);
|
||||
}
|
||||
if(fRMax1==fRMax2)
|
||||
{
|
||||
rRand2=fRMax1; Atot=A1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rRand2 = G4RandFlat::shoot(fRMax1,fRMax2);
|
||||
Atot = A1+std::fabs(fRMax2*fRMax2-fRMax1*fRMax1);
|
||||
}
|
||||
rCh = G4RandFlat::shoot(0.,Atot);
|
||||
|
||||
if(rCh>A1) { rRand1=rRand2; }
|
||||
|
||||
xRand = rRand1*cosphi;
|
||||
yRand = rRand1*sinphi;
|
||||
|
||||
return G4ThreeVector(xRand, yRand, zOne);
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
// GetPointOnCut
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Auxiliary method for Get Point On Surface
|
||||
//
|
||||
G4ThreeVector G4Polycone::GetPointOnCut(G4double fRMin1, G4double fRMax1,
|
||||
G4double fRMin2, G4double fRMax2,
|
||||
G4double zOne, G4double zTwo,
|
||||
G4double& totArea) const
|
||||
{ if(zOne==zTwo)
|
||||
// Return surface area
|
||||
|
||||
G4double G4Polycone::GetSurfaceArea()
|
||||
{
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
// phi cut area
|
||||
G4int nrz = GetNumRZCorner();
|
||||
G4double scut = 0.;
|
||||
if (IsOpen())
|
||||
{
|
||||
return GetPointOnRing(fRMin1, fRMax1,fRMin2,fRMax2,zOne);
|
||||
G4PolyconeSideRZ a = GetCorner(nrz - 1);
|
||||
for (G4int i=0; i<nrz; ++i)
|
||||
{
|
||||
G4PolyconeSideRZ b = GetCorner(i);
|
||||
scut += a.r*b.z - a.z*b.r;
|
||||
a = b;
|
||||
}
|
||||
scut = std::abs(scut);
|
||||
}
|
||||
if( (fRMin1 == fRMin2) && (fRMax1 == fRMax2) )
|
||||
// lateral surface area
|
||||
G4double slat = 0;
|
||||
G4PolyconeSideRZ a = GetCorner(nrz - 1);
|
||||
for (G4int i=0; i<nrz; ++i)
|
||||
{
|
||||
return GetPointOnTubs(fRMin1, fRMax1,zOne,zTwo,totArea);
|
||||
G4PolyconeSideRZ b = GetCorner(i);
|
||||
G4double h = std::sqrt((b.r - a.r)*(b.r - a.r) + (b.z - a.z)*(b.z - a.z));
|
||||
slat += (b.r + a.r)*h;
|
||||
a = b;
|
||||
}
|
||||
return GetPointOnCone(fRMin1,fRMax1,fRMin2,fRMax2,zOne,zTwo,totArea);
|
||||
slat *= (GetEndPhi() - GetStartPhi())/2.;
|
||||
fSurfaceArea = scut + slat;
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
// GetPointOnSurface
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set vector of surface elements, auxiliary method for sampling
|
||||
// random points on surface
|
||||
|
||||
void G4Polycone::SetSurfaceElements() const
|
||||
{
|
||||
fElements = new std::vector<G4Polycone::surface_element>;
|
||||
G4double total = 0.;
|
||||
G4int nrz = GetNumRZCorner();
|
||||
|
||||
// set lateral surface elements
|
||||
G4double dphi = GetEndPhi() - GetStartPhi();
|
||||
G4int ia = nrz - 1;
|
||||
for (G4int ib=0; ib<nrz; ++ib)
|
||||
{
|
||||
G4PolyconeSideRZ a = GetCorner(ia);
|
||||
G4PolyconeSideRZ b = GetCorner(ib);
|
||||
G4Polycone::surface_element selem;
|
||||
selem.i0 = ia;
|
||||
selem.i1 = ib;
|
||||
selem.i2 = -1;
|
||||
ia = ib;
|
||||
if (a.r == 0. && b.r == 0.) continue;
|
||||
G4double h = std::sqrt((b.r - a.r)*(b.r - a.r) + (b.z - a.z)*(b.z - a.z));
|
||||
total += 0.5*dphi*(b.r + a.r)*h;
|
||||
selem.area = total;
|
||||
fElements->push_back(selem);
|
||||
}
|
||||
|
||||
// set elements for phi cuts
|
||||
if (IsOpen())
|
||||
{
|
||||
G4TwoVectorList contourRZ;
|
||||
std::vector<G4int> triangles;
|
||||
for (G4int i=0; i<nrz; ++i)
|
||||
{
|
||||
G4PolyconeSideRZ corner = GetCorner(i);
|
||||
contourRZ.push_back(G4TwoVector(corner.r, corner.z));
|
||||
}
|
||||
G4GeomTools::TriangulatePolygon(contourRZ, triangles);
|
||||
G4int ntria = triangles.size();
|
||||
for (G4int i=0; i<ntria; i+=3)
|
||||
{
|
||||
G4Polycone::surface_element selem;
|
||||
selem.i0 = triangles[i];
|
||||
selem.i1 = triangles[i+1];
|
||||
selem.i2 = triangles[i+2];
|
||||
G4PolyconeSideRZ a = GetCorner(selem.i0);
|
||||
G4PolyconeSideRZ b = GetCorner(selem.i1);
|
||||
G4PolyconeSideRZ c = GetCorner(selem.i2);
|
||||
G4double stria =
|
||||
std::abs(G4GeomTools::TriangleArea(a.r, a.z, b.r, b.z, c.r, c.z));
|
||||
total += stria;
|
||||
selem.area = total;
|
||||
fElements->push_back(selem); // start phi
|
||||
total += stria;
|
||||
selem.area = total;
|
||||
selem.i0 += nrz;
|
||||
fElements->push_back(selem); // end phi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generate random point on surface
|
||||
|
||||
G4ThreeVector G4Polycone::GetPointOnSurface() const
|
||||
{
|
||||
G4double Area=0.,totArea=0.,Achose1=0.,Achose2=0.,phi,cosphi,sinphi,rRand;
|
||||
G4int i=0;
|
||||
G4int numPlanes = original_parameters->Num_z_planes;
|
||||
|
||||
phi = G4RandFlat::shoot(startPhi,endPhi);
|
||||
cosphi = std::cos(phi);
|
||||
sinphi = std::sin(phi);
|
||||
// Set surface elements
|
||||
if (!fElements)
|
||||
{
|
||||
G4AutoLock l(&surface_elementsMutex);
|
||||
SetSurfaceElements();
|
||||
l.unlock();
|
||||
}
|
||||
|
||||
rRand = original_parameters->Rmin[0] +
|
||||
( (original_parameters->Rmax[0]-original_parameters->Rmin[0])
|
||||
* std::sqrt(G4RandFlat::shoot()) );
|
||||
// Select surface element
|
||||
G4Polycone::surface_element selem;
|
||||
selem = fElements->back();
|
||||
G4double select = selem.area*G4QuickRand();
|
||||
auto it = std::lower_bound(fElements->begin(), fElements->end(), select,
|
||||
[](const G4Polycone::surface_element& x, G4double val)
|
||||
-> G4bool { return x.area < val; });
|
||||
|
||||
std::vector<G4double> areas; // (numPlanes+1);
|
||||
std::vector<G4ThreeVector> points; // (numPlanes-1);
|
||||
|
||||
areas.push_back(pi*(sqr(original_parameters->Rmax[0])
|
||||
-sqr(original_parameters->Rmin[0])));
|
||||
|
||||
for(i=0; i<numPlanes-1; ++i)
|
||||
// Generate random point
|
||||
G4double r = 0, z = 0, phi = 0;
|
||||
G4double u = G4QuickRand();
|
||||
G4double v = G4QuickRand();
|
||||
G4int i0 = (*it).i0;
|
||||
G4int i1 = (*it).i1;
|
||||
G4int i2 = (*it).i2;
|
||||
if (i2 < 0) // lateral surface
|
||||
{
|
||||
G4PolyconeSideRZ p0 = GetCorner(i0);
|
||||
G4PolyconeSideRZ p1 = GetCorner(i1);
|
||||
if (p1.r < p0.r)
|
||||
{
|
||||
Area = (original_parameters->Rmin[i]+original_parameters->Rmin[i+1])
|
||||
* std::sqrt(sqr(original_parameters->Rmin[i]
|
||||
-original_parameters->Rmin[i+1])+
|
||||
sqr(original_parameters->Z_values[i+1]
|
||||
-original_parameters->Z_values[i]));
|
||||
|
||||
Area += (original_parameters->Rmax[i]+original_parameters->Rmax[i+1])
|
||||
* std::sqrt(sqr(original_parameters->Rmax[i]
|
||||
-original_parameters->Rmax[i+1])+
|
||||
sqr(original_parameters->Z_values[i+1]
|
||||
-original_parameters->Z_values[i]));
|
||||
|
||||
Area *= 0.5*(endPhi-startPhi);
|
||||
|
||||
if(startPhi==0.&& endPhi == twopi)
|
||||
{
|
||||
Area += std::fabs(original_parameters->Z_values[i+1]
|
||||
-original_parameters->Z_values[i])*
|
||||
(original_parameters->Rmax[i]
|
||||
+original_parameters->Rmax[i+1]
|
||||
-original_parameters->Rmin[i]
|
||||
-original_parameters->Rmin[i+1]);
|
||||
}
|
||||
areas.push_back(Area);
|
||||
totArea += Area;
|
||||
p0 = GetCorner(i1);
|
||||
p1 = GetCorner(i0);
|
||||
}
|
||||
|
||||
areas.push_back(pi*(sqr(original_parameters->Rmax[numPlanes-1])-
|
||||
sqr(original_parameters->Rmin[numPlanes-1])));
|
||||
|
||||
totArea += (areas[0]+areas[numPlanes]);
|
||||
G4double chose = G4RandFlat::shoot(0.,totArea);
|
||||
|
||||
if( (chose>=0.) && (chose<areas[0]) )
|
||||
if (p1.r - p0.r < kCarTolerance) // cylindrical surface
|
||||
{
|
||||
return G4ThreeVector(rRand*cosphi, rRand*sinphi,
|
||||
original_parameters->Z_values[0]);
|
||||
r = (p1.r - p0.r)*u + p0.r;
|
||||
z = (p1.z - p0.z)*u + p0.z;
|
||||
}
|
||||
|
||||
for (i=0; i<numPlanes-1; ++i)
|
||||
else // conical surface
|
||||
{
|
||||
Achose1 += areas[i];
|
||||
Achose2 = (Achose1+areas[i+1]);
|
||||
if(chose>=Achose1 && chose<Achose2)
|
||||
{
|
||||
return GetPointOnCut(original_parameters->Rmin[i],
|
||||
original_parameters->Rmax[i],
|
||||
original_parameters->Rmin[i+1],
|
||||
original_parameters->Rmax[i+1],
|
||||
original_parameters->Z_values[i],
|
||||
original_parameters->Z_values[i+1], Area);
|
||||
}
|
||||
r = std::sqrt(p1.r*p1.r*u + p0.r*p0.r*(1. - u));
|
||||
z = p0.z + (p1.z - p0.z)*(r - p0.r)/(p1.r - p0.r);
|
||||
}
|
||||
|
||||
rRand = original_parameters->Rmin[numPlanes-1] +
|
||||
( (original_parameters->Rmax[numPlanes-1]-original_parameters->Rmin[numPlanes-1])
|
||||
* std::sqrt(G4RandFlat::shoot()) );
|
||||
|
||||
return G4ThreeVector(rRand*cosphi,rRand*sinphi,
|
||||
original_parameters->Z_values[numPlanes-1]);
|
||||
|
||||
phi = (GetEndPhi() - GetStartPhi())*v + GetStartPhi();
|
||||
}
|
||||
else // phi cut
|
||||
{
|
||||
G4int nrz = GetNumRZCorner();
|
||||
phi = (i0 < nrz) ? GetStartPhi() : GetEndPhi();
|
||||
if (i0 >= nrz) { i0 -= nrz; }
|
||||
G4PolyconeSideRZ p0 = GetCorner(i0);
|
||||
G4PolyconeSideRZ p1 = GetCorner(i1);
|
||||
G4PolyconeSideRZ p2 = GetCorner(i2);
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
r = (p1.r - p0.r)*u + (p2.r - p0.r)*v + p0.r;
|
||||
z = (p1.z - p0.z)*u + (p2.z - p0.z)*v + p0.z;
|
||||
}
|
||||
return G4ThreeVector(r*std::cos(phi), r*std::sin(phi), z);
|
||||
}
|
||||
|
||||
// CreatePolyhedron
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CreatePolyhedron
|
||||
|
||||
G4Polyhedron* G4Polycone::CreatePolyhedron() const
|
||||
{
|
||||
{
|
||||
//
|
||||
// This has to be fixed in visualization. Fake it for the moment.
|
||||
//
|
||||
|
||||
//
|
||||
|
||||
return new G4PolyhedronPcon( original_parameters->Start_angle,
|
||||
original_parameters->Opening_angle,
|
||||
original_parameters->Num_z_planes,
|
||||
@@ -1053,12 +973,12 @@ G4Polyhedron* G4Polycone::CreatePolyhedron() const
|
||||
//
|
||||
G4bool G4Polycone::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
{
|
||||
G4int numPlanes = numCorner;
|
||||
G4int numPlanes = numCorner;
|
||||
G4bool isConvertible = true;
|
||||
G4double Zmax=rz->Bmax();
|
||||
rz->StartWithZMin();
|
||||
|
||||
// Prepare vectors for storage
|
||||
// Prepare vectors for storage
|
||||
//
|
||||
std::vector<G4double> Z;
|
||||
std::vector<G4double> Rmin;
|
||||
@@ -1074,24 +994,24 @@ G4bool G4Polycone::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
G4double Zprev=Z[0];
|
||||
if (Zprev == corners[1].z)
|
||||
{
|
||||
Rmin.push_back(corners[0].r);
|
||||
Rmax.push_back (corners[1].r);icurr=1;
|
||||
Rmin.push_back(corners[0].r);
|
||||
Rmax.push_back (corners[1].r);icurr=1;
|
||||
}
|
||||
else if (Zprev == corners[numPlanes-1].z)
|
||||
{
|
||||
Rmin.push_back(corners[numPlanes-1].r);
|
||||
Rmin.push_back(corners[numPlanes-1].r);
|
||||
Rmax.push_back (corners[0].r);
|
||||
icurl=numPlanes-1;
|
||||
icurl=numPlanes-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Rmin.push_back(corners[0].r);
|
||||
Rmin.push_back(corners[0].r);
|
||||
Rmax.push_back (corners[0].r);
|
||||
}
|
||||
|
||||
// next planes until last
|
||||
//
|
||||
G4int inextr=0, inextl=0;
|
||||
G4int inextr=0, inextl=0;
|
||||
for (G4int i=0; i < numPlanes-2; ++i)
|
||||
{
|
||||
inextr=1+icurr;
|
||||
@@ -1103,7 +1023,7 @@ G4bool G4Polycone::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
G4double Zright = corners[inextr].z;
|
||||
if(Zright > Zleft) // Next plane will be Zleft
|
||||
{
|
||||
Z.push_back(Zleft);
|
||||
Z.push_back(Zleft);
|
||||
countPlanes++;
|
||||
G4double difZr=corners[inextr].z - corners[icurr].z;
|
||||
G4double difZl=corners[inextl].z - corners[icurl].z;
|
||||
@@ -1119,7 +1039,7 @@ G4bool G4Polycone::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
{
|
||||
Rmin.push_back(corners[inextl].r);
|
||||
Rmax.push_back(corners[icurr].r + (Zleft-corners[icurr].z)/difZr
|
||||
*(corners[inextr].r - corners[icurr].r));
|
||||
*(corners[inextr].r - corners[icurr].r));
|
||||
}
|
||||
}
|
||||
else if (difZl >= kCarTolerance)
|
||||
@@ -1144,18 +1064,18 @@ G4bool G4Polycone::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
}
|
||||
else if(std::fabs(Zright-Zleft)<kCarTolerance) // Zright=Zleft
|
||||
{
|
||||
Z.push_back(Zleft);
|
||||
Z.push_back(Zleft);
|
||||
++countPlanes;
|
||||
++icurr;
|
||||
|
||||
icurl=(icurl == 0)? numPlanes-1 : icurl-1;
|
||||
|
||||
Rmin.push_back(corners[inextl].r);
|
||||
Rmin.push_back(corners[inextl].r);
|
||||
Rmax.push_back(corners[inextr].r);
|
||||
}
|
||||
else // Zright<Zleft
|
||||
{
|
||||
Z.push_back(Zright);
|
||||
Z.push_back(Zright);
|
||||
++countPlanes;
|
||||
|
||||
G4double difZr=corners[inextr].z - corners[icurr].z;
|
||||
@@ -1165,8 +1085,8 @@ G4bool G4Polycone::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
if(std::fabs(difZl) < kCarTolerance)
|
||||
{
|
||||
Rmax.push_back(corners[inextr].r);
|
||||
Rmin.push_back(corners[icurr].r);
|
||||
}
|
||||
Rmin.push_back(corners[icurr].r);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rmin.push_back(corners[icurl].r + (Zright-corners[icurl].z)/difZl
|
||||
@@ -1180,8 +1100,8 @@ G4bool G4Polycone::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
if(std::fabs(difZl) < kCarTolerance)
|
||||
{
|
||||
Rmax.push_back(corners[inextr].r);
|
||||
Rmin.push_back (corners[icurr].r);
|
||||
}
|
||||
Rmin.push_back (corners[icurr].r);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rmax.push_back(corners[inextr].r);
|
||||
@@ -1203,7 +1123,7 @@ G4bool G4Polycone::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
++countPlanes;
|
||||
inextr=1+icurr;
|
||||
inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
|
||||
|
||||
|
||||
Rmax.push_back(corners[inextr].r);
|
||||
Rmin.push_back(corners[inextl].r);
|
||||
|
||||
@@ -1215,7 +1135,7 @@ G4bool G4Polycone::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
original_parameters->Z_values = new G4double[countPlanes];
|
||||
original_parameters->Rmin = new G4double[countPlanes];
|
||||
original_parameters->Rmax = new G4double[countPlanes];
|
||||
|
||||
|
||||
for(G4int j=0; j < countPlanes; ++j)
|
||||
{
|
||||
original_parameters->Z_values[j] = Z[j];
|
||||
@@ -1225,7 +1145,7 @@ G4bool G4Polycone::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
original_parameters->Start_angle = startPhi;
|
||||
original_parameters->Opening_angle = endPhi-startPhi;
|
||||
original_parameters->Num_z_planes = countPlanes;
|
||||
|
||||
|
||||
}
|
||||
else // Set parameters(r,z) with Rmin==0 as convention
|
||||
{
|
||||
@@ -1240,7 +1160,7 @@ G4bool G4Polycone::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
original_parameters->Z_values = new G4double[numPlanes];
|
||||
original_parameters->Rmin = new G4double[numPlanes];
|
||||
original_parameters->Rmax = new G4double[numPlanes];
|
||||
|
||||
|
||||
for(G4int j=0; j < numPlanes; ++j)
|
||||
{
|
||||
original_parameters->Z_values[j] = corners[j].z;
|
||||
|
||||
@@ -51,24 +51,27 @@
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
|
||||
#include "Randomize.hh"
|
||||
#include "G4QuickRand.hh"
|
||||
|
||||
#include "G4EnclosingCylinder.hh"
|
||||
#include "G4ReduciblePolygon.hh"
|
||||
#include "G4VPVParameterisation.hh"
|
||||
|
||||
#include <sstream>
|
||||
namespace
|
||||
{
|
||||
G4Mutex surface_elementsMutex = G4MUTEX_INITIALIZER;
|
||||
}
|
||||
|
||||
using namespace CLHEP;
|
||||
|
||||
// Constructor (GEANT3 style parameters)
|
||||
//
|
||||
// GEANT3 PGON radii are specified in the distance to the norm of each face.
|
||||
//
|
||||
G4Polyhedra::G4Polyhedra( const G4String& name,
|
||||
//
|
||||
G4Polyhedra::G4Polyhedra( const G4String& name,
|
||||
G4double phiStart,
|
||||
G4double thePhiTotal,
|
||||
G4int theNumSide,
|
||||
G4int theNumSide,
|
||||
G4int numZPlanes,
|
||||
const G4double zPlane[],
|
||||
const G4double rInner[],
|
||||
@@ -96,7 +99,7 @@ G4Polyhedra::G4Polyhedra( const G4String& name,
|
||||
// Some historical stuff
|
||||
//
|
||||
original_parameters = new G4PolyhedraHistorical;
|
||||
|
||||
|
||||
original_parameters->numSide = theNumSide;
|
||||
original_parameters->Start_angle = phiStart;
|
||||
original_parameters->Opening_angle = phiTotal;
|
||||
@@ -129,34 +132,34 @@ G4Polyhedra::G4Polyhedra( const G4String& name,
|
||||
original_parameters->Rmin[i] = rInner[i]/convertRad;
|
||||
original_parameters->Rmax[i] = rOuter[i]/convertRad;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Build RZ polygon using special PCON/PGON GEANT3 constructor
|
||||
//
|
||||
G4ReduciblePolygon* rz =
|
||||
new G4ReduciblePolygon( rInner, rOuter, zPlane, numZPlanes );
|
||||
rz->ScaleA( 1/convertRad );
|
||||
|
||||
|
||||
//
|
||||
// Do the real work
|
||||
//
|
||||
Create( phiStart, phiTotal, theNumSide, rz );
|
||||
|
||||
|
||||
delete rz;
|
||||
}
|
||||
|
||||
// Constructor (generic parameters)
|
||||
//
|
||||
G4Polyhedra::G4Polyhedra( const G4String& name,
|
||||
G4Polyhedra::G4Polyhedra( const G4String& name,
|
||||
G4double phiStart,
|
||||
G4double phiTotal,
|
||||
G4int theNumSide,
|
||||
G4int theNumSide,
|
||||
G4int numRZ,
|
||||
const G4double r[],
|
||||
const G4double z[] )
|
||||
: G4VCSGfaceted( name ), genericPgon(true)
|
||||
{
|
||||
{
|
||||
if (theNumSide <= 0)
|
||||
{
|
||||
std::ostringstream message;
|
||||
@@ -167,13 +170,13 @@ G4Polyhedra::G4Polyhedra( const G4String& name,
|
||||
}
|
||||
|
||||
G4ReduciblePolygon* rz = new G4ReduciblePolygon( r, z, numRZ );
|
||||
|
||||
|
||||
Create( phiStart, phiTotal, theNumSide, rz );
|
||||
|
||||
|
||||
// Set original_parameters struct for consistency
|
||||
//
|
||||
SetOriginalParameters(rz);
|
||||
|
||||
|
||||
delete rz;
|
||||
}
|
||||
|
||||
@@ -184,7 +187,7 @@ G4Polyhedra::G4Polyhedra( const G4String& name,
|
||||
//
|
||||
void G4Polyhedra::Create( G4double phiStart,
|
||||
G4double phiTotal,
|
||||
G4int theNumSide,
|
||||
G4int theNumSide,
|
||||
G4ReduciblePolygon* rz )
|
||||
{
|
||||
//
|
||||
@@ -212,9 +215,9 @@ void G4Polyhedra::Create( G4double phiStart,
|
||||
G4Exception("G4Polyhedra::Create()", "GeomSolids0002",
|
||||
FatalErrorInArgument, message);
|
||||
}
|
||||
|
||||
|
||||
if ( (!rz->RemoveDuplicateVertices( kCarTolerance ))
|
||||
|| (!rz->RemoveRedundantVertices( kCarTolerance )) )
|
||||
|| (!rz->RemoveRedundantVertices( kCarTolerance )) )
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Illegal input parameters - " << GetName() << G4endl
|
||||
@@ -223,7 +226,7 @@ void G4Polyhedra::Create( G4double phiStart,
|
||||
FatalErrorInArgument, message);
|
||||
}
|
||||
|
||||
if (rz->CrossesItself( 1/kInfinity ))
|
||||
if (rz->CrossesItself( 1/kInfinity ))
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Illegal input parameters - " << GetName() << G4endl
|
||||
@@ -250,7 +253,7 @@ void G4Polyhedra::Create( G4double phiStart,
|
||||
else
|
||||
{
|
||||
phiIsOpen = true;
|
||||
|
||||
|
||||
//
|
||||
// Convert phi into our convention
|
||||
//
|
||||
@@ -258,14 +261,14 @@ void G4Polyhedra::Create( G4double phiStart,
|
||||
while( endPhi < startPhi ) // Loop checking, 13.08.2015, G.Cosmo
|
||||
endPhi += twopi;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Save number sides
|
||||
//
|
||||
numSide = theNumSide;
|
||||
|
||||
|
||||
//
|
||||
// Allocate corner array.
|
||||
// Allocate corner array.
|
||||
//
|
||||
corners = new G4PolyhedraSideRZ[numCorner];
|
||||
|
||||
@@ -273,7 +276,7 @@ void G4Polyhedra::Create( G4double phiStart,
|
||||
// Copy corners
|
||||
//
|
||||
G4ReduciblePolygonIterator iterRZ(rz);
|
||||
|
||||
|
||||
G4PolyhedraSideRZ *next = corners;
|
||||
iterRZ.Begin();
|
||||
do // Loop checking, 13.08.2015, G.Cosmo
|
||||
@@ -281,13 +284,13 @@ void G4Polyhedra::Create( G4double phiStart,
|
||||
next->r = iterRZ.GetA();
|
||||
next->z = iterRZ.GetB();
|
||||
} while( ++next, iterRZ.Next() );
|
||||
|
||||
|
||||
//
|
||||
// Allocate face pointer array
|
||||
//
|
||||
numFace = phiIsOpen ? numCorner+2 : numCorner;
|
||||
faces = new G4VCSGface*[numFace];
|
||||
|
||||
|
||||
//
|
||||
// Construct side faces
|
||||
//
|
||||
@@ -306,7 +309,7 @@ void G4Polyhedra::Create( G4double phiStart,
|
||||
if (next >= corners+numCorner) next = corners;
|
||||
nextNext = next+1;
|
||||
if (nextNext >= corners+numCorner) nextNext = corners;
|
||||
|
||||
|
||||
if (corner->r < 1/kInfinity && next->r < 1/kInfinity) continue;
|
||||
/*
|
||||
// We must decide here if we can dare declare one of our faces
|
||||
@@ -333,7 +336,7 @@ void G4Polyhedra::Create( G4double phiStart,
|
||||
*face++ = new G4PolyhedraSide( prev, corner, next, nextNext,
|
||||
numSide, startPhi, endPhi-startPhi, phiIsOpen );
|
||||
} while( prev=corner, corner=next, corner > corners );
|
||||
|
||||
|
||||
if (phiIsOpen)
|
||||
{
|
||||
//
|
||||
@@ -342,12 +345,12 @@ void G4Polyhedra::Create( G4double phiStart,
|
||||
*face++ = new G4PolyPhiFace( rz, startPhi, phiTotal/numSide, endPhi );
|
||||
*face++ = new G4PolyPhiFace( rz, endPhi, phiTotal/numSide, startPhi );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// We might have dropped a face or two: recalculate numFace
|
||||
//
|
||||
numFace = face-faces;
|
||||
|
||||
|
||||
//
|
||||
// Make enclosingCylinder
|
||||
//
|
||||
@@ -370,6 +373,13 @@ G4Polyhedra::~G4Polyhedra()
|
||||
delete [] corners;
|
||||
delete original_parameters;
|
||||
delete enclosingCylinder;
|
||||
delete fElements;
|
||||
delete fpPolyhedron;
|
||||
corners = nullptr;
|
||||
original_parameters = nullptr;
|
||||
enclosingCylinder = nullptr;
|
||||
fElements = nullptr;
|
||||
fpPolyhedron = nullptr;
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
@@ -387,13 +397,13 @@ G4Polyhedra &G4Polyhedra::operator=( const G4Polyhedra& source )
|
||||
if (this == &source) return *this;
|
||||
|
||||
G4VCSGfaceted::operator=( source );
|
||||
|
||||
|
||||
delete [] corners;
|
||||
delete original_parameters;
|
||||
delete enclosingCylinder;
|
||||
|
||||
|
||||
CopyStuff( source );
|
||||
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -415,14 +425,14 @@ void G4Polyhedra::CopyStuff( const G4Polyhedra& source )
|
||||
// The corner array
|
||||
//
|
||||
corners = new G4PolyhedraSideRZ[numCorner];
|
||||
|
||||
|
||||
G4PolyhedraSideRZ* corn = corners,
|
||||
* sourceCorn = source.corners;
|
||||
do // Loop checking, 13.08.2015, G.Cosmo
|
||||
{
|
||||
*corn = *sourceCorn;
|
||||
} while( ++sourceCorn, ++corn < corners+numCorner );
|
||||
|
||||
|
||||
//
|
||||
// Original parameters
|
||||
//
|
||||
@@ -431,13 +441,23 @@ void G4Polyhedra::CopyStuff( const G4Polyhedra& source )
|
||||
original_parameters =
|
||||
new G4PolyhedraHistorical( *source.original_parameters );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Enclosing cylinder
|
||||
//
|
||||
enclosingCylinder = new G4EnclosingCylinder( *source.enclosingCylinder );
|
||||
|
||||
//
|
||||
// Surface elements
|
||||
//
|
||||
delete fElements;
|
||||
fElements = nullptr;
|
||||
|
||||
//
|
||||
// Polyhedron
|
||||
//
|
||||
fRebuildPolyhedron = false;
|
||||
delete fpPolyhedron;
|
||||
fpPolyhedron = nullptr;
|
||||
}
|
||||
|
||||
@@ -464,6 +484,10 @@ G4bool G4Polyhedra::Reset()
|
||||
G4VCSGfaceted::DeleteStuff();
|
||||
delete [] corners;
|
||||
delete enclosingCylinder;
|
||||
delete fElements;
|
||||
corners = nullptr;
|
||||
fElements = nullptr;
|
||||
enclosingCylinder = nullptr;
|
||||
|
||||
//
|
||||
// Rebuild polyhedra
|
||||
@@ -512,7 +536,7 @@ G4double G4Polyhedra::DistanceToIn( const G4ThreeVector& p,
|
||||
//
|
||||
if (enclosingCylinder->ShouldMiss(p,v))
|
||||
return kInfinity;
|
||||
|
||||
|
||||
//
|
||||
// Long answer
|
||||
//
|
||||
@@ -783,274 +807,235 @@ std::ostream& G4Polyhedra::StreamInfo( std::ostream& os ) const
|
||||
return os;
|
||||
}
|
||||
|
||||
// GetPointOnPlane
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Auxiliary method for get point on surface
|
||||
//
|
||||
G4ThreeVector
|
||||
G4Polyhedra::GetPointOnPlane(G4ThreeVector p0, G4ThreeVector p1,
|
||||
G4ThreeVector p2, G4ThreeVector p3) const
|
||||
// Return volume
|
||||
|
||||
G4double G4Polyhedra::GetCubicVolume()
|
||||
{
|
||||
G4double lambda1, lambda2, chose,aOne,aTwo;
|
||||
G4ThreeVector t, u, v, w, Area, normal;
|
||||
aOne = 1.;
|
||||
aTwo = 1.;
|
||||
|
||||
t = p1 - p0;
|
||||
u = p2 - p1;
|
||||
v = p3 - p2;
|
||||
w = p0 - p3;
|
||||
|
||||
chose = G4RandFlat::shoot(0.,aOne+aTwo);
|
||||
if( (chose>=0.) && (chose < aOne) )
|
||||
if (fCubicVolume == 0.)
|
||||
{
|
||||
lambda1 = G4RandFlat::shoot(0.,1.);
|
||||
lambda2 = G4RandFlat::shoot(0.,lambda1);
|
||||
return (p2+lambda1*v+lambda2*w);
|
||||
G4double total = 0.;
|
||||
G4int nrz = GetNumRZCorner();
|
||||
G4PolyhedraSideRZ a = GetCorner(nrz - 1);
|
||||
for (G4int i=0; i<nrz; ++i)
|
||||
{
|
||||
G4PolyhedraSideRZ b = GetCorner(i);
|
||||
total += (b.r*b.r + b.r*a.r + a.r*a.r)*(b.z - a.z);
|
||||
a = b;
|
||||
}
|
||||
fCubicVolume = std::abs(total)*
|
||||
std::sin((GetEndPhi() - GetStartPhi())/GetNumSide())*GetNumSide()/6.;
|
||||
}
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Return surface area
|
||||
|
||||
G4double G4Polyhedra::GetSurfaceArea()
|
||||
{
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
G4double total = 0.;
|
||||
G4int nrz = GetNumRZCorner();
|
||||
if (IsOpen())
|
||||
{
|
||||
G4PolyhedraSideRZ a = GetCorner(nrz - 1);
|
||||
for (G4int i=0; i<nrz; ++i)
|
||||
{
|
||||
G4PolyhedraSideRZ b = GetCorner(i);
|
||||
total += a.r*b.z - a.z*b.r;
|
||||
a = b;
|
||||
}
|
||||
total = std::abs(total);
|
||||
}
|
||||
G4double alp = (GetEndPhi() - GetStartPhi())/GetNumSide();
|
||||
G4double cosa = std::cos(alp);
|
||||
G4double sina = std::sin(alp);
|
||||
G4PolyhedraSideRZ a = GetCorner(nrz - 1);
|
||||
for (G4int i=0; i<nrz; ++i)
|
||||
{
|
||||
G4PolyhedraSideRZ b = GetCorner(i);
|
||||
G4ThreeVector p1(a.r, 0, a.z);
|
||||
G4ThreeVector p2(a.r*cosa, a.r*sina, a.z);
|
||||
G4ThreeVector p3(b.r*cosa, b.r*sina, b.z);
|
||||
G4ThreeVector p4(b.r, 0, b.z);
|
||||
total += GetNumSide()*(G4GeomTools::QuadAreaNormal(p1, p2, p3, p4)).mag();
|
||||
a = b;
|
||||
}
|
||||
fSurfaceArea = total;
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set vector of surface elements, auxiliary method for sampling
|
||||
// random points on surface
|
||||
|
||||
void G4Polyhedra::SetSurfaceElements() const
|
||||
{
|
||||
fElements = new std::vector<G4Polyhedra::surface_element>;
|
||||
G4double total = 0.;
|
||||
G4int nrz = GetNumRZCorner();
|
||||
|
||||
// set lateral surface elements
|
||||
G4double dphi = (GetEndPhi() - GetStartPhi())/GetNumSide();
|
||||
G4double cosa = std::cos(dphi);
|
||||
G4double sina = std::sin(dphi);
|
||||
G4int ia = nrz - 1;
|
||||
for (G4int ib=0; ib<nrz; ++ib)
|
||||
{
|
||||
G4PolyhedraSideRZ a = GetCorner(ia);
|
||||
G4PolyhedraSideRZ b = GetCorner(ib);
|
||||
G4Polyhedra::surface_element selem;
|
||||
selem.i0 = ia;
|
||||
selem.i1 = ib;
|
||||
ia = ib;
|
||||
if (a.r == 0. && b.r == 0.) continue;
|
||||
G4ThreeVector p1(a.r, 0, a.z);
|
||||
G4ThreeVector p2(a.r*cosa, a.r*sina, a.z);
|
||||
G4ThreeVector p3(b.r*cosa, b.r*sina, b.z);
|
||||
G4ThreeVector p4(b.r, 0, b.z);
|
||||
if (a.r > 0.)
|
||||
{
|
||||
selem.i2 = -1;
|
||||
total += GetNumSide()*(G4GeomTools::TriangleAreaNormal(p1, p2, p3)).mag();
|
||||
selem.area = total;
|
||||
fElements->push_back(selem);
|
||||
}
|
||||
if (b.r > 0.)
|
||||
{
|
||||
selem.i2 = -2;
|
||||
total += GetNumSide()*(G4GeomTools::TriangleAreaNormal(p1, p3, p4)).mag();
|
||||
selem.area = total;
|
||||
fElements->push_back(selem);
|
||||
}
|
||||
}
|
||||
|
||||
lambda1 = G4RandFlat::shoot(0.,1.);
|
||||
lambda2 = G4RandFlat::shoot(0.,lambda1);
|
||||
return (p0+lambda1*t+lambda2*u);
|
||||
// set elements for phi cuts
|
||||
if (IsOpen())
|
||||
{
|
||||
G4TwoVectorList contourRZ;
|
||||
std::vector<G4int> triangles;
|
||||
for (G4int i=0; i<nrz; ++i)
|
||||
{
|
||||
G4PolyhedraSideRZ corner = GetCorner(i);
|
||||
contourRZ.push_back(G4TwoVector(corner.r, corner.z));
|
||||
}
|
||||
G4GeomTools::TriangulatePolygon(contourRZ, triangles);
|
||||
G4int ntria = triangles.size();
|
||||
for (G4int i=0; i<ntria; i+=3)
|
||||
{
|
||||
G4Polyhedra::surface_element selem;
|
||||
selem.i0 = triangles[i];
|
||||
selem.i1 = triangles[i+1];
|
||||
selem.i2 = triangles[i+2];
|
||||
G4PolyhedraSideRZ a = GetCorner(selem.i0);
|
||||
G4PolyhedraSideRZ b = GetCorner(selem.i1);
|
||||
G4PolyhedraSideRZ c = GetCorner(selem.i2);
|
||||
G4double stria =
|
||||
std::abs(G4GeomTools::TriangleArea(a.r, a.z, b.r, b.z, c.r, c.z));
|
||||
total += stria;
|
||||
selem.area = total;
|
||||
fElements->push_back(selem); // start phi
|
||||
total += stria;
|
||||
selem.area = total;
|
||||
selem.i0 += nrz;
|
||||
fElements->push_back(selem); // end phi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetPointOnTriangle
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Auxiliary method for get point on surface
|
||||
//
|
||||
G4ThreeVector G4Polyhedra::GetPointOnTriangle(G4ThreeVector p1,
|
||||
G4ThreeVector p2,
|
||||
G4ThreeVector p3) const
|
||||
{
|
||||
G4double lambda1,lambda2;
|
||||
G4ThreeVector v=p3-p1, w=p1-p2;
|
||||
// Generate random point on surface
|
||||
|
||||
lambda1 = G4RandFlat::shoot(0.,1.);
|
||||
lambda2 = G4RandFlat::shoot(0.,lambda1);
|
||||
|
||||
return (p2 + lambda1*w + lambda2*v);
|
||||
}
|
||||
|
||||
// GetPointOnSurface
|
||||
//
|
||||
G4ThreeVector G4Polyhedra::GetPointOnSurface() const
|
||||
{
|
||||
if( !genericPgon ) // Polyhedra by faces
|
||||
// Set surface elements
|
||||
if (!fElements)
|
||||
{
|
||||
G4int j, numPlanes = original_parameters->Num_z_planes, Flag=0;
|
||||
G4double chose, totArea=0., Achose1, Achose2,
|
||||
rad1, rad2, sinphi1, sinphi2, cosphi1, cosphi2;
|
||||
G4double a, b, l2, rang, totalPhi, ksi,
|
||||
area, aTop=0., aBottom=0., zVal=0.;
|
||||
G4AutoLock l(&surface_elementsMutex);
|
||||
SetSurfaceElements();
|
||||
l.unlock();
|
||||
}
|
||||
|
||||
G4ThreeVector p0, p1, p2, p3;
|
||||
std::vector<G4double> aVector1;
|
||||
std::vector<G4double> aVector2;
|
||||
std::vector<G4double> aVector3;
|
||||
// Select surface element
|
||||
G4Polyhedra::surface_element selem;
|
||||
selem = fElements->back();
|
||||
G4double select = selem.area*G4QuickRand();
|
||||
auto it = std::lower_bound(fElements->begin(), fElements->end(), select,
|
||||
[](const G4Polyhedra::surface_element& x, G4double val)
|
||||
-> G4bool { return x.area < val; });
|
||||
|
||||
totalPhi= (phiIsOpen) ? (endPhi-startPhi) : twopi;
|
||||
ksi = totalPhi/numSide;
|
||||
G4double cosksi = std::cos(ksi/2.);
|
||||
|
||||
// Below we generate the areas relevant to our solid
|
||||
//
|
||||
for(j=0; j<numPlanes-1; ++j)
|
||||
// Generate random point
|
||||
G4double x = 0, y = 0, z = 0;
|
||||
G4double u = G4QuickRand();
|
||||
G4double v = G4QuickRand();
|
||||
if (u + v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
G4int i0 = (*it).i0;
|
||||
G4int i1 = (*it).i1;
|
||||
G4int i2 = (*it).i2;
|
||||
if (i2 < 0) // lateral surface
|
||||
{
|
||||
// sample point
|
||||
G4int nside = GetNumSide();
|
||||
G4double dphi = (GetEndPhi() - GetStartPhi())/nside;
|
||||
G4double cosa = std::cos(dphi);
|
||||
G4double sina = std::sin(dphi);
|
||||
G4PolyhedraSideRZ a = GetCorner(i0);
|
||||
G4PolyhedraSideRZ b = GetCorner(i1);
|
||||
G4ThreeVector p0(a.r, 0, a.z);
|
||||
G4ThreeVector p1(b.r, 0, b.z);
|
||||
G4ThreeVector p2(b.r*cosa, b.r*sina, b.z);
|
||||
if (i2 == -1) p1.set(a.r*cosa, a.r*sina, a.z);
|
||||
p0 += (p1 - p0)*u + (p2 - p0)*v;
|
||||
// find selected side and rotate point
|
||||
G4double scurr = (*it).area;
|
||||
G4double sprev = (it == fElements->begin()) ? 0. : (*(--it)).area;
|
||||
G4int iside = nside*(select - sprev)/(scurr - sprev);
|
||||
if (iside == 0 && GetStartPhi() == 0.)
|
||||
{
|
||||
a = original_parameters->Rmax[j+1];
|
||||
b = original_parameters->Rmax[j];
|
||||
l2 = sqr(original_parameters->Z_values[j]
|
||||
-original_parameters->Z_values[j+1]) + sqr(b-a);
|
||||
area = std::sqrt(l2-sqr((a-b)*cosksi))*(a+b)*cosksi;
|
||||
aVector1.push_back(area);
|
||||
}
|
||||
|
||||
for(j=0; j<numPlanes-1; ++j)
|
||||
{
|
||||
a = original_parameters->Rmin[j+1];//*cosksi;
|
||||
b = original_parameters->Rmin[j];//*cosksi;
|
||||
l2 = sqr(original_parameters->Z_values[j]
|
||||
-original_parameters->Z_values[j+1]) + sqr(b-a);
|
||||
area = std::sqrt(l2-sqr((a-b)*cosksi))*(a+b)*cosksi;
|
||||
aVector2.push_back(area);
|
||||
}
|
||||
|
||||
for(j=0; j<numPlanes-1; ++j)
|
||||
{
|
||||
if(phiIsOpen == true)
|
||||
{
|
||||
aVector3.push_back(0.5*(original_parameters->Rmax[j]
|
||||
-original_parameters->Rmin[j]
|
||||
+original_parameters->Rmax[j+1]
|
||||
-original_parameters->Rmin[j+1])
|
||||
*std::fabs(original_parameters->Z_values[j+1]
|
||||
-original_parameters->Z_values[j]));
|
||||
}
|
||||
else { aVector3.push_back(0.); }
|
||||
}
|
||||
|
||||
for(j=0; j<numPlanes-1; ++j)
|
||||
{
|
||||
totArea += numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
|
||||
}
|
||||
|
||||
// Must include top and bottom areas
|
||||
//
|
||||
if(original_parameters->Rmax[numPlanes-1] != 0.)
|
||||
{
|
||||
a = original_parameters->Rmax[numPlanes-1];
|
||||
b = original_parameters->Rmin[numPlanes-1];
|
||||
l2 = sqr(a-b);
|
||||
aTop = std::sqrt(l2-sqr((a-b)*cosksi))*(a+b)*cosksi;
|
||||
}
|
||||
|
||||
if(original_parameters->Rmax[0] != 0.)
|
||||
{
|
||||
a = original_parameters->Rmax[0];
|
||||
b = original_parameters->Rmin[0];
|
||||
l2 = sqr(a-b);
|
||||
aBottom = std::sqrt(l2-sqr((a-b)*cosksi))*(a+b)*cosksi;
|
||||
}
|
||||
|
||||
Achose1 = 0.;
|
||||
Achose2 = numSide*(aVector1[0]+aVector2[0])+2.*aVector3[0];
|
||||
|
||||
chose = G4RandFlat::shoot(0.,totArea+aTop+aBottom);
|
||||
if( (chose >= 0.) && (chose < aTop + aBottom) )
|
||||
{
|
||||
chose = G4RandFlat::shoot(startPhi,startPhi+totalPhi);
|
||||
rang = std::floor((chose-startPhi)/ksi-0.01);
|
||||
if(rang<0) { rang=0; }
|
||||
rang = std::fabs(rang);
|
||||
sinphi1 = std::sin(startPhi+rang*ksi);
|
||||
sinphi2 = std::sin(startPhi+(rang+1)*ksi);
|
||||
cosphi1 = std::cos(startPhi+rang*ksi);
|
||||
cosphi2 = std::cos(startPhi+(rang+1)*ksi);
|
||||
chose = G4RandFlat::shoot(0., aTop + aBottom);
|
||||
if(chose>=0. && chose<aTop)
|
||||
{
|
||||
rad1 = original_parameters->Rmin[numPlanes-1];
|
||||
rad2 = original_parameters->Rmax[numPlanes-1];
|
||||
zVal = original_parameters->Z_values[numPlanes-1];
|
||||
}
|
||||
else
|
||||
{
|
||||
rad1 = original_parameters->Rmin[0];
|
||||
rad2 = original_parameters->Rmax[0];
|
||||
zVal = original_parameters->Z_values[0];
|
||||
}
|
||||
p0 = G4ThreeVector(rad1*cosphi1,rad1*sinphi1,zVal);
|
||||
p1 = G4ThreeVector(rad2*cosphi1,rad2*sinphi1,zVal);
|
||||
p2 = G4ThreeVector(rad2*cosphi2,rad2*sinphi2,zVal);
|
||||
p3 = G4ThreeVector(rad1*cosphi2,rad1*sinphi2,zVal);
|
||||
return GetPointOnPlane(p0,p1,p2,p3);
|
||||
x = p0.x();
|
||||
y = p0.y();
|
||||
z = p0.z();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j=0; j<numPlanes-1; ++j)
|
||||
{
|
||||
if( ((chose >= Achose1) && (chose < Achose2)) || (j == numPlanes-2) )
|
||||
{
|
||||
Flag = j; break;
|
||||
}
|
||||
Achose1 += numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
|
||||
Achose2 = Achose1 + numSide*(aVector1[j+1]+aVector2[j+1])
|
||||
+ 2.*aVector3[j+1];
|
||||
}
|
||||
if (iside == nside) --iside; // iside must be less then nside
|
||||
G4double phi = iside*dphi + GetStartPhi();
|
||||
G4double cosphi = std::cos(phi);
|
||||
G4double sinphi = std::sin(phi);
|
||||
x = p0.x()*cosphi - p0.y()*sinphi;
|
||||
y = p0.x()*sinphi + p0.y()*cosphi;
|
||||
z = p0.z();
|
||||
}
|
||||
|
||||
// At this point we have chosen a subsection
|
||||
// between to adjacent plane cuts...
|
||||
|
||||
j = Flag;
|
||||
|
||||
totArea = numSide*(aVector1[j]+aVector2[j])+2.*aVector3[j];
|
||||
chose = G4RandFlat::shoot(0.,totArea);
|
||||
|
||||
if( (chose>=0.) && (chose<numSide*aVector1[j]) )
|
||||
{
|
||||
chose = G4RandFlat::shoot(startPhi,startPhi+totalPhi);
|
||||
rang = std::floor((chose-startPhi)/ksi-0.01);
|
||||
if(rang<0) { rang=0; }
|
||||
rang = std::fabs(rang);
|
||||
rad1 = original_parameters->Rmax[j];
|
||||
rad2 = original_parameters->Rmax[j+1];
|
||||
sinphi1 = std::sin(startPhi+rang*ksi);
|
||||
sinphi2 = std::sin(startPhi+(rang+1)*ksi);
|
||||
cosphi1 = std::cos(startPhi+rang*ksi);
|
||||
cosphi2 = std::cos(startPhi+(rang+1)*ksi);
|
||||
zVal = original_parameters->Z_values[j];
|
||||
|
||||
p0 = G4ThreeVector(rad1*cosphi1,rad1*sinphi1,zVal);
|
||||
p1 = G4ThreeVector(rad1*cosphi2,rad1*sinphi2,zVal);
|
||||
|
||||
zVal = original_parameters->Z_values[j+1];
|
||||
|
||||
p2 = G4ThreeVector(rad2*cosphi2,rad2*sinphi2,zVal);
|
||||
p3 = G4ThreeVector(rad2*cosphi1,rad2*sinphi1,zVal);
|
||||
return GetPointOnPlane(p0,p1,p2,p3);
|
||||
}
|
||||
else if ( (chose >= numSide*aVector1[j])
|
||||
&& (chose <= numSide*(aVector1[j]+aVector2[j])) )
|
||||
{
|
||||
chose = G4RandFlat::shoot(startPhi,startPhi+totalPhi);
|
||||
rang = std::floor((chose-startPhi)/ksi-0.01);
|
||||
if(rang<0) { rang=0; }
|
||||
rang = std::fabs(rang);
|
||||
rad1 = original_parameters->Rmin[j];
|
||||
rad2 = original_parameters->Rmin[j+1];
|
||||
sinphi1 = std::sin(startPhi+rang*ksi);
|
||||
sinphi2 = std::sin(startPhi+(rang+1)*ksi);
|
||||
cosphi1 = std::cos(startPhi+rang*ksi);
|
||||
cosphi2 = std::cos(startPhi+(rang+1)*ksi);
|
||||
zVal = original_parameters->Z_values[j];
|
||||
|
||||
p0 = G4ThreeVector(rad1*cosphi1,rad1*sinphi1,zVal);
|
||||
p1 = G4ThreeVector(rad1*cosphi2,rad1*sinphi2,zVal);
|
||||
|
||||
zVal = original_parameters->Z_values[j+1];
|
||||
|
||||
p2 = G4ThreeVector(rad2*cosphi2,rad2*sinphi2,zVal);
|
||||
p3 = G4ThreeVector(rad2*cosphi1,rad2*sinphi1,zVal);
|
||||
return GetPointOnPlane(p0,p1,p2,p3);
|
||||
}
|
||||
|
||||
chose = G4RandFlat::shoot(0.,2.2);
|
||||
if( (chose>=0.) && (chose < 1.) )
|
||||
{
|
||||
rang = startPhi;
|
||||
}
|
||||
else
|
||||
{
|
||||
rang = endPhi;
|
||||
}
|
||||
|
||||
cosphi1 = std::cos(rang); rad1 = original_parameters->Rmin[j];
|
||||
sinphi1 = std::sin(rang); rad2 = original_parameters->Rmax[j];
|
||||
|
||||
p0 = G4ThreeVector(rad1*cosphi1,rad1*sinphi1,
|
||||
original_parameters->Z_values[j]);
|
||||
p1 = G4ThreeVector(rad2*cosphi1,rad2*sinphi1,
|
||||
original_parameters->Z_values[j]);
|
||||
|
||||
rad1 = original_parameters->Rmax[j+1];
|
||||
rad2 = original_parameters->Rmin[j+1];
|
||||
|
||||
p2 = G4ThreeVector(rad1*cosphi1,rad1*sinphi1,
|
||||
original_parameters->Z_values[j+1]);
|
||||
p3 = G4ThreeVector(rad2*cosphi1,rad2*sinphi1,
|
||||
original_parameters->Z_values[j+1]);
|
||||
return GetPointOnPlane(p0,p1,p2,p3);
|
||||
}
|
||||
else // Generic polyhedra
|
||||
else // phi cut
|
||||
{
|
||||
return GetPointOnSurfaceGeneric();
|
||||
G4int nrz = GetNumRZCorner();
|
||||
G4double phi = (i0 < nrz) ? GetStartPhi() : GetEndPhi();
|
||||
if (i0 >= nrz) { i0 -= nrz; }
|
||||
G4PolyhedraSideRZ p0 = GetCorner(i0);
|
||||
G4PolyhedraSideRZ p1 = GetCorner(i1);
|
||||
G4PolyhedraSideRZ p2 = GetCorner(i2);
|
||||
G4double r = (p1.r - p0.r)*u + (p2.r - p0.r)*v + p0.r;
|
||||
x = r*std::cos(phi);
|
||||
y = r*std::sin(phi);
|
||||
z = (p1.z - p0.z)*u + (p2.z - p0.z)*v + p0.z;
|
||||
}
|
||||
return G4ThreeVector(x, y, z);
|
||||
}
|
||||
|
||||
// CreatePolyhedron
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CreatePolyhedron
|
||||
|
||||
G4Polyhedron* G4Polyhedra::CreatePolyhedron() const
|
||||
{
|
||||
{
|
||||
if (!genericPgon)
|
||||
{
|
||||
return new G4PolyhedronPgon( original_parameters->Start_angle,
|
||||
@@ -1077,8 +1062,8 @@ G4Polyhedron* G4Polyhedra::CreatePolyhedron() const
|
||||
* array starts from 1 (like in fortran). The indexes can be positive
|
||||
* or negative. Negative sign means that the corresponding edge is
|
||||
* invisible. The normal of the face should be directed to exterior
|
||||
* of the polyhedron.
|
||||
*
|
||||
* of the polyhedron.
|
||||
*
|
||||
* @param Nnodes number of nodes
|
||||
* @param Nfaces number of faces
|
||||
* @param xyz nodes
|
||||
@@ -1309,12 +1294,12 @@ G4Polyhedron* G4Polyhedra::CreatePolyhedron() const
|
||||
//
|
||||
void G4Polyhedra::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
{
|
||||
G4int numPlanes = numCorner;
|
||||
G4int numPlanes = numCorner;
|
||||
G4bool isConvertible = true;
|
||||
G4double Zmax=rz->Bmax();
|
||||
rz->StartWithZMin();
|
||||
|
||||
// Prepare vectors for storage
|
||||
// Prepare vectors for storage
|
||||
//
|
||||
std::vector<G4double> Z;
|
||||
std::vector<G4double> Rmin;
|
||||
@@ -1330,24 +1315,24 @@ void G4Polyhedra::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
G4double Zprev=Z[0];
|
||||
if (Zprev == corners[1].z)
|
||||
{
|
||||
Rmin.push_back(corners[0].r);
|
||||
Rmax.push_back (corners[1].r);icurr=1;
|
||||
Rmin.push_back(corners[0].r);
|
||||
Rmax.push_back (corners[1].r);icurr=1;
|
||||
}
|
||||
else if (Zprev == corners[numPlanes-1].z)
|
||||
{
|
||||
Rmin.push_back(corners[numPlanes-1].r);
|
||||
Rmin.push_back(corners[numPlanes-1].r);
|
||||
Rmax.push_back (corners[0].r);
|
||||
icurl=numPlanes-1;
|
||||
icurl=numPlanes-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Rmin.push_back(corners[0].r);
|
||||
Rmin.push_back(corners[0].r);
|
||||
Rmax.push_back (corners[0].r);
|
||||
}
|
||||
|
||||
// next planes until last
|
||||
//
|
||||
G4int inextr=0, inextl=0;
|
||||
G4int inextr=0, inextl=0;
|
||||
for (G4int i=0; i < numPlanes-2; ++i)
|
||||
{
|
||||
inextr=1+icurr;
|
||||
@@ -1359,7 +1344,7 @@ void G4Polyhedra::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
G4double Zright = corners[inextr].z;
|
||||
if(Zright>Zleft)
|
||||
{
|
||||
Z.push_back(Zleft);
|
||||
Z.push_back(Zleft);
|
||||
countPlanes++;
|
||||
G4double difZr=corners[inextr].z - corners[icurr].z;
|
||||
G4double difZl=corners[inextl].z - corners[icurl].z;
|
||||
@@ -1375,7 +1360,7 @@ void G4Polyhedra::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
{
|
||||
Rmin.push_back(corners[inextl].r);
|
||||
Rmax.push_back(corners[icurr].r + (Zleft-corners[icurr].z)/difZr
|
||||
*(corners[inextr].r - corners[icurr].r));
|
||||
*(corners[inextr].r - corners[icurr].r));
|
||||
}
|
||||
}
|
||||
else if (difZl >= kCarTolerance)
|
||||
@@ -1400,18 +1385,18 @@ void G4Polyhedra::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
}
|
||||
else if(std::fabs(Zright-Zleft)<kCarTolerance) // Zright=Zleft
|
||||
{
|
||||
Z.push_back(Zleft);
|
||||
Z.push_back(Zleft);
|
||||
++countPlanes;
|
||||
++icurr;
|
||||
|
||||
icurl=(icurl == 0)? numPlanes-1 : icurl-1;
|
||||
|
||||
Rmin.push_back(corners[inextl].r);
|
||||
Rmin.push_back(corners[inextl].r);
|
||||
Rmax.push_back (corners[inextr].r);
|
||||
}
|
||||
else // Zright<Zleft
|
||||
{
|
||||
Z.push_back(Zright);
|
||||
Z.push_back(Zright);
|
||||
++countPlanes;
|
||||
|
||||
G4double difZr=corners[inextr].z - corners[icurr].z;
|
||||
@@ -1421,8 +1406,8 @@ void G4Polyhedra::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
if(std::fabs(difZl) < kCarTolerance)
|
||||
{
|
||||
Rmax.push_back(corners[inextr].r);
|
||||
Rmin.push_back(corners[icurr].r);
|
||||
}
|
||||
Rmin.push_back(corners[icurr].r);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rmin.push_back(corners[icurl].r + (Zright-corners[icurl].z)/difZl
|
||||
@@ -1436,8 +1421,8 @@ void G4Polyhedra::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
if(std::fabs(difZl) < kCarTolerance)
|
||||
{
|
||||
Rmax.push_back(corners[inextr].r);
|
||||
Rmin.push_back (corners[icurr].r);
|
||||
}
|
||||
Rmin.push_back (corners[icurr].r);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rmax.push_back(corners[inextr].r);
|
||||
@@ -1459,7 +1444,7 @@ void G4Polyhedra::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
++countPlanes;
|
||||
inextr=1+icurr;
|
||||
inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
|
||||
|
||||
|
||||
Rmax.push_back(corners[inextr].r);
|
||||
Rmin.push_back(corners[inextl].r);
|
||||
|
||||
@@ -1472,7 +1457,7 @@ void G4Polyhedra::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
original_parameters->Z_values = new G4double[countPlanes];
|
||||
original_parameters->Rmin = new G4double[countPlanes];
|
||||
original_parameters->Rmax = new G4double[countPlanes];
|
||||
|
||||
|
||||
for(G4int j=0; j < countPlanes; ++j)
|
||||
{
|
||||
original_parameters->Z_values[j] = Z[j];
|
||||
@@ -1482,7 +1467,7 @@ void G4Polyhedra::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
original_parameters->Start_angle = startPhi;
|
||||
original_parameters->Opening_angle = endPhi-startPhi;
|
||||
original_parameters->Num_z_planes = countPlanes;
|
||||
|
||||
|
||||
}
|
||||
else // Set parameters(r,z) with Rmin==0 as convention
|
||||
{
|
||||
@@ -1498,7 +1483,7 @@ void G4Polyhedra::SetOriginalParameters(G4ReduciblePolygon* rz)
|
||||
original_parameters->Z_values = new G4double[numPlanes];
|
||||
original_parameters->Rmin = new G4double[numPlanes];
|
||||
original_parameters->Rmax = new G4double[numPlanes];
|
||||
|
||||
|
||||
for(G4int j=0; j < numPlanes; ++j)
|
||||
{
|
||||
original_parameters->Z_values[j] = corners[j].z;
|
||||
|
||||
@@ -383,7 +383,7 @@ G4Polyhedron* G4UGenericPolycone::CreatePolyhedron() const
|
||||
// Here is an extract from the header file HepPolyhedron.h:
|
||||
/**
|
||||
* Creates user defined polyhedron.
|
||||
* This function allows to the user to define arbitrary polyhedron.
|
||||
* This function allows one to the user to define arbitrary polyhedron.
|
||||
* The faces of the polyhedron should be either triangles or planar
|
||||
* quadrilateral. Nodes of a face are defined by indexes pointing to
|
||||
* the elements in the xyz array. Numeration of the elements in the
|
||||
|
||||
@@ -266,7 +266,7 @@ G4bool G4UPolycone::Reset()
|
||||
message << "Solid " << GetName() << " built using generic construct."
|
||||
<< G4endl << "Not applicable to the generic construct !";
|
||||
G4Exception("G4UPolycone::Reset()", "GeomSolids1001",
|
||||
JustWarning, message, "Parameters NOT resetted.");
|
||||
JustWarning, message, "Parameters NOT reset.");
|
||||
return true; // error code set
|
||||
}
|
||||
|
||||
|
||||
@@ -284,7 +284,7 @@ G4bool G4UPolyhedra::Reset()
|
||||
message << "Solid " << GetName() << " built using generic construct."
|
||||
<< G4endl << "Not applicable to the generic construct !";
|
||||
G4Exception("G4UPolyhedra::Reset()", "GeomSolids1001",
|
||||
JustWarning, message, "Parameters NOT resetted.");
|
||||
JustWarning, message, "Parameters NOT reset.");
|
||||
return true; // error code set
|
||||
}
|
||||
|
||||
@@ -614,7 +614,7 @@ G4Polyhedron* G4UPolyhedra::CreatePolyhedron() const
|
||||
// Here is an extract from the header file HepPolyhedron.h:
|
||||
/**
|
||||
* Creates user defined polyhedron.
|
||||
* This function allows to the user to define arbitrary polyhedron.
|
||||
* This function allows the user to define arbitrary polyhedron.
|
||||
* The faces of the polyhedron should be either triangles or planar
|
||||
* quadrilateral. Nodes of a face are defined by indexes pointing to
|
||||
* the elements in the xyz array. Numeration of the elements in the
|
||||
|
||||
Reference in New Issue
Block a user