Import Geant4 10.0.0 source tree
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id$
|
||||
// $Id: G4DecayStrongResonances.cc 67984 2013-03-13 10:44:01Z gcosmo $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
@@ -51,8 +51,8 @@
|
||||
|
||||
G4Fancy3DNucleus::G4Fancy3DNucleus()
|
||||
: myA(0), myZ(0), theNucleons(250), currentNucleon(-1), theDensity(0),
|
||||
nucleondistance(0.8*fermi), places(250), momentum(250), fermiM(250),
|
||||
testSums(250)
|
||||
nucleondistance(0.8*fermi),excitationEnergy(0.),
|
||||
places(250), momentum(250), fermiM(250), testSums(250)
|
||||
{
|
||||
//G4cout <<"G4Fancy3DNucleus::G4Fancy3DNucleus()"<<G4endl;
|
||||
}
|
||||
@@ -81,6 +81,7 @@ void G4Fancy3DNucleus::Init(G4int theA, G4int theZ)
|
||||
|
||||
myZ = theZ;
|
||||
myA= theA;
|
||||
excitationEnergy=0;
|
||||
|
||||
theNucleons.resize(myA); // Pre-loads vector with empty elements
|
||||
|
||||
@@ -211,20 +212,24 @@ void G4Fancy3DNucleus::DoLorentzBoost(const G4ThreeVector & theBeta)
|
||||
|
||||
void G4Fancy3DNucleus::DoLorentzContraction(const G4ThreeVector & theBeta)
|
||||
{
|
||||
G4double factor=(1-std::sqrt(1-theBeta.mag2()))/theBeta.mag2(); // (gamma-1)/gamma/beta**2
|
||||
G4ThreeVector rprime;
|
||||
for (G4int i=0; i< myA; i++) {
|
||||
rprime = theNucleons[i].GetPosition() -
|
||||
factor * (theBeta*theNucleons[i].GetPosition()) * theBeta;
|
||||
theNucleons[i].SetPosition(rprime);
|
||||
G4double beta2=theBeta.mag2();
|
||||
if (beta2 > 0) {
|
||||
G4double factor=(1-std::sqrt(1-beta2))/beta2; // (gamma-1)/gamma/beta**2
|
||||
G4ThreeVector rprime;
|
||||
for (G4int i=0; i< myA; i++) {
|
||||
rprime = theNucleons[i].GetPosition() -
|
||||
factor * (theBeta*theNucleons[i].GetPosition()) * theBeta;
|
||||
theNucleons[i].SetPosition(rprime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G4Fancy3DNucleus::DoLorentzContraction(const G4LorentzVector & theBoost)
|
||||
{
|
||||
G4ThreeVector beta = theBoost.vect()/theBoost.e();
|
||||
// DoLorentzBoost(beta);
|
||||
DoLorentzContraction(beta);
|
||||
if (theBoost.e() !=0 ) {
|
||||
G4ThreeVector beta = theBoost.vect()/theBoost.e();
|
||||
DoLorentzContraction(beta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -283,7 +288,7 @@ void G4Fancy3DNucleus::ChoosePositions()
|
||||
G4int i=0;
|
||||
G4ThreeVector aPos, delta;
|
||||
G4bool freeplace;
|
||||
static G4double nd2 = sqr(nucleondistance);
|
||||
static G4ThreadLocal G4double *nd2_G4MT_TLS_ = 0 ; if (!nd2_G4MT_TLS_) {nd2_G4MT_TLS_ = new G4double ; *nd2_G4MT_TLS_= sqr(nucleondistance) ; } G4double &nd2 = *nd2_G4MT_TLS_;
|
||||
G4double maxR=GetNuclearRadius(0.001); // there are no nucleons at a
|
||||
// relative Density of 0.01
|
||||
G4int jr=0;
|
||||
@@ -300,7 +305,8 @@ void G4Fancy3DNucleus::ChoosePositions()
|
||||
if ( jr < 3 )
|
||||
{
|
||||
jr=std::min(600,9*(myA - i));
|
||||
CLHEP::RandFlat::shootArray(jr, prand );
|
||||
G4RandFlat::shootArray(jr,prand);
|
||||
//CLHEP::RandFlat::shootArray(jr, prand );
|
||||
}
|
||||
jx=--jr;
|
||||
jy=--jr;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id$
|
||||
// $Id: G4Fragment.cc 67984 2013-03-13 10:44:01Z gcosmo $
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
@@ -45,7 +45,7 @@
|
||||
#include "G4ios.hh"
|
||||
#include <iomanip>
|
||||
|
||||
G4int G4Fragment::errCount = 0;
|
||||
G4ThreadLocal G4int G4Fragment::errCount = 0;
|
||||
|
||||
// Default constructor
|
||||
G4Fragment::G4Fragment() :
|
||||
|
||||
@@ -24,8 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// $Id: G4GeneralSpaceDecay.cc,v 1.0 1998/05/21
|
||||
// $Id: G4GeneralPhaseSpaceDecay.cc 67984 2013-03-13 10:44:01Z gcosmo $
|
||||
// ----------------------------------------------------------------
|
||||
// GEANT 4 class header file
|
||||
//
|
||||
@@ -71,9 +70,9 @@ G4GeneralPhaseSpaceDecay::G4GeneralPhaseSpaceDecay(const G4String& theParentName
|
||||
if (GetVerboseLevel()>1) G4cout << "G4GeneralPhaseSpaceDecay:: constructor " << G4endl;
|
||||
|
||||
// Set the parent particle (resonance) mass to the (default) PDG vale
|
||||
if (parent != NULL)
|
||||
if (G4MT_parent != NULL)
|
||||
{
|
||||
parentmass = parent->GetPDGMass();
|
||||
parentmass = G4MT_parent->GetPDGMass();
|
||||
} else {
|
||||
parentmass=0.;
|
||||
}
|
||||
@@ -128,8 +127,8 @@ G4DecayProducts *G4GeneralPhaseSpaceDecay::DecayIt(G4double)
|
||||
if (GetVerboseLevel()>1) G4cout << "G4GeneralPhaseSpaceDecay::DecayIt ";
|
||||
G4DecayProducts * products = NULL;
|
||||
|
||||
if (parent == NULL) FillParent();
|
||||
if (daughters == NULL) FillDaughters();
|
||||
if (G4MT_parent == NULL) FillParent();
|
||||
if (G4MT_daughters == NULL) FillDaughters();
|
||||
|
||||
switch (numberOfDaughters){
|
||||
case 0:
|
||||
@@ -167,14 +166,14 @@ G4DecayProducts *G4GeneralPhaseSpaceDecay::OneBodyDecayIt()
|
||||
|
||||
//create parent G4DynamicParticle at rest
|
||||
G4ParticleMomentum dummy;
|
||||
G4DynamicParticle * parentparticle = new G4DynamicParticle(parent, dummy, 0.0);
|
||||
G4DynamicParticle * parentparticle = new G4DynamicParticle(G4MT_parent, dummy, 0.0);
|
||||
|
||||
//create G4Decayproducts
|
||||
G4DecayProducts *products = new G4DecayProducts(*parentparticle);
|
||||
delete parentparticle;
|
||||
|
||||
//create daughter G4DynamicParticle at rest
|
||||
G4DynamicParticle * daughterparticle = new G4DynamicParticle(daughters[0], dummy, 0.0);
|
||||
G4DynamicParticle * daughterparticle = new G4DynamicParticle(G4MT_daughters[0], dummy, 0.0);
|
||||
products->PushProducts(daughterparticle);
|
||||
|
||||
if (GetVerboseLevel()>1)
|
||||
@@ -198,15 +197,15 @@ G4DecayProducts *G4GeneralPhaseSpaceDecay::TwoBodyDecayIt()
|
||||
daughtermass[0]= *(theDaughterMasses);
|
||||
daughtermass[1] = *(theDaughterMasses+1);
|
||||
} else {
|
||||
daughtermass[0] = daughters[0]->GetPDGMass();
|
||||
daughtermass[1] = daughters[1]->GetPDGMass();
|
||||
daughtermass[0] = G4MT_daughters[0]->GetPDGMass();
|
||||
daughtermass[1] = G4MT_daughters[1]->GetPDGMass();
|
||||
}
|
||||
|
||||
// G4double sumofdaughtermass = daughtermass[0] + daughtermass[1];
|
||||
|
||||
//create parent G4DynamicParticle at rest
|
||||
G4ParticleMomentum dummy;
|
||||
G4DynamicParticle * parentparticle = new G4DynamicParticle( parent, dummy, 0.0);
|
||||
G4DynamicParticle * parentparticle = new G4DynamicParticle( G4MT_parent, dummy, 0.0);
|
||||
|
||||
//create G4Decayproducts @@GF why dummy parentparticle?
|
||||
G4DecayProducts *products = new G4DecayProducts(*parentparticle);
|
||||
@@ -221,10 +220,10 @@ G4DecayProducts *G4GeneralPhaseSpaceDecay::TwoBodyDecayIt()
|
||||
|
||||
//create daughter G4DynamicParticle
|
||||
G4double Etotal= std::sqrt(daughtermass[0]*daughtermass[0] + daughtermomentum*daughtermomentum);
|
||||
G4DynamicParticle * daughterparticle = new G4DynamicParticle( daughters[0],Etotal, direction*daughtermomentum);
|
||||
G4DynamicParticle * daughterparticle = new G4DynamicParticle( G4MT_daughters[0],Etotal, direction*daughtermomentum);
|
||||
products->PushProducts(daughterparticle);
|
||||
Etotal= std::sqrt(daughtermass[1]*daughtermass[1] + daughtermomentum*daughtermomentum);
|
||||
daughterparticle = new G4DynamicParticle( daughters[1],Etotal, direction*(-1.0*daughtermomentum));
|
||||
daughterparticle = new G4DynamicParticle( G4MT_daughters[1],Etotal, direction*(-1.0*daughtermomentum));
|
||||
products->PushProducts(daughterparticle);
|
||||
|
||||
if (GetVerboseLevel()>1)
|
||||
@@ -250,14 +249,14 @@ G4DecayProducts *G4GeneralPhaseSpaceDecay::ThreeBodyDecayIt()
|
||||
{
|
||||
daughtermass[index]= *(theDaughterMasses+index);
|
||||
} else {
|
||||
daughtermass[index] = daughters[index]->GetPDGMass();
|
||||
daughtermass[index] = G4MT_daughters[index]->GetPDGMass();
|
||||
}
|
||||
sumofdaughtermass += daughtermass[index];
|
||||
}
|
||||
|
||||
//create parent G4DynamicParticle at rest
|
||||
G4ParticleMomentum dummy;
|
||||
G4DynamicParticle * parentparticle = new G4DynamicParticle( parent, dummy, 0.0);
|
||||
G4DynamicParticle * parentparticle = new G4DynamicParticle( G4MT_parent, dummy, 0.0);
|
||||
|
||||
//create G4Decayproducts
|
||||
G4DecayProducts *products = new G4DecayProducts(*parentparticle);
|
||||
@@ -321,7 +320,7 @@ G4DecayProducts *G4GeneralPhaseSpaceDecay::ThreeBodyDecayIt()
|
||||
G4ParticleMomentum direction0(sintheta*cosphi,sintheta*sinphi,costheta);
|
||||
G4double Etotal=std::sqrt( daughtermass[0]*daughtermass[0] + daughtermomentum[0]*daughtermomentum[0]);
|
||||
G4DynamicParticle * daughterparticle
|
||||
= new G4DynamicParticle( daughters[0], Etotal, direction0*daughtermomentum[0]);
|
||||
= new G4DynamicParticle( G4MT_daughters[0], Etotal, direction0*daughtermomentum[0]);
|
||||
products->PushProducts(daughterparticle);
|
||||
|
||||
costhetan = (daughtermomentum[1]*daughtermomentum[1]-daughtermomentum[2]*daughtermomentum[2]-daughtermomentum[0]*daughtermomentum[0])/(2.0*daughtermomentum[2]*daughtermomentum[0]);
|
||||
@@ -334,12 +333,12 @@ G4DecayProducts *G4GeneralPhaseSpaceDecay::ThreeBodyDecayIt()
|
||||
direction2.setY( sinthetan*cosphin*costheta*sinphi + sinthetan*sinphin*cosphi + costhetan*sintheta*sinphi);
|
||||
direction2.setZ( -sinthetan*cosphin*sintheta + costhetan*costheta);
|
||||
Etotal=std::sqrt( daughtermass[2]*daughtermass[2] + daughtermomentum[2]*daughtermomentum[2]/direction2.mag2());
|
||||
daughterparticle = new G4DynamicParticle( daughters[2],Etotal, direction2*(daughtermomentum[2]/direction2.mag()));
|
||||
daughterparticle = new G4DynamicParticle( G4MT_daughters[2],Etotal, direction2*(daughtermomentum[2]/direction2.mag()));
|
||||
products->PushProducts(daughterparticle);
|
||||
G4ThreeVector mom=(direction0*daughtermomentum[0] + direction2*(daughtermomentum[2]/direction2.mag()))*(-1.0);
|
||||
Etotal= std::sqrt( daughtermass[1]*daughtermass[1] + mom.mag2() );
|
||||
daughterparticle =
|
||||
new G4DynamicParticle(daughters[1], Etotal, mom);
|
||||
new G4DynamicParticle(G4MT_daughters[1], Etotal, mom);
|
||||
products->PushProducts(daughterparticle);
|
||||
|
||||
if (GetVerboseLevel()>1) {
|
||||
@@ -370,7 +369,7 @@ G4DecayProducts *G4GeneralPhaseSpaceDecay::ManyBodyDecayIt()
|
||||
G4double *daughtermass = new G4double[numberOfDaughters];
|
||||
G4double sumofdaughtermass = 0.0;
|
||||
for (G4int index=0; index<numberOfDaughters; index++){
|
||||
daughtermass[index] = daughters[index]->GetPDGMass();
|
||||
daughtermass[index] = G4MT_daughters[index]->GetPDGMass();
|
||||
sumofdaughtermass += daughtermass[index];
|
||||
}
|
||||
|
||||
@@ -482,8 +481,8 @@ G4DecayProducts *G4GeneralPhaseSpaceDecay::ManyBodyDecayIt()
|
||||
direction.setZ(costheta);
|
||||
direction.setY(sintheta*std::sin(phi));
|
||||
direction.setX(sintheta*std::cos(phi));
|
||||
daughterparticle[index1] = new G4DynamicParticle( daughters[index1], direction*daughtermomentum[index1] );
|
||||
daughterparticle[index1+1] = new G4DynamicParticle( daughters[index1+1], direction*(-1.0*daughtermomentum[index1]) );
|
||||
daughterparticle[index1] = new G4DynamicParticle( G4MT_daughters[index1], direction*daughtermomentum[index1] );
|
||||
daughterparticle[index1+1] = new G4DynamicParticle( G4MT_daughters[index1+1], direction*(-1.0*daughtermomentum[index1]) );
|
||||
|
||||
for (index1 = numberOfDaughters -3; index1 >= 0; index1--) {
|
||||
//calculate momentum direction
|
||||
@@ -509,13 +508,13 @@ G4DecayProducts *G4GeneralPhaseSpaceDecay::ManyBodyDecayIt()
|
||||
daughterparticle[index2]->Set4Momentum(p4);
|
||||
}
|
||||
//create daughter G4DynamicParticle
|
||||
daughterparticle[index1]= new G4DynamicParticle( daughters[index1], direction*(-1.0*daughtermomentum[index1]));
|
||||
daughterparticle[index1]= new G4DynamicParticle( G4MT_daughters[index1], direction*(-1.0*daughtermomentum[index1]));
|
||||
}
|
||||
|
||||
//create G4Decayproducts
|
||||
G4DynamicParticle *parentparticle;
|
||||
direction.setX(1.0); direction.setY(0.0); direction.setZ(0.0);
|
||||
parentparticle = new G4DynamicParticle( parent, direction, 0.0);
|
||||
parentparticle = new G4DynamicParticle( G4MT_parent, direction, 0.0);
|
||||
products = new G4DecayProducts(*parentparticle);
|
||||
delete parentparticle;
|
||||
for (index1 = 0; index1<numberOfDaughters; index1++) {
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Multibody "phase space" generator, which provides multiple algorithms
|
||||
// for sampling. Momentum vectors are generated in the center-of-mass
|
||||
// frame of the decay, and returned in a user-supplied buffer. A sampling
|
||||
// algorithm is specified via constructor argument.
|
||||
//
|
||||
// Author: Michael Kelsey (SLAC) <kelsey@slac.stanford.edu>
|
||||
|
||||
#include "G4HadDecayGenerator.hh"
|
||||
#include "G4VHadDecayAlgorithm.hh"
|
||||
#include "G4HadPhaseSpaceKopylov.hh"
|
||||
#include "G4HadPhaseSpaceGenbod.hh"
|
||||
#include "G4HadPhaseSpaceNBodyAsai.hh"
|
||||
#include "G4HadronicException.hh"
|
||||
#include "G4LorentzVector.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "Randomize.hh"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <iterator>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
// Constructors and destructor
|
||||
|
||||
G4HadDecayGenerator::G4HadDecayGenerator(Algorithm alg, G4int verbose)
|
||||
: verboseLevel(verbose), theAlgorithm(0) {
|
||||
switch (alg) {
|
||||
case Kopylov: theAlgorithm = new G4HadPhaseSpaceKopylov(verboseLevel); break;
|
||||
case GENBOD: theAlgorithm = new G4HadPhaseSpaceGenbod(verboseLevel); break;
|
||||
case NBody: theAlgorithm = new G4HadPhaseSpaceNBodyAsai(verboseLevel); break;
|
||||
case NONE: theAlgorithm = 0; break; // User may explicitly set no algorithm
|
||||
default: ReportInvalidAlgorithm(alg);
|
||||
}
|
||||
|
||||
if (verboseLevel) {
|
||||
G4cout << " >>> G4HadDecayGenerator";
|
||||
if (theAlgorithm) G4cout << " using " << theAlgorithm->GetName();
|
||||
G4cout << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
G4HadDecayGenerator::G4HadDecayGenerator(G4VHadDecayAlgorithm* alg,
|
||||
G4int verbose)
|
||||
: verboseLevel(verbose), theAlgorithm(alg) {
|
||||
if (verboseLevel) {
|
||||
G4cout << " >>> G4HadDecayGenerator";
|
||||
if (theAlgorithm) G4cout << " using " << theAlgorithm->GetName();
|
||||
G4cout << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
G4HadDecayGenerator::~G4HadDecayGenerator() {
|
||||
delete theAlgorithm;
|
||||
theAlgorithm = 0;
|
||||
}
|
||||
|
||||
|
||||
// Sanity checks -- throws exception if no algorithm chosen
|
||||
|
||||
void G4HadDecayGenerator::ReportInvalidAlgorithm(Algorithm alg) const {
|
||||
if (verboseLevel)
|
||||
G4cerr << "G4HadDecayGenerator: bad algorithm code " << alg << G4endl;
|
||||
|
||||
throw G4HadronicException(__FILE__, __LINE__, "Invalid algorithm code");
|
||||
}
|
||||
|
||||
void G4HadDecayGenerator::ReportMissingAlgorithm() const {
|
||||
if (verboseLevel)
|
||||
G4cerr << "G4HadDecayGenerator: no algorithm specified" << G4endl;
|
||||
|
||||
throw G4HadronicException(__FILE__, __LINE__, "Null algorithm pointer");
|
||||
}
|
||||
|
||||
|
||||
// Enable (or disable if 0) diagnostic messages
|
||||
void G4HadDecayGenerator::SetVerboseLevel(G4int verbose) {
|
||||
verboseLevel = verbose;
|
||||
if (theAlgorithm) theAlgorithm->SetVerboseLevel(verbose);
|
||||
}
|
||||
|
||||
const G4String& G4HadDecayGenerator::GetAlgorithmName() const {
|
||||
static const G4String& none = "NONE";
|
||||
return (theAlgorithm ? theAlgorithm->GetName() : none);
|
||||
}
|
||||
|
||||
|
||||
// Initial state (rest mass) and list of final masses
|
||||
|
||||
G4bool
|
||||
G4HadDecayGenerator::Generate(G4double initialMass,
|
||||
const std::vector<G4double>& masses,
|
||||
std::vector<G4LorentzVector>& finalState) {
|
||||
if (verboseLevel)
|
||||
G4cout << " >>> G4HadDecayGenerator::Generate (mass)" << G4endl;
|
||||
|
||||
if (!theAlgorithm) ReportMissingAlgorithm();
|
||||
|
||||
if (masses.size() == 1U)
|
||||
return GenerateOneBody(initialMass, masses, finalState);
|
||||
|
||||
theAlgorithm->Generate(initialMass, masses, finalState);
|
||||
return !finalState.empty(); // Generator failure returns empty state
|
||||
}
|
||||
|
||||
// Initial state particle and list of final masses
|
||||
|
||||
G4bool
|
||||
G4HadDecayGenerator::Generate(const G4ParticleDefinition* initialPD,
|
||||
const std::vector<G4double>& masses,
|
||||
std::vector<G4LorentzVector>& finalState) {
|
||||
if (verboseLevel)
|
||||
G4cout << " >>> G4HadDecayGenerator::Generate (particle)" << G4endl;
|
||||
|
||||
return (initialPD && Generate(initialPD->GetPDGMass(), masses, finalState));
|
||||
}
|
||||
|
||||
// Final state particles will be boosted to initial-state frame
|
||||
|
||||
G4bool
|
||||
G4HadDecayGenerator::Generate(const G4LorentzVector& initialState,
|
||||
const std::vector<G4double>& masses,
|
||||
std::vector<G4LorentzVector>& finalState) {
|
||||
if (verboseLevel)
|
||||
G4cout << " >>> G4HadDecayGenerator::Generate (frame)" << G4endl;
|
||||
|
||||
G4bool good = Generate(initialState.m(), masses, finalState);
|
||||
if (good) {
|
||||
G4ThreeVector bv = initialState.boostVector();
|
||||
for (size_t i=0; i<finalState.size(); i++) {
|
||||
finalState[i].boost(bv);
|
||||
}
|
||||
}
|
||||
|
||||
return good;
|
||||
}
|
||||
|
||||
|
||||
// Handle special case of "one body decay" (used for kaon mixing)
|
||||
|
||||
G4bool G4HadDecayGenerator::
|
||||
GenerateOneBody(G4double initialMass,
|
||||
const std::vector<G4double>& masses,
|
||||
std::vector<G4LorentzVector>& finalState) const {
|
||||
if (verboseLevel>1)
|
||||
G4cout << " >>> G4HadDecayGenerator::GenerateOneBody" << G4endl;
|
||||
|
||||
// Initialization and sanity checks
|
||||
finalState.clear();
|
||||
|
||||
if (masses.size() != 1U) return false; // Should not have been called
|
||||
if (std::fabs(initialMass-masses[0]) > eV) return false;
|
||||
|
||||
if (verboseLevel>2) G4cout << " finalState mass = " << masses[0] << G4endl;
|
||||
|
||||
finalState.push_back(G4LorentzVector(0.,0.,0.,masses[0]));
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Multibody "phase space" generator using GENBOD (CERNLIB W515) method.
|
||||
//
|
||||
// Author: Michael Kelsey (SLAC) <kelsey@slac.stanford.edu>
|
||||
|
||||
#include "G4HadPhaseSpaceGenbod.hh"
|
||||
#include "G4LorentzVector.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "Randomize.hh"
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace {
|
||||
// Wrap #define in a true function, for passing to std::fill
|
||||
G4double uniformRand() { return G4UniformRand(); }
|
||||
}
|
||||
|
||||
|
||||
// Constructor initializes everything to zero
|
||||
|
||||
G4HadPhaseSpaceGenbod::G4HadPhaseSpaceGenbod(G4int verbose)
|
||||
: G4VHadPhaseSpaceAlgorithm("G4HadPhaseSpaceGenbod",verbose),
|
||||
nFinal(0), totalMass(0.), massExcess(0.), weightMax(0.), nTrials(0) {;}
|
||||
|
||||
|
||||
// C++ re-implementation of GENBOD.F (Raubold-Lynch method)
|
||||
|
||||
void G4HadPhaseSpaceGenbod::
|
||||
GenerateMultiBody(G4double initialMass,
|
||||
const std::vector<G4double>& masses,
|
||||
std::vector<G4LorentzVector>& finalState) {
|
||||
if (GetVerboseLevel()) G4cout << GetName() << "::GenerateMultiBody" << G4endl;
|
||||
|
||||
finalState.clear();
|
||||
|
||||
Initialize(initialMass, masses);
|
||||
|
||||
nTrials = 0;
|
||||
do { // Apply accept/reject to get distribution
|
||||
++nTrials;
|
||||
FillRandomBuffer();
|
||||
FillEnergySteps(initialMass, masses);
|
||||
} while (!AcceptEvent()); // FIXME: Do we need a limit on nTrials?
|
||||
|
||||
GenerateMomenta(masses, finalState);
|
||||
}
|
||||
|
||||
void G4HadPhaseSpaceGenbod::
|
||||
Initialize(G4double initialMass, const std::vector<G4double>& masses) {
|
||||
if (GetVerboseLevel()>1) G4cout << GetName() << "::Initialize" << G4endl;
|
||||
|
||||
nFinal = masses.size();
|
||||
msum.resize(nFinal, 0.); // Initialize buffers for filling
|
||||
msq.resize(nFinal, 0.);
|
||||
|
||||
std::partial_sum(masses.begin(), masses.end(), msum.begin());
|
||||
std::transform(masses.begin(), masses.end(), masses.begin(), msq.begin(),
|
||||
std::multiplies<G4double>());
|
||||
totalMass = msum.back();
|
||||
massExcess = initialMass - totalMass;
|
||||
|
||||
if (GetVerboseLevel()>2) {
|
||||
PrintVector(msum, "msum", G4cout);
|
||||
PrintVector(msq, "msq", G4cout);
|
||||
G4cout << " totalMass " << totalMass << " massExcess " << massExcess
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
ComputeWeightScale(masses);
|
||||
}
|
||||
|
||||
|
||||
// Generate ordered list of random numbers
|
||||
|
||||
void G4HadPhaseSpaceGenbod::FillRandomBuffer() {
|
||||
if (GetVerboseLevel()>1) G4cout << GetName() << "::FillRandomBuffer" << G4endl;
|
||||
|
||||
rndm.resize(nFinal-2,0.); // Final states generated in sorted order
|
||||
std::generate(rndm.begin(), rndm.end(), uniformRand);
|
||||
std::sort(rndm.begin(), rndm.end());
|
||||
if (GetVerboseLevel()>2) PrintVector(rndm, "rndm", G4cout);
|
||||
}
|
||||
|
||||
|
||||
// Final state effective masses, min to max
|
||||
|
||||
void
|
||||
G4HadPhaseSpaceGenbod::FillEnergySteps(G4double initialMass,
|
||||
const std::vector<G4double>& masses) {
|
||||
if (GetVerboseLevel()>1) G4cout << GetName() << "::FillEnergySteps" << G4endl;
|
||||
|
||||
meff.clear();
|
||||
pd.clear();
|
||||
|
||||
meff.push_back(masses[0]);
|
||||
for (size_t i=1; i<nFinal-1; i++) {
|
||||
meff.push_back(rndm[i-1]*massExcess + msum[i]);
|
||||
pd.push_back(TwoBodyMomentum(meff[i], meff[i-1], masses[i]));
|
||||
}
|
||||
meff.push_back(initialMass);
|
||||
pd.push_back(TwoBodyMomentum(meff[nFinal-1], meff[nFinal-2], masses[nFinal-1]));
|
||||
|
||||
if (GetVerboseLevel()>2) {
|
||||
PrintVector(meff,"meff",G4cout);
|
||||
PrintVector(pd,"pd",G4cout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Maximum possible weight for final state (used with accept/reject)
|
||||
|
||||
void
|
||||
G4HadPhaseSpaceGenbod::ComputeWeightScale(const std::vector<G4double>& masses) {
|
||||
if (GetVerboseLevel()>1)
|
||||
G4cout << GetName() << "::ComputeWeightScale" << G4endl;
|
||||
|
||||
weightMax = 1.;
|
||||
for (size_t i=1; i<nFinal; i++) {
|
||||
weightMax *= TwoBodyMomentum(massExcess+msum[i], msum[i-1], masses[i]);
|
||||
}
|
||||
|
||||
if (GetVerboseLevel()>2) G4cout << " weightMax = " << weightMax << G4endl;
|
||||
}
|
||||
|
||||
|
||||
// Event weight computed as either constant or Fermi-dependent cross-section
|
||||
|
||||
G4double G4HadPhaseSpaceGenbod::ComputeWeight() const {
|
||||
if (GetVerboseLevel()>1) G4cout << GetName() << "::ComputeWeight" << G4endl;
|
||||
|
||||
return (std::accumulate(pd.begin(), pd.end(), 1./weightMax,
|
||||
std::multiplies<G4double>()));
|
||||
}
|
||||
|
||||
G4bool G4HadPhaseSpaceGenbod::AcceptEvent() const {
|
||||
if (GetVerboseLevel()>1)
|
||||
G4cout << GetName() << "::AcceptEvent? " << nTrials << G4endl;
|
||||
|
||||
return (G4UniformRand() <= ComputeWeight());
|
||||
}
|
||||
|
||||
|
||||
// Final state momentum vectors in CMS system, using Raubold-Lynch method
|
||||
|
||||
void G4HadPhaseSpaceGenbod::
|
||||
GenerateMomenta(const std::vector<G4double>& masses,
|
||||
std::vector<G4LorentzVector>& finalState) {
|
||||
if (GetVerboseLevel()>1) G4cout << GetName() << "::GenerateMomenta" << G4endl;
|
||||
|
||||
finalState.resize(nFinal); // Preallocate vectors for convenience below
|
||||
|
||||
for (size_t i=0; i<nFinal; i++) {
|
||||
AccumulateFinalState(i, masses, finalState);
|
||||
if (GetVerboseLevel()>2)
|
||||
G4cout << " finalState[" << i << "] " << finalState[i] << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Process final state daughters up to current index
|
||||
|
||||
void G4HadPhaseSpaceGenbod::
|
||||
AccumulateFinalState(size_t i,
|
||||
const std::vector<G4double>& masses,
|
||||
std::vector<G4LorentzVector>& finalState) {
|
||||
if (GetVerboseLevel()>2)
|
||||
G4cout << GetName() << "::AccumulateFinalState " << i << G4endl;
|
||||
|
||||
if (i==0) { // First final state particle left alone
|
||||
finalState[i].setVectM(G4ThreeVector(0.,pd[i],0.),masses[i]);
|
||||
return;
|
||||
}
|
||||
|
||||
finalState[i].setVectM(G4ThreeVector(0.,-pd[i-1],0.),masses[i]);
|
||||
G4double phi = G4UniformRand() * twopi;
|
||||
G4double theta = std::acos(2.*G4UniformRand() - 1.);
|
||||
|
||||
if (GetVerboseLevel() > 2) {
|
||||
G4cout << " initialized Py " << -pd[i-1] << " phi " << phi
|
||||
<< " theta " << theta << G4endl;
|
||||
}
|
||||
|
||||
G4double esys=0.,beta=0.,gamma=1.;
|
||||
if (i < nFinal-1) { // Do not boost final particle
|
||||
esys = std::sqrt(pd[i]*pd[i]+meff[i]*meff[i]);
|
||||
beta = pd[i] / esys;
|
||||
gamma = esys / meff[i];
|
||||
|
||||
if (GetVerboseLevel()>2)
|
||||
G4cout << " esys " << esys << " beta " << beta << " gamma " << gamma
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
for (size_t j=0; j<=i; j++) { // Accumulate rotations
|
||||
finalState[j].rotateZ(theta).rotateY(phi);
|
||||
finalState[j].setY(gamma*(finalState[j].y() + beta*finalState[j].e()));
|
||||
if (GetVerboseLevel()>2) G4cout << " j " << j << " " << finalState[j] << G4endl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Multibody "phase space" generator using Kopylov's algorithm
|
||||
//
|
||||
// Author: Michael Kelsey (SLAC) <kelsey@slac.stanford.edu>
|
||||
|
||||
#include "G4HadPhaseSpaceKopylov.hh"
|
||||
#include "G4LorentzVector.hh"
|
||||
#include "G4Pow.hh"
|
||||
#include "Randomize.hh"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
// Generator
|
||||
|
||||
void G4HadPhaseSpaceKopylov::
|
||||
GenerateMultiBody(G4double initialMass,
|
||||
const std::vector<G4double>& masses,
|
||||
std::vector<G4LorentzVector>& finalState) {
|
||||
if (GetVerboseLevel()) G4cout << GetName() << "::GenerateMultiBody" << G4endl;
|
||||
|
||||
finalState.clear();
|
||||
|
||||
size_t N = masses.size();
|
||||
finalState.resize(N);
|
||||
|
||||
G4double mtot = std::accumulate(masses.begin(), masses.end(), 0.0);
|
||||
G4double mu = mtot;
|
||||
G4double PFragMagCM = 0.0;
|
||||
G4double Mass = initialMass;
|
||||
G4double T = Mass-mtot;
|
||||
G4LorentzVector PFragCM(0.0,0.0,0.0,0.0);
|
||||
G4LorentzVector PRestCM(0.0,0.0,0.0,0.0);
|
||||
G4LorentzVector PRestLab(0.0,0.0,0.0,Mass);
|
||||
|
||||
for (size_t k=N-1; k>0; --k) {
|
||||
mu -= masses[k];
|
||||
T *= (k>1) ? BetaKopylov(k) : 0.;
|
||||
|
||||
G4double RestMass = mu + T;
|
||||
|
||||
PFragMagCM = TwoBodyMomentum(Mass,masses[k],RestMass);
|
||||
|
||||
// Create a unit vector with a random direction isotropically distributed
|
||||
G4ThreeVector RandVector = UniformVector(PFragMagCM);
|
||||
|
||||
PFragCM.setVectM(RandVector,masses[k]);
|
||||
PRestCM.setVectM(-RandVector,RestMass);
|
||||
|
||||
G4ThreeVector BoostV = PRestLab.boostVector();
|
||||
|
||||
PFragCM.boost(BoostV);
|
||||
PRestCM.boost(BoostV);
|
||||
PRestLab = PRestCM;
|
||||
Mass = RestMass;
|
||||
finalState[k] = PFragCM;
|
||||
}
|
||||
|
||||
finalState[0] = PRestLab;
|
||||
}
|
||||
|
||||
|
||||
// Generate scale factor for final state particle
|
||||
|
||||
G4double G4HadPhaseSpaceKopylov::BetaKopylov(G4int K) const {
|
||||
G4Pow* g4pow = G4Pow::GetInstance();
|
||||
|
||||
G4int N = 3*K - 5;
|
||||
G4double xN = G4double(N);
|
||||
G4double Fmax = std::sqrt(g4pow->powN(xN/(xN+1.),N)/(xN+1.));
|
||||
|
||||
G4double F, chi;
|
||||
do {
|
||||
chi = G4UniformRand();
|
||||
F = std::sqrt(g4pow->powN(chi,N)*(1.-chi));
|
||||
} while ( Fmax*G4UniformRand() > F);
|
||||
return chi;
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Multibody "phase space" generator using Makoto Asai's NBody method.
|
||||
//
|
||||
// Author: Michael Kelsey (SLAC) <kelsey@slac.stanford.edu>
|
||||
|
||||
#include "G4HadPhaseSpaceNBodyAsai.hh"
|
||||
#include "G4LorentzVector.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "Randomize.hh"
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace {
|
||||
// This wraps the existing #define in a true function
|
||||
G4double uniformRand() { return G4UniformRand(); }
|
||||
}
|
||||
|
||||
|
||||
void G4HadPhaseSpaceNBodyAsai::
|
||||
GenerateMultiBody(G4double initialMass,
|
||||
const std::vector<G4double>& masses,
|
||||
std::vector<G4LorentzVector>& finalState) {
|
||||
if (GetVerboseLevel()) G4cout << GetName() << "::GenerateMultiBody" << G4endl;
|
||||
|
||||
finalState.clear();
|
||||
|
||||
//daughters' mass
|
||||
G4int numberOfDaughters = masses.size();
|
||||
G4double sumofmasses =
|
||||
std::accumulate(masses.begin(), masses.end(), 0.);
|
||||
|
||||
//Calculate daughter momentum
|
||||
std::vector<G4double> daughtermomentum(numberOfDaughters);
|
||||
std::vector<G4double> sm(numberOfDaughters);
|
||||
G4double tmas;
|
||||
G4double weight = 1.0;
|
||||
G4int numberOfTry = 0;
|
||||
G4int i;
|
||||
|
||||
std::vector<G4double> rd(numberOfDaughters);
|
||||
do {
|
||||
//Generate random number in descending order
|
||||
rd[0] = 1.0;
|
||||
std::generate(rd.begin()+1, rd.end(), uniformRand);
|
||||
std::sort(rd.begin(), rd.end(), std::greater<G4double>());
|
||||
|
||||
if (GetVerboseLevel()>1) PrintVector(rd,"rd",G4cout);
|
||||
|
||||
//calcurate virtual mass
|
||||
tmas = initialMass - sumofmasses;
|
||||
G4double temp = sumofmasses;
|
||||
for(i =0; i < numberOfDaughters; i++) {
|
||||
sm[i] = rd[i]*tmas + temp;
|
||||
temp -= masses[i];
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cout << i << " random number:" << rd[i]
|
||||
<< " virtual mass:" << sm[i]/GeV << " GeV/c2" <<G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//Calculate daughter momentum
|
||||
weight = 1.0;
|
||||
i = numberOfDaughters-1;
|
||||
daughtermomentum[i] = TwoBodyMomentum(sm[i-1],masses[i-1],sm[i]);
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cout << " daughter " << i << ": momentum "
|
||||
<< daughtermomentum[i]/GeV << " GeV/c" <<G4endl;
|
||||
}
|
||||
for(i =numberOfDaughters-2; i>=0; i--) {
|
||||
// calculate
|
||||
daughtermomentum[i] = TwoBodyMomentum(sm[i],masses[i],sm[i+1]);
|
||||
if(daughtermomentum[i] < 0.0) {
|
||||
// !!! illegal momentum !!!
|
||||
if (GetVerboseLevel()>0) {
|
||||
G4cout << "G4HadPhaseSpaceNBodyAsai::Generate "
|
||||
<< " can not calculate daughter momentum "
|
||||
<< "\n initialMass " << initialMass/GeV << " GeV/c2"
|
||||
<< "\n daughter " << i << ": mass "
|
||||
<< masses[i]/GeV << " GeV/c2; momentum "
|
||||
<< daughtermomentum[i]/GeV << " GeV/c" << G4endl;
|
||||
}
|
||||
return; // Error detection
|
||||
}
|
||||
|
||||
// calculate weight of this events
|
||||
weight *= daughtermomentum[i]/sm[i];
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cout << " daughter " << i << ": momentum "
|
||||
<< daughtermomentum[i]/GeV << " GeV/c" <<G4endl;
|
||||
}
|
||||
}
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cout << " weight: " << weight <<G4endl;
|
||||
}
|
||||
|
||||
// exit if number of Try exceeds 100
|
||||
if (numberOfTry++ > 100) {
|
||||
if (GetVerboseLevel()>0) {
|
||||
G4cout << "G4HadPhaseSpaceNBodyAsai::Generate "
|
||||
<< " can not determine Decay Kinematics " << G4endl;
|
||||
}
|
||||
return; // Error detection
|
||||
}
|
||||
} while (weight > G4UniformRand());
|
||||
|
||||
if (GetVerboseLevel()>1) {
|
||||
G4cout << "Start calulation of daughters momentum vector "<<G4endl;
|
||||
}
|
||||
|
||||
G4double beta;
|
||||
|
||||
finalState.resize(numberOfDaughters);
|
||||
|
||||
i = numberOfDaughters-2;
|
||||
|
||||
G4ThreeVector direction = UniformVector(daughtermomentum[i]);
|
||||
|
||||
finalState[i].setVectM(direction, masses[i]);
|
||||
finalState[i+1].setVectM(-direction, masses[i+1]);
|
||||
|
||||
for (i = numberOfDaughters-3; i >= 0; i--) {
|
||||
direction = UniformVector();
|
||||
|
||||
//create daughter particle
|
||||
finalState[i].setVectM(-daughtermomentum[i]*direction, masses[i]);
|
||||
|
||||
// boost already created particles
|
||||
beta = daughtermomentum[i];
|
||||
beta /= std::sqrt(beta*beta + sm[i+1]*sm[i+1]);
|
||||
for (G4int j = i+1; j<numberOfDaughters; j++) {
|
||||
finalState[j].boost(beta*direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@
|
||||
// Some static clobal for integration
|
||||
//
|
||||
|
||||
static G4double G4KineticTrack_Gmass, G4KineticTrack_xmass1;
|
||||
static G4ThreadLocal G4double G4KineticTrack_Gmass, G4KineticTrack_xmass1;
|
||||
|
||||
//
|
||||
// Default constructor
|
||||
|
||||
@@ -24,21 +24,18 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4NuclearFermiDensity.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
G4NuclearFermiDensity::G4NuclearFermiDensity(G4int anA, G4int aZ)
|
||||
: theA(anA), theZ(aZ), a(0.545 * fermi)
|
||||
G4NuclearFermiDensity::G4NuclearFermiDensity(G4int anA, G4int /*aZ*/)
|
||||
: theA(anA), a(0.545 * fermi)
|
||||
{
|
||||
// const G4double r0=1.14*fermi;
|
||||
const G4double r0=1.16 * ( 1. - 1.16 * std::pow(G4double(anA), -2./3.)) * fermi;
|
||||
theR= r0 * std::pow(anA, 1./3. );
|
||||
Setrho0(3./ (4. * pi * std::pow(r0,3.) * theA * ( 1. + sqr(a/theR)*pi2 )));
|
||||
const G4double r0 = 1.16 * (1. - 1.16 * std::pow(G4double(anA), -2./3.)) * fermi;
|
||||
theR = r0 * std::pow(anA, 1./3.);
|
||||
Setrho0(3./ (4.*pi * std::pow(r0,3.) * theA * (1. + sqr(a/theR)*pi2 )));
|
||||
}
|
||||
|
||||
G4NuclearFermiDensity::~G4NuclearFermiDensity() {}
|
||||
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
G4NuclearShellModelDensity::G4NuclearShellModelDensity(G4int anA, G4int aZ)
|
||||
: theA(anA), theZ(aZ)
|
||||
G4NuclearShellModelDensity::G4NuclearShellModelDensity(G4int anA, G4int /*aZ*/)
|
||||
: theA(anA)//, theZ(aZ)
|
||||
{
|
||||
const G4double r0sq=0.8133*fermi*fermi;
|
||||
theRsquare= r0sq * std::pow(G4double(theA), 2./3. );
|
||||
|
||||
@@ -41,10 +41,10 @@
|
||||
#include "Randomize.hh"
|
||||
#include "G4HadronicException.hh"
|
||||
|
||||
G4SampleResonance::minMassMapType G4SampleResonance::minMassCache;
|
||||
G4ThreadLocal G4SampleResonance::minMassMapType *G4SampleResonance::minMassCache_G4MT_TLS_ = 0;
|
||||
|
||||
G4double G4SampleResonance::GetMinimumMass(const G4ParticleDefinition* p) const
|
||||
{
|
||||
{ ;;; if (!minMassCache_G4MT_TLS_) minMassCache_G4MT_TLS_ = new G4SampleResonance::minMassMapType ; G4SampleResonance::minMassMapType &minMassCache = *minMassCache_G4MT_TLS_; ;;;
|
||||
|
||||
G4double minResonanceMass = DBL_MAX;
|
||||
|
||||
@@ -82,7 +82,9 @@ G4double G4SampleResonance::GetMinimumMass(const G4ParticleDefinition* p) const
|
||||
}
|
||||
// replace this as soon as the compiler supports mutable!!
|
||||
G4SampleResonance* self = const_cast<G4SampleResonance*>(this);
|
||||
(self->minMassCache)[p] = minResonanceMass;
|
||||
//Andrea Dotti (13Jan2013): Change needed for G4MT
|
||||
//(self->minMassCache)[p] = minResonanceMass;
|
||||
self->minMassCache_G4MT_TLS_->operator[](p) = minResonanceMass;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -100,7 +102,7 @@ G4double G4SampleResonance::GetMinimumMass(const G4ParticleDefinition* p) const
|
||||
|
||||
|
||||
G4double G4SampleResonance::SampleMass(const G4ParticleDefinition* p, const G4double maxMass) const
|
||||
{
|
||||
{ if (!minMassCache_G4MT_TLS_) minMassCache_G4MT_TLS_ = new G4SampleResonance::minMassMapType ;
|
||||
return SampleMass(p->GetPDGMass(), p->GetPDGWidth(), GetMinimumMass(p), maxMass);
|
||||
}
|
||||
|
||||
@@ -109,7 +111,7 @@ G4double G4SampleResonance::SampleMass(const G4double poleMass,
|
||||
const G4double gamma,
|
||||
const G4double minMass,
|
||||
const G4double maxMass) const
|
||||
{
|
||||
{ if (!minMassCache_G4MT_TLS_) minMassCache_G4MT_TLS_ = new G4SampleResonance::minMassMapType ;
|
||||
// Chooses a mass randomly between minMass and maxMass
|
||||
// according to a Breit-Wigner function with constant
|
||||
// width gamma and pole poleMass
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Abstract base class for multibody "phase space" generators. Subclasses
|
||||
// implement a specific algorithm, such as Kopylov, GENBOD, or Makoto's
|
||||
// NBody. Subclasses are used by G4HadPhaseSpaceGenerator.
|
||||
//
|
||||
// Author: Michael Kelsey (SLAC) <kelsey@slac.stanford.edu>
|
||||
|
||||
#include "G4VHadDecayAlgorithm.hh"
|
||||
#include "G4HadronicException.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "Randomize.hh"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
|
||||
|
||||
// Initial state (rest mass) and list of final masses
|
||||
|
||||
void G4VHadDecayAlgorithm::Generate(G4double initialMass,
|
||||
const std::vector<G4double>& masses,
|
||||
std::vector<G4LorentzVector>& finalState) {
|
||||
if (verboseLevel) G4cout << GetName() << "::Generate" << G4endl;
|
||||
|
||||
// Initialization and sanity check
|
||||
finalState.clear();
|
||||
if (!IsDecayAllowed(initialMass, masses)) return;
|
||||
|
||||
// Allow different procedures for two-body or N-body distributions
|
||||
if (masses.size() == 2U)
|
||||
GenerateTwoBody(initialMass, masses, finalState);
|
||||
else
|
||||
GenerateMultiBody(initialMass, masses, finalState);
|
||||
}
|
||||
|
||||
|
||||
// Base class does very simple validation of configuration
|
||||
|
||||
G4bool G4VHadDecayAlgorithm::
|
||||
IsDecayAllowed(G4double initialMass,
|
||||
const std::vector<G4double>& masses) const {
|
||||
G4bool okay =
|
||||
(initialMass > 0. && masses.size() >= 2 &&
|
||||
initialMass >= std::accumulate(masses.begin(),masses.end(),0.));
|
||||
|
||||
if (verboseLevel) {
|
||||
G4cout << GetName() << "::IsDecayAllowed? initialMass " << initialMass
|
||||
<< " " << masses.size() << " masses sum "
|
||||
<< std::accumulate(masses.begin(),masses.end(),0.) << G4endl;
|
||||
|
||||
if (verboseLevel>1) PrintVector(masses," ",G4cout);
|
||||
|
||||
G4cout << " Returning " << okay << G4endl;
|
||||
}
|
||||
|
||||
return okay;
|
||||
}
|
||||
|
||||
|
||||
// Momentum function (c.f. PDK() function from CERNLIB W515)
|
||||
|
||||
G4double G4VHadDecayAlgorithm::TwoBodyMomentum(G4double M0, G4double M1,
|
||||
G4double M2) const {
|
||||
G4double PSQ = (M0+M1+M2)*(M0+M1-M2)*(M0-M1+M2)*(M0-M1-M2);
|
||||
if (PSQ < 0.) {
|
||||
G4cout << GetName() << ": problem of decay of M(GeV) " << M0/GeV
|
||||
<< " to M1(GeV) " << M1/GeV << " and M2(GeV) " << M2/GeV
|
||||
<< " PSQ(MeV) " << PSQ/MeV << " < 0" << G4endl;
|
||||
// exception only if the problem is numerically significant
|
||||
if (PSQ < -CLHEP::eV) {
|
||||
throw G4HadronicException(__FILE__, __LINE__,"Error in decay kinematics");
|
||||
}
|
||||
|
||||
PSQ = 0.;
|
||||
}
|
||||
|
||||
return std::sqrt(PSQ)/(2.*M0);
|
||||
}
|
||||
|
||||
// Convenience functions for uniform angular distributions
|
||||
|
||||
G4double G4VHadDecayAlgorithm::UniformTheta() const {
|
||||
return std::acos(2.0*G4UniformRand() - 1.0);
|
||||
}
|
||||
|
||||
G4double G4VHadDecayAlgorithm::UniformPhi() const {
|
||||
return twopi*G4UniformRand();
|
||||
}
|
||||
|
||||
|
||||
// Dump contents of vector to output
|
||||
|
||||
void G4VHadDecayAlgorithm::
|
||||
PrintVector(const std::vector<G4double>& v,
|
||||
const G4String& vname, std::ostream& os) const {
|
||||
os << " " << vname << "(" << v.size() << ") ";
|
||||
std::copy(v.begin(), v.end(), std::ostream_iterator<G4double>(os, " "));
|
||||
os << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Abstract base class for multibody uniform phase space generators.
|
||||
// Subclasses implement a specific algorithm, such as Kopylov, GENBOD,
|
||||
// or Makoto's NBody. Subclasses are used by G4HadDecayGenerator.
|
||||
//
|
||||
// Author: Michael Kelsey (SLAC) <kelsey@slac.stanford.edu>
|
||||
|
||||
#include "G4VHadPhaseSpaceAlgorithm.hh"
|
||||
#include "G4HadronicException.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "Randomize.hh"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
||||
|
||||
// Two body decay with uniform angular distribution
|
||||
|
||||
void G4VHadPhaseSpaceAlgorithm::
|
||||
GenerateTwoBody(G4double initialMass,
|
||||
const std::vector<G4double>& masses,
|
||||
std::vector<G4LorentzVector>& finalState) {
|
||||
if (GetVerboseLevel()>1)
|
||||
G4cout << " >>> G4HadDecayGenerator::FillTwoBody" << G4endl;
|
||||
|
||||
// Initialization and sanity check
|
||||
finalState.clear();
|
||||
if (masses.size() != 2U) return; // Should not have been called
|
||||
|
||||
// Momentum of final state (energy balance has already been checked)
|
||||
G4double p = TwoBodyMomentum(initialMass,masses[0],masses[1]);
|
||||
if (GetVerboseLevel()>2) G4cout << " finalState momentum = " << p << G4endl;
|
||||
|
||||
finalState.resize(2); // Allows filling by index
|
||||
finalState[0].setVectM(UniformVector(p), masses[0]);
|
||||
finalState[1].setVectM(-finalState[0].vect(), masses[1]);
|
||||
}
|
||||
|
||||
|
||||
// Samples a random vector with given magnitude
|
||||
|
||||
G4ThreeVector G4VHadPhaseSpaceAlgorithm::UniformVector(G4double mag) const {
|
||||
// FIXME: Should this be made a static thread-local buffer?
|
||||
G4ThreeVector v;
|
||||
v.setRThetaPhi(mag, UniformTheta(), UniformPhi());
|
||||
return v;
|
||||
}
|
||||
Reference in New Issue
Block a user