Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4SmartVoxelHeader Class Reference

#include <G4SmartVoxelHeader.hh>

Public Member Functions

 G4SmartVoxelHeader (G4LogicalVolume *pVolume, G4int pSlice=0)
 
 ~G4SmartVoxelHeader ()
 
G4int GetMaxEquivalentSliceNo () const
 
void SetMaxEquivalentSliceNo (G4int pMax)
 
G4int GetMinEquivalentSliceNo () const
 
void SetMinEquivalentSliceNo (G4int pMin)
 
EAxis GetAxis () const
 
EAxis GetParamAxis () const
 
G4double GetMaxExtent () const
 
G4double GetMinExtent () const
 
G4int GetNoSlices () const
 
G4SmartVoxelProxyGetSlice (G4int n) const
 
G4bool AllSlicesEqual () const
 
G4bool operator== (const G4SmartVoxelHeader &pHead) const
 

Protected Member Functions

 G4SmartVoxelHeader (G4LogicalVolume *pVolume, const G4VoxelLimits &pLimits, const G4VolumeNosVector *pCandidates, G4int pSlice=0)
 
void BuildVoxels (G4LogicalVolume *pVolume)
 
void BuildReplicaVoxels (G4LogicalVolume *pVolume)
 
void BuildConsumedNodes (G4int nReplicas)
 
void BuildVoxelsWithinLimits (G4LogicalVolume *pVolume, G4VoxelLimits pLimits, const G4VolumeNosVector *pCandidates)
 
void BuildEquivalentSliceNos ()
 
void CollectEquivalentNodes ()
 
void CollectEquivalentHeaders ()
 
G4ProxyVectorBuildNodes (G4LogicalVolume *pVolume, G4VoxelLimits pLimits, const G4VolumeNosVector *pCandidates, EAxis pAxis)
 
G4double CalculateQuality (G4ProxyVector *pSlice)
 
void RefineNodes (G4LogicalVolume *pVolume, G4VoxelLimits pLimits)
 

Protected Attributes

G4int fminEquivalent
 
G4int fmaxEquivalent
 
EAxis faxis
 
EAxis fparamAxis
 
G4double fmaxExtent
 
G4double fminExtent
 
G4ProxyVector fslices
 

Friends

std::ostream & operator<< (std::ostream &s, const G4SmartVoxelHeader &h)
 

Detailed Description

Definition at line 78 of file G4SmartVoxelHeader.hh.

Constructor & Destructor Documentation

◆ G4SmartVoxelHeader() [1/2]

G4SmartVoxelHeader::G4SmartVoxelHeader ( G4LogicalVolume pVolume,
G4int  pSlice = 0 
)

Definition at line 66 of file G4SmartVoxelHeader.cc.

68 : fminEquivalent(pSlice),
69 fmaxEquivalent(pSlice),
71{
72 G4int nDaughters = pVolume->GetNoDaughters();
73 G4VoxelLimits limits; // Create `unlimited' limits object
74
75 // Determine whether daughter is replicated
76 //
77 if ((nDaughters!=1) || (!pVolume->GetDaughter(0)->IsReplicated()))
78 {
79 // Daughter not replicated => conventional voxel Build
80 // where each daughters extents are computed
81 //
82 BuildVoxels(pVolume);
83 }
84 else
85 {
86 // Single replicated daughter
87 //
88 BuildReplicaVoxels(pVolume);
89 }
90}
int G4int
Definition: G4Types.hh:66
G4int GetNoDaughters() const
G4VPhysicalVolume * GetDaughter(const G4int i) const
void BuildReplicaVoxels(G4LogicalVolume *pVolume)
void BuildVoxels(G4LogicalVolume *pVolume)
virtual G4bool IsReplicated() const =0
@ kUndefined
Definition: geomdefs.hh:54

◆ ~G4SmartVoxelHeader()

G4SmartVoxelHeader::~G4SmartVoxelHeader ( )

Definition at line 127 of file G4SmartVoxelHeader.cc.

128{
129 // Manually destroy underlying nodes/headers
130 // Delete collected headers and nodes once only
131 //
132 G4int node, proxy, maxNode=fslices.size();
133 G4SmartVoxelProxy *lastProxy=0;
134 G4SmartVoxelNode *dyingNode, *lastNode=0;
135 G4SmartVoxelHeader *dyingHeader, *lastHeader=0;
136
137 for (node=0; node<maxNode; node++)
138 {
139 if (fslices[node]->IsHeader())
140 {
141 dyingHeader = fslices[node]->GetHeader();
142 if (lastHeader!=dyingHeader)
143 {
144 lastHeader = dyingHeader;
145 lastNode = 0;
146 delete dyingHeader;
147 }
148 }
149 else
150 {
151 dyingNode = fslices[node]->GetNode();
152 if (dyingNode!=lastNode)
153 {
154 lastNode=dyingNode;
155 lastHeader=0;
156 delete dyingNode;
157 }
158 }
159 }
160 // Delete proxies
161 //
162 for (proxy=0; proxy<maxNode; proxy++)
163 {
164 if (fslices[proxy]!=lastProxy)
165 {
166 lastProxy = fslices[proxy];
167 delete lastProxy;
168 }
169 }
170 // Don't need to clear slices
171 // fslices.clear();
172}

◆ G4SmartVoxelHeader() [2/2]

G4SmartVoxelHeader::G4SmartVoxelHeader ( G4LogicalVolume pVolume,
const G4VoxelLimits pLimits,
const G4VolumeNosVector pCandidates,
G4int  pSlice = 0 
)
protected

Definition at line 100 of file G4SmartVoxelHeader.cc.

104 : fminEquivalent(pSlice),
105 fmaxEquivalent(pSlice),
107{
108#ifdef G4GEOMETRY_VOXELDEBUG
109 G4cout << "**** G4SmartVoxelHeader::G4SmartVoxelHeader" << G4endl
110 << " Limits " << pLimits << G4endl
111 << " Candidate #s = " ;
112 for (size_t i=0;i<pCandidates->size();i++)
113 {
114 G4cout << (*pCandidates)[i] << " ";
115 }
116 G4cout << G4endl;
117#endif
118
119 BuildVoxelsWithinLimits(pVolume,pLimits,pCandidates);
120}
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
void BuildVoxelsWithinLimits(G4LogicalVolume *pVolume, G4VoxelLimits pLimits, const G4VolumeNosVector *pCandidates)

Member Function Documentation

◆ AllSlicesEqual()

G4bool G4SmartVoxelHeader::AllSlicesEqual ( ) const

Definition at line 1281 of file G4SmartVoxelHeader.cc.

