Geant4 Cross Reference |
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 /// \file materials/src/G4LatticeManager.cc 27 /// \brief Implementation of the G4LatticeManager class 28 // 29 // 30 // 20131113 Delete lattices in (new) registry, not in lookup maps 31 // 20141008 Change to global singleton; must be shared across worker threads 32 33 #include "G4LatticeManager.hh" 34 #include "G4AutoLock.hh" 35 #include "G4LatticeLogical.hh" 36 #include "G4LatticePhysical.hh" 37 #include "G4LatticeReader.hh" 38 #include "G4LogicalVolume.hh" 39 #include "G4Material.hh" 40 #include "G4VPhysicalVolume.hh" 41 #include "G4SystemOfUnits.hh" 42 #include "G4Threading.hh" 43 #include <fstream> 44 45 G4LatticeManager* G4LatticeManager::fLM = 0; // Global (shared) singleton 46 47 namespace { 48 G4Mutex latMutex = G4MUTEX_INITIALIZER; // For thread protection 49 } 50 51 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 52 53 G4LatticeManager::G4LatticeManager() : verboseLevel(0) { 54 Clear(); 55 } 56 57 G4LatticeManager::~G4LatticeManager() { 58 Reset(); // Deletes all lattices 59 } 60 61 // Delete all registered lattices and clear entries from lookup tables 62 63 void G4LatticeManager::Reset() { 64 for (LatticeLogReg::iterator lm=fLLattices.begin(); 65 lm != fLLattices.end(); ++lm) { 66 delete (*lm); 67 } 68 69 for (LatticePhyReg::iterator pm=fPLattices.begin(); 70 pm != fPLattices.end(); ++pm) { 71 delete (*pm); 72 } 73 74 Clear(); 75 } 76 77 // Remove entries without deletion (for begin-job and end-job initializing) 78 79 void G4LatticeManager::Clear() { 80 fPLatticeList.clear(); 81 fPLattices.clear(); 82 83 fLLatticeList.clear(); 84 fLLattices.clear(); 85 } 86 87 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 88 89 G4LatticeManager* G4LatticeManager::GetLatticeManager() { 90 // if no lattice manager exists, create one. 91 G4AutoLock latLock(&latMutex); // Protect before changing pointer 92 if (!fLM) fLM = new G4LatticeManager(); 93 latLock.unlock(); 94 95 return fLM; 96 } 97 98 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 99 100 // Associate logical lattice with material 101 102 G4bool G4LatticeManager::RegisterLattice(G4Material* Mat, 103 G4LatticeLogical* Lat) { 104 if (!Mat || !Lat) return false; // Don't register null pointers 105 106 G4AutoLock latLock(&latMutex); // Protect before changing registry 107 fLLattices.insert(Lat); // Take ownership in registry 108 fLLatticeList[Mat] = Lat; 109 latLock.unlock(); 110 111 if (verboseLevel) { 112 G4cout << "G4LatticeManager::RegisterLattice: " 113 << " Total number of logical lattices: " << fLLatticeList.size() 114 << " (" << fLLattices.size() << " unique)" << G4endl; 115 } 116 117 return true; 118 } 119 120 // Construct logical lattice for material from config file 121 122 G4LatticeLogical* G4LatticeManager::LoadLattice(G4Material* Mat, 123 const G4String& latDir) { 124 if (verboseLevel) { 125 G4cout << "G4LatticeManager::LoadLattice material " << Mat->GetName() 126 << " " << latDir << G4endl; 127 } 128 129 G4LatticeReader latReader(verboseLevel); 130 G4LatticeLogical* newLat = latReader.MakeLattice(latDir+"/config.txt"); 131 if (verboseLevel>1) G4cout << " Created newLat " << newLat << G4endl; 132 133 if (newLat) RegisterLattice(Mat, newLat); 134 else { 135 G4cerr << "ERROR creating " << latDir << " lattice for material " 136 << Mat->GetName() << G4endl; 137 } 138 139 return newLat; 140 } 141 142 // Combine loading and registration (Material extracted from volume) 143 144 G4LatticePhysical* G4LatticeManager::LoadLattice(G4VPhysicalVolume* Vol, 145 const G4String& latDir) { 146 if (verboseLevel) { 147 G4cout << "G4LatticeManager::LoadLattice volume " << Vol->GetName() 148 << " " << latDir << G4endl; 149 } 150 151 G4Material* theMat = Vol->GetLogicalVolume()->GetMaterial(); 152 153 // Create and register the logical lattice, then the physical lattice 154 G4LatticeLogical* lLattice = LoadLattice(theMat, latDir); 155 if (!lLattice) return 0; 156 157 G4LatticePhysical* pLattice = 158 new G4LatticePhysical(lLattice, Vol->GetFrameRotation()); 159 if (pLattice) RegisterLattice(Vol, pLattice); 160 161 if (verboseLevel>1) G4cout << " Created pLattice " << pLattice << G4endl; 162 163 return pLattice; 164 } 165 166 167 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 168 169 // Associate physical (oriented) lattice with physical volume 170 171 G4bool G4LatticeManager::RegisterLattice(G4VPhysicalVolume* Vol, 172 G4LatticePhysical* Lat) { 173 if (!Vol || !Lat) return false; // Don't register null pointers 174 175 G4AutoLock latLock(&latMutex); // Protect before changing registry 176 177 // SPECIAL: Register first lattice with a null volume to act as default 178 if (fPLatticeList.empty()) fPLatticeList[0] = Lat; 179 180 fPLattices.insert(Lat); 181 fPLatticeList[Vol] = Lat; 182 183 latLock.unlock(); 184 185 if (verboseLevel) { 186 G4cout << "G4LatticeManager::RegisterLattice: " 187 << " Total number of physical lattices: " << fPLatticeList.size()-1 188 << " (" << fPLattices.size() << " unique)" << G4endl; 189 } 190 191 return true; 192 } 193 194 G4bool G4LatticeManager::RegisterLattice(G4VPhysicalVolume* Vol, 195 G4LatticeLogical* LLat) { 196 if (!Vol || !LLat) return false; // Don't register null pointers 197 198 // Make sure logical lattice is registered for material 199 RegisterLattice(Vol->GetLogicalVolume()->GetMaterial(), LLat); 200 201 // Create and register new physical lattice to go with volume 202 return RegisterLattice(Vol, new G4LatticePhysical(LLat, Vol->GetFrameRotation())); 203 } 204 205 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 206 207 // Returns a pointer to the LatticeLogical associated with material 208 209 G4LatticeLogical* G4LatticeManager::GetLattice(G4Material* Mat) const { 210 LatticeMatMap::const_iterator latFind = fLLatticeList.find(Mat); 211 if (latFind != fLLatticeList.end()) { 212 if (verboseLevel) 213 G4cout << "G4LatticeManager::GetLattice found " << latFind->second 214 << " for "<< (Mat ? Mat->GetName() : G4String("NULL")) << "." 215 << G4endl; 216 return latFind->second; 217 } 218 219 if (verboseLevel) 220 G4cerr << "G4LatticeManager:: Found no matching lattices for " 221 << (Mat ? Mat->GetName() : G4String("NULL")) << "." << G4endl; 222 223 return nullptr; // No lattice associated with volume 224 } 225 226 // Returns a pointer to the LatticePhysical associated with volume 227 // NOTE: Passing Vol==0 will return the default lattice 228 229 G4LatticePhysical* G4LatticeManager::GetLattice(G4VPhysicalVolume* Vol) const { 230 LatticeVolMap::const_iterator latFind = fPLatticeList.find(Vol); 231 if (latFind != fPLatticeList.end()) { 232 if (verboseLevel) 233 G4cout << "G4LatticeManager::GetLattice found " << latFind->second 234 << " for " << (Vol ? Vol->GetName() : G4String("default")) << "." 235 << G4endl; 236 return latFind->second; 237 } 238 239 if (verboseLevel) 240 G4cerr << "G4LatticeManager::GetLattice found no matching lattices for " 241 << (Vol ? Vol->GetName() : G4String("default")) << "." << G4endl; 242 243 return nullptr; // No lattice associated with volume 244 } 245 246 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 247 248 // Return true if volume Vol has a physical lattice 249 250 G4bool G4LatticeManager::HasLattice(G4VPhysicalVolume* Vol) const { 251 return (fPLatticeList.find(Vol) != fPLatticeList.end()); 252 } 253 254 // Return true if material Mat has a logical lattice 255 256 G4bool G4LatticeManager::HasLattice(G4Material* Mat) const { 257 return (fLLatticeList.find(Mat) != fLLatticeList.end()); 258 } 259 260 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 261 262 //Given the phonon wave vector k, phonon physical volume Vol 263 //and polarizationState(0=LON, 1=FT, 2=ST), 264 //returns phonon velocity in m/s 265 266 G4double G4LatticeManager::MapKtoV(G4VPhysicalVolume* Vol, 267 G4int polarizationState, 268 const G4ThreeVector & k) const { 269 G4LatticePhysical* theLattice = GetLattice(Vol); 270 if (verboseLevel) 271 G4cout << "G4LatticeManager::MapKtoV using lattice " << theLattice 272 << G4endl; 273 274 // If no lattice available, use generic "speed of sound" 275 return theLattice ? theLattice->MapKtoV(polarizationState, k) : 300.*m/s; 276 } 277 278 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 279 280 // Given the phonon wave vector k, phonon physical volume Vol 281 // and polarizationState(0=LON, 1=FT, 2=ST), 282 // returns phonon propagation direction as dimensionless unit vector 283 284 G4ThreeVector G4LatticeManager::MapKtoVDir(G4VPhysicalVolume* Vol, 285 G4int polarizationState, 286 const G4ThreeVector & k) const { 287 G4LatticePhysical* theLattice = GetLattice(Vol); 288 if (verboseLevel) 289 G4cout << "G4LatticeManager::MapKtoVDir using lattice " << theLattice 290 << G4endl; 291 292 // If no lattice available, propagate along input wavevector 293 return theLattice ? theLattice->MapKtoVDir(polarizationState, k) : k.unit(); 294 } 295