61 : fminEquivalent(pSlice),
62 fmaxEquivalent(pSlice),
97 : fminEquivalent(pSlice),
98 fmaxEquivalent(pSlice),
101 #ifdef G4GEOMETRY_VOXELDEBUG
102 G4cout <<
"**** G4SmartVoxelHeader::G4SmartVoxelHeader" <<
G4endl
103 <<
" Limits " << pLimits <<
G4endl
104 <<
" Candidate #s = " ;
105 for (
auto i=0; i<pCandidates->size(); ++i)
107 G4cout << (*pCandidates)[i] <<
" ";
125 size_t node, proxy, maxNode=
fslices.size();
130 for (node=0; node<maxNode; ++node)
134 dyingHeader =
fslices[node]->GetHeader();
135 if (lastHeader != dyingHeader)
137 lastHeader = dyingHeader;
144 dyingNode =
fslices[node]->GetNode();
145 if (dyingNode != lastNode)
147 lastNode = dyingNode;
148 lastHeader =
nullptr;
155 for (proxy=0; proxy<maxNode; ++proxy)
157 if (
fslices[proxy] != lastProxy)
183 size_t node, maxNode;
189 for (node=0; node<maxNode; ++node)
203 if (!(*leftHeader == *rightHeader))
217 leftNode = leftProxy->
GetNode();
218 rightNode = rightProxy->
GetNode();
219 if (!(*leftNode == *rightNode))
246 targetList.reserve(nDaughters);
247 for (
size_t i=0; i<nDaughters; ++i)
249 targetList.push_back(i);
281 if ( consuming ==
false )
285 targetList.reserve(nReplicas);
286 for (
auto i=0; i<nReplicas; ++i)
288 targetList.push_back(i);
347 G4Exception(
"G4SmartVoxelHeader::BuildReplicaVoxels()",
365 message <<
"Sanity check: wrong solid extent." <<
G4endl
366 <<
" Replicated geometry, logical volume: "
368 G4Exception(
"G4SmartVoxelHeader::BuildReplicaVoxels",
376 G4Exception(
"G4SmartVoxelHeader::BuildReplicaVoxels",
"GeomMgt0002",
397 nodeList.reserve(nReplicas);
398 for (nNode=0; nNode<nReplicas; ++nNode)
401 if (pNode ==
nullptr)
403 G4Exception(
"G4SmartVoxelHeader::BuildConsumedNodes()",
"GeomMgt0003",
406 nodeList.push_back(pNode);
408 for (nVol=0; nVol<nReplicas; ++nVol)
410 nodeList[nVol]->Insert(nVol);
416 for (nNode=0; nNode<nReplicas; ++nNode)
421 G4Exception(
"G4SmartVoxelHeader::BuildConsumedNodes()",
"GeomMgt0003",
444 G4ProxyVector *pGoodSlices=
nullptr, *pTestSlices, *tmpSlices;
448 size_t node, maxNode, iaxis;
453 for (iaxis=0; iaxis<3; ++iaxis)
469 pTestSlices =
BuildNodes(pVolume,pLimits,pCandidates,testAxis);
471 if ( (!pGoodSlices) || (testSliceScore<goodSliceScore) )
473 goodSliceAxis = testAxis;
474 goodSliceScore = testSliceScore;
475 tmpSlices = pGoodSlices;
476 pGoodSlices = pTestSlices;
477 pTestSlices = tmpSlices;
483 maxNode=pTestSlices->size();
484 for (node=0; node<maxNode; ++node)
486 delete (*pTestSlices)[node]->GetNode();
489 while (pTestSlices->size()>0)
491 tmpProx = pTestSlices->back();
492 pTestSlices->pop_back();
493 for (
auto i=pTestSlices->cbegin(); i!=pTestSlices->cend(); )
497 i = pTestSlices->erase(i);
504 if ( tmpProx ) {
delete tmpProx; }
515 G4Exception(
"G4SmartVoxelHeader::BuildVoxelsWithinLimits()",
517 "Cannot select more than 3 axis for optimisation.");
530 faxis = goodSliceAxis;
532 #ifdef G4GEOMETRY_VOXELDEBUG
535 for (
auto islice=0; islice<
fslices.size(); ++islice)
537 G4cout <<
" Node #" << islice <<
" = {";
538 for (
auto j=0; j<
fslices[islice]->GetNode()->GetNoContained(); ++j)
577 size_t sliceNo, minNo, maxNo, equivNo;
578 size_t maxNode =
fslices.size();
580 for (sliceNo=0; sliceNo<maxNode; ++sliceNo)
586 startNode =
fslices[minNo]->GetNode();
590 for (equivNo=minNo+1; equivNo<maxNode; ++equivNo)
592 sampleNode =
fslices[equivNo]->GetNode();
593 if (!((*startNode) == (*sampleNode))) {
break; }
600 for (equivNo=minNo; equivNo<=maxNo; ++equivNo)
602 sampleNode =
fslices[equivNo]->GetNode();
624 size_t sliceNo, maxNo, equivNo;
629 for (sliceNo=0; sliceNo<maxNode; ++sliceNo)
635 equivNode = equivProxy->
GetNode();
637 if (maxNo != sliceNo)
639 #ifdef G4GEOMETRY_VOXELDEBUG
640 G4cout <<
"**** G4SmartVoxelHeader::CollectEquivalentNodes" <<
G4endl
641 <<
" Collecting Nodes = "
642 << sliceNo <<
" - " << maxNo <<
G4endl;
646 for (equivNo=sliceNo+1; equivNo<=maxNo; ++equivNo)
648 delete fslices[equivNo]->GetNode();
671 size_t sliceNo, maxNo, equivNo;
672 size_t maxNode =
fslices.size();
676 for (sliceNo=0; sliceNo<maxNode; ++sliceNo)
683 if (maxNo != sliceNo)
689 #ifdef G4GEOMETRY_VOXELDEBUG
690 G4cout <<
"**** G4SmartVoxelHeader::CollectEquivalentHeaders" <<
G4endl
691 <<
" Collecting Headers =";
693 for (equivNo=sliceNo+1; equivNo<=maxNo; ++equivNo)
695 sampleHeader =
fslices[equivNo]->GetHeader();
696 if ( (*sampleHeader) == (*equivHeader) )
698 #ifdef G4GEOMETRY_VOXELDEBUG
717 #ifdef G4GEOMETRY_VOXELDEBUG
754 size_t nCandidates = pCandidates->size();
755 size_t nVol, nNode, targetVolNo;
758 #ifdef G4GEOMETRY_VOXELDEBUG
759 G4cout <<
"**** G4SmartVoxelHeader::BuildNodes" <<
G4endl
760 <<
" Limits = " << pLimits <<
G4endl
761 <<
" Axis = " << pAxis <<
G4endl
762 <<
" Candidates = " << nCandidates <<
G4endl;
771 motherMinExtent, motherMaxExtent) )
774 motherMinExtent, motherMaxExtent);
787 if (pParam ==
nullptr)
790 message <<
"PANIC! - Missing parameterisation." << G4endl
791 <<
" Replicated volume with no parameterisation object !";
792 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
810 for (nVol=0; nVol<nCandidates; ++nVol)
812 targetVolNo = (*pCandidates)[nVol];
813 if (replicated ==
false)
829 targetSolid = pParam->
ComputeSolid(targetVolNo,pDaughter);
844 targetMinExtent, targetMaxExtent))
847 targetMinExtent,targetMaxExtent);
849 minExtents[nVol] = targetMinExtent;
850 maxExtents[nVol] = targetMaxExtent;
852 #ifdef G4GEOMETRY_VOXELDEBUG
853 G4cout <<
"---------------------------------------------------" << G4endl
854 <<
" Volume = " << pDaughter->
GetName() << G4endl
855 <<
" Min Extent = " << targetMinExtent << G4endl
856 <<
" Max Extent = " << targetMaxExtent << G4endl
857 <<
"---------------------------------------------------" <<
G4endl;
862 if ( (!pLimits.
IsLimited()) && ((targetMaxExtent<=motherMinExtent)
863 ||(targetMinExtent>=motherMaxExtent)) )
866 message <<
"PANIC! - Overlapping daughter with mother volume." << G4endl
867 <<
" Daughter physical volume "
868 << pDaughter->
GetName() << G4endl
869 <<
" is entirely outside mother logical volume "
870 << pVolume->
GetName() <<
" !!";
871 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0002",
875 #ifdef G4GEOMETRY_VOXELDEBUG
883 G4int kStraddlePercent = 5;
884 width = maxExtents[nVol]-minExtents[nVol];
885 if ( (((motherMinExtent-minExtents[nVol])*100/width) > kStraddlePercent)
886 ||(((maxExtents[nVol]-motherMaxExtent)*100/width) > kStraddlePercent) )
888 G4cout <<
"**** G4SmartVoxelHeader::BuildNodes" << G4endl
889 <<
" WARNING : Daughter # " << nVol
890 <<
" name = " << pDaughter->
GetName() << G4endl
891 <<
" Crosses mother boundary of logical volume, name = "
892 << pVolume->
GetName() << G4endl
893 <<
" by more than " << kStraddlePercent
906 for (nVol=0; nVol<nCandidates; ++nVol)
912 currentWidth =
std::abs(maxExtents[nVol]-minExtents[nVol]);
913 if ( (currentWidth<minWidth)
917 minWidth = currentWidth;
924 G4double noNodesExactD = ((motherMaxExtent-motherMinExtent)*2.0/minWidth)+1.0;
929 G4double smartlessComputed = noNodesExactD / nCandidates;
931 G4double smartless = (smartlessComputed <= smartlessUser)
932 ? smartlessComputed : smartlessUser;
933 G4double noNodesSmart = smartless*nCandidates;
935 G4long noNodes = ((noNodesSmart-noNodesExactI)>=0.5)
936 ? noNodesExactI+1 : noNodesExactI;
937 if( noNodes == 0 ) { noNodes=1; }
939 #ifdef G4GEOMETRY_VOXELDEBUG
940 G4cout <<
" Smartless computed = " << smartlessComputed << G4endl
941 <<
" Smartless volume = " << smartlessUser
942 <<
" => # Smartless = " << smartless <<
G4endl;
943 G4cout <<
" Min width = " << minWidth
944 <<
" => # Nodes = " << noNodes <<
G4endl;
950 #ifdef G4GEOMETRY_VOXELDEBUG
954 G4double nodeWidth = (motherMaxExtent-motherMinExtent)/noNodes;
959 if (nodeList ==
nullptr)
961 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
965 nodeList->reserve(noNodes);
967 for (nNode=0;
G4long(nNode)<noNodes; ++nNode)
971 if (pNode ==
nullptr)
973 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
977 nodeList->push_back(pNode);
984 for (nVol=0; nVol<nCandidates; ++nVol)
986 G4long nodeNo, minContainingNode, maxContainingNode;
987 minContainingNode = (minExtents[nVol]-motherMinExtent)/nodeWidth;
988 maxContainingNode = (maxExtents[nVol]-motherMinExtent)/nodeWidth;
992 if ( (maxContainingNode>=0) && (minContainingNode<noNodes) )
997 if (maxContainingNode>=noNodes)
999 maxContainingNode = noNodes-1;
1004 if (minContainingNode<0)
1006 minContainingNode = 0;
1008 for (nodeNo=minContainingNode; nodeNo<=maxContainingNode; ++nodeNo)
1010 (*nodeList)[nodeNo]->Insert((*pCandidates)[nVol]);
1021 if (proxyList ==
nullptr)
1023 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
1027 proxyList->reserve(noNodes);
1032 for (nNode=0;
G4long(nNode)<noNodes; ++nNode)
1036 ((*nodeList)[nNode])->Shrink();
1038 if (pProxyNode ==
nullptr)
1040 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
1044 proxyList->push_back(pProxyNode);
1068 size_t nNodes = pSlice->size();
1069 size_t noContained, maxContained=0, sumContained=0, sumNonEmptyNodes=0;
1072 for (
size_t i=0; i<nNodes; ++i)
1074 if ((*pSlice)[i]->IsNode())
1078 node = (*pSlice)[i]->GetNode();
1083 sumContained += noContained;
1087 if (noContained>maxContained)
1089 maxContained = noContained;
1095 G4Exception(
"G4SmartVoxelHeader::CalculateQuality()",
"GeomMgt0001",
1102 if (sumNonEmptyNodes)
1104 quality = sumContained/sumNonEmptyNodes;
1111 #ifdef G4GEOMETRY_VOXELDEBUG
1112 G4cout <<
"**** G4SmartVoxelHeader::CalculateQuality" <<
G4endl
1113 <<
" Quality = " << quality <<
G4endl
1114 <<
" Nodes = " << nNodes
1115 <<
" of which " << sumNonEmptyNodes <<
" non empty" <<
G4endl
1116 <<
" Max Contained = " << maxContained <<
G4endl;
1134 size_t refinedDepth=0, minVolumes;
1135 size_t maxNode =
fslices.size();
1152 switch (refinedDepth)
1167 size_t targetNo, noContainedDaughters, minNo, maxNo, replaceNo, i;
1177 for (targetNo=0; targetNo<maxNode; ++targetNo)
1181 targetNodeProxy =
fslices[targetNo];
1182 targetNode = targetNodeProxy->
GetNode();
1188 if (targetList ==
nullptr)
1192 "Target volume node list allocation error.");
1195 targetList->reserve(noContainedDaughters);
1196 for (i=0; i<noContainedDaughters; ++i)
1198 targetList->push_back(targetNode->
GetVolume(i));
1203 #ifdef G4GEOMETRY_VOXELDEBUG
1204 G4cout <<
"**** G4SmartVoxelHeader::RefineNodes" <<
G4endl
1205 <<
" Refining nodes " << minNo
1206 <<
" - " << maxNo <<
" inclusive" <<
G4endl;
1218 for (replaceNo=minNo; replaceNo<=maxNo; ++replaceNo)
1220 if (lastProxy !=
fslices[replaceNo])
1232 newLimits = pLimits;
1236 targetList,replaceNo);
1237 if (replaceHeader ==
nullptr)
1239 G4Exception(
"G4SmartVoxelHeader::RefineNodes()",
"GeomMgt0003",
1246 if (replaceHeaderProxy ==
nullptr)
1248 G4Exception(
"G4SmartVoxelHeader::RefineNodes()",
"GeomMgt0003",
1252 for (replaceNo=minNo; replaceNo<=maxNo; ++replaceNo)
1254 fslices[replaceNo] = replaceHeaderProxy;
1275 size_t noSlices =
fslices.size();
1281 for (
size_t i=1; i<noSlices; ++i)
1300 G4int collectNodeNo = 0;
1301 G4int collectHeadNo = 0;
1303 G4bool haveHeaders =
false;
1305 for (i=0; i<h.
fslices.size(); ++i)
1307 os <<
"Slice #" << i <<
" = ";
1310 if (h.
fslices[i]!=collectNode)
1313 for (
size_t k=0;
k<h.
fslices[i]->GetNode()->GetNoContained(); ++
k)
1315 os <<
" " << h.
fslices[i]->GetNode()->GetVolume(
k);
1323 os <<
"As slice #" << collectNodeNo <<
G4endl;
1329 if (h.
fslices[i] != collectHead)
1331 os <<
"Header" <<
G4endl;
1337 os <<
"As slice #" << collectHeadNo <<
G4endl;
1345 for (j=0; j<h.
fslices.size(); ++j)
1349 os <<
"Header at Slice #" << j <<
" = ";
1350 if (h.
fslices[j] != collectHead)
1353 << (*(h.
fslices[j]->GetHeader()));
1359 os <<
"As slice #" << collectHeadNo <<
G4endl;