Import Geant4 11.1.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2022-07-01 10:44:02 +02:00
parent b3bf75a2a1
commit c07cea1fe0
2172 changed files with 183300 additions and 123938 deletions
+20 -14
View File
@@ -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
View File
@@ -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
-----------------------
+10 -14
View File
@@ -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
+10 -14
View File
@@ -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
+10 -14
View File
@@ -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
-----------------------
+20 -15
View File
@@ -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;
+1 -1
View File
@@ -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
+27 -22
View File
@@ -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 );
}
}
+112 -132
View File
@@ -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()
+20 -23
View File
@@ -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
+10 -14
View File
@@ -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().
+11 -14
View File
@@ -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
+53 -14
View File
@@ -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;
}
// --------------------------------------------------------------------
+32 -4
View File
@@ -1080,8 +1080,11 @@ G4VSolid* G4Hype::Clone() const
//
G4double G4Hype::GetCubicVolume()
{
if(fCubicVolume != 0.) {;}
else { fCubicVolume = G4VSolid::GetCubicVolume(); }
if (fCubicVolume == 0.)
{
fCubicVolume = CLHEP::twopi*halfLenZ*
(2.*(outerRadius2 - innerRadius2) + endOuterRadius2 - endInnerRadius2)/3.;
}
return fCubicVolume;
}
@@ -1089,8 +1092,33 @@ G4double G4Hype::GetCubicVolume()
//
G4double G4Hype::GetSurfaceArea()
{
if(fSurfaceArea != 0.) {;}
else { fSurfaceArea = G4VSolid::GetSurfaceArea(); }
if (fSurfaceArea == 0.)
{
G4double h = halfLenZ;
G4double innS = 2.*h*innerRadius;
if (std::abs(endInnerRadius - innerRadius) > kCarTolerance)
{
G4double A = innerRadius;
G4double AA = innerRadius2;
G4double RR = endInnerRadius2;
G4double CC = AA*h*h/(RR - AA);
G4double K = std::sqrt(AA + CC)/CC;
G4double Kh = K*h;
innS = A*(h*std::sqrt(1. + Kh*Kh) + std::asinh(Kh)/K);
}
G4double outS = 2.*h*outerRadius;
if (std::abs(endOuterRadius - outerRadius) > kCarTolerance)
{
G4double A = outerRadius;
G4double AA = outerRadius2;
G4double RR = endOuterRadius2;
G4double CC = AA*h*h/(RR - AA);
G4double K = std::sqrt(AA + CC)/CC;
G4double Kh = K*h;
outS = A*(h*std::sqrt(1. + Kh*Kh) + std::asinh(Kh)/K);
}
fSurfaceArea = CLHEP::twopi*(endOuterRadius2 - endInnerRadius2 + innS + outS);
}
return fSurfaceArea;
}
@@ -67,7 +67,6 @@
#include "G4AffineTransform.hh"
#include "G4BoundingEnvelope.hh"
#include "G4PolyhedronArbitrary.hh"
#include "G4VGraphicsScene.hh"
#include "G4VisExtent.hh"
@@ -1925,34 +1924,31 @@ void G4TessellatedSolid::DescribeYourselfTo (G4VGraphicsScene& scene) const
///////////////////////////////////////////////////////////////////////////////
//
G4Polyhedron *G4TessellatedSolid::CreatePolyhedron () const
G4Polyhedron* G4TessellatedSolid::CreatePolyhedron () const
{
G4int nVertices = fVertexList.size();
G4int nFacets = fFacets.size();
G4PolyhedronArbitrary* polyhedron =
new G4PolyhedronArbitrary (nVertices, nFacets);
for (auto v= fVertexList.cbegin(); v!=fVertexList.cend(); ++v)
G4int nFacets = fFacets.size();
G4Polyhedron* polyhedron = new G4Polyhedron(nVertices, nFacets);
for (G4int i = 0; i < nVertices; ++i)
{
polyhedron->AddVertex(*v);
polyhedron->SetVertex(i+1, fVertexList[i]);
}
G4int size = fFacets.size();
for (G4int i = 0; i < size; ++i)
for (G4int i = 0; i < nFacets; ++i)
{
G4VFacet* facet = fFacets[i];
G4int v[4] = {0};
G4int n = facet->GetNumberOfVertices();
if (n > 4) n = 4;
for (G4int j=0; j<n; ++j)
for (G4int j = 0; j < n; ++j)
{
G4int k = facet->GetVertexIndex(j);
v[j] = k+1;
v[j] = facet->GetVertexIndex(j) + 1;
}
polyhedron->AddFacet(v[0],v[1],v[2],v[3]);
polyhedron->SetFacet(i+1, v[0], v[1], v[2], v[3]);
}
polyhedron->SetReferences();
return (G4Polyhedron*) polyhedron;
return polyhedron;
}
///////////////////////////////////////////////////////////////////////////////
@@ -37,8 +37,8 @@
G4TwistedBox::G4TwistedBox( const G4String& pName,
G4double pPhiTwist,
G4double pDx,
G4double pDy,
G4double pDx,
G4double pDy,
G4double pDz )
: G4VTwistedFaceted( pName, pPhiTwist,pDz,0.,0.,
pDy, pDx, pDx, pDy, pDx, pDx,0. )
@@ -73,7 +73,7 @@ G4TwistedBox::G4TwistedBox(const G4TwistedBox& rhs)
//=====================================================================
//* Assignment operator -----------------------------------------------
G4TwistedBox& G4TwistedBox::operator = (const G4TwistedBox& rhs)
G4TwistedBox& G4TwistedBox::operator = (const G4TwistedBox& rhs)
{
// Check assignment to self
//
@@ -103,7 +103,7 @@ std::ostream& G4TwistedBox::StreamInfo(std::ostream& os) const
<< " pDx = " << GetXHalfLength()/cm << " cm" << G4endl
<< " pDy = " << GetYHalfLength()/cm << " cm" << G4endl
<< " pDz = " << GetZHalfLength()/cm << " cm" << G4endl
<< " pPhiTwist = " << GetPhiTwist()/degree << " deg" << G4endl
<< " pPhiTwist = " << GetPhiTwist()/degree << " deg" << G4endl
<< "-----------------------------------------------------------\n";
return os;
@@ -124,3 +124,44 @@ G4VSolid* G4TwistedBox::Clone() const
{
return new G4TwistedBox(*this);
}
//=====================================================================
//* GetCubicVolume ----------------------------------------------------
double G4TwistedBox::GetCubicVolume()
{
if (fCubicVolume == 0.)
{
fCubicVolume = 8.*GetXHalfLength()*GetYHalfLength()*GetZHalfLength();
}
return fCubicVolume;
}
//=====================================================================
//* GetSurfaceArea ----------------------------------------------------
double G4TwistedBox::GetSurfaceArea()
{
if (fSurfaceArea == 0.)
{
G4double ang = GetPhiTwist();
G4double dx = GetXHalfLength();
G4double dy = GetYHalfLength();
G4double dz = GetZHalfLength();
if (ang == 0.)
{
fSurfaceArea = 8.*(dx*dy + dx*dz + dy*dz);
}
else
{
G4double h = 2.*dz;
G4double hh = h*h;
G4double dxang = dx*ang;
G4double dyang = dy*ang;
fSurfaceArea = 8.*dx*dy +
2.*(dx*std::sqrt(hh + dxang*dxang) + hh*std::asinh(dxang/h)/ang) +
2.*(dy*std::sqrt(hh + dyang*dyang) + hh*std::asinh(dyang/h)/ang);
}
}
return fSurfaceArea;
}
@@ -36,9 +36,9 @@
//* Constructor -------------------------------------------------------
G4TwistedTrd::G4TwistedTrd( const G4String& pName,
G4double pDx1,
G4double pDx1,
G4double pDx2,
G4double pDy1,
G4double pDy1,
G4double pDy2,
G4double pDz,
G4double pPhiTwist )
@@ -75,7 +75,7 @@ G4TwistedTrd::G4TwistedTrd(const G4TwistedTrd& rhs)
//=====================================================================
//* Assignment operator -----------------------------------------------
G4TwistedTrd& G4TwistedTrd::operator = (const G4TwistedTrd& rhs)
G4TwistedTrd& G4TwistedTrd::operator = (const G4TwistedTrd& rhs)
{
// Check assignment to self
//
@@ -107,7 +107,7 @@ std::ostream& G4TwistedTrd::StreamInfo(std::ostream& os) const
<< " pDy1 = " << GetY1HalfLength()/cm << " cm" << G4endl
<< " pDy2 = " << GetY2HalfLength()/cm << " cm" << G4endl
<< " pDz = " << GetZHalfLength()/cm << " cm" << G4endl
<< " pPhiTwist = " << GetPhiTwist()/degree << " deg" << G4endl
<< " pPhiTwist = " << GetPhiTwist()/degree << " deg" << G4endl
<< "-----------------------------------------------------------\n";
return os;
@@ -128,3 +128,101 @@ G4VSolid* G4TwistedTrd::Clone() const
{
return new G4TwistedTrd(*this);
}
//=====================================================================
//* GetCubicVolume ----------------------------------------------------
double G4TwistedTrd::GetCubicVolume()
{
if (fCubicVolume == 0.)
{
G4double x1 = GetX1HalfLength();
G4double x2 = GetX2HalfLength();
G4double y1 = GetY1HalfLength();
G4double y2 = GetY2HalfLength();
G4double h = 2.*GetZHalfLength();
fCubicVolume = h*((x1 + x2)*(y1 + y2) + (x2 - x1)*(y2 - y1)/3.);
}
return fCubicVolume;
}
//=====================================================================
//* GetSurfaceArea ----------------------------------------------------
double G4TwistedTrd::GetSurfaceArea()
{
if (fSurfaceArea == 0.)
{
G4double ang = GetPhiTwist();
G4double x1 = GetX1HalfLength();
G4double x2 = GetX2HalfLength();
G4double y1 = GetY1HalfLength();
G4double y2 = GetY2HalfLength();
G4double h = 2.*GetZHalfLength();
G4double hh = h*h;
G4double delX = x2 - x1;
G4double delY = y2 - y1;
if (ang == 0.)
{
G4double hx = std::sqrt(delY*delY + hh);
G4double hy = std::sqrt(delX*delX + hh);
return fSurfaceArea =
2.*(x1 + x2)*hx + 2.*(y1 + y2)*hy + 4.*(x1*y1 + x2*y2);
}
// compute area of x-faces
G4double U1, U2, V1, V2;
G4double areaX = 0.;
U1 = delY + x1*ang;
U2 = delY + x2*ang;
V1 = delY - x1*ang;
V2 = delY - x2*ang;
if (std::abs(delX) < kCarTolerance) // case x1 == x2
{
areaX = (U1*std::sqrt(hh + U1*U1) + hh*std::asinh(U1/h) -
V1*std::sqrt(hh + V1*V1) - hh*std::asinh(V1/h))/ang;
}
else
{
// U contribution
areaX += ((hh + U2*U2)*std::sqrt(hh + U2*U2) -
(hh + U1*U1)*std::sqrt(hh + U1*U1))/3.
+ hh*(U2*std::asinh(U2/h) - U1*std::asinh(U1/h))
- hh*(std::sqrt(hh + U2*U2) - std::sqrt(hh + U1*U1));
// V contribution
areaX += ((hh + V2*V2)*std::sqrt(hh + V2*V2) -
(hh + V1*V1)*std::sqrt(hh + V1*V1))/3.
+ hh*(V2*std::asinh(V2/h) - V1*std::asinh(V1/h))
- hh*(std::sqrt(hh + V2*V2) - std::sqrt(hh + V1*V1));
areaX /= delX*ang*ang;
}
// compute area of y-faces
G4double areaY = 0.;
U1 = delX + y1*ang;
U2 = delX + y2*ang;
V1 = delX - y1*ang;
V2 = delX - y2*ang;
if (std::abs(delY) < kCarTolerance) // case y1 == y2
{
areaY = (U1*std::sqrt(hh + U1*U1) + hh*std::asinh(U1/h) -
V1*std::sqrt(hh + V1*V1) - hh*std::asinh(V1/h))/ang;
}
else
{
// U contribution
areaY += ((hh + U2*U2)*std::sqrt(hh + U2*U2) -
(hh + U1*U1)*std::sqrt(hh + U1*U1))/3.
+ hh*(U2*std::asinh(U2/h) - U1*std::asinh(U1/h))
- hh*(std::sqrt(hh + U2*U2) - std::sqrt(hh + U1*U1));
// V contribution
areaY += ((hh + V2*V2)*std::sqrt(hh + V2*V2) -
(hh + V1*V1)*std::sqrt(hh + V1*V1))/3.
+ hh*(V2*std::asinh(V2/h) - V1*std::asinh(V1/h))
- hh*(std::sqrt(hh + V2*V2) - std::sqrt(hh + V1*V1));
areaY /= delY*ang*ang;
}
fSurfaceArea = areaX + areaY + 4.*(x1*y1 + x2*y2);
}
return fSurfaceArea;
}
@@ -1050,12 +1050,94 @@ G4double G4TwistedTubs::GetCubicVolume()
return fCubicVolume;
}
//=====================================================================
//* GetLateralArea ----------------------------------------------------
G4double
G4TwistedTubs::GetLateralArea(G4double a, G4double r, G4double z) const
{
if (z == 0) return 0.;
G4double h = std::abs(z);
G4double area = h*a;
if (std::abs(a - r) > kCarTolerance)
{
G4double aa = a*a;
G4double hh = h*h;
G4double rr = r*r;
G4double cc = aa*hh/(rr - aa);
G4double k = std::sqrt(aa + cc)/cc;
G4double kh = k*h;
area = 0.5*a*(h*std::sqrt(1. + kh*kh) + std::asinh(kh)/k);
}
return GetDPhi()*area;
}
//=====================================================================
//* GetPhiCutArea -----------------------------------------------------
G4double
G4TwistedTubs::GetPhiCutArea(G4double a, G4double r, G4double z) const
{
if (GetDPhi() >= CLHEP::twopi || r <= 0 || z == 0) return 0.;
G4double h = std::abs(z);
G4double area = h*a;
if (GetPhiTwist() > kCarTolerance)
{
G4double sinw = std::sin(0.5*GetPhiTwist())*h/GetZHalfLength();
G4double p = sinw*r/h;
G4double q = sinw*r/a;
G4double pp = p*p;
G4double qq = q*q;
G4double pq = p*q;
G4double sqroot = std::sqrt(pp + qq + 1);
area = (pq*sqroot +
0.5*p*(pp + 3.)*std::atanh(q/sqroot) +
0.5*q*(qq + 3.)*std::atanh(p/sqroot) +
std::atan(sqroot/(pq)) - CLHEP::halfpi)*h*a/(3.*pq);
}
return area;
}
//=====================================================================
//* GetSurfaceArea ----------------------------------------------------
G4double G4TwistedTubs::GetSurfaceArea()
{
if (fSurfaceArea == 0.) fSurfaceArea = G4VSolid::GetSurfaceArea();
if (fSurfaceArea == 0.)
{
G4double dphi = GetDPhi();
G4double Ainn = GetInnerRadius();
G4double Aout = GetOuterRadius();
G4double Rinn0 = GetEndInnerRadius(0);
G4double Rout0 = GetEndOuterRadius(0);
G4double Rinn1 = GetEndInnerRadius(1);
G4double Rout1 = GetEndOuterRadius(1);
G4double z0 = GetEndZ(0);
G4double z1 = GetEndZ(1);
G4double base0 = 0.5*dphi*(Rout0*Rout0 - Rinn0*Rinn0); // lower base
G4double inner0 = GetLateralArea(Ainn, Rinn0, z0); // lower inner surface
G4double outer0 = GetLateralArea(Aout, Rout0, z0); // lower outer surface
G4double cut0 = // lower phi cut
GetPhiCutArea(Aout, Rout0, z0) - GetPhiCutArea(Ainn, Rinn0, z0);
G4double base1 = base0;
G4double inner1 = inner0;
G4double outer1 = outer0;
G4double cut1 = cut0;
if (std::abs(z0) != std::abs(z1))
{
base1 = 0.5*dphi*(Rout1*Rout1 - Rinn1*Rinn1); // upper base
inner1 = GetLateralArea(Ainn, Rinn1, z1); // upper inner surface
outer1 = GetLateralArea(Aout, Rout1, z1); // upper outer surface
cut1 = // upper phi cut
GetPhiCutArea(Aout, Rout1, z1) - GetPhiCutArea(Ainn, Rinn1, z1);
}
fSurfaceArea = base0 + base1 +
((z0*z1 < 0) ?
(inner0 + inner1 + outer0 + outer1 + 2.*(cut0 + cut1)) :
std::abs(inner0 - inner1 + outer0 - outer1 + 2.*(cut0 - cut1)));
}
return fSurfaceArea;
}
@@ -37,8 +37,6 @@
#include "G4AffineTransform.hh"
#include "G4BoundingEnvelope.hh"
#include "G4PolyhedronArbitrary.hh"
////////////////////////////////////////////////////////////////////////
//
// Constructors
@@ -382,14 +380,13 @@ G4Polyhedron* G4UExtrudedSolid::CreatePolyhedron () const
unsigned int nFacets = Base_t::GetStruct().fTslHelper.fFacets.size();
unsigned int nVertices = Base_t::GetStruct().fTslHelper.fVertices.size();
G4PolyhedronArbitrary* polyhedron =
new G4PolyhedronArbitrary (nVertices, nFacets);
G4Polyhedron* polyhedron = new G4Polyhedron(nVertices, nFacets);
// Copy vertices
for (unsigned int i = 0; i < nVertices; ++i)
{
U3Vector v = Base_t::GetStruct().fTslHelper.fVertices[i];
polyhedron->AddVertex(G4ThreeVector(v.x(), v.y(), v.z()));
polyhedron->SetVertex(i+1, G4ThreeVector(v.x(), v.y(), v.z()));
}
// Copy facets
@@ -399,11 +396,11 @@ G4Polyhedron* G4UExtrudedSolid::CreatePolyhedron () const
G4int i1 = Base_t::GetStruct().fTslHelper.fFacets[i]->fIndices[0] + 1;
G4int i2 = Base_t::GetStruct().fTslHelper.fFacets[i]->fIndices[1] + 1;
G4int i3 = Base_t::GetStruct().fTslHelper.fFacets[i]->fIndices[2] + 1;
polyhedron->AddFacet(i1, i2, i3);
polyhedron->SetFacet(i+1, i1, i2, i3);
}
polyhedron->SetReferences();
return (G4Polyhedron*) polyhedron;
return polyhedron;
}
#endif // G4GEOM_USE_USOLIDS
@@ -38,7 +38,6 @@
#include "G4BoundingEnvelope.hh"
#include "G4Polyhedron.hh"
#include "G4PolyhedronArbitrary.hh"
using namespace CLHEP;
@@ -256,86 +255,88 @@ G4Polyhedron* G4UGenericTrap::CreatePolyhedron() const
// Approximation of Twisted Side
// Construct extra Points, if Twisted Side
//
G4PolyhedronArbitrary* polyhedron;
G4Polyhedron* polyhedron;
size_t nVertices, nFacets;
G4double fDz = GetZHalfLength();
G4int subdivisions=0;
G4int i;
if(IsTwisted())
G4int subdivisions = 0;
if (IsTwisted())
{
if ( GetVisSubdivisions() != 0 )
if (GetVisSubdivisions() != 0)
{
subdivisions=GetVisSubdivisions();
subdivisions = GetVisSubdivisions();
}
else
{
// Estimation of Number of Subdivisions for smooth visualisation
//
G4double maxTwist=0.;
for(i=0; i<4; ++i)
G4double maxTwist = 0.;
for(G4int i = 0; i < 4; ++i)
{
if(GetTwistAngle(i)>maxTwist) { maxTwist=GetTwistAngle(i); }
if (GetTwistAngle(i) > maxTwist) { maxTwist = GetTwistAngle(i); }
}
// Computes bounding vectors for the shape
//
G4double Dx,Dy;
G4double Dx, Dy;
G4ThreeVector minVec, maxVec;
BoundingLimits(minVec,maxVec);
Dx = 0.5*(maxVec.x()- minVec.y());
Dy = 0.5*(maxVec.y()- minVec.y());
if (Dy > Dx) { Dx=Dy; }
subdivisions=8*G4int(maxTwist/(Dx*Dx*Dx)*fDz);
if (subdivisions<4) { subdivisions=4; }
if (subdivisions>30) { subdivisions=30; }
BoundingLimits(minVec, maxVec);
Dx = 0.5*(maxVec.x() - minVec.y());
Dy = 0.5*(maxVec.y() - minVec.y());
if (Dy > Dx) { Dx = Dy; }
subdivisions = 8*G4int(maxTwist/(Dx*Dx*Dx)*fDz);
if (subdivisions < 4) { subdivisions = 4; }
if (subdivisions > 30) { subdivisions = 30; }
}
}
G4int sub4=4*subdivisions;
nVertices = 8+subdivisions*4;
nFacets = 6+subdivisions*4;
G4double cf=1./(subdivisions+1);
polyhedron = new G4PolyhedronArbitrary (nVertices, nFacets);
G4int sub4 = 4*subdivisions;
nVertices = 8 + subdivisions*4;
nFacets = 6 + subdivisions*4;
G4double cf = 1./(subdivisions + 1);
polyhedron = new G4Polyhedron(nVertices, nFacets);
// Add Vertex
// Set vertices
//
for (i=0; i<4; ++i)
G4int icur = 0;
for (G4int i = 0; i < 4; ++i)
{
polyhedron->AddVertex(G4ThreeVector(GetVertex(i).x(),
GetVertex(i).y(),-fDz));
G4ThreeVector v(GetVertex(i).x(),GetVertex(i).y(),-fDz);
polyhedron->SetVertex(++icur, v);
}
for(i=0; i<subdivisions; ++i)
for (G4int i = 0; i < subdivisions; ++i)
{
for(G4int j=0; j<4 ; ++j)
for (G4int j = 0; j < 4; ++j)
{
G4TwoVector u=GetVertex(j)+cf*(i+1)*( GetVertex(j+4)-GetVertex(j));
polyhedron->AddVertex(G4ThreeVector(u.x(),u.y(),-fDz+cf*2*fDz*(i+1)));
}
G4TwoVector u = GetVertex(j)+cf*(i+1)*( GetVertex(j+4)-GetVertex(j));
G4ThreeVector v(u.x(),u.y(),-fDz+cf*2*fDz*(i+1));
polyhedron->SetVertex(++icur, v);
}
}
for (i=4; i<8; ++i)
for (G4int i = 4; i < 8; ++i)
{
polyhedron->AddVertex(G4ThreeVector(GetVertex(i).x(),
GetVertex(i).y(),fDz));
G4ThreeVector v(GetVertex(i).x(),GetVertex(i).y(),fDz);
polyhedron->SetVertex(++icur, v);
}
// Add Facets
// Set facets
//
polyhedron->AddFacet(1,4,3,2); //Z-plane
for (i=0; i<subdivisions+1; ++i)
icur = 0;
polyhedron->SetFacet(++icur, 1, 4, 3, 2); // Z-plane
for (G4int i = 0; i < subdivisions + 1; ++i)
{
G4int is=i*4;
polyhedron->AddFacet(5+is,8+is,4+is,1+is);
polyhedron->AddFacet(8+is,7+is,3+is,4+is);
polyhedron->AddFacet(7+is,6+is,2+is,3+is);
polyhedron->AddFacet(6+is,5+is,1+is,2+is);
G4int is = i*4;
polyhedron->SetFacet(++icur, 5+is, 8+is, 4+is, 1+is);
polyhedron->SetFacet(++icur, 8+is, 7+is, 3+is, 4+is);
polyhedron->SetFacet(++icur, 7+is, 6+is, 2+is, 3+is);
polyhedron->SetFacet(++icur, 6+is, 5+is, 1+is, 2+is);
}
polyhedron->AddFacet(5+sub4,6+sub4,7+sub4,8+sub4); //Z-plane
polyhedron->SetFacet(++icur, 5+sub4, 6+sub4, 7+sub4, 8+sub4); // Z-plane
polyhedron->SetReferences();
polyhedron->InvertFacets();
return (G4Polyhedron*) polyhedron;
return polyhedron;
}
#endif // G4GEOM_USE_USOLIDS
@@ -40,8 +40,6 @@
#include "G4AffineTransform.hh"
#include "G4BoundingEnvelope.hh"
#include "G4PolyhedronArbitrary.hh"
////////////////////////////////////////////////////////////////////////
//
// Constructors
@@ -382,27 +380,26 @@ G4UTessellatedSolid::CalculateExtent(const EAxis pAxis,
G4Polyhedron* G4UTessellatedSolid::CreatePolyhedron () const
{
G4int nVertices = fVertexList.size();
G4int nFacets = fFacets.size();
G4PolyhedronArbitrary *polyhedron = new G4PolyhedronArbitrary (nVertices,
nFacets);
for (G4int j = 0; j < nVertices; ++j)
G4int nFacets = fFacets.size();
G4Polyhedron* polyhedron = new G4Polyhedron(nVertices, nFacets);
for (G4int i = 0; i < nVertices; ++i)
{
polyhedron->AddVertex(fVertexList[j]);
polyhedron->SetVertex(i+1, fVertexList[i]);
}
for (G4int i = 0; i < nFacets; ++i)
{
G4int v[3]; // Only facets with 3 vertices are defined in VecGeom
G4VFacet* facet = GetFacet(i);
for (G4int j=0; j<3; ++j) // Retrieve indexing directly from VecGeom
for (G4int j = 0; j < 3; ++j) // Retrieve indexing directly from VecGeom
{
v[j] = facet->GetVertexIndex(j) + 1;
}
polyhedron->AddFacet(v[0],v[1],v[2]);
polyhedron->SetFacet(i+1, v[0], v[1], v[2]);
}
polyhedron->SetReferences();
return (G4Polyhedron*) polyhedron;
return polyhedron;
}
#endif // G4GEOM_USE_USOLIDS
@@ -985,6 +985,118 @@ void G4VTwistedFaceted::CreateSurfaces()
}
//=====================================================================
//* GetCubicVolume ----------------------------------------------------
G4double G4VTwistedFaceted::GetCubicVolume()
{
if(fCubicVolume == 0.)
{
fCubicVolume = ((fDx1 + fDx2 + fDx3 + fDx4)*(fDy1 + fDy2) +
(fDx4 + fDx3 - fDx2 - fDx1)*(fDy2 - fDy1)/3)*fDz;
}
return fCubicVolume;
}
//=====================================================================
//* GetLateralFaceArea ------------------------------------------------
G4double
G4VTwistedFaceted::GetLateralFaceArea(const G4TwoVector& p1,
const G4TwoVector& p2,
const G4TwoVector& p3,
const G4TwoVector& p4) const
{
constexpr G4int NSTEP = 100;
constexpr G4double dt = 1./NSTEP;
G4double h = 2.*fDz;
G4double hh = h*h;
G4double hTanTheta = h*std::tan(fTheta);
G4double x1 = p1.x();
G4double y1 = p1.y();
G4double x21 = p2.x() - p1.x();
G4double y21 = p2.y() - p1.y();
G4double x31 = p3.x() - p1.x();
G4double y31 = p3.y() - p1.y();
G4double x42 = p4.x() - p2.x();
G4double y42 = p4.y() - p2.y();
G4double x43 = p4.x() - p3.x();
G4double y43 = p4.y() - p3.y();
// check if face is plane (just in case)
G4double lmax = std::max(std::max(std::abs(x21),std::abs(y21)),
std::max(std::abs(x43),std::abs(y43)));
G4double eps = lmax*kCarTolerance;
if (std::abs(fPhiTwist) < kCarTolerance &&
std::abs(x21*y43 - y21*x43) < eps)
{
G4double x0 = hTanTheta*std::cos(fPhi);
G4double y0 = hTanTheta*std::sin(fPhi);
G4ThreeVector A(p4.x() - p1.x() + x0, p4.y() - p1.y() + y0, h);
G4ThreeVector B(p3.x() - p2.x() + x0, p3.y() - p2.y() + y0, h);
return (A.cross(B)).mag()*0.5;
}
// twisted face
G4double area = 0.;
for (G4int i = 0; i < NSTEP; ++i)
{
G4double t = (i + 0.5)*dt;
G4double I = x21 + (x42 - x31)*t;
G4double J = y21 + (y42 - y31)*t;
G4double II = I*I;
G4double JJ = J*J;
G4double IIJJ = hh*(I*I + J*J);
G4double ang = fPhi + fPhiTwist*(0.5 - t);
G4double A = fPhiTwist*(II + JJ) + x21*y43 - x43*y21;
G4double B = fPhiTwist*(I*(x1 + x31*t) + J*(y1 + y31*t)) +
hTanTheta*(I*std::sin(ang) - J*std::cos(ang)) +
(I*y31 - J*x31);
G4double invAA = 1./(A*A);
G4double sqrtAA = 2.*std::abs(A);
G4double invSqrtAA = 1./sqrtAA;
G4double aa = A*A;
G4double bb = 2.*A*B;
G4double cc = IIJJ + B*B;
G4double R1 = std::sqrt(aa + bb + cc);
G4double R0 = std::sqrt(cc);
G4double log1 = std::log(std::abs(sqrtAA*R1 + 2.*aa + bb));
G4double log0 = std::log(std::abs(sqrtAA*R0 + bb));
area += 0.5*R1 + 0.25*bb*invAA*(R1 - R0) + IIJJ*invSqrtAA*(log1 - log0);
}
return area*dt;
}
//=====================================================================
//* GetSurfaceArea ----------------------------------------------------
G4double G4VTwistedFaceted::GetSurfaceArea()
{
if (fSurfaceArea == 0.)
{
G4TwoVector vv[8];
vv[0] = G4TwoVector(-fDx1 - fDy1*fTAlph,-fDy1);
vv[1] = G4TwoVector( fDx1 - fDy1*fTAlph,-fDy1);
vv[2] = G4TwoVector(-fDx2 + fDy1*fTAlph, fDy1);
vv[3] = G4TwoVector( fDx2 + fDy1*fTAlph, fDy1);
vv[4] = G4TwoVector(-fDx3 - fDy2*fTAlph,-fDy2);
vv[5] = G4TwoVector( fDx3 - fDy2*fTAlph,-fDy2);
vv[6] = G4TwoVector(-fDx4 + fDy2*fTAlph, fDy2);
vv[7] = G4TwoVector( fDx4 + fDy2*fTAlph, fDy2);
fSurfaceArea = 2.*(fDy1*(fDx1 + fDx2) + fDy2*(fDx3 + fDx4)) +
GetLateralFaceArea(vv[0], vv[1], vv[4], vv[5]) +
GetLateralFaceArea(vv[1], vv[3], vv[5], vv[7]) +
GetLateralFaceArea(vv[3], vv[2], vv[7], vv[6]) +
GetLateralFaceArea(vv[2], vv[0], vv[6], vv[4]);
}
return fSurfaceArea;
}
//=====================================================================
//* GetEntityType -----------------------------------------------------
+10 -14
View File
@@ -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