1282{
1283 G4int noSlices = fslices.size();
1284 G4SmartVoxelProxy* refProxy;
1285
1286 if (noSlices>1)
1287 {
1288 refProxy=fslices[0];
1289 for (G4int i=1; i<noSlices; i++)
1290 {
1291 if (refProxy!=fslices[i])
1292 {
1293 return false;
1294 }
1295 }
1296 }
1297 return true;
1298}

◆ BuildConsumedNodes()

void G4SmartVoxelHeader::BuildConsumedNodes ( G4int  nReplicas)
protected

Definition at line 395 of file G4SmartVoxelHeader.cc.

396{
397 G4int nNode, nVol;
398 G4SmartVoxelNode *pNode;
399 G4SmartVoxelProxy *pProxyNode;
400
401 // Create and fill nodes in temporary G4NodeVector (on stack)
402 //
403 G4NodeVector nodeList;
404 nodeList.reserve(nReplicas);
405 for (nNode=0; nNode<nReplicas; nNode++)
406 {
407 pNode=new G4SmartVoxelNode(nNode);
408 if (!pNode)
409 {
410 G4Exception("G4SmartVoxelHeader::BuildConsumedNodes()", "GeomMgt0003",
411 FatalException, "Node allocation error.");
412 }
413 nodeList.push_back(pNode);
414 }
415 for (nVol=0; nVol<nReplicas; nVol++)
416 {
417 nodeList[nVol]->Insert(nVol); // Insert replication of number
418 } // identical to voxel number
419
420 // Create & fill proxy List `in place' by modifying instance data fslices
421 //
422 fslices.clear();
423 for (nNode=0; nNode<nReplicas; nNode++)
424 {
425 pProxyNode = new G4SmartVoxelProxy(nodeList[nNode]);
426 if (!pProxyNode)
427 {
428 G4Exception("G4SmartVoxelHeader::BuildConsumedNodes()", "GeomMgt0003",
429 FatalException, "Proxy node allocation error.");
430 }
431 fslices.push_back(pProxyNode);
432 }
433}
@ FatalException
std::vector< G4SmartVoxelNode * > G4NodeVector
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41

Referenced by BuildReplicaVoxels().

◆ BuildEquivalentSliceNos()

void G4SmartVoxelHeader::BuildEquivalentSliceNos ( )
protected

Definition at line 583 of file G4SmartVoxelHeader.cc.

584{
585 G4int sliceNo, minNo, maxNo, equivNo;
586 G4int maxNode = fslices.size();
587 G4SmartVoxelNode *startNode, *sampleNode;
588 for (sliceNo=0; sliceNo<maxNode; sliceNo++)
589 {
590 minNo = sliceNo;
591
592 // Get first node (see preconditions - will throw exception if a header)
593 //
594 startNode = fslices[minNo]->GetNode();
595
596 // Find max equivalent
597 //
598 for (equivNo=minNo+1; equivNo<maxNode; equivNo++)
599 {
600 sampleNode = fslices[equivNo]->GetNode();
601 if (!((*startNode) == (*sampleNode))) { break; }
602 }
603 maxNo = equivNo-1;
604 if (maxNo != minNo)
605 {
606 // Set min and max nos
607 //
608 for (equivNo=minNo; equivNo<=maxNo; equivNo++)
609 {
610 sampleNode = fslices[equivNo]->GetNode();
611 sampleNode->SetMinEquivalentSliceNo(minNo);
612 sampleNode->SetMaxEquivalentSliceNo(maxNo);
613 }
614 // Advance outer loop to end of equivalent group
615 //
616 sliceNo = maxNo;
617 }
618 }
619}
void SetMaxEquivalentSliceNo(G4int pMax)
void SetMinEquivalentSliceNo(G4int pMin)

Referenced by BuildReplicaVoxels(), and BuildVoxelsWithinLimits().

◆ BuildNodes()

G4ProxyVector * G4SmartVoxelHeader::BuildNodes ( G4LogicalVolume pVolume,
G4VoxelLimits  pLimits,
const G4VolumeNosVector pCandidates,
EAxis  pAxis 
)
protected

Definition at line 750 of file G4SmartVoxelHeader.cc.

