Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Protected Member Functions | Protected Attributes | Friends
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::G4SmartVoxelHeader ( G4LogicalVolume pVolume,
G4int  pSlice = 0 
)

Definition at line 66 of file G4SmartVoxelHeader.cc.

References BuildReplicaVoxels(), BuildVoxels(), G4LogicalVolume::GetDaughter(), G4LogicalVolume::GetNoDaughters(), and G4VPhysicalVolume::IsReplicated().

Referenced by RefineNodes().

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 }
virtual G4bool IsReplicated() const =0
G4VPhysicalVolume * GetDaughter(const G4int i) const
int G4int
Definition: G4Types.hh:78
G4int GetNoDaughters() const
void BuildReplicaVoxels(G4LogicalVolume *pVolume)
void BuildVoxels(G4LogicalVolume *pVolume)
G4SmartVoxelHeader::~G4SmartVoxelHeader ( )

Definition at line 127 of file G4SmartVoxelHeader.cc.

References fslices.

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 }
int G4int
Definition: G4Types.hh:78
G4SmartVoxelHeader::G4SmartVoxelHeader ( G4LogicalVolume pVolume,
const G4VoxelLimits pLimits,
const G4VolumeNosVector pCandidates,
G4int  pSlice = 0 
)
protected

Definition at line 100 of file G4SmartVoxelHeader.cc.

References BuildVoxelsWithinLimits(), G4cout, and G4endl.

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 }
void BuildVoxelsWithinLimits(G4LogicalVolume *pVolume, G4VoxelLimits pLimits, const G4VolumeNosVector *pCandidates)
G4GLOB_DLL std::ostream G4cout
#define G4endl
Definition: G4ios.hh:61

Member Function Documentation

G4bool G4SmartVoxelHeader::AllSlicesEqual ( ) const

Definition at line 1281 of file G4SmartVoxelHeader.cc.

References fslices.

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 }
int G4int
Definition: G4Types.hh:78
void G4SmartVoxelHeader::BuildConsumedNodes ( G4int  nReplicas)
protected

Definition at line 395 of file G4SmartVoxelHeader.cc.

References FatalException, fslices, and G4Exception().

Referenced by BuildReplicaVoxels().

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 }
int G4int
Definition: G4Types.hh:78
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
std::vector< G4SmartVoxelNode * > G4NodeVector
void G4SmartVoxelHeader::BuildEquivalentSliceNos ( )
protected

Definition at line 583 of file G4SmartVoxelHeader.cc.

References fslices, G4SmartVoxelNode::SetMaxEquivalentSliceNo(), and G4SmartVoxelNode::SetMinEquivalentSliceNo().

Referenced by BuildReplicaVoxels(), and BuildVoxelsWithinLimits().

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 }
int G4int
Definition: G4Types.hh:78
void SetMinEquivalentSliceNo(G4int pMin)
void SetMaxEquivalentSliceNo(G4int pMax)
G4ProxyVector * G4SmartVoxelHeader::BuildNodes ( G4LogicalVolume pVolume,
G4VoxelLimits  pLimits,
const G4VolumeNosVector pCandidates,
EAxis  pAxis 
)
protected

Definition at line 750 of file G4SmartVoxelHeader.cc.

References G4VSolid::CalculateExtent(), G4VSolid::ComputeDimensions(), G4VPVParameterisation::ComputeSolid(), G4VPVParameterisation::ComputeTransformation(), FatalException, G4cout, G4endl, G4Exception(), G4LogicalVolume::GetDaughter(), G4VPhysicalVolume::GetLogicalVolume(), G4VoxelLimits::GetMaxExtent(), G4VoxelLimits::GetMinExtent(), G4VPhysicalVolume::GetName(), G4LogicalVolume::GetName(), G4LogicalVolume::GetNoDaughters(), G4VPhysicalVolume::GetParameterisation(), G4VPhysicalVolume::GetRotation(), G4LogicalVolume::GetSmartless(), G4LogicalVolume::GetSolid(), G4VPhysicalVolume::GetTranslation(), G4VoxelLimits::IsLimited(), G4VPhysicalVolume::IsReplicated(), kMaxVoxelNodes, and width.

