Import Geant4 10.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-10 11:51:14 +02:00
parent e2d2f9810a
commit 286caacf06
12421 changed files with 730077 additions and 502383 deletions
@@ -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;
}