754{
755 G4double motherMinExtent= kInfinity, motherMaxExtent= -kInfinity,
756 targetMinExtent= kInfinity, targetMaxExtent= -kInfinity;
757 G4VPhysicalVolume *pDaughter=0;
758 G4VPVParameterisation *pParam=0;
759 G4VSolid *targetSolid;
760 G4AffineTransform targetTransform;
761 G4bool replicated;
762 G4int nCandidates = pCandidates->size();
763 G4int nVol, nNode, targetVolNo;
764 G4VoxelLimits noLimits;
765
766#ifdef G4GEOMETRY_VOXELDEBUG
767 G4cout << "**** G4SmartVoxelHeader::BuildNodes" << G4endl
768 << " Limits = " << pLimits << G4endl
769 << " Axis = " << pAxis << G4endl
770 << " Candidates = " << nCandidates << G4endl;
771#endif
772
773 // Compute extent of logical volume's solid along this axis
774 // NOTE: results stored locally and not preserved/reused
775 //
776 G4VSolid* outerSolid = pVolume->GetSolid();
777 const G4AffineTransform origin;
778 if( !outerSolid->CalculateExtent(pAxis, pLimits, origin,
779 motherMinExtent, motherMaxExtent) )
780 {
781 outerSolid->CalculateExtent(pAxis, noLimits, origin,
782 motherMinExtent, motherMaxExtent);
783 }
784 G4VolumeExtentVector minExtents(nCandidates,0.);
785 G4VolumeExtentVector maxExtents(nCandidates,0.);
786
787 if ( (pVolume->GetNoDaughters()==1)
788 && (pVolume->GetDaughter(0)->IsReplicated()==true) )
789 {
790 // Replication data not required: only parameterisation object
791 // and volume no. List used
792 //
793 pDaughter = pVolume->GetDaughter(0);
794 pParam = pDaughter->GetParameterisation();
795 if (!pParam)
796 {
797 std::ostringstream message;
798 message << "PANIC! - Missing parameterisation." << G4endl
799 << " Replicated volume with no parameterisation object !";
800 G4Exception("G4SmartVoxelHeader::BuildNodes()", "GeomMgt0003",
801 FatalException, message);
802 return 0;
803 }
804
805 // Setup daughter's transformations
806 //
807 targetTransform = G4AffineTransform(pDaughter->GetRotation(),
808 pDaughter->GetTranslation());
809 replicated = true;
810 }
811 else
812 {
813 replicated = false;
814 }
815
816 // Compute extents
817 //
818 for (nVol=0; nVol<nCandidates; nVol++)
819 {
820 targetVolNo=(*pCandidates)[nVol];
821 if (replicated == false)
822 {
823 pDaughter=pVolume->GetDaughter(targetVolNo);
824
825 // Setup daughter's transformations
826 //
827 targetTransform = G4AffineTransform(pDaughter->GetRotation(),
828 pDaughter->GetTranslation());
829 // Get underlying (and setup) solid
830 //
831 targetSolid = pDaughter->GetLogicalVolume()->GetSolid();
832 }
833 else
834 {
835 // Find solid
836 //
837 targetSolid = pParam->ComputeSolid(targetVolNo,pDaughter);
838
839 // Setup solid
840 //
841 targetSolid->ComputeDimensions(pParam,targetVolNo,pDaughter);
842
843 // Setup transform
844 //
845 pParam->ComputeTransformation(targetVolNo,pDaughter);
846 targetTransform = G4AffineTransform(pDaughter->GetRotation(),
847 pDaughter->GetTranslation());
848 }
849 // Calculate extents
850 //
851 if(!targetSolid->CalculateExtent(pAxis, pLimits, targetTransform,
852 targetMinExtent, targetMaxExtent))
853 {
854 targetSolid->CalculateExtent(pAxis, noLimits, targetTransform,
855 targetMinExtent,targetMaxExtent);
856 }
857 minExtents[nVol] = targetMinExtent;
858 maxExtents[nVol] = targetMaxExtent;
859
860#ifdef G4GEOMETRY_VOXELDEBUG
861 G4cout << "---------------------------------------------------" << G4endl
862 << " Volume = " << pDaughter->GetName() << G4endl
863 << " Min Extent = " << targetMinExtent << G4endl
864 << " Max Extent = " << targetMaxExtent << G4endl
865 << "---------------------------------------------------" << G4endl;
866#endif
867
868 // Check not entirely outside mother when processing toplevel nodes
869 //
870 if ( (!pLimits.IsLimited()) && ((targetMaxExtent<=motherMinExtent)
871 ||(targetMinExtent>=motherMaxExtent)) )
872 {
873 std::ostringstream message;
874 message << "PANIC! - Overlapping daughter with mother volume." << G4endl
875 << " Daughter physical volume "
876 << pDaughter->GetName() << G4endl
877 << " is entirely outside mother logical volume "
878 << pVolume->GetName() << " !!";
879 G4Exception("G4SmartVoxelHeader::BuildNodes()", "GeomMgt0002",
880 FatalException, message);
881 }
882
883#ifdef G4GEOMETRY_VOXELDEBUG
884 // Check for straddling volumes when debugging.
885 // If a volume is >kStraddlePercent percent over the mother
886 // boundary, print a warning.
887 //
888 if (!pLimits.IsLimited())
889 {
890 G4double width;
891 G4int kStraddlePercent=5;
892 width = maxExtents[nVol]-minExtents[nVol];
893 if ( (((motherMinExtent-minExtents[nVol])*100/width) > kStraddlePercent)
894 ||(((maxExtents[nVol]-motherMaxExtent)*100/width) > kStraddlePercent) )
895 {
896 G4cout << "**** G4SmartVoxelHeader::BuildNodes" << G4endl
897 << " WARNING : Daughter # " << nVol
898 << " name = " << pDaughter->GetName() << G4endl
899 << " Crosses mother boundary of logical volume, name = "
900 << pVolume->GetName() << G4endl
901 << " by more than " << kStraddlePercent
902 << "%" << G4endl;
903 }
904 }
905#endif
906 }
907
908 // Extents of all daughters known
909
910 // Calculate minimum slice width, only including volumes inside the limits
911 //
912 G4double minWidth = kInfinity;
913 G4double currentWidth;
914 for (nVol=0; nVol<nCandidates; nVol++)
915 {
916 // currentWidth should -always- be a positive value. Inaccurate computed extent
917 // from the solid or situations of malformed geometries (overlaps) may lead to
918 // negative values and therefore unpredictable crashes !
919 //
920 currentWidth = std::abs(maxExtents[nVol]-minExtents[nVol]);
921 if ( (currentWidth<minWidth)
922 && (maxExtents[nVol]>=pLimits.GetMinExtent(pAxis))
923 && (minExtents[nVol]<=pLimits.GetMaxExtent(pAxis)) )
924 {
925 minWidth = currentWidth;
926 }
927 }
928
929 // No. of Nodes formula - nearest integer to
930 // mother width/half min daughter width +1
931 //
932 G4double noNodesExactD = ((motherMaxExtent-motherMinExtent)*2.0/minWidth)+1.0;
933
934 // Compare with "smartless quality", i.e. the average number of slices
935 // used per contained volume.
936 //
937 G4double smartlessComputed = noNodesExactD / nCandidates;
938 G4double smartlessUser = pVolume->GetSmartless();
939 G4double smartless = (smartlessComputed <= smartlessUser)
940 ? smartlessComputed : smartlessUser;
941 G4double noNodesSmart = smartless*nCandidates;
942 G4int noNodesExactI = G4int(noNodesSmart);
943 G4int noNodes = ((noNodesSmart-noNodesExactI)>=0.5)
944 ? noNodesExactI+1 : noNodesExactI;
945 if( noNodes == 0 ) { noNodes=1; }
946
947#ifdef G4GEOMETRY_VOXELDEBUG
948 G4cout << " Smartless computed = " << smartlessComputed << G4endl
949 << " Smartless volume = " << smartlessUser
950 << " => # Smartless = " << smartless << G4endl;
951 G4cout << " Min width = " << minWidth
952 << " => # Nodes = " << noNodes << G4endl;
953#endif
954
955 if (noNodes>kMaxVoxelNodes)
956 {
957 noNodes=kMaxVoxelNodes;
958#ifdef G4GEOMETRY_VOXELDEBUG
959 G4cout << " Nodes Clipped to = " << kMaxVoxelNodes << G4endl;
960#endif
961 }
962 G4double nodeWidth = (motherMaxExtent-motherMinExtent)/noNodes;
963
964 // Create G4VoxelNodes. Will Add proxies before setting fslices
965 //
966 G4NodeVector* nodeList = new G4NodeVector();
967 if (!nodeList)
968 {
969 G4Exception("G4SmartVoxelHeader::BuildNodes()", "GeomMgt0003",
970 FatalException, "NodeList allocation error.");
971 return 0;
972 }
973 nodeList->reserve(noNodes);
974
975 for (nNode=0; nNode<noNodes; nNode++)
976 {
977 G4SmartVoxelNode *pNode;
978 pNode = new G4SmartVoxelNode(nNode);
979 if (!pNode)
980 {
981 G4Exception("G4SmartVoxelHeader::BuildNodes()", "GeomMgt0003",
982 FatalException, "Node allocation error.");
983 return 0;
984 }
985 nodeList->push_back(pNode);
986 }
987
988 // All nodes created (empty)
989
990 // Fill nodes: Step through extent lists
991 //
992 for (nVol=0; nVol<nCandidates; nVol++)
993 {
994 G4int nodeNo, minContainingNode, maxContainingNode;
995 minContainingNode = G4int((minExtents[nVol]-motherMinExtent)/nodeWidth);
996 maxContainingNode = G4int((maxExtents[nVol]-motherMinExtent)/nodeWidth);
997
998 // Only add nodes that are inside the limits of the axis
999 //
1000 if ( (maxContainingNode>=0) && (minContainingNode<noNodes) )
1001 {
1002 // If max extent is on max boundary => maxContainingNode=noNodes:
1003 // should be one less as nodeList has noNodes entries
1004 //
1005 if (maxContainingNode>=noNodes)
1006 {
1007 maxContainingNode = noNodes-1;
1008 }
1009 //
1010 // Protection against protruding volumes
1011 //
1012 if (minContainingNode<0)
1013 {
1014 minContainingNode=0;
1015 }
1016 for (nodeNo=minContainingNode; nodeNo<=maxContainingNode; nodeNo++)
1017 {
1018 (*nodeList)[nodeNo]->Insert((*pCandidates)[nVol]);
1019 }
1020 }
1021 }
1022
1023 // All nodes filled
1024
1025 // Create proxy List : caller has deletion responsibility
1026 // (but we must delete nodeList *itself* - not the contents)
1027 //
1028 G4ProxyVector* proxyList = new G4ProxyVector();
1029 if (!proxyList)
1030 {
1031 G4Exception("G4SmartVoxelHeader::BuildNodes()", "GeomMgt0003",
1032 FatalException, "Proxy list allocation error.");
1033 return 0;
1034 }
1035 proxyList->reserve(noNodes);
1036
1037 //
1038 // Fill proxy List
1039 //
1040 for (nNode=0; nNode<noNodes; nNode++)
1041 {
1042 // Get rid of possible excess capacity in the internal node vector
1043 //
1044 ((*nodeList)[nNode])->Shrink();
1045 G4SmartVoxelProxy* pProxyNode = new G4SmartVoxelProxy((*nodeList)[nNode]);
1046 if (!pProxyNode)
1047 {
1048 G4Exception("G4SmartVoxelHeader::BuildNodes()", "GeomMgt0003",
1049 FatalException, "Proxy node allocation failed.");
1050 return 0;
1051 }
1052 proxyList->push_back(pProxyNode);
1053 }
1054 delete nodeList;
1055 return proxyList;
1056}
std::vector< G4SmartVoxelProxy * > G4ProxyVector
std::vector< G4double > G4VolumeExtentVector
double G4double
Definition: G4Types.hh:64
bool G4bool
Definition: G4Types.hh:67
G4VSolid * GetSolid() const
G4String GetName() const
G4double GetSmartless() const
virtual G4VSolid * ComputeSolid(const G4int, G4VPhysicalVolume *)
virtual void ComputeTransformation(const G4int, G4VPhysicalVolume *) const =0
const G4RotationMatrix * GetRotation() const
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
virtual G4VPVParameterisation * GetParameterisation() const =0
const G4ThreeVector & GetTranslation() const
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
virtual void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
Definition: G4VSolid.cc:137
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const
G4bool IsLimited() const
const G4int kMaxVoxelNodes
Definition: voxeldefs.hh:43