Referenced by BuildReplicaVoxels(), and BuildVoxelsWithinLimits().

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 }
G4double GetSmartless() const
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
const G4ThreeVector & GetTranslation() const
G4String GetName() const
virtual G4bool IsReplicated() const =0
virtual G4VSolid * ComputeSolid(const G4int, G4VPhysicalVolume *)
G4VPhysicalVolume * GetDaughter(const G4int i) const
const G4int kMaxVoxelNodes
Definition: voxeldefs.hh:43
#define width
int G4int
Definition: G4Types.hh:78
G4GLOB_DLL std::ostream G4cout
G4bool IsLimited() const
const G4String & GetName() const
bool G4bool
Definition: G4Types.hh:79
virtual G4VPVParameterisation * GetParameterisation() const =0
std::vector< G4double > G4VolumeExtentVector
G4int GetNoDaughters() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
std::vector< G4SmartVoxelProxy * > G4ProxyVector
G4LogicalVolume * GetLogicalVolume() const
virtual void ComputeTransformation(const G4int, G4VPhysicalVolume *) const =0
const G4RotationMatrix * GetRotation() const
#define G4endl
Definition: G4ios.hh:61
std::vector< G4SmartVoxelNode * > G4NodeVector
double G4double
Definition: G4Types.hh:76
G4double GetMaxExtent(const EAxis pAxis) const
G4double GetMinExtent(const EAxis pAxis) const
G4VSolid * GetSolid() const
void G4SmartVoxelHeader::BuildReplicaVoxels ( G4LogicalVolume pVolume)
protected

Definition at line 267 of file G4SmartVoxelHeader.cc.

References BuildConsumedNodes(), BuildEquivalentSliceNos(), BuildNodes(), BuildVoxelsWithinLimits(), G4VSolid::CalculateExtent(), CollectEquivalentNodes(), FatalException, faxis, fmaxExtent, fminExtent, fparamAxis, fslices, G4endl, G4Exception(), G4LogicalVolume::GetDaughter(), G4LogicalVolume::GetName(), G4LogicalVolume::GetNoDaughters(), G4VPhysicalVolume::GetReplicationData(), G4LogicalVolume::GetSolid(), G4VPhysicalVolume::IsReplicated(), kPhi, kRho, kUndefined, kXAxis, kYAxis, kZAxis, and width.

Referenced by G4SmartVoxelHeader().

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 }
Definition: geomdefs.hh:54
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
void BuildVoxelsWithinLimits(G4LogicalVolume *pVolume, G4VoxelLimits pLimits, const G4VolumeNosVector *pCandidates)
std::vector< G4int > G4VolumeNosVector
G4String GetName() const
virtual G4bool IsReplicated() const =0
void BuildConsumedNodes(G4int nReplicas)
G4VPhysicalVolume * GetDaughter(const G4int i) const
#define width
int G4int
Definition: G4Types.hh:78
bool G4bool
Definition: G4Types.hh:79
G4int GetNoDaughters() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
std::vector< G4SmartVoxelProxy * > G4ProxyVector
EAxis
Definition: geomdefs.hh:54
G4ProxyVector * BuildNodes(G4LogicalVolume *pVolume, G4VoxelLimits pLimits, const G4VolumeNosVector *pCandidates, EAxis pAxis)
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const =0
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
Definition: geomdefs.hh:54
G4VSolid * GetSolid() const
void G4SmartVoxelHeader::BuildVoxels ( G4LogicalVolume pVolume)
protected

Definition at line 247 of file G4SmartVoxelHeader.cc.

References BuildVoxelsWithinLimits(), and G4LogicalVolume::GetNoDaughters().

Referenced by G4SmartVoxelHeader().

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 }
void BuildVoxelsWithinLimits(G4LogicalVolume *pVolume, G4VoxelLimits pLimits, const G4VolumeNosVector *pCandidates)
std::vector< G4int > G4VolumeNosVector
int G4int
Definition: G4Types.hh:78
G4int GetNoDaughters() const
void G4SmartVoxelHeader::BuildVoxelsWithinLimits ( G4LogicalVolume pVolume,
G4VoxelLimits  pLimits,
const G4VolumeNosVector pCandidates 
)
protected

