Files
geant4/source/processes/solidstate/phonon/src/G4LatticeManager.cc
T
2017-06-30 10:49:55 +02:00

294 lines
9.9 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/// \file materials/src/G4LatticeManager.cc
/// \brief Implementation of the G4LatticeManager class
//
// $Id: G4LatticeManager.cc 84149 2014-10-08 18:04:16Z mkelsey $
//
// 20131113 Delete lattices in (new) registry, not in lookup maps
// 20141008 Change to global singleton; must be shared across worker threads
#include "G4LatticeManager.hh"
#include "G4AutoLock.hh"
#include "G4LatticeLogical.hh"
#include "G4LatticePhysical.hh"
#include "G4LatticeReader.hh"
#include "G4LogicalVolume.hh"
#include "G4Material.hh"
#include "G4VPhysicalVolume.hh"
#include "G4SystemOfUnits.hh"
#include "G4Threading.hh"
#include <fstream>
G4LatticeManager* G4LatticeManager::fLM = 0; // Global (shared) singleton
namespace {
G4Mutex latMutex = G4MUTEX_INITIALIZER; // For thread protection
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4LatticeManager::G4LatticeManager() : verboseLevel(0) {
Clear();
}
G4LatticeManager::~G4LatticeManager() {
Reset(); // Deletes all lattices
}
// Delete all registered lattices and clear entries from lookup tables
void G4LatticeManager::Reset() {
for (LatticeLogReg::iterator lm=fLLattices.begin();
lm != fLLattices.end(); ++lm) {
delete (*lm);
}
for (LatticePhyReg::iterator pm=fPLattices.begin();
pm != fPLattices.end(); ++pm) {
delete (*pm);
}
Clear();
}
// Remove entries without deletion (for begin-job and end-job initializing)
void G4LatticeManager::Clear() {
fPLatticeList.clear();
fPLattices.clear();
fLLatticeList.clear();
fLLattices.clear();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4LatticeManager* G4LatticeManager::GetLatticeManager() {
// if no lattice manager exists, create one.
G4AutoLock latLock(&latMutex); // Protect before changing pointer
if (!fLM) fLM = new G4LatticeManager();
latLock.unlock();
return fLM;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// Associate logical lattice with material
G4bool G4LatticeManager::RegisterLattice(G4Material* Mat,
G4LatticeLogical* Lat) {
if (!Mat || !Lat) return false; // Don't register null pointers
G4AutoLock latLock(&latMutex); // Protect before changing registry
fLLattices.insert(Lat); // Take ownership in registry
fLLatticeList[Mat] = Lat;
latLock.unlock();
if (verboseLevel) {
G4cout << "G4LatticeManager::RegisterLattice: "
<< " Total number of logical lattices: " << fLLatticeList.size()
<< " (" << fLLattices.size() << " unique)" << G4endl;
}
return true;
}
// Construct logical lattice for material from config file
G4LatticeLogical* G4LatticeManager::LoadLattice(G4Material* Mat,
const G4String& latDir) {
if (verboseLevel) {
G4cout << "G4LatticeManager::LoadLattice material " << Mat->GetName()
<< " " << latDir << G4endl;
}
G4LatticeReader latReader(verboseLevel);
G4LatticeLogical* newLat = latReader.MakeLattice(latDir+"/config.txt");
if (verboseLevel>1) G4cout << " Created newLat " << newLat << G4endl;
if (newLat) RegisterLattice(Mat, newLat);
else {
G4cerr << "ERROR creating " << latDir << " lattice for material "
<< Mat->GetName() << G4endl;
}
return newLat;
}
// Combine loading and registration (Material extracted from volume)
G4LatticePhysical* G4LatticeManager::LoadLattice(G4VPhysicalVolume* Vol,
const G4String& latDir) {
if (verboseLevel) {
G4cout << "G4LatticeManager::LoadLattice volume " << Vol->GetName()
<< " " << latDir << G4endl;
}
G4Material* theMat = Vol->GetLogicalVolume()->GetMaterial();
// Create and register the logical lattice, then the physical lattice
G4LatticeLogical* lLattice = LoadLattice(theMat, latDir);
if (!lLattice) return 0;
G4LatticePhysical* pLattice =
new G4LatticePhysical(lLattice, Vol->GetFrameRotation());
if (pLattice) RegisterLattice(Vol, pLattice);
if (verboseLevel>1) G4cout << " Created pLattice " << pLattice << G4endl;
return pLattice;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// Associate physical (oriented) lattice with physical volume
G4bool G4LatticeManager::RegisterLattice(G4VPhysicalVolume* Vol,
G4LatticePhysical* Lat) {
if (!Vol || !Lat) return false; // Don't register null pointers
G4AutoLock latLock(&latMutex); // Protect before changing registry
// SPECIAL: Register first lattice with a null volume to act as default
if (fPLatticeList.empty()) fPLatticeList[0] = Lat;
fPLattices.insert(Lat);
fPLatticeList[Vol] = Lat;
latLock.unlock();
if (verboseLevel) {
G4cout << "G4LatticeManager::RegisterLattice: "
<< " Total number of physical lattices: " << fPLatticeList.size()-1
<< " (" << fPLattices.size() << " unique)" << G4endl;
}
return true;
}
G4bool G4LatticeManager::RegisterLattice(G4VPhysicalVolume* Vol,
G4LatticeLogical* LLat) {
if (!Vol || !LLat) return false; // Don't register null pointers
// Make sure logical lattice is registered for material
RegisterLattice(Vol->GetLogicalVolume()->GetMaterial(), LLat);
// Create and register new physical lattice to go with volume
return RegisterLattice(Vol, new G4LatticePhysical(LLat, Vol->GetFrameRotation()));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// Returns a pointer to the LatticeLogical associated with material
G4LatticeLogical* G4LatticeManager::GetLattice(G4Material* Mat) const {
LatticeMatMap::const_iterator latFind = fLLatticeList.find(Mat);
if (latFind != fLLatticeList.end()) {
if (verboseLevel)
G4cout << "G4LatticeManager::GetLattice found " << latFind->second
<< " for " << (Mat?Mat->GetName():"NULL") << "." << G4endl;
return latFind->second;
}
if (verboseLevel)
G4cerr << "G4LatticeManager:: Found no matching lattices for "
<< (Mat?Mat->GetName():"NULL") << "." << G4endl;
return 0; // No lattice associated with volume
}
// Returns a pointer to the LatticePhysical associated with volume
// NOTE: Passing Vol==0 will return the default lattice
G4LatticePhysical* G4LatticeManager::GetLattice(G4VPhysicalVolume* Vol) const {
LatticeVolMap::const_iterator latFind = fPLatticeList.find(Vol);
if (latFind != fPLatticeList.end()) {
if (verboseLevel)
G4cout << "G4LatticeManager::GetLattice found " << latFind->second
<< " for " << (Vol?Vol->GetName():"default") << "." << G4endl;
return latFind->second;
}
if (verboseLevel)
G4cerr << "G4LatticeManager::GetLattice found no matching lattices for "
<< (Vol?Vol->GetName():"default") << "." << G4endl;
return 0; // No lattice associated with volume
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// Return true if volume Vol has a physical lattice
G4bool G4LatticeManager::HasLattice(G4VPhysicalVolume* Vol) const {
return (fPLatticeList.find(Vol) != fPLatticeList.end());
}
// Return true if material Mat has a logical lattice
G4bool G4LatticeManager::HasLattice(G4Material* Mat) const {
return (fLLatticeList.find(Mat) != fLLatticeList.end());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//Given the phonon wave vector k, phonon physical volume Vol
//and polarizationState(0=LON, 1=FT, 2=ST),
//returns phonon velocity in m/s
G4double G4LatticeManager::MapKtoV(G4VPhysicalVolume* Vol,
G4int polarizationState,
const G4ThreeVector & k) const {
G4LatticePhysical* theLattice = GetLattice(Vol);
if (verboseLevel)
G4cout << "G4LatticeManager::MapKtoV using lattice " << theLattice
<< G4endl;
// If no lattice available, use generic "speed of sound"
return theLattice ? theLattice->MapKtoV(polarizationState, k) : 300.*m/s;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// Given the phonon wave vector k, phonon physical volume Vol
// and polarizationState(0=LON, 1=FT, 2=ST),
// returns phonon propagation direction as dimensionless unit vector
G4ThreeVector G4LatticeManager::MapKtoVDir(G4VPhysicalVolume* Vol,
G4int polarizationState,
const G4ThreeVector & k) const {
G4LatticePhysical* theLattice = GetLattice(Vol);
if (verboseLevel)
G4cout << "G4LatticeManager::MapKtoVDir using lattice " << theLattice
<< G4endl;
// If no lattice available, propagate along input wavevector
return theLattice ? theLattice->MapKtoVDir(polarizationState, k) : k.unit();
}