#include <G4SmartVoxelHeader.hh>
Definition at line 78 of file G4SmartVoxelHeader.hh.
G4SmartVoxelHeader::G4SmartVoxelHeader | ( | G4LogicalVolume * | pVolume, | |
G4int | pSlice = 0 | |||
) |
Definition at line 66 of file G4SmartVoxelHeader.cc.
References BuildReplicaVoxels(), BuildVoxels(), G4LogicalVolume::GetDaughter(), G4LogicalVolume::GetNoDaughters(), and G4VPhysicalVolume::IsReplicated().
Referenced by RefineNodes().
00068 : fminEquivalent(pSlice), 00069 fmaxEquivalent(pSlice), 00070 fparamAxis(kUndefined) 00071 { 00072 G4int nDaughters = pVolume->GetNoDaughters(); 00073 G4VoxelLimits limits; // Create `unlimited' limits object 00074 00075 // Determine whether daughter is replicated 00076 // 00077 if ((nDaughters!=1) || (!pVolume->GetDaughter(0)->IsReplicated())) 00078 { 00079 // Daughter not replicated => conventional voxel Build 00080 // where each daughters extents are computed 00081 // 00082 BuildVoxels(pVolume); 00083 } 00084 else 00085 { 00086 // Single replicated daughter 00087 // 00088 BuildReplicaVoxels(pVolume); 00089 } 00090 }
G4SmartVoxelHeader::~G4SmartVoxelHeader | ( | ) |
Definition at line 127 of file G4SmartVoxelHeader.cc.
References fslices.
00128 { 00129 // Manually destroy underlying nodes/headers 00130 // Delete collected headers and nodes once only 00131 // 00132 G4int node, proxy, maxNode=fslices.size(); 00133 G4SmartVoxelProxy *lastProxy=0; 00134 G4SmartVoxelNode *dyingNode, *lastNode=0; 00135 G4SmartVoxelHeader *dyingHeader, *lastHeader=0; 00136 00137 for (node=0; node<maxNode; node++) 00138 { 00139 if (fslices[node]->IsHeader()) 00140 { 00141 dyingHeader = fslices[node]->GetHeader(); 00142 if (lastHeader!=dyingHeader) 00143 { 00144 lastHeader = dyingHeader; 00145 lastNode = 0; 00146 delete dyingHeader; 00147 } 00148 } 00149 else 00150 { 00151 dyingNode = fslices[node]->GetNode(); 00152 if (dyingNode!=lastNode) 00153 { 00154 lastNode=dyingNode; 00155 lastHeader=0; 00156 delete dyingNode; 00157 } 00158 } 00159 } 00160 // Delete proxies 00161 // 00162 for (proxy=0; proxy<maxNode; proxy++) 00163 { 00164 if (fslices[proxy]!=lastProxy) 00165 { 00166 lastProxy = fslices[proxy]; 00167 delete lastProxy; 00168 } 00169 } 00170 // Don't need to clear slices 00171 // fslices.clear(); 00172 }
G4SmartVoxelHeader::G4SmartVoxelHeader | ( | G4LogicalVolume * | pVolume, | |
const G4VoxelLimits & | pLimits, | |||
const G4VolumeNosVector * | pCandidates, | |||
G4int | pSlice = 0 | |||
) | [protected] |
Definition at line 100 of file G4SmartVoxelHeader.cc.
References BuildVoxelsWithinLimits(), G4cout, and G4endl.
00104 : fminEquivalent(pSlice), 00105 fmaxEquivalent(pSlice), 00106 fparamAxis(kUndefined) 00107 { 00108 #ifdef G4GEOMETRY_VOXELDEBUG 00109 G4cout << "**** G4SmartVoxelHeader::G4SmartVoxelHeader" << G4endl 00110 << " Limits " << pLimits << G4endl 00111 << " Candidate #s = " ; 00112 for (size_t i=0;i<pCandidates->size();i++) 00113 { 00114 G4cout << (*pCandidates)[i] << " "; 00115 } 00116 G4cout << G4endl; 00117 #endif 00118 00119 BuildVoxelsWithinLimits(pVolume,pLimits,pCandidates); 00120 }
G4bool G4SmartVoxelHeader::AllSlicesEqual | ( | ) | const |
Definition at line 1281 of file G4SmartVoxelHeader.cc.
References fslices.
01282 { 01283 G4int noSlices = fslices.size(); 01284 G4SmartVoxelProxy* refProxy; 01285 01286 if (noSlices>1) 01287 { 01288 refProxy=fslices[0]; 01289 for (G4int i=1; i<noSlices; i++) 01290 { 01291 if (refProxy!=fslices[i]) 01292 { 01293 return false; 01294 } 01295 } 01296 } 01297 return true; 01298 }
void G4SmartVoxelHeader::BuildConsumedNodes | ( | G4int | nReplicas | ) | [protected] |
Definition at line 395 of file G4SmartVoxelHeader.cc.
References FatalException, fslices, G4Exception(), and JA::Insert().
Referenced by BuildReplicaVoxels().
00396 { 00397 G4int nNode, nVol; 00398 G4SmartVoxelNode *pNode; 00399 G4SmartVoxelProxy *pProxyNode; 00400 00401 // Create and fill nodes in temporary G4NodeVector (on stack) 00402 // 00403 G4NodeVector nodeList; 00404 nodeList.reserve(nReplicas); 00405 for (nNode=0; nNode<nReplicas; nNode++) 00406 { 00407 pNode=new G4SmartVoxelNode(nNode); 00408 if (!pNode) 00409 { 00410 G4Exception("G4SmartVoxelHeader::BuildConsumedNodes()", "GeomMgt0003", 00411 FatalException, "Node allocation error."); 00412 } 00413 nodeList.push_back(pNode); 00414 } 00415 for (nVol=0; nVol<nReplicas; nVol++) 00416 { 00417 nodeList[nVol]->Insert(nVol); // Insert replication of number 00418 } // identical to voxel number 00419 00420 // Create & fill proxy List `in place' by modifying instance data fslices 00421 // 00422 fslices.clear(); 00423 for (nNode=0; nNode<nReplicas; nNode++) 00424 { 00425 pProxyNode = new G4SmartVoxelProxy(nodeList[nNode]); 00426 if (!pProxyNode) 00427 { 00428 G4Exception("G4SmartVoxelHeader::BuildConsumedNodes()", "GeomMgt0003", 00429 FatalException, "Proxy node allocation error."); 00430 } 00431 fslices.push_back(pProxyNode); 00432 } 00433 }
void G4SmartVoxelHeader::BuildEquivalentSliceNos | ( | ) | [protected] |
Definition at line 583 of file G4SmartVoxelHeader.cc.
References fslices, G4SmartVoxelNode::SetMaxEquivalentSliceNo(), and G4SmartVoxelNode::SetMinEquivalentSliceNo().
Referenced by BuildReplicaVoxels(), and BuildVoxelsWithinLimits().
00584 { 00585 G4int sliceNo, minNo, maxNo, equivNo; 00586 G4int maxNode = fslices.size(); 00587 G4SmartVoxelNode *startNode, *sampleNode; 00588 for (sliceNo=0; sliceNo<maxNode; sliceNo++) 00589 { 00590 minNo = sliceNo; 00591 00592 // Get first node (see preconditions - will throw exception if a header) 00593 // 00594 startNode = fslices[minNo]->GetNode(); 00595 00596 // Find max equivalent 00597 // 00598 for (equivNo=minNo+1; equivNo<maxNode; equivNo++) 00599 { 00600 sampleNode = fslices[equivNo]->GetNode(); 00601 if (!((*startNode) == (*sampleNode))) { break; } 00602 } 00603 maxNo = equivNo-1; 00604 if (maxNo != minNo) 00605 { 00606 // Set min and max nos 00607 // 00608 for (equivNo=minNo; equivNo<=maxNo; equivNo++) 00609 { 00610 sampleNode = fslices[equivNo]->GetNode(); 00611 sampleNode->SetMinEquivalentSliceNo(minNo); 00612 sampleNode->SetMaxEquivalentSliceNo(maxNo); 00613 } 00614 // Advance outer loop to end of equivalent group 00615 // 00616 sliceNo = maxNo; 00617 } 00618 } 00619 }
G4ProxyVector * G4SmartVoxelHeader::BuildNodes | ( | G4LogicalVolume * | pVolume, | |
G4VoxelLimits | pLimits, | |||
const G4VolumeNosVector * | pCandidates, | |||
EAxis | pAxis | |||
) | [protected] |
Definition at line 750 of file G4SmartVoxelHeader.cc.
References G4VSolid::CalculateExtent(), G4VSolid::ComputeDimensions(), G4VPVParameterisation::ComputeSolid(), G4VPVParameterisation::ComputeTransformation(), FatalException, G4cout, G4endl, G4Exception(), G4LogicalVolume::GetDaughter(), G4VPhysicalVolume::GetLogicalVolume(), G4VoxelLimits::GetMaxExtent(), G4VoxelLimits::GetMinExtent(), G4LogicalVolume::GetName(), G4VPhysicalVolume::GetName(), G4LogicalVolume::GetNoDaughters(), G4VPhysicalVolume::GetParameterisation(), G4VPhysicalVolume::GetRotation(), G4LogicalVolume::GetSmartless(), G4LogicalVolume::GetSolid(), G4VPhysicalVolume::GetTranslation(), JA::Insert(), G4VoxelLimits::IsLimited(), G4VPhysicalVolume::IsReplicated(), and kMaxVoxelNodes.
Referenced by BuildReplicaVoxels(), and BuildVoxelsWithinLimits().
00754 { 00755 G4double motherMinExtent= kInfinity, motherMaxExtent= -kInfinity, 00756 targetMinExtent= kInfinity, targetMaxExtent= -kInfinity; 00757 G4VPhysicalVolume *pDaughter=0; 00758 G4VPVParameterisation *pParam=0; 00759 G4VSolid *targetSolid; 00760 G4AffineTransform targetTransform; 00761 G4bool replicated; 00762 G4int nCandidates = pCandidates->size(); 00763 G4int nVol, nNode, targetVolNo; 00764 G4VoxelLimits noLimits; 00765 00766 #ifdef G4GEOMETRY_VOXELDEBUG 00767 G4cout << "**** G4SmartVoxelHeader::BuildNodes" << G4endl 00768 << " Limits = " << pLimits << G4endl 00769 << " Axis = " << pAxis << G4endl 00770 << " Candidates = " << nCandidates << G4endl; 00771 #endif 00772 00773 // Compute extent of logical volume's solid along this axis 00774 // NOTE: results stored locally and not preserved/reused 00775 // 00776 G4VSolid* outerSolid = pVolume->GetSolid(); 00777 const G4AffineTransform origin; 00778 if( !outerSolid->CalculateExtent(pAxis, pLimits, origin, 00779 motherMinExtent, motherMaxExtent) ) 00780 { 00781 outerSolid->CalculateExtent(pAxis, noLimits, origin, 00782 motherMinExtent, motherMaxExtent); 00783 } 00784 G4VolumeExtentVector minExtents(nCandidates,0.); 00785 G4VolumeExtentVector maxExtents(nCandidates,0.); 00786 00787 if ( (pVolume->GetNoDaughters()==1) 00788 && (pVolume->GetDaughter(0)->IsReplicated()==true) ) 00789 { 00790 // Replication data not required: only parameterisation object 00791 // and volume no. List used 00792 // 00793 pDaughter = pVolume->GetDaughter(0); 00794 pParam = pDaughter->GetParameterisation(); 00795 if (!pParam) 00796 { 00797 std::ostringstream message; 00798 message << "PANIC! - Missing parameterisation." << G4endl 00799 << " Replicated volume with no parameterisation object !"; 00800 G4Exception("G4SmartVoxelHeader::BuildNodes()", "GeomMgt0003", 00801 FatalException, message); 00802 return 0; 00803 } 00804 00805 // Setup daughter's transformations 00806 // 00807 targetTransform = G4AffineTransform(pDaughter->GetRotation(), 00808 pDaughter->GetTranslation()); 00809 replicated = true; 00810 } 00811 else 00812 { 00813 replicated = false; 00814 } 00815 00816 // Compute extents 00817 // 00818 for (nVol=0; nVol<nCandidates; nVol++) 00819 { 00820 targetVolNo=(*pCandidates)[nVol]; 00821 if (replicated == false) 00822 { 00823 pDaughter=pVolume->GetDaughter(targetVolNo); 00824 00825 // Setup daughter's transformations 00826 // 00827 targetTransform = G4AffineTransform(pDaughter->GetRotation(), 00828 pDaughter->GetTranslation()); 00829 // Get underlying (and setup) solid 00830 // 00831 targetSolid = pDaughter->GetLogicalVolume()->GetSolid(); 00832 } 00833 else 00834 { 00835 // Find solid 00836 // 00837 targetSolid = pParam->ComputeSolid(targetVolNo,pDaughter); 00838 00839 // Setup solid 00840 // 00841 targetSolid->ComputeDimensions(pParam,targetVolNo,pDaughter); 00842 00843 // Setup transform 00844 // 00845 pParam->ComputeTransformation(targetVolNo,pDaughter); 00846 targetTransform = G4AffineTransform(pDaughter->GetRotation(), 00847 pDaughter->GetTranslation()); 00848 } 00849 // Calculate extents 00850 // 00851 if(!targetSolid->CalculateExtent(pAxis, pLimits, targetTransform, 00852 targetMinExtent, targetMaxExtent)) 00853 { 00854 targetSolid->CalculateExtent(pAxis, noLimits, targetTransform, 00855 targetMinExtent,targetMaxExtent); 00856 } 00857 minExtents[nVol] = targetMinExtent; 00858 maxExtents[nVol] = targetMaxExtent; 00859 00860 #ifdef G4GEOMETRY_VOXELDEBUG 00861 G4cout << "---------------------------------------------------" << G4endl 00862 << " Volume = " << pDaughter->GetName() << G4endl 00863 << " Min Extent = " << targetMinExtent << G4endl 00864 << " Max Extent = " << targetMaxExtent << G4endl 00865 << "---------------------------------------------------" << G4endl; 00866 #endif 00867 00868 // Check not entirely outside mother when processing toplevel nodes 00869 // 00870 if ( (!pLimits.IsLimited()) && ((targetMaxExtent<=motherMinExtent) 00871 ||(targetMinExtent>=motherMaxExtent)) ) 00872 { 00873 std::ostringstream message; 00874 message << "PANIC! - Overlapping daughter with mother volume." << G4endl 00875 << " Daughter physical volume " 00876 << pDaughter->GetName() << G4endl 00877 << " is entirely outside mother logical volume " 00878 << pVolume->GetName() << " !!"; 00879 G4Exception("G4SmartVoxelHeader::BuildNodes()", "GeomMgt0002", 00880 FatalException, message); 00881 } 00882 00883 #ifdef G4GEOMETRY_VOXELDEBUG 00884 // Check for straddling volumes when debugging. 00885 // If a volume is >kStraddlePercent percent over the mother 00886 // boundary, print a warning. 00887 // 00888 if (!pLimits.IsLimited()) 00889 { 00890 G4double width; 00891 G4int kStraddlePercent=5; 00892 width = maxExtents[nVol]-minExtents[nVol]; 00893 if ( (((motherMinExtent-minExtents[nVol])*100/width) > kStraddlePercent) 00894 ||(((maxExtents[nVol]-motherMaxExtent)*100/width) > kStraddlePercent) ) 00895 { 00896 G4cout << "**** G4SmartVoxelHeader::BuildNodes" << G4endl 00897 << " WARNING : Daughter # " << nVol 00898 << " name = " << pDaughter->GetName() << G4endl 00899 << " Crosses mother boundary of logical volume, name = " 00900 << pVolume->GetName() << G4endl 00901 << " by more than " << kStraddlePercent 00902 << "%" << G4endl; 00903 } 00904 } 00905 #endif 00906 } 00907 00908 // Extents of all daughters known 00909 00910 // Calculate minimum slice width, only including volumes inside the limits 00911 // 00912 G4double minWidth = kInfinity; 00913 G4double currentWidth; 00914 for (nVol=0; nVol<nCandidates; nVol++) 00915 { 00916 // currentWidth should -always- be a positive value. Inaccurate computed extent 00917 // from the solid or situations of malformed geometries (overlaps) may lead to 00918 // negative values and therefore unpredictable crashes ! 00919 // 00920 currentWidth = std::abs(maxExtents[nVol]-minExtents[nVol]); 00921 if ( (currentWidth<minWidth) 00922 && (maxExtents[nVol]>=pLimits.GetMinExtent(pAxis)) 00923 && (minExtents[nVol]<=pLimits.GetMaxExtent(pAxis)) ) 00924 { 00925 minWidth = currentWidth; 00926 } 00927 } 00928 00929 // No. of Nodes formula - nearest integer to 00930 // mother width/half min daughter width +1 00931 // 00932 G4double noNodesExactD = ((motherMaxExtent-motherMinExtent)*2.0/minWidth)+1.0; 00933 00934 // Compare with "smartless quality", i.e. the average number of slices 00935 // used per contained volume. 00936 // 00937 G4double smartlessComputed = noNodesExactD / nCandidates; 00938 G4double smartlessUser = pVolume->GetSmartless(); 00939 G4double smartless = (smartlessComputed <= smartlessUser) 00940 ? smartlessComputed : smartlessUser; 00941 G4double noNodesSmart = smartless*nCandidates; 00942 G4int noNodesExactI = G4int(noNodesSmart); 00943 G4int noNodes = ((noNodesSmart-noNodesExactI)>=0.5) 00944 ? noNodesExactI+1 : noNodesExactI; 00945 if( noNodes == 0 ) { noNodes=1; } 00946 00947 #ifdef G4GEOMETRY_VOXELDEBUG 00948 G4cout << " Smartless computed = " << smartlessComputed << G4endl 00949 << " Smartless volume = " << smartlessUser 00950 << " => # Smartless = " << smartless << G4endl; 00951 G4cout << " Min width = " << minWidth 00952 << " => # Nodes = " << noNodes << G4endl; 00953 #endif 00954 00955 if (noNodes>kMaxVoxelNodes) 00956 { 00957 noNodes=kMaxVoxelNodes; 00958 #ifdef G4GEOMETRY_VOXELDEBUG 00959 G4cout << " Nodes Clipped to = " << kMaxVoxelNodes << G4endl; 00960 #endif 00961 } 00962 G4double nodeWidth = (motherMaxExtent-motherMinExtent)/noNodes; 00963 00964 // Create G4VoxelNodes. Will Add proxies before setting fslices 00965 // 00966 G4NodeVector* nodeList = new G4NodeVector(); 00967 if (!nodeList) 00968 { 00969 G4Exception("G4SmartVoxelHeader::BuildNodes()", "GeomMgt0003", 00970 FatalException, "NodeList allocation error."); 00971 return 0; 00972 } 00973 nodeList->reserve(noNodes); 00974 00975 for (nNode=0; nNode<noNodes; nNode++) 00976 { 00977 G4SmartVoxelNode *pNode; 00978 pNode = new G4SmartVoxelNode(nNode); 00979 if (!pNode) 00980 { 00981 G4Exception("G4SmartVoxelHeader::BuildNodes()", "GeomMgt0003", 00982 FatalException, "Node allocation error."); 00983 return 0; 00984 } 00985 nodeList->push_back(pNode); 00986 } 00987 00988 // All nodes created (empty) 00989 00990 // Fill nodes: Step through extent lists 00991 // 00992 for (nVol=0; nVol<nCandidates; nVol++) 00993 { 00994 G4int nodeNo, minContainingNode, maxContainingNode; 00995 minContainingNode = G4int((minExtents[nVol]-motherMinExtent)/nodeWidth); 00996 maxContainingNode = G4int((maxExtents[nVol]-motherMinExtent)/nodeWidth); 00997 00998 // Only add nodes that are inside the limits of the axis 00999 // 01000 if ( (maxContainingNode>=0) && (minContainingNode<noNodes) ) 01001 { 01002 // If max extent is on max boundary => maxContainingNode=noNodes: 01003 // should be one less as nodeList has noNodes entries 01004 // 01005 if (maxContainingNode>=noNodes) 01006 { 01007 maxContainingNode = noNodes-1; 01008 } 01009 // 01010 // Protection against protruding volumes 01011 // 01012 if (minContainingNode<0) 01013 { 01014 minContainingNode=0; 01015 } 01016 for (nodeNo=minContainingNode; nodeNo<=maxContainingNode; nodeNo++) 01017 { 01018 (*nodeList)[nodeNo]->Insert((*pCandidates)[nVol]); 01019 } 01020 } 01021 } 01022 01023 // All nodes filled 01024 01025 // Create proxy List : caller has deletion responsibility 01026 // (but we must delete nodeList *itself* - not the contents) 01027 // 01028 G4ProxyVector* proxyList = new G4ProxyVector(); 01029 if (!proxyList) 01030 { 01031 G4Exception("G4SmartVoxelHeader::BuildNodes()", "GeomMgt0003", 01032 FatalException, "Proxy list allocation error."); 01033 return 0; 01034 } 01035 proxyList->reserve(noNodes); 01036 01037 // 01038 // Fill proxy List 01039 // 01040 for (nNode=0; nNode<noNodes; nNode++) 01041 { 01042 // Get rid of possible excess capacity in the internal node vector 01043 // 01044 ((*nodeList)[nNode])->Shrink(); 01045 G4SmartVoxelProxy* pProxyNode = new G4SmartVoxelProxy((*nodeList)[nNode]); 01046 if (!pProxyNode) 01047 { 01048 G4Exception("G4SmartVoxelHeader::BuildNodes()", "GeomMgt0003", 01049 FatalException, "Proxy node allocation failed."); 01050 return 0; 01051 } 01052 proxyList->push_back(pProxyNode); 01053 } 01054 delete nodeList; 01055 return proxyList; 01056 }
void G4SmartVoxelHeader::BuildReplicaVoxels | ( | G4LogicalVolume * | pVolume | ) | [protected] |
Definition at line 267 of file G4SmartVoxelHeader.cc.
References BuildConsumedNodes(), BuildEquivalentSliceNos(), BuildNodes(), BuildVoxelsWithinLimits(), G4VSolid::CalculateExtent(), CollectEquivalentNodes(), FatalException, faxis, fmaxExtent, fminExtent, fparamAxis, fslices, G4endl, G4Exception(), G4LogicalVolume::GetDaughter(), G4LogicalVolume::GetName(), G4LogicalVolume::GetNoDaughters(), G4VPhysicalVolume::GetReplicationData(), G4LogicalVolume::GetSolid(), G4VPhysicalVolume::IsReplicated(), kPhi, kRho, kUndefined, kXAxis, kYAxis, and kZAxis.
Referenced by G4SmartVoxelHeader().
00268 { 00269 G4VPhysicalVolume *pDaughter=0; 00270 00271 // Replication data 00272 // 00273 EAxis axis; 00274 G4int nReplicas; 00275 G4double width,offset; 00276 G4bool consuming; 00277 00278 // Consistency check: pVolume should contain single replicated volume 00279 // 00280 if ( (pVolume->GetNoDaughters()==1) 00281 && (pVolume->GetDaughter(0)->IsReplicated()==true) ) 00282 { 00283 // Obtain replication data 00284 // 00285 pDaughter=pVolume->GetDaughter(0); 00286 pDaughter->GetReplicationData(axis,nReplicas,width,offset,consuming); 00287 fparamAxis = axis; 00288 if ( consuming==false ) 00289 { 00290 G4VoxelLimits limits; // Create `unlimited' limits object 00291 G4VolumeNosVector targetList; 00292 targetList.reserve(nReplicas); 00293 for (G4int i=0; i<nReplicas; i++) 00294 { 00295 targetList.push_back(i); 00296 } 00297 if (axis != kUndefined) 00298 { 00299 // Apply voxelisation along the specified axis only 00300 00301 G4ProxyVector* pSlices=BuildNodes(pVolume,limits,&targetList,axis); 00302 faxis = axis; 00303 fslices = *pSlices; 00304 delete pSlices; 00305 00306 // Calculate and set min and max extents given our axis 00307 // 00308 const G4AffineTransform origin; 00309 pVolume->GetSolid()->CalculateExtent(faxis, limits, origin, 00310 fminExtent, fmaxExtent); 00311 // Calculate equivalent nos 00312 // 00313 BuildEquivalentSliceNos(); 00314 CollectEquivalentNodes(); // Collect common nodes 00315 } 00316 else 00317 { 00318 // Build voxels similarly as for normal placements considering 00319 // all three cartesian axes. 00320 00321 BuildVoxelsWithinLimits(pVolume, limits, &targetList); 00322 } 00323 } 00324 else 00325 { 00326 // Replication is consuming -> Build voxels directly 00327 // 00328 // o Cartesian axes - range is -width*nREplicas/2 to +width*nREplicas/2 00329 // nReplicas replications result 00330 // o Radial axis (rho) = range is 0 to width*nReplicas 00331 // nReplicas replications result 00332 // o Phi axi - range is offset to offset+width*nReplicas radians 00333 // 00334 // Equivalent slices no computation & collection not required - all 00335 // slices are different 00336 // 00337 switch (axis) 00338 { 00339 case kXAxis: 00340 case kYAxis: 00341 case kZAxis: 00342 fminExtent = -width*nReplicas*0.5; 00343 fmaxExtent = width*nReplicas*0.5; 00344 break; 00345 case kRho: 00346 fminExtent = offset; 00347 fmaxExtent = width*nReplicas+offset; 00348 break; 00349 case kPhi: 00350 fminExtent = offset; 00351 fmaxExtent = offset+width*nReplicas; 00352 break; 00353 default: 00354 G4Exception("G4SmartVoxelHeader::BuildReplicaVoxels()", 00355 "GeomMgt0002", FatalException, "Illegal axis."); 00356 break; 00357 } 00358 faxis = axis; // Set axis 00359 BuildConsumedNodes(nReplicas); 00360 if ( (axis==kXAxis) || (axis==kYAxis) || (axis==kZAxis) ) 00361 { 00362 // Sanity check on extent 00363 // 00364 G4double emin = kInfinity, emax = -kInfinity; 00365 G4VoxelLimits limits; 00366 G4AffineTransform origin; 00367 pVolume->GetSolid()->CalculateExtent(axis, limits, origin, emin, emax); 00368 if ( (std::fabs((emin-fminExtent)/fminExtent) + 00369 std::fabs((emax-fmaxExtent)/fmaxExtent)) > 0.05) 00370 { 00371 std::ostringstream message; 00372 message << "Sanity check: wrong solid extent." << G4endl 00373 << " Replicated geometry, logical volume: " 00374 << pVolume->GetName(); 00375 G4Exception("G4SmartVoxelHeader::BuildReplicaVoxels", 00376 "GeomMgt0002", FatalException, message); 00377 } 00378 } 00379 } 00380 } 00381 else 00382 { 00383 G4Exception("G4SmartVoxelHeader::BuildReplicaVoxels", "GeomMgt0002", 00384 FatalException, "Only one replicated daughter is allowed !"); 00385 } 00386 }
void G4SmartVoxelHeader::BuildVoxels | ( | G4LogicalVolume * | pVolume | ) | [protected] |
Definition at line 247 of file G4SmartVoxelHeader.cc.
References BuildVoxelsWithinLimits(), and G4LogicalVolume::GetNoDaughters().
Referenced by G4SmartVoxelHeader().
00248 { 00249 G4VoxelLimits limits; // Create `unlimited' limits object 00250 G4int nDaughters = pVolume->GetNoDaughters(); 00251 00252 G4VolumeNosVector targetList; 00253 targetList.reserve(nDaughters); 00254 for (G4int i=0; i<nDaughters; i++) 00255 { 00256 targetList.push_back(i); 00257 } 00258 BuildVoxelsWithinLimits(pVolume, limits, &targetList); 00259 }
void G4SmartVoxelHeader::BuildVoxelsWithinLimits | ( | G4LogicalVolume * | pVolume, | |
G4VoxelLimits | pLimits, | |||
const G4VolumeNosVector * | pCandidates | |||
) | [protected] |
Definition at line 443 of file G4SmartVoxelHeader.cc.
References BuildEquivalentSliceNos(), BuildNodes(), G4VSolid::CalculateExtent(), CalculateQuality(), CollectEquivalentNodes(), FatalException, faxis, fmaxExtent, fminExtent, fslices, G4cout, G4endl, G4Exception(), G4LogicalVolume::GetName(), G4LogicalVolume::GetSolid(), G4VoxelLimits::IsLimited(), kXAxis, kYAxis, kZAxis, and RefineNodes().
Referenced by BuildReplicaVoxels(), BuildVoxels(), and G4SmartVoxelHeader().
00446 { 00447 // Choose best axis for slicing by: 00448 // 1. Trying all unlimited cartesian axes 00449 // 2. Select axis which gives greatest no slices 00450 00451 G4ProxyVector *pGoodSlices=0, *pTestSlices, *tmpSlices; 00452 G4double goodSliceScore=kInfinity, testSliceScore; 00453 EAxis goodSliceAxis = kXAxis; 00454 EAxis testAxis = kXAxis; 00455 G4int node, maxNode, iaxis; 00456 G4VoxelLimits noLimits; 00457 00458 // Try all non-limited cartesian axes 00459 // 00460 for (iaxis=0; iaxis<3; iaxis++) 00461 { 00462 switch(iaxis) 00463 { 00464 case 0: 00465 testAxis = kXAxis; 00466 break; 00467 case 1: 00468 testAxis = kYAxis; 00469 break; 00470 case 2: 00471 testAxis = kZAxis; 00472 break; 00473 } 00474 if (!pLimits.IsLimited(testAxis)) 00475 { 00476 pTestSlices = BuildNodes(pVolume,pLimits,pCandidates,testAxis); 00477 testSliceScore = CalculateQuality(pTestSlices); 00478 if ( (!pGoodSlices) || (testSliceScore<goodSliceScore) ) 00479 { 00480 goodSliceAxis = testAxis; 00481 goodSliceScore = testSliceScore; 00482 tmpSlices = pGoodSlices; 00483 pGoodSlices = pTestSlices; 00484 pTestSlices = tmpSlices; 00485 } 00486 if (pTestSlices) 00487 { 00488 // Destroy pTestSlices and all its contents 00489 // 00490 maxNode=pTestSlices->size(); 00491 for (node=0; node<maxNode; node++) 00492 { 00493 delete (*pTestSlices)[node]->GetNode(); 00494 } 00495 G4SmartVoxelProxy* tmpProx; 00496 while (pTestSlices->size()>0) 00497 { 00498 tmpProx = pTestSlices->back(); 00499 pTestSlices->pop_back(); 00500 for (G4ProxyVector::iterator i=pTestSlices->begin(); 00501 i!=pTestSlices->end(); ) 00502 { 00503 if (*i==tmpProx) 00504 { 00505 i = pTestSlices->erase(i); 00506 } 00507 else 00508 { 00509 ++i; 00510 } 00511 } 00512 if ( tmpProx ) { delete tmpProx; } 00513 } 00514 delete pTestSlices; 00515 } 00516 } 00517 } 00518 // Check for error case.. when limits already 3d, 00519 // so cannot select a new axis 00520 // 00521 if (!pGoodSlices) 00522 { 00523 G4Exception("G4SmartVoxelHeader::BuildVoxelsWithinLimits()", 00524 "GeomMgt0002", FatalException, 00525 "Cannot select more than 3 axis for optimisation."); 00526 return; 00527 } 00528 00529 // 00530 // We have selected pGoodSlices, with a score testSliceScore 00531 // 00532 00533 // Store chosen axis, slice ptr 00534 // 00535 fslices=*pGoodSlices; // Set slice information, copy ptrs in collection 00536 delete pGoodSlices; // Destroy slices vector, but not contained 00537 // proxies or nodes 00538 faxis=goodSliceAxis; 00539 00540 #ifdef G4GEOMETRY_VOXELDEBUG 00541 G4cout << G4endl << " Volume = " << pVolume->GetName() 00542 << G4endl << " Selected axis = " << faxis << G4endl; 00543 for (size_t islice=0; islice<fslices.size(); islice++) 00544 { 00545 G4cout << " Node #" << islice << " = {"; 00546 for (G4int j=0; j<fslices[islice]->GetNode()->GetNoContained(); j++) 00547 { 00548 G4cout << " " << fslices[islice]->GetNode()->GetVolume(j); 00549 } 00550 G4cout << " }" << G4endl; 00551 } 00552 G4cout << G4endl; 00553 #endif 00554 00555 // Calculate and set min and max extents given our axis 00556 // 00557 G4VSolid* outerSolid = pVolume->GetSolid(); 00558 const G4AffineTransform origin; 00559 if(!outerSolid->CalculateExtent(faxis,pLimits,origin,fminExtent,fmaxExtent)) 00560 { 00561 outerSolid->CalculateExtent(faxis,noLimits,origin,fminExtent,fmaxExtent); 00562 } 00563 00564 // Calculate equivalent nos 00565 // 00566 BuildEquivalentSliceNos(); 00567 CollectEquivalentNodes(); // Collect common nodes 00568 RefineNodes(pVolume,pLimits); // Refine nodes creating headers 00569 00570 // No common headers can exist because collapsed by construction 00571 }
G4double G4SmartVoxelHeader::CalculateQuality | ( | G4ProxyVector * | pSlice | ) | [protected] |
Definition at line 1073 of file G4SmartVoxelHeader.cc.
References FatalException, G4cout, G4endl, G4Exception(), and G4SmartVoxelNode::GetNoContained().
Referenced by BuildVoxelsWithinLimits().
01074 { 01075 G4double quality; 01076 G4int nNodes = pSlice->size(); 01077 G4int noContained, maxContained=0, sumContained=0, sumNonEmptyNodes=0; 01078 G4SmartVoxelNode *node; 01079 01080 for (G4int i=0; i<nNodes; i++) 01081 { 01082 if ((*pSlice)[i]->IsNode()) 01083 { 01084 // Definitely a node. Add info to running totals 01085 // 01086 node = (*pSlice)[i]->GetNode(); 01087 noContained = node->GetNoContained(); 01088 if (noContained) 01089 { 01090 sumNonEmptyNodes++; 01091 sumContained += noContained; 01092 // 01093 // Calc maxContained for statistics 01094 // 01095 if (noContained>maxContained) 01096 { 01097 maxContained = noContained; 01098 } 01099 } 01100 } 01101 else 01102 { 01103 G4Exception("G4SmartVoxelHeader::CalculateQuality()", "GeomMgt0001", 01104 FatalException, "Not applicable to replicated volumes."); 01105 } 01106 } 01107 01108 // Calculate quality with protection against no non-empty nodes 01109 // 01110 if (sumNonEmptyNodes) 01111 { 01112 quality = sumContained/sumNonEmptyNodes; 01113 } 01114 else 01115 { 01116 quality = kInfinity; 01117 } 01118 01119 #ifdef G4GEOMETRY_VOXELDEBUG 01120 G4cout << "**** G4SmartVoxelHeader::CalculateQuality" << G4endl 01121 << " Quality = " << quality << G4endl 01122 << " Nodes = " << nNodes 01123 << " of which " << sumNonEmptyNodes << " non empty" << G4endl 01124 << " Max Contained = " << maxContained << G4endl; 01125 #endif 01126 01127 return quality; 01128 }
void G4SmartVoxelHeader::CollectEquivalentHeaders | ( | ) | [protected] |
Definition at line 677 of file G4SmartVoxelHeader.cc.
References fslices, G4cout, G4endl, G4SmartVoxelProxy::GetHeader(), GetMaxEquivalentSliceNo(), and G4SmartVoxelProxy::IsHeader().
00678 { 00679 G4int sliceNo, maxNo, equivNo; 00680 G4int maxNode = fslices.size(); 00681 G4SmartVoxelHeader *equivHeader, *sampleHeader; 00682 G4SmartVoxelProxy *equivProxy; 00683 00684 for (sliceNo=0; sliceNo<maxNode; sliceNo++) 00685 { 00686 equivProxy = fslices[sliceNo]; 00687 if (equivProxy->IsHeader()) 00688 { 00689 equivHeader = equivProxy->GetHeader(); 00690 maxNo = equivHeader->GetMaxEquivalentSliceNo(); 00691 if (maxNo != sliceNo) 00692 { 00693 // Attempt collection between sliceNo and maxNo inclusive: 00694 // look for common headers. All slices between sliceNo and maxNo 00695 // are guaranteed to be headers but may not have equal contents 00696 // 00697 #ifdef G4GEOMETRY_VOXELDEBUG 00698 G4cout << "**** G4SmartVoxelHeader::CollectEquivalentHeaders" << G4endl 00699 << " Collecting Headers ="; 00700 #endif 00701 for (equivNo=sliceNo+1; equivNo<=maxNo; equivNo++) 00702 { 00703 sampleHeader = fslices[equivNo]->GetHeader(); 00704 if ( (*sampleHeader) == (*equivHeader) ) 00705 { 00706 #ifdef G4GEOMETRY_VOXELDEBUG 00707 G4cout << " " << equivNo; 00708 #endif 00709 // Delete sampleHeader + proxy and replace with equivHeader/Proxy 00710 // 00711 delete sampleHeader; 00712 delete fslices[equivNo]; 00713 fslices[equivNo] = equivProxy; 00714 } 00715 else 00716 { 00717 // Not equal. Set this header to be 00718 // the current header for comparisons 00719 // 00720 equivProxy = fslices[equivNo]; 00721 equivHeader = equivProxy->GetHeader(); 00722 } 00723 00724 } 00725 #ifdef G4GEOMETRY_VOXELDEBUG 00726 G4cout << G4endl; 00727 #endif 00728 // Skip past examined slices 00729 // 00730 sliceNo = maxNo; 00731 } 00732 } 00733 } 00734 }
void G4SmartVoxelHeader::CollectEquivalentNodes | ( | ) | [protected] |
Definition at line 630 of file G4SmartVoxelHeader.cc.
References fslices, G4cout, G4endl, G4SmartVoxelNode::GetMaxEquivalentSliceNo(), and G4SmartVoxelProxy::GetNode().
Referenced by BuildReplicaVoxels(), and BuildVoxelsWithinLimits().
00631 { 00632 G4int sliceNo, maxNo, equivNo; 00633 G4int maxNode=fslices.size(); 00634 G4SmartVoxelNode *equivNode; 00635 G4SmartVoxelProxy *equivProxy; 00636 00637 for (sliceNo=0; sliceNo<maxNode; sliceNo++) 00638 { 00639 equivProxy=fslices[sliceNo]; 00640 00641 // Assumption (see preconditions): all slices are nodes 00642 // 00643 equivNode = equivProxy->GetNode(); 00644 maxNo = equivNode->GetMaxEquivalentSliceNo(); 00645 if (maxNo != sliceNo) 00646 { 00647 #ifdef G4GEOMETRY_VOXELDEBUG 00648 G4cout << "**** G4SmartVoxelHeader::CollectEquivalentNodes" << G4endl 00649 << " Collecting Nodes = " 00650 << sliceNo << " - " << maxNo << G4endl; 00651 #endif 00652 // Do collection between sliceNo and maxNo inclusive 00653 // 00654 for (equivNo=sliceNo+1; equivNo<=maxNo; equivNo++) 00655 { 00656 delete fslices[equivNo]->GetNode(); 00657 delete fslices[equivNo]; 00658 fslices[equivNo] = equivProxy; 00659 } 00660 sliceNo = maxNo; 00661 } 00662 } 00663 }
EAxis G4SmartVoxelHeader::GetAxis | ( | ) | const [inline] |
Definition at line 59 of file G4SmartVoxelHeader.icc.
References faxis.
Referenced by G4VoxelNavigation::LocateNextVoxel(), operator==(), G4ParameterisedNavigation::ParamVoxelLocate(), G4VoxelSafety::SafetyForVoxelHeader(), and G4VoxelNavigation::VoxelLocate().
00060 { 00061 return faxis; 00062 }
G4int G4SmartVoxelHeader::GetMaxEquivalentSliceNo | ( | ) | const [inline] |
Definition at line 35 of file G4SmartVoxelHeader.icc.
References fmaxEquivalent.
Referenced by CollectEquivalentHeaders(), and G4VoxelSafety::SafetyForVoxelHeader().
00036 { 00037 return fmaxEquivalent; 00038 }
G4double G4SmartVoxelHeader::GetMaxExtent | ( | ) | const [inline] |
Definition at line 71 of file G4SmartVoxelHeader.icc.
References fmaxExtent.
Referenced by operator==(), G4ParameterisedNavigation::ParamVoxelLocate(), G4VoxelSafety::SafetyForVoxelHeader(), and G4VoxelNavigation::VoxelLocate().
00072 { 00073 return fmaxExtent; 00074 }
G4int G4SmartVoxelHeader::GetMinEquivalentSliceNo | ( | ) | const [inline] |
Definition at line 47 of file G4SmartVoxelHeader.icc.
References fminEquivalent.
Referenced by G4VoxelSafety::SafetyForVoxelHeader().
00048 { 00049 return fminEquivalent; 00050 }
G4double G4SmartVoxelHeader::GetMinExtent | ( | ) | const [inline] |
Definition at line 77 of file G4SmartVoxelHeader.icc.
References fminExtent.
Referenced by G4ParameterisedNavigation::ComputeSafety(), G4VoxelNavigation::ComputeVoxelSafety(), G4VoxelNavigation::LocateNextVoxel(), operator==(), G4ParameterisedNavigation::ParamVoxelLocate(), G4VoxelSafety::SafetyForVoxelHeader(), and G4VoxelNavigation::VoxelLocate().
00078 { 00079 return fminExtent; 00080 }
G4int G4SmartVoxelHeader::GetNoSlices | ( | ) | const [inline] |
Definition at line 83 of file G4SmartVoxelHeader.icc.
References fslices.
Referenced by G4SmartVoxelStat::CountHeadsAndNodes(), operator==(), G4ParameterisedNavigation::ParamVoxelLocate(), G4VoxelSafety::SafetyForVoxelHeader(), and G4VoxelNavigation::VoxelLocate().
00084 { 00085 return fslices.size(); 00086 }
EAxis G4SmartVoxelHeader::GetParamAxis | ( | ) | const [inline] |
Definition at line 65 of file G4SmartVoxelHeader.icc.
References fparamAxis.
Referenced by G4ParameterisedNavigation::ParamVoxelLocate().
00066 { 00067 return fparamAxis; 00068 }
G4SmartVoxelProxy * G4SmartVoxelHeader::GetSlice | ( | G4int | n | ) | const [inline] |
Definition at line 89 of file G4SmartVoxelHeader.icc.
References fslices.
Referenced by G4ParameterisedNavigation::ComputeSafety(), G4SmartVoxelStat::CountHeadsAndNodes(), operator==(), G4ParameterisedNavigation::ParamVoxelLocate(), G4VoxelSafety::SafetyForVoxelHeader(), and G4VoxelNavigation::VoxelLocate().
G4bool G4SmartVoxelHeader::operator== | ( | const G4SmartVoxelHeader & | pHead | ) | const |
Definition at line 183 of file G4SmartVoxelHeader.cc.
References GetAxis(), G4SmartVoxelProxy::GetHeader(), GetMaxExtent(), GetMinExtent(), G4SmartVoxelProxy::GetNode(), GetNoSlices(), GetSlice(), G4SmartVoxelProxy::IsHeader(), and G4SmartVoxelProxy::IsNode().
00184 { 00185 if ( (GetAxis() == pHead.GetAxis()) 00186 && (GetNoSlices() == pHead.GetNoSlices()) 00187 && (GetMinExtent() == pHead.GetMinExtent()) 00188 && (GetMaxExtent() == pHead.GetMaxExtent()) ) 00189 { 00190 G4int node, maxNode; 00191 G4SmartVoxelProxy *leftProxy, *rightProxy; 00192 G4SmartVoxelHeader *leftHeader, *rightHeader; 00193 G4SmartVoxelNode *leftNode, *rightNode; 00194 00195 maxNode=GetNoSlices(); 00196 for (node=0; node<maxNode; node++) 00197 { 00198 leftProxy = GetSlice(node); 00199 rightProxy = pHead.GetSlice(node); 00200 if (leftProxy->IsHeader()) 00201 { 00202 if (rightProxy->IsNode()) 00203 { 00204 return false; 00205 } 00206 else 00207 { 00208 leftHeader = leftProxy->GetHeader(); 00209 rightHeader = rightProxy->GetHeader(); 00210 if (!(*leftHeader==*rightHeader)) 00211 { 00212 return false; 00213 } 00214 } 00215 } 00216 else 00217 { 00218 if (rightProxy->IsHeader()) 00219 { 00220 return false; 00221 } 00222 else 00223 { 00224 leftNode = leftProxy->GetNode(); 00225 rightNode = rightProxy->GetNode(); 00226 if (!(*leftNode==*rightNode)) 00227 { 00228 return false; 00229 } 00230 } 00231 } 00232 } 00233 return true; 00234 } 00235 else 00236 { 00237 return false; 00238 } 00239 }
void G4SmartVoxelHeader::RefineNodes | ( | G4LogicalVolume * | pVolume, | |
G4VoxelLimits | pLimits | |||
) | [protected] |
Definition at line 1139 of file G4SmartVoxelHeader.cc.
References G4VoxelLimits::AddLimit(), FatalException, faxis, fmaxExtent, fminExtent, fslices, G4cout, G4endl, G4Exception(), G4SmartVoxelHeader(), G4SmartVoxelNode::GetMaxEquivalentSliceNo(), G4SmartVoxelNode::GetMinEquivalentSliceNo(), G4SmartVoxelNode::GetNoContained(), G4SmartVoxelProxy::GetNode(), G4SmartVoxelNode::GetVolume(), G4VoxelLimits::IsXLimited(), G4VoxelLimits::IsYLimited(), G4VoxelLimits::IsZLimited(), kMinVoxelVolumesLevel2, kMinVoxelVolumesLevel3, SetMaxEquivalentSliceNo(), and SetMinEquivalentSliceNo().
Referenced by BuildVoxelsWithinLimits().
01141 { 01142 G4int refinedDepth=0, minVolumes; 01143 G4int maxNode = fslices.size(); 01144 01145 if (pLimits.IsXLimited()) 01146 { 01147 refinedDepth++; 01148 } 01149 if (pLimits.IsYLimited()) 01150 { 01151 refinedDepth++; 01152 } 01153 if (pLimits.IsZLimited()) 01154 { 01155 refinedDepth++; 01156 } 01157 01158 // Calculate minimum number of volumes necessary to refine 01159 // 01160 switch (refinedDepth) 01161 { 01162 case 0: 01163 minVolumes=kMinVoxelVolumesLevel2; 01164 break; 01165 case 1: 01166 minVolumes=kMinVoxelVolumesLevel3; 01167 break; 01168 default: 01169 minVolumes=10000; // catch refinedDepth=3 and errors 01170 break; 01171 } 01172 01173 if (refinedDepth<2) 01174 { 01175 G4int targetNo, noContainedDaughters, minNo, maxNo, replaceNo, i; 01176 G4double sliceWidth = (fmaxExtent-fminExtent)/maxNode; 01177 G4VoxelLimits newLimits; 01178 G4SmartVoxelNode* targetNode; 01179 G4SmartVoxelProxy* targetNodeProxy; 01180 G4SmartVoxelHeader* replaceHeader; 01181 G4SmartVoxelProxy* replaceHeaderProxy; 01182 G4VolumeNosVector* targetList; 01183 G4SmartVoxelProxy* lastProxy; 01184 01185 for (targetNo=0; targetNo<maxNode; targetNo++) 01186 { 01187 // Assume all slices are nodes (see preconditions) 01188 // 01189 targetNodeProxy = fslices[targetNo]; 01190 targetNode = targetNodeProxy->GetNode(); 01191 01192 if (targetNode->GetNoContained() >= minVolumes) 01193 { 01194 noContainedDaughters = targetNode->GetNoContained(); 01195 targetList = new G4VolumeNosVector(); 01196 if (!targetList) 01197 { 01198 G4Exception("G4SmartVoxelHeader::RefineNodes()", 01199 "GeomMgt0003", FatalException, 01200 "Target volume node list allocation error."); 01201 return; 01202 } 01203 targetList->reserve(noContainedDaughters); 01204 for (i=0; i<noContainedDaughters; i++) 01205 { 01206 targetList->push_back(targetNode->GetVolume(i)); 01207 } 01208 minNo = targetNode->GetMinEquivalentSliceNo(); 01209 maxNo = targetNode->GetMaxEquivalentSliceNo(); 01210 01211 #ifdef G4GEOMETRY_VOXELDEBUG 01212 G4cout << "**** G4SmartVoxelHeader::RefineNodes" << G4endl 01213 << " Refining nodes " << minNo 01214 << " - " << maxNo << " inclusive" << G4endl; 01215 #endif 01216 if (minNo > maxNo) // Delete node and list to be replaced 01217 { // and avoid further action ... 01218 delete targetNode; 01219 delete targetList; 01220 return; 01221 } 01222 01223 // Delete node proxies at start of collected sets of nodes/headers 01224 // 01225 lastProxy=0; 01226 for (replaceNo=minNo; replaceNo<=maxNo; replaceNo++) 01227 { 01228 if (lastProxy != fslices[replaceNo]) 01229 { 01230 lastProxy=fslices[replaceNo]; 01231 delete lastProxy; 01232 } 01233 } 01234 // Delete node to be replaced 01235 // 01236 delete targetNode; 01237 01238 // Create new headers + proxies and replace in fslices 01239 // 01240 newLimits = pLimits; 01241 newLimits.AddLimit(faxis,fminExtent+sliceWidth*minNo, 01242 fminExtent+sliceWidth*(maxNo+1)); 01243 replaceHeader = new G4SmartVoxelHeader(pVolume,newLimits, 01244 targetList,replaceNo); 01245 if (!replaceHeader) 01246 { 01247 G4Exception("G4SmartVoxelHeader::RefineNodes()", "GeomMgt0003", 01248 FatalException, "Refined VoxelHeader allocation error."); 01249 return; 01250 } 01251 replaceHeader->SetMinEquivalentSliceNo(minNo); 01252 replaceHeader->SetMaxEquivalentSliceNo(maxNo); 01253 replaceHeaderProxy = new G4SmartVoxelProxy(replaceHeader); 01254 if (!replaceHeaderProxy) 01255 { 01256 G4Exception("G4SmartVoxelHeader::RefineNodes()", "GeomMgt0003", 01257 FatalException, "Refined VoxelProxy allocation error."); 01258 return; 01259 } 01260 for (replaceNo=minNo; replaceNo<=maxNo; replaceNo++) 01261 { 01262 fslices[replaceNo] = replaceHeaderProxy; 01263 } 01264 // Finished replacing current `equivalent' group 01265 // 01266 delete targetList; 01267 targetNo=maxNo; 01268 } 01269 } 01270 } 01271 }
void G4SmartVoxelHeader::SetMaxEquivalentSliceNo | ( | G4int | pMax | ) | [inline] |
Definition at line 41 of file G4SmartVoxelHeader.icc.
References fmaxEquivalent.
Referenced by RefineNodes().
00042 { 00043 fmaxEquivalent=pMax; 00044 }
void G4SmartVoxelHeader::SetMinEquivalentSliceNo | ( | G4int | pMin | ) | [inline] |
Definition at line 53 of file G4SmartVoxelHeader.icc.
References fminEquivalent.
Referenced by RefineNodes().
00054 { 00055 fminEquivalent=pMin; 00056 }
std::ostream& operator<< | ( | std::ostream & | s, | |
const G4SmartVoxelHeader & | h | |||
) | [friend] |
Definition at line 1304 of file G4SmartVoxelHeader.cc.
01305 { 01306 os << "Axis = " << G4int(h.faxis) << G4endl; 01307 G4SmartVoxelProxy *collectNode=0, *collectHead=0; 01308 G4int collectNodeNo=0; 01309 G4int collectHeadNo=0; 01310 size_t i, j; 01311 G4bool haveHeaders=false; 01312 01313 for (i=0; i<h.fslices.size(); i++) 01314 { 01315 os << "Slice #" << i << " = "; 01316 if (h.fslices[i]->IsNode()) 01317 { 01318 if (h.fslices[i]!=collectNode) 01319 { 01320 os << "{"; 01321 for (G4int k=0; k<h.fslices[i]->GetNode()->GetNoContained(); k++) 01322 { 01323 os << " " << h.fslices[i]->GetNode()->GetVolume(k); 01324 } 01325 os << " }" << G4endl; 01326 collectNode = h.fslices[i]; 01327 collectNodeNo = i; 01328 } 01329 else 01330 { 01331 os << "As slice #" << collectNodeNo << G4endl; 01332 } 01333 } 01334 else 01335 { 01336 haveHeaders=true; 01337 if (h.fslices[i] != collectHead) 01338 { 01339 os << "Header" << G4endl; 01340 collectHead = h.fslices[i]; 01341 collectHeadNo = i; 01342 } 01343 else 01344 { 01345 os << "As slice #" << collectHeadNo << G4endl; 01346 } 01347 } 01348 } 01349 01350 if (haveHeaders) 01351 { 01352 collectHead=0; 01353 for (j=0; j<h.fslices.size(); j++) 01354 { 01355 if (h.fslices[j]->IsHeader()) 01356 { 01357 os << "Header at Slice #" << j << " = "; 01358 if (h.fslices[j] != collectHead) 01359 { 01360 os << G4endl 01361 << (*(h.fslices[j]->GetHeader())); 01362 collectHead = h.fslices[j]; 01363 collectHeadNo = j; 01364 } 01365 else 01366 { 01367 os << "As slice #" << collectHeadNo << G4endl; 01368 } 01369 } 01370 } 01371 } 01372 return os; 01373 }
EAxis G4SmartVoxelHeader::faxis [protected] |
Definition at line 191 of file G4SmartVoxelHeader.hh.
Referenced by BuildReplicaVoxels(), BuildVoxelsWithinLimits(), GetAxis(), operator<<(), and RefineNodes().
G4int G4SmartVoxelHeader::fmaxEquivalent [protected] |
Definition at line 188 of file G4SmartVoxelHeader.hh.
Referenced by GetMaxEquivalentSliceNo(), and SetMaxEquivalentSliceNo().
G4double G4SmartVoxelHeader::fmaxExtent [protected] |
Definition at line 194 of file G4SmartVoxelHeader.hh.
Referenced by BuildReplicaVoxels(), BuildVoxelsWithinLimits(), GetMaxExtent(), and RefineNodes().
G4int G4SmartVoxelHeader::fminEquivalent [protected] |
Definition at line 187 of file G4SmartVoxelHeader.hh.
Referenced by GetMinEquivalentSliceNo(), and SetMinEquivalentSliceNo().
G4double G4SmartVoxelHeader::fminExtent [protected] |
Definition at line 195 of file G4SmartVoxelHeader.hh.
Referenced by BuildReplicaVoxels(), BuildVoxelsWithinLimits(), GetMinExtent(), and RefineNodes().
EAxis G4SmartVoxelHeader::fparamAxis [protected] |
Definition at line 191 of file G4SmartVoxelHeader.hh.
Referenced by BuildReplicaVoxels(), and GetParamAxis().
G4ProxyVector G4SmartVoxelHeader::fslices [protected] |
Definition at line 198 of file G4SmartVoxelHeader.hh.
Referenced by AllSlicesEqual(), BuildConsumedNodes(), BuildEquivalentSliceNos(), BuildReplicaVoxels(), BuildVoxelsWithinLimits(), CollectEquivalentHeaders(), CollectEquivalentNodes(), GetNoSlices(), GetSlice(), operator<<(), RefineNodes(), and ~G4SmartVoxelHeader().