Geant4  10.00.p02
G4LogicalVolume.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id: G4LogicalVolume.cc 78050 2013-12-03 08:17:33Z gcosmo $
28 //
29 //
30 // class G4LogicalVolume Implementation
31 //
32 // History:
33 // 15.01.13 G.Cosmo, A.Dotti: Modified for thread-safety for MT
34 // 01.03.05 G.Santin: Added flag for optional propagation of GetMass()
35 // 17.05.02 G.Cosmo: Added flag for optional optimisation
36 // 12.02.99 S.Giani: Default initialization of voxelization quality
37 // 04.08.97 P.M.DeFreitas: Added methods for parameterised simulation
38 // 19.08.96 P.Kent: Modified for G4VSensitive Detector
39 // 11.07.95 P.Kent: Initial version
40 // --------------------------------------------------------------------
41 
42 #include "G4LogicalVolume.hh"
43 #ifdef NO_INLINE
44 #define inline
45 #include "G4LogicalVolume.icc"
46 #undef inline
47 #endif
48 
49 #include "G4LogicalVolumeStore.hh"
50 #include "G4VSolid.hh"
51 #include "G4Material.hh"
52 #include "G4VPVParameterisation.hh"
53 #include "G4VisAttributes.hh"
54 
55 #include "G4UnitsTable.hh"
56 
57 // This static member is thread local. For each thread, it points to the
58 // array of G4LVData instances.
59 //
60 template <class G4LVData> G4ThreadLocal
62 
64 : fSolid(0),fSensitiveDetector(0),fFieldManager(0),
65  fMaterial(0),fMass(0.),fCutsCouple(0)
66 {;}
67 
68 // This new field helps to use the class G4LVManager
69 //
71 
72 // ********************************************************************
73 // InitialiseWorker
74 //
75 // This method is similar to the constructor. It is used by each worker
76 // thread to achieve the same effect as that of the master thread exept
77 // to register the new created instance. This method is invoked explicitly.
78 // It does not create a new G4LogicalVolume instance. It only assign the value
79 // for the fields encapsulated by the class G4LVData.
80 // ********************************************************************
81 //
83 InitialiseWorker( G4LogicalVolume* /*pMasterObject*/,
84  G4VSolid* pSolid,
85  G4VSensitiveDetector* pSDetector)
86 {
88 
89  SetSolid(pSolid);
90  SetSensitiveDetector(pSDetector); // How this object is available now ?
91  AssignFieldManager(fFieldManager); // Should be set - but a per-thread copy is not available yet
92  // G4MT_fmanager= fFieldManager;
93  // Must not call SetFieldManager(fFieldManager, false); which propagates FieldMgr
94 
95 #ifdef CLONE_FIELD_MGR
96  // Create a field FieldManager by cloning
97  G4FieldManager workerFldMgr= fFieldManager->GetWorkerClone(G4bool* created);
98  if( created || (GetFieldManager()!=workerFldMgr) )
99  {
100  SetFieldManager(fFieldManager, false); // which propagates FieldMgr
101  }else{
102  // Field manager existed and is equal to current one
103  AssignFieldManager(workerFldMgr);
104  }
105 #endif
106 }
107 
108 // ********************************************************************
109 // TerminateWorker
110 //
111 // This method is similar to the destructor. It is used by each worker
112 // thread to achieve the partial effect as that of the master thread.
113 // For G4LogicalVolume instances, nothing more to do here.
114 // ********************************************************************
115 //
117 TerminateWorker( G4LogicalVolume* /*pMasterObject*/)
118 {
119 }
120 
121 // ********************************************************************
122 // GetSubInstanceManager
123 //
124 // Returns the private data instance manager.
125 // ********************************************************************
126 //
128 {
129  return subInstanceManager;
130 }
131 
132 // ********************************************************************
133 // Constructor - sets member data and adds to logical Store,
134 // voxel pointer for optimisation set to 0 by default.
135 // Initialises daughter vector to 0 length.
136 // ********************************************************************
137 //
139  G4Material* pMaterial,
140  const G4String& name,
141  G4FieldManager* pFieldMgr,
142  G4VSensitiveDetector* pSDetector,
143  G4UserLimits* pULimits,
144  G4bool optimise )
145  : fDaughters(0,(G4VPhysicalVolume*)0),
146  fVoxel(0), fOptimise(optimise), fRootRegion(false), fLock(false),
147  fSmartless(2.), fVisAttributes(0), fRegion(0)
148 {
149  // Initialize 'Shadow'/master pointers - for use in copying to workers
150  fSolid = pSolid;
151  fSensitiveDetector = pSDetector;
152  fFieldManager = pFieldMgr;
153 
155  AssignFieldManager(pFieldMgr); // G4MT_fmanager = pFieldMgr;
156 
157  // fMasterFieldMgr= pFieldMgr;
158  G4MT_mass = 0.;
159  G4MT_ccouple = 0;
160 
161  SetSolid(pSolid);
162  SetMaterial(pMaterial);
163  SetName(name);
164  SetSensitiveDetector(pSDetector);
165  SetUserLimits(pULimits);
166  //
167  // Add to store
168  //
170 }
171 
172 // ********************************************************************
173 // Fake default constructor - sets only member data and allocates memory
174 // for usage restricted to object persistency.
175 // ********************************************************************
176 //
178  : fDaughters(0,(G4VPhysicalVolume*)0),
179  fName(""), fUserLimits(0),
180  fVoxel(0), fOptimise(true), fRootRegion(false), fLock(false),
181  fSmartless(2.), fVisAttributes(0), fRegion(0), fBiasWeight(0.),
182  fSolid(0), fSensitiveDetector(0), fFieldManager(0)
183 {
185 
186  // G4MT_solid = 0,
187  SetSolid(0);
188  SetSensitiveDetector(0); // G4MT_sdetector = 0;
189  SetFieldManager(0, false); // G4MT_fmanager = 0;
190  SetMaterial(0); // G4MT_material = 0;
191  // this->SetMass(0); //
192  G4MT_mass = 0.;
193  // this->SetCutsCouple(0);
194  G4MT_ccouple = 0;
195 
196  // Add to store
197  //
199 }
200 
201 // ********************************************************************
202 // Destructor - Removes itself from solid Store
203 // NOTE: Not virtual
204 // ********************************************************************
205 //
207 {
208  if (!fLock && fRootRegion) // De-register root region first if not locked
209  { // and flagged as root logical-volume
210  fRegion->RemoveRootLogicalVolume(this, true);
211  }
213 }
214 
215 // ********************************************************************
216 // SetFieldManager
217 // ********************************************************************
218 //
219 void
221  G4bool forceAllDaughters)
222 {
223  // G4MT_fmanager = pNewFieldMgr;
224  AssignFieldManager(pNewFieldMgr);
225 
226  G4int NoDaughters = GetNoDaughters();
227  while ( (NoDaughters--)>0 )
228  {
229  G4LogicalVolume* DaughterLogVol;
230  DaughterLogVol = GetDaughter(NoDaughters)->GetLogicalVolume();
231  if ( forceAllDaughters || (DaughterLogVol->GetFieldManager() == 0) )
232  {
233  DaughterLogVol->SetFieldManager(pNewFieldMgr, forceAllDaughters);
234  }
235  }
236 }
237 
238 
239 // ********************************************************************
240 // IsAncestor
241 //
242 // Finds out if the current logical volume is an ancestor of a given
243 // physical volume
244 // ********************************************************************
245 //
246 G4bool
248 {
249  G4bool isDaughter = IsDaughter(aVolume);
250  if (!isDaughter)
251  {
252  for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
253  itDau != fDaughters.end(); itDau++)
254  {
255  isDaughter = (*itDau)->GetLogicalVolume()->IsAncestor(aVolume);
256  if (isDaughter) break;
257  }
258  }
259  return isDaughter;
260 }
261 
262 // ********************************************************************
263 // TotalVolumeEntities
264 //
265 // Returns the total number of physical volumes (replicated or placed)
266 // in the tree represented by the current logical volume.
267 // ********************************************************************
268 //
270 {
271  G4int vols = 1;
272  for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
273  itDau != fDaughters.end(); itDau++)
274  {
275  G4VPhysicalVolume* physDaughter = (*itDau);
276  vols += physDaughter->GetMultiplicity()
277  *physDaughter->GetLogicalVolume()->TotalVolumeEntities();
278  }
279  return vols;
280 }
281 
282 // ********************************************************************
283 // GetMass
284 //
285 // Returns the mass of the logical volume tree computed from the
286 // estimated geometrical volume of each solid and material associated
287 // to the logical volume and its daughters.
288 // NOTE: the computation may require considerable amount of time,
289 // depending from the complexity of the geometry tree.
290 // The returned value is cached and can be used for successive
291 // calls (default), unless recomputation is forced by providing
292 // 'true' for the boolean argument in input. Computation should
293 // be forced if the geometry setup has changed after the previous
294 // call. By setting the 'propagate' boolean flag to 'false' the
295 // method returns the mass of the present logical volume only
296 // (subtracted for the volume occupied by the daughter volumes).
297 // The extra argument 'parMaterial' is internally used to
298 // consider cases of geometrical parameterisations by material.
299 // ********************************************************************
300 //
302  G4bool propagate,
303  G4Material* parMaterial)
304 {
305  // Return the cached non-zero value, if not forced
306  //
307  if ( (G4MT_mass) && (!forced) ) return G4MT_mass;
308 
309  // Global density and computed mass associated to the logical
310  // volume without considering its daughters
311  //
312  G4Material* logMaterial = parMaterial ? parMaterial : GetMaterial(); // G4MT_material;
313  if (!logMaterial)
314  {
315  std::ostringstream message;
316  message << "No material associated to the logical volume: " << fName << " !"
317  << G4endl
318  << "Sorry, cannot compute the mass ...";
319  G4Exception("G4LogicalVolume::GetMass()", "GeomMgt0002",
320  FatalException, message);
321  return 0;
322  }
323  if (! GetSolid() ) // !G4MT_solid)
324  {
325  std::ostringstream message;
326  message << "No solid is associated to the logical volume: " << fName << " !"
327  << G4endl
328  << "Sorry, cannot compute the mass ...";
329  G4Exception("G4LogicalVolume::GetMass()", "GeomMgt0002",
330  FatalException, message);
331  return 0;
332  }
333  G4double globalDensity = logMaterial->GetDensity();
334  G4double motherMass= GetSolid()->GetCubicVolume() * globalDensity;
335 
336  // G4MT_mass =
337  // SetMass( motherMmass );
338  G4double massSum= motherMass;
339 
340  // For each daughter in the tree, subtract the mass occupied
341  // and if required by the propagate flag, add the real daughter's
342  // one computed recursively
343 
344  for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
345  itDau != fDaughters.end(); itDau++)
346  {
347  G4VPhysicalVolume* physDaughter = (*itDau);
348  G4LogicalVolume* logDaughter = physDaughter->GetLogicalVolume();
349  G4double subMass=0.;
350  G4VSolid* daughterSolid = 0;
351  G4Material* daughterMaterial = 0;
352 
353  // Compute the mass to subtract and to add for each daughter
354  // considering its multiplicity (i.e. replicated or not) and
355  // eventually its parameterisation (by solid and/or by material)
356  //
357  for (G4int i=0; i<physDaughter->GetMultiplicity(); i++)
358  {
360  physParam = physDaughter->GetParameterisation();
361  if (physParam)
362  {
363  daughterSolid = physParam->ComputeSolid(i, physDaughter);
364  daughterSolid->ComputeDimensions(physParam, i, physDaughter);
365  daughterMaterial = physParam->ComputeMaterial(i, physDaughter);
366  }
367  else
368  {
369  daughterSolid = logDaughter->GetSolid();
370  daughterMaterial = logDaughter->GetMaterial();
371  }
372  subMass = daughterSolid->GetCubicVolume() * globalDensity;
373 
374  // Subtract the daughter's portion for the mass and, if required,
375  // add the real daughter's mass computed recursively
376  //
377  massSum -= subMass;
378  if (propagate)
379  {
380  massSum += logDaughter->GetMass(true, true, daughterMaterial);
381  }
382  }
383  }
384  G4MT_mass= massSum;
385  return massSum;
386 }
387 
389 {
391 }
virtual G4Material * ComputeMaterial(const G4int repNo, G4VPhysicalVolume *currentVol, const G4VTouchable *parentTouch=0)
G4String fName
Definition: G4AttUtils.hh:55
G4FieldManager * fFieldManager
static G4GEOM_DLL G4LVManager subInstanceManager
virtual void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
Definition: G4VSolid.cc:137
static void DeRegister(G4LogicalVolume *pVolume)
G4bool IsAncestor(const G4VPhysicalVolume *p) const
G4Material * GetMaterial() const
virtual G4VSolid * ComputeSolid(const G4int, G4VPhysicalVolume *)
G4String name
Definition: TRTMaterials.hh:40
static const G4LVManager & GetSubInstanceManager()
void SetUserLimits(G4UserLimits *pULimits)
virtual G4double GetCubicVolume()
Definition: G4VSolid.cc:188
G4double GetDensity() const
Definition: G4Material.hh:178
G4VPhysicalVolume * GetDaughter(const G4int i) const
void SetSolid(G4VSolid *pSolid)
#define G4ThreadLocal
Definition: tls.hh:52
G4int CreateSubInstance()
int G4int
Definition: G4Types.hh:78
void InitialiseWorker(G4LogicalVolume *ptrMasterObject, G4VSolid *pSolid, G4VSensitiveDetector *pSDetector)
void SetFieldManager(G4FieldManager *pFieldMgr, G4bool forceToAllDaughters)
void AssignFieldManager(G4FieldManager *fldMgr)
G4FieldManager * GetFieldManager() const
bool G4bool
Definition: G4Types.hh:79
void SlaveCopySubInstanceArray()
virtual G4VPVParameterisation * GetParameterisation() const =0
G4int TotalVolumeEntities() const
G4LogicalVolume(G4VSolid *pSolid, G4Material *pMaterial, const G4String &name, G4FieldManager *pFieldMgr=0, G4VSensitiveDetector *pSDetector=0, G4UserLimits *pULimits=0, G4bool optimise=true)
G4int GetNoDaughters() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
void TerminateWorker(G4LogicalVolume *ptrMasterObject)
G4LogicalVolume * GetLogicalVolume() const
G4bool IsDaughter(const G4VPhysicalVolume *p) const
void SetName(const G4String &pName)
virtual G4int GetMultiplicity() const
#define G4endl
Definition: G4ios.hh:61
G4double GetMass(G4bool forced=false, G4bool propagate=true, G4Material *parMaterial=0)
double G4double
Definition: G4Types.hh:76
G4VSensitiveDetector * fSensitiveDetector
void SetMaterial(G4Material *pMaterial)
static void Register(G4LogicalVolume *pVolume)
void RemoveRootLogicalVolume(G4LogicalVolume *lv, G4bool scan=true)
Definition: G4Region.cc:283
void SetVisAttributes(const G4VisAttributes *pVA)
void SetSensitiveDetector(G4VSensitiveDetector *pSDetector)
G4VSolid * GetSolid() const
G4PhysicalVolumeList fDaughters
const G4VisAttributes * fVisAttributes