Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4LogicalVolume.cc
이 파일의 문서화 페이지로 가기
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 103096 2017-03-15 15:21: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 #include "G4LogicalVolumeStore.hh"
44 #include "G4VSolid.hh"
45 #include "G4Material.hh"
46 #include "G4VPVParameterisation.hh"
47 #include "G4VisAttributes.hh"
48 
49 #include "G4UnitsTable.hh"
50 
52 : fSolid(0),fSensitiveDetector(0),fFieldManager(0),
53  fMaterial(0),fMass(0.),fCutsCouple(0)
54 {;}
55 
56 // This new field helps to use the class G4LVManager
57 //
59 
60 // These macros change the references to fields that are now encapsulated
61 // in the class G4LVData.
62 //
63 #define G4MT_solid ((subInstanceManager.offset[instanceID]).fSolid)
64 #define G4MT_sdetector ((subInstanceManager.offset[instanceID]).fSensitiveDetector)
65 #define G4MT_fmanager ((subInstanceManager.offset[instanceID]).fFieldManager)
66 #define G4MT_material ((subInstanceManager.offset[instanceID]).fMaterial)
67 #define G4MT_mass ((subInstanceManager.offset[instanceID]).fMass)
68 #define G4MT_ccouple ((subInstanceManager.offset[instanceID]).fCutsCouple)
69 #define G4MT_instance (subInstanceManager.offset[instanceID])
70 
71 // ********************************************************************
72 // Constructor - sets member data and adds to logical Store,
73 // voxel pointer for optimisation set to 0 by default.
74 // Initialises daughter vector to 0 length.
75 // ********************************************************************
76 //
78  G4Material* pMaterial,
79  const G4String& name,
80  G4FieldManager* pFieldMgr,
81  G4VSensitiveDetector* pSDetector,
82  G4UserLimits* pULimits,
83  G4bool optimise )
84  : fDaughters(0,(G4VPhysicalVolume*)0),
85  fVoxel(0), fOptimise(optimise), fRootRegion(false), fLock(false),
86  fSmartless(2.), fVisAttributes(0), fRegion(0), fBiasWeight(1.)
87 {
88  // Initialize 'Shadow'/master pointers - for use in copying to workers
89  fSolid = pSolid;
90  fSensitiveDetector = pSDetector;
91  fFieldManager = pFieldMgr;
92 
94  AssignFieldManager(pFieldMgr); // G4MT_fmanager = pFieldMgr;
95 
96  // fMasterFieldMgr= pFieldMgr;
97  G4MT_mass = 0.;
98  G4MT_ccouple = 0;
99 
100  SetSolid(pSolid);
101  SetMaterial(pMaterial);
102  SetName(name);
103  SetSensitiveDetector(pSDetector);
104  SetUserLimits(pULimits);
105 
106  // Initialize 'Shadow' data structure - for use by object persistency
107  lvdata = new G4LVData();
108  lvdata->fSolid = pSolid;
109  lvdata->fMaterial = pMaterial;
110 
111  //
112  // Add to store
113  //
115 }
116 
117 // ********************************************************************
118 // Fake default constructor - sets only member data and allocates memory
119 // for usage restricted to object persistency.
120 // ********************************************************************
121 //
123  : fDaughters(0,(G4VPhysicalVolume*)0),
124  fName(""), fUserLimits(0),
125  fVoxel(0), fOptimise(true), fRootRegion(false), fLock(false),
126  fSmartless(2.), fVisAttributes(0), fRegion(0), fBiasWeight(1.),
127  fSolid(0), fSensitiveDetector(0), fFieldManager(0), lvdata(0)
128 {
130 
131  SetSensitiveDetector(0); // G4MT_sdetector = 0;
132  SetFieldManager(0, false); // G4MT_fmanager = 0;
133 
134  G4MT_mass = 0.;
135  G4MT_ccouple = 0;
136 
137  // Add to store
138  //
140 }
141 
142 // ********************************************************************
143 // Destructor - Removes itself from solid Store
144 // NOTE: Not virtual
145 // ********************************************************************
146 //
148 {
149  if (!fLock && fRootRegion) // De-register root region first if not locked
150  { // and flagged as root logical-volume
151  fRegion->RemoveRootLogicalVolume(this, true);
152  }
153  delete lvdata;
155 }
156 
157 // ********************************************************************
158 // InitialiseWorker
159 //
160 // This method is similar to the constructor. It is used by each worker
161 // thread to achieve the same effect as that of the master thread exept
162 // to register the new created instance. This method is invoked explicitly.
163 // It does not create a new G4LogicalVolume instance. It only assign the value
164 // for the fields encapsulated by the class G4LVData.
165 // ********************************************************************
166 //
168 InitialiseWorker( G4LogicalVolume* /*pMasterObject*/,
169  G4VSolid* pSolid,
170  G4VSensitiveDetector* pSDetector)
171 {
173 
174  SetSolid(pSolid);
175  SetSensitiveDetector(pSDetector); // How this object is available now ?
176  AssignFieldManager(fFieldManager); // Should be set - but a per-thread copy is not available yet
177  // G4MT_fmanager= fFieldManager;
178  // Must not call SetFieldManager(fFieldManager, false); which propagates FieldMgr
179 
180 #ifdef CLONE_FIELD_MGR
181  // Create a field FieldManager by cloning
182  G4FieldManager workerFldMgr= fFieldManager->GetWorkerClone(G4bool* created);
183  if( created || (GetFieldManager()!=workerFldMgr) )
184  {
185  SetFieldManager(fFieldManager, false); // which propagates FieldMgr
186  }else{
187  // Field manager existed and is equal to current one
188  AssignFieldManager(workerFldMgr);
189  }
190 #endif
191 }
192 
193 // ********************************************************************
194 // Clean
195 // ********************************************************************
196 //
198 {
200 }
201 
202 // ********************************************************************
203 // TerminateWorker
204 //
205 // This method is similar to the destructor. It is used by each worker
206 // thread to achieve the partial effect as that of the master thread.
207 // For G4LogicalVolume instances, nothing more to do here.
208 // ********************************************************************
209 //
211 TerminateWorker( G4LogicalVolume* /*pMasterObject*/)
212 {
213 }
214 
215 // ********************************************************************
216 // GetSubInstanceManager
217 //
218 // Returns the private data instance manager.
219 // ********************************************************************
220 //
222 {
223  return subInstanceManager;
224 }
225 
226 // ********************************************************************
227 // GetFieldManager
228 // ********************************************************************
229 //
231 {
232  return G4MT_fmanager;
233 }
234 
235 // ********************************************************************
236 // AssignFieldManager
237 // ********************************************************************
238 //
240 {
241  G4MT_fmanager= fldMgr;
243 }
244 
245 // ********************************************************************
246 // IsExtended
247 // ********************************************************************
248 //
250 {
251  return false;
252 }
253 
254 // ********************************************************************
255 // SetFieldManager
256 // ********************************************************************
257 //
258 void
260  G4bool forceAllDaughters)
261 {
262  // G4MT_fmanager = pNewFieldMgr;
263  AssignFieldManager(pNewFieldMgr);
264 
265  G4int NoDaughters = GetNoDaughters();
266  while ( (NoDaughters--)>0 )
267  {
268  G4LogicalVolume* DaughterLogVol;
269  DaughterLogVol = GetDaughter(NoDaughters)->GetLogicalVolume();
270  if ( forceAllDaughters || (DaughterLogVol->GetFieldManager() == 0) )
271  {
272  DaughterLogVol->SetFieldManager(pNewFieldMgr, forceAllDaughters);
273  }
274  }
275 }
276 
277 // ********************************************************************
278 // AddDaughter
279 // ********************************************************************
280 //
282 {
283  if( !fDaughters.empty() && fDaughters[0]->IsReplicated() )
284  {
285  std::ostringstream message;
286  message << "ERROR - Attempt to place a volume in a mother volume" << G4endl
287  << " already containing a replicated volume." << G4endl
288  << " A volume can either contain several placements" << G4endl
289  << " or a unique replica or parameterised volume !" << G4endl
290  << " Mother logical volume: " << GetName() << G4endl
291  << " Placing volume: " << pNewDaughter->GetName() << G4endl;
292  G4Exception("G4LogicalVolume::AddDaughter()", "GeomMgt0002",
293  FatalException, message,
294  "Replica or parameterised volume must be the only daughter !");
295  }
296 
297  // Invalidate previous calculation of mass - if any - for all threads
298  G4MT_mass = 0.;
299  // SignalVolumeChange(); // fVolumeChanged= true;
300  fDaughters.push_back(pNewDaughter);
301 
302  G4LogicalVolume* pDaughterLogical = pNewDaughter->GetLogicalVolume();
303 
304  // Propagate the Field Manager, if the daughter has no field Manager.
305  //
306  G4FieldManager* pDaughterFieldManager = pDaughterLogical->GetFieldManager();
307 
308  if( pDaughterFieldManager == 0 )
309  {
310  pDaughterLogical->SetFieldManager(G4MT_fmanager, false);
311  }
312  if (fRegion)
313  {
314  PropagateRegion();
315  fRegion->RegionModified(true);
316  }
317 }
318 
319 // ********************************************************************
320 // RemoveDaughter
321 // ********************************************************************
322 //
324 {
325  G4PhysicalVolumeList::iterator i;
326  for ( i=fDaughters.begin(); i!=fDaughters.end(); ++i )
327  {
328  if (**i==*p)
329  {
330  fDaughters.erase(i);
331  break;
332  }
333  }
334  if (fRegion)
335  {
336  fRegion->RegionModified(true);
337  }
338  G4MT_mass = 0.;
339 }
340 
341 // ********************************************************************
342 // ClearDaughters
343 // ********************************************************************
344 //
346 {
347  fDaughters.erase(fDaughters.begin(), fDaughters.end());
348  if (fRegion)
349  {
350  fRegion->RegionModified(true);
351  }
352  G4MT_mass = 0.;
353 }
354 
355 // ********************************************************************
356 // ResetMass
357 // ********************************************************************
358 //
360 {
361  G4MT_mass= 0.0;
362 }
363 
364 // ********************************************************************
365 // GetSolid
366 // ********************************************************************
367 //
369 {
370  return instLVdata.fSolid;
371 }
372 
374 {
375  // return G4MT_solid;
376  // return ((subInstanceManager.offset[instanceID]).fSolid);
377  return this->GetSolid( subInstanceManager.offset[instanceID] );
378 }
379 
380 // ********************************************************************
381 // SetSolid
382 // ********************************************************************
383 //
385 {
386 
387  // ((subInstanceManager.offset[instanceID]).fSolid) = pSolid;
388  G4MT_solid=pSolid;
389  // G4MT_mass = 0.;
390  this->ResetMass();
391 }
392 
393 void G4LogicalVolume::SetSolid(G4LVData &instLVdata, G4VSolid *pSolid)
394 {
395  instLVdata.fSolid = pSolid;
396  // G4MT_solid=pSolid;
397  instLVdata.fMass= 0;
398  // A fast way to reset the mass ... ie G4MT_mass = 0.;
399 }
400 
401 // ********************************************************************
402 // GetMaterial
403 // ********************************************************************
404 //
406 {
407  return G4MT_material;
408 }
409 
410 // ********************************************************************
411 // SetMaterial
412 // ********************************************************************
413 //
415 {
416  G4MT_material=pMaterial;
417  G4MT_mass = 0.;
418 }
419 
420 // ********************************************************************
421 // UpdateMaterial
422 // ********************************************************************
423 //
425 {
426  G4MT_material=pMaterial;
427  if(fRegion) { G4MT_ccouple = fRegion->FindCouple(pMaterial); }
428  G4MT_mass = 0.;
429 }
430 
431 // ********************************************************************
432 // GetSensitiveDetector
433 // ********************************************************************
434 //
436 {
437  return G4MT_sdetector;
438 }
439 
440 // ********************************************************************
441 // SetSensitiveDetector
442 // ********************************************************************
443 //
445 {
446  G4MT_sdetector = pSDetector;
448 }
449 
450 // ********************************************************************
451 // GetMaterialCutsCouple
452 // ********************************************************************
453 //
455 {
456  return G4MT_ccouple;
457 }
458 
459 // ********************************************************************
460 // SetMaterialCutsCouple
461 // ********************************************************************
462 //
464 {
465  G4MT_ccouple = cuts;
466 }
467 
468 // ********************************************************************
469 // IsAncestor
470 //
471 // Finds out if the current logical volume is an ancestor of a given
472 // physical volume
473 // ********************************************************************
474 //
475 G4bool
477 {
478  G4bool isDaughter = IsDaughter(aVolume);
479  if (!isDaughter)
480  {
481  for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
482  itDau != fDaughters.end(); itDau++)
483  {
484  isDaughter = (*itDau)->GetLogicalVolume()->IsAncestor(aVolume);
485  if (isDaughter) break;
486  }
487  }
488  return isDaughter;
489 }
490 
491 // ********************************************************************
492 // TotalVolumeEntities
493 //
494 // Returns the total number of physical volumes (replicated or placed)
495 // in the tree represented by the current logical volume.
496 // ********************************************************************
497 //
499 {
500  G4int vols = 1;
501  for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
502  itDau != fDaughters.end(); itDau++)
503  {
504  G4VPhysicalVolume* physDaughter = (*itDau);
505  vols += physDaughter->GetMultiplicity()
506  *physDaughter->GetLogicalVolume()->TotalVolumeEntities();
507  }
508  return vols;
509 }
510 
511 // ********************************************************************
512 // GetMass
513 //
514 // Returns the mass of the logical volume tree computed from the
515 // estimated geometrical volume of each solid and material associated
516 // to the logical volume and its daughters.
517 // NOTE: the computation may require considerable amount of time,
518 // depending from the complexity of the geometry tree.
519 // The returned value is cached and can be used for successive
520 // calls (default), unless recomputation is forced by providing
521 // 'true' for the boolean argument in input. Computation should
522 // be forced if the geometry setup has changed after the previous
523 // call. By setting the 'propagate' boolean flag to 'false' the
524 // method returns the mass of the present logical volume only
525 // (subtracted for the volume occupied by the daughter volumes).
526 // The extra argument 'parMaterial' is internally used to
527 // consider cases of geometrical parameterisations by material.
528 // ********************************************************************
529 //
531  G4bool propagate,
532  G4Material* parMaterial)
533 {
534  // Return the cached non-zero value, if not forced
535  //
536  if ( (G4MT_mass) && (!forced) ) return G4MT_mass;
537 
538  // Global density and computed mass associated to the logical
539  // volume without considering its daughters
540  //
541  G4Material* logMaterial = parMaterial ? parMaterial : GetMaterial(); // G4MT_material;
542  if (!logMaterial)
543  {
544  std::ostringstream message;
545  message << "No material associated to the logical volume: " << fName << " !"
546  << G4endl
547  << "Sorry, cannot compute the mass ...";
548  G4Exception("G4LogicalVolume::GetMass()", "GeomMgt0002",
549  FatalException, message);
550  return 0;
551  }
552  if (! GetSolid() ) // !G4MT_solid)
553  {
554  std::ostringstream message;
555  message << "No solid is associated to the logical volume: " << fName << " !"
556  << G4endl
557  << "Sorry, cannot compute the mass ...";
558  G4Exception("G4LogicalVolume::GetMass()", "GeomMgt0002",
559  FatalException, message);
560  return 0;
561  }
562  G4double globalDensity = logMaterial->GetDensity();
563  G4double motherMass= GetSolid()->GetCubicVolume() * globalDensity;
564 
565  // G4MT_mass =
566  // SetMass( motherMmass );
567  G4double massSum= motherMass;
568 
569  // For each daughter in the tree, subtract the mass occupied
570  // and if required by the propagate flag, add the real daughter's
571  // one computed recursively
572 
573  for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
574  itDau != fDaughters.end(); itDau++)
575  {
576  G4VPhysicalVolume* physDaughter = (*itDau);
577  G4LogicalVolume* logDaughter = physDaughter->GetLogicalVolume();
578  G4double subMass=0.;
579  G4VSolid* daughterSolid = 0;
580  G4Material* daughterMaterial = 0;
581 
582  // Compute the mass to subtract and to add for each daughter
583  // considering its multiplicity (i.e. replicated or not) and
584  // eventually its parameterisation (by solid and/or by material)
585  //
586  for (G4int i=0; i<physDaughter->GetMultiplicity(); i++)
587  {
589  physParam = physDaughter->GetParameterisation();
590  if (physParam)
591  {
592  daughterSolid = physParam->ComputeSolid(i, physDaughter);
593  daughterSolid->ComputeDimensions(physParam, i, physDaughter);
594  daughterMaterial = physParam->ComputeMaterial(i, physDaughter);
595  }
596  else
597  {
598  daughterSolid = logDaughter->GetSolid();
599  daughterMaterial = logDaughter->GetMaterial();
600  }
601  subMass = daughterSolid->GetCubicVolume() * globalDensity;
602 
603  // Subtract the daughter's portion for the mass and, if required,
604  // add the real daughter's mass computed recursively
605  //
606  massSum -= subMass;
607  if (propagate)
608  {
609  massSum += logDaughter->GetMass(true, true, daughterMaterial);
610  }
611  }
612  }
613  G4MT_mass= massSum;
614  return massSum;
615 }
616 
618 {
620 }
621 
const XML_Char * name
Definition: expat.h:151
void SetName(const G4String &pName)
G4LogicalVolume * GetLogicalVolume() const
virtual G4Material * ComputeMaterial(const G4int repNo, G4VPhysicalVolume *currentVol, const G4VTouchable *parentTouch=0)
G4VSensitiveDetector * GetSensitiveDetector() const
G4VSensitiveDetector * fSensitiveDetector
virtual ~G4LogicalVolume()
G4PhysicalVolumeList fDaughters
virtual G4VPVParameterisation * GetParameterisation() const =0
#define G4endl
Definition: G4ios.hh:61
const char * p
Definition: xmltok.h:285
void message(RunManager *runmanager)
Definition: ts_scorers.cc:72
G4int CreateSubInstance()
G4int GetNoDaughters() const
void SetFieldManager(G4FieldManager *pFieldMgr, G4bool forceToAllDaughters)
void UpdateMaterial(G4Material *pMaterial)
G4double fMass
G4bool IsMasterThread()
Definition: G4Threading.cc:130
#define G4MT_material
static void DeRegister(G4LogicalVolume *pVolume)
void RemoveRootLogicalVolume(G4LogicalVolume *lv, G4bool scan=true)
Definition: G4Region.cc:319
G4LogicalVolume(G4VSolid *pSolid, G4Material *pMaterial, const G4String &name, G4FieldManager *pFieldMgr=0, G4VSensitiveDetector *pSDetector=0, G4UserLimits *pULimits=0, G4bool optimise=true)
G4Material * GetMaterial() const
void AssignFieldManager(G4FieldManager *fldMgr)
virtual G4int GetMultiplicity() const
#define G4MT_fmanager
virtual G4VSolid * ComputeSolid(const G4int, G4VPhysicalVolume *)
static void Register(G4LogicalVolume *pVolume)
G4bool IsDaughter(const G4VPhysicalVolume *p) const
double G4double
Definition: G4Types.hh:76
bool G4bool
Definition: G4Types.hh:79
virtual G4bool IsExtended() const
G4VSolid * fSolid
#define G4MT_mass
const G4MaterialCutsCouple * GetMaterialCutsCouple() const
void SetSolid(G4VSolid *pSolid)
static G4GEOM_DLL G4ThreadLocal T * offset
void InitialiseWorker(G4LogicalVolume *ptrMasterObject, G4VSolid *pSolid, G4VSensitiveDetector *pSDetector)
void RemoveDaughter(const G4VPhysicalVolume *p)
void SetMaterialCutsCouple(G4MaterialCutsCouple *cuts)
void AddDaughter(G4VPhysicalVolume *p)
G4String fName
Definition: G4AttUtils.hh:55
void SetVisAttributes(const G4VisAttributes *pVA)
#define G4MT_ccouple
G4bool IsAncestor(const G4VPhysicalVolume *p) const
static void Clean()
void SetUserLimits(G4UserLimits *pULimits)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.hh:65
void PropagateRegion()
int G4int
Definition: G4Types.hh:78
void SlaveCopySubInstanceArray()
void TerminateWorker(G4LogicalVolume *ptrMasterObject)
virtual G4double GetCubicVolume()
Definition: G4VSolid.cc:188
#define G4MT_sdetector
static G4GEOM_DLL G4LVManager subInstanceManager
G4FieldManager * GetFieldManager() const
void SetMaterial(G4Material *pMaterial)
G4VSolid * GetSolid() const
virtual void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
Definition: G4VSolid.cc:137
G4MaterialCutsCouple * FindCouple(G4Material *mat)
G4Material * fMaterial
static const G4LVManager & GetSubInstanceManager()
void RegionModified(G4bool flag)
#define G4MT_solid
const G4VisAttributes * fVisAttributes
G4double GetMass(G4bool forced=false, G4bool propagate=true, G4Material *parMaterial=0)
G4int TotalVolumeEntities() const
const G4String & GetName() const
G4VPhysicalVolume * GetDaughter(const G4int i) const
const G4String & GetName() const
G4FieldManager * fFieldManager
G4double GetDensity() const
Definition: G4Material.hh:181
void SetSensitiveDetector(G4VSensitiveDetector *pSDetector)