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
@@ -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;
}