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 7.1)


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