Import Geant4 11.3.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2024-06-28 13:08:51 +02:00
parent f7b23877ed
commit e58e650b32
5232 changed files with 239416 additions and 244360 deletions
+14
View File
@@ -6,6 +6,20 @@ It must **not** be used as a substitute for writing good git commit messages!
------------------------------------------------------------------------------
## 2024-06-04 Evgueni Tcherniaev (geom-bool-V11-02-02)
- G4BooleanSolid::SetCubVolStatistics(st), G4BooleanSolid::SetCubVolEpsilon(ep):
propagate parameter to all constituents.
- G4UnionSolid::GetCubicVolume(), G4SubtractionSolid::GetCubicVolume():
limit calculations with construction of temporary G4IntersectionSolid by 10 constituents.
## 2024-05-29 Evgueni Tcherniaev (geom-bool-V11-02-01)
- Added new methods GetNumOfConstituents() and IsFaceted().
## 2023-12-22 Stewart Boogert (geom-bool-V11-02-00)
- Added extra external processor method to process solid. Added to void using G4Polyhedron
under any circumstances (floating point math as in G4Polyhedron is almost always going to
fail)
## 2023-10-28 Stewart Boogert (geom-bool-V11-01-05)
- Fix problem with downcast in external boolean processor, could result incorrect nullptr
@@ -76,15 +76,15 @@ class G4BooleanSolid : public G4VSolid
G4double GetCubicVolume() override;
inline G4double GetSurfaceArea() override;
G4GeometryType GetEntityType() const override;
G4Polyhedron* GetPolyhedron () const override;
G4GeometryType GetEntityType() const override;
G4Polyhedron* GetPolyhedron() const override;
std::ostream& StreamInfo(std::ostream& os) const override;
inline G4int GetCubVolStatistics() const;
inline G4double GetCubVolEpsilon() const;
inline void SetCubVolStatistics(G4int st);
inline void SetCubVolEpsilon(G4double ep);
void SetCubVolStatistics(G4int st);
void SetCubVolEpsilon(G4double ep);
inline G4int GetAreaStatistics() const;
inline G4double GetAreaAccuracy() const;
@@ -93,6 +93,9 @@ class G4BooleanSolid : public G4VSolid
G4ThreeVector GetPointOnSurface() const override;
G4int GetNumOfConstituents() const override;
G4bool IsFaceted() const override;
G4BooleanSolid(__void__&);
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
@@ -123,7 +126,7 @@ class G4BooleanSolid : public G4VSolid
G4VSolid* fPtrSolidB = nullptr;
G4double fCubicVolume = -1.0;
// Cached value of fCubicVolume
// Cached value of Cubic Volume
G4double fSurfaceArea = -1.0;
// Cached value of Surface Area
@@ -39,20 +39,6 @@ G4double G4BooleanSolid::GetCubVolEpsilon() const
return fCubVolEpsilon;
}
inline
void G4BooleanSolid::SetCubVolStatistics(G4int st)
{
if (st != fCubVolStatistics) { fCubicVolume = -1.; }
fCubVolStatistics = st;
}
inline
void G4BooleanSolid::SetCubVolEpsilon(G4double ep)
{
if (ep != fCubVolEpsilon) { fCubicVolume = -1.; }
fCubVolEpsilon = ep;
}
inline
G4int G4BooleanSolid::GetAreaStatistics() const
{
@@ -72,7 +58,7 @@ void G4BooleanSolid::SetAreaStatistics(G4int st)
fAreaStatistics = st;
}
inline
inline
void G4BooleanSolid::SetAreaAccuracy(G4double ep)
{
if (ep != fAreaAccuracy) { fSurfaceArea = -1.; }
@@ -98,6 +98,9 @@ class G4DisplacedSolid : public G4VSolid
G4ThreeVector GetPointOnSurface() const override;
G4int GetNumOfConstituents() const override;
G4bool IsFaceted() const override;
G4GeometryType GetEntityType() const override;
G4VSolid* Clone() const override;
@@ -116,6 +116,9 @@ class G4MultiUnion : public G4VSolid
G4double GetCubicVolume() override;
G4double GetSurfaceArea() override;
G4int GetNumOfConstituents() const override;
G4bool IsFaceted() const override;
G4VSolid* Clone() const override ;
G4GeometryType GetEntityType() const override { return "G4MultiUnion"; }
@@ -87,7 +87,10 @@ class G4ScaledSolid : public G4VSolid
G4ThreeVector GetPointOnSurface() const override;
G4Scale3D GetScaleTransform() const;
G4int GetNumOfConstituents() const override;
G4bool IsFaceted() const override;
G4Scale3D GetScaleTransform() const;
void SetScaleTransform(const G4Scale3D& scale);
G4VSolid* GetUnscaledSolid() const;
@@ -36,6 +36,8 @@
class G4Polyhedron;
class G4PolyhedronArbitrary;
class G4BooleanSolid;
class G4VSolid;
class G4VBooleanProcessor
{
@@ -53,6 +55,9 @@ class G4VBooleanProcessor
virtual G4PolyhedronArbitrary* Subtraction(G4Polyhedron* /*p1*/,
G4Polyhedron* /*p2*/)
{ return nullptr; }
virtual G4PolyhedronArbitrary* Process(const G4VSolid* /*bs*/)
{ return nullptr; }
};
#endif
@@ -208,6 +208,134 @@ G4GeometryType G4BooleanSolid::GetEntityType() const
return {"G4BooleanSolid"};
}
//////////////////////////////////////////////////////////////////////////
//
// Set number of random points to be used for computing cubic volume
void G4BooleanSolid::SetCubVolStatistics(G4int st)
{
if (st != fCubVolStatistics) { fCubicVolume = -1.; }
fCubVolStatistics = st;
// Propagate st to all components of the 1st solid
if (fPtrSolidA->GetNumOfConstituents() > 1)
{
G4VSolid* ptr = fPtrSolidA;
while(true)
{
G4String type = ptr->GetEntityType();
if (type == "G4DisplacedSolid")
{
ptr = ((G4DisplacedSolid*)ptr)->GetConstituentMovedSolid();
continue;
}
if (type == "G4ReflectedSolid")
{
ptr = ((G4ReflectedSolid*)ptr)->GetConstituentMovedSolid();
continue;
}
if (type == "G4ScaledSolid")
{
ptr = ((G4ScaledSolid*)ptr)->GetUnscaledSolid();
continue;
}
((G4BooleanSolid*)ptr)->SetCubVolStatistics(st);
break;
}
}
// Propagate st to all components of the 2nd solid
if (fPtrSolidB->GetNumOfConstituents() > 1)
{
G4VSolid* ptr = fPtrSolidB;
while(true)
{
G4String type = ptr->GetEntityType();
if (type == "G4DisplacedSolid")
{
ptr = ((G4DisplacedSolid*)ptr)->GetConstituentMovedSolid();
continue;
}
if (type == "G4ReflectedSolid")
{
ptr = ((G4ReflectedSolid*)ptr)->GetConstituentMovedSolid();
continue;
}
if (type == "G4ScaledSolid")
{
ptr = ((G4ScaledSolid*)ptr)->GetUnscaledSolid();
continue;
}
((G4BooleanSolid*)ptr)->SetCubVolStatistics(st);
break;
}
}
}
//////////////////////////////////////////////////////////////////////////
//
// Set epsilon for computing cubic volume
void G4BooleanSolid::SetCubVolEpsilon(G4double ep)
{
if (ep != fCubVolEpsilon) { fCubicVolume = -1.; }
fCubVolEpsilon = ep;
// Propagate ep to all components of the 1st solid
if (fPtrSolidA->GetNumOfConstituents() > 1)
{
G4VSolid* ptr = fPtrSolidA;
while(true)
{
G4String type = ptr->GetEntityType();
if (type == "G4DisplacedSolid")
{
ptr = ((G4DisplacedSolid*)ptr)->GetConstituentMovedSolid();
continue;
}
if (type == "G4ReflectedSolid")
{
ptr = ((G4ReflectedSolid*)ptr)->GetConstituentMovedSolid();
continue;
}
if (type == "G4ScaledSolid")
{
ptr = ((G4ScaledSolid*)ptr)->GetUnscaledSolid();
continue;
}
((G4BooleanSolid*)ptr)->SetCubVolEpsilon(ep);
break;
}
}
// Propagate ep to all components of the 2nd solid
if (fPtrSolidB->GetNumOfConstituents() > 1)
{
G4VSolid* ptr = fPtrSolidB;
while(true)
{
G4String type = ptr->GetEntityType();
if (type == "G4DisplacedSolid")
{
ptr = ((G4DisplacedSolid*)ptr)->GetConstituentMovedSolid();
continue;
}
if (type == "G4ReflectedSolid")
{
ptr = ((G4ReflectedSolid*)ptr)->GetConstituentMovedSolid();
continue;
}
if (type == "G4ScaledSolid")
{
ptr = ((G4ScaledSolid*)ptr)->GetUnscaledSolid();
continue;
}
((G4BooleanSolid*)ptr)->SetCubVolEpsilon(ep);
break;
}
}
}
//////////////////////////////////////////////////////////////////////////
//
// Stream object contents to an output stream
@@ -340,6 +468,24 @@ G4ThreeVector G4BooleanSolid::GetPointOnSurface() const
return p;
}
//////////////////////////////////////////////////////////////////////////
//
// Return total number of constituents used for construction of the solid
G4int G4BooleanSolid::GetNumOfConstituents() const
{
return (fPtrSolidA->GetNumOfConstituents() + fPtrSolidB->GetNumOfConstituents());
}
//////////////////////////////////////////////////////////////////////////
//
// Return true if the resulting solid has only planar faces
G4bool G4BooleanSolid::IsFaceted() const
{
return (fPtrSolidA->IsFaceted() && fPtrSolidB->IsFaceted());
}
//////////////////////////////////////////////////////////////////////////
//
// Returns polyhedron for visualization
@@ -465,6 +465,24 @@ G4ThreeVector G4DisplacedSolid::GetPointOnSurface() const
return fDirectTransform->TransformPoint(p);
}
//////////////////////////////////////////////////////////////////////////
//
// Return the number of constituents used for construction of the solid
G4int G4DisplacedSolid::GetNumOfConstituents() const
{
return fPtrSolid->GetNumOfConstituents();
}
//////////////////////////////////////////////////////////////////////////
//
// Return true if the solid has only planar faces
G4bool G4DisplacedSolid::IsFaceted() const
{
return fPtrSolid->IsFaceted();
}
//////////////////////////////////////////////////////////////////////////
//
// Return object type name
@@ -562,8 +562,6 @@ G4IntersectionSolid::CreatePolyhedron () const
}
else
{
return fExternalBoolProcessor
->Intersection(GetConstituentSolid(0)->GetPolyhedron(),
GetConstituentSolid(1)->GetPolyhedron());
return fExternalBoolProcessor->Process(this);
}
}
@@ -823,6 +823,21 @@ G4double G4MultiUnion::GetSurfaceArea()
return fSurfaceArea;
}
//______________________________________________________________________________
G4int G4MultiUnion::GetNumOfConstituents() const
{
G4int num = 0;
for (const auto solid : fSolids) { num += solid->GetNumOfConstituents(); }
return num;
}
//______________________________________________________________________________
G4bool G4MultiUnion::IsFaceted() const
{
for (const auto solid : fSolids) { if (!solid->IsFaceted()) return false; }
return true;
}
//______________________________________________________________________________
void G4MultiUnion::Voxelize()
{
@@ -1004,23 +1019,7 @@ G4Polyhedron* G4MultiUnion::CreatePolyhedron() const
}
else
{
G4VSolid* solidA = GetSolid(0);
auto solidAPolyhedron =solidA->GetPolyhedron();
const G4Transform3D transform0 = GetTransformation(0);
G4DisplacedSolid dispSolidA("placedA", solidA, transform0);
// dispSolidA.GetPolyhedron()
for (G4int i = 1; i < GetNumberOfSolids(); ++i)
{
G4VSolid* solidB = GetSolid(i);
const G4Transform3D transform = GetTransformation(i);
G4DisplacedSolid dispSolidB("placedB", solidB, transform);
solidAPolyhedron = G4BooleanSolid::GetExternalBooleanProcessor()
->Union(solidAPolyhedron, dispSolidB.GetPolyhedron());
}
return solidAPolyhedron;
return G4BooleanSolid::GetExternalBooleanProcessor()->Process(this);
}
}
@@ -120,7 +120,7 @@ G4VSolid* G4ScaledSolid::GetUnscaledSolid() const
//////////////////////////////////////////////////////////////////////////
//
// Get bounding box
//
void G4ScaledSolid::BoundingLimits(G4ThreeVector& pMin,
G4ThreeVector& pMax) const
{
@@ -315,6 +315,23 @@ G4ThreeVector G4ScaledSolid::GetPointOnSurface() const
{
return fScale->InverseTransform(fPtrSolid->GetPointOnSurface());
}
//////////////////////////////////////////////////////////////////////////
//
// Return the number of constituents used for construction of the solid
//
G4int G4ScaledSolid::GetNumOfConstituents() const
{
return fPtrSolid->GetNumOfConstituents();
}
//////////////////////////////////////////////////////////////////////////
//
// Return true if the solid has only planar faces
//
G4bool G4ScaledSolid::IsFaceted() const
{
return fPtrSolid->IsFaceted();
}
//////////////////////////////////////////////////////////////////////////
//
@@ -578,9 +578,7 @@ G4Polyhedron* G4SubtractionSolid::CreatePolyhedron () const
}
else
{
return fExternalBoolProcessor
->Subtraction(GetConstituentSolid(0)->GetPolyhedron(),
GetConstituentSolid(1)->GetPolyhedron());
return fExternalBoolProcessor->Process(this);
}
}
@@ -591,30 +589,38 @@ G4Polyhedron* G4SubtractionSolid::CreatePolyhedron () const
G4double G4SubtractionSolid::GetCubicVolume()
{
if( fCubicVolume != -1.0 )
if( fCubicVolume >= 0. )
{
return fCubicVolume;
}
G4double cubVolumeA = fPtrSolidA->GetCubicVolume();
G4ThreeVector bminA, bmaxA, bminB, bmaxB;
fPtrSolidA->BoundingLimits(bminA, bmaxA);
fPtrSolidB->BoundingLimits(bminB, bmaxB);
G4double intersection = 0.;
G4bool canIntersect =
bminA.x() < bmaxB.x() && bminA.y() < bmaxB.y() && bminA.z() < bmaxB.z() &&
bminB.x() < bmaxA.x() && bminB.y() < bmaxA.y() && bminB.z() < bmaxA.z();
if ( canIntersect )
G4bool noIntersection =
bminA.x() >= bmaxB.x() || bminA.y() >= bmaxB.y() || bminA.z() >= bmaxB.z() ||
bminB.x() >= bmaxA.x() || bminB.y() >= bmaxA.y() || bminB.z() >= bmaxA.z();
if (noIntersection)
{
G4IntersectionSolid intersectVol( "Temporary-Intersection-for-Subtraction",
fPtrSolidA, fPtrSolidB );
intersectVol.SetCubVolStatistics(100000);
intersection = intersectVol.GetCubicVolume();
fCubicVolume = fPtrSolidA->GetCubicVolume();
}
else
{
if (GetNumOfConstituents() > 10)
{
fCubicVolume = G4BooleanSolid::GetCubicVolume();
}
else
{
G4IntersectionSolid intersectVol("Temporary-Intersection-for-Subtraction",
fPtrSolidA, fPtrSolidB);
intersectVol.SetCubVolStatistics(GetCubVolStatistics());
intersectVol.SetCubVolEpsilon(GetCubVolEpsilon());
fCubicVolume = cubVolumeA - intersection;
if (fCubicVolume < 0.01*cubVolumeA) fCubicVolume = G4VSolid::GetCubicVolume();
G4double cubVolumeA = fPtrSolidA->GetCubicVolume();
fCubicVolume = cubVolumeA - intersectVol.GetCubicVolume();
if (fCubicVolume < 0.01*cubVolumeA) fCubicVolume = G4BooleanSolid::GetCubicVolume();
}
}
return fCubicVolume;
}
@@ -543,9 +543,7 @@ G4UnionSolid::CreatePolyhedron () const
}
else
{
return fExternalBoolProcessor
->Union(GetConstituentSolid(0)->GetPolyhedron(),
GetConstituentSolid(1)->GetPolyhedron());
return fExternalBoolProcessor->Process(this);
}
}
@@ -555,30 +553,37 @@ G4UnionSolid::CreatePolyhedron () const
G4double G4UnionSolid::GetCubicVolume()
{
if( fCubicVolume != -1.0 )
if( fCubicVolume >= 0. )
{
return fCubicVolume;
}
G4double cubVolumeA = fPtrSolidA->GetCubicVolume();
G4double cubVolumeB = fPtrSolidB->GetCubicVolume();
G4ThreeVector bminA, bmaxA, bminB, bmaxB;
fPtrSolidA->BoundingLimits(bminA, bmaxA);
fPtrSolidB->BoundingLimits(bminB, bmaxB);
G4bool noIntersection =
bminA.x() >= bmaxB.x() || bminA.y() >= bmaxB.y() || bminA.z() >= bmaxB.z() ||
bminB.x() >= bmaxA.x() || bminB.y() >= bmaxA.y() || bminB.z() >= bmaxA.z();
G4double intersection = 0.;
G4bool canIntersect =
bminA.x() < bmaxB.x() && bminA.y() < bmaxB.y() && bminA.z() < bmaxB.z() &&
bminB.x() < bmaxA.x() && bminB.y() < bmaxA.y() && bminB.z() < bmaxA.z();
if ( canIntersect )
if (noIntersection)
{
G4IntersectionSolid intersectVol( "Temporary-Intersection-for-Union",
fPtrSolidA, fPtrSolidB );
intersectVol.SetCubVolStatistics(100000);
intersection = intersectVol.GetCubicVolume();
fCubicVolume = fPtrSolidA->GetCubicVolume() + fPtrSolidB->GetCubicVolume();
}
else
{
if (GetNumOfConstituents() > 10)
{
fCubicVolume = G4BooleanSolid::GetCubicVolume();
}
else
{
G4IntersectionSolid intersectVol("Temporary-Intersection-for-Union",
fPtrSolidA, fPtrSolidB);
intersectVol.SetCubVolStatistics(GetCubVolStatistics());
intersectVol.SetCubVolEpsilon(GetCubVolEpsilon());
fCubicVolume = cubVolumeA + cubVolumeB - intersection;
fCubicVolume = fPtrSolidA->GetCubicVolume() + fPtrSolidB->GetCubicVolume()
- intersectVol.GetCubicVolume();
}
}
return fCubicVolume;
}