Import Geant4 10.6.0 source tree
This commit is contained in:
@@ -14,6 +14,17 @@ code and to keep track of all tags.
|
||||
* Please list in reverse chronological order (last date on top)
|
||||
---------------------------------------------------------------
|
||||
|
||||
7 November 2019 Dennis Wright (hadr-casc-V10-05-02)
|
||||
-----------------------------------------------------
|
||||
- G4LightTargetCollider: fix crash when gamma energy below deuteron
|
||||
disintegration threshold and improve exception handling
|
||||
|
||||
5 November 2019 Dennis Wright (hadr-casc-V10-05-01)
|
||||
-----------------------------------------------------
|
||||
- new class G4LightTargetCollider to more accurately handle collisons
|
||||
on p, d, t, 3He. Currently only gamma on protons and deuterons is
|
||||
implemented.
|
||||
|
||||
29 May 2019 Dennis Wright (hadr-casc-V10-05-00)
|
||||
------------------------------------------------
|
||||
- fix bug found in biasing/B03 example due to FPE from unprotected sqrt
|
||||
|
||||
@@ -79,6 +79,7 @@ class G4CollisionOutput;
|
||||
class G4DynamicParticle;
|
||||
class G4HadFinalState;
|
||||
class G4InuclCollider;
|
||||
class G4LightTargetCollider;
|
||||
class G4InuclParticle;
|
||||
class G4ParticleDefinition;
|
||||
class G4V3DNucleus;
|
||||
@@ -166,6 +167,8 @@ private:
|
||||
G4InuclCollider* collider;
|
||||
G4CascadeCheckBalance* balance;
|
||||
|
||||
G4LightTargetCollider* ltcollider;
|
||||
|
||||
G4InuclParticle* bullet; // Pointers to last filled versions
|
||||
G4InuclParticle* target;
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: G4LightTargetCollider.hh //
|
||||
// Date: 30 September 2019 //
|
||||
// Author: Dennis Wright (SLAC) //
|
||||
// //
|
||||
// Description: model for collision of elementary particles with light //
|
||||
// targets (H, D, T, 3He) //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef G4LIGHT_TARGET_COLLIDER_HH
|
||||
#define G4LIGHT_TARGET_COLLIDER_HH
|
||||
|
||||
#include "G4CascadeColliderBase.hh"
|
||||
#include "G4CascadeFinalStateGenerator.hh"
|
||||
#include "G4CollisionOutput.hh"
|
||||
|
||||
class G4CascadParticle;
|
||||
class G4ElementaryParticleCollider;
|
||||
class G4InuclParticle;
|
||||
class G4KineticTrackVector;
|
||||
|
||||
typedef std::pair<G4InuclElementaryParticle, G4InuclElementaryParticle> NucleonPair;
|
||||
typedef std::vector<G4InuclElementaryParticle> ScatteringProducts;
|
||||
|
||||
class G4LightTargetCollider : public G4CascadeColliderBase {
|
||||
public:
|
||||
G4LightTargetCollider();
|
||||
virtual ~G4LightTargetCollider();
|
||||
|
||||
void collide(G4InuclParticle* bullet, G4InuclParticle* target,
|
||||
G4CollisionOutput& globalOutput);
|
||||
|
||||
void setVerboseLevel(G4int verbose=0);
|
||||
|
||||
private:
|
||||
G4ElementaryParticleCollider* theElementaryParticleCollider;
|
||||
|
||||
G4CollisionOutput output; // Secondaries from main cascade
|
||||
|
||||
private:
|
||||
// Copying of modules is forbidden
|
||||
G4LightTargetCollider(const G4LightTargetCollider&);
|
||||
G4LightTargetCollider& operator=(const G4LightTargetCollider&);
|
||||
|
||||
G4double GammaDCrossSection(G4double /*kineticEnergy*/);
|
||||
|
||||
G4CascadeFinalStateGenerator fsGen;
|
||||
|
||||
NucleonPair AbsorptionOnDeuteron(G4InuclParticle* bullet);
|
||||
|
||||
ScatteringProducts SingleNucleonScattering(const G4InuclElementaryParticle& projectile,
|
||||
const G4InuclElementaryParticle& targetNucleon);
|
||||
|
||||
G4double mP; // proton mass
|
||||
G4double mN; // neutron mass
|
||||
G4double mD; // deuteron mass
|
||||
G4double pFermiD; // deuteron Fermi momentum (GeV/c)
|
||||
};
|
||||
|
||||
#endif /* G4LIGHT_TARGET_COLLIDER_HH */
|
||||
|
||||
|
||||
@@ -161,6 +161,7 @@ GEANT4_DEFINE_MODULE(NAME G4hadronic_bert_cascade
|
||||
G4InteractionCase.hh
|
||||
G4IntraNucleiCascader.hh
|
||||
G4InuclCollider.hh
|
||||
G4LightTargetCollider.hh
|
||||
G4InuclElementaryParticle.hh
|
||||
G4InuclEvaporation.hh
|
||||
G4InuclNuclei.hh
|
||||
@@ -274,6 +275,7 @@ GEANT4_DEFINE_MODULE(NAME G4hadronic_bert_cascade
|
||||
G4InteractionCase.cc
|
||||
G4IntraNucleiCascader.cc
|
||||
G4InuclCollider.cc
|
||||
G4LightTargetCollider.cc
|
||||
G4InuclElementaryParticle.cc
|
||||
G4InuclEvaporation.cc
|
||||
G4InuclNuclei.cc
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4HadronicException.hh"
|
||||
#include "G4InuclCollider.hh"
|
||||
#include "G4LightTargetCollider.hh"
|
||||
#include "G4InuclElementaryParticle.hh"
|
||||
#include "G4InuclNuclei.hh"
|
||||
#include "G4InuclParticle.hh"
|
||||
@@ -143,11 +144,13 @@ typedef std::vector<G4InuclNuclei>::const_iterator nucleiIterator;
|
||||
// Constructor and destrutor
|
||||
|
||||
G4CascadeInterface::G4CascadeInterface(const G4String& name)
|
||||
: G4VIntraNuclearTransportModel(name),
|
||||
randomFile(G4CascadeParameters::randomFile()),
|
||||
maximumTries(20), numberOfTries(0),
|
||||
collider(new G4InuclCollider), balance(new G4CascadeCheckBalance(name)),
|
||||
bullet(0), target(0), output(new G4CollisionOutput) {
|
||||
: G4VIntraNuclearTransportModel(name),
|
||||
randomFile(G4CascadeParameters::randomFile()),
|
||||
maximumTries(20), numberOfTries(0),
|
||||
collider(new G4InuclCollider), balance(new G4CascadeCheckBalance(name)),
|
||||
ltcollider(new G4LightTargetCollider),
|
||||
bullet(0), target(0), output(new G4CollisionOutput)
|
||||
{
|
||||
// Set up global objects for master thread or sequential build
|
||||
if (G4Threading::IsMasterThread()) Initialize();
|
||||
|
||||
@@ -278,55 +281,71 @@ G4CascadeInterface::ApplyYourself(const G4HadProjectile& aTrack,
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
|
||||
// Make conversion between native Geant4 and Bertini cascade classes.
|
||||
if (!createBullet(aTrack)) {
|
||||
if (verboseLevel) G4cerr << " Unable to create usable bullet" << G4endl;
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
// If target A < 3 skip all cascade machinery and do scattering on
|
||||
// nucleons
|
||||
|
||||
if (!createTarget(theNucleus)) {
|
||||
if (verboseLevel) G4cerr << " Unable to create usable target" << G4endl;
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
|
||||
// Different retry conditions for proton target vs. nucleus
|
||||
const G4bool isHydrogen = (theNucleus.GetA_asInt() == 1);
|
||||
|
||||
numberOfTries = 0;
|
||||
do { // we try to create inelastic interaction
|
||||
if (verboseLevel > 1)
|
||||
G4cout << " Generating cascade attempt " << numberOfTries << G4endl;
|
||||
|
||||
if (aTrack.GetDefinition() == G4Gamma::Gamma() &&
|
||||
theNucleus.GetA_asInt() < 3) {
|
||||
output->reset();
|
||||
collider->collide(bullet, target, *output);
|
||||
balance->collide(bullet, target, *output);
|
||||
createBullet(aTrack);
|
||||
createTarget(theNucleus);
|
||||
// Due to binning, gamma-p cross sections between 130 MeV and the inelastic threshold
|
||||
// (144 for pi0 p, 152 for pi+ n) are non-zero, causing energy non-conservation
|
||||
// So, if Egamma is between 144 and 152, only pi0 p is allowed.
|
||||
|
||||
// Also, inelastic gamma-p cross section from G4PhotoNuclearCrossSection seems to be
|
||||
// non-zero below between pi0 mass (135 MeV) and threshold (144 MeV)
|
||||
ltcollider->collide(bullet, target, *output);
|
||||
|
||||
} else {
|
||||
|
||||
// Make conversion between native Geant4 and Bertini cascade classes.
|
||||
if (!createBullet(aTrack)) {
|
||||
if (verboseLevel) G4cerr << " Unable to create usable bullet" << G4endl;
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
|
||||
if (!createTarget(theNucleus)) {
|
||||
if (verboseLevel) G4cerr << " Unable to create usable target" << G4endl;
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
|
||||
// Different retry conditions for proton target vs. nucleus
|
||||
const G4bool isHydrogen = (theNucleus.GetA_asInt() == 1);
|
||||
|
||||
numberOfTries = 0;
|
||||
do { // we try to create inelastic interaction
|
||||
if (verboseLevel > 1)
|
||||
G4cout << " Generating cascade attempt " << numberOfTries << G4endl;
|
||||
|
||||
numberOfTries++;
|
||||
/* Loop checking 08.06.2015 MHK */
|
||||
} while ( isHydrogen ? retryInelasticProton() : retryInelasticNucleus() );
|
||||
output->reset();
|
||||
collider->collide(bullet, target, *output);
|
||||
balance->collide(bullet, target, *output);
|
||||
|
||||
numberOfTries++;
|
||||
/* Loop checking 08.06.2015 MHK */
|
||||
} while ( isHydrogen ? retryInelasticProton() : retryInelasticNucleus() );
|
||||
|
||||
// Null event if unsuccessful
|
||||
if (numberOfTries >= maximumTries) {
|
||||
if (verboseLevel)
|
||||
G4cout << " Cascade aborted after trials " << numberOfTries << G4endl;
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
// Null event if unsuccessful
|
||||
if (numberOfTries >= maximumTries) {
|
||||
if (verboseLevel)
|
||||
G4cout << " Cascade aborted after trials " << numberOfTries << G4endl;
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
|
||||
// Abort job if energy or momentum are not conserved
|
||||
if (!balance->okay()) {
|
||||
throwNonConservationFailure();
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
// Abort job if energy or momentum are not conserved
|
||||
if (!balance->okay()) {
|
||||
throwNonConservationFailure();
|
||||
return NoInteraction(aTrack, theNucleus);
|
||||
}
|
||||
|
||||
// Successful cascade -- clean up and return
|
||||
if (verboseLevel) {
|
||||
G4cout << " Cascade output after trials " << numberOfTries << G4endl;
|
||||
if (verboseLevel > 1) output->printCollisionOutput();
|
||||
}
|
||||
// Successful cascade -- clean up and return
|
||||
if (verboseLevel) {
|
||||
G4cout << " Cascade output after trials " << numberOfTries << G4endl;
|
||||
if (verboseLevel > 1) output->printCollisionOutput();
|
||||
}
|
||||
|
||||
// Rotate event to put Z axis along original projectile direction
|
||||
// Removed by DHW to fix bug #1990
|
||||
// output->rotateEvent(bulletInLabFrame);
|
||||
} // end cascade-style collisions
|
||||
|
||||
copyOutputToHadronicResult();
|
||||
|
||||
|
||||
@@ -84,27 +84,27 @@ const G4CascadeParameters* G4CascadeParameters::Instance() {
|
||||
//#define OLD_RADIUS_UNITS (3.3836/1.2) // Used with NucModel params
|
||||
|
||||
G4CascadeParameters::G4CascadeParameters()
|
||||
: G4CASCADE_VERBOSE(getenv("G4CASCADE_VERBOSE")),
|
||||
G4CASCADE_CHECK_ECONS(getenv("G4CASCADE_CHECK_ECONS")),
|
||||
G4CASCADE_USE_PRECOMPOUND(getenv("G4CASCADE_USE_PRECOMPOUND")),
|
||||
G4CASCADE_DO_COALESCENCE(getenv("G4CASCADE_DO_COALESCENCE")),
|
||||
G4CASCADE_SHOW_HISTORY(getenv("G4CASCADE_SHOW_HISTORY")),
|
||||
G4CASCADE_USE_3BODYMOM(getenv("G4CASCADE_USE_3BODYMOM")),
|
||||
G4CASCADE_USE_PHASESPACE(getenv("G4CASCADE_USE_PHASESPACE")),
|
||||
G4CASCADE_PIN_ABSORPTION(getenv("G4CASCADE_PIN_ABSORPTION")),
|
||||
G4CASCADE_RANDOM_FILE(getenv("G4CASCADE_RANDOM_FILE")),
|
||||
G4NUCMODEL_USE_BEST(getenv("G4NUCMODEL_USE_BEST")),
|
||||
G4NUCMODEL_RAD_2PAR(getenv("G4NUCMODEL_RAD_2PAR")),
|
||||
G4NUCMODEL_RAD_SCALE(getenv("G4NUCMODEL_RAD_SCALE")),
|
||||
G4NUCMODEL_RAD_SMALL(getenv("G4NUCMODEL_RAD_SMALL")),
|
||||
G4NUCMODEL_RAD_ALPHA(getenv("G4NUCMODEL_RAD_ALPHA")),
|
||||
G4NUCMODEL_RAD_TRAILING(getenv("G4NUCMODEL_RAD_TRAILING")),
|
||||
G4NUCMODEL_FERMI_SCALE(getenv("G4NUCMODEL_FERMI_SCALE")),
|
||||
G4NUCMODEL_XSEC_SCALE(getenv("G4NUCMODEL_XSEC_SCALE")),
|
||||
G4NUCMODEL_GAMMAQD(getenv("G4NUCMODEL_GAMMAQD")),
|
||||
DPMAX_2CLUSTER(getenv("DPMAX_2CLUSTER")),
|
||||
DPMAX_3CLUSTER(getenv("DPMAX_3CLUSTER")),
|
||||
DPMAX_4CLUSTER(getenv("DPMAX_4CLUSTER")),
|
||||
: G4CASCADE_VERBOSE(std::getenv("G4CASCADE_VERBOSE")),
|
||||
G4CASCADE_CHECK_ECONS(std::getenv("G4CASCADE_CHECK_ECONS")),
|
||||
G4CASCADE_USE_PRECOMPOUND(std::getenv("G4CASCADE_USE_PRECOMPOUND")),
|
||||
G4CASCADE_DO_COALESCENCE(std::getenv("G4CASCADE_DO_COALESCENCE")),
|
||||
G4CASCADE_SHOW_HISTORY(std::getenv("G4CASCADE_SHOW_HISTORY")),
|
||||
G4CASCADE_USE_3BODYMOM(std::getenv("G4CASCADE_USE_3BODYMOM")),
|
||||
G4CASCADE_USE_PHASESPACE(std::getenv("G4CASCADE_USE_PHASESPACE")),
|
||||
G4CASCADE_PIN_ABSORPTION(std::getenv("G4CASCADE_PIN_ABSORPTION")),
|
||||
G4CASCADE_RANDOM_FILE(std::getenv("G4CASCADE_RANDOM_FILE")),
|
||||
G4NUCMODEL_USE_BEST(std::getenv("G4NUCMODEL_USE_BEST")),
|
||||
G4NUCMODEL_RAD_2PAR(std::getenv("G4NUCMODEL_RAD_2PAR")),
|
||||
G4NUCMODEL_RAD_SCALE(std::getenv("G4NUCMODEL_RAD_SCALE")),
|
||||
G4NUCMODEL_RAD_SMALL(std::getenv("G4NUCMODEL_RAD_SMALL")),
|
||||
G4NUCMODEL_RAD_ALPHA(std::getenv("G4NUCMODEL_RAD_ALPHA")),
|
||||
G4NUCMODEL_RAD_TRAILING(std::getenv("G4NUCMODEL_RAD_TRAILING")),
|
||||
G4NUCMODEL_FERMI_SCALE(std::getenv("G4NUCMODEL_FERMI_SCALE")),
|
||||
G4NUCMODEL_XSEC_SCALE(std::getenv("G4NUCMODEL_XSEC_SCALE")),
|
||||
G4NUCMODEL_GAMMAQD(std::getenv("G4NUCMODEL_GAMMAQD")),
|
||||
DPMAX_2CLUSTER(std::getenv("DPMAX_2CLUSTER")),
|
||||
DPMAX_3CLUSTER(std::getenv("DPMAX_3CLUSTER")),
|
||||
DPMAX_4CLUSTER(std::getenv("DPMAX_4CLUSTER")),
|
||||
messenger(0) {
|
||||
messenger = new G4CascadeParamMessenger(this);
|
||||
Initialize();
|
||||
|
||||
@@ -246,7 +246,7 @@ void G4InuclCollider::collide(G4InuclParticle* bullet, G4InuclParticle* target,
|
||||
output.removeRecoilFragment();
|
||||
|
||||
//*** TEMPORARY, USE ENVVAR TO ENABLE/DISABLE THIS TEST ***
|
||||
if (getenv("G4CASCADE_CHECK_PHOTONUCLEAR"))
|
||||
if (std::getenv("G4CASCADE_CHECK_PHOTONUCLEAR"))
|
||||
if (!photonuclearOkay(output)) continue;
|
||||
|
||||
if (verboseLevel > 2)
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: G4LightTargetCollider.cc //
|
||||
// Date: 30 September 2019 //
|
||||
// Author: Dennis Wright (SLAC) //
|
||||
// //
|
||||
// Description: model for collision of elementary particles with light //
|
||||
// targets (H, D, T, 3He) //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "G4LightTargetCollider.hh"
|
||||
#include "G4CascadeChannel.hh"
|
||||
#include "G4CascadeChannelTables.hh"
|
||||
#include "G4CascadeCheckBalance.hh"
|
||||
#include "G4CollisionOutput.hh"
|
||||
#include "G4ElementaryParticleCollider.hh"
|
||||
#include "G4InuclElementaryParticle.hh"
|
||||
#include "G4InuclNuclei.hh"
|
||||
#include "G4NucleiModel.hh"
|
||||
#include "G4LorentzConvertor.hh"
|
||||
#include "G4Deuteron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4PionZero.hh"
|
||||
#include "G4PionPlus.hh"
|
||||
#include "G4PionMinus.hh"
|
||||
#include "G4RandomDirection.hh"
|
||||
|
||||
|
||||
G4LightTargetCollider::G4LightTargetCollider()
|
||||
: G4CascadeColliderBase("G4LightTargetCollider"),
|
||||
theElementaryParticleCollider(new G4ElementaryParticleCollider)
|
||||
{
|
||||
mP = G4Proton::Proton()->GetPDGMass()/CLHEP::GeV;
|
||||
mN = G4Neutron::Neutron()->GetPDGMass()/CLHEP::GeV;
|
||||
mD = G4Deuteron::Deuteron()->GetPDGMass()/CLHEP::GeV;
|
||||
pFermiD = 0.045; // Fermi momentum of nucleon in deuteron Hulthen potential
|
||||
}
|
||||
|
||||
G4LightTargetCollider::~G4LightTargetCollider() {
|
||||
delete theElementaryParticleCollider;
|
||||
}
|
||||
|
||||
|
||||
// Set verbosity and pass on to member objects
|
||||
void G4LightTargetCollider::setVerboseLevel(G4int verbose) {
|
||||
G4CascadeColliderBase::setVerboseLevel(verbose);
|
||||
theElementaryParticleCollider->setVerboseLevel(verboseLevel);
|
||||
output.setVerboseLevel(verboseLevel);
|
||||
}
|
||||
|
||||
|
||||
void G4LightTargetCollider::collide(G4InuclParticle* bullet,
|
||||
G4InuclParticle* target,
|
||||
G4CollisionOutput& globalOutput)
|
||||
{
|
||||
if (verboseLevel) {
|
||||
G4cout << " >>> G4LightTargetCollider::collide" << G4endl;
|
||||
G4cout << " Projectile: " << bullet->getDefinition()->GetParticleName() << G4endl;
|
||||
G4cout << " Target: " << target->getDefinition()->GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
// Particle-on-particle collision
|
||||
// No nucleus involved, just a proton in this case
|
||||
if (useEPCollider(bullet,target)) {
|
||||
if (verboseLevel > 2)
|
||||
G4cout << " InuclCollider -> particle on particle collision" << G4endl;
|
||||
|
||||
theElementaryParticleCollider->collide(bullet, target, globalOutput);
|
||||
return;
|
||||
}
|
||||
|
||||
G4double ke = bullet->getKineticEnergy();
|
||||
if (target->getDefinition() == G4Deuteron::Deuteron()) {
|
||||
|
||||
if (ke < mP + mN - mD) {
|
||||
// Should not happen as long as inelastic cross section is zero
|
||||
G4Exception("G4LightTargetCollider::collide()","HAD_BERT_201",
|
||||
JustWarning, "Projectile energy below reaction threshold");
|
||||
globalOutput.trivialise(bullet, target);
|
||||
|
||||
} else {
|
||||
// Get p, n and deuteron cross sections; use lab energy to access
|
||||
G4double gammaPXS = G4CascadeChannelTables::GetTable(9)->getCrossSection(ke);
|
||||
G4double gammaNXS = G4CascadeChannelTables::GetTable(18)->getCrossSection(ke);
|
||||
G4double gammaDXS = GammaDCrossSection(ke);
|
||||
|
||||
G4double probP = 0.0;
|
||||
G4double probN = 0.0;
|
||||
// Highest threshold is 0.152 (for gamma p -> n pi+)
|
||||
// Because of Fermi momentum in deuteron, raise this to 0.159
|
||||
if (ke > 0.159) {
|
||||
G4double totalDXS = gammaPXS + gammaNXS + gammaDXS;
|
||||
probP = gammaPXS/totalDXS;
|
||||
probN = (gammaPXS+gammaNXS)/totalDXS;
|
||||
}
|
||||
|
||||
G4double rndm = G4UniformRand();
|
||||
if (rndm < probP) {
|
||||
// Generate Fermi momenta of bullet and target
|
||||
G4ThreeVector fermiMomentum = pFermiD*G4RandomDirection();
|
||||
G4LorentzVector protonMomentum(fermiMomentum, std::sqrt(mP*mP + pFermiD*pFermiD) );
|
||||
G4LorentzVector neutronMomentum(-fermiMomentum, std::sqrt(mN*mN + pFermiD*pFermiD) );
|
||||
|
||||
G4LorentzVector bulletMomentum = bullet->getMomentum();
|
||||
G4ThreeVector betacm = bulletMomentum.findBoostToCM(protonMomentum);
|
||||
|
||||
// First boost bullet and target so that target is at rest
|
||||
G4ThreeVector toProtonRest = -protonMomentum.boostVector();
|
||||
protonMomentum.boost(toProtonRest);
|
||||
bulletMomentum.boost(toProtonRest);
|
||||
|
||||
G4InuclElementaryParticle projectile(bulletMomentum, bullet->getDefinition() );
|
||||
G4InuclElementaryParticle targetNucleon(protonMomentum, G4Proton::Proton() );
|
||||
G4InuclElementaryParticle spectatorNucleon(neutronMomentum, G4Neutron::Neutron() );
|
||||
ScatteringProducts products = SingleNucleonScattering(projectile, targetNucleon);
|
||||
|
||||
// Particles from SingleNucleonScattering are in CM frame of projectile
|
||||
// and moving proton. Transform back to lab frame with -betacm, then
|
||||
// add them to outgoing list.
|
||||
globalOutput.reset();
|
||||
G4LorentzVector temp;
|
||||
for (G4int i = 0; i < G4int(products.size()); i++) {
|
||||
temp = products[i].getMomentum();
|
||||
temp.boost(-betacm);
|
||||
products[i].setMomentum(temp);
|
||||
globalOutput.addOutgoingParticle(products[i]);
|
||||
}
|
||||
|
||||
// Add the recoil nucleon unmodified
|
||||
globalOutput.addOutgoingParticle(spectatorNucleon);
|
||||
|
||||
} else if (rndm < probN) {
|
||||
G4ThreeVector fermiMomentum = pFermiD*G4RandomDirection();
|
||||
G4LorentzVector protonMomentum(fermiMomentum, std::sqrt(mP*mP + pFermiD*pFermiD) );
|
||||
G4LorentzVector neutronMomentum(-fermiMomentum, std::sqrt(mN*mN + pFermiD*pFermiD) );
|
||||
|
||||
G4LorentzVector bulletMomentum = bullet->getMomentum();
|
||||
G4ThreeVector betacm = bulletMomentum.findBoostToCM(neutronMomentum);
|
||||
|
||||
// First boost bullet and target so that target is at rest
|
||||
G4ThreeVector toNeutronRest = -neutronMomentum.boostVector();
|
||||
neutronMomentum.boost(toNeutronRest);
|
||||
bulletMomentum.boost(toNeutronRest);
|
||||
|
||||
G4InuclElementaryParticle projectile(bulletMomentum, bullet->getDefinition() );
|
||||
G4InuclElementaryParticle targetNucleon(neutronMomentum, G4Neutron::Neutron() );
|
||||
G4InuclElementaryParticle spectatorNucleon(protonMomentum, G4Proton::Proton() );
|
||||
|
||||
ScatteringProducts products = SingleNucleonScattering(projectile, targetNucleon);
|
||||
|
||||
// Particles from SingleNucleonScattering are in CM frame of projectile
|
||||
// and moving neutron. Transform back to lab frame with -betacm, then add
|
||||
// them to outgoing list
|
||||
globalOutput.reset();
|
||||
G4LorentzVector temp;
|
||||
for (G4int i = 0; i < G4int(products.size()); i++) {
|
||||
temp = products[i].getMomentum();
|
||||
temp.boost(-betacm);
|
||||
products[i].setMomentum(temp);
|
||||
globalOutput.addOutgoingParticle(products[i]);
|
||||
}
|
||||
|
||||
// Add the recoil nucleon unmodified
|
||||
globalOutput.addOutgoingParticle(spectatorNucleon);
|
||||
|
||||
} else {
|
||||
NucleonPair products = AbsorptionOnDeuteron(bullet);
|
||||
globalOutput.reset();
|
||||
globalOutput.addOutgoingParticle(products.first);
|
||||
globalOutput.addOutgoingParticle(products.second);
|
||||
}
|
||||
} // Energy above threshold ?
|
||||
|
||||
// Test code
|
||||
// G4int numPart = globalOutput.numberOfOutgoingParticles();
|
||||
// std::vector<G4InuclElementaryParticle> testList = globalOutput.getOutgoingParticles();
|
||||
// G4LorentzVector sumP;
|
||||
// G4cout << " Global output " << G4endl;
|
||||
// for (G4int i = 0; i < numPart; i++) {
|
||||
// sumP += testList[i].getMomentum();
|
||||
// G4cout << testList[i] << G4endl;
|
||||
// }
|
||||
// G4cout << " Global 4-momentum sum = " << sumP << G4endl;
|
||||
// G4cout << " Initial lab energy = " << mD + bullet->getEnergy() << G4endl;
|
||||
|
||||
} else {
|
||||
G4Exception("G4LightTargetCollider::collide()","HAD_BERT_203",
|
||||
FatalException, "Scattering from this target not implemented");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
G4double G4LightTargetCollider::GammaDCrossSection(G4double gammaEnergy)
|
||||
{
|
||||
// Gamma deuteron cross section in mb parameterized from JLab data
|
||||
// No parameterization needed below pi0 threshold where cross section
|
||||
// is 100% disintegration
|
||||
G4double sigma = 1000.0;
|
||||
G4double term = 0.;
|
||||
if (gammaEnergy > 0.144 && gammaEnergy < 0.42) {
|
||||
term = (gammaEnergy - 0.24)/0.155;
|
||||
sigma = 0.065*std::exp(-term*term);
|
||||
} else if (gammaEnergy >= 0.42) {
|
||||
sigma = 0.000526/gammaEnergy/gammaEnergy/gammaEnergy/gammaEnergy;
|
||||
}
|
||||
|
||||
return sigma;
|
||||
}
|
||||
|
||||
|
||||
NucleonPair G4LightTargetCollider::AbsorptionOnDeuteron(G4InuclParticle* bullet)
|
||||
{
|
||||
// Do break-up in center of mass, convert to lab frame before returning
|
||||
// particles
|
||||
|
||||
G4double bulletMass = bullet->getMass();
|
||||
G4double bulletE = bullet->getEnergy();
|
||||
|
||||
G4double S = bulletMass*bulletMass + mD*mD + 2.*mD*bulletE;
|
||||
|
||||
G4double qcm = 0.;
|
||||
G4int outType1 = 0;
|
||||
G4int outType2 = 0;
|
||||
G4LorentzVector Mom1;
|
||||
G4LorentzVector Mom2;
|
||||
|
||||
// Set up outgoing particle types
|
||||
if (bullet->getDefinition() == G4Gamma::Gamma() ||
|
||||
bullet->getDefinition() == G4PionZero::PionZero() ) {
|
||||
qcm = std::sqrt( (S - (mP + mN)*(mP + mN)) * (S - (mP - mN)*(mP - mN))/S/4.);
|
||||
Mom1.setE(std::sqrt(mP*mP + qcm*qcm) );
|
||||
outType1 = G4InuclParticleNames::proton;
|
||||
Mom2.setE(std::sqrt(mN*mN + qcm*qcm) );
|
||||
outType2 = G4InuclParticleNames::neutron;
|
||||
|
||||
} else if (bullet->getDefinition() == G4PionPlus::PionPlus() ) {
|
||||
qcm = std::sqrt( (S - 4.*mP*mP)/4.);
|
||||
Mom1.setE(std::sqrt(mP*mP + qcm*qcm) );
|
||||
outType1 = G4InuclParticleNames::proton;
|
||||
Mom2.setE(std::sqrt(mP*mP + qcm*qcm) );
|
||||
outType2 = G4InuclParticleNames::proton;
|
||||
|
||||
} else if (bullet->getDefinition() == G4PionMinus::PionMinus() ) {
|
||||
qcm = std::sqrt( (S - 4.*mN*mN)/4.);
|
||||
Mom1.setE(std::sqrt(mN*mN + qcm*qcm) );
|
||||
outType1 = G4InuclParticleNames::neutron;
|
||||
Mom2.setE(std::sqrt(mN*mN + qcm*qcm) );
|
||||
outType2 = G4InuclParticleNames::neutron;
|
||||
|
||||
} else {
|
||||
G4Exception("G4LightTargetCollider::collide()","HAD_BERT_204",
|
||||
FatalException, "Illegal bullet type");
|
||||
}
|
||||
|
||||
// Sample angular distribution, assuming 100% S wave (no D-wave)
|
||||
G4ThreeVector qVect = qcm*G4RandomDirection();
|
||||
Mom1.setVect(qVect);
|
||||
Mom2.setVect(-qVect);
|
||||
|
||||
// Boost to lab frame
|
||||
G4ThreeVector betacm(0., 0., bullet->getMomModule()/(bulletE + mD) );
|
||||
Mom1.boost(betacm);
|
||||
Mom2.boost(betacm);
|
||||
|
||||
G4InuclElementaryParticle particle1(Mom1, outType1);
|
||||
G4InuclElementaryParticle particle2(Mom2, outType2);
|
||||
NucleonPair nucleon_pair(particle1, particle2);
|
||||
|
||||
// if pion, use parameterization of B.G. Ritchie, PRC 44, 533 (1991)
|
||||
// Total cross section: 1/E + Lorentzian
|
||||
|
||||
return nucleon_pair;
|
||||
}
|
||||
|
||||
|
||||
ScatteringProducts
|
||||
G4LightTargetCollider::SingleNucleonScattering(const G4InuclElementaryParticle& projectile,
|
||||
const G4InuclElementaryParticle& nucleon)
|
||||
{
|
||||
// At this point projectile and nucleon momenta are in nucleon rest frame
|
||||
G4int reactionIndex = G4InuclElementaryParticle::type(projectile.getDefinition() )
|
||||
* G4InuclElementaryParticle::type(nucleon.getDefinition() );
|
||||
|
||||
const G4CascadeChannel* xsecTable = G4CascadeChannelTables::GetTable(reactionIndex);
|
||||
G4double ke = projectile.getKineticEnergy();
|
||||
G4int mult = xsecTable->getMultiplicity(ke);
|
||||
|
||||
std::vector<G4double> masses;
|
||||
G4double mass = 0.0;
|
||||
G4LorentzVector totalMom = projectile.getMomentum() + nucleon.getMomentum();
|
||||
G4double Ecm = totalMom.mag();
|
||||
|
||||
std::vector<G4LorentzVector> cmMomenta;
|
||||
std::vector<G4int> particle_kinds;
|
||||
G4int itry = 0;
|
||||
G4int itry_max = 200;
|
||||
G4bool generate = true;
|
||||
|
||||
while (mult > 1) {
|
||||
itry = 0;
|
||||
generate = true;
|
||||
while (generate && itry < itry_max) {
|
||||
particle_kinds.clear();
|
||||
xsecTable->getOutgoingParticleTypes(particle_kinds, mult, ke);
|
||||
masses.clear();
|
||||
for (G4int i = 0; i < mult; i++) {
|
||||
mass = G4InuclElementaryParticle::getParticleMass(particle_kinds[i]);
|
||||
masses.push_back(mass);
|
||||
}
|
||||
|
||||
fsGen.Configure(const_cast<G4InuclElementaryParticle*>(&projectile),
|
||||
const_cast<G4InuclElementaryParticle*>(&nucleon),
|
||||
particle_kinds);
|
||||
// Generate final state in CM of projectile and at-rest nucleon
|
||||
cmMomenta.clear();
|
||||
generate = !fsGen.Generate(Ecm, masses, cmMomenta);
|
||||
itry++;
|
||||
} // while
|
||||
|
||||
if (itry == itry_max) mult--;
|
||||
else break;
|
||||
|
||||
} // while mult
|
||||
|
||||
ScatteringProducts finalState;
|
||||
if (mult < 2) {
|
||||
G4Exception("G4LightTargetCollider::SingleNucleonScattering()","HAD_BERT_202",
|
||||
JustWarning, "Failed to generate final state");
|
||||
// Final state particles not in CM - just using them as dummies
|
||||
finalState.push_back(projectile);
|
||||
finalState.push_back(nucleon);
|
||||
|
||||
} else {
|
||||
for (G4int i = 0; i < mult; i++) {
|
||||
G4InuclElementaryParticle fsPart(cmMomenta[i], particle_kinds[i]);
|
||||
finalState.push_back(fsPart);
|
||||
}
|
||||
}
|
||||
|
||||
return finalState;
|
||||
}
|
||||
Reference in New Issue
Block a user