Referenced by BuildReplicaVoxels(), and BuildVoxelsWithinLimits().

◆ BuildReplicaVoxels()

void G4SmartVoxelHeader::BuildReplicaVoxels ( G4LogicalVolume pVolume)
protected

Definition at line 267 of file G4SmartVoxelHeader.cc.

268{
269 G4VPhysicalVolume *pDaughter=0;
270
271 // Replication data
272 //
273 EAxis axis;
274 G4int nReplicas;
275 G4double width,offset;
276 G4bool consuming;
277
278 // Consistency check: pVolume should contain single replicated volume
279 //
280 if ( (pVolume->GetNoDaughters()==1)
281 && (pVolume->GetDaughter(0)->IsReplicated()==true) )
282 {
283 // Obtain replication data
284 //
285 pDaughter=pVolume->GetDaughter(0);
286 pDaughter->GetReplicationData(axis,nReplicas,width,offset,consuming);
287 fparamAxis = axis;
288 if ( consuming==false )
289 {
290 G4VoxelLimits limits; // Create `unlimited' limits object
291 G4VolumeNosVector targetList;
292 targetList.reserve(nReplicas);
293 for (G4int i=0; i<nReplicas; i++)
294 {
295 targetList.push_back(i);
296 }
297 if (axis != kUndefined)
298 {
299 // Apply voxelisation along the specified axis only
300
301 G4ProxyVector* pSlices=BuildNodes(pVolume,limits,&targetList,axis);
302 faxis = axis;
303 fslices = *pSlices;
304 delete pSlices;
305
306 // Calculate and set min and max extents given our axis
307 //
308 const G4AffineTransform origin;
309 pVolume->GetSolid()->CalculateExtent(faxis, limits, origin,
311 // Calculate equivalent nos
312 //
314 CollectEquivalentNodes(); // Collect common nodes
315 }
316 else
317 {
318 // Build voxels similarly as for normal placements considering
319 // all three cartesian axes.
320
321 BuildVoxelsWithinLimits(pVolume, limits, &targetList);
322 }
323 }
324 else
325 {
326 // Replication is consuming -> Build voxels directly
327 //
328 // o Cartesian axes - range is -width*nREplicas/2 to +width*nREplicas/2
329 // nReplicas replications result
330 // o Radial axis (rho) = range is 0 to width*nReplicas
331 // nReplicas replications result
332 // o Phi axi - range is offset to offset+width*nReplicas radians
333 //
334 // Equivalent slices no computation & collection not required - all
335 // slices are different
336 //
337 switch (axis)
338 {
339 case kXAxis:
340 case kYAxis:
341 case kZAxis:
342 fminExtent = -width*nReplicas*0.5;
343 fmaxExtent = width*nReplicas*0.5;
344 break;
345 case kRho:
346 fminExtent = offset;
347 fmaxExtent = width*nReplicas+offset;
348 break;
349 case kPhi:
350 fminExtent = offset;
351 fmaxExtent = offset+width*nReplicas;
352 break;
353 default:
354 G4Exception("G4SmartVoxelHeader::BuildReplicaVoxels()",
355 "GeomMgt0002", FatalException, "Illegal axis.");
356 break;
357 }
358 faxis = axis; // Set axis
359 BuildConsumedNodes(nReplicas);
360 if ( (axis==kXAxis) || (axis==kYAxis) || (axis==kZAxis) )
361 {
362 // Sanity check on extent
363 //
364 G4double emin = kInfinity, emax = -kInfinity;
365 G4VoxelLimits limits;
366 G4AffineTransform origin;
367 pVolume->GetSolid()->CalculateExtent(axis, limits, origin, emin, emax);
368 if ( (std::fabs((emin-fminExtent)/fminExtent) +
369 std::fabs((emax-fmaxExtent)/fmaxExtent)) > 0.05)
370 {
371 std::ostringstream message;
372 message << "Sanity check: wrong solid extent." << G4endl
373 << " Replicated geometry, logical volume: "
374 << pVolume->GetName();
375 G4Exception("G4SmartVoxelHeader::BuildReplicaVoxels",
376 "GeomMgt0002", FatalException, message);
377 }
378 }
379 }
380 }
381 else
382 {
383 G4Exception("G4SmartVoxelHeader::BuildReplicaVoxels", "GeomMgt0002",
384 FatalException, "Only one replicated daughter is allowed !");
385 }
386}
std::vector< G4int > G4VolumeNosVector
G4ProxyVector * BuildNodes(G4LogicalVolume *pVolume, G4VoxelLimits pLimits, const G4VolumeNosVector *pCandidates, EAxis pAxis)
void BuildConsumedNodes(G4int nReplicas)
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const =0
EAxis
Definition: geomdefs.hh:54
@ kPhi
Definition: geomdefs.hh:54
@ kYAxis
Definition: geomdefs.hh:54
@ kXAxis
Definition: geomdefs.hh:54
@ kZAxis
Definition: geomdefs.hh:54
@ kRho
Definition: geomdefs.hh:54

Referenced by G4SmartVoxelHeader().

◆ BuildVoxels()

void G4SmartVoxelHeader::BuildVoxels ( G4LogicalVolume pVolume)
protected

Definition at line 247 of file G4SmartVoxelHeader.cc.

248{
249 G4VoxelLimits limits; // Create `unlimited' limits object
250 G4int nDaughters = pVolume->GetNoDaughters();
251
252 G4VolumeNosVector targetList;
253 targetList.reserve(nDaughters);
254 for (G4int i=0; i<nDaughters; i++)
255 {
256 targetList.push_back(i);
257 }
258 BuildVoxelsWithinLimits(pVolume, limits, &targetList);
259}

Referenced by G4SmartVoxelHeader().

◆ BuildVoxelsWithinLimits()

void G4SmartVoxelHeader::BuildVoxelsWithinLimits ( G4LogicalVolume pVolume,
G4VoxelLimits  pLimits,
const G4VolumeNosVector pCandidates 
)
protected

Definition at line 443 of file G4SmartVoxelHeader.cc.

446{
447 // Choose best axis for slicing by:
448 // 1. Trying all unlimited cartesian axes
449 // 2. Select axis which gives greatest no slices
450
451 G4ProxyVector *pGoodSlices=0, *pTestSlices, *tmpSlices;
452 G4double goodSliceScore=kInfinity, testSliceScore;
453 EAxis goodSliceAxis = kXAxis;
454 EAxis testAxis = kXAxis;
455 G4int node, maxNode, iaxis;
456 G4VoxelLimits noLimits;
457
458 // Try all non-limited cartesian axes
459 //
460 for (iaxis=0; iaxis<3; iaxis++)
461 {
462 switch(iaxis)
463 {
464 case 0:
465 testAxis = kXAxis;
466 break;
467 case 1:
468 testAxis = kYAxis;
469 break;
470 case 2:
471 testAxis = kZAxis;
472 break;
473 }
474 if (!pLimits.IsLimited(testAxis))
475 {
476 pTestSlices = BuildNodes(pVolume,pLimits,pCandidates,testAxis);
477 testSliceScore = CalculateQuality(pTestSlices);
478 if ( (!pGoodSlices) || (testSliceScore<goodSliceScore) )
479 {
480 goodSliceAxis = testAxis;
481 goodSliceScore = testSliceScore;
482 tmpSlices = pGoodSlices;
483 pGoodSlices = pTestSlices;
484 pTestSlices = tmpSlices;
485 }
486 if (pTestSlices)
487 {
488 // Destroy pTestSlices and all its contents
489 //
490 maxNode=pTestSlices->size();
491 for (node=0; node<maxNode; node++)
492 {
493 delete (*pTestSlices)[node]->GetNode();
494 }
495 G4SmartVoxelProxy* tmpProx;
496 while (pTestSlices->size()>0)
497 {
498 tmpProx = pTestSlices->back();
499 pTestSlices->pop_back();
500 for (G4ProxyVector::iterator i=pTestSlices->begin();
501 i!=pTestSlices->end(); )
502 {
503 if (*i==tmpProx)
504 {
505 i = pTestSlices->erase(i);
506 }
507 else
508 {
509 ++i;
510 }
511 }
512 if ( tmpProx ) { delete tmpProx; }
513 }
514 delete pTestSlices;
515 }
516 }
517 }
518 // Check for error case.. when limits already 3d,
519 // so cannot select a new axis
520 //
521 if (!pGoodSlices)
522 {
523 G4Exception("G4SmartVoxelHeader::BuildVoxelsWithinLimits()",
524 "GeomMgt0002", FatalException,
525 "Cannot select more than 3 axis for optimisation.");
526 return;
527 }
528
529 //
530 // We have selected pGoodSlices, with a score testSliceScore
531 //
532
533 // Store chosen axis, slice ptr
534 //
535 fslices=*pGoodSlices; // Set slice information, copy ptrs in collection
536 delete pGoodSlices; // Destroy slices vector, but not contained
537 // proxies or nodes
538 faxis=goodSliceAxis;
539
540#ifdef G4GEOMETRY_VOXELDEBUG
541 G4cout << G4endl << " Volume = " << pVolume->GetName()
542 << G4endl << " Selected axis = " << faxis << G4endl;
543 for (size_t islice=0; islice<fslices.size(); islice++)
544 {
545 G4cout << " Node #" << islice << " = {";
546 for (G4int j=0; j<fslices[islice]->GetNode()->GetNoContained(); j++)
547 {
548 G4cout << " " << fslices[islice]->GetNode()->GetVolume(j);
549 }
550 G4cout << " }" << G4endl;
551 }
552 G4cout << G4endl;
553#endif
554
555 // Calculate and set min and max extents given our axis
556 //
557 G4VSolid* outerSolid = pVolume->GetSolid();
558 const G4AffineTransform origin;
559 if(!outerSolid->CalculateExtent(faxis,pLimits,origin,fminExtent,fmaxExtent))
560 {
561 outerSolid->CalculateExtent(faxis,noLimits,origin,fminExtent,fmaxExtent);
562 }
563
564 // Calculate equivalent nos
565 //
567 CollectEquivalentNodes(); // Collect common nodes
568 RefineNodes(pVolume,pLimits); // Refine nodes creating headers
569
570 // No common headers can exist because collapsed by construction
571}
G4double CalculateQuality(G4ProxyVector *pSlice)
void RefineNodes(G4LogicalVolume *pVolume, G4VoxelLimits pLimits)

Referenced by BuildReplicaVoxels(), BuildVoxels(), and G4SmartVoxelHeader().

◆ CalculateQuality()

G4double G4SmartVoxelHeader::CalculateQuality ( G4ProxyVector pSlice)
protected

Definition at line 1073 of file G4SmartVoxelHeader.cc.

1074{
1075 G4double quality;
1076 G4int nNodes = pSlice->size();
1077 G4int noContained, maxContained=0, sumContained=0, sumNonEmptyNodes=0;
1078 G4SmartVoxelNode *node;
1079
1080 for (G4int i=0; i<nNodes; i++)
1081 {
1082 if ((*pSlice)[i]->IsNode())
1083 {
1084 // Definitely a node. Add info to running totals
1085 //
1086 node = (*pSlice)[i]->GetNode();
1087 noContained = node->GetNoContained();
1088 if (noContained)
1089 {
1090 sumNonEmptyNodes++;
1091 sumContained += noContained;
1092 //
1093 // Calc maxContained for statistics
1094 //
1095 if (noContained>maxContained)
1096 {
1097 maxContained = noContained;
1098 }
1099 }
1100 }
1101 else
1102 {
1103 G4Exception("G4SmartVoxelHeader::CalculateQuality()", "GeomMgt0001",
1104 FatalException, "Not applicable to replicated volumes.");
1105 }
1106 }
1107
1108 // Calculate quality with protection against no non-empty nodes
1109 //
1110 if (sumNonEmptyNodes)
1111 {
1112 quality = sumContained/sumNonEmptyNodes;
1113 }
1114 else
1115 {
1116 quality = kInfinity;
1117 }
1118
1119#ifdef G4GEOMETRY_VOXELDEBUG
1120 G4cout << "**** G4SmartVoxelHeader::CalculateQuality" << G4endl
1121 << " Quality = " << quality << G4endl
1122 << " Nodes = " << nNodes
1123 << " of which " << sumNonEmptyNodes << " non empty" << G4endl
1124 << " Max Contained = " << maxContained << G4endl;
1125#endif
1126
1127 return quality;
1128}
G4int GetNoContained() const

Referenced by BuildVoxelsWithinLimits().

◆ CollectEquivalentHeaders()

void G4SmartVoxelHeader::CollectEquivalentHeaders ( )
protected

Definition at line 677 of file G4SmartVoxelHeader.cc.

678{
679 G4int sliceNo, maxNo, equivNo;
680 G4int maxNode = fslices.size();
681 G4SmartVoxelHeader *equivHeader, *sampleHeader;
682 G4SmartVoxelProxy *equivProxy;
683
684 for (sliceNo=0; sliceNo<maxNode; sliceNo++)
685 {
686 equivProxy = fslices[sliceNo];
687 if (equivProxy->IsHeader())
688 {
689 equivHeader = equivProxy->GetHeader();
690 maxNo = equivHeader->GetMaxEquivalentSliceNo();
691 if (maxNo != sliceNo)
692 {
693 // Attempt collection between sliceNo and maxNo inclusive:
694 // look for common headers. All slices between sliceNo and maxNo
695 // are guaranteed to be headers but may not have equal contents
696 //
697#ifdef G4GEOMETRY_VOXELDEBUG
698 G4cout << "**** G4SmartVoxelHeader::CollectEquivalentHeaders" << G4endl
699 << " Collecting Headers =";
700#endif
701 for (equivNo=sliceNo+1; equivNo<=maxNo; equivNo++)
702 {
703 sampleHeader = fslices[equivNo]->GetHeader();
704 if ( (*sampleHeader) == (*equivHeader) )
705 {
706#ifdef G4GEOMETRY_VOXELDEBUG
707 G4cout << " " << equivNo;
708#endif
709 // Delete sampleHeader + proxy and replace with equivHeader/Proxy
710 //
711 delete sampleHeader;
712 delete fslices[equivNo];
713 fslices[equivNo] = equivProxy;
714 }
715 else
716 {
717 // Not equal. Set this header to be
718 // the current header for comparisons
719 //
720 equivProxy = fslices[equivNo];
721 equivHeader = equivProxy->GetHeader();
722 }
723
724 }
725#ifdef G4GEOMETRY_VOXELDEBUG
726 G4cout << G4endl;
727#endif
728 // Skip past examined slices
729 //
730 sliceNo = maxNo;
731 }
732 }
733 }
734}
G4int GetMaxEquivalentSliceNo() const
G4SmartVoxelHeader * GetHeader() const
G4bool IsHeader() const

◆ CollectEquivalentNodes()

void G4SmartVoxelHeader::CollectEquivalentNodes ( )
protected

Definition at line 630 of file G4SmartVoxelHeader.cc.

631{
632 G4int sliceNo, maxNo, equivNo;
633 G4int maxNode=fslices.size();
634 G4SmartVoxelNode *equivNode;
635 G4SmartVoxelProxy *equivProxy;
636
637 for (sliceNo=0; sliceNo<maxNode; sliceNo++)
638 {
639 equivProxy=fslices[sliceNo];
640
641 // Assumption (see preconditions): all slices are nodes
642 //
643 equivNode = equivProxy->GetNode();
644 maxNo = equivNode->GetMaxEquivalentSliceNo();
645 if (maxNo != sliceNo)
646 {
647#ifdef G4GEOMETRY_VOXELDEBUG
648 G4cout << "**** G4SmartVoxelHeader::CollectEquivalentNodes" << G4endl
649 << " Collecting Nodes = "
650 << sliceNo << " - " << maxNo << G4endl;
651#endif
652 // Do collection between sliceNo and maxNo inclusive
653 //
654 for (equivNo=sliceNo+1; equivNo<=maxNo; equivNo++)
655 {
656 delete fslices[equivNo]->GetNode();
657 delete fslices[equivNo];
658 fslices[equivNo] = equivProxy;
659 }
660 sliceNo = maxNo;
661 }
662 }
663}
G4int GetMaxEquivalentSliceNo() const
G4SmartVoxelNode * GetNode() const

Referenced by BuildReplicaVoxels(), and BuildVoxelsWithinLimits().

◆ GetAxis()

EAxis G4SmartVoxelHeader::GetAxis ( ) const

◆ GetMaxEquivalentSliceNo()

G4int G4SmartVoxelHeader::GetMaxEquivalentSliceNo ( ) const

◆ GetMaxExtent()

G4double G4SmartVoxelHeader::GetMaxExtent ( ) const

◆ GetMinEquivalentSliceNo()

G4int G4SmartVoxelHeader::GetMinEquivalentSliceNo ( ) const

◆ GetMinExtent()

◆ GetNoSlices()

G4int G4SmartVoxelHeader::GetNoSlices ( ) const

◆ GetParamAxis()

EAxis G4SmartVoxelHeader::GetParamAxis ( ) const

◆ GetSlice()

◆ operator==()

G4bool G4SmartVoxelHeader::operator== ( const G4SmartVoxelHeader pHead) const

Definition at line 183 of file G4SmartVoxelHeader.cc.

184{
185 if ( (GetAxis() == pHead.GetAxis())
186 && (GetNoSlices() == pHead.GetNoSlices())
187 && (GetMinExtent() == pHead.GetMinExtent())
188 && (GetMaxExtent() == pHead.GetMaxExtent()) )
189 {
190 G4int node, maxNode;
191 G4SmartVoxelProxy *leftProxy, *rightProxy;
192 G4SmartVoxelHeader *leftHeader, *rightHeader;
193 G4SmartVoxelNode *leftNode, *rightNode;
194
195 maxNode=GetNoSlices();
196 for (node=0; node<maxNode; node++)
197 {
198 leftProxy = GetSlice(node);
199 rightProxy = pHead.GetSlice(node);
200 if (leftProxy->IsHeader())
201 {
202 if (rightProxy->IsNode())
203 {
204 return false;
205 }
206 else
207 {
208 leftHeader = leftProxy->GetHeader();
209 rightHeader = rightProxy->GetHeader();
210 if (!(*leftHeader==*rightHeader))
211 {
212 return false;
213 }
214 }
215 }
216 else
217 {
218 if (rightProxy->IsHeader())
219 {
220 return false;
221 }
222 else
223 {
224 leftNode = leftProxy->GetNode();
225 rightNode = rightProxy->GetNode();
226 if (!(*leftNode==*rightNode))
227 {
228 return false;
229 }
230 }
231 }
232 }
233 return true;
234 }
235 else
236 {
237 return false;
238 }
239}
G4double GetMaxExtent() const
G4double GetMinExtent() const
EAxis GetAxis() const
G4SmartVoxelProxy * GetSlice(G4int n) const
G4int GetNoSlices() const
G4bool IsNode() const

◆ RefineNodes()

void G4SmartVoxelHeader::RefineNodes ( G4LogicalVolume pVolume,
G4VoxelLimits  pLimits 
)
protected

Definition at line 1139 of file G4SmartVoxelHeader.cc.

1141{
1142 G4int refinedDepth=0, minVolumes;
1143 G4int maxNode = fslices.size();
1144
1145 if (pLimits.IsXLimited())
1146 {
1147 refinedDepth++;
1148 }
1149 if (pLimits.IsYLimited())
1150 {
1151 refinedDepth++;
1152 }
1153 if (pLimits.IsZLimited())
1154 {
1155 refinedDepth++;
1156 }
1157
1158 // Calculate minimum number of volumes necessary to refine
1159 //
1160 switch (refinedDepth)
1161 {
1162 case 0:
1163 minVolumes=kMinVoxelVolumesLevel2;
1164 break;
1165 case 1:
1166 minVolumes=kMinVoxelVolumesLevel3;
1167 break;
1168 default:
1169 minVolumes=10000; // catch refinedDepth=3 and errors
1170 break;
1171 }
1172
1173 if (refinedDepth<2)
1174 {
1175 G4int targetNo, noContainedDaughters, minNo, maxNo, replaceNo, i;
1176 G4double sliceWidth = (fmaxExtent-fminExtent)/maxNode;
1177 G4VoxelLimits newLimits;
1178 G4SmartVoxelNode* targetNode;
1179 G4SmartVoxelProxy* targetNodeProxy;
1180 G4SmartVoxelHeader* replaceHeader;
1181 G4SmartVoxelProxy* replaceHeaderProxy;
1182 G4VolumeNosVector* targetList;
1183 G4SmartVoxelProxy* lastProxy;
1184
1185 for (targetNo=0; targetNo<maxNode; targetNo++)
1186 {
1187 // Assume all slices are nodes (see preconditions)
1188 //
1189 targetNodeProxy = fslices[targetNo];
1190 targetNode = targetNodeProxy->GetNode();
1191
1192 if (targetNode->GetNoContained() >= minVolumes)
1193 {
1194 noContainedDaughters = targetNode->GetNoContained();
1195 targetList = new G4VolumeNosVector();
1196 if (!targetList)
1197 {
1198 G4Exception("G4SmartVoxelHeader::RefineNodes()",
1199 "GeomMgt0003", FatalException,
1200 "Target volume node list allocation error.");
1201 return;
1202 }
1203 targetList->reserve(noContainedDaughters);
1204 for (i=0; i<noContainedDaughters; i++)
1205 {
1206 targetList->push_back(targetNode->GetVolume(i));
1207 }
1208 minNo = targetNode->GetMinEquivalentSliceNo();
1209 maxNo = targetNode->GetMaxEquivalentSliceNo();
1210
1211#ifdef G4GEOMETRY_VOXELDEBUG
1212 G4cout << "**** G4SmartVoxelHeader::RefineNodes" << G4endl
1213 << " Refining nodes " << minNo
1214 << " - " << maxNo << " inclusive" << G4endl;
1215#endif
1216 if (minNo > maxNo) // Delete node and list to be replaced
1217 { // and avoid further action ...
1218 delete targetNode;
1219 delete targetList;
1220 return;
1221 }
1222
1223 // Delete node proxies at start of collected sets of nodes/headers
1224 //
1225 lastProxy=0;
1226 for (replaceNo=minNo; replaceNo<=maxNo; replaceNo++)
1227 {
1228 if (lastProxy != fslices[replaceNo])
1229 {
1230 lastProxy=fslices[replaceNo];
1231 delete lastProxy;
1232 }
1233 }
1234 // Delete node to be replaced
1235 //
1236 delete targetNode;
1237
1238 // Create new headers + proxies and replace in fslices
1239 //
1240 newLimits = pLimits;
1241 newLimits.AddLimit(faxis,fminExtent+sliceWidth*minNo,
1242 fminExtent+sliceWidth*(maxNo+1));
1243 replaceHeader = new G4SmartVoxelHeader(pVolume,newLimits,
1244 targetList,replaceNo);
1245 if (!replaceHeader)
1246 {
1247 G4Exception("G4SmartVoxelHeader::RefineNodes()", "GeomMgt0003",
1248 FatalException, "Refined VoxelHeader allocation error.");
1249 return;
1250 }
1251 replaceHeader->SetMinEquivalentSliceNo(minNo);
1252 replaceHeader->SetMaxEquivalentSliceNo(maxNo);
1253 replaceHeaderProxy = new G4SmartVoxelProxy(replaceHeader);
1254 if (!replaceHeaderProxy)
1255 {
1256 G4Exception("G4SmartVoxelHeader::RefineNodes()", "GeomMgt0003",
1257 FatalException, "Refined VoxelProxy allocation error.");
1258 return;
1259 }
1260 for (replaceNo=minNo; replaceNo<=maxNo; replaceNo++)
1261 {
1262 fslices[replaceNo] = replaceHeaderProxy;
1263 }
1264 // Finished replacing current `equivalent' group
1265 //
1266 delete targetList;
1267 targetNo=maxNo;
1268 }
1269 }
1270 }
1271}
void SetMinEquivalentSliceNo(G4int pMin)
void SetMaxEquivalentSliceNo(G4int pMax)
G4int GetVolume(G4int pVolumeNo) const
G4int GetMinEquivalentSliceNo() const
G4bool IsYLimited() const
void AddLimit(const EAxis pAxis, const G4double pMin, const G4double pMax)
G4bool IsXLimited() const
G4bool IsZLimited() const
const G4int kMinVoxelVolumesLevel3
Definition: voxeldefs.hh:50
const G4int kMinVoxelVolumesLevel2
Definition: voxeldefs.hh:47

Referenced by BuildVoxelsWithinLimits().

◆ SetMaxEquivalentSliceNo()

void G4SmartVoxelHeader::SetMaxEquivalentSliceNo ( G4int  pMax)

Referenced by RefineNodes().

◆ SetMinEquivalentSliceNo()

void G4SmartVoxelHeader::SetMinEquivalentSliceNo ( G4int  pMin)

Referenced by RefineNodes().

Friends And Related Function Documentation

◆ operator<<

std::ostream & operator<< ( std::ostream &  s,
const G4SmartVoxelHeader h 
)
friend

Definition at line 1304 of file G4SmartVoxelHeader.cc.

1305{
1306 os << "Axis = " << G4int(h.faxis) << G4endl;
1307 G4SmartVoxelProxy *collectNode=0, *collectHead=0;
1308 G4int collectNodeNo=0;
1309 G4int collectHeadNo=0;
1310 size_t i, j;
1311 G4bool haveHeaders=false;
1312
1313 for (i=0; i<h.fslices.size(); i++)
1314 {
1315 os << "Slice #" << i << " = ";
1316 if (h.fslices[i]->IsNode())
1317 {
1318 if (h.fslices[i]!=collectNode)
1319 {
1320 os << "{";
1321 for (G4int k=0; k<h.fslices[i]->GetNode()->GetNoContained(); k++)
1322 {
1323 os << " " << h.fslices[i]->GetNode()->GetVolume(k);
1324 }
1325 os << " }" << G4endl;
1326 collectNode = h.fslices[i];
1327 collectNodeNo = i;
1328 }
1329 else
1330 {
1331 os << "As slice #" << collectNodeNo << G4endl;
1332 }
1333 }
1334 else
1335 {
1336 haveHeaders=true;
1337 if (h.fslices[i] != collectHead)
1338 {
1339 os << "Header" << G4endl;
1340 collectHead = h.fslices[i];
1341 collectHeadNo = i;
1342 }
1343 else
1344 {
1345 os << "As slice #" << collectHeadNo << G4endl;
1346 }
1347 }
1348 }
1349
1350 if (haveHeaders)
1351 {
1352 collectHead=0;
1353 for (j=0; j<h.fslices.size(); j++)
1354 {
1355 if (h.fslices[j]->IsHeader())
1356 {
1357 os << "Header at Slice #" << j << " = ";
1358 if (h.fslices[j] != collectHead)
1359 {
1360 os << G4endl
1361 << (*(h.fslices[j]->GetHeader()));
1362 collectHead = h.fslices[j];
1363 collectHeadNo = j;
1364 }
1365 else
1366 {
1367 os << "As slice #" << collectHeadNo << G4endl;
1368 }
1369 }
1370 }
1371 }
1372 return os;
1373}

Member Data Documentation

◆ faxis

EAxis G4SmartVoxelHeader::faxis
protected

Definition at line 191 of file G4SmartVoxelHeader.hh.

Referenced by BuildReplicaVoxels(), BuildVoxelsWithinLimits(), and RefineNodes().

◆ fmaxEquivalent

G4int G4SmartVoxelHeader::fmaxEquivalent
protected

Definition at line 188 of file G4SmartVoxelHeader.hh.

◆ fmaxExtent

G4double G4SmartVoxelHeader::fmaxExtent
protected

Definition at line 194 of file G4SmartVoxelHeader.hh.

Referenced by BuildReplicaVoxels(), BuildVoxelsWithinLimits(), and RefineNodes().

◆ fminEquivalent

G4int G4SmartVoxelHeader::fminEquivalent
protected

Definition at line 187 of file G4SmartVoxelHeader.hh.

◆ fminExtent

G4double G4SmartVoxelHeader::fminExtent
protected

Definition at line 195 of file G4SmartVoxelHeader.hh.

Referenced by BuildReplicaVoxels(), BuildVoxelsWithinLimits(), and RefineNodes().

◆ fparamAxis

EAxis G4SmartVoxelHeader::fparamAxis
protected

Definition at line 191 of file G4SmartVoxelHeader.hh.

Referenced by BuildReplicaVoxels().

◆ fslices


The documentation for this class was generated from the following files: