Import Geant4 10.0.0 source tree
This commit is contained in:
@@ -0,0 +1,279 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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 76693 2013-11-14 08:47:37Z gcosmo $
|
||||
//
|
||||
// 20131113 Delete lattices in (new) registry, not in lookup maps
|
||||
|
||||
#include "G4LatticeManager.hh"
|
||||
#include "G4LatticeLogical.hh"
|
||||
#include "G4LatticePhysical.hh"
|
||||
#include "G4LatticeReader.hh"
|
||||
#include "G4LogicalVolume.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4VPhysicalVolume.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include <fstream>
|
||||
|
||||
G4ThreadLocal G4LatticeManager* G4LatticeManager::fLM = 0;
|
||||
|
||||
|
||||
//....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.
|
||||
if (!fLM) fLM = new G4LatticeManager();
|
||||
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
|
||||
|
||||
fLLattices.insert(Lat); // Take ownership in registry
|
||||
fLLatticeList[Mat] = Lat;
|
||||
|
||||
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
|
||||
|
||||
// SPECIAL: Register first lattice with a null volume to act as default
|
||||
if (fPLatticeList.empty()) fPLatticeList[0] = Lat;
|
||||
|
||||
fPLattices.insert(Lat);
|
||||
fPLatticeList[Vol] = Lat;
|
||||
|
||||
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();
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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 processes/phonon/include/G4LatticeReader.hh
|
||||
/// \brief Implementation of the G4LatticeReader class
|
||||
//
|
||||
// NOTE: This reader class for logical lattices should be moved to
|
||||
// materials/ after the 10.0 release (and this comment removed).
|
||||
// $Id: G4LatticeReader.cc 76885 2013-11-18 12:55:15Z gcosmo $
|
||||
//
|
||||
// 20131106 M.Kelsey -- Add const to getenv() to avoid compiler warning.
|
||||
// 20131112 Throw exception if input file fails.
|
||||
// 20131115 Check file input arguments for maps for validity before use;
|
||||
// move ctor, dtor here; check stream pointer before closing.
|
||||
|
||||
#include "G4LatticeReader.hh"
|
||||
#include "G4ExceptionSeverity.hh"
|
||||
#include "G4LatticeLogical.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
// Default path to lattice files, for use with filenames below
|
||||
|
||||
const G4String G4LatticeReader::fDataDir =
|
||||
getenv("G4LATTICEDATA") ? (const char*)getenv("G4LATTICEDATA") : "./CrystalMaps";
|
||||
|
||||
|
||||
// Constructor and destructor
|
||||
|
||||
G4LatticeReader::G4LatticeReader(G4int vb)
|
||||
: verboseLevel(vb), psLatfile(0), pLattice(0), fMapPath(""),
|
||||
fToken(""), fValue(0.), fMap(""), fsPol(""), fPol(-1), fNX(0), fNY(0) {;}
|
||||
|
||||
G4LatticeReader::~G4LatticeReader() {
|
||||
delete psLatfile; psLatfile = 0;
|
||||
}
|
||||
|
||||
|
||||
// Main drivers to read configuration from file or stream
|
||||
|
||||
G4LatticeLogical* G4LatticeReader::MakeLattice(const G4String& filename) {
|
||||
if (verboseLevel) G4cout << "G4LatticeReader " << filename << G4endl;
|
||||
|
||||
if (!OpenFile(filename)) {
|
||||
G4ExceptionDescription msg;
|
||||
msg << "Unable to open " << filename;
|
||||
G4Exception("G4LatticeReader::MakeLattice", "Lattice001",
|
||||
FatalException, msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pLattice = new G4LatticeLogical; // Create lattice to be filled
|
||||
|
||||
G4bool goodLattice = true;
|
||||
while (!psLatfile->eof()) {
|
||||
goodLattice &= ProcessToken();
|
||||
}
|
||||
CloseFile();
|
||||
|
||||
if (!goodLattice) {
|
||||
G4ExceptionDescription msg;
|
||||
msg << "Error reading lattice from " << filename;
|
||||
G4Exception("G4LatticeReader::MakeLattice", "Lattice002",
|
||||
FatalException, msg);
|
||||
delete pLattice;
|
||||
pLattice = 0;
|
||||
}
|
||||
|
||||
return pLattice; // Lattice complete; return pointer with ownership
|
||||
}
|
||||
|
||||
|
||||
// Open local file or file found under data path
|
||||
|
||||
G4bool G4LatticeReader::OpenFile(const G4String& filename) {
|
||||
if (verboseLevel)
|
||||
G4cout << "G4LatticeReader::OpenFile " << filename << G4endl;
|
||||
|
||||
G4String filepath = filename;
|
||||
psLatfile = new std::ifstream(filepath);
|
||||
if (!psLatfile->good()) { // Local file not found
|
||||
filepath = fDataDir + "/" + filename;
|
||||
psLatfile->open(filepath); // Try data directory
|
||||
if (!psLatfile->good()) {
|
||||
CloseFile();
|
||||
return false;
|
||||
}
|
||||
if (verboseLevel>1) G4cout << " Found file " << filepath << G4endl;
|
||||
}
|
||||
|
||||
// Extract path from filename to use in finding .ssv map files
|
||||
size_t lastdir = filepath.last('/');
|
||||
if (lastdir == std::string::npos) fMapPath = "."; // No path at all
|
||||
else fMapPath = filepath(0,lastdir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Close and delete input stream
|
||||
|
||||
void G4LatticeReader::CloseFile() {
|
||||
if (psLatfile) psLatfile->close();
|
||||
delete psLatfile;
|
||||
psLatfile = 0;
|
||||
}
|
||||
|
||||
|
||||
// Read next token from file, use it to store next data into lattice
|
||||
|
||||
G4bool G4LatticeReader::ProcessToken() {
|
||||
fToken = "";
|
||||
*psLatfile >> fToken;
|
||||
if (fToken.empty() || psLatfile->eof()) return true; // End of file reached
|
||||
|
||||
if (verboseLevel>1) G4cout << " ProcessToken " << fToken << G4endl;
|
||||
|
||||
fToken.toLower();
|
||||
if (fToken.contains('#')) return SkipComments(); // Ignore rest of line
|
||||
if (fToken == "vdir") return ProcessNMap(); // Direction vector map
|
||||
if (fToken == "vg") return ProcessMap(); // Velocity magnitudes
|
||||
if (fToken == "dyn") return ProcessConstants(); // Dynamical parameters
|
||||
return ProcessValue(fToken); // Single numeric value
|
||||
}
|
||||
|
||||
// Eat remainder of line, assuming a '#' token was found
|
||||
|
||||
G4bool G4LatticeReader::SkipComments() {
|
||||
psLatfile->ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
return true; // Never fails
|
||||
}
|
||||
|
||||
// Read double value from file, store based on name string
|
||||
|
||||
G4bool G4LatticeReader::ProcessValue(const G4String& name) {
|
||||
*psLatfile >> fValue;
|
||||
if (verboseLevel>1) G4cout << " ProcessValue " << fValue << G4endl;
|
||||
|
||||
G4bool good = true;
|
||||
/***** NOTE: Individual Set functions not included in Release 10.0
|
||||
if (name == "beta") pLattice->SetBeta(fValue);
|
||||
else if (name == "gamma") pLattice->SetGamma(fValue);
|
||||
else if (name == "lambda") pLattice->SetLambda(fValue);
|
||||
else if (name == "mu") pLattice->SetMu(fValue);
|
||||
else *****/
|
||||
if (name == "scat") pLattice->SetScatteringConstant(fValue*s*s*s);
|
||||
else if (name == "b") pLattice->SetScatteringConstant(fValue*s*s*s);
|
||||
else if (name == "decay") pLattice->SetAnhDecConstant(fValue*s*s*s*s);
|
||||
else if (name == "a") pLattice->SetAnhDecConstant(fValue*s*s*s*s);
|
||||
else if (name == "ldos") pLattice->SetLDOS(fValue);
|
||||
else if (name == "stdos") pLattice->SetSTDOS(fValue);
|
||||
else if (name == "ftdos") pLattice->SetFTDOS(fValue);
|
||||
else {
|
||||
G4cerr << "G4LatticeReader: Unrecognized token " << name << G4endl;
|
||||
good = false;
|
||||
}
|
||||
|
||||
return good;
|
||||
}
|
||||
|
||||
G4bool G4LatticeReader::ProcessConstants() {
|
||||
G4double beta=0., gamma=0., lambda=0., mu=0.;
|
||||
*psLatfile >> beta >> gamma >> lambda >> mu;
|
||||
if (verboseLevel>1)
|
||||
G4cout << " ProcessConstants " << beta << " " << gamma
|
||||
<< " " << lambda << " " << mu << G4endl;
|
||||
|
||||
pLattice->SetDynamicalConstants(beta, gamma, lambda, mu);
|
||||
return psLatfile->good();
|
||||
}
|
||||
|
||||
// Read map filename, polarization, and binning dimensions
|
||||
|
||||
G4bool G4LatticeReader::ReadMapInfo() {
|
||||
*psLatfile >> fMap >> fsPol >> fNX >> fNY;
|
||||
if (verboseLevel>1)
|
||||
G4cout << " ReadMapInfo " << fMap << " " << fsPol
|
||||
<< " " << fNX << " " << fNY << G4endl;
|
||||
|
||||
if (fNX < 0 || fNX >= G4LatticeLogical::MAXRES) {
|
||||
G4cerr << "G4LatticeReader: Invalid map theta dimension " << fNX << G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fNY < 0 || fNY >= G4LatticeLogical::MAXRES) {
|
||||
G4cerr << "G4LatticeReader: Invalid map phi dimension " << fNY << G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prepend path to data files to map filename
|
||||
fMap = fMapPath + "/" + fMap;
|
||||
|
||||
// Convert string code (L,ST,LT) to polarization index
|
||||
fsPol.toLower();
|
||||
fPol = ( (fsPol=="l") ? 0 : // Longitudinal
|
||||
(fsPol=="st") ? 1 : // Slow-transverse
|
||||
(fsPol=="ft") ? 2 : // Fast-transverse
|
||||
-1 ); // Invalid code
|
||||
|
||||
if (fPol<0 || fPol>2) {
|
||||
G4cerr << "G4LatticeReader: Invalid polarization code " << fsPol << G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
G4bool G4LatticeReader::ProcessMap() {
|
||||
if (!ReadMapInfo()) { // Get specific parameters for map to load
|
||||
G4cerr << "G4LatticeReader: Unable to process mapfile directive." << G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return pLattice->LoadMap(fNX, fNY, fPol, fMap);
|
||||
}
|
||||
|
||||
G4bool G4LatticeReader::ProcessNMap() {
|
||||
if (!ReadMapInfo()) { // Get specific parameters for map to load
|
||||
G4cerr << "G4LatticeReader: Unable to process mapfile directive." << G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return pLattice->Load_NMap(fNX, fNY, fPol, fMap);
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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 processes/phonon/src/G4PhononDownconversion.cc
|
||||
/// \brief Implementation of the G4PhononDownconversion class
|
||||
//
|
||||
// $Id: G4PhononDownconversion.cc 76885 2013-11-18 12:55:15Z gcosmo $
|
||||
//
|
||||
// 20131111 Add verbose output for MFP calculation
|
||||
// 20131115 Initialize data buffers in ctor
|
||||
|
||||
#include "G4PhononDownconversion.hh"
|
||||
#include "G4LatticePhysical.hh"
|
||||
#include "G4PhononLong.hh"
|
||||
#include "G4PhononPolarization.hh"
|
||||
#include "G4PhononTrackMap.hh"
|
||||
#include "G4PhononTransFast.hh"
|
||||
#include "G4PhononTransSlow.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4RandomDirection.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
#include "Randomize.hh"
|
||||
#include <cmath>
|
||||
|
||||
|
||||
|
||||
G4PhononDownconversion::G4PhononDownconversion(const G4String& aName)
|
||||
: G4VPhononProcess(aName), fBeta(0.), fGamma(0.), fLambda(0.), fMu(0.) {;}
|
||||
|
||||
G4PhononDownconversion::~G4PhononDownconversion() {;}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4PhononDownconversion::GetMeanFreePath(const G4Track& aTrack,
|
||||
G4double /*previousStepSize*/,
|
||||
G4ForceCondition* condition) {
|
||||
//Determines mean free path for longitudinal phonons to split
|
||||
G4double A = theLattice->GetAnhDecConstant();
|
||||
G4double Eoverh = aTrack.GetKineticEnergy()/h_Planck;
|
||||
|
||||
//Calculate mean free path for anh. decay
|
||||
G4double mfp = aTrack.GetVelocity()/(Eoverh*Eoverh*Eoverh*Eoverh*Eoverh*A);
|
||||
|
||||
if (verboseLevel > 1)
|
||||
G4cout << "G4PhononDownconversion::GetMeanFreePath = " << mfp << G4endl;
|
||||
|
||||
*condition = NotForced;
|
||||
return mfp;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4VParticleChange* G4PhononDownconversion::PostStepDoIt( const G4Track& aTrack,
|
||||
const G4Step&) {
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
//Obtain dynamical constants from this volume's lattice
|
||||
fBeta=theLattice->GetBeta();
|
||||
fGamma=theLattice->GetGamma();
|
||||
fLambda=theLattice->GetLambda();
|
||||
fMu=theLattice->GetMu();
|
||||
|
||||
//Destroy the parent phonon and create the daughter phonons.
|
||||
//74% chance that daughter phonons are both transverse
|
||||
//26% Transverse and Longitudinal
|
||||
if (G4UniformRand()>0.740) MakeLTSecondaries(aTrack);
|
||||
else MakeTTSecondaries(aTrack);
|
||||
|
||||
aParticleChange.ProposeEnergy(0.);
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
return &aParticleChange;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4PhononDownconversion::IsApplicable(const G4ParticleDefinition& aPD) {
|
||||
//Only L-phonons decay
|
||||
return (&aPD==G4PhononLong::PhononDefinition());
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
//probability density of energy distribution of L'-phonon in L->L'+T process
|
||||
|
||||
inline double G4PhononDownconversion::GetLTDecayProb(double d, double x) const {
|
||||
//d=delta= ratio of group velocities vl/vt and x is the fraction of energy in the longitudinal mode, i.e. x=EL'/EL
|
||||
return (1/(x*x))*(1-x*x)*(1-x*x)*((1+x)*(1+x)-d*d*((1-x)*(1-x)))*(1+x*x-d*d*(1-x)*(1-x))*(1+x*x-d*d*(1-x)*(1-x));
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
//probability density of energy distribution of T-phonon in L->T+T process
|
||||
|
||||
inline double G4PhononDownconversion::GetTTDecayProb(double d, double x) const {
|
||||
//dynamic constants from Tamura, PRL31, 1985
|
||||
G4double A = 0.5*(1-d*d)*(fBeta+fLambda+(1+d*d)*(fGamma+fMu));
|
||||
G4double B = fBeta+fLambda+2*d*d*(fGamma+fMu);
|
||||
G4double C = fBeta + fLambda + 2*(fGamma+fMu);
|
||||
G4double D = (1-d*d)*(2*fBeta+4*fGamma+fLambda+3*fMu);
|
||||
|
||||
return (A+B*d*x-B*x*x)*(A+B*d*x-B*x*x)+(C*x*(d-x)-D/(d-x)*(x-d-(1-d*d)/(4*x)))*(C*x*(d-x)-D/(d-x)*(x-d-(1-d*d)/(4*x)));
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
inline double G4PhononDownconversion::MakeLDeviation(double d, double x) const {
|
||||
//change in L'-phonon propagation direction after decay
|
||||
|
||||
return std::acos((1+(x*x)-((d*d)*(1-x)*(1-x)))/(2*x));
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
inline double G4PhononDownconversion::MakeTDeviation(double d, double x) const {
|
||||
//change in T-phonon propagation direction after decay (L->L+T process)
|
||||
|
||||
return std::acos((1-x*x+d*d*(1-x)*(1-x))/(2*d*(1-x)));
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
inline double G4PhononDownconversion::MakeTTDeviation(double d, double x) const {
|
||||
//change in T-phonon propagation direction after decay (L->T+T process)
|
||||
|
||||
return std::acos((1-d*d*(1-x)*(1-x)+d*d*x*x)/(2*d*x));
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
//Generate daughter phonons from L->T+T process
|
||||
|
||||
void G4PhononDownconversion::MakeTTSecondaries(const G4Track& aTrack) {
|
||||
//d is the velocity ratio vL/vT
|
||||
G4double d=1.6338;
|
||||
G4double upperBound=(1+(1/d))/2;
|
||||
G4double lowerBound=(1-(1/d))/2;
|
||||
|
||||
//Use MC method to generate point from distribution:
|
||||
//if a random point on the energy-probability plane is
|
||||
//smaller that the curve of the probability density,
|
||||
//then accept that point.
|
||||
//x=fraction of parent phonon energy in first T phonon
|
||||
G4double x = G4UniformRand()*(upperBound-lowerBound) + lowerBound;
|
||||
G4double p = 1.5*G4UniformRand();
|
||||
while(p >= GetTTDecayProb(d, x*d)) {
|
||||
x = G4UniformRand()*(upperBound-lowerBound) + lowerBound;
|
||||
p = 1.5*G4UniformRand();
|
||||
}
|
||||
|
||||
//using energy fraction x to calculate daughter phonon directions
|
||||
G4double theta1=MakeTTDeviation(d, x);
|
||||
G4double theta2=MakeTTDeviation(d, 1-x);
|
||||
G4ThreeVector dir1=trackKmap->GetK(aTrack);
|
||||
G4ThreeVector dir2=dir1;
|
||||
|
||||
// FIXME: These extra randoms change timing and causting outputs of example!
|
||||
G4ThreeVector ran = G4RandomDirection(); // FIXME: Drop this line
|
||||
|
||||
G4double ph=G4UniformRand()*twopi;
|
||||
dir1 = dir1.rotate(dir1.orthogonal(),theta1).rotate(dir1, ph);
|
||||
dir2 = dir2.rotate(dir2.orthogonal(),-theta2).rotate(dir2,ph);
|
||||
|
||||
G4double E=aTrack.GetKineticEnergy();
|
||||
G4double Esec1 = x*E, Esec2 = E-Esec1;
|
||||
|
||||
// Make FT or ST phonon (0. means no longitudinal)
|
||||
G4int polarization1 = ChoosePolarization(0., theLattice->GetSTDOS(),
|
||||
theLattice->GetFTDOS());
|
||||
|
||||
// Make FT or ST phonon (0. means no longitudinal)
|
||||
G4int polarization2 = ChoosePolarization(0., theLattice->GetSTDOS(),
|
||||
theLattice->GetFTDOS());
|
||||
|
||||
// Construct the secondaries and set their wavevectors
|
||||
G4Track* sec1 = CreateSecondary(polarization1, dir1, Esec1);
|
||||
G4Track* sec2 = CreateSecondary(polarization2, dir2, Esec2);
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(2);
|
||||
aParticleChange.AddSecondary(sec1);
|
||||
aParticleChange.AddSecondary(sec2);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
//Generate daughter phonons from L->L'+T process
|
||||
|
||||
void G4PhononDownconversion::MakeLTSecondaries(const G4Track& aTrack) {
|
||||
//d is the velocity ratio vL/v
|
||||
G4double d=1.6338;
|
||||
G4double upperBound=1;
|
||||
G4double lowerBound=(d-1)/(d+1);
|
||||
|
||||
//Use MC method to generate point from distribution:
|
||||
//if a random point on the energy-probability plane is
|
||||
//smaller that the curve of the probability density,
|
||||
//then accept that point.
|
||||
//x=fraction of parent phonon energy in L phonon
|
||||
G4double x = G4UniformRand()*(upperBound-lowerBound) + lowerBound;
|
||||
G4double p = 4.0*G4UniformRand();
|
||||
while(p >= GetLTDecayProb(d, x)) {
|
||||
x = G4UniformRand()*(upperBound-lowerBound) + lowerBound;
|
||||
p = 4.0*G4UniformRand(); //4.0 is about the max in the PDF
|
||||
}
|
||||
|
||||
//using energy fraction x to calculate daughter phonon directions
|
||||
G4double thetaL=MakeLDeviation(d, x);
|
||||
G4double thetaT=MakeTDeviation(d, x); // FIXME: Should be 1-x?
|
||||
G4ThreeVector dir1=trackKmap->GetK(aTrack);
|
||||
G4ThreeVector dir2=dir1;
|
||||
|
||||
G4double ph=G4UniformRand()*twopi;
|
||||
dir1 = dir1.rotate(dir1.orthogonal(),thetaL).rotate(dir1, ph);
|
||||
dir2 = dir2.rotate(dir2.orthogonal(),-thetaT).rotate(dir2,ph);
|
||||
|
||||
G4double E=aTrack.GetKineticEnergy();
|
||||
G4double Esec1 = x*E, Esec2 = E-Esec1;
|
||||
|
||||
// First secondary is longitudnal
|
||||
int polarization1 = G4PhononPolarization::Long;
|
||||
|
||||
// Make FT or ST phonon (0. means no longitudinal)
|
||||
G4int polarization2 = ChoosePolarization(0., theLattice->GetSTDOS(),
|
||||
theLattice->GetFTDOS());
|
||||
|
||||
// Construct the secondaries and set their wavevectors
|
||||
G4Track* sec1 = CreateSecondary(polarization1, dir1, Esec1);
|
||||
G4Track* sec2 = CreateSecondary(polarization2, dir2, Esec2);
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(2);
|
||||
aParticleChange.AddSecondary(sec1);
|
||||
aParticleChange.AddSecondary(sec2);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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 processes/phonon/src/G4PhononPolarization.cc
|
||||
/// \brief implementation of the G4PhononPolarization enum
|
||||
//
|
||||
// $Id: G4PhononPolarization.cc 75725 2013-11-05 16:52:30Z mkelsey $
|
||||
//
|
||||
|
||||
#include "G4PhononPolarization.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4PhononLong.hh"
|
||||
#include "G4PhononTransFast.hh"
|
||||
#include "G4PhononTransSlow.hh"
|
||||
|
||||
|
||||
G4int G4PhononPolarization::Get(const G4ParticleDefinition* aPD) {
|
||||
if (aPD == G4PhononLong::Definition()) return Long;
|
||||
if (aPD == G4PhononTransSlow::Definition()) return TransSlow;
|
||||
if (aPD == G4PhononTransFast::Definition()) return TransFast;
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
G4ParticleDefinition* G4PhononPolarization::Get(G4int pol) {
|
||||
switch (pol) {
|
||||
case Long: return G4PhononLong::Definition(); break;
|
||||
case TransSlow: return G4PhononTransSlow::Definition(); break;
|
||||
case TransFast: return G4PhononTransFast::Definition(); break;
|
||||
default: ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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 processes/phonon/src/G4PhononReflection.cc
|
||||
/// \brief Implementation of the G4PhononReflection class
|
||||
//
|
||||
// This process handles the interaction of phonons with
|
||||
// boundaries. Implementation of this class is highly
|
||||
// geometry dependent.Currently, phonons are killed when
|
||||
// they reach a boundary. If the other side of the
|
||||
// boundary was Al, a hit is registered.
|
||||
//
|
||||
// $Id: G4PhononReflection.cc 76885 2013-11-18 12:55:15Z gcosmo $
|
||||
//
|
||||
// 20131115 Throw exception if track's polarization state is invalid.
|
||||
|
||||
#include "G4PhononReflection.hh"
|
||||
#include "G4ExceptionSeverity.hh"
|
||||
#include "G4GeometryTolerance.hh"
|
||||
#include "G4LatticePhysical.hh"
|
||||
#include "G4PhononLong.hh"
|
||||
#include "G4PhononTransFast.hh"
|
||||
#include "G4PhononTransSlow.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4StepPoint.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
|
||||
|
||||
G4PhononReflection::G4PhononReflection(const G4String& aName)
|
||||
: G4VPhononProcess(aName),
|
||||
kCarTolerance(G4GeometryTolerance::GetInstance()->GetSurfaceTolerance()) {;}
|
||||
|
||||
G4PhononReflection::~G4PhononReflection() {;}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
// Always return DBL_MAX and Forced. This ensures that the process is
|
||||
// called at the end of every step. In PostStepDoIt the process
|
||||
// decides whether the step encountered a volume boundary and a
|
||||
// reflection should be applied
|
||||
|
||||
G4double G4PhononReflection::GetMeanFreePath(const G4Track&, G4double,
|
||||
G4ForceCondition* condition) {
|
||||
*condition = Forced;
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
// This process handles the interaction of phonons with
|
||||
// boundaries. Implementation of this class is highly geometry
|
||||
// dependent.Currently, phonons are killed when they reach a
|
||||
// boundary. If the other side of the boundary was Al, a hit is
|
||||
// registered.
|
||||
|
||||
G4VParticleChange* G4PhononReflection::PostStepDoIt(const G4Track& aTrack,
|
||||
const G4Step& aStep) {
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
//Check if current step is limited by a volume boundary
|
||||
G4StepPoint* postStepPoint = aStep.GetPostStepPoint();
|
||||
if (postStepPoint->GetStepStatus()!=fGeomBoundary) {
|
||||
//make sure that correct phonon velocity is used after the step
|
||||
int pol = GetPolarization(aTrack);
|
||||
if (pol < 0 || pol > 2) {
|
||||
G4Exception("G4PhononReflection::PostStepDoIt","Phonon001",
|
||||
EventMustBeAborted, "Track is not a phonon");
|
||||
return &aParticleChange; // NOTE: Will never get here
|
||||
}
|
||||
|
||||
// FIXME: This should be using wave-vector, shouldn't it?
|
||||
G4double vg = theLattice->MapKtoV(pol, aTrack.GetMomentumDirection());
|
||||
|
||||
//Since step was not a volume boundary, just set correct phonon velocity and return
|
||||
aParticleChange.ProposeVelocity(vg);
|
||||
return &aParticleChange;
|
||||
}
|
||||
|
||||
// do nothing but return is the step is too short
|
||||
// This is to allow actual reflection where after
|
||||
// the first boundary crossing a second, infinitesimal
|
||||
// step occurs crossing back into the original volume
|
||||
if (aTrack.GetStepLength()<=kCarTolerance/2) {
|
||||
return &aParticleChange;
|
||||
}
|
||||
|
||||
G4double eKin = aTrack.GetKineticEnergy();
|
||||
aParticleChange.ProposeNonIonizingEnergyDeposit(eKin);
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
return &aParticleChange;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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 processes/phonon/src/G4PhononScattering.cc
|
||||
/// \brief Implementation of the G4PhononScattering class
|
||||
//
|
||||
// $Id: G4PhononScattering.cc 76693 2013-11-14 08:47:37Z gcosmo $
|
||||
//
|
||||
// 20131111 Add verbose output for MFP calculation
|
||||
|
||||
#include "G4PhononScattering.hh"
|
||||
#include "G4LatticePhysical.hh"
|
||||
#include "G4PhononPolarization.hh"
|
||||
#include "G4PhononLong.hh"
|
||||
#include "G4PhononTrackMap.hh"
|
||||
#include "G4PhononTransFast.hh"
|
||||
#include "G4PhononTransSlow.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4RandomDirection.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
|
||||
G4PhononScattering::G4PhononScattering(const G4String& aName)
|
||||
: G4VPhononProcess(aName) {;}
|
||||
|
||||
G4PhononScattering::~G4PhononScattering() {;}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4PhononScattering::GetMeanFreePath(const G4Track& aTrack,
|
||||
G4double /*previousStepSize*/,
|
||||
G4ForceCondition* condition) {
|
||||
//Dynamical constants retrieved from PhysicalLattice
|
||||
G4double B = theLattice->GetScatteringConstant();
|
||||
G4double Eoverh = aTrack.GetKineticEnergy()/h_Planck;
|
||||
|
||||
//Calculate mean free path
|
||||
G4double mfp = aTrack.GetVelocity()/(Eoverh*Eoverh*Eoverh*Eoverh*B);
|
||||
|
||||
if (verboseLevel > 1)
|
||||
G4cout << "G4PhononScattering::GetMeanFreePath = " << mfp << G4endl;
|
||||
|
||||
*condition = NotForced;
|
||||
|
||||
return mfp;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VParticleChange* G4PhononScattering::PostStepDoIt( const G4Track& aTrack,
|
||||
const G4Step& aStep) {
|
||||
G4StepPoint* postStepPoint = aStep.GetPostStepPoint();
|
||||
if (postStepPoint->GetStepStatus()==fGeomBoundary) {
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
}
|
||||
|
||||
//Initialize particle change
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
//randomly generate a new direction and polarization state
|
||||
G4ThreeVector newDir = G4RandomDirection();
|
||||
G4int polarization = ChoosePolarization(theLattice->GetLDOS(),
|
||||
theLattice->GetSTDOS(),
|
||||
theLattice->GetFTDOS());
|
||||
|
||||
// Generate the new track after scattering
|
||||
// FIXME: If polarization state is the same, just step the track!
|
||||
G4Track* sec =
|
||||
CreateSecondary(polarization, newDir, aTrack.GetKineticEnergy());
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary(sec);
|
||||
|
||||
// Scattered phonon replaces current track
|
||||
aParticleChange.ProposeEnergy(0.);
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
return &aParticleChange;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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 processes/phonon/src/G4PhononTrackMap.hh
|
||||
/// \brief Implementation of the G4PhononTrackMap base class
|
||||
//
|
||||
// $Id: G4PhononTrackMap.cc 76503 2013-11-12 08:20:50Z gcosmo $
|
||||
//
|
||||
// 20131111 Move Clear() function to .cc file
|
||||
|
||||
#include "G4PhononTrackMap.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4Track.hh"
|
||||
#include <map>
|
||||
|
||||
namespace { const G4ThreeVector nullVec(0.,0.,0.); } // For convenience below
|
||||
|
||||
// Singleton instance, must be created at first request
|
||||
|
||||
G4ThreadLocal G4PhononTrackMap* G4PhononTrackMap::theTrackMap = 0;
|
||||
|
||||
|
||||
// Pseudo-constructor creates singleton instance
|
||||
|
||||
G4PhononTrackMap* G4PhononTrackMap::GetPhononTrackMap() {
|
||||
if (!theTrackMap) theTrackMap = new G4PhononTrackMap;
|
||||
return theTrackMap;
|
||||
}
|
||||
|
||||
void G4PhononTrackMap::Clear() {
|
||||
theMap.clear(); // Remove all entries from map
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Check if specified track is already loaded
|
||||
|
||||
G4bool G4PhononTrackMap::Find(const G4Track* track) const {
|
||||
return (!track || theMap.find(track) != theMap.end());
|
||||
}
|
||||
|
||||
|
||||
// Remove specified track from map (used by EndTracking)
|
||||
|
||||
void G4PhononTrackMap::RemoveTrack(const G4Track* track) {
|
||||
TrkIDKmap::iterator entry = theMap.find(track);
|
||||
if (entry != theMap.end()) theMap.erase(entry);
|
||||
}
|
||||
|
||||
|
||||
// Update the wavevector for specified track, add track if non-existent
|
||||
|
||||
void G4PhononTrackMap::SetK(const G4Track* track, const G4ThreeVector& K) {
|
||||
if (track) theMap[track] = K;
|
||||
}
|
||||
|
||||
|
||||
// Access current wavevector for specified track (NULL if doesn't exist)
|
||||
|
||||
const G4ThreeVector& G4PhononTrackMap::GetK(const G4Track* track) const {
|
||||
TrkIDKmap::const_iterator entry = theMap.find(track);
|
||||
return (entry != theMap.end()) ? entry->second : nullVec;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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 processes/phonon/src/G4VPhononProcess.cc
|
||||
/// \brief Implementation of the G4VPhononProcess base class
|
||||
//
|
||||
// $Id: G4VPhononProcess.cc 76885 2013-11-18 12:55:15Z gcosmo $
|
||||
//
|
||||
// 20131111 Add verbosity to report creating secondaries
|
||||
|
||||
#include "G4VPhononProcess.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ExceptionSeverity.hh"
|
||||
#include "G4LatticeManager.hh"
|
||||
#include "G4LatticePhysical.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4PhononLong.hh"
|
||||
#include "G4PhononPolarization.hh"
|
||||
#include "G4PhononTrackMap.hh"
|
||||
#include "G4PhononTransFast.hh"
|
||||
#include "G4PhononTransSlow.hh"
|
||||
#include "G4ProcessType.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4Track.hh"
|
||||
|
||||
namespace {
|
||||
const G4ThreeVector nullVec(0.,0.,0.); // For convenience below
|
||||
}
|
||||
|
||||
// Constructor and destructor
|
||||
|
||||
G4VPhononProcess::G4VPhononProcess(const G4String& processName)
|
||||
: G4VDiscreteProcess(processName, fPhonon),
|
||||
trackKmap(G4PhononTrackMap::GetInstance()), theLattice(0),
|
||||
currentTrack(0) {}
|
||||
|
||||
G4VPhononProcess::~G4VPhononProcess() {;}
|
||||
|
||||
|
||||
// Only applies to the known phonon polarization states
|
||||
|
||||
G4bool G4VPhononProcess::IsApplicable(const G4ParticleDefinition& aPD) {
|
||||
return (&aPD==G4PhononLong::Definition() ||
|
||||
&aPD==G4PhononTransFast::Definition() ||
|
||||
&aPD==G4PhononTransSlow::Definition() );
|
||||
}
|
||||
|
||||
|
||||
// Initialize wave vectors for currently active track(s)
|
||||
|
||||
void G4VPhononProcess::StartTracking(G4Track* track) {
|
||||
G4VProcess::StartTracking(track); // Apply base class actions
|
||||
|
||||
// FIXME: THE WAVEVECTOR SHOULD BE COMPUTED BY INVERTING THE K/V MAP
|
||||
if (!trackKmap->Find(track))
|
||||
trackKmap->SetK(track, track->GetMomentumDirection());
|
||||
|
||||
currentTrack = track; // Save for use by EndTracking
|
||||
|
||||
// Fetch lattice for current track once, use in subsequent steps
|
||||
G4LatticeManager* LM = G4LatticeManager::GetLatticeManager();
|
||||
theLattice = LM->GetLattice(track->GetVolume());
|
||||
}
|
||||
|
||||
void G4VPhononProcess::EndTracking() {
|
||||
G4VProcess::EndTracking(); // Apply base class actions
|
||||
trackKmap->RemoveTrack(currentTrack);
|
||||
currentTrack = 0;
|
||||
theLattice = 0;
|
||||
}
|
||||
|
||||
|
||||
// For convenience, map phonon type to polarization code
|
||||
|
||||
G4int G4VPhononProcess::GetPolarization(const G4Track& track) const {
|
||||
return G4PhononPolarization::Get(track.GetParticleDefinition());
|
||||
}
|
||||
|
||||
|
||||
// Generate random polarization from density of states
|
||||
|
||||
G4int G4VPhononProcess::ChoosePolarization(G4double Ldos, G4double STdos,
|
||||
G4double FTdos) const {
|
||||
G4double norm = Ldos + STdos + FTdos;
|
||||
G4double cProbST = STdos/norm;
|
||||
G4double cProbFT = FTdos/norm + cProbST;
|
||||
|
||||
// NOTE: Order of selection done to match previous random sequences
|
||||
G4double modeMixer = G4UniformRand();
|
||||
if (modeMixer<cProbST) return G4PhononPolarization::TransSlow;
|
||||
if (modeMixer<cProbFT) return G4PhononPolarization::TransFast;
|
||||
return G4PhononPolarization::Long;
|
||||
}
|
||||
|
||||
|
||||
// Create new secondary track from phonon configuration
|
||||
|
||||
G4Track* G4VPhononProcess::CreateSecondary(G4int polarization,
|
||||
const G4ThreeVector& waveVec,
|
||||
G4double energy) const {
|
||||
if (verboseLevel>1) {
|
||||
G4cout << GetProcessName() << " CreateSecondary pol " << polarization
|
||||
<< " K " << waveVec << " E " << energy << G4endl;
|
||||
}
|
||||
|
||||
G4ThreeVector vgroup = theLattice->MapKtoVDir(polarization, waveVec);
|
||||
if (verboseLevel>1) G4cout << " MapKtoVDir returned " << vgroup << G4endl;
|
||||
|
||||
vgroup = theLattice->RotateToGlobal(vgroup);
|
||||
if (verboseLevel>1) G4cout << " RotateToGlobal returned " << vgroup << G4endl;
|
||||
|
||||
if (verboseLevel && std::fabs(vgroup.mag()-1.) > 0.01) {
|
||||
G4cout << "WARNING: " << GetProcessName() << " vgroup not a unit vector: "
|
||||
<< vgroup << G4endl;
|
||||
}
|
||||
|
||||
G4ParticleDefinition* thePhonon = G4PhononPolarization::Get(polarization);
|
||||
|
||||
// Secondaries are created at the current track coordinates
|
||||
G4Track* sec = new G4Track(new G4DynamicParticle(thePhonon, vgroup, energy),
|
||||
currentTrack->GetGlobalTime(),
|
||||
currentTrack->GetPosition());
|
||||
|
||||
// Store wavevector in lookup table for future tracking
|
||||
trackKmap->SetK(sec, theLattice->RotateToGlobal(waveVec));
|
||||
|
||||
if (verboseLevel>1) {
|
||||
G4cout << GetProcessName() << " secondary K rotated to "
|
||||
<< trackKmap->GetK(sec) << G4endl;
|
||||
}
|
||||
|
||||
sec->SetVelocity(theLattice->MapKtoV(polarization, waveVec));
|
||||
sec->UseGivenVelocity(true);
|
||||
|
||||
return sec;
|
||||
}
|
||||
Reference in New Issue
Block a user