Definition at line 443 of file G4SmartVoxelHeader.cc.

References BuildEquivalentSliceNos(), BuildNodes(), G4VSolid::CalculateExtent(), CalculateQuality(), CollectEquivalentNodes(), FatalException, faxis, fmaxExtent, fminExtent, fslices, G4cout, G4endl, G4Exception(), G4LogicalVolume::GetName(), G4LogicalVolume::GetSolid(), G4VoxelLimits::IsLimited(), kXAxis, kYAxis, kZAxis, and RefineNodes().

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

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 }
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
G4String GetName() const
G4double CalculateQuality(G4ProxyVector *pSlice)
int G4int
Definition: G4Types.hh:78
G4GLOB_DLL std::ostream G4cout
G4bool IsLimited() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
std::vector< G4SmartVoxelProxy * > G4ProxyVector
EAxis
Definition: geomdefs.hh:54
G4ProxyVector * BuildNodes(G4LogicalVolume *pVolume, G4VoxelLimits pLimits, const G4VolumeNosVector *pCandidates, EAxis pAxis)
#define G4endl
Definition: G4ios.hh:61
void RefineNodes(G4LogicalVolume *pVolume, G4VoxelLimits pLimits)
double G4double
Definition: G4Types.hh:76
G4VSolid * GetSolid() const
G4double G4SmartVoxelHeader::CalculateQuality ( G4ProxyVector pSlice)
protected

Definition at line 1073 of file G4SmartVoxelHeader.cc.

References FatalException, G4cout, G4endl, G4Exception(), and G4SmartVoxelNode::GetNoContained().

Referenced by BuildVoxelsWithinLimits().

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 }
int G4int
Definition: G4Types.hh:78
G4int GetNoContained() const
G4GLOB_DLL std::ostream G4cout
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
void G4SmartVoxelHeader::CollectEquivalentHeaders ( )
protected

Definition at line 677 of file G4SmartVoxelHeader.cc.

References fslices, G4cout, G4endl, G4SmartVoxelProxy::GetHeader(), GetMaxEquivalentSliceNo(), and G4SmartVoxelProxy::IsHeader().

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 }
G4SmartVoxelHeader * GetHeader() const
G4int GetMaxEquivalentSliceNo() const
int G4int
Definition: G4Types.hh:78
G4GLOB_DLL std::ostream G4cout
#define G4endl
Definition: G4ios.hh:61
G4bool IsHeader() const
void G4SmartVoxelHeader::CollectEquivalentNodes ( )
protected

Definition at line 630 of file G4SmartVoxelHeader.cc.

References fslices, G4cout, G4endl, G4SmartVoxelNode::GetMaxEquivalentSliceNo(), and G4SmartVoxelProxy::GetNode().

Referenced by BuildReplicaVoxels(), and BuildVoxelsWithinLimits().

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 }
int G4int
Definition: G4Types.hh:78
G4int GetMaxEquivalentSliceNo() const
G4GLOB_DLL std::ostream G4cout
G4SmartVoxelNode * GetNode() const
#define G4endl
Definition: G4ios.hh:61
EAxis G4SmartVoxelHeader::GetAxis ( ) const
G4int G4SmartVoxelHeader::GetMaxEquivalentSliceNo ( ) const
G4double G4SmartVoxelHeader::GetMaxExtent ( ) const
G4int G4SmartVoxelHeader::GetMinEquivalentSliceNo ( ) const
G4double G4SmartVoxelHeader::GetMinExtent ( ) const
G4int G4SmartVoxelHeader::GetNoSlices ( ) const
EAxis G4SmartVoxelHeader::GetParamAxis ( ) const
G4SmartVoxelProxy* G4SmartVoxelHeader::GetSlice ( G4int  n) const
G4bool G4SmartVoxelHeader::operator== ( const G4SmartVoxelHeader pHead) const

Definition at line 183 of file G4SmartVoxelHeader.cc.

