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()",
357 G4double emin = kInfinity, emax = -kInfinity;
364 std::ostringstream message;
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;
445 G4double goodSliceScore=kInfinity, testSliceScore;
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
747 G4double motherMinExtent= kInfinity, motherMaxExtent= -kInfinity,
748 targetMinExtent= kInfinity, targetMaxExtent= -kInfinity;
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)
789 std::ostringstream message;
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
855 <<
" Min Extent = " << targetMinExtent <<
G4endl
856 <<
" Max Extent = " << targetMaxExtent <<
G4endl
857 <<
"---------------------------------------------------" <<
G4endl;
862 if ( (!pLimits.
IsLimited()) && ((targetMaxExtent<=motherMinExtent)
863 ||(targetMinExtent>=motherMaxExtent)) )
865 std::ostringstream message;
866 message <<
"PANIC! - Overlapping daughter with mother volume." <<
G4endl
867 <<
" Daughter physical volume "
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
891 <<
" Crosses mother boundary of logical volume, name = "
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;
1108 quality = kInfinity;
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;
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4GLOB_DLL std::ostream G4cout
G4VSolid * GetSolid() const
size_t GetNoDaughters() const
G4double GetSmartless() const
G4VPhysicalVolume * GetDaughter(const G4int i) const
const G4String & GetName() const
G4int GetMaxEquivalentSliceNo() const
G4int GetVolume(G4int pVolumeNo) const
void SetMaxEquivalentSliceNo(G4int pMax)
size_t GetNoContained() const
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
const G4ThreeVector GetTranslation() 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
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
const G4int kMaxVoxelNodes
const G4int kMinVoxelVolumesLevel3
const G4int kMinVoxelVolumesLevel2