Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/volumes/src/G4GeometryWorkspace.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/volumes/src/G4GeometryWorkspace.cc (Version 11.3.0) and /geometry/volumes/src/G4GeometryWorkspace.cc (Version 10.0.p1)


  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 //                                             << 
 26 // G4GeometryWorkspace - implementation        << 
 27 //                                                 25 //
 28 // Authors: John Apostolakis (CERN), Andrea Do << 
 29 // ------------------------------------------- << 
 30                                                    26 
 31 #include "G4GeometryWorkspace.hh"                  27 #include "G4GeometryWorkspace.hh"
                                                   >>  28 
                                                   >>  29 #include "G4PVReplica.hh"
                                                   >>  30 #include "G4PVParameterised.hh"
                                                   >>  31 #include "G4VPVParameterisation.hh"
 32 #include "G4PhysicalVolumeStore.hh"                32 #include "G4PhysicalVolumeStore.hh"
 33 #include "G4AutoLock.hh"                       <<  33 #include "G4VSolid.hh"
 34                                                    34 
 35 namespace                                      <<  35 #include "G4LogicalVolume.hh"
 36 {                                              <<  36 #include "G4VPhysicalVolume.hh"
 37   G4Mutex mutex_init = G4MUTEX_INITIALIZER;    <<  37 #include "G4PVReplica.hh"
 38   G4GeometryWorkspace::pool_type thePool;      <<  38 #include "G4Region.hh"
 39 }                                              <<  39 
                                                   >>  40 #include "G4AutoLock.hh"
 40                                                    41 
 41 // ------------------------------------------- << 
 42 //                                             << 
 43 G4GeometryWorkspace::pool_type* G4GeometryWork << 
 44 {                                              << 
 45   return &thePool;                             << 
 46 }                                              << 
 47                                                    42 
 48 // ------------------------------------------- << 
 49 //                                             << 
 50 G4GeometryWorkspace::G4GeometryWorkspace()         43 G4GeometryWorkspace::G4GeometryWorkspace()
                                                   >>  44   : fVerbose(false)
 51 {                                                  45 {
 52   fpLogicalVolumeSIM=                              46   fpLogicalVolumeSIM=
 53       &const_cast<G4LVManager&>(G4LogicalVolum     47       &const_cast<G4LVManager&>(G4LogicalVolume::GetSubInstanceManager());
 54   fpPhysicalVolumeSIM=                             48   fpPhysicalVolumeSIM=
 55       &const_cast<G4PVManager&>( G4VPhysicalVo     49       &const_cast<G4PVManager&>( G4VPhysicalVolume::GetSubInstanceManager() );
 56   fpReplicaSIM=                                    50   fpReplicaSIM=
 57       &const_cast<G4PVRManager&>(G4PVReplica::     51       &const_cast<G4PVRManager&>(G4PVReplica::GetSubInstanceManager());
 58   fpRegionSIM=                                     52   fpRegionSIM=
 59       &const_cast<G4RegionManager&>(G4Region::     53       &const_cast<G4RegionManager&>(G4Region::GetSubInstanceManager());
 60                                                    54 
 61   // Create a work area for Logical Volumes in <<  55   // Create a work area for Logical Volumes in this thread - then capture its address
 62   // then capture its address                  << 
 63   //                                           << 
 64   InitialiseWorkspace();                           56   InitialiseWorkspace();
 65                                                    57   
 66   fLogicalVolumeOffset = fpLogicalVolumeSIM->G <<  58   fLogicalVolumeOffset= fpLogicalVolumeSIM->GetOffset();
 67                                                    59 
 68   fPhysicalVolumeOffset = fpPhysicalVolumeSIM- <<  60   fPhysicalVolumeOffset= fpPhysicalVolumeSIM->GetOffset();
 69                                                    61 
 70   fReplicaOffset = fpReplicaSIM->GetOffset();  <<  62   fReplicaOffset= fpReplicaSIM->GetOffset();
 71                                                    63 
 72   fRegionOffset = fpRegionSIM->GetOffset();    <<  64   fRegionOffset= fpRegionSIM->GetOffset();
 73 }                                                  65 }
 74                                                    66 
 75 // ------------------------------------------- <<  67 G4GeometryWorkspace::~G4GeometryWorkspace()
 76 //                                             <<  68 {
                                                   >>  69   
                                                   >>  70 }
                                                   >>  71 
                                                   >>  72 //  Static methods 
                                                   >>  73 //      For with current (original) G4WorkerThread -- which uses static methods
                                                   >>  74 
 77 void                                               75 void
 78 G4GeometryWorkspace::UseWorkspace()                76 G4GeometryWorkspace::UseWorkspace()
 79 {                                                  77 {
 80   // Geometry related, split classes mechanism <<  78   if( fVerbose ) 
 81   // for this thread                           <<  79      G4cout << "G4GeometryWorkspace::UseWorkspace: Start " << G4endl;
 82   //                                           <<  80 
                                                   >>  81   // Implementation copied from  G4WorkerThread::BuildGeometryAndPhysicsVector()
                                                   >>  82   //  and improved for G4PVParamaterised
                                                   >>  83   //   John Apostolakis, May 30, 2013
                                                   >>  84   
                                                   >>  85   //Geometry related, split classes mechanism: instantiate sub-instance for this thread
 83   fpLogicalVolumeSIM->UseWorkArea(fLogicalVolu     86   fpLogicalVolumeSIM->UseWorkArea(fLogicalVolumeOffset);
 84   fpPhysicalVolumeSIM->UseWorkArea(fPhysicalVo     87   fpPhysicalVolumeSIM->UseWorkArea(fPhysicalVolumeOffset);
 85                                                    88   
 86   fpReplicaSIM->UseWorkArea(fReplicaOffset);       89   fpReplicaSIM->UseWorkArea(fReplicaOffset);
 87   fpRegionSIM->UseWorkArea(fRegionOffset);         90   fpRegionSIM->UseWorkArea(fRegionOffset);
 88                                                    91 
 89   // When recycling a workspace                    92   // When recycling a workspace 
 90   //   - it must be a lightweight operation, t     93   //   - it must be a lightweight operation, to reuse a valid work area
 91   //   - so it must NOT Initialise anything!       94   //   - so it must NOT Initialise anything!
 92   // Do not call InitialisePhysicalVolumes();      95   // Do not call InitialisePhysicalVolumes();
                                                   >>  96 
                                                   >>  97   if( fVerbose ) 
                                                   >>  98      G4cout << "G4GeometryWorkspace::UseWorkspace:  End " << G4endl;
 93 }                                                  99 }
 94                                                   100 
 95 // ------------------------------------------- << 101 
 96 //                                             << 
 97 void G4GeometryWorkspace::ReleaseWorkspace()      102 void G4GeometryWorkspace::ReleaseWorkspace()
                                                   >> 103 //  The opposite of Use Workspace - let go of it.
 98 {                                                 104 {
 99   fpLogicalVolumeSIM->UseWorkArea(nullptr);    << 105   fpLogicalVolumeSIM->UseWorkArea(0);
100   fpPhysicalVolumeSIM->UseWorkArea(nullptr);   << 106   fpPhysicalVolumeSIM->UseWorkArea(0);
101                                                   107   
102   fpReplicaSIM->UseWorkArea(nullptr);          << 108   fpReplicaSIM->UseWorkArea(0);
103   fpRegionSIM->UseWorkArea(nullptr);           << 109   fpRegionSIM->UseWorkArea(0);
104 }                                                 110 }
105                                                   111 
106 // ------------------------------------------- << 112 namespace {
107 //                                             << 113     G4Mutex solidclone= G4MUTEX_INITIALIZER;
                                                   >> 114 }
108 void G4GeometryWorkspace::InitialisePhysicalVo    115 void G4GeometryWorkspace::InitialisePhysicalVolumes()
109 {                                              << 
110   G4PhysicalVolumeStore* physVolStore = G4Phys << 
111   for (auto physVol : *physVolStore)           << 
112   {                                               116   {
113     G4LogicalVolume *logicalVol = physVol->Get << 117     G4PhysicalVolumeStore* physVolStore = G4PhysicalVolumeStore::GetInstance();
114                                                << 118     for (size_t ip=0; ip<physVolStore->size(); ip++)
115     // Use shadow pointer                      << 
116     //                                         << 
117     G4VSolid* solid = logicalVol->GetMasterSol << 
118     auto g4PVReplica = dynamic_cast<G4PVReplic << 
119     if (g4PVReplica == nullptr)                << 
120     {                                             119     {
121       // Placement volume                      << 120         G4VPhysicalVolume* physVol = (*physVolStore)[ip];
122       //                                       << 121         G4LogicalVolume *logicalVol = physVol->GetLogicalVolume();
123       logicalVol->InitialiseWorker(logicalVol, << 122         //use shadow pointer
                                                   >> 123         G4VSolid *solid = logicalVol->GetMasterSolid();
                                                   >> 124         G4PVReplica *g4PVReplica = 0;
                                                   >> 125         g4PVReplica =  dynamic_cast<G4PVReplica*>(physVol);
                                                   >> 126         if (!g4PVReplica)
                                                   >> 127         {
                                                   >> 128             // Placement volume
                                                   >> 129             logicalVol->InitialiseWorker(logicalVol,solid,0);
                                                   >> 130         }
                                                   >> 131         else
                                                   >> 132         {          
                                                   >> 133             //g4PVReplica->SlaveG4PVReplica(g4PVReplica);
                                                   >> 134             g4PVReplica->InitialiseWorker(g4PVReplica);
                                                   >> 135             if( ! g4PVReplica->IsParameterised() )
                                                   >> 136             {
                                                   >> 137                logicalVol->InitialiseWorker(logicalVol,solid,0);
                                                   >> 138                // If the replica's solid (in LV) is changed during navigation, it must be thread-private
                                                   >> 139                CloneReplicaSolid( g4PVReplica );
                                                   >> 140             }
                                                   >> 141             else
                                                   >> 142             {
                                                   >> 143                G4PVParameterised *paramVol
                                                   >> 144                    =  dynamic_cast<G4PVParameterised*>(physVol);
                                                   >> 145                if (!paramVol)
                                                   >> 146                {
                                                   >> 147                   G4Exception("G4GeometryWorkspace::CreateAndUseWorkspace", "Runtime Error PV01",
                                                   >> 148                               FatalException,
                                                   >> 149                               "Cannot find Parameterisation for G4PVParameterised object.");
                                                   >> 150                }
                                                   >> 151                CloneParameterisedSolids( paramVol );
                                                   >> 152             }
                                                   >> 153         }
124     }                                             154     }
125     else                                       << 155     if( fVerbose )
126     {                                          << 156        G4cout << "G4GeometryWorkspace::InitialisePhysicalVolumes: "
127       g4PVReplica->InitialiseWorker(g4PVReplic << 157               << "Copying geometry - Done!" << G4endl;
128       logicalVol->InitialiseWorker(logicalVol, << 
129                                                << 
130       // If the replica's solid (in LV) is cha << 
131       // it must be thread-private             << 
132       //                                       << 
133       CloneReplicaSolid( g4PVReplica );        << 
134     }                                          << 
135   }                                            << 
136 }                                                 158 }
137                                                   159 
138 // ------------------------------------------- << 160 
139 // Create a clone of the solid for this replic << 161 G4bool G4GeometryWorkspace::CloneReplicaSolid( G4PVReplica *replicaPV )
140 //                                             << 
141 G4bool G4GeometryWorkspace::CloneReplicaSolid( << 
142 {                                                 162 {
143   G4LogicalVolume* logicalV = replicaPV->GetLo << 163    // Create a clone of the solid for this replica in this thread
144   G4VSolid* solid = logicalV->GetSolid();      << 164 
                                                   >> 165    // Check that it is not a parameterisation ? 
145                                                   166 
146   G4AutoLock aLock(&mutex_init);               << 167    // The solid Ptr is in the Logical Volume
147   G4VSolid* workerSolid = solid->Clone();      << 168   G4LogicalVolume *logicalV= replicaPV ->GetLogicalVolume();
                                                   >> 169   G4VSolid *solid= logicalV->GetSolid();
                                                   >> 170 
                                                   >> 171   G4AutoLock aLock(&solidclone);
                                                   >> 172   G4VSolid *workerSolid = solid->Clone();
148   aLock.unlock();                                 173   aLock.unlock();
149                                                   174 
150   if( workerSolid != nullptr )                 << 175   if( workerSolid )
                                                   >> 176   {
                                                   >> 177     logicalV->InitialiseWorker(logicalV,workerSolid,0);
                                                   >> 178   }else{
                                                   >> 179     // In the case that not all solids support(ed) the Clone()
                                                   >> 180     // method, we do similar thing here to dynamically cast
                                                   >> 181     // and then get the clone method.
                                                   >> 182     G4ExceptionDescription ed;
                                                   >> 183     ed << " ERROR: Unable to initialise geometry for worker node." << G4endl;
                                                   >> 184     ed << " A solid lacks the Clone() method - or Clone() failed." << G4endl;
                                                   >> 185     ed << "   Type of solid: " << solid->GetEntityType() << G4endl;
                                                   >> 186     ed << "   Parameters: " << *solid << G4endl;
                                                   >> 187     G4Exception(" G4GeometryWorkspace::CloneParameterisedVolume", "MT-BuildGeometry001",
                                                   >> 188                 FatalException, ed);
                                                   >> 189     return false; 
                                                   >> 190   }
                                                   >> 191   return true; // It Worked
                                                   >> 192 }
                                                   >> 193 
                                                   >> 194 G4bool G4GeometryWorkspace::CloneParameterisedSolids( G4PVParameterised *paramVol )
                                                   >> 195 {
                                                   >> 196   // Each G4PVParameterised instance, has associated with it at least one
                                                   >> 197   // solid for each worker thread.
                                                   >> 198   // *Simple* Parameterisations have a single type of solid, and the
                                                   >> 199   // pointer points to the same instance of a solid during the  simulation.
                                                   >> 200   // For this case, it is possible to adapt automatically to
                                                   >> 201   // multi-threading, simply by cloning the solid - so long
                                                   >> 202   // as all solids support the Clone() method.
                                                   >> 203   
                                                   >> 204   // Check whether it is a simple parameterisation or not
                                                   >> 205   G4VPVParameterisation *param= paramVol->GetParameterisation();
                                                   >> 206   unsigned int numCopies= paramVol->GetMultiplicity();
                                                   >> 207   unsigned int numDifferent= 0;
                                                   >> 208 
                                                   >> 209   G4LogicalVolume *logicalV= paramVol->GetLogicalVolume();
                                                   >> 210   // assert( logicalV != 0);
                                                   >> 211   G4VSolid *solid= logicalV->GetSolid();
                                                   >> 212   
                                                   >> 213   for( unsigned int i=0; i< numCopies; i++)
                                                   >> 214   {
                                                   >> 215     G4VSolid *solidChk= param->ComputeSolid(i, paramVol);
                                                   >> 216     if( solidChk != solid)
                                                   >> 217     {
                                                   >> 218       numDifferent++;
                                                   >> 219     }
                                                   >> 220   }
                                                   >> 221   if( numDifferent>0 )
151   {                                               222   {
152     logicalV->InitialiseWorker(logicalV,worker << 223     G4ExceptionDescription ed;
                                                   >> 224 
                                                   >> 225     ed << " Parameterisation is implemented using several instances of Solids "
                                                   >> 226        << " - potentially to support different types of solids. " << G4endl;
                                                   >> 227     ed << "  The current implementation of Geant4-MT does not support "
                                                   >> 228     << " this type of Parameterisation" << G4endl;
                                                   >> 229     G4Exception("G4GeometryWorkspace::CloneParameterisedVolume", "GeometryNotSupportedInMT-01",
                                                   >> 230                 FatalException, ed);
153   }                                               231   }
154   else                                         << 232   
                                                   >> 233   // Threads may attempt to clone a solids simultaneously. Those cloned solids will be
                                                   >> 234   // registered into a shared solid store (C++ container). Need a lock to
                                                   >> 235   // guarantee thread safety
                                                   >> 236   G4AutoLock aLock(&solidclone);
                                                   >> 237   G4VSolid *workerSolid = solid->Clone();
                                                   >> 238   aLock.unlock();
                                                   >> 239   if( workerSolid )
155   {                                               240   {
                                                   >> 241     logicalV->InitialiseWorker(logicalV,workerSolid,0);
                                                   >> 242   }else{
156     // In the case that not all solids support    243     // In the case that not all solids support(ed) the Clone()
157     // method, we do similar thing here to dyn    244     // method, we do similar thing here to dynamically cast
158     // and then get the clone method           << 245     // and then get the clone method.
159     //                                         << 
160     G4ExceptionDescription ed;                    246     G4ExceptionDescription ed;
161     ed << "ERROR - Unable to initialise geomet << 247     ed << " ERROR: Unable to initialise geometry for worker node." << G4endl;
162        << "A solid lacks the Clone() method -  << 248     ed << " A solid lacks the Clone() method - or Clone() failed." << G4endl;
163        << "   Type of solid: " << solid->GetEn << 249     ed << "   Type of solid: " << solid->GetEntityType() << G4endl;
164        << "   Parameters: " << *solid;         << 250     ed << "   Parameters: " << *solid << G4endl;
165     G4Exception("G4GeometryWorkspace::CloneRep << 251     G4Exception(" G4GeometryWorkspace::CloneParameterisedVolume", "MT-BuildGeometry001",
166                 "GeomVol0003", FatalException, << 252                 FatalException, ed);
167     return false;                              << 
168   }                                               253   }
169   return true; // It Worked                       254   return true; // It Worked
170 }                                                 255 }
171                                                   256 
172 // ------------------------------------------- << 257 
173 //                                             << 258 void
174 void G4GeometryWorkspace::InitialiseWorkspace( << 259 G4GeometryWorkspace::InitialiseWorkspace()
175 {                                                 260 {
176   // Geometry related, split classes mechanism << 261   if( fVerbose ) 
177   // Do *NOT* instantiate sub-instance for thi << 262      G4cout << "G4GeometryWorkspace::InitialiseWorkspace: Copying geometry - Start " << G4endl;
178   //                                           << 263   
                                                   >> 264   // Implementation copied from  G4WorkerThread::BuildGeometryAndPhysicsVector()
                                                   >> 265   //  and improved for G4PVParamaterised
                                                   >> 266   //   John Apostolakis, May 30, 2013
                                                   >> 267   
                                                   >> 268   //Geometry related, split classes mechanism:
                                                   >> 269   //   Do *NOT* instantiate sub-instance for this thread,
                                                   >> 270   //     just copy the contents !!
179   fpLogicalVolumeSIM->SlaveCopySubInstanceArra    271   fpLogicalVolumeSIM->SlaveCopySubInstanceArray();
180   fpPhysicalVolumeSIM->SlaveCopySubInstanceArr    272   fpPhysicalVolumeSIM->SlaveCopySubInstanceArray();
181   fpReplicaSIM->SlaveCopySubInstanceArray();      273   fpReplicaSIM->SlaveCopySubInstanceArray();
182   fpRegionSIM->SlaveInitializeSubInstance();      274   fpRegionSIM->SlaveInitializeSubInstance();
183                                                   275 
184   InitialisePhysicalVolumes();                    276   InitialisePhysicalVolumes();
                                                   >> 277   
                                                   >> 278   if( fVerbose ) 
                                                   >> 279      G4cout << "G4GeometryWorkspace::InitialiseWorkspace: "
                                                   >> 280             << "Copying geometry - Done!" << G4endl;
185 }                                                 281 }
186                                                   282 
187 // ------------------------------------------- << 
188 //                                             << 
189 void G4GeometryWorkspace::DestroyWorkspace()      283 void G4GeometryWorkspace::DestroyWorkspace()
190 {                                                 284 {
191   G4PhysicalVolumeStore* physVolStore = G4Phys    285   G4PhysicalVolumeStore* physVolStore = G4PhysicalVolumeStore::GetInstance();
192   for (auto physVol : *physVolStore)           << 286   for (size_t ip=0; ip<physVolStore->size(); ip++)
193   {                                               287   {
194     G4LogicalVolume* logicalVol = physVol->Get << 288     G4VPhysicalVolume* physVol = (*physVolStore)[ip];
195     auto g4PVReplica = dynamic_cast<G4PVReplic << 289     G4LogicalVolume *logicalVol = physVol->GetLogicalVolume();
196     if (g4PVReplica != nullptr)                << 290     G4PVReplica *g4PVReplica = 0;
                                                   >> 291     g4PVReplica =  dynamic_cast<G4PVReplica*>(physVol);
                                                   >> 292     if (g4PVReplica)
197     {                                             293     {
198       g4PVReplica->TerminateWorker(g4PVReplica    294       g4PVReplica->TerminateWorker(g4PVReplica);
                                                   >> 295       G4PVParameterised *paramVol = 0;
                                                   >> 296       paramVol =  dynamic_cast<G4PVParameterised*>(physVol);
                                                   >> 297       if (paramVol)
                                                   >> 298       {
                                                   >> 299         // G4VSolid *solid = logicalVol->fSolid;
                                                   >> 300         logicalVol->TerminateWorker(logicalVol);
                                                   >> 301         // if( solid->IsClone() ) delete solid;
                                                   >> 302       }
                                                   >> 303       else
                                                   >> 304       {
                                                   >> 305         logicalVol->TerminateWorker(logicalVol);
                                                   >> 306       }
                                                   >> 307     }
                                                   >> 308     else
                                                   >> 309     {
                                                   >> 310       logicalVol->TerminateWorker(logicalVol);
199     }                                             311     }
200     logicalVol->TerminateWorker(logicalVol);   << 
201   }                                               312   }
202                                                << 313   
203   // Threads may attempt to free memory simult << 
204   // Need a lock to guarantee thread safety    << 
205   //                                           << 
206   G4AutoLock aLock(&mutex_init);               << 
207   fpLogicalVolumeSIM->FreeSlave();                314   fpLogicalVolumeSIM->FreeSlave();
208   fpPhysicalVolumeSIM->FreeSlave();               315   fpPhysicalVolumeSIM->FreeSlave();
209   fpReplicaSIM->FreeSlave();                      316   fpReplicaSIM->FreeSlave();
210   fpRegionSIM->FreeSlave();                       317   fpRegionSIM->FreeSlave();
211   aLock.unlock();                              << 
212 }                                                 318 }
213                                                   319