00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <iomanip>
00038 #include "G4Timer.hh"
00039 #include "G4GeometryManager.hh"
00040 #include "G4SystemOfUnits.hh"
00041
00042 #ifdef G4GEOMETRY_VOXELDEBUG
00043 #include "G4ios.hh"
00044 #endif
00045
00046
00047
00048 #include "G4LogicalVolumeStore.hh"
00049 #include "G4VPhysicalVolume.hh"
00050 #include "G4SmartVoxelHeader.hh"
00051 #include "voxeldefs.hh"
00052
00053
00054
00055 #include "G4GeometryTolerance.hh"
00056 #include "G4SolidStore.hh"
00057 #include "G4VSolid.hh"
00058
00059
00060
00061
00062
00063 G4GeometryManager* G4GeometryManager::fgInstance = 0;
00064
00065
00066
00067
00068
00069 G4GeometryManager::G4GeometryManager()
00070 : fIsClosed(false)
00071 {
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081 G4bool G4GeometryManager::CloseGeometry(G4bool pOptimise, G4bool verbose,
00082 G4VPhysicalVolume* pVolume)
00083 {
00084 if (!fIsClosed)
00085 {
00086 if (pVolume)
00087 {
00088 BuildOptimisations(pOptimise, pVolume);
00089 }
00090 else
00091 {
00092 BuildOptimisations(pOptimise, verbose);
00093 }
00094 fIsClosed=true;
00095 }
00096 return true;
00097 }
00098
00099
00100
00101
00102
00103
00104
00105 void G4GeometryManager::OpenGeometry(G4VPhysicalVolume* pVolume)
00106 {
00107 if (fIsClosed)
00108 {
00109 if (pVolume)
00110 {
00111 DeleteOptimisations(pVolume);
00112 }
00113 else
00114 {
00115 DeleteOptimisations();
00116 }
00117 fIsClosed=false;
00118 }
00119 }
00120
00121
00122
00123
00124
00125 G4bool G4GeometryManager::IsGeometryClosed()
00126 {
00127 return fIsClosed;
00128 }
00129
00130
00131
00132
00133
00134
00135 G4GeometryManager* G4GeometryManager::GetInstance()
00136 {
00137 static G4GeometryManager worldManager;
00138 if (!fgInstance)
00139 {
00140 fgInstance = &worldManager;
00141 }
00142 return fgInstance;
00143 }
00144
00145
00146
00147
00148
00149
00150 void G4GeometryManager::BuildOptimisations(G4bool allOpts, G4bool verbose)
00151 {
00152 G4Timer timer;
00153 G4Timer allTimer;
00154 std::vector<G4SmartVoxelStat> stats;
00155 if (verbose) { allTimer.Start(); }
00156
00157 G4LogicalVolumeStore* Store = G4LogicalVolumeStore::GetInstance();
00158 G4LogicalVolume* volume;
00159 G4SmartVoxelHeader* head;
00160
00161 for (size_t n=0; n<Store->size(); n++)
00162 {
00163 if (verbose) timer.Start();
00164 volume=(*Store)[n];
00165
00166
00167
00168 head = volume->GetVoxelHeader();
00169 delete head;
00170 volume->SetVoxelHeader(0);
00171 if ( ( (volume->IsToOptimise())
00172 && (volume->GetNoDaughters()>=kMinVoxelVolumesLevel1&&allOpts) )
00173 || ( (volume->GetNoDaughters()==1)
00174 && (volume->GetDaughter(0)->IsReplicated()==true)
00175 && (volume->GetDaughter(0)->GetRegularStructureId()!=1) ) )
00176 {
00177 #ifdef G4GEOMETRY_VOXELDEBUG
00178 G4cout << "**** G4GeometryManager::BuildOptimisations" << G4endl
00179 << " Examining logical volume name = "
00180 << volume->GetName() << G4endl;
00181 #endif
00182 head = new G4SmartVoxelHeader(volume);
00183 if (head)
00184 {
00185 volume->SetVoxelHeader(head);
00186 }
00187 else
00188 {
00189 std::ostringstream message;
00190 message << "VoxelHeader allocation error." << G4endl
00191 << "Allocation of new VoxelHeader" << G4endl
00192 << " for volume " << volume->GetName() << " failed.";
00193 G4Exception("G4GeometryManager::BuildOptimisations()", "GeomMgt0003",
00194 FatalException, message);
00195 }
00196 if (verbose)
00197 {
00198 timer.Stop();
00199 stats.push_back( G4SmartVoxelStat( volume, head,
00200 timer.GetSystemElapsed(),
00201 timer.GetUserElapsed() ) );
00202 }
00203 }
00204 else
00205 {
00206
00207 #ifdef G4GEOMETRY_VOXELDEBUG
00208 G4cout << "**** G4GeometryManager::BuildOptimisations" << G4endl
00209 << " Skipping logical volume name = " << volume->GetName()
00210 << G4endl;
00211 #endif
00212 }
00213 }
00214 if (verbose)
00215 {
00216 allTimer.Stop();
00217 ReportVoxelStats( stats, allTimer.GetSystemElapsed()
00218 + allTimer.GetUserElapsed() );
00219 }
00220 }
00221
00222
00223
00224
00225
00226 void G4GeometryManager::BuildOptimisations(G4bool allOpts,
00227 G4VPhysicalVolume* pVolume)
00228 {
00229 if (!pVolume) { return; }
00230
00231
00232
00233
00234 G4LogicalVolume* tVolume = pVolume->GetMotherLogical();
00235 if (!tVolume) { return BuildOptimisations(allOpts, false); }
00236
00237 G4SmartVoxelHeader* head = tVolume->GetVoxelHeader();
00238 delete head;
00239 tVolume->SetVoxelHeader(0);
00240 if ( ( (tVolume->IsToOptimise())
00241 && (tVolume->GetNoDaughters()>=kMinVoxelVolumesLevel1&&allOpts) )
00242 || ( (tVolume->GetNoDaughters()==1)
00243 && (tVolume->GetDaughter(0)->IsReplicated()==true) ) )
00244 {
00245 head = new G4SmartVoxelHeader(tVolume);
00246 if (head)
00247 {
00248 tVolume->SetVoxelHeader(head);
00249 }
00250 else
00251 {
00252 std::ostringstream message;
00253 message << "VoxelHeader allocation error." << G4endl
00254 << "Allocation of new VoxelHeader" << G4endl
00255 << " for volume " << tVolume->GetName() << " failed.";
00256 G4Exception("G4GeometryManager::BuildOptimisations()", "GeomMgt0003",
00257 FatalException, message);
00258 }
00259 }
00260 else
00261 {
00262
00263 #ifdef G4GEOMETRY_VOXELDEBUG
00264 G4cout << "**** G4GeometryManager::BuildOptimisations" << G4endl
00265 << " Skipping logical volume name = " << tVolume->GetName()
00266 << G4endl;
00267 #endif
00268 }
00269
00270
00271
00272 tVolume = pVolume->GetLogicalVolume();
00273 if (tVolume->GetNoDaughters())
00274 {
00275 BuildOptimisations(allOpts, tVolume->GetDaughter(0));
00276 }
00277 }
00278
00279
00280
00281
00282
00283
00284 void G4GeometryManager::DeleteOptimisations()
00285 {
00286 G4LogicalVolume* tVolume = 0;
00287 G4LogicalVolumeStore* Store = G4LogicalVolumeStore::GetInstance();
00288 for (size_t n=0; n<Store->size(); n++)
00289 {
00290 tVolume=(*Store)[n];
00291 delete tVolume->GetVoxelHeader();
00292 tVolume->SetVoxelHeader(0);
00293 }
00294 }
00295
00296
00297
00298
00299
00300
00301 void G4GeometryManager::DeleteOptimisations(G4VPhysicalVolume* pVolume)
00302 {
00303 if (!pVolume) { return; }
00304
00305
00306
00307
00308 G4LogicalVolume* tVolume = pVolume->GetMotherLogical();
00309 if (!tVolume) { return DeleteOptimisations(); }
00310 delete tVolume->GetVoxelHeader();
00311 tVolume->SetVoxelHeader(0);
00312
00313
00314
00315 tVolume = pVolume->GetLogicalVolume();
00316 if (tVolume->GetNoDaughters())
00317 {
00318 DeleteOptimisations(tVolume->GetDaughter(0));
00319 }
00320 }
00321
00322
00323
00324
00325
00326
00327 void G4GeometryManager::SetWorldMaximumExtent(G4double extent)
00328 {
00329 if (G4SolidStore::GetInstance()->size())
00330 {
00331
00332
00333
00334 G4Exception("G4GeometryManager::SetMaximumExtent()",
00335 "GeomMgt0003", FatalException,
00336 "Extent can be set only BEFORE creating any geometry object!");
00337 }
00338 G4GeometryTolerance::GetInstance()->SetSurfaceTolerance(extent);
00339 }
00340
00341
00342
00343
00344
00345 void
00346 G4GeometryManager::ReportVoxelStats( std::vector<G4SmartVoxelStat> & stats,
00347 G4double totalCpuTime )
00348 {
00349 G4cout << "G4GeometryManager::ReportVoxelStats -- Voxel Statistics"
00350 << G4endl << G4endl;
00351
00352
00353
00354
00355 G4int i, nStat = stats.size();
00356 G4long totalMemory = 0;
00357
00358 for( i=0;i<nStat;++i ) { totalMemory += stats[i].GetMemoryUse(); }
00359
00360 G4cout << " Total memory consumed for geometry optimisation: "
00361 << totalMemory/1024 << " kByte" << G4endl;
00362 G4cout << " Total CPU time elapsed for geometry optimisation: "
00363 << std::setprecision(2) << totalCpuTime << " seconds"
00364 << std::setprecision(6) << G4endl;
00365
00366
00367
00368
00369 std::sort( stats.begin(), stats.end(), G4SmartVoxelStat::ByCpu() );
00370
00371 G4int nPrint = nStat > 10 ? 10 : nStat;
00372
00373 if (nPrint)
00374 {
00375 G4cout << "\n Voxelisation: top CPU users:" << G4endl;
00376 G4cout << " Percent Total CPU System CPU Memory Volume\n"
00377 << " ------- ---------- ---------- -------- ----------"
00378 << G4endl;
00379
00380 }
00381
00382 for(i=0;i<nPrint;++i)
00383 {
00384 G4double total = stats[i].GetTotalTime();
00385 G4double system = stats[i].GetSysTime();
00386 G4double perc = 0.0;
00387
00388 if (system < 0) { system = 0.0; }
00389 if ((total < 0) || (totalCpuTime < perMillion))
00390 { total = 0; }
00391 else
00392 { perc = total*100/totalCpuTime; }
00393
00394 G4cout << std::setprecision(2)
00395 << std::setiosflags(std::ios::fixed|std::ios::right)
00396 << std::setw(11) << perc
00397 << std::setw(13) << total
00398 << std::setw(13) << system
00399 << std::setw(13) << (stats[i].GetMemoryUse()+512)/1024
00400 << "k " << std::setiosflags(std::ios::left)
00401 << stats[i].GetVolume()->GetName()
00402 << std::resetiosflags(std::ios::floatfield|std::ios::adjustfield)
00403 << std::setprecision(6)
00404 << G4endl;
00405 }
00406
00407
00408
00409
00410 std::sort( stats.begin(), stats.end(), G4SmartVoxelStat::ByMemory() );
00411
00412 if (nPrint)
00413 {
00414 G4cout << "\n Voxelisation: top memory users:" << G4endl;
00415 G4cout << " Percent Memory Heads Nodes Pointers Total CPU Volume\n"
00416 << " ------- -------- ------ ------ -------- ---------- ----------"
00417 << G4endl;
00418
00419 }
00420
00421 for(i=0;i<nPrint;++i)
00422 {
00423 G4long memory = stats[i].GetMemoryUse();
00424 G4double totTime = stats[i].GetTotalTime();
00425 if (totTime < 0) { totTime = 0.0; }
00426
00427 G4cout << std::setprecision(2)
00428 << std::setiosflags(std::ios::fixed|std::ios::right)
00429 << std::setw(11) << G4double(memory*100)/G4double(totalMemory)
00430 << std::setw(11) << memory/1024 << "k "
00431 << std::setw( 9) << stats[i].GetNumberHeads()
00432 << std::setw( 9) << stats[i].GetNumberNodes()
00433 << std::setw(11) << stats[i].GetNumberPointers()
00434 << std::setw(13) << totTime << " "
00435 << std::setiosflags(std::ios::left)
00436 << stats[i].GetVolume()->GetName()
00437 << std::resetiosflags(std::ios::floatfield|std::ios::adjustfield)
00438 << std::setprecision(6)
00439 << G4endl;
00440 }
00441 }