Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/management/src/G4LogicalVolume.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /geometry/management/src/G4LogicalVolume.cc (Version 11.3.0) and /geometry/management/src/G4LogicalVolume.cc (Version 11.2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 // 
 26 // class G4LogicalVolume implementation            26 // class G4LogicalVolume implementation
 27 //                                                 27 //
 28 // 15.01.13 G.Cosmo, A.Dotti: Modified for thr     28 // 15.01.13 G.Cosmo, A.Dotti: Modified for thread-safety for MT
 29 // 01.03.05 G.Santin: Added flag for optional      29 // 01.03.05 G.Santin: Added flag for optional propagation of GetMass()
 30 // 17.05.02 G.Cosmo: Added flag for optional o     30 // 17.05.02 G.Cosmo: Added flag for optional optimisation
 31 // 12.02.99 S.Giani: Default initialization of     31 // 12.02.99 S.Giani: Default initialization of voxelization quality
 32 // 04.08.97 P.M.DeFreitas: Added methods for p     32 // 04.08.97 P.M.DeFreitas: Added methods for parameterised simulation 
 33 // 11.07.95 P.Kent: Initial version                33 // 11.07.95 P.Kent: Initial version
 34 // -------------------------------------------     34 // --------------------------------------------------------------------
 35                                                    35 
 36 #include "G4LogicalVolume.hh"                      36 #include "G4LogicalVolume.hh"
 37 #include "G4LogicalVolumeStore.hh"                 37 #include "G4LogicalVolumeStore.hh"
 38 #include "G4VSolid.hh"                             38 #include "G4VSolid.hh"
 39 #include "G4Material.hh"                           39 #include "G4Material.hh"
 40 #include "G4VPVParameterisation.hh"                40 #include "G4VPVParameterisation.hh"
 41 #include "G4VisAttributes.hh"                      41 #include "G4VisAttributes.hh"
 42                                                    42 
 43 #include "G4UnitsTable.hh"                         43 #include "G4UnitsTable.hh"
 44                                                    44 
 45 G4LVData::G4LVData() {;}                           45 G4LVData::G4LVData() {;}
 46                                                    46 
 47 // This new field helps to use the class G4LVM     47 // This new field helps to use the class G4LVManager
 48 //                                                 48 //
 49 G4LVManager G4LogicalVolume::subInstanceManage     49 G4LVManager G4LogicalVolume::subInstanceManager;
 50                                                    50 
 51 // These macros change the references to field     51 // These macros change the references to fields that are now encapsulated
 52 // in the class G4LVData.                          52 // in the class G4LVData.
 53 //                                                 53 //
 54 #define G4MT_solid     ((subInstanceManager.of     54 #define G4MT_solid     ((subInstanceManager.offset[instanceID]).fSolid)
 55 #define G4MT_sdetector ((subInstanceManager.of     55 #define G4MT_sdetector ((subInstanceManager.offset[instanceID]).fSensitiveDetector)
 56 #define G4MT_fmanager  ((subInstanceManager.of     56 #define G4MT_fmanager  ((subInstanceManager.offset[instanceID]).fFieldManager)
 57 #define G4MT_material  ((subInstanceManager.of     57 #define G4MT_material  ((subInstanceManager.offset[instanceID]).fMaterial)
 58 #define G4MT_mass      ((subInstanceManager.of     58 #define G4MT_mass      ((subInstanceManager.offset[instanceID]).fMass)
 59 #define G4MT_ccouple   ((subInstanceManager.of     59 #define G4MT_ccouple   ((subInstanceManager.offset[instanceID]).fCutsCouple)
 60 #define G4MT_instance  (subInstanceManager.off     60 #define G4MT_instance  (subInstanceManager.offset[instanceID])
 61                                                    61 
 62 // *******************************************     62 // ********************************************************************
 63 // Constructor - sets member data and adds to      63 // Constructor - sets member data and adds to logical Store,
 64 //               voxel pointer for optimisatio     64 //               voxel pointer for optimisation set to 0 by default.
 65 //               Initialises daughter vector t     65 //               Initialises daughter vector to 0 length.
 66 // *******************************************     66 // ********************************************************************
 67 //                                                 67 //
 68 G4LogicalVolume::G4LogicalVolume( G4VSolid* pS     68 G4LogicalVolume::G4LogicalVolume( G4VSolid* pSolid,
 69                                   G4Material*      69                                   G4Material* pMaterial,
 70                             const G4String& na     70                             const G4String& name,
 71                                   G4FieldManag     71                                   G4FieldManager* pFieldMgr,
 72                                   G4VSensitive     72                                   G4VSensitiveDetector* pSDetector,
 73                                   G4UserLimits     73                                   G4UserLimits* pULimits,
 74                                   G4bool optim     74                                   G4bool optimise )
 75  : fDaughters(0,(G4VPhysicalVolume*)nullptr),      75  : fDaughters(0,(G4VPhysicalVolume*)nullptr), fDaughtersVolumeType(kNormal),
 76    fOptimise(optimise)                             76    fOptimise(optimise)
 77 {                                                  77 {
 78   // Initialize 'Shadow'/master pointers - for     78   // Initialize 'Shadow'/master pointers - for use in copying to workers
 79   //                                               79   //
 80   fSolid = pSolid;                                 80   fSolid = pSolid;
 81   fSensitiveDetector = pSDetector;                 81   fSensitiveDetector = pSDetector;
 82   fFieldManager = pFieldMgr;                       82   fFieldManager = pFieldMgr;
 83                                                    83 
 84   instanceID = subInstanceManager.CreateSubIns     84   instanceID = subInstanceManager.CreateSubInstance();
 85   AssignFieldManager(pFieldMgr);                   85   AssignFieldManager(pFieldMgr);
 86                                                    86   
 87   G4MT_mass = 0.;                                  87   G4MT_mass = 0.;
 88   G4MT_ccouple = nullptr;                          88   G4MT_ccouple = nullptr;
 89                                                    89 
 90   SetSolid(pSolid);                                90   SetSolid(pSolid);
 91   SetMaterial(pMaterial);                          91   SetMaterial(pMaterial);
 92   SetName(name);                                   92   SetName(name);
 93   SetSensitiveDetector(pSDetector);                93   SetSensitiveDetector(pSDetector);
 94   SetUserLimits(pULimits);                         94   SetUserLimits(pULimits);    
 95                                                    95 
 96   // Initialize 'Shadow' data structure - for      96   // Initialize 'Shadow' data structure - for use by object persistency
 97   //                                               97   //
 98   lvdata = new G4LVData();                         98   lvdata = new G4LVData();
 99   lvdata->fSolid = pSolid;                         99   lvdata->fSolid = pSolid;
100   lvdata->fMaterial = pMaterial;                  100   lvdata->fMaterial = pMaterial;
101                                                   101 
102   //                                              102   //
103   // Add to store                                 103   // Add to store
104   //                                              104   //
105   G4LogicalVolumeStore::Register(this);           105   G4LogicalVolumeStore::Register(this);
106 }                                                 106 }
107                                                   107 
108 // *******************************************    108 // ********************************************************************
109 // Fake default constructor - sets only member    109 // Fake default constructor - sets only member data and allocates memory
110 //                            for usage restri    110 //                            for usage restricted to object persistency.
111 // *******************************************    111 // ********************************************************************
112 //                                                112 //
113 G4LogicalVolume::G4LogicalVolume( __void__& )     113 G4LogicalVolume::G4LogicalVolume( __void__& )
114  : fDaughters(0,(G4VPhysicalVolume*)nullptr),     114  : fDaughters(0,(G4VPhysicalVolume*)nullptr), fName("")
115 {                                                 115 {
116   instanceID = subInstanceManager.CreateSubIns    116   instanceID = subInstanceManager.CreateSubInstance();
117                                                   117   
118   SetSensitiveDetector(nullptr);    // G4MT_sd    118   SetSensitiveDetector(nullptr);    // G4MT_sdetector = nullptr;
119   SetFieldManager(nullptr, false);  // G4MT_fm    119   SetFieldManager(nullptr, false);  // G4MT_fmanager = nullptr;
120                                                   120 
121   G4MT_mass = 0.;                                 121   G4MT_mass = 0.;
122   G4MT_ccouple = nullptr;                         122   G4MT_ccouple = nullptr;
123                                                   123   
124   // Add to store                                 124   // Add to store
125   //                                              125   //
126   G4LogicalVolumeStore::Register(this);           126   G4LogicalVolumeStore::Register(this);
127 }                                                 127 }
128                                                   128 
129 // *******************************************    129 // ********************************************************************
130 // Destructor - Removes itself from solid Stor    130 // Destructor - Removes itself from solid Store
131 // NOTE: Not virtual                              131 // NOTE: Not virtual
132 // *******************************************    132 // ********************************************************************
133 //                                                133 //
134 G4LogicalVolume::~G4LogicalVolume()               134 G4LogicalVolume::~G4LogicalVolume()
135 {                                                 135 {
136   if (!fLock && fRootRegion)  // De-register r    136   if (!fLock && fRootRegion)  // De-register root region first if not locked
137   {                           // and flagged a    137   {                           // and flagged as root logical-volume
138     fRegion->RemoveRootLogicalVolume(this, tru    138     fRegion->RemoveRootLogicalVolume(this, true);
139   }                                               139   }
140   delete lvdata;                                  140   delete lvdata;
141   G4LogicalVolumeStore::DeRegister(this);         141   G4LogicalVolumeStore::DeRegister(this);
142 }                                                 142 }
143                                                   143 
144 // *******************************************    144 // ********************************************************************
145 // SetName - Set volume name and notify store     145 // SetName - Set volume name and notify store of the change
146 // *******************************************    146 // ********************************************************************
147 //                                                147 //
148 void G4LogicalVolume::SetName(const G4String&     148 void G4LogicalVolume::SetName(const G4String& pName)
149 {                                                 149 {
150   fName = pName;                                  150   fName = pName;
151   G4LogicalVolumeStore::GetInstance()->SetMapV    151   G4LogicalVolumeStore::GetInstance()->SetMapValid(false);
152 }                                                 152 }
153                                                   153 
154 // *******************************************    154 // ********************************************************************
155 // InitialiseWorker                               155 // InitialiseWorker
156 //                                                156 //
157 // This method is similar to the constructor.     157 // This method is similar to the constructor. It is used by each worker
158 // thread to achieve the same effect as that o    158 // thread to achieve the same effect as that of the master thread exept
159 // to register the new created instance. This     159 // to register the new created instance. This method is invoked explicitly.
160 // It does not create a new G4LogicalVolume in    160 // It does not create a new G4LogicalVolume instance. It only assign the value
161 // for the fields encapsulated by the class G4    161 // for the fields encapsulated by the class G4LVData.
162 // *******************************************    162 // ********************************************************************
163 //                                                163 //
164 void G4LogicalVolume::                            164 void G4LogicalVolume::
165 InitialiseWorker( G4LogicalVolume* /*pMasterOb    165 InitialiseWorker( G4LogicalVolume* /*pMasterObject*/,
166                   G4VSolid* pSolid,               166                   G4VSolid* pSolid,
167                   G4VSensitiveDetector* pSDete    167                   G4VSensitiveDetector* pSDetector)
168 {                                                 168 {
169   subInstanceManager.SlaveCopySubInstanceArray    169   subInstanceManager.SlaveCopySubInstanceArray();
170                                                   170 
171   SetSolid(pSolid);                               171   SetSolid(pSolid);
172   SetSensitiveDetector(pSDetector); //  How th    172   SetSensitiveDetector(pSDetector); //  How this object is available now ?
173   AssignFieldManager(fFieldManager);              173   AssignFieldManager(fFieldManager);
174    // Should be set - but a per-thread copy is    174    // Should be set - but a per-thread copy is not available yet
175    // Must not call SetFieldManager(), which p    175    // Must not call SetFieldManager(), which propagates FieldMgr
176                                                   176 
177 #ifdef CLONE_FIELD_MGR                            177 #ifdef CLONE_FIELD_MGR
178   // Create a field FieldManager by cloning       178   // Create a field FieldManager by cloning
179   //                                              179   //
180   G4FieldManager workerFldMgr = fFieldManager-    180   G4FieldManager workerFldMgr = fFieldManager->GetWorkerClone(G4bool* created);
181   if( created || (GetFieldManager() != workerF    181   if( created || (GetFieldManager() != workerFldMgr) )
182   {                                               182   {
183     SetFieldManager(fFieldManager, false); //     183     SetFieldManager(fFieldManager, false); // which propagates FieldMgr
184   }                                               184   }
185   else                                            185   else
186   {                                               186   {
187     // Field manager existed and is equal to c    187     // Field manager existed and is equal to current one
188     //                                            188     //
189     AssignFieldManager(workerFldMgr);             189     AssignFieldManager(workerFldMgr);
190   }                                               190   }
191 #endif                                            191 #endif
192 }                                                 192 }
193                                                   193 
194 // *******************************************    194 // ********************************************************************
195 // Clean                                          195 // Clean
196 // *******************************************    196 // ********************************************************************
197 //                                                197 //
198 void G4LogicalVolume::Clean()                     198 void G4LogicalVolume::Clean()
199 {                                                 199 {
200   subInstanceManager.FreeSlave();                 200   subInstanceManager.FreeSlave();
201 }                                                 201 }
202                                                   202 
203 // *******************************************    203 // ********************************************************************
204 // TerminateWorker                                204 // TerminateWorker
205 //                                                205 //
206 // This method is similar to the destructor. I    206 // This method is similar to the destructor. It is used by each worker
207 // thread to achieve the partial effect as tha    207 // thread to achieve the partial effect as that of the master thread.
208 // For G4LogicalVolume instances, nothing more    208 // For G4LogicalVolume instances, nothing more to do here.
209 // *******************************************    209 // ********************************************************************
210 //                                                210 //
211 void G4LogicalVolume::                            211 void G4LogicalVolume::
212 TerminateWorker( G4LogicalVolume* /*pMasterObj    212 TerminateWorker( G4LogicalVolume* /*pMasterObject*/)
213 {                                                 213 {
214 }                                                 214 }
215                                                   215 
216 // *******************************************    216 // ********************************************************************
217 // GetSubInstanceManager                          217 // GetSubInstanceManager
218 //                                                218 //
219 // Returns the private data instance manager.     219 // Returns the private data instance manager.    
220 // *******************************************    220 // ********************************************************************
221 //                                                221 //
222 const G4LVManager& G4LogicalVolume::GetSubInst    222 const G4LVManager& G4LogicalVolume::GetSubInstanceManager()
223 {                                                 223 {
224   return subInstanceManager;                      224   return subInstanceManager;
225 }                                                 225 }
226                                                   226 
227 // *******************************************    227 // ********************************************************************
228 // GetFieldManager                                228 // GetFieldManager
229 // *******************************************    229 // ********************************************************************
230 //                                                230 //
231 G4FieldManager* G4LogicalVolume::GetFieldManag    231 G4FieldManager* G4LogicalVolume::GetFieldManager() const
232 {                                                 232 {
233   return G4MT_fmanager;                           233   return G4MT_fmanager;
234 }                                                 234 }
235                                                   235 
236 // *******************************************    236 // ********************************************************************
237 // AssignFieldManager                             237 // AssignFieldManager
238 // *******************************************    238 // ********************************************************************
239 //                                                239 //
240 void G4LogicalVolume::AssignFieldManager( G4Fi    240 void G4LogicalVolume::AssignFieldManager( G4FieldManager *fldMgr)
241 {                                                 241 {
242   G4MT_fmanager= fldMgr;                          242   G4MT_fmanager= fldMgr;
243   if(G4Threading::IsMasterThread())  { fFieldM    243   if(G4Threading::IsMasterThread())  { fFieldManager = fldMgr; }
244 }                                                 244 }
245                                                   245 
246 // *******************************************    246 // ********************************************************************
247 // IsExtended                                     247 // IsExtended
248 // *******************************************    248 // ********************************************************************
249 //                                                249 //
250 G4bool G4LogicalVolume::IsExtended() const        250 G4bool G4LogicalVolume::IsExtended() const
251 {                                                 251 {
252   return false;                                   252   return false;
253 }                                                 253 }
254                                                   254 
255 // *******************************************    255 // ********************************************************************
256 // SetFieldManager                                256 // SetFieldManager
257 // *******************************************    257 // ********************************************************************
258 //                                                258 //
259 void                                              259 void
260 G4LogicalVolume::SetFieldManager(G4FieldManage    260 G4LogicalVolume::SetFieldManager(G4FieldManager* pNewFieldMgr,
261                                  G4bool           261                                  G4bool          forceAllDaughters) 
262 {                                                 262 {
263   AssignFieldManager(pNewFieldMgr);               263   AssignFieldManager(pNewFieldMgr);
264                                                   264 
265   auto NoDaughters = GetNoDaughters();            265   auto NoDaughters = GetNoDaughters();
266   while ( (NoDaughters--)>0 )                     266   while ( (NoDaughters--)>0 )
267   {                                               267   {
268     G4LogicalVolume* DaughterLogVol;              268     G4LogicalVolume* DaughterLogVol; 
269     DaughterLogVol = GetDaughter(NoDaughters)-    269     DaughterLogVol = GetDaughter(NoDaughters)->GetLogicalVolume();
270     if ( forceAllDaughters || (DaughterLogVol-    270     if ( forceAllDaughters || (DaughterLogVol->GetFieldManager() == nullptr) )
271     {                                             271     {
272       DaughterLogVol->SetFieldManager(pNewFiel    272       DaughterLogVol->SetFieldManager(pNewFieldMgr, forceAllDaughters);
273     }                                             273     }
274   }                                               274   }
275 }                                                 275 }
276                                                   276 
277 // *******************************************    277 // ********************************************************************
278 // AddDaughter                                    278 // AddDaughter
279 // *******************************************    279 // ********************************************************************
280 //                                                280 //
281 void G4LogicalVolume::AddDaughter(G4VPhysicalV    281 void G4LogicalVolume::AddDaughter(G4VPhysicalVolume* pNewDaughter)
282 {                                                 282 {
283   EVolume daughterType = pNewDaughter->VolumeT    283   EVolume daughterType = pNewDaughter->VolumeType();
284                                                   284 
285   // The type of the navigation needed is dete    285   // The type of the navigation needed is determined by the first daughter
286   //                                              286   //
287   if( fDaughters.empty() )                        287   if( fDaughters.empty() )
288   {                                               288   {
289     fDaughtersVolumeType = daughterType;          289     fDaughtersVolumeType = daughterType;
290   }                                               290   }
291   else                                            291   else
292   {                                               292   {
293     // Check consistency of detector descripti    293     // Check consistency of detector description
294                                                   294 
295     // 1. A replica or parameterised volume ca    295     // 1. A replica or parameterised volume can have only one daughter
296     //                                            296     //
297     if( fDaughters[0]->IsReplicated() )           297     if( fDaughters[0]->IsReplicated() )
298     {                                             298     {
299       std::ostringstream message;                 299       std::ostringstream message;
300       message << "ERROR - Attempt to place a v    300       message << "ERROR - Attempt to place a volume in a mother volume"
301         << G4endl                                 301         << G4endl
302         << "        already containing a repli    302         << "        already containing a replicated volume." << G4endl
303         << "        A volume can either contai    303         << "        A volume can either contain several placements" << G4endl
304         << "        or a unique replica or par    304         << "        or a unique replica or parameterised volume !" << G4endl
305         << "           Mother logical volume:     305         << "           Mother logical volume: " << GetName() << G4endl
306         << "           Placing volume: " << pN    306         << "           Placing volume: " << pNewDaughter->GetName()
307         << G4endl;                                307         << G4endl;
308       G4Exception("G4LogicalVolume::AddDaughte    308       G4Exception("G4LogicalVolume::AddDaughter()", "GeomMgt0002",
309                   FatalException, message,        309                   FatalException, message,
310                   "Replica or parameterised vo    310                   "Replica or parameterised volume must be the only daughter!");
311     }                                             311     }
312     else                                          312     else
313     {                                             313     {
314       // 2. Ensure that Placement and External    314       // 2. Ensure that Placement and External physical volumes do not mix
315       //                                          315       //
316       if(  daughterType != fDaughtersVolumeTyp    316       if(  daughterType != fDaughtersVolumeType )
317       {                                           317       {
318         std::ostringstream message;               318         std::ostringstream message;
319         message << "ERROR - Attempt to place a    319         message << "ERROR - Attempt to place a volume in a mother volume"
320           << G4endl                               320           << G4endl
321           << "        already containing a dif    321           << "        already containing a different type of volume." << G4endl
322           << "        A volume can either cont    322           << "        A volume can either contain" << G4endl
323           << "        - one or more placements    323           << "        - one or more placements, OR" << G4endl
324           << "        - one or more 'external'    324           << "        - one or more 'external' type physical volumes." << G4endl
325           << "          Mother logical volume:    325           << "          Mother logical volume: " << GetName() << G4endl
326           << "          Volume being placed: "    326           << "          Volume being placed: " << pNewDaughter->GetName()
327           << G4endl;                              327           << G4endl;
328         G4Exception("G4LogicalVolume::AddDaugh    328         G4Exception("G4LogicalVolume::AddDaughter()", "GeomMgt0002",
329                     FatalException, message,      329                     FatalException, message,
330                     "Cannot mix placements and    330                     "Cannot mix placements and external physical volumes !");
331       }                                           331       }
332     }                                             332     }
333   }                                               333   }
334                                                   334 
335   // Invalidate previous calculation of mass -    335   // Invalidate previous calculation of mass - if any - for all threads
336   //                                              336   //
337   G4MT_mass = 0.;                                 337   G4MT_mass = 0.;
338   fDaughters.push_back(pNewDaughter);             338   fDaughters.push_back(pNewDaughter);
339                                                   339 
340   G4LogicalVolume* pDaughterLogical = pNewDaug    340   G4LogicalVolume* pDaughterLogical = pNewDaughter->GetLogicalVolume();
341                                                   341 
342   // Propagate the Field Manager, if the daugh    342   // Propagate the Field Manager, if the daughter has no field Manager
343   //                                              343   //
344   G4FieldManager* pDaughterFieldManager = pDau    344   G4FieldManager* pDaughterFieldManager = pDaughterLogical->GetFieldManager();
345                                                   345 
346   // Avoid propagating the fieldManager pointe    346   // Avoid propagating the fieldManager pointer if null
347   // and daughter's one is null as well...        347   // and daughter's one is null as well...
348   //                                              348   // 
349   if( (G4MT_fmanager != nullptr ) && (pDaughte    349   if( (G4MT_fmanager != nullptr ) && (pDaughterFieldManager == nullptr) )
350   {                                               350   {
351     pDaughterLogical->SetFieldManager(G4MT_fma    351     pDaughterLogical->SetFieldManager(G4MT_fmanager, false);
352   }                                               352   }
353   if (fRegion != nullptr)                         353   if (fRegion != nullptr)
354   {                                               354   {
355     PropagateRegion();                            355     PropagateRegion();
356     fRegion->RegionModified(true);                356     fRegion->RegionModified(true);
357   }                                               357   }
358 }                                                 358 }
359                                                   359 
360 // *******************************************    360 // ********************************************************************
361 // RemoveDaughter                                 361 // RemoveDaughter
362 // *******************************************    362 // ********************************************************************
363 //                                                363 //
364 void G4LogicalVolume::RemoveDaughter(const G4V    364 void G4LogicalVolume::RemoveDaughter(const G4VPhysicalVolume* p)
365 {                                                 365 {
366   for (auto i=fDaughters.cbegin(); i!=fDaughte    366   for (auto i=fDaughters.cbegin(); i!=fDaughters.cend(); ++i )
367   {                                               367   {
368     if (**i==*p)                                  368     if (**i==*p)
369     {                                             369     {
370       fDaughters.erase(i);                        370       fDaughters.erase(i);
371       break;                                      371       break;
372     }                                             372     }
373   }                                               373   }
374   if (fRegion != nullptr)                         374   if (fRegion != nullptr)
375   {                                               375   {
376     fRegion->RegionModified(true);                376     fRegion->RegionModified(true);
377   }                                               377   }
378   G4MT_mass = 0.;                                 378   G4MT_mass = 0.;
379 }                                                 379 }
380                                                   380 
381 // *******************************************    381 // ********************************************************************
382 // ClearDaughters                                 382 // ClearDaughters
383 // *******************************************    383 // ********************************************************************
384 //                                                384 //
385 void G4LogicalVolume::ClearDaughters()            385 void G4LogicalVolume::ClearDaughters()
386 {                                                 386 {
387   fDaughters.erase(fDaughters.cbegin(), fDaugh    387   fDaughters.erase(fDaughters.cbegin(), fDaughters.cend());
388   if (fRegion != nullptr)                         388   if (fRegion != nullptr)
389   {                                               389   {
390     fRegion->RegionModified(true);                390     fRegion->RegionModified(true);
391   }                                               391   }
392   G4MT_mass = 0.;                                 392   G4MT_mass = 0.;
393 }                                                 393 }
394                                                   394 
395 // *******************************************    395 // ********************************************************************
396 // ResetMass                                      396 // ResetMass
397 // *******************************************    397 // ********************************************************************
398 //                                                398 //
399 void G4LogicalVolume::ResetMass()                 399 void G4LogicalVolume::ResetMass()
400 {                                                 400 {
401   G4MT_mass= 0.0;                                 401   G4MT_mass= 0.0;
402 }                                                 402 }
403                                                   403 
404 // *******************************************    404 // ********************************************************************
405 // GetSolid                                       405 // GetSolid
406 // *******************************************    406 // ********************************************************************
407 //                                                407 //
408 G4VSolid* G4LogicalVolume::GetSolid(G4LVData &    408 G4VSolid* G4LogicalVolume::GetSolid(G4LVData &instLVdata) // const
409 {                                                 409 {
410   return instLVdata.fSolid;                       410   return instLVdata.fSolid;
411 }                                                 411 }
412                                                   412 
413 G4VSolid* G4LogicalVolume::GetSolid() const       413 G4VSolid* G4LogicalVolume::GetSolid() const
414 {                                                 414 {
415   return this->GetSolid( subInstanceManager.of    415   return this->GetSolid( subInstanceManager.offset[instanceID] ); 
416 }                                                 416 }
417                                                   417 
418 // *******************************************    418 // ********************************************************************
419 // SetSolid                                       419 // SetSolid
420 // *******************************************    420 // ********************************************************************
421 //                                                421 //
422 void G4LogicalVolume::SetSolid(G4VSolid *pSoli    422 void G4LogicalVolume::SetSolid(G4VSolid *pSolid)
423 {                                                 423 {
424                                                   424 
425   G4MT_solid = pSolid;                            425   G4MT_solid = pSolid;
426   this->ResetMass();                              426   this->ResetMass(); 
427 }                                                 427 }
428                                                   428 
429 void G4LogicalVolume::SetSolid(G4LVData& instL    429 void G4LogicalVolume::SetSolid(G4LVData& instLVdata, G4VSolid* pSolid)
430 {                                                 430 {  
431   instLVdata.fSolid = pSolid;                     431   instLVdata.fSolid = pSolid;
432   instLVdata.fMass = 0.0;                         432   instLVdata.fMass = 0.0;
433 }                                                 433 }
434                                                   434 
435 // *******************************************    435 // ********************************************************************
436 // GetMaterial                                    436 // GetMaterial
437 // *******************************************    437 // ********************************************************************
438 //                                                438 //
439 G4Material* G4LogicalVolume::GetMaterial() con    439 G4Material* G4LogicalVolume::GetMaterial() const
440 {                                                 440 {
441   return G4MT_material;                           441   return G4MT_material;
442 }                                                 442 }
443                                                   443 
444 // *******************************************    444 // ********************************************************************
445 // SetMaterial                                    445 // SetMaterial
446 // *******************************************    446 // ********************************************************************
447 //                                                447 //
448 void G4LogicalVolume::SetMaterial(G4Material*     448 void G4LogicalVolume::SetMaterial(G4Material* pMaterial)
449 {                                                 449 {
450   G4MT_material = pMaterial;                      450   G4MT_material = pMaterial;
451   G4MT_mass = 0.0;                                451   G4MT_mass = 0.0;
452 }                                                 452 }
453                                                   453 
454 // *******************************************    454 // ********************************************************************
455 // UpdateMaterial                                 455 // UpdateMaterial
456 // *******************************************    456 // ********************************************************************
457 //                                                457 //
458 void G4LogicalVolume::UpdateMaterial(G4Materia    458 void G4LogicalVolume::UpdateMaterial(G4Material* pMaterial)
459 {                                                 459 {
460   G4MT_material=pMaterial;                        460   G4MT_material=pMaterial;
461   if (fRegion != nullptr) { G4MT_ccouple = fRe    461   if (fRegion != nullptr) { G4MT_ccouple = fRegion->FindCouple(pMaterial); }
462   G4MT_mass = 0.0;                                462   G4MT_mass = 0.0;
463 }                                                 463 }
464                                                   464 
465 // *******************************************    465 // ********************************************************************
466 // GetSensitiveDetector                           466 // GetSensitiveDetector
467 // *******************************************    467 // ********************************************************************
468 //                                                468 //
469 G4VSensitiveDetector* G4LogicalVolume::GetSens    469 G4VSensitiveDetector* G4LogicalVolume::GetSensitiveDetector() const
470 {                                                 470 {
471   return G4MT_sdetector;                          471   return G4MT_sdetector;
472 }                                                 472 }
473                                                   473 
474 // *******************************************    474 // ********************************************************************
475 // SetSensitiveDetector                           475 // SetSensitiveDetector
476 // *******************************************    476 // ********************************************************************
477 //                                                477 //
478 void G4LogicalVolume::SetSensitiveDetector(G4V    478 void G4LogicalVolume::SetSensitiveDetector(G4VSensitiveDetector* pSDetector)
479 {                                                 479 {
480   G4MT_sdetector = pSDetector;                    480   G4MT_sdetector = pSDetector;
481   if (G4Threading::IsMasterThread())  { fSensi    481   if (G4Threading::IsMasterThread())  { fSensitiveDetector = pSDetector; }
482 }                                                 482 }
483                                                   483 
484 // *******************************************    484 // ********************************************************************
485 // GetMaterialCutsCouple                          485 // GetMaterialCutsCouple
486 // *******************************************    486 // ********************************************************************
487 //                                                487 //
488 const G4MaterialCutsCouple* G4LogicalVolume::G    488 const G4MaterialCutsCouple* G4LogicalVolume::GetMaterialCutsCouple() const
489 {                                                 489 {
490   return G4MT_ccouple;                            490   return G4MT_ccouple;
491 }                                                 491 }
492                                                   492 
493 // *******************************************    493 // ********************************************************************
494 // SetMaterialCutsCouple                          494 // SetMaterialCutsCouple
495 // *******************************************    495 // ********************************************************************
496 //                                                496 //
497 void G4LogicalVolume::SetMaterialCutsCouple(G4    497 void G4LogicalVolume::SetMaterialCutsCouple(G4MaterialCutsCouple* cuts)
498 {                                                 498 {
499   G4MT_ccouple = cuts;                            499   G4MT_ccouple = cuts;
500 }                                                 500 }
501                                                   501 
502 // *******************************************    502 // ********************************************************************
503 // IsAncestor                                     503 // IsAncestor
504 //                                                504 //
505 // Finds out if the current logical volume is     505 // Finds out if the current logical volume is an ancestor of a given 
506 // physical volume                                506 // physical volume
507 // *******************************************    507 // ********************************************************************
508 //                                                508 //
509 G4bool                                            509 G4bool
510 G4LogicalVolume::IsAncestor(const G4VPhysicalV    510 G4LogicalVolume::IsAncestor(const G4VPhysicalVolume* aVolume) const
511 {                                                 511 {
512   G4bool isDaughter = IsDaughter(aVolume);        512   G4bool isDaughter = IsDaughter(aVolume);
513   if (!isDaughter)                                513   if (!isDaughter)
514   {                                               514   {
515     for (auto itDau = fDaughters.cbegin(); itD    515     for (auto itDau = fDaughters.cbegin(); itDau != fDaughters.cend(); ++itDau)
516     {                                             516     {
517       isDaughter = (*itDau)->GetLogicalVolume(    517       isDaughter = (*itDau)->GetLogicalVolume()->IsAncestor(aVolume);
518       if (isDaughter)  break;                     518       if (isDaughter)  break;
519     }                                             519     }
520   }                                               520   }
521   return isDaughter;                              521   return isDaughter;
522 }                                                 522 }
523                                                   523 
524 // *******************************************    524 // ********************************************************************
525 // TotalVolumeEntities                            525 // TotalVolumeEntities
526 //                                                526 //
527 // Returns the total number of physical volume    527 // Returns the total number of physical volumes (replicated or placed)
528 // in the tree represented by the current logi    528 // in the tree represented by the current logical volume.
529 // *******************************************    529 // ********************************************************************
530 //                                                530 //
531 G4int G4LogicalVolume::TotalVolumeEntities() c    531 G4int G4LogicalVolume::TotalVolumeEntities() const
532 {                                                 532 {
533   G4int vols = 1;                                 533   G4int vols = 1;
534   for (auto itDau = fDaughters.cbegin(); itDau    534   for (auto itDau = fDaughters.cbegin(); itDau != fDaughters.cend(); ++itDau)
535   {                                               535   {
536     G4VPhysicalVolume* physDaughter = (*itDau)    536     G4VPhysicalVolume* physDaughter = (*itDau);
537     vols += physDaughter->GetMultiplicity()       537     vols += physDaughter->GetMultiplicity()
538            *physDaughter->GetLogicalVolume()->    538            *physDaughter->GetLogicalVolume()->TotalVolumeEntities();
539   }                                               539   }
540   return vols;                                    540   return vols;
541 }                                                 541 }
542                                                   542 
543 // *******************************************    543 // ********************************************************************
544 // GetMass                                        544 // GetMass
545 //                                                545 //
546 // Returns the mass of the logical volume tree    546 // Returns the mass of the logical volume tree computed from the
547 // estimated geometrical volume of each solid     547 // estimated geometrical volume of each solid and material associated
548 // to the logical volume and its daughters.       548 // to the logical volume and its daughters.
549 // NOTE: the computation may require considera    549 // NOTE: the computation may require considerable amount of time,
550 //       depending from the complexity of the     550 //       depending from the complexity of the geometry tree.
551 //       The returned value is cached and can     551 //       The returned value is cached and can be used for successive
552 //       calls (default), unless recomputation    552 //       calls (default), unless recomputation is forced by providing
553 //       'true' for the boolean argument in in    553 //       'true' for the boolean argument in input. Computation should
554 //       be forced if the geometry setup has c    554 //       be forced if the geometry setup has changed after the previous
555 //       call. By setting the 'propagate' bool    555 //       call. By setting the 'propagate' boolean flag to 'false' the 
556 //       method returns the mass of the presen    556 //       method returns the mass of the present logical volume only 
557 //       (subtracted for the volume occupied b    557 //       (subtracted for the volume occupied by the daughter volumes).
558 //       The extra argument 'parMaterial' is i    558 //       The extra argument 'parMaterial' is internally used to
559 //       consider cases of geometrical paramet    559 //       consider cases of geometrical parameterisations by material.
560 // *******************************************    560 // ********************************************************************
561 //                                                561 //
562 G4double G4LogicalVolume::GetMass(G4bool force    562 G4double G4LogicalVolume::GetMass(G4bool forced,
563                                   G4bool propa    563                                   G4bool propagate,
564                                   G4Material*     564                                   G4Material* parMaterial)
565 {                                                 565 {
566   // Return the cached non-zero value, if not     566   // Return the cached non-zero value, if not forced
567   //                                              567   //
568   if ( ((G4MT_mass) != 0.0) && (!forced) )  {     568   if ( ((G4MT_mass) != 0.0) && (!forced) )  { return G4MT_mass; }
569                                                   569 
570   // Global density and computed mass associat    570   // Global density and computed mass associated to the logical
571   // volume without considering its daughters     571   // volume without considering its daughters
572   //                                              572   //
573   G4Material* logMaterial = parMaterial != nul    573   G4Material* logMaterial = parMaterial != nullptr ? parMaterial : GetMaterial();
574   if (logMaterial == nullptr)                     574   if (logMaterial == nullptr)
575   {                                               575   {
576     std::ostringstream message;                   576     std::ostringstream message;
577     message << "No material associated to the     577     message << "No material associated to the logical volume: "
578             << fName << " !" << G4endl            578             << fName << " !" << G4endl
579             << "Sorry, cannot compute the mass    579             << "Sorry, cannot compute the mass ...";
580     G4Exception("G4LogicalVolume::GetMass()",     580     G4Exception("G4LogicalVolume::GetMass()", "GeomMgt0002",
581                 FatalException, message);         581                 FatalException, message);
582     return 0.0;                                   582     return 0.0;
583   }                                               583   }
584   if ( GetSolid() == nullptr )                    584   if ( GetSolid() == nullptr )
585   {                                               585   {
586     std::ostringstream message;                   586     std::ostringstream message;
587     message << "No solid is associated to the     587     message << "No solid is associated to the logical volume: "
588             << fName << " !" << G4endl            588             << fName << " !" << G4endl
589             << "Sorry, cannot compute the mass    589             << "Sorry, cannot compute the mass ...";
590     G4Exception("G4LogicalVolume::GetMass()",     590     G4Exception("G4LogicalVolume::GetMass()", "GeomMgt0002",
591                 FatalException, message);         591                 FatalException, message);
592     return 0.0;                                   592     return 0.0;
593   }                                               593   }
594   G4double globalDensity = logMaterial->GetDen    594   G4double globalDensity = logMaterial->GetDensity();
595   G4double motherMass = GetSolid()->GetCubicVo    595   G4double motherMass = GetSolid()->GetCubicVolume() * globalDensity;
596   G4double massSum = motherMass;                  596   G4double massSum = motherMass;
597                                                   597   
598   // For each daughter in the tree, subtract t    598   // For each daughter in the tree, subtract the mass occupied
599   // and if required by the propagate flag, ad    599   // and if required by the propagate flag, add the real daughter's
600   // one computed recursively                     600   // one computed recursively
601                                                   601 
602   for (auto itDau = fDaughters.cbegin(); itDau    602   for (auto itDau = fDaughters.cbegin(); itDau != fDaughters.cend(); ++itDau)
603   {                                               603   {
604     G4VPhysicalVolume* physDaughter = (*itDau)    604     G4VPhysicalVolume* physDaughter = (*itDau);
605     G4LogicalVolume* logDaughter = physDaughte    605     G4LogicalVolume* logDaughter = physDaughter->GetLogicalVolume();
606     G4double subMass = 0.0;                       606     G4double subMass = 0.0;
607     G4VSolid* daughterSolid = nullptr;            607     G4VSolid* daughterSolid = nullptr;
608     G4Material* daughterMaterial = nullptr;       608     G4Material* daughterMaterial = nullptr;
609                                                   609 
610     // Compute the mass to subtract and to add    610     // Compute the mass to subtract and to add for each daughter
611     // considering its multiplicity (i.e. repl    611     // considering its multiplicity (i.e. replicated or not) and
612     // eventually its parameterisation (by sol    612     // eventually its parameterisation (by solid and/or by material)
613     //                                            613     //
614     for (auto i=0; i<physDaughter->GetMultipli    614     for (auto i=0; i<physDaughter->GetMultiplicity(); ++i)
615     {                                             615     {
616       G4VPVParameterisation* physParam = physD    616       G4VPVParameterisation* physParam = physDaughter->GetParameterisation();
617       if (physParam != nullptr)                   617       if (physParam != nullptr)
618       {                                           618       {
619         daughterSolid = physParam->ComputeSoli    619         daughterSolid = physParam->ComputeSolid(i, physDaughter);
620         daughterSolid->ComputeDimensions(physP    620         daughterSolid->ComputeDimensions(physParam, i, physDaughter);
621         daughterMaterial = physParam->ComputeM    621         daughterMaterial = physParam->ComputeMaterial(i, physDaughter);
622       }                                           622       }
623       else                                        623       else
624       {                                           624       {
625         daughterSolid = logDaughter->GetSolid(    625         daughterSolid = logDaughter->GetSolid();
626         daughterMaterial = logDaughter->GetMat    626         daughterMaterial = logDaughter->GetMaterial();
627       }                                           627       }
628       subMass = daughterSolid->GetCubicVolume(    628       subMass = daughterSolid->GetCubicVolume() * globalDensity;
629                                                   629 
630       // Subtract the daughter's portion for t    630       // Subtract the daughter's portion for the mass and, if required,
631       // add the real daughter's mass computed    631       // add the real daughter's mass computed recursively
632       //                                          632       //
633       massSum -= subMass;                         633       massSum -= subMass;
634       if (propagate)                              634       if (propagate)
635       {                                           635       {
636         massSum += logDaughter->GetMass(true,     636         massSum += logDaughter->GetMass(true, true, daughterMaterial);
637       }                                           637       }
638     }                                             638     }
639   }                                               639   }
640   G4MT_mass = massSum;                            640   G4MT_mass = massSum;
641   return massSum;                                 641   return massSum;
642 }                                                 642 }
643                                                   643 
644 // *******************************************    644 // ********************************************************************
645 // Change the daughters volume type -- checkin    645 // Change the daughters volume type -- checking proposed values
646 //                                                646 //
647 //  Undertakes primitive checking, to ensure t    647 //  Undertakes primitive checking, to ensure that only 'legal' changes
648 //  are made:                                     648 //  are made:
649 //    - any type to 'external'  ( user respons    649 //    - any type to 'external'  ( user responsibility )
650 //    - the type proposed is checked against t    650 //    - the type proposed is checked against the deduced type
651 //       (for potential switch back to 'intern    651 //       (for potential switch back to 'internal' type.)
652 //  Returns success (true) or failure (false)     652 //  Returns success (true) or failure (false)
653 //                                                653 //
654 G4bool G4LogicalVolume::ChangeDaughtersType(EV    654 G4bool G4LogicalVolume::ChangeDaughtersType(EVolume aType)
655 {                                                 655 {
656   G4bool works = false;                           656   G4bool works = false;
657   if( aType == kExternal )                        657   if( aType == kExternal )
658   {                                               658   {
659     // It is the responsibility of External Na    659     // It is the responsibility of External Navigator to handle types selected
660     //                                            660     //
661     fDaughtersVolumeType = aType;                 661     fDaughtersVolumeType = aType;
662     works = true;                                 662     works = true;
663   }                                               663   }
664   else                                            664   else
665   {                                               665   {
666     EVolume expectedVType = DeduceDaughtersTyp    666     EVolume expectedVType = DeduceDaughtersType();
667     works = (expectedVType == aType);             667     works = (expectedVType == aType);
668     if ( works )                                  668     if ( works )
669     {                                             669     {
670       fDaughtersVolumeType = aType;               670       fDaughtersVolumeType = aType;
671     }                                             671     }
672   }                                               672   }
673   return works;                                   673   return works;
674 }                                                 674 }
675                                                   675 
676 // *******************************************    676 // ********************************************************************
677 // SetVisAttributes - copy version                677 // SetVisAttributes - copy version
678 // *******************************************    678 // ********************************************************************
679 //                                                679 //
680 void G4LogicalVolume::SetVisAttributes (const     680 void G4LogicalVolume::SetVisAttributes (const G4VisAttributes& VA)
681 {                                                 681 {
682   if (G4Threading::IsWorkerThread()) return;      682   if (G4Threading::IsWorkerThread()) return;
683   fVisAttributes = std::make_shared<const G4Vi    683   fVisAttributes = std::make_shared<const G4VisAttributes>(VA);
684 }                                                 684 }
685                                                   685 
686 // *******************************************    686 // ********************************************************************
687 // SetVisAttributes                               687 // SetVisAttributes
688 // *******************************************    688 // ********************************************************************
689 //                                                689 //
690 void G4LogicalVolume::SetVisAttributes (const     690 void G4LogicalVolume::SetVisAttributes (const G4VisAttributes* pVA)
691 {                                                 691 {
692   if (G4Threading::IsWorkerThread()) return;      692   if (G4Threading::IsWorkerThread()) return;
693   fVisAttributes = std::shared_ptr<const G4Vis    693   fVisAttributes = std::shared_ptr<const G4VisAttributes>(pVA,[](const G4VisAttributes*){});
694 }                                                 694 }
695                                                   695