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()",
364 G4double emin = kInfinity, emax = -kInfinity;
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",
452 G4double goodSliceScore=kInfinity, testSliceScore;
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
755 G4double motherMinExtent= kInfinity, motherMaxExtent= -kInfinity,
756 targetMinExtent= kInfinity, targetMaxExtent= -kInfinity;
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
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 "
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
899 <<
" Crosses mother boundary of logical volume, name = "
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;
1116 quality = kInfinity;
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;
G4DLLIMPORT std::ostream G4cout
G4VSolid * GetSolid() const
G4int GetNoDaughters() const
G4double GetSmartless() const
G4VPhysicalVolume * GetDaughter(const G4int i) const
G4int GetMaxEquivalentSliceNo() const
G4int GetNoContained() const
G4int GetVolume(G4int pVolumeNo) const
void SetMaxEquivalentSliceNo(G4int pMax)
void SetMinEquivalentSliceNo(G4int pMin)
G4int GetMinEquivalentSliceNo() const
G4SmartVoxelNode * GetNode() const
G4SmartVoxelHeader * GetHeader() const
virtual G4VSolid * ComputeSolid(const G4int, G4VPhysicalVolume *)
virtual void ComputeTransformation(const G4int, G4VPhysicalVolume *) const =0
virtual G4bool IsReplicated() const =0
const G4RotationMatrix * GetRotation() const
G4LogicalVolume * GetLogicalVolume() const
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const =0
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)
G4double GetMinExtent(const EAxis pAxis) const
G4bool IsYLimited() const
void AddLimit(const EAxis pAxis, const G4double pMin, const G4double pMax)
G4bool IsXLimited() const
G4double GetMaxExtent(const EAxis pAxis) const
G4bool IsZLimited() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
const G4int kMaxVoxelNodes
const G4int kMinVoxelVolumesLevel3
const G4int kMinVoxelVolumesLevel2