62const G4String G4ReflectionFactory::fDefaultNameExtension =
"_refl";
80 : fNameExtension(fDefaultNameExtension)
124 G4cout <<
"Place " << name <<
" lv " << LV <<
" "
147 if (!IsReflection(scale))
149 if (fVerboseLevel>0) {
G4cout <<
"Scale positive" <<
G4endl; }
153 motherLV, isMany, copyNo, surfCheck);
162 ReflectLV(LV, surfCheck), name, reflMotherLV,
163 isMany, copyNo, surfCheck);
173 if (fVerboseLevel>0) {
G4cout <<
"scale negative" <<
G4endl; }
176 =
new G4PVPlacement(pureTransform3D, ReflectLV(LV, surfCheck), name,
177 motherLV, isMany, copyNo, surfCheck);
187 LV, name, reflMotherLV, isMany, copyNo, surfCheck);
213 G4cout <<
"Replicate " << name <<
" lv " << LV <<
" "
226 pv2 =
new G4PVReplica(name, ReflectLV(LV), reflMotherLV,
252 G4cout <<
"Divide " << name <<
" lv " << LV <<
" "
293 G4cout <<
"Divide " << name <<
" lv " << LV <<
" "
334 G4cout <<
"Divide " << name <<
" lv " << LV <<
" "
341 -> CreatePVDivision(name, LV, motherLV,
axis, width,
offset);
372 if (refLV ==
nullptr)
377 refLV = CreateReflectedLV(LV);
381 ReflectDaughters(LV, refLV, surfCheck);
404 if (fReflectedLVMap.find(LV) != fReflectedLVMap.cend())
406 std::ostringstream message;
407 message <<
"Invalid reflection for volume: "
409 <<
"Cannot be applied to a volume already reflected !";
410 G4Exception(
"G4ReflectionFactory::CreateReflectedLV()",
419 =
new G4LogicalVolume(refSolid,
421 LV->
GetName() + fNameExtension,
435 fConstituentLVMap[LV] = refLV;
436 fReflectedLVMap[refLV] = LV;
452 G4cout <<
"G4ReflectionFactory::ReflectDaughters(): "
462 ReflectPVPlacement(dPV, refLV, surfCheck);
466 ReflectPVReplica(dPV, refLV);
471 ReflectPVDivision(dPV, refLV);
475 ReflectPVParameterised(dPV, refLV, surfCheck);
495 dt = fScale * (dt * fScale.inverse());
497 G4LogicalVolume* refDLV;
499 if (fVerboseLevel>0) {
G4cout <<
"Daughter: " << dPV <<
" " << dLV->
GetName(); }
504 if (fVerboseLevel>0) {
G4cout <<
" will be reflected." <<
G4endl; }
509 if (refDLV ==
nullptr)
513 refDLV = CreateReflectedLV(dLV);
517 ReflectDaughters(dLV, refDLV, surfCheck);
523 new G4PVPlacement(dt, refDLV, dPV->
GetName(), refLV,
529 if (fVerboseLevel>0) {
G4cout <<
" will be reconstitued." <<
G4endl; }
533 new G4PVPlacement(dt, refDLV, dPV->
GetName(), refLV,
559 G4LogicalVolume* refDLV;
561 if (fVerboseLevel>0) {
G4cout <<
"Daughter: " << dPV <<
" " << dLV->
GetName(); }
565 if (fVerboseLevel>0) {
G4cout <<
" will be reflected." <<
G4endl; }
571 if (refDLV ==
nullptr)
575 refDLV = CreateReflectedLV(dLV);
579 ReflectDaughters(dLV, refDLV);
589 if (fVerboseLevel>0) {
G4cout <<
" will be reconstitued." <<
G4endl; }
607 G4VPVDivisionFactory* divisionFactory = GetPVDivisionFactory();
615 G4LogicalVolume* refDLV;
617 if (fVerboseLevel>0) {
G4cout <<
"Daughter: " << dPV <<
" " << dLV->
GetName(); }
621 if (fVerboseLevel>0) {
G4cout <<
" will be reflected." <<
G4endl; }
627 if (refDLV ==
nullptr)
631 refDLV = CreateReflectedLV(dLV);
635 ReflectDaughters(dLV, refDLV);
644 if (fVerboseLevel>0) {
G4cout <<
" will be reconstitued." <<
G4endl; }
662 std::ostringstream message;
663 message <<
"Not yet implemented. Volume: " << dPV->
GetName() <<
G4endl
664 <<
"Reflection of parameterised volumes is not yet implemented.";
665 G4Exception(
"G4ReflectionFactory::ReflectPVParameterised()",
678 auto it = fReflectedLVMap.find(reflLV);
680 if (it == fReflectedLVMap.cend()) {
return nullptr; }
694 auto it = fConstituentLVMap.find(lv);
696 if (it == fConstituentLVMap.cend()) {
return nullptr; }
709 return (fConstituentLVMap.find(lv) != fConstituentLVMap.cend());
720 return (fReflectedLVMap.find(lv) != fReflectedLVMap.cend());
730 return scale(0,0)*scale(1,1)*scale(2,2) < 0.;
738 return fReflectedLVMap;
745 fConstituentLVMap.clear();
746 fReflectedLVMap.clear();
751void G4ReflectionFactory::PrintConstituentLVMap()
const
756 for (
const auto & it : fConstituentLVMap)
758 G4cout <<
"lv: " << it.first <<
" lv_refl: " << it.second <<
G4endl;
765void G4ReflectionFactory::CheckScale(
const G4Scale3D& scale)
const
771 if (!IsReflection(scale)) {
return;
775 for (
auto i=0; i<4; ++i)
777 for (
auto j=0; j<4; ++j)
779 diff += std::abs(scale(i,j) - fScale(i,j));
783 if (diff > fScalePrecision)
785 std::ostringstream message;
786 message <<
"Unexpected scale in input !" <<
G4endl
787 <<
" Difference: " << diff;
802 if (divisionFactory ==
nullptr)
804 std::ostringstream message;
805 message <<
"A concrete G4PVDivisionFactory instantiated is required !"
807 <<
" It has been requested to reflect divided volumes."
809 <<
" In this case, it is required to instantiate a concrete"
811 <<
" factory G4PVDivisionFactory in your program -before-"
813 <<
" executing the reflection !";
814 G4Exception(
"G4ReflectionFactory::GetPVDivisionFactory()",
818 return divisionFactory;
825 fScalePrecision = scaleValue;
832 return fScalePrecision;
839 fVerboseLevel = verboseLevel;
846 return fVerboseLevel;
853 fNameExtension = nameExtension;
860 return fNameExtension;
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4ThreadLocal T * G4GeomSplitter< T >::offset
G4PVReplica(const G4String &pName, G4LogicalVolume *pLogical, G4LogicalVolume *pMother, const EAxis pAxis, const G4int nReplicas, const G4double width, const G4double offset=0.)
G4PVReplica represents many touchable detector elements differing only in their positioning....
std::map< G4LogicalVolume *, G4LogicalVolume *, std::less< G4LogicalVolume * > > G4ReflectedVolumesMap
std::pair< G4VPhysicalVolume *, G4VPhysicalVolume * > G4PhysicalVolumesPair
G4GLOB_DLL std::ostream G4cout
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
G4LogicalVolume represents a leaf node or unpositioned subtree in the geometry hierarchy....
G4VSolid * GetSolid() const
const G4VisAttributes * GetVisAttributes() const
G4VSensitiveDetector * GetSensitiveDetector() const
std::size_t GetNoDaughters() const
void SetRegion(G4Region *reg)
G4bool IsRootRegion() const
G4Region * GetRegion() const
G4double GetBiasWeight() const
G4Material * GetMaterial() const
G4VPhysicalVolume * GetDaughter(const std::size_t i) const
G4UserLimits * GetUserLimits() const
G4FieldManager * GetFieldManager() const
void SetVisAttributes(const G4VisAttributes *pVA)
void SetBiasWeight(G4double w)
const G4String & GetName() const
G4PVPlacement represents a single volume positioned within and relative to a mother volume.
G4ReflectionFactory provides functions for volumes placements with a general transfomation that can c...
G4int GetVerboseLevel() const
const G4String & GetVolumesNameExtension() const
G4bool IsReflected(G4LogicalVolume *lv) const
G4PhysicalVolumesPair Divide(const G4String &name, G4LogicalVolume *LV, G4LogicalVolume *motherLV, EAxis axis, G4int nofDivisions, G4double width, G4double offset)
G4LogicalVolume * GetReflectedLV(G4LogicalVolume *lv) const
static G4ReflectionFactory * Instance()
void SetVerboseLevel(G4int verboseLevel)
G4double GetScalePrecision() const
G4PhysicalVolumesPair Place(const G4Transform3D &transform3D, const G4String &name, G4LogicalVolume *LV, G4LogicalVolume *motherLV, G4bool isMany, G4int copyNo, G4bool surfCheck=false)
G4ReflectionFactory(const G4ReflectionFactory &)=delete
G4bool IsConstituent(G4LogicalVolume *lv) const
void SetScalePrecision(G4double scaleValue)
const G4ReflectedVolumesMap & GetReflectedVolumesMap() const
G4LogicalVolume * GetConstituentLV(G4LogicalVolume *reflLV) const
G4PhysicalVolumesPair Replicate(const G4String &name, G4LogicalVolume *LV, G4LogicalVolume *motherLV, EAxis axis, G4int nofReplicas, G4double width, G4double offset=0.)
void SetVolumesNameExtension(const G4String &nameExtension)
void AddRootLogicalVolume(G4LogicalVolume *lv, G4bool search=true)
G4VPVDivisionFactory is an abstract factory that defines the interfaces for creating volume divisions...
static G4VPVDivisionFactory * Instance()
virtual G4VPhysicalVolume * CreatePVDivision(const G4String &pName, G4LogicalVolume *pLogical, G4LogicalVolume *pMother, const EAxis pAxis, const G4int nReplicas, const G4double width, const G4double offset)=0
G4VPhysicalVolume is an abstract base class for the representation of a positioned volume....
virtual G4bool IsReplicated() const =0
G4LogicalVolume * GetLogicalVolume() const
G4RotationMatrix GetObjectRotationValue() const
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const =0
virtual G4int GetCopyNo() const =0
const G4String & GetName() const
virtual G4VPVParameterisation * GetParameterisation() const =0
virtual G4bool IsMany() const =0
G4ThreeVector GetObjectTranslation() const
const axis_t axis_to_type< N >::axis