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