00001 // 00002 // ******************************************************************** 00003 // * License and Disclaimer * 00004 // * * 00005 // * The Geant4 software is copyright of the Copyright Holders of * 00006 // * the Geant4 Collaboration. It is provided under the terms and * 00007 // * conditions of the Geant4 Software License, included in the file * 00008 // * LICENSE and available at http://cern.ch/geant4/license . These * 00009 // * include a list of copyright holders. * 00010 // * * 00011 // * Neither the authors of this software system, nor their employing * 00012 // * institutes,nor the agencies providing financial support for this * 00013 // * work make any representation or warranty, express or implied, * 00014 // * regarding this software system or assume any liability for its * 00015 // * use. Please see the license in the file LICENSE and URL above * 00016 // * for the full disclaimer and the limitation of liability. * 00017 // * * 00018 // * This code implementation is the result of the scientific and * 00019 // * technical work of the GEANT4 collaboration. * 00020 // * By using, copying, modifying or distributing the software (or * 00021 // * any work based on the software) you agree to acknowledge its * 00022 // * use in resulting scientific publications, and indicate your * 00023 // * acceptance of all terms of the Geant4 Software license. * 00024 // ******************************************************************** 00025 // 00026 // 00027 // $Id$ 00028 // 00029 // G4RegionStore 00030 // 00031 // Implementation for singleton container 00032 // 00033 // History: 00034 // 18.09.02 G.Cosmo Initial version 00035 // -------------------------------------------------------------------- 00036 00037 #include "G4Region.hh" 00038 #include "G4RegionStore.hh" 00039 #include "G4GeometryManager.hh" 00040 #include "G4VPhysicalVolume.hh" 00041 #include "G4PhysicalVolumeStore.hh" 00042 00043 #include "G4ios.hh" 00044 00045 // *************************************************************************** 00046 // Static class variables 00047 // *************************************************************************** 00048 // 00049 G4RegionStore* G4RegionStore::fgInstance = 0; 00050 G4VStoreNotifier* G4RegionStore::fgNotifier = 0; 00051 G4bool G4RegionStore::locked = false; 00052 00053 // *************************************************************************** 00054 // Protected constructor: Construct underlying container with 00055 // initial size of 20 entries 00056 // *************************************************************************** 00057 // 00058 G4RegionStore::G4RegionStore() 00059 : std::vector<G4Region*>() 00060 { 00061 reserve(20); 00062 } 00063 00064 // *************************************************************************** 00065 // Destructor 00066 // *************************************************************************** 00067 // 00068 G4RegionStore::~G4RegionStore() 00069 { 00070 Clean(); 00071 } 00072 00073 // *************************************************************************** 00074 // Delete all regions from the store except for the world region 00075 // *************************************************************************** 00076 // 00077 void G4RegionStore::Clean() 00078 { 00079 // Do nothing if geometry is closed 00080 // 00081 if (G4GeometryManager::GetInstance()->IsGeometryClosed()) 00082 { 00083 G4cout << "WARNING - Attempt to delete the region store" 00084 << " while geometry closed !" << G4endl; 00085 return; 00086 } 00087 00088 // Locks store for deletion of regions. De-registration will be 00089 // performed at this stage. G4Regions will not de-register themselves. 00090 // 00091 locked = true; 00092 00093 size_t i=0; 00094 G4RegionStore* store = GetInstance(); 00095 00096 #ifdef G4GEOMETRY_VOXELDEBUG 00097 G4cout << "Deleting Regions ... "; 00098 #endif 00099 00100 for(iterator pos=store->begin(); pos!=store->end(); ++pos) 00101 { 00102 if (fgNotifier) { fgNotifier->NotifyDeRegistration(); } 00103 if (*pos) { delete *pos; } 00104 i++; 00105 } 00106 00107 #ifdef G4GEOMETRY_VOXELDEBUG 00108 if (store->size() < i-1) 00109 { G4cout << "No regions deleted. Already deleted by user ?" << G4endl; } 00110 else 00111 { G4cout << i-1 << " regions deleted !" << G4endl; } 00112 #endif 00113 00114 locked = false; 00115 store->clear(); 00116 } 00117 00118 // *************************************************************************** 00119 // Associate user notifier to the store 00120 // *************************************************************************** 00121 // 00122 void G4RegionStore::SetNotifier(G4VStoreNotifier* pNotifier) 00123 { 00124 GetInstance(); 00125 fgNotifier = pNotifier; 00126 } 00127 00128 // *************************************************************************** 00129 // Add Region to container 00130 // *************************************************************************** 00131 // 00132 void G4RegionStore::Register(G4Region* pRegion) 00133 { 00134 GetInstance()->push_back(pRegion); 00135 if (fgNotifier) { fgNotifier->NotifyRegistration(); } 00136 } 00137 00138 // *************************************************************************** 00139 // Remove Region from container 00140 // *************************************************************************** 00141 // 00142 void G4RegionStore::DeRegister(G4Region* pRegion) 00143 { 00144 if (!locked) // Do not de-register if locked ! 00145 { 00146 if (fgNotifier) { fgNotifier->NotifyDeRegistration(); } 00147 for (iterator i=GetInstance()->begin(); i!=GetInstance()->end(); i++) 00148 { 00149 if (**i==*pRegion) 00150 { 00151 GetInstance()->erase(i); 00152 break; 00153 } 00154 } 00155 } 00156 } 00157 00158 // *************************************************************************** 00159 // Return ptr to Store, setting if necessary 00160 // *************************************************************************** 00161 // 00162 G4RegionStore* G4RegionStore::GetInstance() 00163 { 00164 static G4RegionStore worldStore; 00165 if (!fgInstance) 00166 { 00167 fgInstance = &worldStore; 00168 } 00169 return fgInstance; 00170 } 00171 00172 // *************************************************************************** 00173 // Loops through all regions to verify if a region has been modified. 00174 // It returns TRUE if just one region is modified. 00175 // *************************************************************************** 00176 // 00177 G4bool G4RegionStore::IsModified() const 00178 { 00179 for (iterator i=GetInstance()->begin(); i!=GetInstance()->end(); i++) 00180 { 00181 if ((*i)->IsModified()) { return true; } 00182 } 00183 return false; 00184 } 00185 00186 // *************************************************************************** 00187 // Loops through all regions to reset flag for modification to FALSE. 00188 // Used by the run manager to notify that the physics table has been updated. 00189 // *************************************************************************** 00190 // 00191 void G4RegionStore::ResetRegionModified() 00192 { 00193 for (iterator i=GetInstance()->begin(); i!=GetInstance()->end(); i++) 00194 { 00195 (*i)->RegionModified(false); 00196 } 00197 } 00198 00199 // *************************************************************************** 00200 // Forces recomputation of material lists in all regions in the store. 00201 // *************************************************************************** 00202 // 00203 void G4RegionStore::UpdateMaterialList(G4VPhysicalVolume* currentWorld) 00204 { 00205 for (iterator i=GetInstance()->begin(); i!=GetInstance()->end(); i++) 00206 { 00207 if((*i)->IsInMassGeometry() || (*i)->IsInParallelGeometry() || currentWorld) 00208 { (*i)->UpdateMaterialList(); } 00209 } 00210 } 00211 00212 // *************************************************************************** 00213 // Returns a region through its name specification. 00214 // *************************************************************************** 00215 // 00216 G4Region* G4RegionStore::GetRegion(const G4String& name, G4bool verbose) const 00217 { 00218 for (iterator i=GetInstance()->begin(); i!=GetInstance()->end(); i++) 00219 { 00220 if ((*i)->GetName() == name) { return *i; } 00221 } 00222 if (verbose) 00223 { 00224 std::ostringstream message; 00225 message << "Region NOT found in store !" << G4endl 00226 << " Region " << name << " NOT found in store !" << G4endl 00227 << " Returning NULL pointer."; 00228 G4Exception("G4RegionStore::GetRegion()", 00229 "GeomMgt1001", JustWarning, message); 00230 } 00231 return 0; 00232 } 00233 00234 // *************************************************************************** 00235 // Returns a region through its name specification, if it exists. 00236 // If it does not exist it will allocate a new region with the given 00237 // name, delegating the ownership to the caller client. 00238 // *************************************************************************** 00239 // 00240 G4Region* G4RegionStore::FindOrCreateRegion(const G4String& name) 00241 { 00242 G4Region* target = GetRegion(name,false); 00243 if (!target) 00244 { 00245 target = new G4Region(name); 00246 } 00247 return target; 00248 } 00249 00250 // ************************************************************************** 00251 // Set a world physical volume pointer to a region that belongs to it. 00252 // Scan over all world volumes. 00253 // ************************************************************************** 00254 // 00255 void G4RegionStore::SetWorldVolume() 00256 { 00257 // Reset all pointers first 00258 // 00259 for (iterator i=GetInstance()->begin(); i!=GetInstance()->end(); i++) 00260 { (*i)->SetWorld(0); } 00261 00262 // Find world volumes 00263 // 00264 G4PhysicalVolumeStore* fPhysicalVolumeStore 00265 = G4PhysicalVolumeStore::GetInstance(); 00266 size_t nPhys = fPhysicalVolumeStore->size(); 00267 for(size_t iPhys=0; iPhys<nPhys; iPhys++) 00268 { 00269 G4VPhysicalVolume* fPhys = (*fPhysicalVolumeStore)[iPhys]; 00270 if(fPhys->GetMotherLogical()) { continue; } // not a world volume 00271 00272 // Now 'fPhys' is a world volume, set it to regions that belong to it. 00273 // 00274 for (iterator i=GetInstance()->begin(); i!=GetInstance()->end(); i++) 00275 { (*i)->SetWorld(fPhys); } 00276 } 00277 } 00278