61 : fminEquivalent(pSlice),
62 fmaxEquivalent(pSlice),
96 : fminEquivalent(pSlice),
97 fmaxEquivalent(pSlice),
100#ifdef G4GEOMETRY_VOXELDEBUG
101 G4cout <<
"**** G4SmartVoxelHeader::G4SmartVoxelHeader" <<
G4endl
102 <<
" Limits " << pLimits <<
G4endl
103 <<
" Candidate #s = " ;
104 for (
auto i=0; i<pCandidates->size(); ++i)
106 G4cout << (*pCandidates)[i] <<
" ";
124 std::size_t node, proxy, maxNode=
fslices.size();
129 for (node=0; node<maxNode; ++node)
133 dyingHeader =
fslices[node]->GetHeader();
134 if (lastHeader != dyingHeader)
136 lastHeader = dyingHeader;
143 dyingNode =
fslices[node]->GetNode();
144 if (dyingNode != lastNode)
146 lastNode = dyingNode;
147 lastHeader =
nullptr;
154 for (proxy=0; proxy<maxNode; ++proxy)
156 if (
fslices[proxy] != lastProxy)
182 std::size_t node, maxNode;
188 for (node=0; node<maxNode; ++node)
202 if (!(*leftHeader == *rightHeader))
216 leftNode = leftProxy->
GetNode();
217 rightNode = rightProxy->
GetNode();
218 if (!(*leftNode == *rightNode))
245 targetList.reserve(nDaughters);
246 for (std::size_t i=0; i<nDaughters; ++i)
248 targetList.push_back((
G4int)i);
280 if ( consuming ==
false )
284 targetList.reserve(nReplicas);
285 for (
auto i=0; i<nReplicas; ++i)
287 targetList.push_back(i);
346 G4Exception(
"G4SmartVoxelHeader::BuildReplicaVoxels()",
356 G4double emin = kInfinity, emax = -kInfinity;
363 std::ostringstream message;
364 message <<
"Sanity check: wrong solid extent." <<
G4endl
365 <<
" Replicated geometry, logical volume: "
367 G4Exception(
"G4SmartVoxelHeader::BuildReplicaVoxels",
375 G4Exception(
"G4SmartVoxelHeader::BuildReplicaVoxels",
"GeomMgt0002",
396 nodeList.reserve(nReplicas);
397 for (nNode=0; nNode<nReplicas; ++nNode)
400 if (pNode ==
nullptr)
402 G4Exception(
"G4SmartVoxelHeader::BuildConsumedNodes()",
"GeomMgt0003",
405 nodeList.push_back(pNode);
407 for (nVol=0; nVol<nReplicas; ++nVol)
409 nodeList[nVol]->Insert(nVol);
415 for (nNode=0; nNode<nReplicas; ++nNode)
420 G4Exception(
"G4SmartVoxelHeader::BuildConsumedNodes()",
"GeomMgt0003",
443 G4ProxyVector *pGoodSlices=
nullptr, *pTestSlices, *tmpSlices;
444 G4double goodSliceScore=kInfinity, testSliceScore;
447 std::size_t node, maxNode, iaxis;
452 for (iaxis=0; iaxis<3; ++iaxis)
468 pTestSlices =
BuildNodes(pVolume,pLimits,pCandidates,testAxis);
470 if ( (!pGoodSlices) || (testSliceScore<goodSliceScore) )
472 goodSliceAxis = testAxis;
473 goodSliceScore = testSliceScore;
474 tmpSlices = pGoodSlices;
475 pGoodSlices = pTestSlices;
476 pTestSlices = tmpSlices;
482 maxNode=pTestSlices->size();
483 for (node=0; node<maxNode; ++node)
485 delete (*pTestSlices)[node]->GetNode();
488 while (pTestSlices->size()>0)
490 tmpProx = pTestSlices->back();
491 pTestSlices->pop_back();
492 for (
auto i=pTestSlices->cbegin(); i!=pTestSlices->cend(); )
496 i = pTestSlices->erase(i);
503 if ( tmpProx ) {
delete tmpProx; }
514 G4Exception(
"G4SmartVoxelHeader::BuildVoxelsWithinLimits()",
516 "Cannot select more than 3 axis for optimisation.");
529 faxis = goodSliceAxis;
531#ifdef G4GEOMETRY_VOXELDEBUG
534 for (
auto islice=0; islice<
fslices.size(); ++islice)
536 G4cout <<
" Node #" << islice <<
" = {";
537 for (
auto j=0; j<
fslices[islice]->GetNode()->GetNoContained(); ++j)
576 std::size_t sliceNo, minNo, maxNo, equivNo;
577 std::size_t maxNode =
fslices.size();
579 for (sliceNo=0; sliceNo<maxNode; ++sliceNo)
585 startNode =
fslices[minNo]->GetNode();
589 for (equivNo=minNo+1; equivNo<maxNode; ++equivNo)
591 sampleNode =
fslices[equivNo]->GetNode();
592 if (!((*startNode) == (*sampleNode))) {
break; }
599 for (equivNo=minNo; equivNo<=maxNo; ++equivNo)
601 sampleNode =
fslices[equivNo]->GetNode();
623 std::size_t sliceNo, maxNo, equivNo;
624 std::size_t maxNode=
fslices.size();
628 for (sliceNo=0; sliceNo<maxNode; ++sliceNo)
634 equivNode = equivProxy->
GetNode();
636 if (maxNo != sliceNo)
638#ifdef G4GEOMETRY_VOXELDEBUG
639 G4cout <<
"**** G4SmartVoxelHeader::CollectEquivalentNodes" <<
G4endl
640 <<
" Collecting Nodes = "
641 << sliceNo <<
" - " << maxNo <<
G4endl;
645 for (equivNo=sliceNo+1; equivNo<=maxNo; ++equivNo)
647 delete fslices[equivNo]->GetNode();
670 std::size_t sliceNo, maxNo, equivNo;
671 std::size_t maxNode =
fslices.size();
675 for (sliceNo=0; sliceNo<maxNode; ++sliceNo)
682 if (maxNo != sliceNo)
688#ifdef G4GEOMETRY_VOXELDEBUG
689 G4cout <<
"**** G4SmartVoxelHeader::CollectEquivalentHeaders" <<
G4endl
690 <<
" Collecting Headers =";
692 for (equivNo=sliceNo+1; equivNo<=maxNo; ++equivNo)
694 sampleHeader =
fslices[equivNo]->GetHeader();
695 if ( (*sampleHeader) == (*equivHeader) )
697#ifdef G4GEOMETRY_VOXELDEBUG
716#ifdef G4GEOMETRY_VOXELDEBUG
746 G4double motherMinExtent= kInfinity, motherMaxExtent= -kInfinity,
747 targetMinExtent= kInfinity, targetMaxExtent= -kInfinity;
753 std::size_t nCandidates = pCandidates->size();
754 std::size_t nVol, nNode, targetVolNo;
757#ifdef G4GEOMETRY_VOXELDEBUG
758 G4cout <<
"**** G4SmartVoxelHeader::BuildNodes" <<
G4endl
759 <<
" Limits = " << pLimits <<
G4endl
760 <<
" Axis = " << pAxis <<
G4endl
761 <<
" Candidates = " << nCandidates <<
G4endl;
770 motherMinExtent, motherMaxExtent) )
773 motherMinExtent, motherMaxExtent);
786 if (pParam ==
nullptr)
788 std::ostringstream message;
789 message <<
"PANIC! - Missing parameterisation." <<
G4endl
790 <<
" Replicated volume with no parameterisation object !";
791 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
809 for (nVol=0; nVol<nCandidates; ++nVol)
811 targetVolNo = (*pCandidates)[nVol];
812 if (replicated ==
false)
843 targetMinExtent, targetMaxExtent))
846 targetMinExtent,targetMaxExtent);
848 minExtents[nVol] = targetMinExtent;
849 maxExtents[nVol] = targetMaxExtent;
851#ifdef G4GEOMETRY_VOXELDEBUG
852 G4cout <<
"---------------------------------------------------" <<
G4endl
854 <<
" Min Extent = " << targetMinExtent <<
G4endl
855 <<
" Max Extent = " << targetMaxExtent <<
G4endl
856 <<
"---------------------------------------------------" <<
G4endl;
861 if ( (!pLimits.
IsLimited()) && ((targetMaxExtent<=motherMinExtent)
862 ||(targetMinExtent>=motherMaxExtent)) )
864 std::ostringstream message;
865 message <<
"PANIC! - Overlapping daughter with mother volume." <<
G4endl
866 <<
" Daughter physical volume "
868 <<
" is entirely outside mother logical volume "
869 << pVolume->
GetName() <<
" !!";
870 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0002",
874#ifdef G4GEOMETRY_VOXELDEBUG
882 G4int kStraddlePercent = 5;
883 width = maxExtents[nVol]-minExtents[nVol];
884 if ( (((motherMinExtent-minExtents[nVol])*100/width) > kStraddlePercent)
885 ||(((maxExtents[nVol]-motherMaxExtent)*100/width) > kStraddlePercent) )
887 G4cout <<
"**** G4SmartVoxelHeader::BuildNodes" <<
G4endl
888 <<
" WARNING : Daughter # " << nVol
890 <<
" Crosses mother boundary of logical volume, name = "
892 <<
" by more than " << kStraddlePercent
905 for (nVol=0; nVol<nCandidates; ++nVol)
911 currentWidth = std::abs(maxExtents[nVol]-minExtents[nVol]);
912 if ( (currentWidth<minWidth)
916 minWidth = currentWidth;
923 G4double noNodesExactD = ((motherMaxExtent-motherMinExtent)*2.0/minWidth)+1.0;
928 G4double smartlessComputed = noNodesExactD / nCandidates;
930 G4double smartless = (smartlessComputed <= smartlessUser)
931 ? smartlessComputed : smartlessUser;
932 G4double noNodesSmart = smartless*nCandidates;
934 G4long noNodes = ((noNodesSmart-noNodesExactI)>=0.5)
935 ? noNodesExactI+1 : noNodesExactI;
936 if( noNodes == 0 ) { noNodes=1; }
938#ifdef G4GEOMETRY_VOXELDEBUG
939 G4cout <<
" Smartless computed = " << smartlessComputed <<
G4endl
940 <<
" Smartless volume = " << smartlessUser
941 <<
" => # Smartless = " << smartless <<
G4endl;
942 G4cout <<
" Min width = " << minWidth
943 <<
" => # Nodes = " << noNodes <<
G4endl;
949#ifdef G4GEOMETRY_VOXELDEBUG
953 G4double nodeWidth = (motherMaxExtent-motherMinExtent)/noNodes;
958 if (nodeList ==
nullptr)
960 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
964 nodeList->reserve(noNodes);
966 for (nNode=0;
G4long(nNode)<noNodes; ++nNode)
970 if (pNode ==
nullptr)
972 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
976 nodeList->push_back(pNode);
983 for (nVol=0; nVol<nCandidates; ++nVol)
985 G4long nodeNo, minContainingNode, maxContainingNode;
986 minContainingNode = (minExtents[nVol]-motherMinExtent)/nodeWidth;
987 maxContainingNode = (maxExtents[nVol]-motherMinExtent)/nodeWidth;
991 if ( (maxContainingNode>=0) && (minContainingNode<noNodes) )
996 if (maxContainingNode>=noNodes)
998 maxContainingNode = noNodes-1;
1003 if (minContainingNode<0)
1005 minContainingNode = 0;
1007 for (nodeNo=minContainingNode; nodeNo<=maxContainingNode; ++nodeNo)
1009 (*nodeList)[nodeNo]->Insert((*pCandidates)[nVol]);
1020 if (proxyList ==
nullptr)
1022 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
1026 proxyList->reserve(noNodes);
1031 for (nNode=0;
G4long(nNode)<noNodes; ++nNode)
1035 ((*nodeList)[nNode])->Shrink();
1037 if (pProxyNode ==
nullptr)
1039 G4Exception(
"G4SmartVoxelHeader::BuildNodes()",
"GeomMgt0003",
1043 proxyList->push_back(pProxyNode);
1067 std::size_t nNodes = pSlice->size();
1068 std::size_t noContained, maxContained=0, sumContained=0, sumNonEmptyNodes=0;
1071 for (std::size_t i=0; i<nNodes; ++i)
1073 if ((*pSlice)[i]->IsNode())
1077 node = (*pSlice)[i]->GetNode();
1082 sumContained += noContained;
1086 if (noContained>maxContained)
1088 maxContained = noContained;
1094 G4Exception(
"G4SmartVoxelHeader::CalculateQuality()",
"GeomMgt0001",
1101 if (sumNonEmptyNodes)
1103 quality = sumContained/sumNonEmptyNodes;
1107 quality = kInfinity;
1110#ifdef G4GEOMETRY_VOXELDEBUG
1111 G4cout <<
"**** G4SmartVoxelHeader::CalculateQuality" <<
G4endl
1112 <<
" Quality = " << quality <<
G4endl
1113 <<
" Nodes = " << nNodes
1114 <<
" of which " << sumNonEmptyNodes <<
" non empty" <<
G4endl
1115 <<
" Max Contained = " << maxContained <<
G4endl;
1133 std::size_t refinedDepth=0, minVolumes;
1134 std::size_t maxNode =
fslices.size();
1151 switch (refinedDepth)
1166 std::size_t targetNo, noContainedDaughters, minNo, maxNo, replaceNo, i;
1176 for (targetNo=0; targetNo<maxNode; ++targetNo)
1180 targetNodeProxy =
fslices[targetNo];
1181 targetNode = targetNodeProxy->
GetNode();
1187 if (targetList ==
nullptr)
1191 "Target volume node list allocation error.");
1194 targetList->reserve(noContainedDaughters);
1195 for (i=0; i<noContainedDaughters; ++i)
1202#ifdef G4GEOMETRY_VOXELDEBUG
1203 G4cout <<
"**** G4SmartVoxelHeader::RefineNodes" <<
G4endl
1204 <<
" Refining nodes " << minNo
1205 <<
" - " << maxNo <<
" inclusive" <<
G4endl;
1217 for (replaceNo=minNo; replaceNo<=maxNo; ++replaceNo)
1219 if (lastProxy !=
fslices[replaceNo])
1231 newLimits = pLimits;
1235 targetList,(
G4int)replaceNo);
1236 if (replaceHeader ==
nullptr)
1238 G4Exception(
"G4SmartVoxelHeader::RefineNodes()",
"GeomMgt0003",
1245 if (replaceHeaderProxy ==
nullptr)
1247 G4Exception(
"G4SmartVoxelHeader::RefineNodes()",
"GeomMgt0003",
1251 for (replaceNo=minNo; replaceNo<=maxNo; ++replaceNo)
1253 fslices[replaceNo] = replaceHeaderProxy;
1274 std::size_t noSlices =
fslices.size();
1280 for (std::size_t i=1; i<noSlices; ++i)
1299 std::size_t collectNodeNo = 0;
1300 std::size_t collectHeadNo = 0;
1302 G4bool haveHeaders =
false;
1304 for (i=0; i<h.
fslices.size(); ++i)
1306 os <<
"Slice #" << i <<
" = ";
1309 if (h.
fslices[i]!=collectNode)
1312 for (std::size_t k=0; k<h.
fslices[i]->GetNode()->GetNoContained(); ++k)
1314 os <<
" " << h.
fslices[i]->GetNode()->GetVolume((
G4int)k);
1322 os <<
"As slice #" << collectNodeNo <<
G4endl;
1328 if (h.
fslices[i] != collectHead)
1330 os <<
"Header" <<
G4endl;
1336 os <<
"As slice #" << collectHeadNo <<
G4endl;
1343 collectHead=
nullptr;
1344 for (j=0; j<h.
fslices.size(); ++j)
1348 os <<
"Header at Slice #" << j <<
" = ";
1349 if (h.
fslices[j] != collectHead)
1352 << (*(h.
fslices[j]->GetHeader()));
1358 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
std::size_t GetNoDaughters() const
G4double GetSmartless() const
G4VPhysicalVolume * GetDaughter(const std::size_t i) const
const G4String & GetName() const
G4int GetMaxEquivalentSliceNo() const
G4int GetVolume(G4int pVolumeNo) const
void SetMaxEquivalentSliceNo(G4int pMax)
void SetMinEquivalentSliceNo(G4int pMin)
std::size_t GetNoContained() const
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