References GetAxis(), G4SmartVoxelProxy::GetHeader(), GetMaxExtent(), GetMinExtent(), G4SmartVoxelProxy::GetNode(), GetNoSlices(), GetSlice(), G4SmartVoxelProxy::IsHeader(), and G4SmartVoxelProxy::IsNode().

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 }
G4SmartVoxelHeader * GetHeader() const
int G4int
Definition: G4Types.hh:78
G4bool IsNode() const
EAxis GetAxis() const
G4double GetMinExtent() const
G4int GetNoSlices() const
G4double GetMaxExtent() const
G4SmartVoxelNode * GetNode() const
G4bool IsHeader() const
G4SmartVoxelProxy * GetSlice(G4int n) const
void G4SmartVoxelHeader::RefineNodes ( G4LogicalVolume pVolume,
G4VoxelLimits  pLimits 
)
protected

Definition at line 1139 of file G4SmartVoxelHeader.cc.

References G4VoxelLimits::AddLimit(), FatalException, faxis, fmaxExtent, fminExtent, fslices, G4cout, G4endl, G4Exception(), G4SmartVoxelHeader(), G4SmartVoxelNode::GetMaxEquivalentSliceNo(), G4SmartVoxelNode::GetMinEquivalentSliceNo(), G4SmartVoxelNode::GetNoContained(), G4SmartVoxelProxy::GetNode(), G4SmartVoxelNode::GetVolume(), G4VoxelLimits::IsXLimited(), G4VoxelLimits::IsYLimited(), G4VoxelLimits::IsZLimited(), kMinVoxelVolumesLevel2, kMinVoxelVolumesLevel3, SetMaxEquivalentSliceNo(), and SetMinEquivalentSliceNo().

Referenced by BuildVoxelsWithinLimits().

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 }
G4int GetMinEquivalentSliceNo() const
std::vector< G4int > G4VolumeNosVector
G4int GetVolume(G4int pVolumeNo) const
G4bool IsYLimited() const
G4bool IsXLimited() const
int G4int
Definition: G4Types.hh:78
G4int GetNoContained() const
G4int GetMaxEquivalentSliceNo() const
void AddLimit(const EAxis pAxis, const G4double pMin, const G4double pMax)
G4GLOB_DLL std::ostream G4cout
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4SmartVoxelNode * GetNode() const
G4SmartVoxelHeader(G4LogicalVolume *pVolume, G4int pSlice=0)
const G4int kMinVoxelVolumesLevel3
Definition: voxeldefs.hh:50
const G4int kMinVoxelVolumesLevel2
Definition: voxeldefs.hh:47
#define G4endl
Definition: G4ios.hh:61
void SetMinEquivalentSliceNo(G4int pMin)
double G4double
Definition: G4Types.hh:76
G4bool IsZLimited() const
void SetMaxEquivalentSliceNo(G4int pMax)
void G4SmartVoxelHeader::SetMaxEquivalentSliceNo ( G4int  pMax)

Referenced by RefineNodes().

void G4SmartVoxelHeader::SetMinEquivalentSliceNo ( G4int  pMin)

Referenced by RefineNodes().

Friends And Related Function Documentation

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 }
int G4int
Definition: G4Types.hh:78
bool G4bool
Definition: G4Types.hh:79
#define G4endl
Definition: G4ios.hh:61

Field Documentation

EAxis G4SmartVoxelHeader::faxis
protected
G4int G4SmartVoxelHeader::fmaxEquivalent
protected

Definition at line 188 of file G4SmartVoxelHeader.hh.

G4double G4SmartVoxelHeader::fmaxExtent
protected

Definition at line 194 of file G4SmartVoxelHeader.hh.

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

G4int G4SmartVoxelHeader::fminEquivalent
protected

Definition at line 187 of file G4SmartVoxelHeader.hh.

G4double G4SmartVoxelHeader::fminExtent
protected

Definition at line 195 of file G4SmartVoxelHeader.hh.

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

EAxis G4SmartVoxelHeader::fparamAxis
protected

Definition at line 191 of file G4SmartVoxelHeader.hh.

Referenced by BuildReplicaVoxels().

G4ProxyVector G4SmartVoxelHeader::fslices
protected

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