68 : fminEquivalent(pSlice),
69 fmaxEquivalent(pSlice),
104 : fminEquivalent(pSlice),
105 fmaxEquivalent(pSlice),
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++)
114 G4cout << (*pCandidates)[i] <<
" ";
137 for (node=0; node<maxNode; node++)
141 dyingHeader =
fslices[node]->GetHeader();
142 if (lastHeader!=dyingHeader)
144 lastHeader = dyingHeader;
151 dyingNode =
fslices[node]->GetNode();
152 if (dyingNode!=lastNode)
162 for (proxy=0; proxy<maxNode; proxy++)
196 for (node=0; node<maxNode; node++)
210 if (!(*leftHeader==*rightHeader))
224 leftNode = leftProxy->
GetNode();
225 rightNode = rightProxy->
GetNode();
226 if (!(*leftNode==*rightNode))
253 targetList.reserve(nDaughters);
254 for (
G4int i=0; i<nDaughters; i++)
256 targetList.push_back(i);
288 if ( consuming==
false )
292 targetList.reserve(nReplicas);
293 for (
G4int i=0; i<nReplicas; i++)
295 targetList.push_back(i);
354 G4Exception(
"G4SmartVoxelHeader::BuildReplicaVoxels()",
371 std::ostringstream message;
372 message <<
"Sanity check: wrong solid extent." <<
G4endl
373 <<
" Replicated geometry, logical volume: "
375 G4Exception(
"G4SmartVoxelHeader::BuildReplicaVoxels",
383 G4Exception(
"G4SmartVoxelHeader::BuildReplicaVoxels",
"GeomMgt0002",
404 nodeList.reserve(nReplicas);
405 for (nNode=0; nNode<nReplicas; nNode++)
410 G4Exception(
"G4SmartVoxelHeader::BuildConsumedNodes()",
"GeomMgt0003",
413 nodeList.push_back(pNode);
415 for (nVol=0; nVol<nReplicas; nVol++)
417 nodeList[nVol]->Insert(nVol);
423 for (nNode=0; nNode<nReplicas; nNode++)
428 G4Exception(
"G4SmartVoxelHeader::BuildConsumedNodes()",
"GeomMgt0003",
455 G4int node, maxNode, iaxis;
460 for (iaxis=0; iaxis<3; iaxis++)
476 pTestSlices =
BuildNodes(pVolume,pLimits,pCandidates,testAxis);
478 if ( (!pGoodSlices) || (testSliceScore<goodSliceScore) )
480 goodSliceAxis = testAxis;
481 goodSliceScore = testSliceScore;
482 tmpSlices = pGoodSlices;
483 pGoodSlices = pTestSlices;
484 pTestSlices = tmpSlices;
490 maxNode=pTestSlices->size();
491 for (node=0; node<maxNode; node++)
493 delete (*pTestSlices)[node]->GetNode();
496 while (pTestSlices->size()>0)
498 tmpProx = pTestSlices->back();
499 pTestSlices->pop_back();
500 for (G4ProxyVector::iterator i=pTestSlices->begin();
501 i!=pTestSlices->end(); )
505 i = pTestSlices->erase(i);
512 if ( tmpProx ) {
delete tmpProx; }
523 G4Exception(
"G4SmartVoxelHeader::BuildVoxelsWithinLimits()",
525 "Cannot select more than 3 axis for optimisation.");
540 #ifdef G4GEOMETRY_VOXELDEBUG
543 for (
size_t islice=0; islice<
fslices.size(); islice++)
545 G4cout <<
" Node #" << islice <<
" = {";
546 for (
G4int j=0; j<
fslices[islice]->GetNode()->GetNoContained(); j++)
585 G4int sliceNo, minNo, maxNo, equivNo;
588 for (sliceNo=0; sliceNo<maxNode; sliceNo++)
594 startNode =
fslices[minNo]->GetNode();
598 for (equivNo=minNo+1; equivNo<maxNode; equivNo++)
600 sampleNode =
fslices[equivNo]->GetNode();
601 if (!((*startNode) == (*sampleNode))) {
break; }
608 for (equivNo=minNo; equivNo<=maxNo; equivNo++)
610 sampleNode =
fslices[equivNo]->GetNode();
632 G4int sliceNo, maxNo, equivNo;
637 for (sliceNo=0; sliceNo<maxNode; sliceNo++)
643 equivNode = equivProxy->
GetNode();
645 if (maxNo != sliceNo)
647 #ifdef G4GEOMETRY_VOXELDEBUG
648 G4cout <<
"**** G4SmartVoxelHeader::CollectEquivalentNodes" <<
G4endl
649 <<
" Collecting Nodes = "
650 << sliceNo <<
" - " << maxNo <<
G4endl;
654 for (equivNo=sliceNo+1; equivNo<=maxNo; equivNo++)
656 delete fslices[equivNo]->GetNode();
679 G4int sliceNo, maxNo, equivNo;
684 for (sliceNo=0; sliceNo<maxNode; sliceNo++)
691 if (maxNo != sliceNo)
697 #ifdef G4GEOMETRY_VOXELDEBUG
698 G4cout <<
"**** G4SmartVoxelHeader::CollectEquivalentHeaders" <<
G4endl
699 <<
" Collecting Headers =";
701 for (equivNo=sliceNo+1; equivNo<=maxNo; equivNo++)
703 sampleHeader =
fslices[equivNo]->GetHeader();
704 if ( (*sampleHeader) == (*equivHeader) )
706 #ifdef G4GEOMETRY_VOXELDEBUG
725 #ifdef G4GEOMETRY_VOXELDEBUG
762 G4int nCandidates = pCandidates->size();
763 G4int nVol, nNode, targetVolNo;
766 #ifdef G4GEOMETRY_VOXELDEBUG
767 G4cout <<
"**** G4SmartVoxelHeader::BuildNodes" <<
G4endl
768 <<
" Limits = " << pLimits <<
G4endl
769 <<
" Axis = " << pAxis <<
G4endl
770 <<
" Candidates = " << nCandidates <<
G4endl;
779 motherMinExtent, motherMaxExtent) )
782 motherMinExtent, motherMaxExtent);
797 std::ostringstream message;
798 message <<
"PANIC! - Missing parameterisation." << G4endl
799 <<
" Replicated volume with no parameterisation object !";
800 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
818 for (nVol=0; nVol<nCandidates; nVol++)
820 targetVolNo=(*pCandidates)[nVol];
821 if (replicated ==
false)
837 targetSolid = pParam->
ComputeSolid(targetVolNo,pDaughter);
852 targetMinExtent, targetMaxExtent))
855 targetMinExtent,targetMaxExtent);
857 minExtents[nVol] = targetMinExtent;
858 maxExtents[nVol] = targetMaxExtent;
860 #ifdef G4GEOMETRY_VOXELDEBUG
861 G4cout <<
"---------------------------------------------------" << G4endl
862 <<
" Volume = " << pDaughter->
GetName() << G4endl
863 <<
" Min Extent = " << targetMinExtent << G4endl
864 <<
" Max Extent = " << targetMaxExtent << G4endl
865 <<
"---------------------------------------------------" <<
G4endl;
870 if ( (!pLimits.
IsLimited()) && ((targetMaxExtent<=motherMinExtent)
871 ||(targetMinExtent>=motherMaxExtent)) )
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",
883 #ifdef G4GEOMETRY_VOXELDEBUG
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) )
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
914 for (nVol=0; nVol<nCandidates; nVol++)
920 currentWidth = std::abs(maxExtents[nVol]-minExtents[nVol]);
921 if ( (currentWidth<minWidth)
925 minWidth = currentWidth;
932 G4double noNodesExactD = ((motherMaxExtent-motherMinExtent)*2.0/minWidth)+1.0;
937 G4double smartlessComputed = noNodesExactD / nCandidates;
939 G4double smartless = (smartlessComputed <= smartlessUser)
940 ? smartlessComputed : smartlessUser;
941 G4double noNodesSmart = smartless*nCandidates;
943 G4int noNodes = ((noNodesSmart-noNodesExactI)>=0.5)
944 ? noNodesExactI+1 : noNodesExactI;
945 if( noNodes == 0 ) { noNodes=1; }
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;
958 #ifdef G4GEOMETRY_VOXELDEBUG
962 G4double nodeWidth = (motherMaxExtent-motherMinExtent)/noNodes;
969 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
973 nodeList->reserve(noNodes);
975 for (nNode=0; nNode<noNodes; nNode++)
981 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
985 nodeList->push_back(pNode);
992 for (nVol=0; nVol<nCandidates; nVol++)
994 G4int nodeNo, minContainingNode, maxContainingNode;
995 minContainingNode =
G4int((minExtents[nVol]-motherMinExtent)/nodeWidth);
996 maxContainingNode =
G4int((maxExtents[nVol]-motherMinExtent)/nodeWidth);
1000 if ( (maxContainingNode>=0) && (minContainingNode<noNodes) )
1005 if (maxContainingNode>=noNodes)
1007 maxContainingNode = noNodes-1;
1012 if (minContainingNode<0)
1014 minContainingNode=0;
1016 for (nodeNo=minContainingNode; nodeNo<=maxContainingNode; nodeNo++)
1018 (*nodeList)[nodeNo]->Insert((*pCandidates)[nVol]);
1031 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
1035 proxyList->reserve(noNodes);
1040 for (nNode=0; nNode<noNodes; nNode++)
1044 ((*nodeList)[nNode])->Shrink();
1048 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
1052 proxyList->push_back(pProxyNode);
1076 G4int nNodes = pSlice->size();
1077 G4int noContained, maxContained=0, sumContained=0, sumNonEmptyNodes=0;
1080 for (
G4int i=0; i<nNodes; i++)
1082 if ((*pSlice)[i]->IsNode())
1086 node = (*pSlice)[i]->GetNode();
1091 sumContained += noContained;
1095 if (noContained>maxContained)
1097 maxContained = noContained;
1103 G4Exception(
"G4SmartVoxelHeader::CalculateQuality()",
"GeomMgt0001",
1110 if (sumNonEmptyNodes)
1112 quality = sumContained/sumNonEmptyNodes;
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;
1142 G4int refinedDepth=0, minVolumes;
1160 switch (refinedDepth)
1175 G4int targetNo, noContainedDaughters, minNo, maxNo, replaceNo, i;
1185 for (targetNo=0; targetNo<maxNode; targetNo++)
1189 targetNodeProxy =
fslices[targetNo];
1190 targetNode = targetNodeProxy->
GetNode();
1200 "Target volume node list allocation error.");
1203 targetList->reserve(noContainedDaughters);
1204 for (i=0; i<noContainedDaughters; i++)
1206 targetList->push_back(targetNode->
GetVolume(i));
1211 #ifdef G4GEOMETRY_VOXELDEBUG
1212 G4cout <<
"**** G4SmartVoxelHeader::RefineNodes" <<
G4endl
1213 <<
" Refining nodes " << minNo
1214 <<
" - " << maxNo <<
" inclusive" <<
G4endl;
1226 for (replaceNo=minNo; replaceNo<=maxNo; replaceNo++)
1228 if (lastProxy !=
fslices[replaceNo])
1240 newLimits = pLimits;
1244 targetList,replaceNo);
1247 G4Exception(
"G4SmartVoxelHeader::RefineNodes()",
"GeomMgt0003",
1254 if (!replaceHeaderProxy)
1256 G4Exception(
"G4SmartVoxelHeader::RefineNodes()",
"GeomMgt0003",
1260 for (replaceNo=minNo; replaceNo<=maxNo; replaceNo++)
1262 fslices[replaceNo] = replaceHeaderProxy;
1289 for (
G4int i=1; i<noSlices; i++)
1308 G4int collectNodeNo=0;
1309 G4int collectHeadNo=0;
1311 G4bool haveHeaders=
false;
1313 for (i=0; i<h.
fslices.size(); i++)
1315 os <<
"Slice #" << i <<
" = ";
1318 if (h.
fslices[i]!=collectNode)
1321 for (
G4int k=0; k<h.
fslices[i]->GetNode()->GetNoContained(); k++)
1323 os <<
" " << h.
fslices[i]->GetNode()->GetVolume(k);
1331 os <<
"As slice #" << collectNodeNo <<
G4endl;
1337 if (h.
fslices[i] != collectHead)
1339 os <<
"Header" <<
G4endl;
1345 os <<
"As slice #" << collectHeadNo <<
G4endl;
1353 for (j=0; j<h.
fslices.size(); j++)
1357 os <<
"Header at Slice #" << j <<
" = ";
1358 if (h.
fslices[j] != collectHead)
1361 << (*(h.
fslices[j]->GetHeader()));
1367 os <<
"As slice #" << collectHeadNo <<
G4endl;
G4SmartVoxelHeader * GetHeader() const
G4double GetSmartless() const
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
G4int GetMinEquivalentSliceNo() const
static const G4double kInfinity
virtual G4bool IsReplicated() const =0
virtual void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4int GetVolume(G4int pVolumeNo) const
G4bool IsYLimited() const
virtual G4VSolid * ComputeSolid(const G4int, G4VPhysicalVolume *)
G4VSolid * GetSolid() const
G4VPhysicalVolume * GetDaughter(const G4int i) const
const G4int kMaxVoxelNodes
G4bool IsXLimited() const
const G4RotationMatrix * GetRotation() const
G4int GetNoContained() const
G4int GetMaxEquivalentSliceNo() const
void AddLimit(const EAxis pAxis, const G4double pMin, const G4double pMax)
G4GLOB_DLL std::ostream G4cout
const G4String & GetName() const
virtual G4VPVParameterisation * GetParameterisation() const =0
void SetMinEquivalentSliceNo(G4int pMin)
G4int GetNoDaughters() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
static const G4double emax
const G4ThreeVector & GetTranslation() const
G4LogicalVolume * GetLogicalVolume() const
G4SmartVoxelNode * GetNode() const
virtual void ComputeTransformation(const G4int, G4VPhysicalVolume *) const =0
std::ostream & operator<<(std::ostream &, const BasicVector3D< float > &)
const G4int kMinVoxelVolumesLevel3
const G4int kMinVoxelVolumesLevel2
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const =0
const G4String & GetName() const
G4double GetMaxExtent(const EAxis pAxis) const
void SetMaxEquivalentSliceNo(G4int pMax)
G4bool IsZLimited() const
G4double GetMinExtent(const EAxis pAxis) const