G4SmartVoxelHeader Class Reference

#include <G4SmartVoxelHeader.hh>


Public Member Functions

 G4SmartVoxelHeader (G4LogicalVolume *pVolume, G4int pSlice=0)
 ~G4SmartVoxelHeader ()
G4int GetMaxEquivalentSliceNo () const
void SetMaxEquivalentSliceNo (G4int pMax)
G4int GetMinEquivalentSliceNo () const
void SetMinEquivalentSliceNo (G4int pMin)
EAxis GetAxis () const
EAxis GetParamAxis () const
G4double GetMaxExtent () const
G4double GetMinExtent () const
G4int GetNoSlices () const
G4SmartVoxelProxyGetSlice (G4int n) const
G4bool AllSlicesEqual () const
G4bool operator== (const G4SmartVoxelHeader &pHead) const

Protected Member Functions

 G4SmartVoxelHeader (G4LogicalVolume *pVolume, const G4VoxelLimits &pLimits, const G4VolumeNosVector *pCandidates, G4int pSlice=0)
void BuildVoxels (G4LogicalVolume *pVolume)
void BuildReplicaVoxels (G4LogicalVolume *pVolume)
void BuildConsumedNodes (G4int nReplicas)
void BuildVoxelsWithinLimits (G4LogicalVolume *pVolume, G4VoxelLimits pLimits, const G4VolumeNosVector *pCandidates)
void BuildEquivalentSliceNos ()
void CollectEquivalentNodes ()
void CollectEquivalentHeaders ()
G4ProxyVectorBuildNodes (G4LogicalVolume *pVolume, G4VoxelLimits pLimits, const G4VolumeNosVector *pCandidates, EAxis pAxis)
G4double CalculateQuality (G4ProxyVector *pSlice)
void RefineNodes (G4LogicalVolume *pVolume, G4VoxelLimits pLimits)

Protected Attributes

G4int fminEquivalent
G4int fmaxEquivalent
EAxis faxis
EAxis fparamAxis
G4double fmaxExtent
G4double fminExtent
G4ProxyVector fslices

Friends

std::ostream & operator<< (std::ostream &s, const G4SmartVoxelHeader &h)


Detailed Description

Definition at line 78 of file G4SmartVoxelHeader.hh.


Constructor & Destructor Documentation

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 }


Member Function Documentation

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().

00090 {
00091   return fslices[n];
00092 }

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 }


Friends And Related Function Documentation

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 }


Field Documentation

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().


The documentation for this class was generated from the following files:
Generated on Mon May 27 17:53:23 2013 for Geant4 by  doxygen 1.4.7