Import Geant4 11.1.0.beta source tree
This commit is contained in:
@@ -1,17 +1,23 @@
|
||||
# - G4geometry category builds
|
||||
|
||||
# Add (private) allocation export symbol
|
||||
add_definitions(-DG4GEOM_ALLOC_EXPORT)
|
||||
|
||||
# Compose library from subcategories
|
||||
geant4_global_library_target(NAME G4geometry
|
||||
COMPONENTS
|
||||
biasing/sources.cmake
|
||||
divisions/sources.cmake
|
||||
magneticfield/sources.cmake
|
||||
management/sources.cmake
|
||||
navigation/sources.cmake
|
||||
solids/Boolean/sources.cmake
|
||||
solids/CSG/sources.cmake
|
||||
solids/specific/sources.cmake
|
||||
volumes/sources.cmake)
|
||||
include(biasing/sources.cmake)
|
||||
include(divisions/sources.cmake)
|
||||
include(magneticfield/sources.cmake)
|
||||
include(management/sources.cmake)
|
||||
include(navigation/sources.cmake)
|
||||
include(solids/Boolean/sources.cmake)
|
||||
include(solids/CSG/sources.cmake)
|
||||
include(solids/specific/sources.cmake)
|
||||
include(volumes/sources.cmake)
|
||||
|
||||
geant4_add_category(G4geometry MODULES
|
||||
G4geombias
|
||||
G4geomdivision
|
||||
G4magneticfield
|
||||
G4geometrymng
|
||||
G4navigation
|
||||
G4geomBoolean
|
||||
G4csg
|
||||
G4specsolids
|
||||
G4volumes)
|
||||
|
||||
+13
-14
@@ -1,20 +1,19 @@
|
||||
-------------------------------------------------------------------
|
||||
# Category geometry History
|
||||
|
||||
=========================================================
|
||||
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
|
||||
=========================================================
|
||||
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
|
||||
which **must** added in reverse chronological order (newest at the top). It must **not**
|
||||
be used as a substitute for writing good git commit messages!
|
||||
|
||||
Category History file
|
||||
---------------------
|
||||
This file should be used by G4 developers and category coordinators
|
||||
to briefly summarize all major modifications introduced in the code
|
||||
and keep track of all category-tags.
|
||||
It DOES NOT substitute the CVS log-message one should put at every
|
||||
committal in the CVS repository !
|
||||
## 2022-01-28 Ben Morgan (geometry-V11-00-01)
|
||||
- Replace `geant4_global_library_target` with direct file inclusion and
|
||||
call to `geant4_add_category` to define library build from source modules.
|
||||
|
||||
----------------------------------------------------------
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
## 2021-12-10 Ben Morgan (geometry-V11-00-00)
|
||||
- Change to new Markdown History format
|
||||
|
||||
---
|
||||
|
||||
# History entries prior to 11.0
|
||||
|
||||
March 30, 2021 B.Morgan geometry-V10-07-00
|
||||
-----------------------
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
-------------------------------------------------------------------
|
||||
# Category geombias History
|
||||
|
||||
=========================================================
|
||||
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
|
||||
=========================================================
|
||||
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
|
||||
which **must** added in reverse chronological order (newest at the top). It must **not**
|
||||
be used as a substitute for writing good git commit messages!
|
||||
|
||||
Category History file
|
||||
---------------------
|
||||
This file should be used by G4 developers and category coordinators
|
||||
to briefly summarize all major modifications introduced in the code
|
||||
and keep track of all category-tags.
|
||||
It DOES NOT substitute the CVS log-message one should put at every
|
||||
committal in the CVS repository !
|
||||
|
||||
----------------------------------------------------------
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
## 2021-12-10 Ben Morgan (geombias-V11-00-00)
|
||||
- Change to new Markdown History format
|
||||
|
||||
---
|
||||
|
||||
# History entries prior to 11.0
|
||||
|
||||
December 1st, 2021 B.Morgan (geombias-V10-07-01)
|
||||
- Add missing include of G4Threading header for G4Mutex
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
-------------------------------------------------------------------
|
||||
# Category geomdiv History
|
||||
|
||||
=========================================================
|
||||
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
|
||||
=========================================================
|
||||
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
|
||||
which **must** added in reverse chronological order (newest at the top). It must **not**
|
||||
be used as a substitute for writing good git commit messages!
|
||||
|
||||
Category History file
|
||||
---------------------
|
||||
This file should be used by G4 developers and category coordinators
|
||||
to briefly summarize all major modifications introduced in the code
|
||||
and keep track of all category-tags.
|
||||
It DOES NOT substitute the CVS log-message one should put at every
|
||||
committal in the CVS repository !
|
||||
|
||||
----------------------------------------------------------
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
## 2021-12-10 Ben Morgan (geomdiv-V11-00-00)
|
||||
- Change to new Markdown History format
|
||||
|
||||
---
|
||||
|
||||
# History entries prior to 11.0
|
||||
|
||||
October 29th, 2021 G.Cosmo (geomdiv-V10-07-04)
|
||||
- G4ReplicatedSlice: added protection against null pointer for mother
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
-------------------------------------------------------------------
|
||||
# Category field History
|
||||
|
||||
=========================================================
|
||||
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
|
||||
=========================================================
|
||||
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
|
||||
which **must** added in reverse chronological order (newest at the top). It must **not**
|
||||
be used as a substitute for writing good git commit messages!
|
||||
|
||||
Category History file
|
||||
---------------------
|
||||
This file should be used by G4 developers and category coordinators
|
||||
to briefly summarize all major modifications introduced in the code
|
||||
and keep track of all category-tags.
|
||||
It DOES NOT substitute the CVS log-message one should put at every
|
||||
committal in the CVS repository !
|
||||
|
||||
----------------------------------------------------------
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
## 2021-12-10 Ben Morgan (field-V11-00-00)
|
||||
- Change to new Markdown History format
|
||||
|
||||
---
|
||||
|
||||
# History entries prior to 11.0
|
||||
|
||||
March 30, 2021 B.Morgan - field-V10-07-00
|
||||
-----------------------
|
||||
|
||||
@@ -1,25 +1,30 @@
|
||||
-------------------------------------------------------------------
|
||||
# Category geommng History
|
||||
|
||||
=========================================================
|
||||
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
|
||||
=========================================================
|
||||
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
|
||||
which **must** added in reverse chronological order (newest at the top). It must **not**
|
||||
be used as a substitute for writing good git commit messages!
|
||||
|
||||
Category History file
|
||||
---------------------
|
||||
This file should be used by G4 developers and category coordinators
|
||||
to briefly summarize all major modifications introduced in the code
|
||||
and keep track of all category-tags.
|
||||
It DOES NOT substitute the log-message one should put in every
|
||||
commit in the repository !
|
||||
|
||||
----------------------------------------------------------
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
## 2022-04-13 Ben Morgan (geommng-V11-00-04)
|
||||
- Add missing dependency on G4heprandom
|
||||
|
||||
March 5 2022 M.Asai (geommng-V10-07-08)
|
||||
## 2021-03-05 Makoto Asai (geommng-V11-00-03)
|
||||
- G4SolidStore, G4LogicalVolumeStore, G4PhysicalVolumeStore:
|
||||
extend getter methods to optionally return the last-found object.
|
||||
|
||||
## 2021-02-05 Evgueni Tcherniaev (geommng-V11-00-02)
|
||||
- G4BoundingEnvelope: get rid of "new" operators
|
||||
|
||||
## 2021-01-19 Evgueni Tcherniaev (geommng-V11-00-01)
|
||||
- G4ReflectedSolid: added GetCubicVolume(), GetSurfaceArea()
|
||||
|
||||
## 2021-12-10 Ben Morgan (geommng-V11-00-00)
|
||||
- Change to new Markdown History format
|
||||
|
||||
---
|
||||
|
||||
# History entries prior to 11.0
|
||||
|
||||
September 28, 2021 G.Cosmo (geommng-V10-07-07)
|
||||
- Use G4Allocator to dynamically allocate nodes and proxies for the
|
||||
voxels optimisation structure. Should help reducing memory fragmentation.
|
||||
|
||||
@@ -104,7 +104,8 @@ class G4BoundingEnvelope
|
||||
// Find max scale factor of the transformation
|
||||
|
||||
void TransformVertices(const G4Transform3D& pTransform3D,
|
||||
std::vector<G4Polygon3D*>& pBases) const;
|
||||
std::vector<G4Point3D>& pVertices,
|
||||
std::vector<std::pair<G4int,G4int>>& pBases) const;
|
||||
// Create list of transformed polygons
|
||||
|
||||
void GetPrismAABB(const G4Polygon3D& pBaseA,
|
||||
@@ -116,7 +117,7 @@ class G4BoundingEnvelope
|
||||
const G4Polygon3D& baseB,
|
||||
std::vector<G4Segment3D>& pEdges) const;
|
||||
// Create list of edges of a prism
|
||||
|
||||
|
||||
void CreateListOfPlanes(const G4Polygon3D& baseA,
|
||||
const G4Polygon3D& baseB,
|
||||
std::vector<G4Plane3D>& pPlanes) const;
|
||||
@@ -136,7 +137,7 @@ class G4BoundingEnvelope
|
||||
|
||||
private:
|
||||
|
||||
G4ThreeVector fMin, fMax;
|
||||
G4ThreeVector fMin, fMax;
|
||||
// original bounding box
|
||||
|
||||
const std::vector<const G4ThreeVectorList*>* fPolygons = nullptr;
|
||||
|
||||
@@ -68,7 +68,7 @@ class G4LogicalVolumeStore : public std::vector<G4LogicalVolume*>
|
||||
// Delete all volumes from the store.
|
||||
|
||||
G4LogicalVolume* GetVolume(const G4String& name, G4bool verbose=true,
|
||||
G4bool reverseSearch=false) const;
|
||||
G4bool reverseSearch=false) const;
|
||||
// Return the pointer of the first or last volume in the collection having
|
||||
// that name. Uses the internal map for fast search and warns if
|
||||
// a volume in the collection is not unique or not found.
|
||||
|
||||
@@ -83,6 +83,9 @@ class G4ReflectedSolid : public G4VSolid
|
||||
const G4int n,
|
||||
const G4VPhysicalVolume* pRep );
|
||||
|
||||
G4double GetCubicVolume();
|
||||
G4double GetSurfaceArea();
|
||||
|
||||
G4ThreeVector GetPointOnSurface() const;
|
||||
|
||||
G4VSolid* Clone() const;
|
||||
|
||||
@@ -104,7 +104,7 @@ geant4_module_include_directories(G4geometrymng
|
||||
# - Link to modules/deps
|
||||
geant4_module_link_libraries(G4geometrymng
|
||||
PUBLIC G4globman G4hepgeometry G4graphics_reps ${VECGEOM_LIBRARIES}
|
||||
PRIVATE G4materials)
|
||||
PRIVATE G4materials G4heprandom)
|
||||
|
||||
# WORKAROUND: When building/testing examples uing ROOT, ROOT's
|
||||
# dictionary generation is not smart enough to handle target usage
|
||||
|
||||
@@ -67,16 +67,16 @@ G4BoundingEnvelope(const std::vector<const G4ThreeVectorList*>& polygons)
|
||||
G4double xmin = kInfinity, ymin = kInfinity, zmin = kInfinity;
|
||||
G4double xmax = -kInfinity, ymax = -kInfinity, zmax = -kInfinity;
|
||||
for (auto ibase = fPolygons->cbegin(); ibase != fPolygons->cend(); ++ibase)
|
||||
{
|
||||
{
|
||||
for (auto ipoint = (*ibase)->cbegin(); ipoint != (*ibase)->cend(); ++ipoint)
|
||||
{
|
||||
G4double x = ipoint->x();
|
||||
G4double x = ipoint->x();
|
||||
if (x < xmin) xmin = x;
|
||||
if (x > xmax) xmax = x;
|
||||
G4double y = ipoint->y();
|
||||
G4double y = ipoint->y();
|
||||
if (y < ymin) ymin = y;
|
||||
if (y > ymax) ymax = y;
|
||||
G4double z = ipoint->z();
|
||||
G4double z = ipoint->z();
|
||||
if (z < zmin) zmin = z;
|
||||
if (z > zmax) zmax = z;
|
||||
}
|
||||
@@ -100,7 +100,7 @@ G4BoundingEnvelope( const G4ThreeVector& pMin,
|
||||
: fMin(pMin), fMax(pMax), fPolygons(&polygons)
|
||||
{
|
||||
// Check correctness of bounding box and polygons
|
||||
//
|
||||
//
|
||||
CheckBoundingBox();
|
||||
CheckBoundingPolygons();
|
||||
}
|
||||
@@ -115,7 +115,7 @@ void G4BoundingEnvelope::CheckBoundingBox()
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Badly defined bounding box (min >= max)!"
|
||||
<< "\npMin = " << fMin
|
||||
<< "\npMin = " << fMin
|
||||
<< "\npMax = " << fMax;
|
||||
G4Exception("G4BoundingEnvelope::CheckBoundingBox()",
|
||||
"GeomMgt0001", JustWarning, message);
|
||||
@@ -135,7 +135,7 @@ void G4BoundingEnvelope::CheckBoundingPolygons()
|
||||
std::ostringstream message;
|
||||
message << "Wrong number of polygons in the sequence: " << nbases
|
||||
<< "\nShould be at least two!";
|
||||
G4Exception("G4BoundingEnvelope::CheckBoundingPolygons()",
|
||||
G4Exception("G4BoundingEnvelope::CheckBoundingPolygons()",
|
||||
"GeomMgt0001", FatalException, message);
|
||||
return;
|
||||
}
|
||||
@@ -149,7 +149,7 @@ void G4BoundingEnvelope::CheckBoundingPolygons()
|
||||
<< "\nPolygon #0 size: " << (*fPolygons)[0]->size()
|
||||
<< "\nPolygon #1 size: " << (*fPolygons)[1]->size()
|
||||
<< "\n...";
|
||||
G4Exception("G4BoundingEnvelope::CheckBoundingPolygons()",
|
||||
G4Exception("G4BoundingEnvelope::CheckBoundingPolygons()",
|
||||
"GeomMgt0001", FatalException, message);
|
||||
return;
|
||||
}
|
||||
@@ -165,10 +165,10 @@ void G4BoundingEnvelope::CheckBoundingPolygons()
|
||||
<< "\nNumber of polygons: " << nbases
|
||||
<< "\nPolygon #" << k << " size: " << np
|
||||
<< "\nexpected size: " << nsize;
|
||||
G4Exception("G4BoundingEnvelope::SetBoundingPolygons()",
|
||||
G4Exception("G4BoundingEnvelope::SetBoundingPolygons()",
|
||||
"GeomMgt0001", FatalException, message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
@@ -218,7 +218,7 @@ BoundingBoxVsVoxelLimits(const EAxis pAxis,
|
||||
{
|
||||
pMin = (xmin-kCarTolerance < xminlim) ? xminlim : xmin;
|
||||
pMax = (xmax+kCarTolerance > xmaxlim) ? xmaxlim : xmax;
|
||||
}
|
||||
}
|
||||
else if (pAxis == kYAxis)
|
||||
{
|
||||
pMin = (ymin-kCarTolerance < yminlim) ? yminlim : ymin;
|
||||
@@ -235,11 +235,11 @@ BoundingBoxVsVoxelLimits(const EAxis pAxis,
|
||||
}
|
||||
}
|
||||
|
||||
// Find max scale factor of the transformation, set delta
|
||||
// Find max scale factor of the transformation, set delta
|
||||
// equal to kCarTolerance multiplied by the scale factor
|
||||
//
|
||||
G4double scale = FindScaleFactor(pTransform3D);
|
||||
G4double delta = kCarTolerance*scale;
|
||||
G4double delta = kCarTolerance*scale;
|
||||
|
||||
// Set the sphere surrounding the bounding box
|
||||
//
|
||||
@@ -301,7 +301,7 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
|
||||
{
|
||||
pMin = (xmin-kCarTolerance < xminlim) ? xminlim : xmin;
|
||||
pMax = (xmax+kCarTolerance > xmaxlim) ? xmaxlim : xmax;
|
||||
}
|
||||
}
|
||||
else if (pAxis == kYAxis)
|
||||
{
|
||||
pMin = (ymin-kCarTolerance < yminlim) ? yminlim : ymin;
|
||||
@@ -318,11 +318,11 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
|
||||
}
|
||||
}
|
||||
|
||||
// Find max scale factor of the transformation, set delta
|
||||
// Find max scale factor of the transformation, set delta
|
||||
// equal to kCarTolerance multiplied by the scale factor
|
||||
//
|
||||
G4double scale = FindScaleFactor(pTransform3D);
|
||||
G4double delta = kCarTolerance*scale;
|
||||
G4double delta = kCarTolerance*scale;
|
||||
|
||||
// Set the sphere surrounding the bounding box
|
||||
//
|
||||
@@ -338,28 +338,28 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
|
||||
{
|
||||
G4double cx, cy, cz, cd;
|
||||
if (pAxis == kXAxis)
|
||||
{
|
||||
cx = pTransform3D.xx();
|
||||
{
|
||||
cx = pTransform3D.xx();
|
||||
cy = pTransform3D.xy();
|
||||
cz = pTransform3D.xz();
|
||||
cd = pTransform3D.dx();
|
||||
}
|
||||
else if (pAxis == kYAxis)
|
||||
{
|
||||
cx = pTransform3D.yx();
|
||||
{
|
||||
cx = pTransform3D.yx();
|
||||
cy = pTransform3D.yy();
|
||||
cz = pTransform3D.yz();
|
||||
cd = pTransform3D.dy();
|
||||
}
|
||||
else if (pAxis == kZAxis)
|
||||
{
|
||||
cx = pTransform3D.zx();
|
||||
{
|
||||
cx = pTransform3D.zx();
|
||||
cy = pTransform3D.zy();
|
||||
cz = pTransform3D.zz();
|
||||
cd = pTransform3D.dz();
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
cx = cy = cz = cd = kInfinity;
|
||||
}
|
||||
G4double emin = kInfinity, emax = -kInfinity;
|
||||
@@ -394,7 +394,7 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
|
||||
else
|
||||
{
|
||||
for (auto ibase=fPolygons->cbegin(); ibase!=fPolygons->cend(); ++ibase)
|
||||
{
|
||||
{
|
||||
for (auto ipoint=(*ibase)->cbegin(); ipoint!=(*ibase)->cend(); ++ipoint)
|
||||
{
|
||||
G4double coor = ipoint->x()*cx + ipoint->y()*cy + ipoint->z()*cz + cd;
|
||||
@@ -406,7 +406,7 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
|
||||
pMin = emin - delta;
|
||||
pMax = emax + delta;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the sphere surrounding the bounding box is outside
|
||||
// the voxel limits
|
||||
@@ -418,33 +418,19 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
|
||||
if (center.y()+radius < yminlim) return false;
|
||||
if (center.z()+radius < zminlim) return false;
|
||||
|
||||
// Allocate memory for transformed polygons
|
||||
// Transform polygons
|
||||
//
|
||||
G4int nbases = (fPolygons == nullptr) ? 2 : fPolygons->size();
|
||||
std::vector<G4Polygon3D*> bases(nbases);
|
||||
if (fPolygons == nullptr)
|
||||
{
|
||||
bases[0] = new G4Polygon3D(4);
|
||||
bases[1] = new G4Polygon3D(4);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (G4int i=0; i<nbases; ++i)
|
||||
{
|
||||
bases[i] = new G4Polygon3D((*fPolygons)[i]->size());
|
||||
}
|
||||
}
|
||||
std::vector<G4Point3D> vertices;
|
||||
std::vector<std::pair<G4int, G4int>> bases;
|
||||
TransformVertices(pTransform3D, vertices, bases);
|
||||
G4int nbases = bases.size();
|
||||
|
||||
// Transform vertices
|
||||
//
|
||||
TransformVertices(pTransform3D, bases);
|
||||
|
||||
// Create adjusted G4VoxelLimits box. New limits are extended by
|
||||
// Create adjusted G4VoxelLimits box. New limits are extended by
|
||||
// delta, kCarTolerance multiplied by max scale factor of
|
||||
// the transformation
|
||||
//
|
||||
EAxis axis[] = { kXAxis,kYAxis,kZAxis };
|
||||
G4VoxelLimits limits; // default is unlimited
|
||||
EAxis axis[] = { kXAxis, kYAxis, kZAxis };
|
||||
G4VoxelLimits limits; // default is unlimited
|
||||
for (auto i=0; i<3; ++i)
|
||||
{
|
||||
if (pVoxelLimits.IsLimited(axis[i]))
|
||||
@@ -457,16 +443,23 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
|
||||
|
||||
// Main loop along the set of prisms
|
||||
//
|
||||
G4Polygon3D baseA, baseB;
|
||||
G4Segment3D extent;
|
||||
extent.first = G4Point3D( kInfinity, kInfinity, kInfinity);
|
||||
extent.second = G4Point3D(-kInfinity,-kInfinity,-kInfinity);
|
||||
for (G4int k=0; k<nbases-1; ++k)
|
||||
{
|
||||
baseA.resize(bases[k].second);
|
||||
for (G4int i = 0; i < bases[k].second; ++i)
|
||||
baseA[i] = vertices[bases[k].first + i];
|
||||
|
||||
baseB.resize(bases[k+1].second);
|
||||
for (G4int i = 0; i < bases[k+1].second; ++i)
|
||||
baseB[i] = vertices[bases[k+1].first + i];
|
||||
|
||||
// Find bounding box of current prism
|
||||
G4Polygon3D* baseA = bases[k];
|
||||
G4Polygon3D* baseB = bases[k+1];
|
||||
G4Segment3D prismAABB;
|
||||
GetPrismAABB(*baseA, *baseB, prismAABB);
|
||||
GetPrismAABB(baseA, baseB, prismAABB);
|
||||
|
||||
// Check if prismAABB is completely within the voxel limits
|
||||
if (prismAABB.first.x() >= limits.GetMinXExtent() &&
|
||||
@@ -474,21 +467,21 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
|
||||
prismAABB.first.z() >= limits.GetMinZExtent() &&
|
||||
prismAABB.second.x()<= limits.GetMaxXExtent() &&
|
||||
prismAABB.second.y()<= limits.GetMaxYExtent() &&
|
||||
prismAABB.second.z()<= limits.GetMaxZExtent())
|
||||
prismAABB.second.z()<= limits.GetMaxZExtent())
|
||||
{
|
||||
if (extent.first.x() > prismAABB.first.x())
|
||||
extent.first.setX( prismAABB.first.x() );
|
||||
extent.first.setX( prismAABB.first.x() );
|
||||
if (extent.first.y() > prismAABB.first.y())
|
||||
extent.first.setY( prismAABB.first.y() );
|
||||
extent.first.setY( prismAABB.first.y() );
|
||||
if (extent.first.z() > prismAABB.first.z())
|
||||
extent.first.setZ( prismAABB.first.z() );
|
||||
extent.first.setZ( prismAABB.first.z() );
|
||||
if (extent.second.x() < prismAABB.second.x())
|
||||
extent.second.setX(prismAABB.second.x());
|
||||
extent.second.setX(prismAABB.second.x());
|
||||
if (extent.second.y() < prismAABB.second.y())
|
||||
extent.second.setY(prismAABB.second.y());
|
||||
extent.second.setY(prismAABB.second.y());
|
||||
if (extent.second.z() < prismAABB.second.z())
|
||||
extent.second.setZ(prismAABB.second.z());
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if prismAABB is outside the voxel limits
|
||||
@@ -500,13 +493,13 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
|
||||
if (prismAABB.second.z() < limits.GetMinZExtent()) continue;
|
||||
|
||||
// Clip edges of the prism by adjusted G4VoxelLimits box
|
||||
std::vector<G4Segment3D> vecEdges;
|
||||
CreateListOfEdges(*baseA, *baseB, vecEdges);
|
||||
std::vector<G4Segment3D> vecEdges;
|
||||
CreateListOfEdges(baseA, baseB, vecEdges);
|
||||
if (ClipEdgesByVoxel(vecEdges, limits, extent)) continue;
|
||||
|
||||
// Some edges of the prism are completely outside of the voxel
|
||||
// limits, clip selected edges (see bits) of adjusted G4VoxelLimits
|
||||
// by the prism
|
||||
// by the prism
|
||||
G4int bits = 0x000;
|
||||
if (limits.GetMinXExtent() < prismAABB.first.x())
|
||||
bits |= 0x988; // 1001 1000 1000
|
||||
@@ -524,17 +517,13 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
|
||||
bits |= 0x0F0; // 0000 1111 0000
|
||||
if (bits == 0xFFF) continue;
|
||||
|
||||
std::vector<G4Plane3D> vecPlanes;
|
||||
CreateListOfPlanes(*baseA, *baseB, vecPlanes);
|
||||
std::vector<G4Plane3D> vecPlanes;
|
||||
CreateListOfPlanes(baseA, baseB, vecPlanes);
|
||||
ClipVoxelByPlanes(bits, limits, vecPlanes, prismAABB, extent);
|
||||
} // End of the main loop
|
||||
|
||||
// Free memory
|
||||
//
|
||||
for (G4int i=0; i<nbases; ++i) { delete bases[i]; bases[i] = nullptr; }
|
||||
|
||||
// Final adjustment of the extent
|
||||
//
|
||||
//
|
||||
G4double emin = 0, emax = 0;
|
||||
if (pAxis == kXAxis) { emin = extent.first.x(); emax = extent.second.x(); }
|
||||
if (pAxis == kYAxis) { emin = extent.first.y(); emax = extent.second.y(); }
|
||||
@@ -550,7 +539,6 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Find max scale factor of the transformation
|
||||
@@ -583,12 +571,15 @@ G4BoundingEnvelope::FindScaleFactor(const G4Transform3D& pTransform3D) const
|
||||
// Transform polygonal bases
|
||||
//
|
||||
void
|
||||
G4BoundingEnvelope::TransformVertices(const G4Transform3D& pTransform3D,
|
||||
std::vector<G4Polygon3D*>& pBases) const
|
||||
G4BoundingEnvelope::
|
||||
TransformVertices(const G4Transform3D& pTransform3D,
|
||||
std::vector<G4Point3D>& pVertices,
|
||||
std::vector<std::pair<G4int, G4int>>& pBases) const
|
||||
{
|
||||
G4ThreeVectorList baseA(4), baseB(4);
|
||||
std::vector<const G4ThreeVectorList*> aabb(2);
|
||||
aabb[0] = &baseA; aabb[1] = &baseB;
|
||||
aabb[0] = &baseA;
|
||||
aabb[1] = &baseB;
|
||||
if (fPolygons == nullptr)
|
||||
{
|
||||
baseA[0].set(fMin.x(),fMin.y(),fMin.z());
|
||||
@@ -600,32 +591,35 @@ G4BoundingEnvelope::TransformVertices(const G4Transform3D& pTransform3D,
|
||||
baseB[2].set(fMax.x(),fMax.y(),fMax.z());
|
||||
baseB[3].set(fMin.x(),fMax.y(),fMax.z());
|
||||
}
|
||||
std::vector<const G4ThreeVectorList*>::const_iterator ia, iaend;
|
||||
auto ib = pBases.begin();
|
||||
ia = (fPolygons == nullptr) ? aabb.cbegin() : fPolygons->cbegin();
|
||||
iaend = (fPolygons == nullptr) ? aabb.cend() : fPolygons->cend();
|
||||
auto ia = (fPolygons == nullptr) ? aabb.cbegin() : fPolygons->cbegin();
|
||||
auto iaend = (fPolygons == nullptr) ? aabb.cend() : fPolygons->cend();
|
||||
|
||||
if (pTransform3D.xx()==1 && pTransform3D.yy()==1 && pTransform3D.zz()==1)
|
||||
// Fill vector of bases
|
||||
//
|
||||
G4int index = 0;
|
||||
for (auto i = ia; i != iaend; ++i)
|
||||
{
|
||||
G4int nv = (*i)->size();
|
||||
pBases.push_back(std::make_pair(index, nv));
|
||||
index += nv;
|
||||
}
|
||||
|
||||
// Fill vector of transformed vertices
|
||||
//
|
||||
if (pTransform3D.xx() == 1. &&
|
||||
pTransform3D.yy() == 1. &&
|
||||
pTransform3D.zz() == 1.)
|
||||
{
|
||||
G4ThreeVector offset = pTransform3D.getTranslation();
|
||||
for ( ; ia != iaend; ++ia, ++ib)
|
||||
{
|
||||
auto ka = (*ia)->cbegin();
|
||||
auto kb = (*ib)->begin();
|
||||
for ( ; ka != (*ia)->cend(); ++ka, ++kb) { (*kb) = (*ka) + offset; }
|
||||
}
|
||||
for (auto i = ia; i != iaend; ++i)
|
||||
for (auto k = (*i)->cbegin(); k != (*i)->cend(); ++k)
|
||||
pVertices.push_back(G4Point3D((*k) + offset));
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( ; ia != iaend; ++ia, ++ib)
|
||||
{
|
||||
auto ka = (*ia)->cbegin();
|
||||
auto kb = (*ib)->begin();
|
||||
for ( ; ka != (*ia)->cend(); ++ka, ++kb)
|
||||
{
|
||||
(*kb) = pTransform3D*G4Point3D(*ka);
|
||||
}
|
||||
}
|
||||
for (auto i = ia; i != iaend; ++i)
|
||||
for (auto k = (*i)->cbegin(); k != (*i)->cend(); ++k)
|
||||
pVertices.push_back(pTransform3D*G4Point3D(*k));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -644,14 +638,14 @@ G4BoundingEnvelope::GetPrismAABB(const G4Polygon3D& pBaseA,
|
||||
// First base
|
||||
//
|
||||
for (auto it1 = pBaseA.cbegin(); it1 != pBaseA.cend(); ++it1)
|
||||
{
|
||||
{
|
||||
G4double x = it1->x();
|
||||
if (x < xmin) xmin = x;
|
||||
if (x > xmax) xmax = x;
|
||||
G4double y = it1->y();
|
||||
G4double y = it1->y();
|
||||
if (y < ymin) ymin = y;
|
||||
if (y > ymax) ymax = y;
|
||||
G4double z = it1->z();
|
||||
G4double z = it1->z();
|
||||
if (z < zmin) zmin = z;
|
||||
if (z > zmax) zmax = z;
|
||||
}
|
||||
@@ -659,14 +653,14 @@ G4BoundingEnvelope::GetPrismAABB(const G4Polygon3D& pBaseA,
|
||||
// Second base
|
||||
//
|
||||
for (auto it2 = pBaseB.cbegin(); it2 != pBaseB.cend(); ++it2)
|
||||
{
|
||||
G4double x = it2->x();
|
||||
{
|
||||
G4double x = it2->x();
|
||||
if (x < xmin) xmin = x;
|
||||
if (x > xmax) xmax = x;
|
||||
G4double y = it2->y();
|
||||
G4double y = it2->y();
|
||||
if (y < ymin) ymin = y;
|
||||
if (y > ymax) ymax = y;
|
||||
G4double z = it2->z();
|
||||
G4double z = it2->z();
|
||||
if (z < zmin) zmin = z;
|
||||
if (z > zmax) zmax = z;
|
||||
}
|
||||
@@ -817,7 +811,7 @@ G4BoundingEnvelope::CreateListOfPlanes(const G4Polygon3D& baseA,
|
||||
{
|
||||
pPlanes[i] = G4Plane3D(-pPlanes[i].a(),-pPlanes[i].b(),
|
||||
-pPlanes[i].c(),-pPlanes[i].d());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -825,7 +819,7 @@ G4BoundingEnvelope::CreateListOfPlanes(const G4Polygon3D& baseA,
|
||||
//
|
||||
// Clip edges of a prism by G4VoxelLimits box. Return true if all edges
|
||||
// are inside or intersect the voxel, in this case further calculations
|
||||
// are not needed
|
||||
// are not needed
|
||||
//
|
||||
G4bool
|
||||
G4BoundingEnvelope::ClipEdgesByVoxel(const std::vector<G4Segment3D>& pEdges,
|
||||
@@ -846,8 +840,8 @@ G4BoundingEnvelope::ClipEdgesByVoxel(const std::vector<G4Segment3D>& pEdges,
|
||||
std::abs(p1.z()-p2.z()) < kCarTolerance) continue;
|
||||
G4double d1, d2;
|
||||
// Clip current edge by X min
|
||||
d1 = pBox.GetMinXExtent() - p1.x();
|
||||
d2 = pBox.GetMinXExtent() - p2.x();
|
||||
d1 = pBox.GetMinXExtent() - p1.x();
|
||||
d2 = pBox.GetMinXExtent() - p2.x();
|
||||
if (d1 > 0.0)
|
||||
{
|
||||
if (d2 > 0.0) { done = false; continue; } // go to next edge
|
||||
@@ -859,8 +853,8 @@ G4BoundingEnvelope::ClipEdgesByVoxel(const std::vector<G4Segment3D>& pEdges,
|
||||
}
|
||||
|
||||
// Clip current edge by X max
|
||||
d1 = p1.x() - pBox.GetMaxXExtent();
|
||||
d2 = p2.x() - pBox.GetMaxXExtent();
|
||||
d1 = p1.x() - pBox.GetMaxXExtent();
|
||||
d2 = p2.x() - pBox.GetMaxXExtent();
|
||||
if (d1 > 0.)
|
||||
{
|
||||
if (d2 > 0.) { done = false; continue; } // go to next edge
|
||||
@@ -872,8 +866,8 @@ G4BoundingEnvelope::ClipEdgesByVoxel(const std::vector<G4Segment3D>& pEdges,
|
||||
}
|
||||
|
||||
// Clip current edge by Y min
|
||||
d1 = pBox.GetMinYExtent() - p1.y();
|
||||
d2 = pBox.GetMinYExtent() - p2.y();
|
||||
d1 = pBox.GetMinYExtent() - p1.y();
|
||||
d2 = pBox.GetMinYExtent() - p2.y();
|
||||
if (d1 > 0.)
|
||||
{
|
||||
if (d2 > 0.) { done = false; continue; } // go to next edge
|
||||
@@ -885,8 +879,8 @@ G4BoundingEnvelope::ClipEdgesByVoxel(const std::vector<G4Segment3D>& pEdges,
|
||||
}
|
||||
|
||||
// Clip current edge by Y max
|
||||
d1 = p1.y() - pBox.GetMaxYExtent();
|
||||
d2 = p2.y() - pBox.GetMaxYExtent();
|
||||
d1 = p1.y() - pBox.GetMaxYExtent();
|
||||
d2 = p2.y() - pBox.GetMaxYExtent();
|
||||
if (d1 > 0.)
|
||||
{
|
||||
if (d2 > 0.) { done = false; continue; } // go to next edge
|
||||
@@ -898,8 +892,8 @@ G4BoundingEnvelope::ClipEdgesByVoxel(const std::vector<G4Segment3D>& pEdges,
|
||||
}
|
||||
|
||||
// Clip current edge by Z min
|
||||
d1 = pBox.GetMinZExtent() - p1.z();
|
||||
d2 = pBox.GetMinZExtent() - p2.z();
|
||||
d1 = pBox.GetMinZExtent() - p1.z();
|
||||
d2 = pBox.GetMinZExtent() - p2.z();
|
||||
if (d1 > 0.)
|
||||
{
|
||||
if (d2 > 0.) { done = false; continue; } // go to next edge
|
||||
@@ -911,8 +905,8 @@ G4BoundingEnvelope::ClipEdgesByVoxel(const std::vector<G4Segment3D>& pEdges,
|
||||
}
|
||||
|
||||
// Clip current edge by Z max
|
||||
d1 = p1.z() - pBox.GetMaxZExtent();
|
||||
d2 = p2.z() - pBox.GetMaxZExtent();
|
||||
d1 = p1.z() - pBox.GetMaxZExtent();
|
||||
d2 = p2.z() - pBox.GetMaxZExtent();
|
||||
if (d1 > 0.)
|
||||
{
|
||||
if (d2 > 0.) { done = false; continue; } // go to next edge
|
||||
@@ -924,13 +918,13 @@ G4BoundingEnvelope::ClipEdgesByVoxel(const std::vector<G4Segment3D>& pEdges,
|
||||
}
|
||||
|
||||
// Adjust current extent
|
||||
emin.setX(std::min(std::min(p1.x(),p2.x()),emin.x()));
|
||||
emin.setY(std::min(std::min(p1.y(),p2.y()),emin.y()));
|
||||
emin.setZ(std::min(std::min(p1.z(),p2.z()),emin.z()));
|
||||
emin.setX(std::min(std::min(p1.x(),p2.x()),emin.x()));
|
||||
emin.setY(std::min(std::min(p1.y(),p2.y()),emin.y()));
|
||||
emin.setZ(std::min(std::min(p1.z(),p2.z()),emin.z()));
|
||||
|
||||
emax.setX(std::max(std::max(p1.x(),p2.x()),emax.x()));
|
||||
emax.setY(std::max(std::max(p1.y(),p2.y()),emax.y()));
|
||||
emax.setZ(std::max(std::max(p1.z(),p2.z()),emax.z()));
|
||||
emax.setX(std::max(std::max(p1.x(),p2.x()),emax.x()));
|
||||
emax.setY(std::max(std::max(p1.y(),p2.y()),emax.y()));
|
||||
emax.setZ(std::max(std::max(p1.z(),p2.z()),emax.z()));
|
||||
}
|
||||
|
||||
// Return true if all edges (at least partially) are inside
|
||||
@@ -970,8 +964,8 @@ G4BoundingEnvelope::ClipVoxelByPlanes(G4int pBits,
|
||||
std::vector<G4Segment3D> edges(12);
|
||||
G4int i = 0, bits = pBits;
|
||||
if (!(bits & 0x001))
|
||||
{
|
||||
edges[i ].first.set( xmin,ymin,zmin);
|
||||
{
|
||||
edges[i ].first.set( xmin,ymin,zmin);
|
||||
edges[i++].second.set(xmax,ymin,zmin);
|
||||
}
|
||||
if (!(bits & 0x002))
|
||||
@@ -987,12 +981,12 @@ G4BoundingEnvelope::ClipVoxelByPlanes(G4int pBits,
|
||||
if (!(bits & 0x008))
|
||||
{
|
||||
edges[i ].first.set( xmin,ymax,zmin);
|
||||
edges[i++].second.set(xmin,ymin,zmin);
|
||||
edges[i++].second.set(xmin,ymin,zmin);
|
||||
}
|
||||
|
||||
if (!(bits & 0x010))
|
||||
{
|
||||
edges[i ].first.set( xmin,ymin,zmax);
|
||||
{
|
||||
edges[i ].first.set( xmin,ymin,zmax);
|
||||
edges[i++].second.set(xmax,ymin,zmax);
|
||||
}
|
||||
if (!(bits & 0x020))
|
||||
@@ -1008,13 +1002,13 @@ G4BoundingEnvelope::ClipVoxelByPlanes(G4int pBits,
|
||||
if (!(bits & 0x080))
|
||||
{
|
||||
edges[i ].first.set( xmin,ymax,zmax);
|
||||
edges[i++].second.set(xmin,ymin,zmax);
|
||||
edges[i++].second.set(xmin,ymin,zmax);
|
||||
}
|
||||
|
||||
if (!(bits & 0x100))
|
||||
{
|
||||
edges[i ].first.set( xmin,ymin,zmin);
|
||||
edges[i++].second.set(xmin,ymin,zmax);
|
||||
{
|
||||
edges[i ].first.set( xmin,ymin,zmin);
|
||||
edges[i++].second.set(xmin,ymin,zmax);
|
||||
}
|
||||
if (!(bits & 0x200))
|
||||
{
|
||||
@@ -1043,8 +1037,8 @@ G4BoundingEnvelope::ClipVoxelByPlanes(G4int pBits,
|
||||
for (auto iplane = pPlanes.cbegin(); iplane != pPlanes.cend(); ++iplane)
|
||||
{
|
||||
// Clip current edge
|
||||
G4double d1 = iplane->distance(p1);
|
||||
G4double d2 = iplane->distance(p2);
|
||||
G4double d1 = iplane->distance(p1);
|
||||
G4double d2 = iplane->distance(p2);
|
||||
if (d1 > 0.0)
|
||||
{
|
||||
if (d2 > 0.0) { exist = false; break; } // go to next edge
|
||||
@@ -1058,13 +1052,13 @@ G4BoundingEnvelope::ClipVoxelByPlanes(G4int pBits,
|
||||
// Adjust the extent
|
||||
if (exist)
|
||||
{
|
||||
emin.setX(std::min(std::min(p1.x(),p2.x()),emin.x()));
|
||||
emin.setY(std::min(std::min(p1.y(),p2.y()),emin.y()));
|
||||
emin.setZ(std::min(std::min(p1.z(),p2.z()),emin.z()));
|
||||
emin.setX(std::min(std::min(p1.x(),p2.x()),emin.x()));
|
||||
emin.setY(std::min(std::min(p1.y(),p2.y()),emin.y()));
|
||||
emin.setZ(std::min(std::min(p1.z(),p2.z()),emin.z()));
|
||||
|
||||
emax.setX(std::max(std::max(p1.x(),p2.x()),emax.x()));
|
||||
emax.setY(std::max(std::max(p1.y(),p2.y()),emax.y()));
|
||||
emax.setZ(std::max(std::max(p1.z(),p2.z()),emax.z()));
|
||||
emax.setX(std::max(std::max(p1.x(),p2.x()),emax.x()));
|
||||
emax.setY(std::max(std::max(p1.y(),p2.y()),emax.y()));
|
||||
emax.setZ(std::max(std::max(p1.z(),p2.z()),emax.z()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -348,6 +348,24 @@ G4ReflectedSolid::ComputeDimensions( G4VPVParameterisation*,
|
||||
"Method not applicable in this context!");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Return volume
|
||||
|
||||
G4double G4ReflectedSolid::GetCubicVolume()
|
||||
{
|
||||
return fPtrSolid->GetCubicVolume();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Return surface area
|
||||
|
||||
G4double G4ReflectedSolid::GetSurfaceArea()
|
||||
{
|
||||
return fPtrSolid->GetSurfaceArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Return a point (G4ThreeVector) randomly and uniformly selected
|
||||
|
||||
@@ -1,32 +1,37 @@
|
||||
-------------------------------------------------------------------
|
||||
# Category geomnav History
|
||||
|
||||
=========================================================
|
||||
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
|
||||
=========================================================
|
||||
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
|
||||
which **must** added in reverse chronological order (newest at the top).
|
||||
It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
Category History file
|
||||
---------------------
|
||||
This file should be used by G4 developers and category coordinators
|
||||
to briefly summarize all major modifications introduced in the code
|
||||
and keep track of all category-tags.
|
||||
It DOES NOT substitute the CVS log-message one should put at every
|
||||
committal in the CVS repository !
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
----------------------------------------------------------
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
## 2022-05-10 Guilherme Amadio (geomnav-V11-00-05)
|
||||
- G4Navigator: minor improvements to ComputeSafety/ComputeStep/LocateGlobalPointAndSetup
|
||||
|
||||
March 3, 2022 - P.Arce (geomnav-V10-07-06)
|
||||
-------------
|
||||
- G4RegularNavigation: reset the zero step counter when a non-zero step was
|
||||
performed, to avoid aborted events. Correct tabulation.
|
||||
Fixes as proposed in [GitHub PR #38](https://github.com/Geant4/geant4/pull/38)
|
||||
## 2022-03-11 Pedro Arce (geomnav-V11-00-04)
|
||||
- `G4RegularNavigation`: reset the zero step counter when a non-zero step was performed, to avoid aborted events. Correct tabulation.
|
||||
Fixes as proposed in [GitHub PR #38](https://github.com/Geant4/geant4/pull/38)
|
||||
|
||||
January 1, 2022 - G.Cosmo
|
||||
-------------------------
|
||||
- G4VIntersectionLocator: fixed compilation warning on Intel-icx compiler
|
||||
## 2022-02-14 Sergio Losilla (geomnav-V11-00-03)
|
||||
- /geometry/run/test also checks for overlaps in parallel worlds if
|
||||
/geometry/run/check_parallel is set to true.
|
||||
|
||||
## 2022-01-08 Gabriele Cosmo (geomnav-V11-00-02)
|
||||
- `G4VIntersectionLocator`: Fixed compilation warning on Intel-icx compiler
|
||||
for unused data.
|
||||
|
||||
## 2022-01-05 Jonas Hahnfeld (geomnav-V11-00-01)
|
||||
- `G4TransportationManager`: Add constant `kMassNavigatorId`
|
||||
- `G4SafetyHelper`: Use it
|
||||
|
||||
## 2021-12-10 Ben Morgan (geomnav-V11-00-00)
|
||||
- Change to new Markdown History format
|
||||
|
||||
---
|
||||
|
||||
# History entries prior to 11.0
|
||||
|
||||
September 25, 2021 - P.Arce (geomnav-V10-07-05)
|
||||
----------------------------
|
||||
- Reduce warning messages in GetReplicaNo: only when difference is > kCarTolerance
|
||||
|
||||
@@ -48,6 +48,8 @@ class G4UIcmdWithADoubleAndUnit;
|
||||
class G4TransportationManager;
|
||||
class G4GeomTestVolume;
|
||||
|
||||
#include <vector>
|
||||
|
||||
class G4GeometryMessenger : public G4UImessenger
|
||||
{
|
||||
public: // with description
|
||||
@@ -70,16 +72,17 @@ class G4GeometryMessenger : public G4UImessenger
|
||||
void RecursiveOverlapTest();
|
||||
|
||||
G4UIdirectory *geodir, *navdir, *testdir;
|
||||
G4UIcmdWithABool *chkCmd, *pchkCmd, *verCmd;
|
||||
G4UIcmdWithABool *chkCmd, *pchkCmd, *verCmd, *parCmd;
|
||||
G4UIcmdWithoutParameter *recCmd, *resCmd;
|
||||
G4UIcmdWithADoubleAndUnit *tolCmd;
|
||||
G4UIcmdWithAnInteger *verbCmd, *rslCmd, *rcsCmd, *rcdCmd, *errCmd;
|
||||
|
||||
G4double tol = 0.0;
|
||||
G4int recLevel = 0, recDepth = -1;
|
||||
G4bool checkParallelWorlds = false;
|
||||
|
||||
G4TransportationManager* tmanager;
|
||||
G4GeomTestVolume* tvolume = nullptr;
|
||||
std::vector<G4GeomTestVolume*> tvolumes{};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -92,7 +92,6 @@ class G4SafetyHelper
|
||||
|
||||
G4PathFinder* fpPathFinder = nullptr;
|
||||
G4Navigator* fpMassNavigator = nullptr;
|
||||
G4int fMassNavigatorId = -1;
|
||||
|
||||
G4bool fUseParallelGeometries = false;
|
||||
// Flag whether to use PathFinder or single (mass) Navigator directly
|
||||
|
||||
@@ -153,6 +153,10 @@ class G4TransportationManager
|
||||
static G4ThreadLocal G4TransportationManager* fTransportationManager;
|
||||
|
||||
static G4Navigator* fFirstTrackingNavigator;
|
||||
|
||||
public:
|
||||
|
||||
static constexpr G4int kMassNavigatorId = 0;
|
||||
};
|
||||
|
||||
#include "G4TransportationManager.icc"
|
||||
|
||||
@@ -155,6 +155,12 @@ G4GeometryMessenger::G4GeometryMessenger(G4TransportationManager* tman)
|
||||
errCmd->SetParameterName("maximum_errors",true);
|
||||
errCmd->SetDefaultValue(1);
|
||||
|
||||
parCmd = new G4UIcmdWithABool( "/geometry/test/check_parallel", this );
|
||||
parCmd->SetGuidance( "Check for overlaps in parallel worlds." );
|
||||
parCmd->SetGuidance( "By default, overlaps are only checked in the mass world (FALSE)." );
|
||||
parCmd->SetParameterName("check_parallel",true);
|
||||
parCmd->SetDefaultValue(true);
|
||||
|
||||
recCmd = new G4UIcmdWithoutParameter( "/geometry/test/run", this );
|
||||
recCmd->SetGuidance( "Start running the recursive overlap check." );
|
||||
recCmd->SetGuidance( "Volumes are recursively asked to verify for overlaps" );
|
||||
@@ -177,7 +183,9 @@ G4GeometryMessenger::~G4GeometryMessenger()
|
||||
delete tolCmd;
|
||||
delete verbCmd; delete pchkCmd; delete chkCmd;
|
||||
delete geodir; delete navdir; delete testdir;
|
||||
delete tvolume;
|
||||
for(auto* tvolume: tvolumes) {
|
||||
delete tvolume;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@@ -188,16 +196,18 @@ G4GeometryMessenger::Init()
|
||||
{
|
||||
// Create checker...
|
||||
//
|
||||
if (tvolume == nullptr)
|
||||
if (tvolumes.empty())
|
||||
{
|
||||
// Get the world volume
|
||||
// Get all world volumes
|
||||
//
|
||||
G4VPhysicalVolume* world =
|
||||
tmanager->GetNavigatorForTracking()->GetWorldVolume();
|
||||
|
||||
// Test the actual detector...
|
||||
//
|
||||
tvolume = new G4GeomTestVolume(world);
|
||||
const auto noWorlds = tmanager->GetNoWorlds();
|
||||
const auto fWorld = tmanager->GetWorldsIterator();
|
||||
for(size_t i=0;i<noWorlds;++i)
|
||||
{
|
||||
// Test the actual detector...
|
||||
//
|
||||
tvolumes.push_back(new G4GeomTestVolume(fWorld[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,15 +233,24 @@ G4GeometryMessenger::SetNewValue( G4UIcommand* command, G4String newValues )
|
||||
Init();
|
||||
tol = tolCmd->GetNewDoubleValue( newValues )
|
||||
* tolCmd->GetNewUnitValue( newValues );
|
||||
tvolume->SetTolerance(tol);
|
||||
for(auto* tvolume: tvolumes)
|
||||
{
|
||||
tvolume->SetTolerance(tol);
|
||||
}
|
||||
}
|
||||
else if (command == verCmd) {
|
||||
Init();
|
||||
tvolume->SetVerbosity(verCmd->GetNewBoolValue( newValues ));
|
||||
for(auto* tvolume: tvolumes)
|
||||
{
|
||||
tvolume->SetVerbosity(verCmd->GetNewBoolValue( newValues ));
|
||||
}
|
||||
}
|
||||
else if (command == rslCmd) {
|
||||
Init();
|
||||
tvolume->SetResolution(rslCmd->GetNewIntValue( newValues ));
|
||||
for(auto* tvolume: tvolumes)
|
||||
{
|
||||
tvolume->SetResolution(rslCmd->GetNewIntValue( newValues ));
|
||||
}
|
||||
}
|
||||
else if (command == rcsCmd) {
|
||||
recLevel = rcsCmd->GetNewIntValue( newValues );
|
||||
@@ -241,7 +260,10 @@ G4GeometryMessenger::SetNewValue( G4UIcommand* command, G4String newValues )
|
||||
}
|
||||
else if (command == errCmd) {
|
||||
Init();
|
||||
tvolume->SetErrorsThreshold(errCmd->GetNewIntValue( newValues ));
|
||||
for(auto* tvolume: tvolumes)
|
||||
{
|
||||
tvolume->SetErrorsThreshold(errCmd->GetNewIntValue( newValues ));
|
||||
}
|
||||
}
|
||||
else if (command == recCmd) {
|
||||
Init();
|
||||
@@ -345,5 +367,15 @@ G4GeometryMessenger::RecursiveOverlapTest()
|
||||
|
||||
// Make test on single line supplied by user recursively
|
||||
//
|
||||
tvolume->TestRecursiveOverlap( recLevel, recDepth );
|
||||
if (checkParallelWorlds)
|
||||
{
|
||||
for(auto* tvolume: tvolumes)
|
||||
{
|
||||
tvolume->TestRecursiveOverlap( recLevel, recDepth );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tvolumes.front()->TestRecursiveOverlap( recLevel, recDepth );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,12 +141,12 @@ G4Navigator::LocateGlobalPointAndSetup( const G4ThreeVector& globalPoint,
|
||||
G4ThreeVector localPoint, globalDirection;
|
||||
EInside insideCode;
|
||||
|
||||
G4bool considerDirection = (!ignoreDirection) || fLocatedOnEdge;
|
||||
G4bool considerDirection = pGlobalDirection && ((!ignoreDirection) || fLocatedOnEdge);
|
||||
|
||||
fLastTriedStepComputation = false;
|
||||
fChangedGrandMotherRefFrame = false; // For local exit normal
|
||||
|
||||
if( considerDirection && pGlobalDirection != nullptr )
|
||||
if( considerDirection )
|
||||
{
|
||||
globalDirection=*pGlobalDirection;
|
||||
}
|
||||
@@ -342,103 +342,96 @@ G4Navigator::LocateGlobalPointAndSetup( const G4ThreeVector& globalPoint,
|
||||
}
|
||||
}
|
||||
|
||||
if ( insideCode==kOutside )
|
||||
{
|
||||
++noLevelsExited;
|
||||
if ( fHistory.GetDepth() )
|
||||
{
|
||||
fBlockedPhysicalVolume = fHistory.GetTopVolume();
|
||||
fBlockedReplicaNo = fHistory.GetTopReplicaNo();
|
||||
fHistory.BackLevel();
|
||||
fExiting = false;
|
||||
// Point is inside current volume, break out of the loop
|
||||
if ( insideCode == kInside )
|
||||
break;
|
||||
|
||||
if( noLevelsExited > 1 )
|
||||
// Point is outside current volume, move up a level in the hierarchy
|
||||
if ( insideCode == kOutside )
|
||||
{
|
||||
++noLevelsExited;
|
||||
|
||||
// Exiting world volume
|
||||
if ( fHistory.GetDepth() == 0 )
|
||||
{
|
||||
fLocatedOutsideWorld = true;
|
||||
fLastLocatedPointLocal = localPoint;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
fBlockedPhysicalVolume = fHistory.GetTopVolume();
|
||||
fBlockedReplicaNo = fHistory.GetTopReplicaNo();
|
||||
fHistory.BackLevel();
|
||||
fExiting = false;
|
||||
|
||||
if( noLevelsExited > 1 )
|
||||
{
|
||||
// The first transformation was done by the sub-navigator
|
||||
//
|
||||
if(const auto *mRot = fBlockedPhysicalVolume->GetRotation())
|
||||
{
|
||||
// The first transformation was done by the sub-navigator
|
||||
//
|
||||
const G4RotationMatrix* mRot = fBlockedPhysicalVolume->GetRotation();
|
||||
if( mRot )
|
||||
{
|
||||
fGrandMotherExitNormal *= (*mRot).inverse();
|
||||
fChangedGrandMotherRefFrame = true;
|
||||
}
|
||||
fGrandMotherExitNormal *= (*mRot).inverse();
|
||||
fChangedGrandMotherRefFrame = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
// Point is on the surface of a volume
|
||||
G4bool isExiting = fExiting;
|
||||
if( (!fExiting) && considerDirection )
|
||||
{
|
||||
// Figure out whether we are exiting this level's volume
|
||||
// by using the direction
|
||||
//
|
||||
G4bool directionExiting = false;
|
||||
G4ThreeVector localDirection =
|
||||
fHistory.GetTopTransform().TransformAxis(globalDirection);
|
||||
|
||||
// Make sure localPoint in correct reference frame
|
||||
// ( Was it already correct ? How ? )
|
||||
//
|
||||
localPoint= fHistory.GetTopTransform().TransformPoint(globalPoint);
|
||||
if ( fHistory.GetTopVolumeType() != kReplica )
|
||||
{
|
||||
fLastLocatedPointLocal = localPoint;
|
||||
fLocatedOutsideWorld = true;
|
||||
// No extra transformation for ExitNormal - is in frame of Top Volume
|
||||
return nullptr; // Have exited world volume
|
||||
G4ThreeVector normal = targetSolid->SurfaceNormal(localPoint);
|
||||
directionExiting = normal.dot(localDirection) > 0.0;
|
||||
isExiting = isExiting || directionExiting;
|
||||
}
|
||||
}
|
||||
else
|
||||
if ( insideCode==kSurface )
|
||||
{
|
||||
G4bool isExiting = fExiting;
|
||||
if( (!fExiting) && considerDirection )
|
||||
{
|
||||
// Figure out whether we are exiting this level's volume
|
||||
// by using the direction
|
||||
//
|
||||
G4bool directionExiting = false;
|
||||
G4ThreeVector localDirection =
|
||||
fHistory.GetTopTransform().TransformAxis(globalDirection);
|
||||
|
||||
// Make sure localPoint in correct reference frame
|
||||
// ( Was it already correct ? How ? )
|
||||
//
|
||||
localPoint= fHistory.GetTopTransform().TransformPoint(globalPoint);
|
||||
if ( fHistory.GetTopVolumeType() != kReplica )
|
||||
{
|
||||
G4ThreeVector normal = targetSolid->SurfaceNormal(localPoint);
|
||||
directionExiting = normal.dot(localDirection) > 0.0;
|
||||
isExiting = isExiting || directionExiting;
|
||||
}
|
||||
}
|
||||
if( isExiting )
|
||||
{
|
||||
++noLevelsExited;
|
||||
if ( fHistory.GetDepth() )
|
||||
{
|
||||
fBlockedPhysicalVolume = fHistory.GetTopVolume();
|
||||
fBlockedReplicaNo = fHistory.GetTopReplicaNo();
|
||||
fHistory.BackLevel();
|
||||
//
|
||||
// Still on surface but exited volume not necessarily convex
|
||||
//
|
||||
fValidExitNormal = false;
|
||||
// Point is on a surface, but no longer exiting, break out of the loop
|
||||
if ( !isExiting )
|
||||
break;
|
||||
|
||||
if( noLevelsExited > 1 )
|
||||
{
|
||||
// The first transformation was done by the sub-navigator
|
||||
//
|
||||
const G4RotationMatrix* mRot =
|
||||
fBlockedPhysicalVolume->GetRotation();
|
||||
if( mRot )
|
||||
{
|
||||
fGrandMotherExitNormal *= (*mRot).inverse();
|
||||
fChangedGrandMotherRefFrame = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fLastLocatedPointLocal = localPoint;
|
||||
fLocatedOutsideWorld = true;
|
||||
// No extra transformation for ExitNormal, is in frame of Top Vol
|
||||
return nullptr; // Have exited world volume
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notKnownContained = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
++noLevelsExited;
|
||||
|
||||
// Point is on the outer surface, leaving world volume
|
||||
if ( fHistory.GetDepth() == 0 )
|
||||
{
|
||||
fLocatedOutsideWorld = true;
|
||||
fLastLocatedPointLocal = localPoint;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Point is still on a surface, but exited a volume not necessarily convex
|
||||
fValidExitNormal = false;
|
||||
fBlockedPhysicalVolume = fHistory.GetTopVolume();
|
||||
fBlockedReplicaNo = fHistory.GetTopReplicaNo();
|
||||
fHistory.BackLevel();
|
||||
|
||||
if( noLevelsExited > 1 )
|
||||
{
|
||||
// The first transformation was done by the sub-navigator
|
||||
//
|
||||
const G4RotationMatrix* mRot =
|
||||
fBlockedPhysicalVolume->GetRotation();
|
||||
if( mRot )
|
||||
{
|
||||
notKnownContained = false;
|
||||
fGrandMotherExitNormal *= (*mRot).inverse();
|
||||
fChangedGrandMotherRefFrame = true;
|
||||
}
|
||||
}
|
||||
} // END while (notKnownContained)
|
||||
//
|
||||
// Search downwards until deepest containing volume found,
|
||||
@@ -772,6 +765,11 @@ G4double G4Navigator::ComputeStep( const G4ThreeVector& pGlobalpoint,
|
||||
const G4double pCurrentProposedStepLength,
|
||||
G4double& pNewSafety)
|
||||
{
|
||||
#ifdef G4DEBUG_NAVIGATION
|
||||
static G4ThreadLocal G4int sNavCScalls = 0;
|
||||
++sNavCScalls;
|
||||
#endif
|
||||
|
||||
G4ThreeVector localDirection = ComputeLocalAxis(pDirection);
|
||||
G4double Step = kInfinity;
|
||||
G4VPhysicalVolume *motherPhysical = fHistory.GetTopVolume();
|
||||
@@ -787,11 +785,6 @@ G4double G4Navigator::ComputeStep( const G4ThreeVector& pGlobalpoint,
|
||||
fCalculatedExitNormal = false;
|
||||
// Reset for new step
|
||||
|
||||
static G4ThreadLocal G4int sNavCScalls = 0;
|
||||
++sNavCScalls;
|
||||
|
||||
fLastTriedStepComputation = true;
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if( fVerbose > 0 )
|
||||
{
|
||||
@@ -816,6 +809,7 @@ G4double G4Navigator::ComputeStep( const G4ThreeVector& pGlobalpoint,
|
||||
#endif
|
||||
|
||||
G4ThreeVector newLocalPoint = ComputeLocalPoint(pGlobalpoint);
|
||||
|
||||
if( newLocalPoint != fLastLocatedPointLocal )
|
||||
{
|
||||
// Check whether the relocation is within safety
|
||||
@@ -831,7 +825,6 @@ G4double G4Navigator::ComputeStep( const G4ThreeVector& pGlobalpoint,
|
||||
// Relocate the point within the same volume
|
||||
//
|
||||
LocateGlobalPointWithinVolume( pGlobalpoint );
|
||||
fLastTriedStepComputation = true; // Ensure that this is set again !!
|
||||
}
|
||||
}
|
||||
if ( fHistory.GetTopVolumeType()!=kReplica )
|
||||
@@ -873,7 +866,6 @@ G4double G4Navigator::ComputeStep( const G4ThreeVector& pGlobalpoint,
|
||||
else // Regular (non-voxelised) structure
|
||||
{
|
||||
LocateGlobalPointAndSetup( pGlobalpoint, &pDirection, true, true );
|
||||
fLastTriedStepComputation = true; // Ensure that this is set again!!
|
||||
//
|
||||
// if physical process limits the step, the voxel will not be the
|
||||
// one given by ComputeStepSkippingEqualMaterials() and the local
|
||||
@@ -974,8 +966,7 @@ G4double G4Navigator::ComputeStep( const G4ThreeVector& pGlobalpoint,
|
||||
// In the case of a replica, it must handle the exiting
|
||||
// edge/corner problem by itself
|
||||
//
|
||||
G4bool exitingReplica = fExitedMother;
|
||||
G4bool calculatedExitNormal;
|
||||
fExiting = fExitedMother;
|
||||
Step = freplicaNav.ComputeStep(pGlobalpoint,
|
||||
pDirection,
|
||||
fLastLocatedPointLocal,
|
||||
@@ -984,14 +975,12 @@ G4double G4Navigator::ComputeStep( const G4ThreeVector& pGlobalpoint,
|
||||
pNewSafety,
|
||||
fHistory,
|
||||
fValidExitNormal,
|
||||
calculatedExitNormal,
|
||||
fCalculatedExitNormal,
|
||||
fExitNormal,
|
||||
exitingReplica,
|
||||
fExiting,
|
||||
fEntering,
|
||||
&fBlockedPhysicalVolume,
|
||||
fBlockedReplicaNo);
|
||||
fExiting = exitingReplica;
|
||||
fCalculatedExitNormal = calculatedExitNormal;
|
||||
}
|
||||
|
||||
// Remember last safety origin & value.
|
||||
@@ -1127,17 +1116,8 @@ G4double G4Navigator::ComputeStep( const G4ThreeVector& pGlobalpoint,
|
||||
|
||||
if ( fValidExitNormal || fCalculatedExitNormal )
|
||||
{
|
||||
if ( fHistory.GetTopVolumeType() != kReplica )
|
||||
{
|
||||
// Convention: fExitNormal is in the 'grand-mother' coordinate system
|
||||
//
|
||||
fGrandMotherExitNormal = fExitNormal;
|
||||
fCalculatedExitNormal = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fGrandMotherExitNormal = fExitNormal;
|
||||
}
|
||||
// Convention: fExitNormal is in the 'grand-mother' coordinate system
|
||||
fGrandMotherExitNormal = fExitNormal;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1168,8 +1148,6 @@ G4double G4Navigator::ComputeStep( const G4ThreeVector& pGlobalpoint,
|
||||
|
||||
// Do not set fValidExitNormal -- this signifies
|
||||
// that the solid is convex!
|
||||
//
|
||||
fCalculatedExitNormal = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1195,6 +1173,9 @@ G4double G4Navigator::ComputeStep( const G4ThreeVector& pGlobalpoint,
|
||||
}
|
||||
}
|
||||
|
||||
if ( fHistory.GetTopVolumeType() != kReplica )
|
||||
fCalculatedExitNormal = true;
|
||||
|
||||
// Now transform it to the global reference frame !!
|
||||
//
|
||||
if( fValidExitNormal || fCalculatedExitNormal )
|
||||
@@ -1243,6 +1224,8 @@ G4double G4Navigator::ComputeStep( const G4ThreeVector& pGlobalpoint,
|
||||
}
|
||||
#endif
|
||||
|
||||
fLastTriedStepComputation = true;
|
||||
|
||||
return Step;
|
||||
}
|
||||
|
||||
@@ -1328,27 +1311,22 @@ void G4Navigator::ResetState()
|
||||
//
|
||||
void G4Navigator::SetupHierarchy()
|
||||
{
|
||||
const G4int cdepth = fHistory.GetDepth();
|
||||
G4VPhysicalVolume* current;
|
||||
G4VSolid* pSolid;
|
||||
G4VPVParameterisation* pParam;
|
||||
|
||||
for ( auto i=1; i<=cdepth; ++i )
|
||||
const G4int depth = fHistory.GetDepth();
|
||||
for ( auto i = 1; i <= depth; ++i )
|
||||
{
|
||||
current = fHistory.GetVolume(i);
|
||||
switch ( fHistory.GetVolumeType(i) )
|
||||
{
|
||||
case kNormal:
|
||||
case kExternal:
|
||||
break;
|
||||
case kReplica:
|
||||
freplicaNav.ComputeTransformation(fHistory.GetReplicaNo(i), current);
|
||||
freplicaNav.ComputeTransformation(fHistory.GetReplicaNo(i), fHistory.GetVolume(i));
|
||||
break;
|
||||
case kParameterised:
|
||||
G4int replicaNo;
|
||||
pParam = current->GetParameterisation();
|
||||
replicaNo = fHistory.GetReplicaNo(i);
|
||||
pSolid = pParam->ComputeSolid(replicaNo, current);
|
||||
G4VPhysicalVolume* current = fHistory.GetVolume(i);
|
||||
G4int replicaNo = fHistory.GetReplicaNo(i);
|
||||
G4VPVParameterisation* pParam = current->GetParameterisation();
|
||||
G4VSolid* pSolid = pParam->ComputeSolid(replicaNo, current);
|
||||
|
||||
// Set up dimensions & transform in solid/physical volume
|
||||
//
|
||||
@@ -1814,8 +1792,6 @@ G4double G4Navigator::ComputeSafety( const G4ThreeVector& pGlobalpoint,
|
||||
const G4double pMaxLength,
|
||||
const G4bool keepState)
|
||||
{
|
||||
G4double newSafety = 0.0;
|
||||
|
||||
#ifdef G4DEBUG_NAVIGATION
|
||||
G4int oldcoutPrec = G4cout.precision(8);
|
||||
if( fVerbose > 0 )
|
||||
@@ -1849,12 +1825,17 @@ G4double G4Navigator::ComputeSafety( const G4ThreeVector& pGlobalpoint,
|
||||
if( fExitedMother ) { G4cout << " and exited previous volume."; }
|
||||
G4cout << G4endl;
|
||||
G4cout << " EndPoint was = " << fStepEndPoint << G4endl;
|
||||
G4cout << " ---- Exiting ComputeSafety " << G4endl;
|
||||
PrintState();
|
||||
G4cout << " Returned value of Safety is zero " << G4endl;
|
||||
G4cout.precision(oldcoutPrec);
|
||||
}
|
||||
#endif
|
||||
newSafety = 0.0;
|
||||
return 0.0;
|
||||
}
|
||||
else // if( !(endpointOnSurface && stayedOnEndpoint) )
|
||||
{
|
||||
|
||||
G4double newSafety = 0.0;
|
||||
|
||||
if (keepState) { SetSavedState(); }
|
||||
|
||||
// Pseudo-relocate to this point (updates voxel information only)
|
||||
@@ -1933,7 +1914,6 @@ G4double G4Navigator::ComputeSafety( const G4ThreeVector& pGlobalpoint,
|
||||
// We overwrite the Safety 'sphere' - keeping old behaviour
|
||||
fPreviousSftOrigin = pGlobalpoint;
|
||||
fPreviousSafety = newSafety;
|
||||
}
|
||||
|
||||
#ifdef G4DEBUG_NAVIGATION
|
||||
if( fVerbose > 1 )
|
||||
|
||||
@@ -58,8 +58,6 @@ void G4SafetyHelper::InitialiseNavigator()
|
||||
"GeomNav0003", FatalException,
|
||||
"Found that existing tracking Navigator has NULL world");
|
||||
}
|
||||
|
||||
fMassNavigatorId = pTransportMgr->ActivateNavigator( fpMassNavigator );
|
||||
}
|
||||
|
||||
void G4SafetyHelper::InitialiseHelper()
|
||||
|
||||
@@ -1,39 +1,36 @@
|
||||
# Category geom-bool History
|
||||
|
||||
-------------------------------------------------------------------
|
||||
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
|
||||
which **must** added in reverse chronological order (newest at the top).
|
||||
It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
=========================================================
|
||||
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
|
||||
=========================================================
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Category History file
|
||||
---------------------
|
||||
This file should be used by G4 developers and category coordinators
|
||||
to briefly summarize all major modifications introduced in the code
|
||||
and keep track of all category-tags.
|
||||
It DOES NOT substitute the CVS log-message one should put at every
|
||||
committal in the CVS repository !
|
||||
## 2022-05-04 Gabriele Cosmo (geom-bool-V11-00-05)
|
||||
- Minor cleanup in headers and G4UnionSolid constructors.
|
||||
|
||||
Please keep a summary of these message in geometry/History!
|
||||
|
||||
----------------------------------------------------------
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
|
||||
May 4, 2022, G.Cosmo (geom-bool-V10-07-05)
|
||||
- Minor cleanup in G4UnionSolid constructors.
|
||||
|
||||
April 29, 2022, G.Cosmo
|
||||
## 2022-04-29 Gabriele Cosmo (geom-bool-V11-00-04)
|
||||
- G4UnionSolid: added missing data initialisation in copy-ctr and operator=().
|
||||
|
||||
April 5, 2022, G.Cosmo
|
||||
## 2022-04-05 Gabriele Cosmo (geom-bool-V11-00-03)
|
||||
- G4UnionSolid: add surface tolerance in Inside(p) for check on Z.
|
||||
Minor optimisation in caching half-tolerance.
|
||||
|
||||
January 10, 2022, G.Cosmo geom-bool-V10-07-04
|
||||
## 2022-01-19 Evgueni Tcherniaev (geom-bool-V11-00-02)
|
||||
- G4DisplacedSolid: added GetCubicVolume(), GetSurfaceArea()
|
||||
|
||||
## 2022-01-10 Gabriele Cosmo (geom-bool-V11-00-01)
|
||||
- Added alternative signature for AddNode() taking a pointer to solid.
|
||||
Added 'const' qualification to transformation passed as argument.
|
||||
Addressing problem report #2457.
|
||||
|
||||
## 2021-12-10 Ben Morgan (geom-bool-V11-00-00)
|
||||
- Change to new Markdown History format
|
||||
|
||||
---
|
||||
|
||||
# History entries prior to 11.0
|
||||
|
||||
October 12, 2021 G.Cosmo geom-bool-V10-07-03
|
||||
- In G4BooleanSolid, use G4RecursiveMutex in place of G4Mutex in GetPolyhedron()
|
||||
to avoid potential deadlocks in recursive Boolean operations.
|
||||
|
||||
@@ -45,7 +45,7 @@ class HepPolyhedronProcessor;
|
||||
|
||||
class G4BooleanSolid : public G4VSolid
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
|
||||
G4BooleanSolid( const G4String& pName,
|
||||
G4VSolid* pSolidA ,
|
||||
@@ -90,8 +90,6 @@ class G4BooleanSolid : public G4VSolid
|
||||
|
||||
G4ThreeVector GetPointOnSurface() const;
|
||||
|
||||
public: // without description
|
||||
|
||||
G4BooleanSolid(__void__&);
|
||||
// Fake default constructor for usage restricted to direct object
|
||||
// persistency for clients requiring preallocation of memory for
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
class G4DisplacedSolid : public G4VSolid
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
|
||||
G4DisplacedSolid( const G4String& pName,
|
||||
G4VSolid* pSolid ,
|
||||
@@ -62,10 +62,6 @@ class G4DisplacedSolid : public G4VSolid
|
||||
|
||||
virtual ~G4DisplacedSolid() ;
|
||||
|
||||
public: // without description
|
||||
|
||||
// It also has all the methods that a solid requires, eg.
|
||||
|
||||
EInside Inside( const G4ThreeVector& p ) const ;
|
||||
|
||||
void BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const;
|
||||
@@ -97,9 +93,10 @@ class G4DisplacedSolid : public G4VSolid
|
||||
|
||||
void CleanTransformations();
|
||||
|
||||
G4ThreeVector GetPointOnSurface() const;
|
||||
G4double GetCubicVolume();
|
||||
G4double GetSurfaceArea();
|
||||
|
||||
public: // with description
|
||||
G4ThreeVector GetPointOnSurface() const;
|
||||
|
||||
G4GeometryType GetEntityType() const;
|
||||
G4VSolid* Clone() const;
|
||||
@@ -134,8 +131,6 @@ class G4DisplacedSolid : public G4VSolid
|
||||
|
||||
std::ostream& StreamInfo(std::ostream& os) const;
|
||||
|
||||
public: // without description
|
||||
|
||||
G4DisplacedSolid(__void__&);
|
||||
// Fake default constructor for usage restricted to direct object
|
||||
// persistency for clients requiring preallocation of memory for
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
class G4IntersectionSolid : public G4BooleanSolid
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
|
||||
G4IntersectionSolid( const G4String& pName,
|
||||
G4VSolid* pSolidA ,
|
||||
@@ -67,8 +67,6 @@ class G4IntersectionSolid : public G4BooleanSolid
|
||||
|
||||
G4VSolid* Clone() const;
|
||||
|
||||
public: // without description
|
||||
|
||||
G4IntersectionSolid(__void__&);
|
||||
// Fake default constructor for usage restricted to direct object
|
||||
// persistency for clients requiring preallocation of memory for
|
||||
|
||||
@@ -44,7 +44,7 @@ class G4ScaleTransform;
|
||||
|
||||
class G4ScaledSolid : public G4VSolid
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
|
||||
G4ScaledSolid( const G4String& pName,
|
||||
G4VSolid* pSolid ,
|
||||
@@ -97,8 +97,6 @@ class G4ScaledSolid : public G4VSolid
|
||||
|
||||
std::ostream& StreamInfo(std::ostream& os) const;
|
||||
|
||||
public: // without description
|
||||
|
||||
G4ScaledSolid(__void__&);
|
||||
// Fake default constructor for usage restricted to direct object
|
||||
// persistency for clients requiring preallocation of memory for
|
||||
@@ -121,6 +119,6 @@ class G4ScaledSolid : public G4VSolid
|
||||
G4double fSurfaceArea = -1.0;
|
||||
mutable G4bool fRebuildPolyhedron = false;
|
||||
mutable G4Polyhedron* fpPolyhedron = nullptr;
|
||||
} ;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
class G4SubtractionSolid : public G4BooleanSolid
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
|
||||
G4SubtractionSolid( const G4String& pName,
|
||||
G4VSolid* pSolidA ,
|
||||
@@ -68,8 +68,6 @@ class G4SubtractionSolid : public G4BooleanSolid
|
||||
|
||||
G4VSolid* Clone() const;
|
||||
|
||||
public: // without description
|
||||
|
||||
G4SubtractionSolid(__void__&);
|
||||
// Fake default constructor for usage restricted to direct object
|
||||
// persistency for clients requiring preallocation of memory for
|
||||
|
||||
@@ -435,6 +435,24 @@ G4DisplacedSolid::ComputeDimensions( G4VPVParameterisation*,
|
||||
"Method not applicable in this context!");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Return volume
|
||||
|
||||
G4double G4DisplacedSolid::GetCubicVolume()
|
||||
{
|
||||
return fPtrSolid->GetCubicVolume();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Return surface area
|
||||
|
||||
G4double G4DisplacedSolid::GetSurfaceArea()
|
||||
{
|
||||
return fPtrSolid->GetSurfaceArea();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Returns a point (G4ThreeVector) randomly and uniformly selected
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
-------------------------------------------------------------------
|
||||
# Category geom-csg History
|
||||
|
||||
=========================================================
|
||||
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
|
||||
=========================================================
|
||||
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
|
||||
which **must** added in reverse chronological order (newest at the top). It must **not**
|
||||
be used as a substitute for writing good git commit messages!
|
||||
|
||||
Sub-Category History file
|
||||
-------------------------
|
||||
This file should be used by G4 developers and category coordinators
|
||||
to briefly summarize all major modifications introduced in the code
|
||||
and keep track of all directory-tags.
|
||||
It DOES NOT substitute the CVS log-message one should put at every
|
||||
committal in the CVS repository !
|
||||
|
||||
----------------------------------------------------------
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
## 2021-12-10 Ben Morgan (geom-csg-V11-00-00)
|
||||
- Change to new Markdown History format
|
||||
|
||||
---
|
||||
|
||||
# History entries prior to 11.0
|
||||
|
||||
November 24, 2021 G.Cosmo geom-csg-V10-07-06
|
||||
- Corrected typo in G4UPara::GetXHalfLength().
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
-------------------------------------------------------------------
|
||||
# Category geomsolids History
|
||||
|
||||
=========================================================
|
||||
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
|
||||
=========================================================
|
||||
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
|
||||
which **must** added in reverse chronological order (newest at the top). It must **not**
|
||||
be used as a substitute for writing good git commit messages!
|
||||
|
||||
Sub-Category History file
|
||||
-------------------------
|
||||
This file should be used by G4 developers and category coordinators
|
||||
to briefly summarize all major modifications introduced in the code
|
||||
and keep track of all directory-tags.
|
||||
It DOES NOT substitute the CVS log-message one should put at every
|
||||
committal in the CVS repository !
|
||||
|
||||
----------------------------------------------------------
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
## 2021-12-10 Ben Morgan (geomsolids-V11-00-00)
|
||||
- Change to new Markdown History format
|
||||
|
||||
---
|
||||
|
||||
# History entries prior to 11.0
|
||||
|
||||
March 30, 2021 B.Morgan - geomsolids-V10-07-00
|
||||
- Migrate sources.cmake to modular build API
|
||||
|
||||
|
||||
@@ -1,20 +1,59 @@
|
||||
-------------------------------------------------------------------
|
||||
# Category geom-specific History
|
||||
|
||||
=========================================================
|
||||
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
|
||||
=========================================================
|
||||
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
|
||||
which **must** added in reverse chronological order (newest at the top). It must **not**
|
||||
be used as a substitute for writing good git commit messages!
|
||||
|
||||
Sub-Category History file
|
||||
-------------------------
|
||||
This file should be used by G4 developers and category coordinators
|
||||
to briefly summarize all major modifications introduced in the code
|
||||
and keep track of all directory-tags.
|
||||
It DOES NOT substitute the log-message one should put at every
|
||||
committal in the source repository !
|
||||
|
||||
----------------------------------------------------------
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
## 2022-04-03 Evgueni Tcherniaev (geom-specific-V11-00-08)
|
||||
- G4GenericTrap.cc, G4UGenericTrap.cc, G4UExtrudedSolid.cc,
|
||||
G4TessellatedSolid.cc, G4TessellatedSolid.cc:
|
||||
revision of CreatePolyhedron()
|
||||
|
||||
## 2022-02-04 Evgueni Tcherniaev (geom-specific-V11-00-07)
|
||||
- G4VTwistedFaceted: used numerical evaluation of a single
|
||||
integral to calculate lateral face surface area
|
||||
|
||||
## 2022-02-01 Evgueni Tcherniaev (geom-specific-V11-00-06)
|
||||
- G4ExtrudedSolid, G4UExtrudedSolid: added default values for
|
||||
parameters in the constructor with two z-sections
|
||||
- G4ExtrudedSolid::ZSection, G4UExtrudedSolid::ZSection:
|
||||
added default constructor
|
||||
|
||||
## 2022-01-26 Evgueni Tcherniaev (geom-specific-V11-00-05)
|
||||
- G4GenericTrap::GetCubicVolume(): calculation of volume
|
||||
using analytical expression; removed private function
|
||||
GetFaceCubicVolume();
|
||||
- G4GenericTrap::GetSurfaceArea(): improved calculation
|
||||
of the area of lateral faces; private functions
|
||||
GetFaceSurfaceArea(), GetTwistedFaceSurfaceArea()
|
||||
replaced with private function GetLateralFaceArea()
|
||||
|
||||
## 2022-01-21 Evgueni Tcherniaev (geom-specific-V11-00-04)
|
||||
- G4Ellipsoid::LateralSurfaceArea(): Enhanced calculation of
|
||||
the lateral surface area
|
||||
|
||||
## 2022-01-11 Evgueni Tcherniaev (geom-specific-V11-00-03)
|
||||
- G4VTwistedFaceted: fCubicVolume, fSurfaceArea made protected,
|
||||
GetCubicVolume(), GetSurfaceArea() moved to *.cc
|
||||
- G4VTwistedFaceted, G4TwistedBox, G4TwistedTrd: optimized
|
||||
calculation of volume and surface area
|
||||
|
||||
## 2022-01-06 Evgueni Tcherniaev (geom-specific-V11-00-02)
|
||||
- G4TwistedTubs: Implemented GetSurfaceArea() based on
|
||||
analytical expressions; added private functions
|
||||
GetLateralArea() and GetPhiCutArea()
|
||||
|
||||
## 2021-12-19 Evgueni Tcherniaev (geom-specific-V11-00-01)
|
||||
- G4Hype: Used analytical expression in GetCubicVolume()
|
||||
and GetSurfaceArea()
|
||||
|
||||
## 2021-12-10 Ben Morgan (geom-specific-V11-00-00)
|
||||
- Change to new Markdown History format
|
||||
|
||||
---
|
||||
|
||||
# History entries prior to 11.0
|
||||
|
||||
03-December-2021 E.Tcherniaev (geom-specific-V10-07-13)
|
||||
- G4TwistedTubs: Accurate calculation of the bounding box in
|
||||
|
||||
@@ -75,6 +75,7 @@ class G4ExtrudedSolid : public G4TessellatedSolid
|
||||
|
||||
struct ZSection
|
||||
{
|
||||
ZSection() : fZ(0.), fOffset(0.,0.), fScale(1.) {}
|
||||
ZSection(G4double z, const G4TwoVector& offset, G4double scale)
|
||||
: fZ(z), fOffset(offset), fScale(scale) {}
|
||||
|
||||
@@ -93,8 +94,10 @@ class G4ExtrudedSolid : public G4TessellatedSolid
|
||||
G4ExtrudedSolid( const G4String& pName,
|
||||
const std::vector<G4TwoVector>& polygon,
|
||||
G4double halfZ,
|
||||
const G4TwoVector& off1, G4double scale1,
|
||||
const G4TwoVector& off2, G4double scale2 );
|
||||
const G4TwoVector& off1 = G4TwoVector(0.,0.),
|
||||
G4double scale1 = 1.,
|
||||
const G4TwoVector& off2 = G4TwoVector(0.,0.),
|
||||
G4double scale2 = 1. );
|
||||
// Special constructor for solid with 2 z-sections
|
||||
|
||||
virtual ~G4ExtrudedSolid();
|
||||
|
||||
@@ -181,18 +181,8 @@ class G4GenericTrap : public G4VSolid
|
||||
G4ThreeVector NormalToPlane(const G4ThreeVector& p,
|
||||
const G4int ipl) const;
|
||||
G4double SafetyToFace(const G4ThreeVector& p, const G4int iseg) const;
|
||||
G4double GetFaceSurfaceArea(const G4ThreeVector& p0,
|
||||
const G4ThreeVector& p1,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3) const;
|
||||
G4double GetTwistedFaceSurfaceArea(const G4ThreeVector& p0,
|
||||
const G4ThreeVector& p1,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3) const;
|
||||
G4double GetFaceCubicVolume(const G4ThreeVector& p0,
|
||||
const G4ThreeVector& p1,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3) const;
|
||||
G4double GetLateralFaceArea(G4int iface) const;
|
||||
|
||||
protected:
|
||||
|
||||
mutable G4bool fRebuildPolyhedron = false;
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
// Class description:
|
||||
//
|
||||
// A G4TwistedBox is a twisted cuboid of given half lengths pDx,pDy,pDz
|
||||
// and twist angle pPhiTwist.
|
||||
// and twist angle pPhiTwist.
|
||||
// The Box is centred on the origin with sides parallel to the x/y/z axes.
|
||||
//
|
||||
// Member Data:
|
||||
//
|
||||
// pDx Half-length along x axis
|
||||
// pDx Half-length along x axis
|
||||
// pDy Half-length along y asis
|
||||
// pDz Half-length along z axis
|
||||
// pPhiTwist Twist angle
|
||||
@@ -52,7 +52,7 @@ class G4TwistedBox : public G4VTwistedFaceted
|
||||
G4TwistedBox(const G4String& pName,
|
||||
G4double pPhiTwist,
|
||||
G4double pDx,
|
||||
G4double pDy,
|
||||
G4double pDy,
|
||||
G4double pDz );
|
||||
|
||||
virtual ~G4TwistedBox();
|
||||
@@ -66,6 +66,9 @@ class G4TwistedBox : public G4VTwistedFaceted
|
||||
|
||||
G4GeometryType GetEntityType() const;
|
||||
|
||||
G4double GetCubicVolume();
|
||||
G4double GetSurfaceArea();
|
||||
|
||||
G4VSolid* Clone() const;
|
||||
|
||||
std::ostream& StreamInfo(std::ostream& os) const;
|
||||
@@ -78,7 +81,7 @@ class G4TwistedBox : public G4VTwistedFaceted
|
||||
// persistifiable objects.
|
||||
|
||||
G4TwistedBox(const G4TwistedBox& rhs);
|
||||
G4TwistedBox& operator=(const G4TwistedBox& rhs);
|
||||
G4TwistedBox& operator=(const G4TwistedBox& rhs);
|
||||
// Copy constructor and assignment operator.
|
||||
};
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// A G4TwistedTrd is a twisted trapezoid with the x and y dimensions
|
||||
// varying along z
|
||||
//
|
||||
// A G4TwistedTrd is a twisted trapezoid with the x and y dimensions
|
||||
// varying along z
|
||||
//
|
||||
//
|
||||
// Member Data:
|
||||
//
|
||||
@@ -54,7 +54,7 @@ class G4TwistedTrd : public G4VTwistedFaceted
|
||||
G4TwistedTrd( const G4String& pName,
|
||||
G4double pDx1,
|
||||
G4double pDx2,
|
||||
G4double pDy1,
|
||||
G4double pDy1,
|
||||
G4double pDy2,
|
||||
G4double pDz,
|
||||
G4double pPhiTwist );
|
||||
@@ -72,6 +72,9 @@ class G4TwistedTrd : public G4VTwistedFaceted
|
||||
|
||||
G4GeometryType GetEntityType() const;
|
||||
|
||||
G4double GetCubicVolume();
|
||||
G4double GetSurfaceArea();
|
||||
|
||||
G4VSolid* Clone() const;
|
||||
|
||||
std::ostream& StreamInfo(std::ostream& os) const;
|
||||
@@ -84,7 +87,7 @@ class G4TwistedTrd : public G4VTwistedFaceted
|
||||
// persistifiable objects.
|
||||
|
||||
G4TwistedTrd(const G4TwistedTrd& rhs);
|
||||
G4TwistedTrd& operator=(const G4TwistedTrd& rhs);
|
||||
G4TwistedTrd& operator=(const G4TwistedTrd& rhs);
|
||||
// Copy constructor and assignment operator.
|
||||
|
||||
} ;
|
||||
|
||||
@@ -162,8 +162,8 @@ class G4TwistedTubs : public G4VSolid
|
||||
// Returns an estimation of the geometrical cubic volume of the
|
||||
// solid. Caches the computed value once computed the first time.
|
||||
G4double GetSurfaceArea();
|
||||
// Returns an estimation of the geometrical surface area of the
|
||||
// solid. Caches the computed value once computed the first time.
|
||||
// Returns the geometrical surface area of the solid.
|
||||
// Caches the computed value once computed the first time.
|
||||
|
||||
G4ThreeVector GetPointOnSurface() const ;
|
||||
|
||||
@@ -184,11 +184,12 @@ class G4TwistedTubs : public G4VSolid
|
||||
|
||||
private:
|
||||
|
||||
inline void SetFields(G4double phitwist, G4double innerrad,
|
||||
G4double outerrad,
|
||||
G4double negativeEndz, G4double positiveEndz);
|
||||
|
||||
inline void SetFields(G4double phitwist, G4double innerrad,
|
||||
G4double outerrad,
|
||||
G4double negativeEndz, G4double positiveEndz);
|
||||
void CreateSurfaces();
|
||||
G4double GetLateralArea(G4double a, G4double r, G4double z) const;
|
||||
G4double GetPhiCutArea(G4double a, G4double r, G4double z) const;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ class G4UExtrudedSolid : public G4UAdapter<vecgeom::UnplacedExtruded>
|
||||
|
||||
struct ZSection
|
||||
{
|
||||
ZSection() : fZ(0.), fOffset(0.,0.), fScale(1.) {}
|
||||
ZSection(G4double z, G4TwoVector offset, G4double scale)
|
||||
: fZ(z), fOffset(offset), fScale(scale) {}
|
||||
|
||||
@@ -70,8 +71,10 @@ class G4UExtrudedSolid : public G4UAdapter<vecgeom::UnplacedExtruded>
|
||||
G4UExtrudedSolid(const G4String& pName,
|
||||
const std::vector<G4TwoVector>& polygon,
|
||||
G4double halfZ,
|
||||
const G4TwoVector& off1, G4double scale1,
|
||||
const G4TwoVector& off2, G4double scale2);
|
||||
const G4TwoVector& off1 = G4TwoVector(0.,0.),
|
||||
G4double scale1 = 1.,
|
||||
const G4TwoVector& off2 = G4TwoVector(0.,0.),
|
||||
G4double scale2 = 1. );
|
||||
// Special constructor for solid with 2 z-sections
|
||||
|
||||
~G4UExtrudedSolid();
|
||||
|
||||
@@ -36,10 +36,11 @@
|
||||
#define G4VTWISTEDFACETED_HH
|
||||
|
||||
#include "G4VSolid.hh"
|
||||
#include "G4TwoVector.hh"
|
||||
#include "G4TwistTrapAlphaSide.hh"
|
||||
#include "G4TwistTrapParallelSide.hh"
|
||||
#include "G4TwistBoxSide.hh"
|
||||
#include "G4TwistTrapFlatSide.hh"
|
||||
#include "G4TwistTrapFlatSide.hh"
|
||||
|
||||
class G4SolidExtentList;
|
||||
class G4ClippablePolygon;
|
||||
@@ -47,7 +48,7 @@ class G4ClippablePolygon;
|
||||
class G4VTwistedFaceted: public G4VSolid
|
||||
{
|
||||
public: // with description
|
||||
|
||||
|
||||
G4VTwistedFaceted(const G4String& pname, // Name of instance
|
||||
G4double PhiTwist, // twist angle
|
||||
G4double pDz, // half z lenght
|
||||
@@ -61,13 +62,13 @@ class G4VTwistedFaceted: public G4VSolid
|
||||
G4double pDx4, // half x length at +pDz,+pDy
|
||||
G4double pAlph // tilt angle at +pDz
|
||||
);
|
||||
|
||||
|
||||
virtual ~G4VTwistedFaceted();
|
||||
|
||||
|
||||
virtual void ComputeDimensions(G4VPVParameterisation*,
|
||||
const G4int,
|
||||
const G4VPhysicalVolume* );
|
||||
|
||||
|
||||
virtual void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const;
|
||||
|
||||
virtual G4bool CalculateExtent(const EAxis pAxis,
|
||||
@@ -80,24 +81,24 @@ class G4VTwistedFaceted: public G4VSolid
|
||||
const G4ThreeVector& v ) const;
|
||||
|
||||
virtual G4double DistanceToIn (const G4ThreeVector& p ) const;
|
||||
|
||||
virtual G4double DistanceToOut(const G4ThreeVector& p,
|
||||
|
||||
virtual G4double DistanceToOut(const G4ThreeVector& p,
|
||||
const G4ThreeVector& v,
|
||||
const G4bool calcnorm = false,
|
||||
G4bool* validnorm = nullptr,
|
||||
G4bool* validnorm = nullptr,
|
||||
G4ThreeVector* n = nullptr ) const;
|
||||
|
||||
virtual G4double DistanceToOut(const G4ThreeVector& p) const;
|
||||
|
||||
|
||||
virtual EInside Inside (const G4ThreeVector& p) const;
|
||||
|
||||
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector& p) const;
|
||||
|
||||
G4ThreeVector GetPointOnSurface() const;
|
||||
G4ThreeVector GetPointInSolid(G4double z) const;
|
||||
|
||||
virtual inline G4double GetCubicVolume();
|
||||
virtual inline G4double GetSurfaceArea();
|
||||
|
||||
virtual G4double GetCubicVolume();
|
||||
virtual G4double GetSurfaceArea();
|
||||
|
||||
virtual void DescribeYourselfTo (G4VGraphicsScene& scene) const;
|
||||
virtual G4Polyhedron* CreatePolyhedron () const;
|
||||
@@ -106,15 +107,15 @@ class G4VTwistedFaceted: public G4VSolid
|
||||
virtual std::ostream &StreamInfo(std::ostream& os) const;
|
||||
|
||||
// accessors
|
||||
|
||||
|
||||
inline G4double GetTwistAngle() const { return fPhiTwist; }
|
||||
|
||||
inline G4double GetDx1 () const { return fDx1 ; }
|
||||
inline G4double GetDx2 () const { return fDx2 ; }
|
||||
inline G4double GetDx3 () const { return fDx3 ; }
|
||||
inline G4double GetDx4 () const { return fDx4 ; }
|
||||
inline G4double GetDy1 () const { return fDy1 ; }
|
||||
inline G4double GetDy2 () const { return fDy2 ; }
|
||||
inline G4double GetDx1 () const { return fDx1 ; }
|
||||
inline G4double GetDx2 () const { return fDx2 ; }
|
||||
inline G4double GetDx3 () const { return fDx3 ; }
|
||||
inline G4double GetDx4 () const { return fDx4 ; }
|
||||
inline G4double GetDy1 () const { return fDy1 ; }
|
||||
inline G4double GetDy2 () const { return fDy2 ; }
|
||||
inline G4double GetDz () const { return fDz ; }
|
||||
inline G4double GetPhi () const { return fPhi ; }
|
||||
inline G4double GetTheta () const { return fTheta ; }
|
||||
@@ -138,7 +139,7 @@ class G4VTwistedFaceted: public G4VSolid
|
||||
// persistifiable objects.
|
||||
|
||||
G4VTwistedFaceted(const G4VTwistedFaceted& rhs);
|
||||
G4VTwistedFaceted& operator=(const G4VTwistedFaceted& rhs);
|
||||
G4VTwistedFaceted& operator=(const G4VTwistedFaceted& rhs);
|
||||
// Copy constructor and assignment operator.
|
||||
|
||||
protected: // with description
|
||||
@@ -147,25 +148,29 @@ class G4VTwistedFaceted: public G4VSolid
|
||||
mutable G4Polyhedron* fpPolyhedron = nullptr; // polyhedron for vis
|
||||
|
||||
private:
|
||||
|
||||
|
||||
double GetLateralFaceArea(const G4TwoVector& p1,
|
||||
const G4TwoVector& p2,
|
||||
const G4TwoVector& p3,
|
||||
const G4TwoVector& p4) const;
|
||||
void CreateSurfaces();
|
||||
|
||||
private:
|
||||
|
||||
G4double fTheta;
|
||||
|
||||
G4double fTheta;
|
||||
G4double fPhi ;
|
||||
|
||||
G4double fDy1;
|
||||
G4double fDx1;
|
||||
G4double fDx2;
|
||||
|
||||
G4double fDy2;
|
||||
G4double fDx3;
|
||||
G4double fDx4;
|
||||
G4double fDy1;
|
||||
G4double fDx1;
|
||||
G4double fDx2;
|
||||
|
||||
G4double fDy2;
|
||||
G4double fDx3;
|
||||
G4double fDx4;
|
||||
|
||||
G4double fDz; // Half-length along the z axis
|
||||
|
||||
G4double fDx ; // maximum side in x
|
||||
G4double fDx ; // maximum side in x
|
||||
G4double fDy ; // maximum side in y
|
||||
|
||||
G4double fAlph ;
|
||||
@@ -173,20 +178,24 @@ class G4VTwistedFaceted: public G4VSolid
|
||||
|
||||
G4double fdeltaX ;
|
||||
G4double fdeltaY ;
|
||||
|
||||
|
||||
G4double fPhiTwist; // twist angle ( dphi in surface equation)
|
||||
|
||||
G4VTwistSurface* fLowerEndcap ; // surface of -ve z
|
||||
G4VTwistSurface* fUpperEndcap ; // surface of +ve z
|
||||
|
||||
|
||||
G4VTwistSurface* fSide0 ; // Twisted Side at phi = 0 deg
|
||||
G4VTwistSurface* fSide90 ; // Twisted Side at phi = 90 deg
|
||||
G4VTwistSurface* fSide180 ; // Twisted Side at phi = 180 deg
|
||||
G4VTwistSurface* fSide270 ; // Twisted Side at phi = 270 deg
|
||||
|
||||
protected:
|
||||
|
||||
G4double fCubicVolume = 0.0; // volume of the solid
|
||||
G4double fSurfaceArea = 0.0; // area of the solid
|
||||
|
||||
private:
|
||||
|
||||
class LastState // last Inside result
|
||||
{
|
||||
public:
|
||||
@@ -206,7 +215,7 @@ class G4VTwistedFaceted: public G4VSolid
|
||||
G4ThreeVector p;
|
||||
EInside inside;
|
||||
};
|
||||
|
||||
|
||||
class LastVector // last SurfaceNormal result
|
||||
{
|
||||
public:
|
||||
@@ -259,7 +268,7 @@ class G4VTwistedFaceted: public G4VSolid
|
||||
G4ThreeVector p;
|
||||
G4double value;
|
||||
};
|
||||
|
||||
|
||||
class LastValueWithDoubleVector // last G4double value
|
||||
{
|
||||
public:
|
||||
@@ -283,7 +292,7 @@ class G4VTwistedFaceted: public G4VSolid
|
||||
G4ThreeVector vec;
|
||||
G4double value;
|
||||
};
|
||||
|
||||
|
||||
LastState fLastInside;
|
||||
LastVector fLastNormal;
|
||||
LastValue fLastDistanceToIn;
|
||||
@@ -294,25 +303,6 @@ class G4VTwistedFaceted: public G4VSolid
|
||||
|
||||
//=====================================================================
|
||||
|
||||
inline
|
||||
G4double G4VTwistedFaceted::GetCubicVolume()
|
||||
{
|
||||
if(fCubicVolume == 0.)
|
||||
{
|
||||
fCubicVolume = ((fDx1 + fDx2 + fDx3 + fDx4)*(fDy1 + fDy2) +
|
||||
(fDx4 + fDx3 - fDx2 - fDx1)*(fDy2 - fDy1)/3)*fDz;
|
||||
}
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
inline
|
||||
G4double G4VTwistedFaceted::GetSurfaceArea()
|
||||
{
|
||||
if(fSurfaceArea != 0.) ;
|
||||
else fSurfaceArea = G4VSolid::GetSurfaceArea();
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
inline
|
||||
G4double G4VTwistedFaceted::GetValueA(G4double phi) const
|
||||
{
|
||||
@@ -323,18 +313,18 @@ inline
|
||||
G4double G4VTwistedFaceted::GetValueD(G4double phi) const
|
||||
{
|
||||
return ( fDx3 + fDx1 + ( fDx3 - fDx1 ) * ( 2 * phi ) / fPhiTwist ) ;
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
inline
|
||||
G4double G4VTwistedFaceted::GetValueB(G4double phi) const
|
||||
{
|
||||
return ( fDy2 + fDy1 + ( fDy2 - fDy1 ) * ( 2 * phi ) / fPhiTwist ) ;
|
||||
}
|
||||
|
||||
inline
|
||||
G4double G4VTwistedFaceted::Xcoef(G4double u, G4double phi, G4double ftg) const
|
||||
G4double G4VTwistedFaceted::Xcoef(G4double u, G4double phi, G4double ftg) const
|
||||
{
|
||||
return GetValueA(phi)/2. + (GetValueD(phi)-GetValueA(phi))/4.
|
||||
return GetValueA(phi)/2. + (GetValueD(phi)-GetValueA(phi))/4.
|
||||
- u*( ( GetValueD(phi)-GetValueA(phi) ) / ( 2 * GetValueB(phi) ) - ftg );
|
||||
}
|
||||
|
||||
|
||||
@@ -705,49 +705,84 @@ G4double G4Ellipsoid::GetCubicVolume()
|
||||
|
||||
G4double G4Ellipsoid::LateralSurfaceArea() const
|
||||
{
|
||||
const G4int Nphi = 100;
|
||||
const G4int Nz = 200;
|
||||
G4double rho[Nz + 1];
|
||||
constexpr G4int NPHI = 1000.;
|
||||
constexpr G4double dPhi = CLHEP::halfpi/NPHI;
|
||||
constexpr G4double eps = 4.*DBL_EPSILON;
|
||||
|
||||
// Set array of rho
|
||||
G4double zbot = fZBottomCut / fDz;
|
||||
G4double ztop = fZTopCut / fDz;
|
||||
G4double dz = (ztop - zbot) / Nz;
|
||||
for (G4int iz = 0; iz < Nz; ++iz)
|
||||
{
|
||||
G4double z = zbot + iz * dz;
|
||||
rho[iz] = std::sqrt((1. + z) * (1. - z));
|
||||
}
|
||||
rho[Nz] = std::sqrt((1. + ztop) * (1. - ztop));
|
||||
|
||||
// Compute area
|
||||
zbot = fZBottomCut;
|
||||
ztop = fZTopCut;
|
||||
dz = (ztop - zbot) / Nz;
|
||||
G4double aa = fDx*fDx;
|
||||
G4double bb = fDy*fDy;
|
||||
G4double cc = fDz*fDz;
|
||||
G4double ab = fDx*fDy;
|
||||
G4double cc_aa = cc/aa;
|
||||
G4double cc_bb = cc/bb;
|
||||
G4double zmax = std::min(fZTopCut, fDz);
|
||||
G4double zmin = std::max(fZBottomCut,-fDz);
|
||||
G4double zmax_c = zmax/fDz;
|
||||
G4double zmin_c = zmin/fDz;
|
||||
G4double area = 0.;
|
||||
G4double dphi = CLHEP::halfpi / Nphi;
|
||||
for (G4int iphi = 0; iphi < Nphi; ++iphi)
|
||||
|
||||
if (aa == bb) // spheroid, use analytical expression
|
||||
{
|
||||
G4double phi1 = iphi * dphi;
|
||||
G4double phi2 = (iphi == Nphi - 1) ? CLHEP::halfpi : phi1 + dphi;
|
||||
G4double cos1 = std::cos(phi1) * fDx;
|
||||
G4double cos2 = std::cos(phi2) * fDx;
|
||||
G4double sin1 = std::sin(phi1) * fDy;
|
||||
G4double sin2 = std::sin(phi2) * fDy;
|
||||
for (G4int iz = 0; iz < Nz; ++iz)
|
||||
G4double k = fDz/fDx;
|
||||
G4double kk = k*k;
|
||||
if (kk < 1. - eps)
|
||||
{
|
||||
G4double z1 = zbot + iz * dz;
|
||||
G4double z2 = (iz == Nz - 1) ? ztop : z1 + dz;
|
||||
G4double rho1 = rho[iz];
|
||||
G4double rho2 = rho[iz + 1];
|
||||
G4ThreeVector p1(rho1 * cos1, rho1 * sin1, z1);
|
||||
G4ThreeVector p2(rho1 * cos2, rho1 * sin2, z1);
|
||||
G4ThreeVector p3(rho2 * cos1, rho2 * sin1, z2);
|
||||
G4ThreeVector p4(rho2 * cos2, rho2 * sin2, z2);
|
||||
area += ((p4 - p1).cross(p3 - p2)).mag();
|
||||
G4double invk = fDx/fDz;
|
||||
G4double root = std::sqrt(1. - kk);
|
||||
G4double tmax = zmax_c*root;
|
||||
G4double tmin = zmin_c*root;
|
||||
area = CLHEP::pi*ab*
|
||||
((zmax_c*std::sqrt(kk + tmax*tmax) - zmin_c*std::sqrt(kk + tmin*tmin)) +
|
||||
(std::asinh(tmax*invk) - std::asinh(tmin*invk))*kk/root);
|
||||
}
|
||||
else if (kk > 1. + eps)
|
||||
{
|
||||
G4double invk = fDx/fDz;
|
||||
G4double root = std::sqrt(kk - 1.);
|
||||
G4double tmax = zmax_c*root;
|
||||
G4double tmin = zmin_c*root;
|
||||
area = CLHEP::pi*ab*
|
||||
((zmax_c*std::sqrt(kk - tmax*tmax) - zmin_c*std::sqrt(kk - tmin*tmin)) +
|
||||
(std::asin(tmax*invk) - std::asin(tmin*invk))*kk/root);
|
||||
}
|
||||
else
|
||||
{
|
||||
area = CLHEP::twopi*fDx*(zmax - zmin);
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
// ellipsoid, integration along phi
|
||||
for (G4int i = 0; i < NPHI; ++i)
|
||||
{
|
||||
G4double sinPhi = std::sin(dPhi*(i + 0.5));
|
||||
G4double kk = cc_aa + (cc_bb - cc_aa)*sinPhi*sinPhi;
|
||||
if (kk < 1. - eps)
|
||||
{
|
||||
G4double root = std::sqrt(1. - kk);
|
||||
G4double tmax = zmax_c*root;
|
||||
G4double tmin = zmin_c*root;
|
||||
G4double invk = 1./std::sqrt(kk);
|
||||
area += 2.*ab*dPhi*
|
||||
((zmax_c*std::sqrt(kk + tmax*tmax) - zmin_c*std::sqrt(kk + tmin*tmin)) +
|
||||
(std::asinh(tmax*invk) - std::asinh(tmin*invk))*kk/root);
|
||||
}
|
||||
else if (kk > 1. + eps)
|
||||
{
|
||||
G4double root = std::sqrt(kk - 1.);
|
||||
G4double tmax = zmax_c*root;
|
||||
G4double tmin = zmin_c*root;
|
||||
G4double invk = 1./std::sqrt(kk);
|
||||
area += 2.*ab*dPhi*
|
||||
((zmax_c*std::sqrt(kk - tmax*tmax) - zmin_c*std::sqrt(kk - tmin*tmin)) +
|
||||
(std::asin(tmax*invk) - std::asin(tmin*invk))*kk/root);
|
||||
}
|
||||
else
|
||||
{
|
||||
area += 4.*ab*dPhi*(zmax_c - zmin_c);
|
||||
}
|
||||
}
|
||||
return 2. * area;
|
||||
return area;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
|
||||
#include "G4VGraphicsScene.hh"
|
||||
#include "G4Polyhedron.hh"
|
||||
#include "G4PolyhedronArbitrary.hh"
|
||||
#include "G4VisExtent.hh"
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
@@ -1318,20 +1317,19 @@ G4ThreeVector G4GenericTrap::GetPointOnSurface() const
|
||||
vertices.push_back(G4ThreeVector(fVertices[i].x(),fVertices[i].y(),fDz));
|
||||
}
|
||||
|
||||
// Surface Area of Planes(only estimation for twisted)
|
||||
// Surface Area of Planes
|
||||
//
|
||||
G4double Surface0=GetFaceSurfaceArea(vertices[0],vertices[1],
|
||||
vertices[2],vertices[3]);//-fDz plane
|
||||
G4double Surface1=GetFaceSurfaceArea(vertices[0],vertices[1],
|
||||
vertices[5],vertices[4]);// Lat plane
|
||||
G4double Surface2=GetFaceSurfaceArea(vertices[3],vertices[0],
|
||||
vertices[4],vertices[7]);// Lat plane
|
||||
G4double Surface3=GetFaceSurfaceArea(vertices[2],vertices[3],
|
||||
vertices[7],vertices[6]);// Lat plane
|
||||
G4double Surface4=GetFaceSurfaceArea(vertices[2],vertices[1],
|
||||
vertices[5],vertices[6]);// Lat plane
|
||||
G4double Surface5=GetFaceSurfaceArea(vertices[4],vertices[5],
|
||||
vertices[6],vertices[7]);// fDz plane
|
||||
G4TwoVector A = fVertices[3] - fVertices[1];
|
||||
G4TwoVector B = fVertices[2] - fVertices[0];
|
||||
G4TwoVector C = fVertices[7] - fVertices[5];
|
||||
G4TwoVector D = fVertices[6] - fVertices[4];
|
||||
G4double Surface0 = 0.5*(A.x()*B.y() - A.y()*B.x()); //-fDz plane
|
||||
G4double Surface1 = GetLateralFaceArea(0);
|
||||
G4double Surface2 = GetLateralFaceArea(1);
|
||||
G4double Surface3 = GetLateralFaceArea(2);
|
||||
G4double Surface4 = GetLateralFaceArea(3);
|
||||
G4double Surface5 = 0.5*(C.x()*D.y() - C.y()*D.x()); // fDz plane
|
||||
|
||||
rand = G4UniformRand();
|
||||
area = Surface0+Surface1+Surface2+Surface3+Surface4+Surface5;
|
||||
chose = rand*area;
|
||||
@@ -1381,130 +1379,109 @@ G4ThreeVector G4GenericTrap::GetPointOnSurface() const
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
G4double G4GenericTrap::GetSurfaceArea()
|
||||
{
|
||||
// Set vertices
|
||||
G4ThreeVector v0(fVertices[0].x(),fVertices[0].y(),-fDz);
|
||||
G4ThreeVector v1(fVertices[1].x(),fVertices[1].y(),-fDz);
|
||||
G4ThreeVector v2(fVertices[2].x(),fVertices[2].y(),-fDz);
|
||||
G4ThreeVector v3(fVertices[3].x(),fVertices[3].y(),-fDz);
|
||||
G4ThreeVector v4(fVertices[4].x(),fVertices[4].y(), fDz);
|
||||
G4ThreeVector v5(fVertices[5].x(),fVertices[5].y(), fDz);
|
||||
G4ThreeVector v6(fVertices[6].x(),fVertices[6].y(), fDz);
|
||||
G4ThreeVector v7(fVertices[7].x(),fVertices[7].y(), fDz);
|
||||
|
||||
// Find Surface Area
|
||||
if (fSurfaceArea == 0.0)
|
||||
{
|
||||
if(fIsTwisted)
|
||||
{
|
||||
fSurfaceArea = GetFaceSurfaceArea(v0,v1,v2,v3) // -fDz plane
|
||||
+ GetTwistedFaceSurfaceArea(v1,v0,v4,v5) // Lat plane
|
||||
+ GetTwistedFaceSurfaceArea(v2,v1,v5,v6) // Lat plane
|
||||
+ GetTwistedFaceSurfaceArea(v3,v2,v6,v7) // Lat plane
|
||||
+ GetTwistedFaceSurfaceArea(v0,v3,v7,v4) // Lat plane
|
||||
+ GetFaceSurfaceArea(v7,v6,v5,v4); // +fDz plane
|
||||
}
|
||||
else
|
||||
{
|
||||
fSurfaceArea = GetFaceSurfaceArea(v0,v1,v2,v3) // -fDz plane
|
||||
+ GetFaceSurfaceArea(v1,v0,v4,v5) // Lat plane
|
||||
+ GetFaceSurfaceArea(v2,v1,v5,v6) // Lat plane
|
||||
+ GetFaceSurfaceArea(v3,v2,v6,v7) // Lat plane
|
||||
+ GetFaceSurfaceArea(v0,v3,v7,v4) // Lat plane
|
||||
+ GetFaceSurfaceArea(v7,v6,v5,v4); // +fDz plane
|
||||
}
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
G4double G4GenericTrap::GetCubicVolume()
|
||||
{
|
||||
if (fCubicVolume == 0.0)
|
||||
{
|
||||
if(fIsTwisted)
|
||||
{
|
||||
fCubicVolume = G4VSolid::GetCubicVolume();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set vertices
|
||||
G4ThreeVector v0(fVertices[0].x(),fVertices[0].y(),-fDz);
|
||||
G4ThreeVector v1(fVertices[1].x(),fVertices[1].y(),-fDz);
|
||||
G4ThreeVector v2(fVertices[2].x(),fVertices[2].y(),-fDz);
|
||||
G4ThreeVector v3(fVertices[3].x(),fVertices[3].y(),-fDz);
|
||||
G4ThreeVector v4(fVertices[4].x(),fVertices[4].y(), fDz);
|
||||
G4ThreeVector v5(fVertices[5].x(),fVertices[5].y(), fDz);
|
||||
G4ThreeVector v6(fVertices[6].x(),fVertices[6].y(), fDz);
|
||||
G4ThreeVector v7(fVertices[7].x(),fVertices[7].y(), fDz);
|
||||
// diagonals
|
||||
G4TwoVector A = fVertices[3] - fVertices[1];
|
||||
G4TwoVector B = fVertices[2] - fVertices[0];
|
||||
G4TwoVector C = fVertices[7] - fVertices[5];
|
||||
G4TwoVector D = fVertices[6] - fVertices[4];
|
||||
|
||||
// Find Cubic Volume
|
||||
fCubicVolume = GetFaceCubicVolume(v0,v1,v2,v3) // -fDz plane
|
||||
+ GetFaceCubicVolume(v1,v0,v4,v5) // Lat plane
|
||||
+ GetFaceCubicVolume(v2,v1,v5,v6) // Lat plane
|
||||
+ GetFaceCubicVolume(v3,v2,v6,v7) // Lat plane
|
||||
+ GetFaceCubicVolume(v0,v3,v7,v4) // Lat plane
|
||||
+ GetFaceCubicVolume(v7,v6,v5,v4); // +fDz plane
|
||||
}
|
||||
// kross products
|
||||
G4double AB = A.x()*B.y() - A.y()*B.x();
|
||||
G4double CD = C.x()*D.y() - C.y()*D.x();
|
||||
G4double AD = A.x()*D.y() - A.y()*D.x();
|
||||
G4double CB = C.x()*B.y() - C.y()*B.x();
|
||||
|
||||
fCubicVolume = ((AB + CD)/3. + (AD + CB)/6.)*fDz;
|
||||
}
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
G4double G4GenericTrap::GetFaceSurfaceArea(const G4ThreeVector& p0,
|
||||
const G4ThreeVector& p1,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3) const
|
||||
G4double G4GenericTrap::GetLateralFaceArea(G4int iface) const
|
||||
{
|
||||
// Returns area of the facet
|
||||
return 0.5*((p2-p0).cross(p3-p1)).mag();
|
||||
}
|
||||
constexpr G4int NSTEP = 250;
|
||||
constexpr G4double dt = 1./NSTEP;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
G4int i1 = iface, i2 = (iface + 1)%4;
|
||||
G4int i3 = i1 + 4, i4 = i2 + 4;
|
||||
|
||||
G4double
|
||||
G4GenericTrap::GetTwistedFaceSurfaceArea(const G4ThreeVector& p0,
|
||||
const G4ThreeVector& p1,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3) const
|
||||
{
|
||||
G4int nstep = 100;
|
||||
G4ThreeVector dels1 = (p1 - p0)/nstep;
|
||||
G4ThreeVector dels2 = (p2 - p3)/nstep;
|
||||
G4double area = 0;
|
||||
for (G4int is = 0; is < nstep; ++is)
|
||||
G4double x21 = fVertices[i2].x() - fVertices[i1].x();
|
||||
G4double y21 = fVertices[i2].y() - fVertices[i1].y();
|
||||
G4double x31 = fVertices[i3].x() - fVertices[i1].x();
|
||||
G4double y31 = fVertices[i3].y() - fVertices[i1].y();
|
||||
G4double x42 = fVertices[i4].x() - fVertices[i2].x();
|
||||
G4double y42 = fVertices[i4].y() - fVertices[i2].y();
|
||||
G4double x43 = fVertices[i4].x() - fVertices[i3].x();
|
||||
G4double y43 = fVertices[i4].y() - fVertices[i3].y();
|
||||
|
||||
G4double A = x21*y43 - y21*x43;
|
||||
G4double lmax = std::max(std::max(std::abs(x21),std::abs(y21)),
|
||||
std::max(std::abs(x43),std::abs(y43)));
|
||||
G4double eps = lmax*kCarTolerance;
|
||||
if (std::abs(A) < eps) // plane face
|
||||
{
|
||||
G4ThreeVector s0 = p0 + dels1*is;
|
||||
G4ThreeVector s1 = s0 + dels1;
|
||||
G4ThreeVector s3 = p3 + dels2*is;
|
||||
G4ThreeVector s2 = s3 + dels2;
|
||||
G4ThreeVector delt1 = (s3 - s0)/nstep;
|
||||
G4ThreeVector delt2 = (s2 - s1)/nstep;
|
||||
for (G4int it = 0; it < nstep; ++it)
|
||||
{
|
||||
G4ThreeVector t0 = s0 + delt1*it;
|
||||
G4ThreeVector t1 = t0 + delt1;
|
||||
G4ThreeVector t3 = s1 + delt2*it;
|
||||
G4ThreeVector t2 = t3 + delt2;
|
||||
area += 0.5*((t2-t0).cross(t3-t1)).mag();
|
||||
}
|
||||
G4ThreeVector p1(fVertices[i1].x(), fVertices[i1].y(),-fDz);
|
||||
G4ThreeVector p2(fVertices[i2].x(), fVertices[i2].y(),-fDz);
|
||||
G4ThreeVector p3(fVertices[i3].x(), fVertices[i3].y(), fDz);
|
||||
G4ThreeVector p4(fVertices[i4].x(), fVertices[i4].y(), fDz);
|
||||
return ((p4 - p1).cross(p3 - p2)).mag()*0.5;
|
||||
}
|
||||
return area;
|
||||
|
||||
// twisted face
|
||||
G4double B0 = x21*y31 - y21*x31;
|
||||
G4double B1 = x42*y31 - y42*x31;
|
||||
G4double HH = 4*fDz*fDz;
|
||||
G4double invAA = 1./(A*A);
|
||||
G4double sqrtAA = 2.*std::abs(A);
|
||||
G4double invSqrtAA = 1./sqrtAA;
|
||||
|
||||
G4double area = 0.;
|
||||
for (G4int i = 0; i < NSTEP; ++i)
|
||||
{
|
||||
G4double t = (i + 0.5)*dt;
|
||||
G4double I = y21 + (y43 - y21)*t;
|
||||
G4double J = x21 + (x43 - x21)*t;
|
||||
G4double IIJJ = HH*(I*I + J*J);
|
||||
G4double B = B1*t + B0;
|
||||
|
||||
G4double aa = A*A;
|
||||
G4double bb = 2.*A*B;
|
||||
G4double cc = IIJJ + B*B;
|
||||
|
||||
G4double R1 = std::sqrt(aa + bb + cc);
|
||||
G4double R0 = std::sqrt(cc);
|
||||
G4double log1 = std::log(std::abs(sqrtAA*R1 + 2.*aa + bb));
|
||||
G4double log0 = std::log(std::abs(sqrtAA*R0 + bb));
|
||||
|
||||
area += 0.5*R1 + 0.25*bb*invAA*(R1 - R0) + IIJJ*invSqrtAA*(log1 - log0);
|
||||
}
|
||||
return area*dt;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
G4double G4GenericTrap::GetFaceCubicVolume(const G4ThreeVector& p0,
|
||||
const G4ThreeVector& p1,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3) const
|
||||
G4double G4GenericTrap::GetSurfaceArea()
|
||||
{
|
||||
// Returns contribution of the facet to the volume of the solid.
|
||||
// Orientation of the facet is important, normal should point to outside.
|
||||
return (((p2-p0).cross(p3-p1)).dot(p0)) / 6.;
|
||||
if (fSurfaceArea == 0.0)
|
||||
{
|
||||
G4TwoVector A = fVertices[3] - fVertices[1];
|
||||
G4TwoVector B = fVertices[2] - fVertices[0];
|
||||
G4TwoVector C = fVertices[7] - fVertices[5];
|
||||
G4TwoVector D = fVertices[6] - fVertices[4];
|
||||
G4double S_bot = 0.5*(A.x()*B.y() - A.y()*B.x());
|
||||
G4double S_top = 0.5*(C.x()*D.y() - C.y()*D.x());
|
||||
fSurfaceArea = S_bot + S_top +
|
||||
GetLateralFaceArea(0) +
|
||||
GetLateralFaceArea(1) +
|
||||
GetLateralFaceArea(2) +
|
||||
GetLateralFaceArea(3);
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -2047,89 +2024,91 @@ G4Polyhedron* G4GenericTrap::CreatePolyhedron() const
|
||||
return fTessellatedSolid->CreatePolyhedron();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Approximation of Twisted Side
|
||||
// Construct extra Points, if Twisted Side
|
||||
//
|
||||
G4PolyhedronArbitrary* polyhedron;
|
||||
G4Polyhedron* polyhedron;
|
||||
size_t nVertices, nFacets;
|
||||
|
||||
G4int subdivisions=0;
|
||||
G4int i;
|
||||
if(fIsTwisted)
|
||||
G4int subdivisions = 0;
|
||||
if (fIsTwisted)
|
||||
{
|
||||
if ( GetVisSubdivisions()!= 0 )
|
||||
if (GetVisSubdivisions() != 0)
|
||||
{
|
||||
subdivisions=GetVisSubdivisions();
|
||||
subdivisions = GetVisSubdivisions();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Estimation of Number of Subdivisions for smooth visualisation
|
||||
//
|
||||
G4double maxTwist=0.;
|
||||
for(i=0; i<4; ++i)
|
||||
G4double maxTwist = 0.;
|
||||
for(G4int i = 0; i < 4; ++i)
|
||||
{
|
||||
if(GetTwistAngle(i)>maxTwist) { maxTwist=GetTwistAngle(i); }
|
||||
if (GetTwistAngle(i) > maxTwist) { maxTwist = GetTwistAngle(i); }
|
||||
}
|
||||
|
||||
// Computes bounding vectors for the shape
|
||||
//
|
||||
G4double Dx,Dy;
|
||||
G4double Dx, Dy;
|
||||
G4ThreeVector minVec = GetMinimumBBox();
|
||||
G4ThreeVector maxVec = GetMaximumBBox();
|
||||
Dx = 0.5*(maxVec.x()- minVec.y());
|
||||
Dy = 0.5*(maxVec.y()- minVec.y());
|
||||
if (Dy > Dx) { Dx=Dy; }
|
||||
|
||||
subdivisions=8*G4int(maxTwist/(Dx*Dx*Dx)*fDz);
|
||||
if (subdivisions<4) { subdivisions=4; }
|
||||
if (subdivisions>30) { subdivisions=30; }
|
||||
Dx = 0.5*(maxVec.x() - minVec.y());
|
||||
Dy = 0.5*(maxVec.y() - minVec.y());
|
||||
if (Dy > Dx) { Dx = Dy; }
|
||||
|
||||
subdivisions = 8*G4int(maxTwist/(Dx*Dx*Dx)*fDz);
|
||||
if (subdivisions < 4) { subdivisions = 4; }
|
||||
if (subdivisions > 30) { subdivisions = 30; }
|
||||
}
|
||||
}
|
||||
G4int sub4=4*subdivisions;
|
||||
nVertices = 8+subdivisions*4;
|
||||
nFacets = 6+subdivisions*4;
|
||||
G4double cf=1./(subdivisions+1);
|
||||
polyhedron = new G4PolyhedronArbitrary (nVertices, nFacets);
|
||||
G4int sub4 = 4*subdivisions;
|
||||
nVertices = 8 + subdivisions*4;
|
||||
nFacets = 6 + subdivisions*4;
|
||||
G4double cf = 1./(subdivisions + 1);
|
||||
polyhedron = new G4Polyhedron(nVertices, nFacets);
|
||||
|
||||
// Add Vertex
|
||||
// Set vertices
|
||||
//
|
||||
for (i=0; i<4; ++i)
|
||||
G4int icur = 0;
|
||||
for (G4int i = 0; i < 4; ++i)
|
||||
{
|
||||
polyhedron->AddVertex(G4ThreeVector(fVertices[i].x(),
|
||||
fVertices[i].y(),-fDz));
|
||||
G4ThreeVector v(fVertices[i].x(),fVertices[i].y(),-fDz);
|
||||
polyhedron->SetVertex(++icur, v);
|
||||
}
|
||||
for( i=0; i<subdivisions; ++i)
|
||||
for (G4int i = 0; i < subdivisions; ++i)
|
||||
{
|
||||
for(G4int j=0;j<4;j++)
|
||||
for (G4int j = 0; j < 4; ++j)
|
||||
{
|
||||
G4TwoVector u=fVertices[j]+cf*(i+1)*( fVertices[j+4]-fVertices[j]);
|
||||
polyhedron->AddVertex(G4ThreeVector(u.x(),u.y(),-fDz+cf*2*fDz*(i+1)));
|
||||
}
|
||||
G4TwoVector u = fVertices[j]+cf*(i+1)*(fVertices[j+4]-fVertices[j]);
|
||||
G4ThreeVector v(u.x(),u.y(),-fDz+cf*2*fDz*(i+1));
|
||||
polyhedron->SetVertex(++icur, v);
|
||||
}
|
||||
}
|
||||
for (i=4; i<8; ++i)
|
||||
for (G4int i = 4; i < 8; ++i)
|
||||
{
|
||||
polyhedron->AddVertex(G4ThreeVector(fVertices[i].x(),
|
||||
fVertices[i].y(),fDz));
|
||||
G4ThreeVector v(fVertices[i].x(),fVertices[i].y(),fDz);
|
||||
polyhedron->SetVertex(++icur, v);
|
||||
}
|
||||
|
||||
// Add Facets
|
||||
// Set facets
|
||||
//
|
||||
polyhedron->AddFacet(1,4,3,2); //Z-plane
|
||||
for (i=0; i<subdivisions+1; ++i)
|
||||
icur = 0;
|
||||
polyhedron->SetFacet(++icur, 1, 4, 3, 2); // Z-plane
|
||||
for (G4int i = 0; i < subdivisions + 1; ++i)
|
||||
{
|
||||
G4int is=i*4;
|
||||
polyhedron->AddFacet(5+is,8+is,4+is,1+is);
|
||||
polyhedron->AddFacet(8+is,7+is,3+is,4+is);
|
||||
polyhedron->AddFacet(7+is,6+is,2+is,3+is);
|
||||
polyhedron->AddFacet(6+is,5+is,1+is,2+is);
|
||||
G4int is = i*4;
|
||||
polyhedron->SetFacet(++icur, 5+is, 8+is, 4+is, 1+is);
|
||||
polyhedron->SetFacet(++icur, 8+is, 7+is, 3+is, 4+is);
|
||||
polyhedron->SetFacet(++icur, 7+is, 6+is, 2+is, 3+is);
|
||||
polyhedron->SetFacet(++icur, 6+is, 5+is, 1+is, 2+is);
|
||||
}
|
||||
polyhedron->AddFacet(5+sub4,6+sub4,7+sub4,8+sub4); //Z-plane
|
||||
polyhedron->SetFacet(++icur, 5+sub4, 6+sub4, 7+sub4, 8+sub4); // Z-plane
|
||||
|
||||
polyhedron->SetReferences();
|
||||
polyhedron->InvertFacets();
|
||||
|
||||
return (G4Polyhedron*) polyhedron;
|
||||
return polyhedron;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -1080,8 +1080,11 @@ G4VSolid* G4Hype::Clone() const
|
||||
//
|
||||
G4double G4Hype::GetCubicVolume()
|
||||
{
|
||||
if(fCubicVolume != 0.) {;}
|
||||
else { fCubicVolume = G4VSolid::GetCubicVolume(); }
|
||||
if (fCubicVolume == 0.)
|
||||
{
|
||||
fCubicVolume = CLHEP::twopi*halfLenZ*
|
||||
(2.*(outerRadius2 - innerRadius2) + endOuterRadius2 - endInnerRadius2)/3.;
|
||||
}
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
@@ -1089,8 +1092,33 @@ G4double G4Hype::GetCubicVolume()
|
||||
//
|
||||
G4double G4Hype::GetSurfaceArea()
|
||||
{
|
||||
if(fSurfaceArea != 0.) {;}
|
||||
else { fSurfaceArea = G4VSolid::GetSurfaceArea(); }
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
G4double h = halfLenZ;
|
||||
G4double innS = 2.*h*innerRadius;
|
||||
if (std::abs(endInnerRadius - innerRadius) > kCarTolerance)
|
||||
{
|
||||
G4double A = innerRadius;
|
||||
G4double AA = innerRadius2;
|
||||
G4double RR = endInnerRadius2;
|
||||
G4double CC = AA*h*h/(RR - AA);
|
||||
G4double K = std::sqrt(AA + CC)/CC;
|
||||
G4double Kh = K*h;
|
||||
innS = A*(h*std::sqrt(1. + Kh*Kh) + std::asinh(Kh)/K);
|
||||
}
|
||||
G4double outS = 2.*h*outerRadius;
|
||||
if (std::abs(endOuterRadius - outerRadius) > kCarTolerance)
|
||||
{
|
||||
G4double A = outerRadius;
|
||||
G4double AA = outerRadius2;
|
||||
G4double RR = endOuterRadius2;
|
||||
G4double CC = AA*h*h/(RR - AA);
|
||||
G4double K = std::sqrt(AA + CC)/CC;
|
||||
G4double Kh = K*h;
|
||||
outS = A*(h*std::sqrt(1. + Kh*Kh) + std::asinh(Kh)/K);
|
||||
}
|
||||
fSurfaceArea = CLHEP::twopi*(endOuterRadius2 - endInnerRadius2 + innS + outS);
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
|
||||
#include "G4PolyhedronArbitrary.hh"
|
||||
#include "G4VGraphicsScene.hh"
|
||||
#include "G4VisExtent.hh"
|
||||
|
||||
@@ -1925,34 +1924,31 @@ void G4TessellatedSolid::DescribeYourselfTo (G4VGraphicsScene& scene) const
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4Polyhedron *G4TessellatedSolid::CreatePolyhedron () const
|
||||
G4Polyhedron* G4TessellatedSolid::CreatePolyhedron () const
|
||||
{
|
||||
G4int nVertices = fVertexList.size();
|
||||
G4int nFacets = fFacets.size();
|
||||
G4PolyhedronArbitrary* polyhedron =
|
||||
new G4PolyhedronArbitrary (nVertices, nFacets);
|
||||
for (auto v= fVertexList.cbegin(); v!=fVertexList.cend(); ++v)
|
||||
G4int nFacets = fFacets.size();
|
||||
G4Polyhedron* polyhedron = new G4Polyhedron(nVertices, nFacets);
|
||||
for (G4int i = 0; i < nVertices; ++i)
|
||||
{
|
||||
polyhedron->AddVertex(*v);
|
||||
polyhedron->SetVertex(i+1, fVertexList[i]);
|
||||
}
|
||||
|
||||
G4int size = fFacets.size();
|
||||
for (G4int i = 0; i < size; ++i)
|
||||
for (G4int i = 0; i < nFacets; ++i)
|
||||
{
|
||||
G4VFacet* facet = fFacets[i];
|
||||
G4int v[4] = {0};
|
||||
G4int n = facet->GetNumberOfVertices();
|
||||
if (n > 4) n = 4;
|
||||
for (G4int j=0; j<n; ++j)
|
||||
for (G4int j = 0; j < n; ++j)
|
||||
{
|
||||
G4int k = facet->GetVertexIndex(j);
|
||||
v[j] = k+1;
|
||||
v[j] = facet->GetVertexIndex(j) + 1;
|
||||
}
|
||||
polyhedron->AddFacet(v[0],v[1],v[2],v[3]);
|
||||
polyhedron->SetFacet(i+1, v[0], v[1], v[2], v[3]);
|
||||
}
|
||||
polyhedron->SetReferences();
|
||||
|
||||
return (G4Polyhedron*) polyhedron;
|
||||
return polyhedron;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
|
||||
G4TwistedBox::G4TwistedBox( const G4String& pName,
|
||||
G4double pPhiTwist,
|
||||
G4double pDx,
|
||||
G4double pDy,
|
||||
G4double pDx,
|
||||
G4double pDy,
|
||||
G4double pDz )
|
||||
: G4VTwistedFaceted( pName, pPhiTwist,pDz,0.,0.,
|
||||
pDy, pDx, pDx, pDy, pDx, pDx,0. )
|
||||
@@ -73,7 +73,7 @@ G4TwistedBox::G4TwistedBox(const G4TwistedBox& rhs)
|
||||
//=====================================================================
|
||||
//* Assignment operator -----------------------------------------------
|
||||
|
||||
G4TwistedBox& G4TwistedBox::operator = (const G4TwistedBox& rhs)
|
||||
G4TwistedBox& G4TwistedBox::operator = (const G4TwistedBox& rhs)
|
||||
{
|
||||
// Check assignment to self
|
||||
//
|
||||
@@ -103,7 +103,7 @@ std::ostream& G4TwistedBox::StreamInfo(std::ostream& os) const
|
||||
<< " pDx = " << GetXHalfLength()/cm << " cm" << G4endl
|
||||
<< " pDy = " << GetYHalfLength()/cm << " cm" << G4endl
|
||||
<< " pDz = " << GetZHalfLength()/cm << " cm" << G4endl
|
||||
<< " pPhiTwist = " << GetPhiTwist()/degree << " deg" << G4endl
|
||||
<< " pPhiTwist = " << GetPhiTwist()/degree << " deg" << G4endl
|
||||
<< "-----------------------------------------------------------\n";
|
||||
|
||||
return os;
|
||||
@@ -124,3 +124,44 @@ G4VSolid* G4TwistedBox::Clone() const
|
||||
{
|
||||
return new G4TwistedBox(*this);
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetCubicVolume ----------------------------------------------------
|
||||
|
||||
double G4TwistedBox::GetCubicVolume()
|
||||
{
|
||||
if (fCubicVolume == 0.)
|
||||
{
|
||||
fCubicVolume = 8.*GetXHalfLength()*GetYHalfLength()*GetZHalfLength();
|
||||
}
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetSurfaceArea ----------------------------------------------------
|
||||
|
||||
double G4TwistedBox::GetSurfaceArea()
|
||||
{
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
G4double ang = GetPhiTwist();
|
||||
G4double dx = GetXHalfLength();
|
||||
G4double dy = GetYHalfLength();
|
||||
G4double dz = GetZHalfLength();
|
||||
if (ang == 0.)
|
||||
{
|
||||
fSurfaceArea = 8.*(dx*dy + dx*dz + dy*dz);
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double h = 2.*dz;
|
||||
G4double hh = h*h;
|
||||
G4double dxang = dx*ang;
|
||||
G4double dyang = dy*ang;
|
||||
fSurfaceArea = 8.*dx*dy +
|
||||
2.*(dx*std::sqrt(hh + dxang*dxang) + hh*std::asinh(dxang/h)/ang) +
|
||||
2.*(dy*std::sqrt(hh + dyang*dyang) + hh*std::asinh(dyang/h)/ang);
|
||||
}
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
//* Constructor -------------------------------------------------------
|
||||
|
||||
G4TwistedTrd::G4TwistedTrd( const G4String& pName,
|
||||
G4double pDx1,
|
||||
G4double pDx1,
|
||||
G4double pDx2,
|
||||
G4double pDy1,
|
||||
G4double pDy1,
|
||||
G4double pDy2,
|
||||
G4double pDz,
|
||||
G4double pPhiTwist )
|
||||
@@ -75,7 +75,7 @@ G4TwistedTrd::G4TwistedTrd(const G4TwistedTrd& rhs)
|
||||
//=====================================================================
|
||||
//* Assignment operator -----------------------------------------------
|
||||
|
||||
G4TwistedTrd& G4TwistedTrd::operator = (const G4TwistedTrd& rhs)
|
||||
G4TwistedTrd& G4TwistedTrd::operator = (const G4TwistedTrd& rhs)
|
||||
{
|
||||
// Check assignment to self
|
||||
//
|
||||
@@ -107,7 +107,7 @@ std::ostream& G4TwistedTrd::StreamInfo(std::ostream& os) const
|
||||
<< " pDy1 = " << GetY1HalfLength()/cm << " cm" << G4endl
|
||||
<< " pDy2 = " << GetY2HalfLength()/cm << " cm" << G4endl
|
||||
<< " pDz = " << GetZHalfLength()/cm << " cm" << G4endl
|
||||
<< " pPhiTwist = " << GetPhiTwist()/degree << " deg" << G4endl
|
||||
<< " pPhiTwist = " << GetPhiTwist()/degree << " deg" << G4endl
|
||||
<< "-----------------------------------------------------------\n";
|
||||
|
||||
return os;
|
||||
@@ -128,3 +128,101 @@ G4VSolid* G4TwistedTrd::Clone() const
|
||||
{
|
||||
return new G4TwistedTrd(*this);
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetCubicVolume ----------------------------------------------------
|
||||
|
||||
double G4TwistedTrd::GetCubicVolume()
|
||||
{
|
||||
if (fCubicVolume == 0.)
|
||||
{
|
||||
G4double x1 = GetX1HalfLength();
|
||||
G4double x2 = GetX2HalfLength();
|
||||
G4double y1 = GetY1HalfLength();
|
||||
G4double y2 = GetY2HalfLength();
|
||||
G4double h = 2.*GetZHalfLength();
|
||||
fCubicVolume = h*((x1 + x2)*(y1 + y2) + (x2 - x1)*(y2 - y1)/3.);
|
||||
}
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetSurfaceArea ----------------------------------------------------
|
||||
|
||||
double G4TwistedTrd::GetSurfaceArea()
|
||||
{
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
G4double ang = GetPhiTwist();
|
||||
G4double x1 = GetX1HalfLength();
|
||||
G4double x2 = GetX2HalfLength();
|
||||
G4double y1 = GetY1HalfLength();
|
||||
G4double y2 = GetY2HalfLength();
|
||||
G4double h = 2.*GetZHalfLength();
|
||||
G4double hh = h*h;
|
||||
G4double delX = x2 - x1;
|
||||
G4double delY = y2 - y1;
|
||||
if (ang == 0.)
|
||||
{
|
||||
G4double hx = std::sqrt(delY*delY + hh);
|
||||
G4double hy = std::sqrt(delX*delX + hh);
|
||||
return fSurfaceArea =
|
||||
2.*(x1 + x2)*hx + 2.*(y1 + y2)*hy + 4.*(x1*y1 + x2*y2);
|
||||
}
|
||||
|
||||
// compute area of x-faces
|
||||
G4double U1, U2, V1, V2;
|
||||
G4double areaX = 0.;
|
||||
U1 = delY + x1*ang;
|
||||
U2 = delY + x2*ang;
|
||||
V1 = delY - x1*ang;
|
||||
V2 = delY - x2*ang;
|
||||
if (std::abs(delX) < kCarTolerance) // case x1 == x2
|
||||
{
|
||||
areaX = (U1*std::sqrt(hh + U1*U1) + hh*std::asinh(U1/h) -
|
||||
V1*std::sqrt(hh + V1*V1) - hh*std::asinh(V1/h))/ang;
|
||||
}
|
||||
else
|
||||
{
|
||||
// U contribution
|
||||
areaX += ((hh + U2*U2)*std::sqrt(hh + U2*U2) -
|
||||
(hh + U1*U1)*std::sqrt(hh + U1*U1))/3.
|
||||
+ hh*(U2*std::asinh(U2/h) - U1*std::asinh(U1/h))
|
||||
- hh*(std::sqrt(hh + U2*U2) - std::sqrt(hh + U1*U1));
|
||||
// V contribution
|
||||
areaX += ((hh + V2*V2)*std::sqrt(hh + V2*V2) -
|
||||
(hh + V1*V1)*std::sqrt(hh + V1*V1))/3.
|
||||
+ hh*(V2*std::asinh(V2/h) - V1*std::asinh(V1/h))
|
||||
- hh*(std::sqrt(hh + V2*V2) - std::sqrt(hh + V1*V1));
|
||||
areaX /= delX*ang*ang;
|
||||
}
|
||||
|
||||
// compute area of y-faces
|
||||
G4double areaY = 0.;
|
||||
U1 = delX + y1*ang;
|
||||
U2 = delX + y2*ang;
|
||||
V1 = delX - y1*ang;
|
||||
V2 = delX - y2*ang;
|
||||
if (std::abs(delY) < kCarTolerance) // case y1 == y2
|
||||
{
|
||||
areaY = (U1*std::sqrt(hh + U1*U1) + hh*std::asinh(U1/h) -
|
||||
V1*std::sqrt(hh + V1*V1) - hh*std::asinh(V1/h))/ang;
|
||||
}
|
||||
else
|
||||
{
|
||||
// U contribution
|
||||
areaY += ((hh + U2*U2)*std::sqrt(hh + U2*U2) -
|
||||
(hh + U1*U1)*std::sqrt(hh + U1*U1))/3.
|
||||
+ hh*(U2*std::asinh(U2/h) - U1*std::asinh(U1/h))
|
||||
- hh*(std::sqrt(hh + U2*U2) - std::sqrt(hh + U1*U1));
|
||||
// V contribution
|
||||
areaY += ((hh + V2*V2)*std::sqrt(hh + V2*V2) -
|
||||
(hh + V1*V1)*std::sqrt(hh + V1*V1))/3.
|
||||
+ hh*(V2*std::asinh(V2/h) - V1*std::asinh(V1/h))
|
||||
- hh*(std::sqrt(hh + V2*V2) - std::sqrt(hh + V1*V1));
|
||||
areaY /= delY*ang*ang;
|
||||
}
|
||||
fSurfaceArea = areaX + areaY + 4.*(x1*y1 + x2*y2);
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
@@ -1050,12 +1050,94 @@ G4double G4TwistedTubs::GetCubicVolume()
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetLateralArea ----------------------------------------------------
|
||||
|
||||
G4double
|
||||
G4TwistedTubs::GetLateralArea(G4double a, G4double r, G4double z) const
|
||||
{
|
||||
if (z == 0) return 0.;
|
||||
G4double h = std::abs(z);
|
||||
G4double area = h*a;
|
||||
if (std::abs(a - r) > kCarTolerance)
|
||||
{
|
||||
G4double aa = a*a;
|
||||
G4double hh = h*h;
|
||||
G4double rr = r*r;
|
||||
G4double cc = aa*hh/(rr - aa);
|
||||
G4double k = std::sqrt(aa + cc)/cc;
|
||||
G4double kh = k*h;
|
||||
area = 0.5*a*(h*std::sqrt(1. + kh*kh) + std::asinh(kh)/k);
|
||||
}
|
||||
return GetDPhi()*area;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetPhiCutArea -----------------------------------------------------
|
||||
|
||||
G4double
|
||||
G4TwistedTubs::GetPhiCutArea(G4double a, G4double r, G4double z) const
|
||||
{
|
||||
if (GetDPhi() >= CLHEP::twopi || r <= 0 || z == 0) return 0.;
|
||||
G4double h = std::abs(z);
|
||||
G4double area = h*a;
|
||||
if (GetPhiTwist() > kCarTolerance)
|
||||
{
|
||||
G4double sinw = std::sin(0.5*GetPhiTwist())*h/GetZHalfLength();
|
||||
G4double p = sinw*r/h;
|
||||
G4double q = sinw*r/a;
|
||||
G4double pp = p*p;
|
||||
G4double qq = q*q;
|
||||
G4double pq = p*q;
|
||||
G4double sqroot = std::sqrt(pp + qq + 1);
|
||||
area = (pq*sqroot +
|
||||
0.5*p*(pp + 3.)*std::atanh(q/sqroot) +
|
||||
0.5*q*(qq + 3.)*std::atanh(p/sqroot) +
|
||||
std::atan(sqroot/(pq)) - CLHEP::halfpi)*h*a/(3.*pq);
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetSurfaceArea ----------------------------------------------------
|
||||
|
||||
G4double G4TwistedTubs::GetSurfaceArea()
|
||||
{
|
||||
if (fSurfaceArea == 0.) fSurfaceArea = G4VSolid::GetSurfaceArea();
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
G4double dphi = GetDPhi();
|
||||
G4double Ainn = GetInnerRadius();
|
||||
G4double Aout = GetOuterRadius();
|
||||
G4double Rinn0 = GetEndInnerRadius(0);
|
||||
G4double Rout0 = GetEndOuterRadius(0);
|
||||
G4double Rinn1 = GetEndInnerRadius(1);
|
||||
G4double Rout1 = GetEndOuterRadius(1);
|
||||
G4double z0 = GetEndZ(0);
|
||||
G4double z1 = GetEndZ(1);
|
||||
|
||||
G4double base0 = 0.5*dphi*(Rout0*Rout0 - Rinn0*Rinn0); // lower base
|
||||
G4double inner0 = GetLateralArea(Ainn, Rinn0, z0); // lower inner surface
|
||||
G4double outer0 = GetLateralArea(Aout, Rout0, z0); // lower outer surface
|
||||
G4double cut0 = // lower phi cut
|
||||
GetPhiCutArea(Aout, Rout0, z0) - GetPhiCutArea(Ainn, Rinn0, z0);
|
||||
|
||||
G4double base1 = base0;
|
||||
G4double inner1 = inner0;
|
||||
G4double outer1 = outer0;
|
||||
G4double cut1 = cut0;
|
||||
if (std::abs(z0) != std::abs(z1))
|
||||
{
|
||||
base1 = 0.5*dphi*(Rout1*Rout1 - Rinn1*Rinn1); // upper base
|
||||
inner1 = GetLateralArea(Ainn, Rinn1, z1); // upper inner surface
|
||||
outer1 = GetLateralArea(Aout, Rout1, z1); // upper outer surface
|
||||
cut1 = // upper phi cut
|
||||
GetPhiCutArea(Aout, Rout1, z1) - GetPhiCutArea(Ainn, Rinn1, z1);
|
||||
}
|
||||
fSurfaceArea = base0 + base1 +
|
||||
((z0*z1 < 0) ?
|
||||
(inner0 + inner1 + outer0 + outer1 + 2.*(cut0 + cut1)) :
|
||||
std::abs(inner0 - inner1 + outer0 - outer1 + 2.*(cut0 - cut1)));
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,8 +37,6 @@
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
|
||||
#include "G4PolyhedronArbitrary.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructors
|
||||
@@ -382,14 +380,13 @@ G4Polyhedron* G4UExtrudedSolid::CreatePolyhedron () const
|
||||
unsigned int nFacets = Base_t::GetStruct().fTslHelper.fFacets.size();
|
||||
unsigned int nVertices = Base_t::GetStruct().fTslHelper.fVertices.size();
|
||||
|
||||
G4PolyhedronArbitrary* polyhedron =
|
||||
new G4PolyhedronArbitrary (nVertices, nFacets);
|
||||
G4Polyhedron* polyhedron = new G4Polyhedron(nVertices, nFacets);
|
||||
|
||||
// Copy vertices
|
||||
for (unsigned int i = 0; i < nVertices; ++i)
|
||||
{
|
||||
U3Vector v = Base_t::GetStruct().fTslHelper.fVertices[i];
|
||||
polyhedron->AddVertex(G4ThreeVector(v.x(), v.y(), v.z()));
|
||||
polyhedron->SetVertex(i+1, G4ThreeVector(v.x(), v.y(), v.z()));
|
||||
}
|
||||
|
||||
// Copy facets
|
||||
@@ -399,11 +396,11 @@ G4Polyhedron* G4UExtrudedSolid::CreatePolyhedron () const
|
||||
G4int i1 = Base_t::GetStruct().fTslHelper.fFacets[i]->fIndices[0] + 1;
|
||||
G4int i2 = Base_t::GetStruct().fTslHelper.fFacets[i]->fIndices[1] + 1;
|
||||
G4int i3 = Base_t::GetStruct().fTslHelper.fFacets[i]->fIndices[2] + 1;
|
||||
polyhedron->AddFacet(i1, i2, i3);
|
||||
polyhedron->SetFacet(i+1, i1, i2, i3);
|
||||
}
|
||||
polyhedron->SetReferences();
|
||||
|
||||
return (G4Polyhedron*) polyhedron;
|
||||
return polyhedron;
|
||||
}
|
||||
|
||||
#endif // G4GEOM_USE_USOLIDS
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
|
||||
#include "G4Polyhedron.hh"
|
||||
#include "G4PolyhedronArbitrary.hh"
|
||||
|
||||
using namespace CLHEP;
|
||||
|
||||
@@ -256,86 +255,88 @@ G4Polyhedron* G4UGenericTrap::CreatePolyhedron() const
|
||||
// Approximation of Twisted Side
|
||||
// Construct extra Points, if Twisted Side
|
||||
//
|
||||
G4PolyhedronArbitrary* polyhedron;
|
||||
G4Polyhedron* polyhedron;
|
||||
size_t nVertices, nFacets;
|
||||
G4double fDz = GetZHalfLength();
|
||||
|
||||
G4int subdivisions=0;
|
||||
G4int i;
|
||||
if(IsTwisted())
|
||||
G4int subdivisions = 0;
|
||||
if (IsTwisted())
|
||||
{
|
||||
if ( GetVisSubdivisions() != 0 )
|
||||
if (GetVisSubdivisions() != 0)
|
||||
{
|
||||
subdivisions=GetVisSubdivisions();
|
||||
subdivisions = GetVisSubdivisions();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Estimation of Number of Subdivisions for smooth visualisation
|
||||
//
|
||||
G4double maxTwist=0.;
|
||||
for(i=0; i<4; ++i)
|
||||
G4double maxTwist = 0.;
|
||||
for(G4int i = 0; i < 4; ++i)
|
||||
{
|
||||
if(GetTwistAngle(i)>maxTwist) { maxTwist=GetTwistAngle(i); }
|
||||
if (GetTwistAngle(i) > maxTwist) { maxTwist = GetTwistAngle(i); }
|
||||
}
|
||||
|
||||
// Computes bounding vectors for the shape
|
||||
//
|
||||
G4double Dx,Dy;
|
||||
G4double Dx, Dy;
|
||||
G4ThreeVector minVec, maxVec;
|
||||
BoundingLimits(minVec,maxVec);
|
||||
Dx = 0.5*(maxVec.x()- minVec.y());
|
||||
Dy = 0.5*(maxVec.y()- minVec.y());
|
||||
if (Dy > Dx) { Dx=Dy; }
|
||||
|
||||
subdivisions=8*G4int(maxTwist/(Dx*Dx*Dx)*fDz);
|
||||
if (subdivisions<4) { subdivisions=4; }
|
||||
if (subdivisions>30) { subdivisions=30; }
|
||||
BoundingLimits(minVec, maxVec);
|
||||
Dx = 0.5*(maxVec.x() - minVec.y());
|
||||
Dy = 0.5*(maxVec.y() - minVec.y());
|
||||
if (Dy > Dx) { Dx = Dy; }
|
||||
|
||||
subdivisions = 8*G4int(maxTwist/(Dx*Dx*Dx)*fDz);
|
||||
if (subdivisions < 4) { subdivisions = 4; }
|
||||
if (subdivisions > 30) { subdivisions = 30; }
|
||||
}
|
||||
}
|
||||
G4int sub4=4*subdivisions;
|
||||
nVertices = 8+subdivisions*4;
|
||||
nFacets = 6+subdivisions*4;
|
||||
G4double cf=1./(subdivisions+1);
|
||||
polyhedron = new G4PolyhedronArbitrary (nVertices, nFacets);
|
||||
G4int sub4 = 4*subdivisions;
|
||||
nVertices = 8 + subdivisions*4;
|
||||
nFacets = 6 + subdivisions*4;
|
||||
G4double cf = 1./(subdivisions + 1);
|
||||
polyhedron = new G4Polyhedron(nVertices, nFacets);
|
||||
|
||||
// Add Vertex
|
||||
// Set vertices
|
||||
//
|
||||
for (i=0; i<4; ++i)
|
||||
G4int icur = 0;
|
||||
for (G4int i = 0; i < 4; ++i)
|
||||
{
|
||||
polyhedron->AddVertex(G4ThreeVector(GetVertex(i).x(),
|
||||
GetVertex(i).y(),-fDz));
|
||||
G4ThreeVector v(GetVertex(i).x(),GetVertex(i).y(),-fDz);
|
||||
polyhedron->SetVertex(++icur, v);
|
||||
}
|
||||
for(i=0; i<subdivisions; ++i)
|
||||
for (G4int i = 0; i < subdivisions; ++i)
|
||||
{
|
||||
for(G4int j=0; j<4 ; ++j)
|
||||
for (G4int j = 0; j < 4; ++j)
|
||||
{
|
||||
G4TwoVector u=GetVertex(j)+cf*(i+1)*( GetVertex(j+4)-GetVertex(j));
|
||||
polyhedron->AddVertex(G4ThreeVector(u.x(),u.y(),-fDz+cf*2*fDz*(i+1)));
|
||||
}
|
||||
G4TwoVector u = GetVertex(j)+cf*(i+1)*( GetVertex(j+4)-GetVertex(j));
|
||||
G4ThreeVector v(u.x(),u.y(),-fDz+cf*2*fDz*(i+1));
|
||||
polyhedron->SetVertex(++icur, v);
|
||||
}
|
||||
}
|
||||
for (i=4; i<8; ++i)
|
||||
for (G4int i = 4; i < 8; ++i)
|
||||
{
|
||||
polyhedron->AddVertex(G4ThreeVector(GetVertex(i).x(),
|
||||
GetVertex(i).y(),fDz));
|
||||
G4ThreeVector v(GetVertex(i).x(),GetVertex(i).y(),fDz);
|
||||
polyhedron->SetVertex(++icur, v);
|
||||
}
|
||||
|
||||
// Add Facets
|
||||
// Set facets
|
||||
//
|
||||
polyhedron->AddFacet(1,4,3,2); //Z-plane
|
||||
for (i=0; i<subdivisions+1; ++i)
|
||||
icur = 0;
|
||||
polyhedron->SetFacet(++icur, 1, 4, 3, 2); // Z-plane
|
||||
for (G4int i = 0; i < subdivisions + 1; ++i)
|
||||
{
|
||||
G4int is=i*4;
|
||||
polyhedron->AddFacet(5+is,8+is,4+is,1+is);
|
||||
polyhedron->AddFacet(8+is,7+is,3+is,4+is);
|
||||
polyhedron->AddFacet(7+is,6+is,2+is,3+is);
|
||||
polyhedron->AddFacet(6+is,5+is,1+is,2+is);
|
||||
G4int is = i*4;
|
||||
polyhedron->SetFacet(++icur, 5+is, 8+is, 4+is, 1+is);
|
||||
polyhedron->SetFacet(++icur, 8+is, 7+is, 3+is, 4+is);
|
||||
polyhedron->SetFacet(++icur, 7+is, 6+is, 2+is, 3+is);
|
||||
polyhedron->SetFacet(++icur, 6+is, 5+is, 1+is, 2+is);
|
||||
}
|
||||
polyhedron->AddFacet(5+sub4,6+sub4,7+sub4,8+sub4); //Z-plane
|
||||
polyhedron->SetFacet(++icur, 5+sub4, 6+sub4, 7+sub4, 8+sub4); // Z-plane
|
||||
|
||||
polyhedron->SetReferences();
|
||||
polyhedron->InvertFacets();
|
||||
|
||||
return (G4Polyhedron*) polyhedron;
|
||||
return polyhedron;
|
||||
}
|
||||
|
||||
#endif // G4GEOM_USE_USOLIDS
|
||||
|
||||
@@ -40,8 +40,6 @@
|
||||
#include "G4AffineTransform.hh"
|
||||
#include "G4BoundingEnvelope.hh"
|
||||
|
||||
#include "G4PolyhedronArbitrary.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructors
|
||||
@@ -382,27 +380,26 @@ G4UTessellatedSolid::CalculateExtent(const EAxis pAxis,
|
||||
G4Polyhedron* G4UTessellatedSolid::CreatePolyhedron () const
|
||||
{
|
||||
G4int nVertices = fVertexList.size();
|
||||
G4int nFacets = fFacets.size();
|
||||
G4PolyhedronArbitrary *polyhedron = new G4PolyhedronArbitrary (nVertices,
|
||||
nFacets);
|
||||
for (G4int j = 0; j < nVertices; ++j)
|
||||
G4int nFacets = fFacets.size();
|
||||
G4Polyhedron* polyhedron = new G4Polyhedron(nVertices, nFacets);
|
||||
for (G4int i = 0; i < nVertices; ++i)
|
||||
{
|
||||
polyhedron->AddVertex(fVertexList[j]);
|
||||
polyhedron->SetVertex(i+1, fVertexList[i]);
|
||||
}
|
||||
|
||||
for (G4int i = 0; i < nFacets; ++i)
|
||||
{
|
||||
G4int v[3]; // Only facets with 3 vertices are defined in VecGeom
|
||||
G4VFacet* facet = GetFacet(i);
|
||||
for (G4int j=0; j<3; ++j) // Retrieve indexing directly from VecGeom
|
||||
for (G4int j = 0; j < 3; ++j) // Retrieve indexing directly from VecGeom
|
||||
{
|
||||
v[j] = facet->GetVertexIndex(j) + 1;
|
||||
}
|
||||
polyhedron->AddFacet(v[0],v[1],v[2]);
|
||||
polyhedron->SetFacet(i+1, v[0], v[1], v[2]);
|
||||
}
|
||||
polyhedron->SetReferences();
|
||||
|
||||
return (G4Polyhedron*) polyhedron;
|
||||
return polyhedron;
|
||||
}
|
||||
|
||||
#endif // G4GEOM_USE_USOLIDS
|
||||
|
||||
@@ -985,6 +985,118 @@ void G4VTwistedFaceted::CreateSurfaces()
|
||||
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetCubicVolume ----------------------------------------------------
|
||||
|
||||
G4double G4VTwistedFaceted::GetCubicVolume()
|
||||
{
|
||||
if(fCubicVolume == 0.)
|
||||
{
|
||||
fCubicVolume = ((fDx1 + fDx2 + fDx3 + fDx4)*(fDy1 + fDy2) +
|
||||
(fDx4 + fDx3 - fDx2 - fDx1)*(fDy2 - fDy1)/3)*fDz;
|
||||
}
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetLateralFaceArea ------------------------------------------------
|
||||
|
||||
G4double
|
||||
G4VTwistedFaceted::GetLateralFaceArea(const G4TwoVector& p1,
|
||||
const G4TwoVector& p2,
|
||||
const G4TwoVector& p3,
|
||||
const G4TwoVector& p4) const
|
||||
{
|
||||
constexpr G4int NSTEP = 100;
|
||||
constexpr G4double dt = 1./NSTEP;
|
||||
|
||||
G4double h = 2.*fDz;
|
||||
G4double hh = h*h;
|
||||
G4double hTanTheta = h*std::tan(fTheta);
|
||||
G4double x1 = p1.x();
|
||||
G4double y1 = p1.y();
|
||||
G4double x21 = p2.x() - p1.x();
|
||||
G4double y21 = p2.y() - p1.y();
|
||||
G4double x31 = p3.x() - p1.x();
|
||||
G4double y31 = p3.y() - p1.y();
|
||||
G4double x42 = p4.x() - p2.x();
|
||||
G4double y42 = p4.y() - p2.y();
|
||||
G4double x43 = p4.x() - p3.x();
|
||||
G4double y43 = p4.y() - p3.y();
|
||||
|
||||
// check if face is plane (just in case)
|
||||
G4double lmax = std::max(std::max(std::abs(x21),std::abs(y21)),
|
||||
std::max(std::abs(x43),std::abs(y43)));
|
||||
G4double eps = lmax*kCarTolerance;
|
||||
if (std::abs(fPhiTwist) < kCarTolerance &&
|
||||
std::abs(x21*y43 - y21*x43) < eps)
|
||||
{
|
||||
G4double x0 = hTanTheta*std::cos(fPhi);
|
||||
G4double y0 = hTanTheta*std::sin(fPhi);
|
||||
G4ThreeVector A(p4.x() - p1.x() + x0, p4.y() - p1.y() + y0, h);
|
||||
G4ThreeVector B(p3.x() - p2.x() + x0, p3.y() - p2.y() + y0, h);
|
||||
return (A.cross(B)).mag()*0.5;
|
||||
}
|
||||
|
||||
// twisted face
|
||||
G4double area = 0.;
|
||||
for (G4int i = 0; i < NSTEP; ++i)
|
||||
{
|
||||
G4double t = (i + 0.5)*dt;
|
||||
G4double I = x21 + (x42 - x31)*t;
|
||||
G4double J = y21 + (y42 - y31)*t;
|
||||
G4double II = I*I;
|
||||
G4double JJ = J*J;
|
||||
G4double IIJJ = hh*(I*I + J*J);
|
||||
|
||||
G4double ang = fPhi + fPhiTwist*(0.5 - t);
|
||||
G4double A = fPhiTwist*(II + JJ) + x21*y43 - x43*y21;
|
||||
G4double B = fPhiTwist*(I*(x1 + x31*t) + J*(y1 + y31*t)) +
|
||||
hTanTheta*(I*std::sin(ang) - J*std::cos(ang)) +
|
||||
(I*y31 - J*x31);
|
||||
|
||||
G4double invAA = 1./(A*A);
|
||||
G4double sqrtAA = 2.*std::abs(A);
|
||||
G4double invSqrtAA = 1./sqrtAA;
|
||||
|
||||
G4double aa = A*A;
|
||||
G4double bb = 2.*A*B;
|
||||
G4double cc = IIJJ + B*B;
|
||||
|
||||
G4double R1 = std::sqrt(aa + bb + cc);
|
||||
G4double R0 = std::sqrt(cc);
|
||||
G4double log1 = std::log(std::abs(sqrtAA*R1 + 2.*aa + bb));
|
||||
G4double log0 = std::log(std::abs(sqrtAA*R0 + bb));
|
||||
|
||||
area += 0.5*R1 + 0.25*bb*invAA*(R1 - R0) + IIJJ*invSqrtAA*(log1 - log0);
|
||||
}
|
||||
return area*dt;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetSurfaceArea ----------------------------------------------------
|
||||
|
||||
G4double G4VTwistedFaceted::GetSurfaceArea()
|
||||
{
|
||||
if (fSurfaceArea == 0.)
|
||||
{
|
||||
G4TwoVector vv[8];
|
||||
vv[0] = G4TwoVector(-fDx1 - fDy1*fTAlph,-fDy1);
|
||||
vv[1] = G4TwoVector( fDx1 - fDy1*fTAlph,-fDy1);
|
||||
vv[2] = G4TwoVector(-fDx2 + fDy1*fTAlph, fDy1);
|
||||
vv[3] = G4TwoVector( fDx2 + fDy1*fTAlph, fDy1);
|
||||
vv[4] = G4TwoVector(-fDx3 - fDy2*fTAlph,-fDy2);
|
||||
vv[5] = G4TwoVector( fDx3 - fDy2*fTAlph,-fDy2);
|
||||
vv[6] = G4TwoVector(-fDx4 + fDy2*fTAlph, fDy2);
|
||||
vv[7] = G4TwoVector( fDx4 + fDy2*fTAlph, fDy2);
|
||||
fSurfaceArea = 2.*(fDy1*(fDx1 + fDx2) + fDy2*(fDx3 + fDx4)) +
|
||||
GetLateralFaceArea(vv[0], vv[1], vv[4], vv[5]) +
|
||||
GetLateralFaceArea(vv[1], vv[3], vv[5], vv[7]) +
|
||||
GetLateralFaceArea(vv[3], vv[2], vv[7], vv[6]) +
|
||||
GetLateralFaceArea(vv[2], vv[0], vv[6], vv[4]);
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
//* GetEntityType -----------------------------------------------------
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
-------------------------------------------------------------------
|
||||
# Category geomvol History
|
||||
|
||||
=========================================================
|
||||
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
|
||||
=========================================================
|
||||
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
|
||||
which **must** added in reverse chronological order (newest at the top). It must **not**
|
||||
be used as a substitute for writing good git commit messages!
|
||||
|
||||
Category History file
|
||||
---------------------
|
||||
This file should be used by G4 developers and category coordinators
|
||||
to briefly summarize all major modifications introduced in the code
|
||||
and keep track of all category-tags.
|
||||
It DOES NOT substitute the log-message one should put at every
|
||||
commit in the repository !
|
||||
|
||||
----------------------------------------------------------
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
## 2021-12-10 Ben Morgan (geomvol-V11-00-00)
|
||||
- Change to new Markdown History format
|
||||
|
||||
---
|
||||
|
||||
# History entries prior to 11.0
|
||||
|
||||
October 14th, 2021 G.Cosmo - geomvol-V10-07-05
|
||||
- Use same strategy for cloning solids for replicated volumes types in
|
||||
|
||||
Reference in New Issue
Block a user