Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/management/src/G4GeometryManager.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/G4GeometryManager.cc (Version 11.3.0) and /geometry/management/src/G4GeometryManager.cc (Version 8.3.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 //                                                 25 //
 26 // Class G4GeometryManager implementation      << 
 27 //                                                 26 //
 28 // 26.07.95, P.Kent - Initial version, includi <<  27 // $Id: G4GeometryManager.cc,v 1.18 2006/06/29 18:33:23 gunter Exp $
 29 // 12.06.24, J.Apostolakis - Added parallel op <<  28 // GEANT4 tag $Name: geant4-08-03-patch-01 $
                                                   >>  29 //
                                                   >>  30 // class G4GeometryManager
                                                   >>  31 //
                                                   >>  32 // Implementation
                                                   >>  33 //
                                                   >>  34 // Author:
                                                   >>  35 // 26.07.95 P.Kent Initial version, including optimisation Build
 30 // -------------------------------------------     36 // --------------------------------------------------------------------
 31                                                    37 
 32 #include <iomanip>                                 38 #include <iomanip>
 33                                                << 
 34 #include "G4ios.hh"                            << 
 35 #include "G4Timer.hh"                              39 #include "G4Timer.hh"
 36 #include "G4GeometryManager.hh"                    40 #include "G4GeometryManager.hh"
 37 #include "G4SystemOfUnits.hh"                  <<  41 
 38 #include "G4Threading.hh"                      <<  42 #ifdef  G4GEOMETRY_VOXELDEBUG
                                                   >>  43 #include "G4ios.hh"
                                                   >>  44 #endif
 39                                                    45 
 40 // Needed for building optimisations               46 // Needed for building optimisations
 41 //                                                 47 //
 42 #include "G4LogicalVolumeStore.hh"                 48 #include "G4LogicalVolumeStore.hh"
 43 #include "G4VPhysicalVolume.hh"                    49 #include "G4VPhysicalVolume.hh"
 44 #include "G4SmartVoxelHeader.hh"                   50 #include "G4SmartVoxelHeader.hh"
 45 #include "voxeldefs.hh"                            51 #include "voxeldefs.hh"
 46                                                    52 
 47 // Needed for setting the extent for tolerance << 
 48 //                                             << 
 49 #include "G4GeometryTolerance.hh"              << 
 50 #include "G4SolidStore.hh"                     << 
 51 #include "G4VSolid.hh"                         << 
 52                                                << 
 53 // Needed for parallel optimisation            << 
 54 #include "G4AutoLock.hh"                       << 
 55                                                << 
 56 namespace  // Data structures / mutexes for pa << 
 57 {                                              << 
 58   // Mutex to obtain a volume to optimise      << 
 59   G4Mutex obtainVolumeMutex = G4MUTEX_INITIALI << 
 60                                                << 
 61   // Mutex to lock saving of voxel statistics  << 
 62   G4Mutex voxelStatsMutex = G4MUTEX_INITIALIZE << 
 63                                                << 
 64   // Mutex to provide Statistics Results       << 
 65   G4Mutex statResultsMutex = G4MUTEX_INITIALIZ << 
 66                                                << 
 67   // Mutex to start wall clock (global) timer  << 
 68   G4Mutex wallClockTimerMutex = G4MUTEX_INITIA << 
 69                                                << 
 70   // Mutex to write debug output               << 
 71   G4Mutex outputDbgMutex = G4MUTEX_INITIALIZER << 
 72 }                                              << 
 73                                                << 
 74 // *******************************************     53 // ***************************************************************************
 75 // Static class data                           <<  54 // Static class variable: ptr to single instance of class
 76 // *******************************************     55 // ***************************************************************************
 77 //                                                 56 //
 78 G4ThreadLocal G4GeometryManager* G4GeometryMan <<  57 G4GeometryManager* G4GeometryManager::fgInstance = 0;
 79                                                << 
 80 // Static *global* class data                  << 
 81 G4bool G4GeometryManager::fParallelVoxelOptimi << 
 82   // Records User choice to use parallel voxel << 
 83                                                << 
 84 G4bool  G4GeometryManager::fOptimiseInParallel << 
 85   // Configured = requested && available (ie i << 
 86   // Value calculated during each effort to op << 
 87                                                << 
 88 std::vector<G4LogicalVolume*> G4GeometryManage << 
 89 std::vector<G4LogicalVolume*>::const_iterator  << 
 90                                                << 
 91 std::vector<G4SmartVoxelStat> G4GeometryManage << 
 92 // Container for statistics                    << 
 93                                                << 
 94 // Derived state                               << 
 95 G4bool G4GeometryManager::fVerboseParallel = f << 
 96 G4bool G4GeometryManager::fParallelVoxelOptimi << 
 97 G4bool G4GeometryManager::fParallelVoxelOptimi << 
 98 G4double G4GeometryManager::fSumVoxelTime = 0. << 
 99                                                << 
100 G4int G4GeometryManager::fNumberThreadsReporti << 
101 unsigned int G4GeometryManager::fTotalNumberVo << 
102                                                << 
103 // For Wall clock                              << 
104 G4Timer* G4GeometryManager::fWallClockTimer =  << 
105 G4bool G4GeometryManager::fWallClockStarted =  << 
106                                                    58 
107 // *******************************************     59 // ***************************************************************************
108 // Destructor                                  <<  60 // Constructor. Set the geometry to be open
109 // *******************************************     61 // ***************************************************************************
110 //                                                 62 //
111 G4GeometryManager::~G4GeometryManager()        <<  63 G4GeometryManager::G4GeometryManager() 
112 {                                                  64 {
113   fgInstance = nullptr;                        <<  65   fIsClosed=false;
114   fIsClosed = false;                           << 
115                                                << 
116   if( fWallClockTimer && G4Threading::IsMaster << 
117   {                                            << 
118     delete fWallClockTimer;                    << 
119     fWallClockTimer= nullptr;                  << 
120   }                                            << 
121 }                                                  66 }
122                                                    67 
123 // *******************************************     68 // ***************************************************************************
124 // Closes geometry - performs sanity checks an     69 // Closes geometry - performs sanity checks and optionally builds optimisation
125 // for placed volumes (always built for replic     70 // for placed volumes (always built for replicas & parameterised).
126 // NOTE: Currently no sanity checks are perfor     71 // NOTE: Currently no sanity checks are performed.
127 // Applies to just a specific subtree if a phy     72 // Applies to just a specific subtree if a physical volume is specified.
128 // *******************************************     73 // ***************************************************************************
129 //                                                 74 //
130 G4bool G4GeometryManager::CloseGeometry(G4bool     75 G4bool G4GeometryManager::CloseGeometry(G4bool pOptimise, G4bool verbose,
131                                         G4VPhy     76                                         G4VPhysicalVolume* pVolume)
132 {                                                  77 {
133   if (!fIsClosed && G4Threading::IsMasterThrea <<  78    if (!fIsClosed)
134   {                                                79   {
135     if (pVolume != nullptr)                    <<  80     if (pVolume)
136     {                                              81     {
137       BuildOptimisations(pOptimise, pVolume);      82       BuildOptimisations(pOptimise, pVolume);
138     }                                              83     }
139     else                                           84     else
140     {                                              85     {
141       BuildOptimisations(pOptimise, verbose);      86       BuildOptimisations(pOptimise, verbose);
142     }                                              87     }
143     fIsClosed = true;                          <<  88     fIsClosed=true;
144   }                                                89   }
145   return true;                                     90   return true;
146 }                                                  91 }
147                                                    92 
148 // *******************************************     93 // ***************************************************************************
149 // Opens the geometry and removes optimisation     94 // Opens the geometry and removes optimisations (optionally, related to just
150 // the specified logical-volume).                  95 // the specified logical-volume).
151 // Applies to just a specific subtree if a phy     96 // Applies to just a specific subtree if a physical volume is specified.
152 // *******************************************     97 // ***************************************************************************
153 //                                                 98 //
154 void G4GeometryManager::OpenGeometry(G4VPhysic     99 void G4GeometryManager::OpenGeometry(G4VPhysicalVolume* pVolume)
155 {                                                 100 {
156   if (fIsClosed && G4Threading::IsMasterThread << 101   if (fIsClosed)
157   {                                               102   {
158     if (pVolume != nullptr)                    << 103     if (pVolume)
159     {                                             104     {
160       DeleteOptimisations(pVolume);               105       DeleteOptimisations(pVolume);
161     }                                             106     }
162     else                                          107     else
163     {                                             108     {
164       DeleteOptimisations();                      109       DeleteOptimisations();
165     }                                             110     }
166     fIsClosed = false;                         << 111     fIsClosed=false;
167   }                                               112   }
168 }                                                 113 }
169                                                   114 
170 // *******************************************    115 // ***************************************************************************
171 // Returns the instance of the singleton.      << 116 // Returns status of geometry
172 // Creates it in case it's called for the firs << 
173 // *******************************************    117 // ***************************************************************************
174 //                                                118 //
175 G4GeometryManager* G4GeometryManager::GetInsta << 119 G4bool G4GeometryManager::IsGeometryClosed()
176 {                                                 120 {
177   if (fgInstance == nullptr)                   << 121   return fIsClosed;
178   {                                            << 
179     fgInstance = new G4GeometryManager;        << 
180                                                << 
181     if( (fWallClockTimer == nullptr) && G4Thre << 
182     {                                          << 
183       fWallClockTimer = new G4Timer;           << 
184     }                                          << 
185   }                                            << 
186   return fgInstance;                           << 
187 }                                                 122 }
188                                                   123 
189 // *******************************************    124 // ***************************************************************************
190 // Returns the instance of the singleton.         125 // Returns the instance of the singleton.
                                                   >> 126 // Creates it in case it's called for the first time.
191 // *******************************************    127 // ***************************************************************************
192 //                                                128 //
193 G4GeometryManager* G4GeometryManager::GetInsta << 129 G4GeometryManager* G4GeometryManager::GetInstance()
194 {                                              << 
195   return fgInstance;                           << 
196 }                                              << 
197                                                << 
198 // ******************************************* << 
199 // Simplest user method to request parallel op << 
200 // ******************************************* << 
201 //                                             << 
202 void G4GeometryManager::OptimiseInParallel( G4 << 
203 {                                              << 
204   RequestParallelOptimisation(val);            << 
205 }                                              << 
206                                                << 
207 // ******************************************* << 
208 // Report about Voxel(isation) of a logical vo << 
209 // ******************************************* << 
210 //                                             << 
211 void                                           << 
212 G4GeometryManager::ReportVoxelInfo(G4LogicalVo << 
213 {                                              << 
214   G4SmartVoxelHeader* head = logVolume->GetVox << 
215   if( head != nullptr )                        << 
216   {                                            << 
217     os << "** Created optimisations for logica << 
218        << std::setw(50) << logVolume->GetName( << 
219        << "- Result VoxelInfo - START: " << "  << 
220        << *head                                << 
221        << "- Result VoxelInfo -   END. " << G4 << 
222   }                                            << 
223   else                                         << 
224   {                                            << 
225     os << "** No optimisation for log-vol " << << 
226   }                                            << 
227   os << "*** Report Voxel Info: END " <<  G4en << 
228 }                                              << 
229                                                << 
230 // ******************************************* << 
231 // Creates optimisation info. Builds all voxel << 
232 // otherwise it builds voxels only for replica << 
233 // ******************************************* << 
234 // Returns whether optimisation is finished    << 
235 //                                             << 
236 G4bool G4GeometryManager::BuildOptimisations(G << 
237 {                                                 130 {
238   G4bool finishedOptimisation = false;         << 131   static G4GeometryManager worldManager;
239                                                << 132   if (!fgInstance)
240   fOptimiseInParallelConfigured = fParallelVox << 
241                                && G4Threading: << 
242                                                << 
243   static unsigned int NumCallsBuildOptimisatio << 
244   if( fOptimiseInParallelConfigured && (NumCal << 
245   {                                            << 
246     PrepareParallelOptimisation(allOpts, verbo << 
247     ++NumCallsBuildOptimisations;              << 
248   }                                            << 
249   else                                         << 
250   {                                               133   {
251     BuildOptimisationsSequential(allOpts, verb << 134     fgInstance = &worldManager;
252     finishedOptimisation= true;                << 
253   }                                               135   }
254                                                << 136   return fgInstance;    
255   return finishedOptimisation;                 << 
256 }                                                 137 }
257                                                   138 
258 // *******************************************    139 // ***************************************************************************
259 // Creates optimisation info. Builds all voxel    140 // Creates optimisation info. Builds all voxels if allOpts=true
260 // otherwise it builds voxels only for replica    141 // otherwise it builds voxels only for replicated volumes.
261 //                                             << 
262 // This is the original sequential implementat << 
263 // - at first initialisation to create voxels, << 
264 // - at re-initialisation if the geometry has  << 
265 // *******************************************    142 // ***************************************************************************
266 //                                                143 //
267 void G4GeometryManager::BuildOptimisationsSequ << 144 void G4GeometryManager::BuildOptimisations(G4bool allOpts, G4bool verbose)
268                                                << 
269 {                                                 145 {
270   G4Timer timer;                               << 146    G4Timer timer;
271   G4Timer allTimer;                            << 147    G4Timer allTimer;
272   std::vector<G4SmartVoxelStat> stats;         << 148    std::vector<G4SmartVoxelStat> stats;
273                                                << 149    if (verbose)  { allTimer.Start(); }
274   if (verbose)  { allTimer.Start(); }          << 150 
275                                                << 151    G4LogicalVolumeStore* Store = G4LogicalVolumeStore::GetInstance();
276   G4LogicalVolumeStore* Store = G4LogicalVolum << 152    G4LogicalVolume* volume;
277   G4LogicalVolume* volume;                     << 153    G4SmartVoxelHeader* head;
278   G4SmartVoxelHeader* head;                    << 154  
279                                                << 155    for (size_t n=0; n<Store->size(); n++)
280 #ifdef G4GEOMETRY_VOXELDEBUG                   << 156    {
281   G4cout << G4endl                             << 157      if (verbose) timer.Start();
282      << "*** G4GeometryManager::BuildOptimisat << 158      volume=(*Store)[n];
283      << G4Threading::G4GetThreadId() << " all- << 159      // For safety, check if there are any existing voxels and
284 #endif                                         << 160      // delete before replacement
285                                                << 161      //
286   for (auto & n : *Store)                      << 162      head = volume->GetVoxelHeader();
287   {                                            << 163      delete head;
288     if (verbose) timer.Start();                << 164      volume->SetVoxelHeader(0);
289     volume=n;                                  << 165      if (    (volume->IsToOptimise())
290     // For safety, check if there are any exis << 166           && (volume->GetNoDaughters()>=kMinVoxelVolumesLevel1&&allOpts)
291     // delete before replacement               << 167           || ( (volume->GetNoDaughters()==1)
292     //                                         << 168             && (volume->GetDaughter(0)->IsReplicated()==true) ) ) 
293     head = volume->GetVoxelHeader();           << 169      {
294     delete head;                               << 
295     volume->SetVoxelHeader(nullptr);           << 
296     if (    ( (volume->IsToOptimise())         << 
297              && (volume->GetNoDaughters()>=kMi << 
298         || ( (volume->GetNoDaughters()==1)     << 
299             && (volume->GetDaughter(0)->IsRepl << 
300             && (volume->GetDaughter(0)->GetReg << 
301     {                                          << 
302 #ifdef G4GEOMETRY_VOXELDEBUG                      170 #ifdef G4GEOMETRY_VOXELDEBUG
303     G4cout << "** G4GeometryManager::BuildOpti << 171        G4cout << "**** G4GeometryManager::BuildOptimisations" << G4endl
304            << "   Examining logical volume nam << 172               << "     Examining logical volume name = "
305            << "'  #daughters= " << volume->Get << 173               << volume->GetName() << G4endl;
306 #endif                                            174 #endif
307       head = new G4SmartVoxelHeader(volume);   << 175        head = new G4SmartVoxelHeader(volume);
308                                                << 176        if (head)
309       if (head != nullptr)                     << 177        {
310       {                                        << 178          volume->SetVoxelHeader(head);
311         volume->SetVoxelHeader(head);          << 179        }
312       }                                        << 180        else
313       else                                     << 181        {
314       {                                        << 182          G4cerr << "ERROR - Allocation of new VoxelHeader" << G4endl
315         std::ostringstream message;            << 183                 << "        for volume " << volume->GetName() << " failed."
316         message << "VoxelHeader allocation err << 184                 << G4endl;
317                 << "Allocation of new VoxelHea << 185          G4Exception("G4GeometryManager::BuildOptimisations()", "FatalError",
318                 << "        for volume '" << v << 186                      FatalException, "VoxelHeader allocation error.");
319         G4Exception("G4GeometryManager::BuildO << 187        }
320                     FatalException, message);  << 188        if (verbose)
321       }                                        << 189        {
322       if (verbose)                             << 190          timer.Stop();
323       {                                        << 191          stats.push_back( G4SmartVoxelStat( volume, head,
324         timer.Stop();                          << 192                                             timer.GetSystemElapsed(),
325         stats.emplace_back( volume, head,      << 193                                             timer.GetUserElapsed() ) );
326                            timer.GetSystemElap << 194        }
327                            timer.GetUserElapse << 195      }
328       }                                        << 196      else
329     }                                          << 197      {
330     else                                       << 198        // Don't create voxels for this node
331     {                                          << 
332       // Don't create voxels for this node     << 
333 #ifdef G4GEOMETRY_VOXELDEBUG                      199 #ifdef G4GEOMETRY_VOXELDEBUG
334       auto numDaughters = volume->GetNoDaughte << 200        G4cout << "**** G4GeometryManager::BuildOptimisations" << G4endl
335       G4cout << "- Skipping logical volume wit << 201               << "     Skipping logical volume name = " << volume->GetName()
336              << " daughters and name = '" << v << 202               << G4endl;
337       if( numDaughters > 1 )                   << 
338       {                                        << 
339         G4cout << "[Placement]";               << 
340       }                                        << 
341       else                                     << 
342       {                                        << 
343         if( numDaughters == 1 )                << 
344         {                                      << 
345           G4cout << ( volume->GetDaughter(0)-> << 
346                                                << 
347         }                                      << 
348       }                                        << 
349       G4cout << G4endl;                        << 
350 #endif                                            203 #endif
351     }                                          << 204      }
352   }                                               205   }
353   if (verbose)                                    206   if (verbose)
354   {                                               207   {
355     allTimer.Stop();                           << 208      allTimer.Stop();
356                                                << 209      ReportVoxelStats( stats, allTimer.GetSystemElapsed()
357     ReportVoxelStats( stats, allTimer.GetSyste << 210                             + allTimer.GetUserElapsed() );
358                      + allTimer.GetUserElapsed << 
359   }                                            << 
360 }                                              << 
361                                                << 
362 // ******************************************* << 
363 // Creates a list of logical volumes which wil << 
364 //    if allOpts=true it lists all voxels      << 
365 //    otherwise       it lists only the voxels << 
366 // This list will be used subsequently to buil << 
367 //                                             << 
368 // Note: this method is NOT thread safe!       << 
369 //    It expects to be called only once in eac << 
370 //    i.e. either by master thread or a select << 
371 // ******************************************* << 
372 //                                             << 
373 void                                           << 
374 G4GeometryManager::CreateListOfVolumesToOptimi << 
375 {                                              << 
376   // Prepare the work - must be called only in << 
377                                                << 
378   G4LogicalVolumeStore* Store = G4LogicalVolum << 
379                                                << 
380   if( !fVolumesToOptimise.empty() )            << 
381   {                                            << 
382     ResetListOfVolumesToOptimise();            << 
383   }                                            << 
384                                                << 
385   for (auto & n : *Store)                      << 
386   {                                            << 
387     G4LogicalVolume* volume=n;                 << 
388                                                << 
389     if (    ( (volume->IsToOptimise())         << 
390              && (volume->GetNoDaughters()>=kMi << 
391         || ( (volume->GetNoDaughters()==1)     << 
392             && (volume->GetDaughter(0)->IsRepl << 
393             && (volume->GetDaughter(0)->GetReg << 
394     {                                          << 
395       fVolumesToOptimise.push_back(volume);    << 
396                                                << 
397       // For safety, must check (later) if the << 
398       //     delete before replacement:        << 
399       // All 'clients' of this code must do th << 
400       //   delete volume->GetVoxelHeader();    << 
401       //   volume->SetVoxelHeader(nullptr);    << 
402                                                << 
403 #ifdef G4GEOMETRY_VOXELDEBUG                   << 
404       G4cout << "- Booking  logical volume wit << 
405       << " daughters and name = '" << volume-> << 
406       << " -- for optimisation (ie voxels will << 
407 #endif                                         << 
408     }                                          << 
409     else                                       << 
410     {                                          << 
411 #ifdef G4GEOMETRY_VOXELDEBUG                   << 
412       G4cout << "- Skipping logical volume wit << 
413       << " daughters and name = '" << volume-> << 
414 #endif                                         << 
415     }                                          << 
416   }                                            << 
417                                                << 
418   if(verbose)                                  << 
419     G4cout << "** G4GeometryManager::PrepareOp << 
420            << "  Number of volumes for voxelis << 
421            << fVolumesToOptimise.size() << G4e << 
422                                                << 
423   fLogVolumeIterator = fVolumesToOptimise.cbeg << 
424 }                                              << 
425                                                << 
426 // ******************************************* << 
427 // Obtain a logical volume from the list of vo << 
428 // Must be thread-safe: its role is to be call << 
429 // Critical method for parallel optimisation - << 
430 // ******************************************* << 
431 //                                             << 
432 G4LogicalVolume* G4GeometryManager::ObtainVolu << 
433 {                                              << 
434   G4LogicalVolume* logVolume = nullptr;        << 
435                                                << 
436   G4AutoLock lock(obtainVolumeMutex);          << 
437                                                << 
438   if( fLogVolumeIterator != fVolumesToOptimise << 
439   {                                            << 
440     logVolume = *fLogVolumeIterator;           << 
441     ++fLogVolumeIterator;                      << 
442   }                                            << 
443   return logVolume;                            << 
444 }                                              << 
445                                                << 
446 // ******************************************* << 
447 // Thread-safe method to clear the list of vol << 
448 // ******************************************* << 
449 //                                             << 
450 void G4GeometryManager::ResetListOfVolumesToOp << 
451 {                                              << 
452   G4AutoLock lock(obtainVolumeMutex);          << 
453                                                << 
454   std::vector<G4LogicalVolume*>().swap(fVolume << 
455   // Swapping with an empty vector in order to << 
456   // without calling destructors of logical vo << 
457   // Must not call clear: i.e. fVolumesToOptim << 
458                                                << 
459   assert(fVolumesToOptimise.empty());          << 
460   fLogVolumeIterator = fVolumesToOptimise.cbeg << 
461                                                << 
462   fGlobVoxelStats.clear();                     << 
463   // Reset also the statistics of volumes -- t << 
464 }                                              << 
465                                                << 
466 // ******************************************* << 
467 // Method which user calls to ask for parallel << 
468 // ******************************************* << 
469 //                                             << 
470 void G4GeometryManager::RequestParallelOptimis << 
471 {                                              << 
472   fParallelVoxelOptimisationRequested = flag;  << 
473   if( flag )                                   << 
474   {                                            << 
475     ConfigureParallelOptimisation(verbose);    << 
476   }                                            << 
477 }                                              << 
478                                                << 
479 // ******************************************* << 
480 // Setup up state to enable parallel optimisat << 
481 // ******************************************* << 
482 //                                             << 
483 void G4GeometryManager::ConfigureParallelOptim << 
484 {                                              << 
485   if(verbose)                                  << 
486   {                                            << 
487     G4cout << "** G4GeometryManager::Configure << 
488     << " LEAVING all the work (of voxel optimi << 
489     << G4endl;                                 << 
490   }                                            << 
491   fParallelVoxelOptimisationRequested = true;  << 
492   fParallelVoxelOptimisationUnderway = false;  << 
493   fParallelVoxelOptimisationFinished = false;  << 
494                                                << 
495   // Keep values of options / verbosity for us << 
496   fVerboseParallel = verbose;                  << 
497                                                << 
498   // New effort -- reset the total time -- and << 
499   fSumVoxelTime = 0.0;                         << 
500   fNumberThreadsReporting = 0;                 << 
501   fTotalNumberVolumesOptimised = 0;   // Numbe << 
502                                                << 
503   fWallClockStarted = false;  // Will need to  << 
504 }                                              << 
505                                                << 
506 // ******************************************* << 
507 // Build voxel optimisation in parallel -- pre << 
508 // ******************************************* << 
509 //                                             << 
510 void                                           << 
511 G4GeometryManager::PrepareParallelOptimisation << 
512 {                                              << 
513   if( verbose )                                << 
514   {                                            << 
515     G4cout << "** G4GeometryManager::PreparePa << 
516            << G4endl;                          << 
517   }                                            << 
518   CreateListOfVolumesToOptimise(allOpts, verbo << 
519   ConfigureParallelOptimisation(verbose);      << 
520 }                                              << 
521                                                << 
522 // ******************************************* << 
523 // Method for a thread/task to contribute dyna << 
524 // ******************************************* << 
525 //                                             << 
526 void G4GeometryManager::UndertakeOptimisation( << 
527 {                                              << 
528   G4bool verbose = fVerboseParallel;           << 
529   G4LogicalVolume* logVolume = nullptr;        << 
530                                                << 
531   fParallelVoxelOptimisationUnderway  = true;  << 
532                                                << 
533   // Start timer - if not already done         << 
534   if( ( !fWallClockStarted ) && verbose )      << 
535   {                                            << 
536     G4AutoLock startTimeLock(wallClockTimerMut << 
537     if( !fWallClockStarted )                   << 
538     {                                          << 
539       fWallClockTimer->Start();                << 
540       fWallClockStarted= true;                 << 
541     }                                          << 
542   }                                            << 
543                                                << 
544   G4Timer fetimer;                             << 
545   unsigned int numVolumesOptimised = 0;        << 
546                                                << 
547   while( (logVolume = ObtainVolumeToOptimise() << 
548   {                                            << 
549     if (verbose) fetimer.Start();              << 
550                                                << 
551     G4SmartVoxelHeader* head = logVolume->GetV << 
552     delete head;                               << 
553     logVolume->SetVoxelHeader(nullptr);        << 
554                                                << 
555     head = new G4SmartVoxelHeader(logVolume);  << 
556     //     *********************************   << 
557     logVolume->SetVoxelHeader(head);           << 
558                                                << 
559     if (head != nullptr)                       << 
560     {                                          << 
561       ++numVolumesOptimised;                   << 
562     }                                          << 
563     else                                       << 
564     {                                          << 
565       G4ExceptionDescription message;          << 
566       message << "VoxelHeader allocation error << 
567               << "Allocation of new VoxelHeade << 
568               << "for logical volume " << logV << 
569       G4Exception("G4GeometryManager::BuildOpt << 
570                   "GeomMgt0003", FatalExceptio << 
571     }                                          << 
572                                                << 
573     if(verbose)                                << 
574     {                                          << 
575       fetimer.Stop();                          << 
576       auto feRealElapsed = fetimer.GetRealElap << 
577       // Must use 'real' elapsed time -- canno << 
578       // (it accounts for all threads)         << 
579                                                << 
580       G4AutoLock lock(voxelStatsMutex);        << 
581       fGlobVoxelStats.emplace_back( logVolume, << 
582                           0.0,             //  << 
583                           feRealElapsed ); //  << 
584       fSumVoxelTime += feRealElapsed;          << 
585     }                                          << 
586   }                                            << 
587                                                << 
588   G4bool allDone = false;                      << 
589   G4int myCount= -1;                           << 
590                                                << 
591   myCount = ReportWorkerIsDoneOptimising(numVo << 
592   allDone = IsParallelOptimisationFinished();  << 
593                                                << 
594   if( allDone && (myCount == G4Threading::GetN << 
595   {                                            << 
596     G4int badVolumes = CheckOptimisation(); // << 
597     if( badVolumes > 0 )                       << 
598     {                                          << 
599       G4ExceptionDescription errmsg;           << 
600       errmsg <<" Expected that all voxelisatio << 
601              << "but found that voxels headers << 
602              << badVolumes << " volumes.";     << 
603       G4Exception("G4GeometryManager::Undertak << 
604                   "GeomMng002", FatalException << 
605     }                                          << 
606                                                << 
607     // Create report                           << 
608                                                << 
609     if( verbose )                              << 
610     {                                          << 
611       fWallClockTimer->Stop();                 << 
612                                                << 
613       std::ostream& report_stream = std::cout; << 
614       report_stream << G4endl                  << 
615         << "G4GeometryManager::UndertakeOptimi << 
616         << " -- Timing for Voxel Optimisation" << 
617       report_stream << "  - Elapsed time (real << 
618         << fWallClockTimer->GetRealElapsed() < << 
619         << ", user " << fWallClockTimer->GetUs << 
620         << ", system " << fWallClockTimer->Get << 
621         << G4endl;                             << 
622       report_stream << "  - Sum voxel time (re << 
623                     << "s.";                   << 
624       report_stream << std::setprecision(6) << << 
625                                                << 
626       ReportVoxelStats( fGlobVoxelStats, fSumV << 
627       report_stream.flush();                   << 
628     }                                          << 
629   }                                            << 
630   else                                         << 
631   {                                            << 
632     WaitForVoxelisationFinish(false);          << 
633   }                                            << 
634 }                                              << 
635                                                << 
636 // ******************************************* << 
637 // Ensure that all the work of voxelisation is << 
638 // Can be called in GeometryManager methods or << 
639 // ******************************************* << 
640 //                                             << 
641 void G4GeometryManager::WaitForVoxelisationFin << 
642 {                                              << 
643   // Must wait until all workers are done ...  << 
644   using namespace std::chrono_literals;        << 
645   unsigned int trials = 0;                     << 
646   auto tid = G4Threading::G4GetThreadId();     << 
647                                                << 
648   std::ostream& out_stream = std::cout; // G4c << 
649   while( ! IsParallelOptimisationFinished() )  << 
650   {                                            << 
651     // Each thread must wait until all are don << 
652     std::this_thread::sleep_for(250ms);        << 
653     ++trials;                                  << 
654   }                                            << 
655                                                << 
656   if( verbose )                                << 
657   {                                            << 
658     G4AutoLock lock(outputDbgMutex);           << 
659     out_stream << G4endl                       << 
660                << "** UndertakeOptimisation do << 
661                <<  " after waiting for " << tr << 
662     out_stream.flush();                        << 
663   }                                               211   }
664 }                                                 212 }
665                                                   213 
666 // *******************************************    214 // ***************************************************************************
667 // Ensure that all logical volumes in list hav << 215 // Creates optimisation info for the specified volumes subtree.
668 // ******************************************* << 
669 //                                             << 
670 G4int G4GeometryManager::CheckOptimisation()   << 
671 {                                              << 
672   unsigned int numErrors = 0;                  << 
673   for ( const auto& logical : fVolumesToOptimi << 
674   {                                            << 
675     if( logical->GetVoxelHeader() == nullptr ) << 
676   }                                            << 
677   return numErrors;                            << 
678 }                                              << 
679                                                << 
680 // ******************************************* << 
681 // Report that current thread/task is done opt << 
682 // A thread call this method to reports that i << 
683 // many volumes it optimised. The method:      << 
684 //   - increments the count of workers that ha << 
685 //   - keeps count of number of volumes optimi << 
686 //   - if all works is done (ie all workers ha << 
687 //     in the 'Finished' state.                << 
688 // ******************************************* << 
689 //                                             << 
690 G4int                                          << 
691 G4GeometryManager::ReportWorkerIsDoneOptimisin << 
692 {                                              << 
693   // Check that all are done and, if so, signa << 
694   G4int orderReporting;                        << 
695                                                << 
696   G4AutoLock lock(statResultsMutex);           << 
697   orderReporting = ++fNumberThreadsReporting;  << 
698   fTotalNumberVolumesOptimised += numVolumesOp << 
699                                                << 
700   if (fNumberThreadsReporting == G4Threading:: << 
701   {                                            << 
702     InformOptimisationIsFinished(fVerboseParal << 
703   }                                            << 
704                                                << 
705   return orderReporting;                       << 
706 }                                              << 
707                                                << 
708 // ******************************************* << 
709 // Inform that all work for parallel optimisat << 
710 // ******************************************* << 
711 //                                             << 
712 void G4GeometryManager::InformOptimisationIsFi << 
713 {                                              << 
714   if(verbose)   // G4cout does not work!       << 
715   {                                            << 
716     std::cout << "** G4GeometryManager: All vo << 
717               << G4endl;                       << 
718     std::cout << "   Total number of volumes o << 
719               << fTotalNumberVolumesOptimised  << 
720               << " of " << fVolumesToOptimise. << 
721     std::cout << "   Number of workers reporti << 
722               << fNumberThreadsReporting       << 
723               << " of " << G4Threading::GetNum << 
724               << " expected\n";                << 
725   }                                            << 
726   assert ( fTotalNumberVolumesOptimised == fVo << 
727                                                << 
728   fParallelVoxelOptimisationFinished  = true;  << 
729   // fParallelVoxelOptimisationRequested = fal << 
730   fParallelVoxelOptimisationUnderway  = false; << 
731 }                                              << 
732                                                << 
733 // ******************************************* << 
734 // Creates Optimisation info for the specified << 
735 // *******************************************    216 // ***************************************************************************
736 //                                                217 //
737 void G4GeometryManager::BuildOptimisations(G4b    218 void G4GeometryManager::BuildOptimisations(G4bool allOpts,
738                                            G4V    219                                            G4VPhysicalVolume* pVolume)
739 {                                                 220 {
740   if (pVolume == nullptr) { return; }          << 221    if (!pVolume) { return; }
741                                                << 
742   // Retrieve the mother logical volume, if no << 
743   // otherwise apply global optimisation for t << 
744   //                                           << 
745   G4LogicalVolume* tVolume = pVolume->GetMothe << 
746   if (tVolume == nullptr)                      << 
747   {                                            << 
748     BuildOptimisations(allOpts, false);        << 
749     return;                                    << 
750   }                                            << 
751                                                   222 
752   G4SmartVoxelHeader* head = tVolume->GetVoxel << 223    // Retrieve the mother logical volume, if not NULL,
753   delete head;                                 << 224    // otherwise apply global optimisation for the world volume
754   tVolume->SetVoxelHeader(nullptr);            << 225    //
755   if (    ( (tVolume->IsToOptimise())          << 226    G4LogicalVolume* tVolume = pVolume->GetMotherLogical();
756          && (tVolume->GetNoDaughters()>=kMinVo << 227    if (!tVolume) { return BuildOptimisations(allOpts, false); }
757        || ( (tVolume->GetNoDaughters()==1)     << 228 
758          && (tVolume->GetDaughter(0)->IsReplic << 229    G4SmartVoxelHeader* head = tVolume->GetVoxelHeader();
759   {                                            << 230    delete head;
760     head = new G4SmartVoxelHeader(tVolume);    << 231    tVolume->SetVoxelHeader(0);
761     if (head != nullptr)                       << 232    if (    (tVolume->IsToOptimise())
762     {                                          << 233         && (tVolume->GetNoDaughters()>=kMinVoxelVolumesLevel1&&allOpts)
763       tVolume->SetVoxelHeader(head);           << 234         || ( (tVolume->GetNoDaughters()==1)
764     }                                          << 235           && (tVolume->GetDaughter(0)->IsReplicated()==true) ) ) 
765     else                                       << 236    {
766     {                                          << 237      head = new G4SmartVoxelHeader(tVolume);
767       std::ostringstream message;              << 238      if (head)
768       message << "VoxelHeader allocation error << 239      {
769               << "Allocation of new VoxelHeade << 240        tVolume->SetVoxelHeader(head);
770               << "        for volume " << tVol << 241      }
771       G4Exception("G4GeometryManager::BuildOpt << 242      else
772                   FatalException, message);    << 243      {
773     }                                          << 244        G4cerr << "ERROR - Allocation of new VoxelHeader" << G4endl
774   }                                            << 245               << "        for volume " << tVolume->GetName() << " failed."
775   else                                         << 246               << G4endl;
776   {                                            << 247        G4Exception("G4GeometryManager::BuildOptimisations()", "FatalError",
777     // Don't create voxels for this node       << 248                    FatalException, "VoxelHeader allocation error.");
                                                   >> 249      }
                                                   >> 250    }
                                                   >> 251    else
                                                   >> 252    {
                                                   >> 253      // Don't create voxels for this node
778 #ifdef G4GEOMETRY_VOXELDEBUG                      254 #ifdef G4GEOMETRY_VOXELDEBUG
779     G4cout << "** G4GeometryManager::BuildOpti << 255      G4cout << "**** G4GeometryManager::BuildOptimisations" << G4endl
780            << "     Skipping logical volume na << 256             << "     Skipping logical volume name = " << volume->GetName()
781            << G4endl;                          << 257             << G4endl;
782 #endif                                            258 #endif
783   }                                            << 259    }
784                                                   260 
785   // Scan recursively the associated logical v << 261    // Scan recursively the associated logical volume tree
786   //                                           << 262    //
787   tVolume = pVolume->GetLogicalVolume();          263   tVolume = pVolume->GetLogicalVolume();
788   if (tVolume->GetNoDaughters() != 0)          << 264   if (tVolume->GetNoDaughters()) {  BuildOptimisations(allOpts, tVolume->GetDaughter(0)); }
789   {                                            << 
790     BuildOptimisations(allOpts, tVolume->GetDa << 
791   }                                            << 
792 }                                                 265 }
793                                                   266 
794 // *******************************************    267 // ***************************************************************************
795 // Removes all optimisation info.                 268 // Removes all optimisation info.
796 // Loops over all logical volumes, deleting no << 269 // Loops over all logical volumes, deleting non-null voxels pointers,
797 // *******************************************    270 // ***************************************************************************
798 //                                                271 //
799 void G4GeometryManager::DeleteOptimisations()     272 void G4GeometryManager::DeleteOptimisations()
800 {                                                 273 {
801   G4LogicalVolume* tVolume = nullptr;          << 274   G4LogicalVolume* tVolume = 0;
802   G4LogicalVolumeStore* Store = G4LogicalVolum    275   G4LogicalVolumeStore* Store = G4LogicalVolumeStore::GetInstance();
803   for (auto & n : *Store)                      << 276   for (size_t n=0; n<Store->size(); n++)
804   {                                               277   {
805     tVolume=n;                                 << 278     tVolume=(*Store)[n];
806     delete tVolume->GetVoxelHeader();             279     delete tVolume->GetVoxelHeader();
807     tVolume->SetVoxelHeader(nullptr);          << 280     tVolume->SetVoxelHeader(0);
808   }                                               281   }
809 }                                                 282 }
810                                                   283 
811 // *******************************************    284 // ***************************************************************************
812 // Removes optimisation info for the specified    285 // Removes optimisation info for the specified subtree.
813 // Scans recursively all daughter volumes, del    286 // Scans recursively all daughter volumes, deleting non-null voxels pointers.
814 // *******************************************    287 // ***************************************************************************
815 //                                                288 //
816 void G4GeometryManager::DeleteOptimisations(G4    289 void G4GeometryManager::DeleteOptimisations(G4VPhysicalVolume* pVolume)
817 {                                                 290 {
818   if (pVolume == nullptr) { return; }          << 291   if (!pVolume) { return; }
819                                                   292 
820   // Retrieve the mother logical volume, if no    293   // Retrieve the mother logical volume, if not NULL,
821   // otherwise global deletion to world volume    294   // otherwise global deletion to world volume.
822   //                                              295   //
823   G4LogicalVolume* tVolume = pVolume->GetMothe    296   G4LogicalVolume* tVolume = pVolume->GetMotherLogical();
824   if (tVolume == nullptr) { return DeleteOptim << 297   if (!tVolume) { return DeleteOptimisations(); }
825   delete tVolume->GetVoxelHeader();               298   delete tVolume->GetVoxelHeader();
826   tVolume->SetVoxelHeader(nullptr);            << 299   tVolume->SetVoxelHeader(0);
827                                                   300 
828   // Scan recursively the associated logical v    301   // Scan recursively the associated logical volume tree
829   //                                              302   //
830   tVolume = pVolume->GetLogicalVolume();          303   tVolume = pVolume->GetLogicalVolume();
831   if (tVolume->GetNoDaughters() != 0)          << 304   if (tVolume->GetNoDaughters()) { DeleteOptimisations(tVolume->GetDaughter(0)); }
832   {                                            << 
833     DeleteOptimisations(tVolume->GetDaughter(0 << 
834   }                                            << 
835 }                                              << 
836                                                << 
837 // ******************************************* << 
838 // Sets the maximum extent of the world volume << 
839 // if NO solids have been created already.     << 
840 // ******************************************* << 
841 //                                             << 
842 void G4GeometryManager::SetWorldMaximumExtent( << 
843 {                                              << 
844   if (!G4SolidStore::GetInstance()->empty())   << 
845   {                                            << 
846      // Sanity check to assure that extent is  << 
847      // any geometry object (solids in this ca << 
848      //                                        << 
849      G4Exception("G4GeometryManager::SetMaximu << 
850                  "GeomMgt0003", FatalException << 
851                  "Extent can be set only BEFOR << 
852   }                                            << 
853   G4GeometryTolerance::GetInstance()->SetSurfa << 
854 }                                                 305 }
855                                                   306 
856 // *******************************************    307 // ***************************************************************************
857 // Reports statistics on voxel optimisation wh    308 // Reports statistics on voxel optimisation when closing geometry.
858 // *******************************************    309 // ***************************************************************************
859 //                                                310 //
860 void                                              311 void
861 G4GeometryManager::ReportVoxelStats( std::vect    312 G4GeometryManager::ReportVoxelStats( std::vector<G4SmartVoxelStat> & stats,
862                                      G4double  << 313                                      G4double totalCpuTime )
863                                      std::ostr << 
864 {                                                 314 {
865   os << "------------------------------------- << 315   G4cout << "G4GeometryManager::ReportVoxelStats -- Voxel Statistics"
866      << G4endl;                                << 
867   os << "G4GeometryManager::ReportVoxelStats - << 
868          << G4endl << G4endl;                     316          << G4endl << G4endl;
869                                                   317  
870   //                                              318   //
871   // Get total memory use                         319   // Get total memory use
872   //                                              320   //
873   G4int i, nStat = (G4int)stats.size();        << 321   G4int i, nStat = stats.size();
874   G4long totalMemory = 0;                         322   G4long totalMemory = 0;
875                                                   323  
876   for( i=0; i<nStat; ++i )  { totalMemory += s << 324   for( i=0;i<nStat;++i )  { totalMemory += stats[i].GetMemoryUse(); }
877                                                   325  
878   os << "    Total memory consumed for geometr << 326   G4cout << "    Total memory consumed for geometry optimisation:   "
879          << totalMemory/1024 << " kByte" << G4    327          << totalMemory/1024 << " kByte" << G4endl;
880   os << "    Total CPU time elapsed for geomet << 328   G4cout << "    Total CPU time elapsed for geometry optimisation: " 
881          << std::setprecision(4) << totalCpuTi << 329          << std::setprecision(2) << totalCpuTime << " seconds" << G4endl;
882          << std::setprecision(6) << G4endl;    << 
883                                                   330  
884   //                                              331   //
885   // First list: sort by total CPU time           332   // First list: sort by total CPU time
886   //                                              333   //
887   std::sort( stats.begin(), stats.end(),       << 334   std::sort( stats.begin(), stats.end(), G4SmartVoxelStat::ByCpu() );
888     [](const G4SmartVoxelStat& a, const G4Smar << 
889   {                                            << 
890     return a.GetTotalTime() > b.GetTotalTime() << 
891   } );                                         << 
892                                                   335          
893   const G4int maxPrint = 20;                   << 336   G4int nPrint = nStat > 10 ? 10 : nStat;
894   G4int nPrint = std::min ( nStat, maxPrint ); << 
895                                                   337 
896   if (nPrint != 0)                             << 338   if (nPrint)
897   {                                               339   {
898     os << "\n    Voxelisation: top CPU users:" << 340     G4cout << "\n    Voxelisation: top CPU users:" << G4endl;
899     os << "    Percent   Total CPU    System C << 341     G4cout << "    Percent   Total CPU    System CPU       Memory  Volume\n"
900        << "    -------   ----------   -------- << 342            << "    -------   ----------   ----------     --------  ----------"
901        << G4endl;                              << 343            << G4endl;
                                                   >> 344     //         12345678901.234567890123.234567890123.234567890123k .
902   }                                               345   }
903                                                   346 
904   for(i=0; i<nPrint; ++i)                      << 347   for(i=0;i<nPrint;++i)
905   {                                               348   {
906     G4double total = stats[i].GetTotalTime();     349     G4double total = stats[i].GetTotalTime();
907     G4double system = stats[i].GetSysTime();      350     G4double system = stats[i].GetSysTime();
908     G4double perc = 0.0;                          351     G4double perc = 0.0;
909                                                   352 
910     if (system < 0) { system = 0.0; }             353     if (system < 0) { system = 0.0; }
911     if ((total < 0) || (totalCpuTime < perMill    354     if ((total < 0) || (totalCpuTime < perMillion))
912       { total = 0; }                              355       { total = 0; }
913     else                                          356     else
914       { perc = total*100/totalCpuTime; }          357       { perc = total*100/totalCpuTime; }
915                                                   358 
916     os << std::setprecision(2)                 << 359     G4cout << std::setprecision(2) 
917            << std::setiosflags(std::ios::fixed    360            << std::setiosflags(std::ios::fixed|std::ios::right)
918            << std::setw(11) << perc               361            << std::setw(11) << perc
919            << std::setw(13) << total              362            << std::setw(13) << total
920            << std::setw(13) << system             363            << std::setw(13) << system
921            << std::setw(13) << (stats[i].GetMe    364            << std::setw(13) << (stats[i].GetMemoryUse()+512)/1024
922            << "k " << std::setiosflags(std::io    365            << "k " << std::setiosflags(std::ios::left)
923            << stats[i].GetVolume()->GetName()     366            << stats[i].GetVolume()->GetName()
924            << std::resetiosflags(std::ios::flo    367            << std::resetiosflags(std::ios::floatfield|std::ios::adjustfield)
925            << std::setprecision(6)                368            << std::setprecision(6)
926            << G4endl;                             369            << G4endl;
927   }                                               370   }
928                                                   371  
929   //                                              372   //
930   // Second list: sort by memory use              373   // Second list: sort by memory use
931   //                                              374   //
932   std::sort( stats.begin(), stats.end(),       << 375   std::sort( stats.begin(), stats.end(), G4SmartVoxelStat::ByMemory() );
933     [](const G4SmartVoxelStat& a, const G4Smar << 
934   {                                            << 
935     return a.GetMemoryUse() > b.GetMemoryUse() << 
936   } );                                         << 
937                                                   376  
938   if (nPrint != 0)                             << 377   if (nPrint)
939   {                                               378   {
940     os << "\n    Voxelisation: top memory user << 379     G4cout << "\n    Voxelisation: top memory users:" << G4endl;
941     os << "    Percent     Memory      Heads   << 380     G4cout << "    Percent     Memory      Heads    Nodes   Pointers    Total CPU    Volume\n"
942        << "    -------   --------     ------   << 381            << "    -------   --------     ------   ------   --------   ----------    ----------"
943        << G4endl;                              << 382            << G4endl;
                                                   >> 383     //         12345678901.2345678901k .23456789.23456789.2345678901.234567890123.   .
944   }                                               384   }
945                                                   385 
946   for(i=0; i<nPrint; ++i)                      << 386   for(i=0;i<nPrint;++i)
947   {                                               387   {
948     G4long memory = stats[i].GetMemoryUse();      388     G4long memory = stats[i].GetMemoryUse();
949     G4double totTime = stats[i].GetTotalTime()    389     G4double totTime = stats[i].GetTotalTime();
950     if (totTime < 0) { totTime = 0.0; }           390     if (totTime < 0) { totTime = 0.0; }
951                                                   391 
952     os << std::setprecision(2)                 << 392     G4cout << std::setprecision(2) 
953        << std::setiosflags(std::ios::fixed|std << 393            << std::setiosflags(std::ios::fixed|std::ios::right)
954        << std::setw(11) << G4double(memory*100 << 394            << std::setw(11) << G4double(memory*100)/G4double(totalMemory)
955        << std::setw(11) << memory/1024 << "k " << 395            << std::setw(11) << memory/1024 << "k "
956        << std::setw( 9) << stats[i].GetNumberH << 396            << std::setw( 9) << stats[i].GetNumberHeads()
957        << std::setw( 9) << stats[i].GetNumberN << 397            << std::setw( 9) << stats[i].GetNumberNodes()
958        << std::setw(11) << stats[i].GetNumberP << 398            << std::setw(11) << stats[i].GetNumberPointers()
959        << std::setw(13) << totTime << "    "   << 399            << std::setw(13) << totTime << "    "
960        << std::setiosflags(std::ios::left)     << 400            << std::setiosflags(std::ios::left)
961        << stats[i].GetVolume()->GetName()      << 401            << stats[i].GetVolume()->GetName()
962        << std::resetiosflags(std::ios::floatfi << 402            << std::resetiosflags(std::ios::floatfield|std::ios::adjustfield)
963        << std::setprecision(6)                 << 403            << std::setprecision(6)
964        << G4endl;                              << 404            << G4endl;
965   }                                               405   }
966   os << "------------------------------------- << 
967      << G4endl << G4endl;                      << 
968 }                                              << 
969                                                << 
970 // ******************************************* << 
971 // Check whether parallel optimisation was req << 
972 // ******************************************* << 
973 //                                             << 
974 G4bool G4GeometryManager::IsParallelOptimisati << 
975 {                                              << 
976   return fOptimiseInParallelConfigured;        << 
977 }                                              << 
978                                                << 
979 // ******************************************* << 
980 // Report whether parallel optimisation is don << 
981 // ******************************************* << 
982 //                                             << 
983 G4bool G4GeometryManager::IsParallelOptimisati << 
984 {                                              << 
985   return fParallelVoxelOptimisationFinished;   << 
986 }                                                 406 }
987                                                   407