Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4GeometryManager.cc
이 파일의 문서화 페이지로 가기
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id: G4GeometryManager.cc 103235 2017-03-22 15:53:48Z gcosmo $
28 //
29 // class G4GeometryManager
30 //
31 // Implementation
32 //
33 // Author:
34 // 26.07.95 P.Kent Initial version, including optimisation Build
35 // --------------------------------------------------------------------
36 
37 #include <iomanip>
38 #include "G4Timer.hh"
39 #include "G4GeometryManager.hh"
40 #include "G4SystemOfUnits.hh"
41 
42 #ifdef G4GEOMETRY_VOXELDEBUG
43 #include "G4ios.hh"
44 #endif
45 
46 // Needed for building optimisations
47 //
48 #include "G4LogicalVolumeStore.hh"
49 #include "G4VPhysicalVolume.hh"
50 #include "G4SmartVoxelHeader.hh"
51 #include "voxeldefs.hh"
52 
53 // Needed for setting the extent for tolerance value
54 //
55 #include "G4GeometryTolerance.hh"
56 #include "G4SolidStore.hh"
57 #include "G4VSolid.hh"
58 
59 // ***************************************************************************
60 // Static class data
61 // ***************************************************************************
62 //
65 
66 // ***************************************************************************
67 // Constructor. Set the geometry to be open
68 // ***************************************************************************
69 //
71 {
72 }
73 
74 // ***************************************************************************
75 // Destructor
76 // ***************************************************************************
77 //
79 {
80  fgInstance = 0;
81  fIsClosed = false;
82 }
83 
84 // ***************************************************************************
85 // Closes geometry - performs sanity checks and optionally builds optimisation
86 // for placed volumes (always built for replicas & parameterised).
87 // NOTE: Currently no sanity checks are performed.
88 // Applies to just a specific subtree if a physical volume is specified.
89 // ***************************************************************************
90 //
92  G4VPhysicalVolume* pVolume)
93 {
94  if (!fIsClosed)
95  {
96  if (pVolume)
97  {
98  BuildOptimisations(pOptimise, pVolume);
99  }
100  else
101  {
102  BuildOptimisations(pOptimise, verbose);
103  }
104  fIsClosed=true;
105  }
106  return true;
107 }
108 
109 // ***************************************************************************
110 // Opens the geometry and removes optimisations (optionally, related to just
111 // the specified logical-volume).
112 // Applies to just a specific subtree if a physical volume is specified.
113 // ***************************************************************************
114 //
116 {
117  if (fIsClosed)
118  {
119  if (pVolume)
120  {
121  DeleteOptimisations(pVolume);
122  }
123  else
124  {
126  }
127  fIsClosed=false;
128  }
129 }
130 
131 // ***************************************************************************
132 // Returns status of geometry
133 // ***************************************************************************
134 //
136 {
137  return fIsClosed;
138 }
139 
140 // ***************************************************************************
141 // Returns the instance of the singleton.
142 // Creates it in case it's called for the first time.
143 // ***************************************************************************
144 //
146 {
147  if (!fgInstance)
148  {
150  }
151  return fgInstance;
152 }
153 
154 // ***************************************************************************
155 // Returns the instance of the singleton.
156 // ***************************************************************************
157 //
159 {
160  return fgInstance;
161 }
162 
163 // ***************************************************************************
164 // Creates optimisation info. Builds all voxels if allOpts=true
165 // otherwise it builds voxels only for replicated volumes.
166 // ***************************************************************************
167 //
169 {
170  G4Timer timer;
171  G4Timer allTimer;
172  std::vector<G4SmartVoxelStat> stats;
173  if (verbose) { allTimer.Start(); }
174 
176  G4LogicalVolume* volume;
177  G4SmartVoxelHeader* head;
178 
179  for (size_t n=0; n<Store->size(); n++)
180  {
181  if (verbose) timer.Start();
182  volume=(*Store)[n];
183  // For safety, check if there are any existing voxels and
184  // delete before replacement
185  //
186  head = volume->GetVoxelHeader();
187  delete head;
188  volume->SetVoxelHeader(0);
189  if ( ( (volume->IsToOptimise())
190  && (volume->GetNoDaughters()>=kMinVoxelVolumesLevel1&&allOpts) )
191  || ( (volume->GetNoDaughters()==1)
192  && (volume->GetDaughter(0)->IsReplicated()==true)
193  && (volume->GetDaughter(0)->GetRegularStructureId()!=1) ) )
194  {
195 #ifdef G4GEOMETRY_VOXELDEBUG
196  G4cout << "**** G4GeometryManager::BuildOptimisations" << G4endl
197  << " Examining logical volume name = "
198  << volume->GetName() << G4endl;
199 #endif
200  head = new G4SmartVoxelHeader(volume);
201  if (head)
202  {
203  volume->SetVoxelHeader(head);
204  }
205  else
206  {
207  std::ostringstream message;
208  message << "VoxelHeader allocation error." << G4endl
209  << "Allocation of new VoxelHeader" << G4endl
210  << " for volume " << volume->GetName() << " failed.";
211  G4Exception("G4GeometryManager::BuildOptimisations()", "GeomMgt0003",
212  FatalException, message);
213  }
214  if (verbose)
215  {
216  timer.Stop();
217  stats.push_back( G4SmartVoxelStat( volume, head,
218  timer.GetSystemElapsed(),
219  timer.GetUserElapsed() ) );
220  }
221  }
222  else
223  {
224  // Don't create voxels for this node
225 #ifdef G4GEOMETRY_VOXELDEBUG
226  G4cout << "**** G4GeometryManager::BuildOptimisations" << G4endl
227  << " Skipping logical volume name = " << volume->GetName()
228  << G4endl;
229 #endif
230  }
231  }
232  if (verbose)
233  {
234  allTimer.Stop();
235  ReportVoxelStats( stats, allTimer.GetSystemElapsed()
236  + allTimer.GetUserElapsed() );
237  }
238 }
239 
240 // ***************************************************************************
241 // Creates optimisation info for the specified volumes subtree.
242 // ***************************************************************************
243 //
245  G4VPhysicalVolume* pVolume)
246 {
247  if (!pVolume) { return; }
248 
249  // Retrieve the mother logical volume, if not NULL,
250  // otherwise apply global optimisation for the world volume
251  //
252  G4LogicalVolume* tVolume = pVolume->GetMotherLogical();
253  if (!tVolume) { return BuildOptimisations(allOpts, false); }
254 
255  G4SmartVoxelHeader* head = tVolume->GetVoxelHeader();
256  delete head;
257  tVolume->SetVoxelHeader(0);
258  if ( ( (tVolume->IsToOptimise())
259  && (tVolume->GetNoDaughters()>=kMinVoxelVolumesLevel1&&allOpts) )
260  || ( (tVolume->GetNoDaughters()==1)
261  && (tVolume->GetDaughter(0)->IsReplicated()==true) ) )
262  {
263  head = new G4SmartVoxelHeader(tVolume);
264  if (head)
265  {
266  tVolume->SetVoxelHeader(head);
267  }
268  else
269  {
270  std::ostringstream message;
271  message << "VoxelHeader allocation error." << G4endl
272  << "Allocation of new VoxelHeader" << G4endl
273  << " for volume " << tVolume->GetName() << " failed.";
274  G4Exception("G4GeometryManager::BuildOptimisations()", "GeomMgt0003",
275  FatalException, message);
276  }
277  }
278  else
279  {
280  // Don't create voxels for this node
281 #ifdef G4GEOMETRY_VOXELDEBUG
282  G4cout << "**** G4GeometryManager::BuildOptimisations" << G4endl
283  << " Skipping logical volume name = " << tVolume->GetName()
284  << G4endl;
285 #endif
286  }
287 
288  // Scan recursively the associated logical volume tree
289  //
290  tVolume = pVolume->GetLogicalVolume();
291  if (tVolume->GetNoDaughters())
292  {
293  BuildOptimisations(allOpts, tVolume->GetDaughter(0));
294  }
295 }
296 
297 // ***************************************************************************
298 // Removes all optimisation info.
299 // Loops over all logical volumes, deleting non-null voxels pointers,
300 // ***************************************************************************
301 //
303 {
304  G4LogicalVolume* tVolume = 0;
306  for (size_t n=0; n<Store->size(); n++)
307  {
308  tVolume=(*Store)[n];
309  delete tVolume->GetVoxelHeader();
310  tVolume->SetVoxelHeader(0);
311  }
312 }
313 
314 // ***************************************************************************
315 // Removes optimisation info for the specified subtree.
316 // Scans recursively all daughter volumes, deleting non-null voxels pointers.
317 // ***************************************************************************
318 //
320 {
321  if (!pVolume) { return; }
322 
323  // Retrieve the mother logical volume, if not NULL,
324  // otherwise global deletion to world volume.
325  //
326  G4LogicalVolume* tVolume = pVolume->GetMotherLogical();
327  if (!tVolume) { return DeleteOptimisations(); }
328  delete tVolume->GetVoxelHeader();
329  tVolume->SetVoxelHeader(0);
330 
331  // Scan recursively the associated logical volume tree
332  //
333  tVolume = pVolume->GetLogicalVolume();
334  if (tVolume->GetNoDaughters())
335  {
336  DeleteOptimisations(tVolume->GetDaughter(0));
337  }
338 }
339 
340 // ***************************************************************************
341 // Sets the maximum extent of the world volume. The operation is allowed only
342 // if NO solids have been created already.
343 // ***************************************************************************
344 //
346 {
347  if (G4SolidStore::GetInstance()->size())
348  {
349  // Sanity check to assure that extent is fixed BEFORE creating
350  // any geometry object (solids in this case)
351  //
352  G4Exception("G4GeometryManager::SetMaximumExtent()",
353  "GeomMgt0003", FatalException,
354  "Extent can be set only BEFORE creating any geometry object!");
355  }
357 }
358 
359 // ***************************************************************************
360 // Reports statistics on voxel optimisation when closing geometry.
361 // ***************************************************************************
362 //
363 void
364 G4GeometryManager::ReportVoxelStats( std::vector<G4SmartVoxelStat> & stats,
365  G4double totalCpuTime )
366 {
367  G4cout << "G4GeometryManager::ReportVoxelStats -- Voxel Statistics"
368  << G4endl << G4endl;
369 
370  //
371  // Get total memory use
372  //
373  G4int i, nStat = stats.size();
374  G4long totalMemory = 0;
375 
376  for( i=0;i<nStat;++i ) { totalMemory += stats[i].GetMemoryUse(); }
377 
378  G4cout << " Total memory consumed for geometry optimisation: "
379  << totalMemory/1024 << " kByte" << G4endl;
380  G4cout << " Total CPU time elapsed for geometry optimisation: "
381  << std::setprecision(2) << totalCpuTime << " seconds"
382  << std::setprecision(6) << G4endl;
383 
384  //
385  // First list: sort by total CPU time
386  //
387  std::sort( stats.begin(), stats.end(), G4SmartVoxelStat::ByCpu() );
388 
389  G4int nPrint = nStat > 10 ? 10 : nStat;
390 
391  if (nPrint)
392  {
393  G4cout << "\n Voxelisation: top CPU users:" << G4endl;
394  G4cout << " Percent Total CPU System CPU Memory Volume\n"
395  << " ------- ---------- ---------- -------- ----------"
396  << G4endl;
397  // 12345678901.234567890123.234567890123.234567890123k .
398  }
399 
400  for(i=0;i<nPrint;++i)
401  {
402  G4double total = stats[i].GetTotalTime();
403  G4double system = stats[i].GetSysTime();
404  G4double perc = 0.0;
405 
406  if (system < 0) { system = 0.0; }
407  if ((total < 0) || (totalCpuTime < perMillion))
408  { total = 0; }
409  else
410  { perc = total*100/totalCpuTime; }
411 
412  G4cout << std::setprecision(2)
413  << std::setiosflags(std::ios::fixed|std::ios::right)
414  << std::setw(11) << perc
415  << std::setw(13) << total
416  << std::setw(13) << system
417  << std::setw(13) << (stats[i].GetMemoryUse()+512)/1024
418  << "k " << std::setiosflags(std::ios::left)
419  << stats[i].GetVolume()->GetName()
420  << std::resetiosflags(std::ios::floatfield|std::ios::adjustfield)
421  << std::setprecision(6)
422  << G4endl;
423  }
424 
425  //
426  // Second list: sort by memory use
427  //
428  std::sort( stats.begin(), stats.end(), G4SmartVoxelStat::ByMemory() );
429 
430  if (nPrint)
431  {
432  G4cout << "\n Voxelisation: top memory users:" << G4endl;
433  G4cout << " Percent Memory Heads Nodes Pointers Total CPU Volume\n"
434  << " ------- -------- ------ ------ -------- ---------- ----------"
435  << G4endl;
436  // 12345678901.2345678901k .23456789.23456789.2345678901.234567890123. .
437  }
438 
439  for(i=0;i<nPrint;++i)
440  {
441  G4long memory = stats[i].GetMemoryUse();
442  G4double totTime = stats[i].GetTotalTime();
443  if (totTime < 0) { totTime = 0.0; }
444 
445  G4cout << std::setprecision(2)
446  << std::setiosflags(std::ios::fixed|std::ios::right)
447  << std::setw(11) << G4double(memory*100)/G4double(totalMemory)
448  << std::setw(11) << memory/1024 << "k "
449  << std::setw( 9) << stats[i].GetNumberHeads()
450  << std::setw( 9) << stats[i].GetNumberNodes()
451  << std::setw(11) << stats[i].GetNumberPointers()
452  << std::setw(13) << totTime << " "
453  << std::setiosflags(std::ios::left)
454  << stats[i].GetVolume()->GetName()
455  << std::resetiosflags(std::ios::floatfield|std::ios::adjustfield)
456  << std::setprecision(6)
457  << G4endl;
458  }
459 }
void SetSurfaceTolerance(G4double worldExtent)
static G4GeometryManager * GetInstanceIfExist()
G4double total(Particle const *const p1, Particle const *const p2)
system("rm -rf microbeam.root")
G4LogicalVolume * GetLogicalVolume() const
void Start()
#define G4endl
Definition: G4ios.hh:61
G4SmartVoxelHeader * GetVoxelHeader() const
void message(RunManager *runmanager)
Definition: ts_scorers.cc:72
G4int GetNoDaughters() const
static constexpr double perMillion
Definition: G4SIunits.hh:334
#define G4ThreadLocal
Definition: tls.hh:69
void SetVoxelHeader(G4SmartVoxelHeader *pVoxel)
double G4double
Definition: G4Types.hh:76
bool G4bool
Definition: G4Types.hh:79
G4LogicalVolume * GetMotherLogical() const
virtual G4int GetRegularStructureId() const =0
G4double GetSystemElapsed() const
Definition: G4Timer.cc:134
long G4long
Definition: G4Types.hh:80
static G4GeometryManager * GetInstance()
void Stop()
G4double GetUserElapsed() const
Definition: G4Timer.cc:145
G4bool IsToOptimise() const
static G4ThreadLocal G4GeometryManager * fgInstance
void OpenGeometry(G4VPhysicalVolume *vol=0)
void SetWorldMaximumExtent(G4double worldExtent)
static G4ThreadLocal G4bool fIsClosed
static void ReportVoxelStats(std::vector< G4SmartVoxelStat > &stats, G4double totalCpuTime)
static G4SolidStore * GetInstance()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.hh:65
static G4bool IsGeometryClosed()
void BuildOptimisations(G4bool allOpt, G4bool verbose=false)
int G4int
Definition: G4Types.hh:78
G4bool CloseGeometry(G4bool pOptimise=true, G4bool verbose=false, G4VPhysicalVolume *vol=0)
const G4int kMinVoxelVolumesLevel1
Definition: voxeldefs.hh:45
G4GLOB_DLL std::ostream G4cout
virtual G4bool IsReplicated() const =0
static G4GeometryTolerance * GetInstance()
Char_t n[5]
static G4LogicalVolumeStore * GetInstance()
G4VPhysicalVolume * GetDaughter(const G4int i) const
const G4String & GetName() const