Import Geant4 10.2.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-10 14:11:04 +02:00
parent c9b32a6c0a
commit d4af681f38
4886 changed files with 420149 additions and 1023309 deletions
@@ -1,4 +1,4 @@
# $Id: GNUmakefile 66793 2013-01-12 15:31:15Z gcosmo $
# $Id: GNUmakefile 87883 2015-01-16 10:21:34Z gcosmo $
# -----------------------------------------------------------
# GNUmakefile for hadronic library. Gabriele Cosmo, 18/9/96.
# -----------------------------------------------------------
@@ -19,10 +19,12 @@ CPPFLAGS += -I$(G4BASE)/global/management/include \
-I$(G4BASE)/intercoms/include \
-I$(G4BASE)/geometry/volumes/include \
-I$(G4BASE)/geometry/management/include \
-I$(G4BASE)/materials/include \
-I$(G4BASE)/processes/cuts/include \
-I$(G4BASE)/processes/management/include \
-I$(G4BASE)/processes/electromagnetic/utils/include/ \
-I$(G4BASE)/processes/hadronic/management/include/ \
-I$(G4BASE)/processes/electromagnetic/lowenergy/include \
-I$(G4BASE)/processes/electromagnetic/utils/include \
-I$(G4BASE)/processes/hadronic/management/include \
-I$(G4BASE)/processes/hadronic/util/include \
-I$(G4BASE)/processes/hadronic/processes/include \
-I$(G4BASE)/processes/hadronic/cross_sections/include \
@@ -30,13 +32,11 @@ CPPFLAGS += -I$(G4BASE)/global/management/include \
-I$(G4BASE)/processes/hadronic/models/de_excitation/management/include \
-I$(G4BASE)/processes/hadronic/models/de_excitation/util/include \
-I$(G4BASE)/processes/hadronic/models/util/include \
-I$(G4BASE)/processes/hadronic/management/include \
-I$(G4BASE)/particles/management/include \
-I$(G4BASE)/particles/leptons/include \
-I$(G4BASE)/particles/bosons/include \
-I$(G4BASE)/particles/hadrons/mesons/include \
-I$(G4BASE)/particles/hadrons/barions/include \
-I$(G4BASE)/particles/hadrons/ions/include \
-I$(G4BASE)/materials/include
-I$(G4BASE)/particles/hadrons/ions/include
include $(G4INSTALL)/config/common.gmk
@@ -14,6 +14,138 @@ track of all tags.
* Reverse chronological order (last date on top), please *
---------------------------------------------------------
18 November 2015 Dennis Wright radioactive_decay-V10-01-23
-----------------------------------------------------------
- use method proposed by Andreas Zoglauer to temporarily fix energy
non-conservation in IT and EC modes due to incomplete atomic relaxation
model. Fixes bug #1756.
12 November 2015 Dennis Wright radioactive_decay-V10-01-22
-----------------------------------------------------------
- G4RadioactiveDecay::DoDecay() : pass parent mass + 30 MeV to
G4DecayTable::SelectADecayChannel in order to account for difference in
mass defects between parent and daughter. This fixes bug #1793.
29 October 2015 Dennis Wright radioactive_decay-V10-01-21
----------------------------------------------------------
- remove obsolete class G4BetaFermiFunction and references to it in
sources.cmake, G4NuclearDecayChannel. Addresses bug report 1785.
21 October 2015 Luis Sarmiento radioactive_decay-V10-01-20
----------------------------------------------------------
- G4NeutronDecay added to work with the "Neutron" key in the radfiles
9 October 2015 Dennis Wright radioactive_decay-V10-01-19
---------------------------------------------------------
- G4ITDecay.cc: fix memory leak of G4Fragment* nucleus, G4Fragment* eOrGamma
from Bug Report #1787
22 September 2015 Dennis Wright radioactive_decay-V10-01-18
------------------------------------------------------------
- G4RIsotopeTable: add object name in ctor
- G4RadioactiveDecay: remove G4RIsotopeTable (now redundant) and all associated
pointers
8 September 2015 Luis Sarmiento radioactive_decay-V10-01-17
-----------------------------------------------------------
- G4ProtonDecay linking problem fixed.
8 September 2015 Luis Sarmiento radioactive_decay-V10-01-16
-----------------------------------------------------------
- Changed G4ProtonDecayChannel by G4ProtonDecay
1 September 2015 Dennis Wright radioactive_decay-V10-01-15
-----------------------------------------------------------
- G4RIsotopeTable.cc, G4NuclearDecayChannel.cc, G4BetaDecayCorrections.cc,
G4RadioactiveDecay.cc: add temporary checks on while loops
30 July 2015 S Incerti, V Iv. radioactive_decay-V10-01-14
---------------------------------------------------------
- Fixing Bugzilla #1727
13 July 2015 A Dotti radioactive_decay-V10-01-13
----------------------------------------------------
- Fixing coverity issues #60965 #60966
22 May 2015 L Desorgher radioactive_decay-V10-01-12
----------------------------------------------------
- G4ECDecay use of daughter atom instead of parent atom when calling atomic relaxation
13 April 2015 Dennis Wright radioactive_decay-V10-01-11
--------------------------------------------------------
- G4RadioactivedDecay::LoadDecayTable : implement Laurent's changes back to
level search using tolerance (now 0.1 keV)
- G4RadioactivedDecay::AddDecayTable : bug fix in combination of branching
ratios (brs[1] -> brs[2] in beta+ decay)
10 March 2015 Dennis Wright radioactive_decay-V10-01-10
--------------------------------------------------------
- re-enable setting of ARM on or off (default is on) in G4ITDecay and
G4ECDecay
- also include Michel Maire's change from 5 March
05 March 2015 Michel Maire
--------------------------
- G4RadioactiveDecay::BuildPhysicsTable() : add p->SetAuger(true)
27 February 2015 Dennis Wright radioactive_decay-V10-01-09
-----------------------------------------------------------
- improved efficiency of neutrino energy sectrum calculation in
G4BetaPlusDecay and G4BetaMinusDecay
- use Q value and electron binding energy to calculate CM momentum
in G4ECDecay
11 February 2015 Andrea Dotti radioactive_decay-V10-01-08
-----------------------------------------------------------
- Temporary removing sharing of decay table map between
threads to verify if failures in MT disappear
29 January 2015 Dennis Wright radioactive_decay-V10-01-07
-----------------------------------------------------------
- put autolock on new of master decay map
27 January 2015 Dennis Wright radioactive_decay-V10-01-06
-----------------------------------------------------------
-G4BetaMinusDecay::DecayIt: fix FPE error in sqrt
-G4BetaPlusDecay::DecayIt: fix possible FPE error in sqrt
22 January 2015 Dennis Wright radioactive_decay-V10-01-05
-----------------------------------------------------------
- G4BetaMinusDecay.cc: fix divide by zero neutrino energy
- G4BetaPlusDecay.cc: fix zero pointer for spectrumSampler
16 January 2015 Gabriele Cosmo radioactive_decay-V10-01-04
------------------------------------------------------------
- Corrected GNUmakefile and sources.cmake scripts to add missing dependency
on electromagnetic/lowenergy module.
15 January 2015 Dennis Wright radioactive_decay-V10-01-03
-----------------------------------------------------------
- G4RadioactiveDecay::BuildPhysicsTable: change code to create new atomic
deexcitation only if one doesn't already exist
- G4ECDecay.cc: re-install check for zero pointer to atomic deexcitation
12 January 2015 Dennis Wright radioactive_decay-V10-01-02
-----------------------------------------------------------
- G4RadioactiveDecay::BuildPhysicsTable : register G4UAtomicDeexcitation to
G4LossTableManager so that electron shells can be found. Set Fluo and
Auger flags to true, PIXE to false
- G4ECDecay.cc: re-arrange code to accommodate above change
19 December 2014 Dennis Wright radioactive_decay-V10-01-01
-----------------------------------------------------------
- use G4NuclearDecay as the new base class for all the decay channels. This
replaces G4NuclearDecayChannel
- all decay channels (G4AlphaDecay, G4BetaMinusDecay, G4BetaPlusDecay,
G4ITDecay and G4ECDecay) modified to use new base class
- G4NuclearDecayChannel removed from G4RadioactiveDecay
08 December 2014 Dennis Wright radioactive_decay-V10-01-00
----------------------------------------------------------
- added new classes G4BetaMinusDecay, G4BetaPlusDecay, G4ECDecay and G4ITDecay
to streamline inheritance chain and reduce non-reproducibility
06 November 2014 Dennis Wright radioactive_decay-V10-00-11
----------------------------------------------------------
- G4NuclearDecayChannel: remove upper limit on number of gammas produced by
@@ -36,31 +36,24 @@
#ifndef G4AlphaDecay_h
#define G4AlphaDecay_h 1
#include "G4VDecayChannel.hh"
#include "G4NuclearDecay.hh"
class G4AlphaDecay : public G4VDecayChannel
class G4AlphaDecay : public G4NuclearDecay
{
public:
G4AlphaDecay(const G4ParticleDefinition* theParentNucleus,
const G4double& theBR, const G4double& Qvalue,
const G4double& excitation);
G4AlphaDecay(const G4AlphaDecay&);
~G4AlphaDecay();
virtual ~G4AlphaDecay();
virtual G4DecayProducts* DecayIt(G4double);
void SetHLThreshold(G4double HLT) {halflifeThreshold = HLT;}
G4double GetHLThreshold() {return halflifeThreshold;}
void DumpInfo();
virtual void DumpNuclearInfo();
private:
const G4double transitionQ;
const G4double daughterEx;
G4double halflifeThreshold; // for variance reduction mode
};
#endif
@@ -0,0 +1,65 @@
//
// ********************************************************************
// * 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: G4BetaMinusDecay.hh //
// Author: D.H. Wright (SLAC) //
// Date: 25 October 2014 //
// Description: performs beta- decay of radioactive nuclei, and returns //
// daughter particles in rest frame of parent nucleus //
// //
////////////////////////////////////////////////////////////////////////////////
#ifndef G4BetaMinusDecay_h
#define G4BetaMinusDecay_h 1
#include "G4NuclearDecay.hh"
#include "G4BetaDecayType.hh"
#include "Randomize.hh"
class G4BetaMinusDecay : public G4NuclearDecay
{
public:
G4BetaMinusDecay(const G4ParticleDefinition* theParentNucleus,
const G4double& theBR, const G4double& endpointE,
const G4double& ex, const G4BetaDecayType& type);
virtual ~G4BetaMinusDecay();
virtual G4DecayProducts* DecayIt(G4double);
virtual void DumpNuclearInfo();
private:
void SetUpBetaSpectrumSampler(const G4int& parentZ, const G4int& parentA,
const G4BetaDecayType& type);
const G4double endpointEnergy;
G4RandGeneral* spectrumSampler;
};
#endif
@@ -0,0 +1,65 @@
//
// ********************************************************************
// * 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: G4BetaPlusDecay.hh //
// Author: D.H. Wright (SLAC) //
// Date: 14 November 2014 //
// Description: performs beta+ decay of radioactive nuclei, and returns //
// daughter particles in rest frame of parent nucleus //
// //
////////////////////////////////////////////////////////////////////////////////
#ifndef G4BetaPlusDecay_h
#define G4BetaPlusDecay_h 1
#include "G4NuclearDecay.hh"
#include "G4BetaDecayType.hh"
#include "Randomize.hh"
class G4BetaPlusDecay : public G4NuclearDecay
{
public:
G4BetaPlusDecay(const G4ParticleDefinition* theParentNucleus,
const G4double& theBR, const G4double& endpointE,
const G4double& ex, const G4BetaDecayType& type);
virtual ~G4BetaPlusDecay();
virtual G4DecayProducts* DecayIt(G4double);
virtual void DumpNuclearInfo();
private:
void SetUpBetaSpectrumSampler(const G4int& parentZ, const G4int& parentA,
const G4BetaDecayType& type);
const G4double endpointEnergy;
G4RandGeneral* spectrumSampler;
};
#endif
@@ -23,64 +23,40 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
#ifndef G4BetaFermiFunction_h
#define G4BetaFermiFunction_h 1
////////////////////////////////////////////////////////////////////////////////
// //
// File: G4ECDecay.hh //
// Author: D.H. Wright (SLAC) //
// Date: 25 November 2014 //
// Description: performs electron capture decay of radioactive nuclei, and //
// returns daughter particles in rest frame of parent nucleus //
// //
////////////////////////////////////////////////////////////////////////////////
#include "globals.hh"
#ifndef G4ECDecay_h
#define G4ECDecay_h 1
class G4BetaFermiFunction
#include "G4NuclearDecay.hh"
class G4ECDecay : public G4NuclearDecay
{
// class description
// It is to calculate the Coulomb correction to beta particles
//
public:
G4ECDecay(const G4ParticleDefinition* theParentNucleus,
const G4double& theBR, const G4double& Qvalue,
const G4double& excitation, const G4RadioactiveDecayMode& mode);
public: // with description
G4BetaFermiFunction(G4int const fA, G4int const fZ) :
A(fA), Z(fZ)
{};
// constructor: fA the daughter nucleus mass.
// fZ the daughter nucleus charge. Negative value for
// beta+ decays.
//
~G4BetaFermiFunction()
// desctructor
//
{};
G4double GetFF(const G4double E);
// Returns the BetaFermi factor at energy E.
// E kinetic energy of the beta particle in unit of Me.
//
G4double GetFFN(const G4double E0);
// Returns the BetaFermi factor normalisation, i.e. the maximum
// value for beta decay with end-point energy E0.
// E0 dose not including beta particle rest mass in unit
// of Me.
//
private:
virtual ~G4ECDecay();
G4int A;
G4int Z;
static const G4double PI;
virtual G4DecayProducts* DecayIt(G4double);
private:
virtual void DumpNuclearInfo();
G4double Gamma(G4double X);
void SetARM(G4bool onoff) {applyARM = onoff;}
private:
const G4double transitionQ;
G4bool applyARM;
};
#endif
@@ -0,0 +1,69 @@
//
// ********************************************************************
// * 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: G4ITDecay.hh //
// Author: D.H. Wright (SLAC) //
// Date: 14 November 2014 //
// Description: performs isomeric transition for excited states of //
// radioactive nuclei by emitting gammas or internal conversion //
// electrons, and returns daughter particles the rest frame //
// of the parent nucleus //
// //
////////////////////////////////////////////////////////////////////////////////
#ifndef G4ITDecay_h
#define G4ITDecay_h 1
#include "G4NuclearDecay.hh"
class G4PhotonEvaporation;
class G4ITDecay : public G4NuclearDecay
{
public:
G4ITDecay(const G4ParticleDefinition* theParentNucleus,
const G4double& theBR, const G4double& Qvalue,
const G4double& excitation);
virtual ~G4ITDecay();
virtual G4DecayProducts* DecayIt(G4double);
virtual void DumpNuclearInfo();
void SetARM(G4bool onoff) {applyARM = onoff;}
private:
const G4double transitionQ;
G4int parentZ;
G4int parentA;
G4bool applyARM;
};
#endif
@@ -0,0 +1,61 @@
//
// ********************************************************************
// * 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: G4NeutronDecay.hh //
// Author: L.G. Sarmiento (Lund) //
// Date: 10 October 2015 //
// Description: performs protom emission from radioactive nuclei, and //
// returns daughter particles in rest frame of parent nucleus //
// //
// This class is created based on G4AlphaDecay //
// //
////////////////////////////////////////////////////////////////////////////////
#ifndef G4NeutronDecay_h
#define G4NeutronDecay_h 1
#include "G4NuclearDecay.hh"
class G4NeutronDecay : public G4NuclearDecay
{
public:
G4NeutronDecay(const G4ParticleDefinition* theParentNucleus,
const G4double& theBR, const G4double& Qvalue,
const G4double& excitation);
virtual ~G4NeutronDecay();
virtual G4DecayProducts* DecayIt(G4double);
virtual void DumpNuclearInfo();
private:
const G4double transitionQ;
};
#endif
@@ -0,0 +1,71 @@
//
// ********************************************************************
// * 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: G4NuclearDecay.hh //
// Author: D.H. Wright (SLAC) //
// Date: 11 December 2014 //
// Description: base class for all radioactive decay channels //
// //
////////////////////////////////////////////////////////////////////////////////
#ifndef G4NuclearDecay_h
#define G4NuclearDecay_h 1
#include "G4VDecayChannel.hh"
#include "G4RadioactiveDecayMode.hh"
class G4NuclearDecay : public G4VDecayChannel
{
public:
G4NuclearDecay(const G4String& channelName,
const G4RadioactiveDecayMode& mode,
const G4double& excitation);
virtual ~G4NuclearDecay();
G4RadioactiveDecayMode GetDecayMode() {return theMode;}
G4double GetDaughterExcitation() {return daughterEx;}
G4ParticleDefinition* GetDaughterNucleus() {return GetDaughter(0);}
void SetHLThreshold(G4double HLT) {halflifeThreshold = HLT;}
G4double GetHLThreshold() {return halflifeThreshold;}
virtual void DumpNuclearInfo() = 0;
protected:
const G4RadioactiveDecayMode theMode;
private:
// Needed for variance reduction mode
const G4double daughterEx;
G4double halflifeThreshold;
};
#endif
@@ -0,0 +1,61 @@
//
// ********************************************************************
// * 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: G4ProtonDecay.hh //
// Author: L.G. Sarmiento (Lund) //
// Date: 10 March 2015 //
// Description: performs protom emission from radioactive nuclei, and //
// returns daughter particles in rest frame of parent nucleus //
// //
// This class is created based on G4AlphaDecay //
// //
////////////////////////////////////////////////////////////////////////////////
#ifndef G4ProtonDecay_h
#define G4ProtonDecay_h 1
#include "G4NuclearDecay.hh"
class G4ProtonDecay : public G4NuclearDecay
{
public:
G4ProtonDecay(const G4ParticleDefinition* theParentNucleus,
const G4double& theBR, const G4double& Qvalue,
const G4double& excitation);
virtual ~G4ProtonDecay();
virtual G4DecayProducts* DecayIt(G4double);
virtual void DumpNuclearInfo();
private:
const G4double transitionQ;
};
#endif
@@ -265,7 +265,6 @@ class G4RadioactiveDecay : public G4VRestDiscreteProcess
G4RadioactiveDecay & operator=(const G4RadioactiveDecay &right);
G4RadioactiveDecaymessenger* theRadioactiveDecaymessenger;
G4RIsotopeTable* theIsotopeTable;
G4NucleusLimits theNucleusLimits;
@@ -53,7 +53,9 @@
// 0.b.3 release.
//
// 13 April 2000, F Lei, DERA UK
// 0.b.4 release. No change to this file
// 0.b.4 release. No change to this file
//
// 13 October 2015 L.G Sarmiento included different decay modes in the enum
//
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
////////////////////////////////////////////////////////////////////////////////
@@ -63,7 +65,7 @@
//
enum G4RadioactiveDecayMode
{RDM_ERROR=-1, IT=0, BetaMinus=1, BetaPlus=2, KshellEC=3, LshellEC=4, MshellEC=5, Alpha=6,
Proton=7, Beta2Minus=8, Beta2Plus=9, Proton2=10, SpFission=11};
Proton=7, Neutron=8, BDProton=9, BDNeutron=10, Beta2Minus=11, Beta2Plus=12, Proton2=13, Neutron2=14, SpFission=15};
std::istream &operator >> (std::istream &s, G4RadioactiveDecayMode &q);
@@ -11,7 +11,7 @@
#
# Generated on : 24/9/2010
#
# $Id: sources.cmake 85817 2014-11-05 15:15:58Z gcosmo $
# $Id: sources.cmake 93732 2015-10-30 10:57:14Z gcosmo $
#
#------------------------------------------------------------------------------
@@ -33,10 +33,10 @@ include_directories(${CMAKE_SOURCE_DIR}/source/particles/hadrons/mesons/include)
include_directories(${CMAKE_SOURCE_DIR}/source/particles/leptons/include)
include_directories(${CMAKE_SOURCE_DIR}/source/particles/management/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/cuts/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/electromagnetic/lowenergy/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/electromagnetic/utils/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/hadronic/cross_sections/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/hadronic/management/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/hadronic/management/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/hadronic/models/de_excitation/management/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/hadronic/models/de_excitation/photon_evaporation/include)
include_directories(${CMAKE_SOURCE_DIR}/source/processes/hadronic/models/de_excitation/util/include)
@@ -56,15 +56,21 @@ GEANT4_DEFINE_MODULE(NAME G4hadronic_radioactivedecay
G4AlphaDecayChannel.hh
G4BetaDecayCorrections.hh
G4BetaDecayType.hh
G4BetaFermiFunction.hh
G4BetaMinusDecay.hh
G4BetaMinusDecayChannel.hh
G4BetaPlusDecay.hh
G4BetaPlusDecayChannel.hh
G4ECDecay.hh
G4ITDecay.hh
G4ITDecayChannel.hh
G4KshellECDecayChannel.hh
G4LshellECDecayChannel.hh
G4MshellECDecayChannel.hh
G4NeutronDecay.hh
G4NuclearDecayChannel.hh
G4NuclearDecay.hh
G4NucleusLimits.hh
G4ProtonDecay.hh
G4ProtonDecayChannel.hh
G4RIsotopeTable.hh
G4RadioactiveDecay.hh
@@ -79,9 +85,15 @@ GEANT4_DEFINE_MODULE(NAME G4hadronic_radioactivedecay
G4AlphaDecay.cc
G4BetaDecayCorrections.cc
G4BetaDecayType.cc
G4BetaFermiFunction.cc
G4BetaMinusDecay.cc
G4BetaPlusDecay.cc
G4ECDecay.cc
G4ITDecay.cc
G4NeutronDecay.cc
G4NuclearDecayChannel.cc
G4NuclearDecay.cc
G4NucleusLimits.cc
G4ProtonDecay.cc
G4RIsotopeTable.cc
G4RadioactiveDecay.cc
G4RadioactiveDecayMode.cc
@@ -45,28 +45,21 @@
G4AlphaDecay::G4AlphaDecay(const G4ParticleDefinition* theParentNucleus,
const G4double& branch, const G4double& Qvalue,
const G4double& excitationE)
: G4VDecayChannel("alpha decay"), transitionQ(Qvalue), daughterEx(excitationE),
halflifeThreshold(nanosecond)
: G4NuclearDecay("alpha decay", Alpha, excitationE), transitionQ(Qvalue)
{
SetParent(theParentNucleus); // Store name of parent nucleus, delete G4MT_parent
SetBR(branch);
SetNumberOfDaughters(2);
SetDaughter(0, "alpha"); // Store name of 1st daughter
G4IonTable* theIonTable =
(G4IonTable*)(G4ParticleTable::GetParticleTable()->GetIonTable());
G4int daughterZ = theParentNucleus->GetAtomicNumber() - 2;
G4int daughterA = theParentNucleus->GetAtomicMass() - 4;
SetDaughter(1, theIonTable->GetIon(daughterZ, daughterA, daughterEx) );
SetDaughter(0, theIonTable->GetIon(daughterZ, daughterA, excitationE) );
SetDaughter(1, "alpha");
}
G4AlphaDecay::G4AlphaDecay(const G4AlphaDecay& right)
: G4VDecayChannel(right), transitionQ(right.transitionQ),
daughterEx(right.daughterEx), halflifeThreshold(right.halflifeThreshold)
{}
G4AlphaDecay::~G4AlphaDecay()
{}
@@ -79,9 +72,9 @@ G4DecayProducts* G4AlphaDecay::DecayIt(G4double)
// Fill G4MT_daughters with alpha and residual nucleus (stored by SetDaughter)
if (G4MT_daughters == 0) FillDaughters();
G4double alphaMass = G4MT_daughters[0]->GetPDGMass();
G4double alphaMass = G4MT_daughters[1]->GetPDGMass();
// Excitation energy included in PDG mass
G4double nucleusMass = G4MT_daughters[1]->GetPDGMass();
G4double nucleusMass = G4MT_daughters[0]->GetPDGMass();
// Q value was calculated from atomic masses.
// Use it to get correct alpha energy.
@@ -105,23 +98,39 @@ G4DecayProducts* G4AlphaDecay::DecayIt(G4double)
G4double KE = std::sqrt(cmMomentum*cmMomentum + alphaMass*alphaMass)
- alphaMass;
G4DynamicParticle* daughterparticle =
new G4DynamicParticle(G4MT_daughters[0], direction, KE, alphaMass);
new G4DynamicParticle(G4MT_daughters[1], direction, KE, alphaMass);
products->PushProducts(daughterparticle);
KE = std::sqrt(cmMomentum*cmMomentum + nucleusMass*nucleusMass) - nucleusMass;
daughterparticle =
new G4DynamicParticle(G4MT_daughters[1], -1.0*direction, KE, nucleusMass);
new G4DynamicParticle(G4MT_daughters[0], -1.0*direction, KE, nucleusMass);
products->PushProducts(daughterparticle);
// Energy conservation check
// For alpha decays, do final energy check against reaction Q value
// which is well-measured using atomic mass differences. Nuclear masses
// should not be used since they are not usually directly measured and we
// always decay atoms and not fully stripped nuclei.
/*
G4int nProd = products->entries();
G4DynamicParticle* temp = 0;
G4double Esum = 0.0;
for (G4int i = 0; i < nProd; i++) {
temp = products->operator[](i);
Esum += temp->GetKineticEnergy();
}
G4double eCons = (transitionQ - Esum)/keV;
if (eCons > 1.e-07) G4cout << " Alpha decay check: Ediff (keV) = " << eCons << G4endl;
*/
return products;
}
void G4AlphaDecay::DumpInfo()
void G4AlphaDecay::DumpNuclearInfo()
{
G4cout << " G4AlphaDecay for parent nucleus " << GetParentName() << G4endl;
G4cout << " decays to " << GetDaughterName(0) << " + " << GetDaughterName(1)
<< " with branching ratio " << GetBR() << " and Q value "
<< " with branching ratio " << GetBR() << "% and Q value "
<< transitionQ << G4endl;
}
@@ -108,9 +108,18 @@ G4double G4BetaDecayCorrections::Gamma(const G4double& arg)
// Use recursion relation to get argument < 1
G4double fac = 1.0;
G4double x = arg - 1.;
while (x > 1.0) {
G4int loop = 0;
G4ExceptionDescription ed;
ed << " While count exceeded " << G4endl;
while (x > 1.0) { /* Loop checking, 01.09.2015, D.Wright */
fac *= x;
x -= 1.0;
loop++;
if (loop > 1000) {
G4Exception("G4BetaDecayCorrections::Gamma()", "HAD_RDM_100", JustWarning, ed);
break;
}
}
// Calculation of Gamma function with real argument
@@ -0,0 +1,197 @@
//
// ********************************************************************
// * 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: G4BetaMinusDecay.cc //
// Author: D.H. Wright (SLAC) //
// Date: 25 October 2014 //
// //
////////////////////////////////////////////////////////////////////////////////
#include "G4BetaMinusDecay.hh"
#include "G4BetaDecayCorrections.hh"
#include "G4IonTable.hh"
#include "G4ThreeVector.hh"
#include "G4DynamicParticle.hh"
#include "G4DecayProducts.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include <iostream>
#include <iomanip>
G4BetaMinusDecay::G4BetaMinusDecay(const G4ParticleDefinition* theParentNucleus,
const G4double& branch, const G4double& e0,
const G4double& excitationE,
const G4BetaDecayType& betaType)
: G4NuclearDecay("beta- decay", BetaMinus, excitationE), endpointEnergy(e0)
{
SetParent(theParentNucleus); // Store name of parent nucleus, delete G4MT_parent
SetBR(branch);
SetNumberOfDaughters(3);
G4IonTable* theIonTable =
(G4IonTable*)(G4ParticleTable::GetParticleTable()->GetIonTable());
G4int daughterZ = theParentNucleus->GetAtomicNumber() + 1;
G4int daughterA = theParentNucleus->GetAtomicMass();
SetDaughter(0, theIonTable->GetIon(daughterZ, daughterA, excitationE) );
SetDaughter(1, "e-");
SetDaughter(2, "anti_nu_e");
SetUpBetaSpectrumSampler(daughterZ, daughterA, betaType);
}
G4BetaMinusDecay::~G4BetaMinusDecay()
{
delete spectrumSampler;
}
G4DecayProducts* G4BetaMinusDecay::DecayIt(G4double)
{
// Fill G4MT_parent with theParentNucleus (stored by SetParent in ctor)
if (G4MT_parent == 0) FillParent();
// Fill G4MT_daughters with e-, nu and residual nucleus (stored by SetDaughter)
if (G4MT_daughters == 0) FillDaughters();
G4double parentMass = G4MT_parent->GetPDGMass();
G4double eMass = G4MT_daughters[1]->GetPDGMass();
G4double nucleusMass = G4MT_daughters[0]->GetPDGMass();
// Set up final state
// parentParticle is set at rest here because boost with correct momentum
// is done later
G4DynamicParticle parentParticle(G4MT_parent, G4ThreeVector(0,0,0), 0.0);
G4DecayProducts* products = new G4DecayProducts(parentParticle);
// Electron, neutrino and daughter nucleus energies
G4double eKE = endpointEnergy*spectrumSampler->shoot(G4Random::getTheEngine() );
G4double eMomentum = std::sqrt(eKE*(eKE + 2.*eMass) );
G4double cosThetaENu = 2.*G4UniformRand() - 1.;
G4double eTE = eMass + eKE;
G4double nuEnergy = ((endpointEnergy - eKE)*(parentMass + nucleusMass - eTE)
- eMomentum*eMomentum)/(parentMass - eTE + eMomentum*cosThetaENu)/2.;
// Electron 4-vector, isotropic angular distribution
G4double cosTheta = 2.*G4UniformRand() - 1.0;
G4double sinTheta = std::sqrt(1.0 - cosTheta*cosTheta);
G4double phi = twopi*G4UniformRand()*rad;
G4double sinPhi = std::sin(phi);
G4double cosPhi = std::cos(phi);
G4ParticleMomentum eDirection(sinTheta*cosPhi, sinTheta*sinPhi, cosTheta);
G4DynamicParticle* dynamicElectron
= new G4DynamicParticle(G4MT_daughters[1], eDirection*eMomentum);
products->PushProducts(dynamicElectron);
// Neutrino 4-vector
G4double sinThetaENu = std::sqrt(1.0 - cosThetaENu*cosThetaENu);
phi = twopi*G4UniformRand()*rad;
G4double sinPhiNu = std::sin(phi);
G4double cosPhiNu = std::cos(phi);
G4ParticleMomentum nuDirection;
nuDirection.setX(sinThetaENu*cosPhiNu*cosTheta*cosPhi -
sinThetaENu*sinPhiNu*sinPhi + cosThetaENu*sinTheta*cosPhi);
nuDirection.setY(sinThetaENu*cosPhiNu*cosTheta*sinPhi +
sinThetaENu*sinPhiNu*cosPhi + cosThetaENu*sinTheta*sinPhi);
nuDirection.setZ(-sinThetaENu*cosPhiNu*sinTheta + cosThetaENu*cosTheta);
G4DynamicParticle* dynamicNeutrino
= new G4DynamicParticle(G4MT_daughters[2], nuDirection*nuEnergy);
products->PushProducts(dynamicNeutrino);
// Daughter nucleus 4-vector
// p_D = - p_e - p_nu
G4DynamicParticle* dynamicDaughter =
new G4DynamicParticle(G4MT_daughters[0],
-eDirection*eMomentum - nuDirection*nuEnergy);
products->PushProducts(dynamicDaughter);
// Check energy conservation against Q value, not nuclear masses
/*
G4int nProd = products->entries();
G4DynamicParticle* temp = 0;
G4double Esum = 0.0;
for (G4int i = 0; i < nProd; i++) {
temp = products->operator[](i);
// G4cout << temp->GetParticleDefinition()->GetParticleName() << " has "
// << temp->GetTotalEnergy()/keV << " keV " << G4endl;
Esum += temp->GetKineticEnergy();
}
G4double eCons = (endpointEnergy - Esum)/keV;
if (std::abs(eCons) > 0.001) G4cout << " Beta- check: eCons = " << eCons << G4endl;
*/
return products;
}
void
G4BetaMinusDecay::SetUpBetaSpectrumSampler(const G4int& daughterZ,
const G4int& daughterA,
const G4BetaDecayType& betaType)
{
G4double e0 = endpointEnergy/0.510999;
G4BetaDecayCorrections corrections(daughterZ, daughterA);
// Array to store spectrum pdf
G4int npti = 100;
G4double* pdf = new G4double[npti];
G4double e; // Total electron energy in units of electron mass
G4double p; // Electron momentum in units of electron mass
G4double f; // Spectral shap function
for (G4int ptn = 0; ptn < npti; ptn++) {
// Calculate simple phase space
e = 1. + e0*(ptn + 0.5)/G4double(npti);
p = std::sqrt(e*e - 1.);
f = p*e*(e0 - e + 1.)*(e0 - e + 1.);
// Apply Fermi factor to get allowed shape
f *= corrections.FermiFunction(e);
// Apply shape factor for forbidden transitions
f *= corrections.ShapeFactor(betaType, p, e0-e+1.);
pdf[ptn] = f;
}
spectrumSampler = new G4RandGeneral(pdf, npti);
delete[] pdf;
}
void G4BetaMinusDecay::DumpNuclearInfo()
{
G4cout << " G4BetaMinusDecay for parent nucleus " << GetParentName() << G4endl;
G4cout << " decays to " << GetDaughterName(0) << " , " << GetDaughterName(1)
<< " and " << GetDaughterName(2) << " with branching ratio " << GetBR()
<< "% and endpoint energy " << endpointEnergy/keV << " keV " << G4endl;
}
@@ -0,0 +1,204 @@
//
// ********************************************************************
// * 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: G4BetaPlusDecay.cc //
// Author: D.H. Wright (SLAC) //
// Date: 14 November 2014 //
// //
////////////////////////////////////////////////////////////////////////////////
#include "G4BetaPlusDecay.hh"
#include "G4BetaDecayCorrections.hh"
#include "G4IonTable.hh"
#include "G4ThreeVector.hh"
#include "G4DynamicParticle.hh"
#include "G4DecayProducts.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include <iostream>
#include <iomanip>
G4BetaPlusDecay::G4BetaPlusDecay(const G4ParticleDefinition* theParentNucleus,
const G4double& branch, const G4double& e0,
const G4double& excitationE,
const G4BetaDecayType& betaType)
: G4NuclearDecay("beta+ decay", BetaPlus, excitationE),
endpointEnergy(e0 - 2.*CLHEP::electron_mass_c2)
{
SetParent(theParentNucleus); // Store name of parent nucleus, delete G4MT_parent
SetBR(branch);
SetNumberOfDaughters(3);
G4IonTable* theIonTable =
(G4IonTable*)(G4ParticleTable::GetParticleTable()->GetIonTable());
G4int daughterZ = theParentNucleus->GetAtomicNumber() - 1;
G4int daughterA = theParentNucleus->GetAtomicMass();
SetDaughter(0, theIonTable->GetIon(daughterZ, daughterA, excitationE) );
SetUpBetaSpectrumSampler(daughterZ, daughterA, betaType);
SetDaughter(1, "e+");
SetDaughter(2, "nu_e");
}
G4BetaPlusDecay::~G4BetaPlusDecay()
{
delete spectrumSampler;
}
G4DecayProducts* G4BetaPlusDecay::DecayIt(G4double)
{
// Fill G4MT_parent with theParentNucleus (stored by SetParent in ctor)
if (G4MT_parent == 0) FillParent();
// Fill G4MT_daughters with e-, nu and residual nucleus (stored by SetDaughter)
if (G4MT_daughters == 0) FillDaughters();
G4double parentMass = G4MT_parent->GetPDGMass();
G4double eMass = G4MT_daughters[1]->GetPDGMass();
G4double nucleusMass = G4MT_daughters[0]->GetPDGMass();
// Set up final state
// parentParticle is set at rest here because boost with correct momentum
// is done later
G4DynamicParticle parentParticle(G4MT_parent, G4ThreeVector(0,0,0), 0.0);
G4DecayProducts* products = new G4DecayProducts(parentParticle);
if (spectrumSampler) {
// Generate positron isotropic in angle, with energy from stored spectrum
G4double eKE = endpointEnergy*spectrumSampler->shoot(G4Random::getTheEngine() );
G4double eMomentum = std::sqrt(eKE*(eKE + 2.*eMass) );
G4double cosTheta = 2.*G4UniformRand() - 1.0;
G4double sinTheta = std::sqrt(1.0 - cosTheta*cosTheta);
G4double phi = twopi*G4UniformRand()*rad;
G4double sinPhi = std::sin(phi);
G4double cosPhi = std::cos(phi);
G4ParticleMomentum eDirection(sinTheta*cosPhi, sinTheta*sinPhi, cosTheta);
G4DynamicParticle* dynamicPositron
= new G4DynamicParticle(G4MT_daughters[1], eDirection*eMomentum);
products->PushProducts(dynamicPositron);
// Generate neutrino with angle relative to positron, and energy from
// energy-momentum conservation using endpoint energy of reaction
G4double cosThetaENu = 2.*G4UniformRand() - 1.;
G4double eTE = eMass + eKE;
G4double nuEnergy = ((endpointEnergy - eKE)*(parentMass + nucleusMass - eTE)
- eMomentum*eMomentum)/(parentMass - eTE + eMomentum*cosThetaENu)/2.;
G4double sinThetaENu = std::sqrt(1.0 - cosThetaENu*cosThetaENu);
phi = twopi*G4UniformRand()*rad;
G4double sinPhiNu = std::sin(phi);
G4double cosPhiNu = std::cos(phi);
G4ParticleMomentum nuDirection;
nuDirection.setX(sinThetaENu*cosPhiNu*cosTheta*cosPhi -
sinThetaENu*sinPhiNu*sinPhi + cosThetaENu*sinTheta*cosPhi);
nuDirection.setY(sinThetaENu*cosPhiNu*cosTheta*sinPhi +
sinThetaENu*sinPhiNu*cosPhi + cosThetaENu*sinTheta*sinPhi);
nuDirection.setZ(-sinThetaENu*cosPhiNu*sinTheta + cosThetaENu*cosTheta);
G4DynamicParticle* dynamicNeutrino
= new G4DynamicParticle(G4MT_daughters[2], nuDirection*nuEnergy);
products->PushProducts(dynamicNeutrino);
// Generate daughter nucleus from sum of positron and neutrino 4-vectors:
// p_D = - p_e - p_nu
G4DynamicParticle* dynamicDaughter =
new G4DynamicParticle(G4MT_daughters[0],
-eDirection*eMomentum - nuDirection*nuEnergy);
products->PushProducts(dynamicDaughter);
} else {
// positron energy below threshold -> no decay
G4DynamicParticle* noDecay =
new G4DynamicParticle(G4MT_parent, G4ThreeVector(0,0,0), 0.0);
products->PushProducts(noDecay);
}
// Check energy conservation against endpoint value, not nuclear masses
/*
G4int nProd = products->entries();
G4DynamicParticle* temp = 0;
G4double Esum = 0.0;
for (G4int i = 0; i < nProd; i++) {
temp = products->operator[](i);
Esum += temp->GetKineticEnergy();
}
G4double eCons = (endpointEnergy - Esum)/keV;
if (eCons > 0.001) G4cout << " Beta+ check: eCons (keV) = " << eCons << G4endl;
*/
return products;
}
void
G4BetaPlusDecay::SetUpBetaSpectrumSampler(const G4int& daughterZ,
const G4int& daughterA,
const G4BetaDecayType& betaType)
{
G4double e0 = endpointEnergy/CLHEP::electron_mass_c2;
G4BetaDecayCorrections corrections(daughterZ, daughterA);
spectrumSampler = 0;
// Check for cases in which Q < 2Me (e.g. z67.a162)
if (e0 > 0.) {
// Array to store spectrum pdf
G4int npti = 100;
G4double* pdf = new G4double[npti];
G4double e; // Total positron energy in units of electron mass
G4double p; // Positron momentum in units of electron mass
G4double f; // Spectral shap function
for (G4int ptn = 0; ptn < npti; ptn++) {
// Calculate simple phase space
e = 1. + e0*(ptn + 0.5)/G4double(npti);
p = std::sqrt(e*e - 1.);
f = p*e*(e0 - e + 1.)*(e0 - e + 1.);
// Apply Fermi factor to get allowed shape
f *= corrections.FermiFunction(e);
// Apply shape factor for forbidden transitions
f *= corrections.ShapeFactor(betaType, p, e0-e+1.);
pdf[ptn] = f;
}
spectrumSampler = new G4RandGeneral(pdf, npti);
delete[] pdf;
}
}
void G4BetaPlusDecay::DumpNuclearInfo()
{
G4cout << " G4BetaPlusDecay for parent nucleus " << GetParentName() << G4endl;
G4cout << " decays to " << GetDaughterName(0) << " , " << GetDaughterName(1)
<< " and " << GetDaughterName(2) << " with branching ratio " << GetBR()
<< "% and endpoint energy " << endpointEnergy/keV << " keV " << G4endl;
}
@@ -0,0 +1,212 @@
//
// ********************************************************************
// * 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: G4ECDecay.cc //
// Author: D.H. Wright (SLAC) //
// Date: 25 November 2014 //
// //
////////////////////////////////////////////////////////////////////////////////
#include "G4ECDecay.hh"
#include "G4IonTable.hh"
#include "Randomize.hh"
#include "G4ThreeVector.hh"
#include "G4DynamicParticle.hh"
#include "G4DecayProducts.hh"
#include "G4VAtomDeexcitation.hh"
#include "G4AtomicShells.hh"
#include "G4Electron.hh"
#include "G4LossTableManager.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
G4ECDecay::G4ECDecay(const G4ParticleDefinition* theParentNucleus,
const G4double& branch, const G4double& Qvalue,
const G4double& excitationE,
const G4RadioactiveDecayMode& mode)
: G4NuclearDecay("electron capture", mode, excitationE), transitionQ(Qvalue),
applyARM(true)
{
SetParent(theParentNucleus); // Store name of parent nucleus, delete G4MT_parent
SetBR(branch);
SetNumberOfDaughters(2);
G4IonTable* theIonTable =
(G4IonTable*)(G4ParticleTable::GetParticleTable()->GetIonTable());
G4int daughterZ = theParentNucleus->GetAtomicNumber() - 1;
G4int daughterA = theParentNucleus->GetAtomicMass();
SetDaughter(0, theIonTable->GetIon(daughterZ, daughterA, excitationE) );
SetDaughter(1, "nu_e");
}
G4ECDecay::~G4ECDecay()
{}
G4DecayProducts* G4ECDecay::DecayIt(G4double)
{
// Fill G4MT_parent with theParentNucleus (stored by SetParent in ctor)
if (G4MT_parent == 0) FillParent();
// Fill G4MT_daughters with alpha and residual nucleus (stored by SetDaughter)
if (G4MT_daughters == 0) FillDaughters();
// Get shell number of captured electron
G4int shellIndex = -1;
switch (theMode)
{
case KshellEC:
shellIndex = 0;
break;
case LshellEC:
shellIndex = G4int(G4UniformRand()*3) + 1;
break;
case MshellEC:
shellIndex = G4int(G4UniformRand()*3) + 4;
break;
default:
G4Exception("G4ECDecay::DecayIt()", "HAD_RDM_009",
FatalException, "Invalid electron shell selected");
}
// Initialize decay products with parent nucleus at rest
G4DynamicParticle parentParticle(G4MT_parent, G4ThreeVector(0,0,0), 0.0);
G4DecayProducts* products = new G4DecayProducts(parentParticle);
G4double eBind = 0.0;
// G4LossTableManager must already be initialized with G4UAtomicDeexcitation
// This is currently done in G4RadioactiveDecay::BuildPhysicsTable
G4VAtomDeexcitation* atomDeex =
G4LossTableManager::Instance()->AtomDeexcitation();
std::vector<G4DynamicParticle*> armProducts;
if (applyARM) {
if (atomDeex) {
G4int aZ = G4MT_daughters[0]->GetAtomicNumber();
G4int nShells = G4AtomicShells::GetNumberOfShells(aZ);
if (shellIndex >= nShells) shellIndex = nShells;
G4AtomicShellEnumerator as = G4AtomicShellEnumerator(shellIndex);
const G4AtomicShell* shell = atomDeex->GetAtomicShell(aZ, as);
eBind = shell->BindingEnergy();
if (atomDeex->IsFluoActive() && aZ > 5 && aZ < 100) {
// Do atomic relaxation
// VI, SI
// Allows fixing of Bugzilla 1727
//const G4double deexLimit = 0.1*keV;
G4double deexLimit = 0.1*keV;
if (G4EmParameters::Instance()->DeexcitationIgnoreCut()) deexLimit =0.;
//
atomDeex->GenerateParticles(&armProducts, shell, aZ, deexLimit, deexLimit);
}
G4double productEnergy = 0.;
for (G4int i = 0; i < G4int(armProducts.size()); i++)
productEnergy += armProducts[i]->GetKineticEnergy();
G4double deficit = shell->BindingEnergy() - productEnergy;
if (deficit > 0.0) {
// Add a dummy electron to make up extra energy
G4double cosTh = 1.-2.*G4UniformRand();
G4double sinTh = std::sqrt(1.- cosTh*cosTh);
G4double phi = twopi*G4UniformRand();
G4ThreeVector electronDirection(sinTh*std::sin(phi),
sinTh*std::cos(phi), cosTh);
G4DynamicParticle* extra =
new G4DynamicParticle(G4Electron::Electron(), electronDirection,
deficit);
armProducts.push_back(extra);
}
} // atomDeex
} // applyARM
G4double daughterMass = G4MT_daughters[0]->GetPDGMass();
// CM momentum using Q value corrected for binding energy of captured electron
G4double Q = transitionQ - eBind;
G4double cmMomentum = Q*(Q + 2.*daughterMass)/(Q + daughterMass)/2.;
G4double costheta = 2.*G4UniformRand() - 1.0;
G4double sintheta = std::sqrt(1.0 - costheta*costheta);
G4double phi = twopi*G4UniformRand()*rad;
G4ThreeVector direction(sintheta*std::cos(phi),sintheta*std::sin(phi),
costheta);
G4double KE = cmMomentum;
G4DynamicParticle* daughterParticle =
new G4DynamicParticle(G4MT_daughters[1], direction, KE, 0.0);
products->PushProducts(daughterParticle);
KE = std::sqrt(cmMomentum*cmMomentum + daughterMass*daughterMass) - daughterMass;
daughterParticle =
new G4DynamicParticle(G4MT_daughters[0], -1.0*direction, KE, daughterMass);
products->PushProducts(daughterParticle);
G4int nArm = armProducts.size();
if (nArm > 0) {
G4ThreeVector bst = daughterParticle->Get4Momentum().boostVector();
for (G4int i = 0; i < nArm; ++i) {
G4DynamicParticle* dp = armProducts[i];
G4LorentzVector lv = dp->Get4Momentum().boost(bst);
dp->Set4Momentum(lv);
products->PushProducts(dp);
}
}
// Energy conservation check
/*
G4int newSize = products->entries();
G4DynamicParticle* temp = 0;
G4double KEsum = 0.0;
for (G4int i = 0; i < newSize; i++) {
temp = products->operator[](i);
KEsum += temp->GetKineticEnergy();
}
G4double eCons = (transitionQ - KEsum)/keV;
G4cout << " EC check: Ediff (keV) = " << eCons << G4endl;
*/
return products;
}
void G4ECDecay::DumpNuclearInfo()
{
G4cout << " G4ECDecay of parent nucleus " << GetParentName() << " from ";
if (theMode == 3) {
G4cout << "K shell";
} else if (theMode == 4) {
G4cout << "L shell";
} else if (theMode == 5) {
G4cout << "M shell";
}
G4cout << G4endl;
G4cout << " to " << GetDaughterName(0) << " + " << GetDaughterName(1)
<< " with branching ratio " << GetBR() << "% and Q value "
<< transitionQ << G4endl;
}
@@ -0,0 +1,197 @@
//
// ********************************************************************
// * 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: G4ITDecay.cc //
// Author: D.H. Wright (SLAC) //
// Date: 14 November 2014 //
// //
////////////////////////////////////////////////////////////////////////////////
#include "G4ITDecay.hh"
#include "G4IonTable.hh"
#include "G4ThreeVector.hh"
#include "G4LorentzVector.hh"
#include "G4DynamicParticle.hh"
#include "G4DecayProducts.hh"
#include "G4PhotonEvaporation.hh"
#include "G4VAtomDeexcitation.hh"
#include "G4AtomicShells.hh"
#include "G4Electron.hh"
#include "G4LossTableManager.hh"
#include "G4Fragment.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
G4ITDecay::G4ITDecay(const G4ParticleDefinition* theParentNucleus,
const G4double& branch, const G4double& Qvalue,
const G4double& excitationE)
: G4NuclearDecay("IT decay", IT, excitationE), transitionQ(Qvalue),
applyARM(true)
{
SetParent(theParentNucleus); // Store name of parent nucleus, delete G4MT_parent
SetBR(branch);
parentZ = theParentNucleus->GetAtomicNumber();
parentA = theParentNucleus->GetAtomicMass();
SetNumberOfDaughters(1);
G4IonTable* theIonTable =
(G4IonTable*)(G4ParticleTable::GetParticleTable()->GetIonTable());
SetDaughter(0, theIonTable->GetIon(parentZ, parentA, excitationE) );
}
G4ITDecay::~G4ITDecay()
{}
G4DecayProducts* G4ITDecay::DecayIt(G4double)
{
// Fill G4MT_parent with theParentNucleus (stored by SetParent in ctor)
if (G4MT_parent == 0) FillParent();
// Set up final state
// parentParticle is set at rest here because boost with correct momentum
// is done later
G4LorentzVector atRest(G4MT_parent->GetPDGMass(),
G4ThreeVector(0.,0.,0.) );
G4DynamicParticle parentParticle(G4MT_parent, atRest);
G4DecayProducts* products = new G4DecayProducts(parentParticle);
// Let G4PhotonEvaporation do the decay
G4PhotonEvaporation* photoEvap = new G4PhotonEvaporation;
photoEvap->RDMForced(true);
photoEvap->SetICM(true);
G4Fragment* nucleus = new G4Fragment(parentA, parentZ, atRest);
G4Fragment* eOrGamma = photoEvap->EmittedFragment(nucleus);
// Daughter nuclide is returned in nucleus pointer
G4double finalDaughterExcitation = nucleus->GetExcitationEnergy();
if (finalDaughterExcitation < 1*keV) finalDaughterExcitation = 0.0;
G4LorentzVector daughterMomentum = nucleus->GetMomentum();
G4IonTable* theIonTable =
(G4IonTable*)(G4ParticleTable::GetParticleTable()->GetIonTable() );
G4ParticleDefinition* daughterIon =
theIonTable->GetIon(parentZ, parentA, finalDaughterExcitation);
G4DynamicParticle* dynDaughter = new G4DynamicParticle(daughterIon,
daughterMomentum);
delete nucleus;
if (eOrGamma) {
G4DynamicParticle* eOrGammaDyn =
new G4DynamicParticle(eOrGamma->GetParticleDefinition(),
eOrGamma->GetMomentum() );
eOrGammaDyn->SetProperTime(eOrGamma->GetCreationTime() );
products->PushProducts(eOrGammaDyn);
delete eOrGamma;
// Now do atomic relaxation
if (applyARM) {
G4int shellIndex = photoEvap->GetVacantShellNumber();
if (shellIndex > -1) {
G4VAtomDeexcitation* atomDeex =
G4LossTableManager::Instance()->AtomDeexcitation();
if (atomDeex->IsFluoActive() && parentZ > 5 && parentZ < 100) {
G4int nShells = G4AtomicShells::GetNumberOfShells(parentZ);
if (shellIndex >= nShells) shellIndex = nShells;
G4AtomicShellEnumerator as = G4AtomicShellEnumerator(shellIndex);
const G4AtomicShell* shell = atomDeex->GetAtomicShell(parentZ, as);
std::vector<G4DynamicParticle*> armProducts;
// VI, SI
// Allows fixing of Bugzilla 1727
//const G4double deexLimit = 0.1*keV;
G4double deexLimit = 0.1*keV;
if (G4EmParameters::Instance()->DeexcitationIgnoreCut()) deexLimit =0.;
//
atomDeex->GenerateParticles(&armProducts, shell, parentZ, deexLimit,
deexLimit);
G4double productEnergy = 0.;
for (G4int i = 0; i < G4int(armProducts.size()); i++)
productEnergy += armProducts[i]->GetKineticEnergy();
G4double deficit = shell->BindingEnergy() - productEnergy;
if (deficit > 0.0) {
// Add a dummy electron to make up extra energy
G4double cosTh = 1.-2.*G4UniformRand();
G4double sinTh = std::sqrt(1.- cosTh*cosTh);
G4double phi = twopi*G4UniformRand();
G4ThreeVector electronDirection(sinTh*std::sin(phi),
sinTh*std::cos(phi), cosTh);
G4DynamicParticle* extra =
new G4DynamicParticle(G4Electron::Electron(), electronDirection,
deficit);
armProducts.push_back(extra);
}
G4int nArm = armProducts.size();
if (nArm > 0) {
G4ThreeVector bst = dynDaughter->Get4Momentum().boostVector();
for (G4int i = 0; i < nArm; ++i) {
G4DynamicParticle* dp = armProducts[i];
G4LorentzVector lv = dp->Get4Momentum().boost(bst);
dp->Set4Momentum(lv);
products->PushProducts(dp);
}
}
}
}
} // if ARM on
} // eOrGamma
products->PushProducts(dynDaughter);
// Energy conservation check
/*
G4int newSize = products->entries();
G4DynamicParticle* temp = 0;
G4double KEsum = 0.0;
for (G4int i = 0; i < newSize; i++) {
temp = products->operator[](i);
KEsum += temp->GetKineticEnergy();
}
G4double eCons = G4MT_parent->GetPDGMass() - dynDaughter->GetMass() - KEsum;
G4cout << " IT check: Ediff (keV) = " << eCons/keV << G4endl;
*/
delete photoEvap;
return products;
}
void G4ITDecay::DumpNuclearInfo()
{
G4cout << " G4ITDecay for parent nucleus " << GetParentName() << G4endl;
G4cout << " decays to " << GetDaughterName(0)
<< " + gammas (or electrons), with branching ratio " << GetBR()
<< "% and Q value " << transitionQ << G4endl;
}
@@ -0,0 +1,136 @@
//
// ********************************************************************
// * 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: G4NeutronDecay.cc //
// Author: L.G. Sarmiento (Lund) //
// Date: 10 October 2015 //
// //
////////////////////////////////////////////////////////////////////////////////
#include "G4NeutronDecay.hh"
#include "G4IonTable.hh"
#include "Randomize.hh"
#include "G4ThreeVector.hh"
#include "G4DynamicParticle.hh"
#include "G4DecayProducts.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include <iostream>
#include <iomanip>
G4NeutronDecay::G4NeutronDecay(const G4ParticleDefinition* theParentNucleus,
const G4double& branch, const G4double& Qvalue,
const G4double& excitationE)
: G4NuclearDecay("neutron decay", Neutron, excitationE), transitionQ(Qvalue)
{
SetParent(theParentNucleus); // Store name of parent nucleus, delete G4MT_parent
SetBR(branch);
SetNumberOfDaughters(2);
G4IonTable* theIonTable =
(G4IonTable*)(G4ParticleTable::GetParticleTable()->GetIonTable());
G4int daughterZ = theParentNucleus->GetAtomicNumber();
G4int daughterA = theParentNucleus->GetAtomicMass() - 1;
SetDaughter(0, theIonTable->GetIon(daughterZ, daughterA, excitationE) );
SetDaughter(1, "neutron");
}
G4NeutronDecay::~G4NeutronDecay()
{}
G4DecayProducts* G4NeutronDecay::DecayIt(G4double)
{
// Fill G4MT_parent with theParentNucleus (stored by SetParent in ctor)
if (G4MT_parent == 0) FillParent();
// Fill G4MT_daughters with neutron and residual nucleus (stored by SetDaughter)
if (G4MT_daughters == 0) FillDaughters();
G4double neutronMass = G4MT_daughters[1]->GetPDGMass();
// Excitation energy included in PDG mass
G4double nucleusMass = G4MT_daughters[0]->GetPDGMass();
// Q value was calculated from atomic masses.
// Use it to get correct neutron energy.
G4double cmMomentum = std::sqrt(transitionQ*(transitionQ + 2.*neutronMass)*
(transitionQ + 2.*nucleusMass)*
(transitionQ + 2.*neutronMass + 2.*nucleusMass) )/
(transitionQ + neutronMass + nucleusMass)/2.;
// Set up final state
// parentParticle is set at rest here because boost with correct momentum
// is done later
G4DynamicParticle parentParticle(G4MT_parent, G4ThreeVector(0,0,0), 0.0);
G4DecayProducts* products = new G4DecayProducts(parentParticle);
G4double costheta = 2.*G4UniformRand()-1.0;
G4double sintheta = std::sqrt(1.0 - costheta*costheta);
G4double phi = twopi*G4UniformRand()*rad;
G4ThreeVector direction(sintheta*std::cos(phi),sintheta*std::sin(phi),
costheta);
G4double KE = std::sqrt(cmMomentum*cmMomentum + neutronMass*neutronMass)
- neutronMass;
G4DynamicParticle* daughterparticle =
new G4DynamicParticle(G4MT_daughters[1], direction, KE, neutronMass);
products->PushProducts(daughterparticle);
KE = std::sqrt(cmMomentum*cmMomentum + nucleusMass*nucleusMass) - nucleusMass;
daughterparticle =
new G4DynamicParticle(G4MT_daughters[0], -1.0*direction, KE, nucleusMass);
products->PushProducts(daughterparticle);
// Energy conservation check
// For neutron decays, do final energy check against reaction Q value
// which is well-measured using atomic mass differences. Nuclear masses
// should not be used since they are not usually directly measured and we
// always decay atoms and not fully stripped nuclei.
/*
G4int nProd = products->entries();
G4DynamicParticle* temp = 0;
G4double Esum = 0.0;
for (G4int i = 0; i < nProd; i++) {
temp = products->operator[](i);
Esum += temp->GetKineticEnergy();
}
G4double eCons = (transitionQ - Esum)/keV;
if (eCons > 1.e-07) G4cout << " Neutron decay check: Ediff (keV) = " << eCons << G4endl;
*/
return products;
}
void G4NeutronDecay::DumpNuclearInfo()
{
G4cout << " G4NeutronDecay for parent nucleus " << GetParentName() << G4endl;
G4cout << " decays to " << GetDaughterName(0) << " + " << GetDaughterName(1)
<< " with branching ratio " << GetBR() << "% and Q value "
<< transitionQ << G4endl;
}
@@ -23,74 +23,25 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
#include "globals.hh"
#include "G4BetaFermiFunction.hh"
const G4double G4BetaFermiFunction::PI=3.14159;
//////////////////////////////////////////////////////////////////
//
// calculate the Fermi Function foe energy E0
//
G4double G4BetaFermiFunction::GetFF( const G4double E0)
{
G4double A1, A2;
G4double P, U, S, Y;
G4double F2;
G4double E = E0+1.;
P=std::sqrt(E*E-1.0) ;
U=Z/137.0;
S=std::sqrt(1.0-U*U) - 1.;
Y = 2*PI*U*E/P;
A1 = U*U*E*E + P*P/4.;
A2 = std::fabs(Y/(1-std::exp(-Y)));
F2 = std::pow(A1,S) * A2;
return F2;
}
//////////////////////////////////////////////////////////////////
//
// calculate the Fermi normalization factor
// here E0 is the end point energy of the beta decay
//
G4double G4BetaFermiFunction::GetFFN(const G4double E0)
{
G4double A1, A2;
G4double P, U, S, Y;
G4double F2,E;
G4double EE = E0/100.;
U=Z/137.0;
S=std::sqrt(1.0-U*U) - 1.;
G4double F1 = 1E-10;
for (G4int i = 1; i<=100 ; i++) {
E = G4double(i)*EE + 1.;
P=std::sqrt(E*E-1.0) ;
Y = 2*PI*U*E/P;
A1 = U*U*E*E + P*P/4.;
A2 = std::fabs(Y/(1-std::exp(-Y)));
F2 = std::pow(A1,S) * A2;
if (F2 > F1) F1 = F2;
}
return F1;
}
////////////////////////////////////////////////////////////////////////////////
// //
// File: G4NuclearDecay.cc //
// Author: D.H. Wright (SLAC) //
// Date: 11 December 2014 //
// //
////////////////////////////////////////////////////////////////////////////////
#include "G4NuclearDecay.hh"
#include "G4SystemOfUnits.hh"
G4NuclearDecay::G4NuclearDecay(const G4String& channelName,
const G4RadioactiveDecayMode& aMode,
const G4double& excitationE)
: G4VDecayChannel(channelName), theMode(aMode),daughterEx(excitationE),
halflifeThreshold(nanosecond)
{}
G4NuclearDecay::~G4NuclearDecay()
{}
@@ -72,7 +72,6 @@
#include "G4PhysicsLogVector.hh"
#include "G4ParticleChangeForRadDecay.hh"
#include "G4IonTable.hh"
#include "G4BetaFermiFunction.hh"
#include "G4PhotonEvaporation.hh"
#include "G4VAtomDeexcitation.hh"
@@ -302,6 +301,7 @@ G4DecayProducts* G4NuclearDecayChannel::DecayIt(G4double)
daughterMomentum.setE(daughterMomentum.e() + exe);
}
G4Fragment nucleus(daughterA, daughterZ, daughterMomentum);
G4PhotonEvaporation* deexcitation = new G4PhotonEvaporation;
deexcitation->SetVerboseLevel(GetVerboseLevel());
@@ -333,6 +333,7 @@ G4DecayProducts* G4NuclearDecayChannel::DecayIt(G4double)
if (decayMode != 0) {
daughterIon = theIonTable->GetIon(daughterZ, daughterA, daughterExcitation);
} else {
// The fragment vector from photon evaporation contains the list of
// evaporated gammas, some of which may have been replaced by conversion
@@ -372,13 +373,13 @@ G4DecayProducts* G4NuclearDecayChannel::DecayIt(G4double)
daughterMomentum.setE(daughterMomentum.e() - eOrGammaEnergy);
// Delete/reset variables associated with the gammas.
while (!gammas->empty() ) {
while (!gammas->empty() ) { /* Loop checking, 01.09.2015, D.Wright */
delete *(gammas->end()-1);
gammas->pop_back();
}
delete gammas;
} // end if decayMode == 0
G4ThreeVector const daughterMomentum1(static_cast<const G4LorentzVector> (daughterMomentum));
dynamicDaughter = new G4DynamicParticle(daughterIon, daughterMomentum1);
products->PushProducts(dynamicDaughter);
@@ -439,7 +440,14 @@ G4DecayProducts* G4NuclearDecayChannel::DecayIt(G4double)
G4AtomicShellEnumerator as = G4AtomicShellEnumerator(eShell);
const G4AtomicShell* shell = atomDeex->GetAtomicShell(aZ, as);
std::vector<G4DynamicParticle*> armProducts;
const G4double deexLimit = 0.1*keV;
// VI, SI
// Allows fixing of Bugzilla 1727
//const G4double deexLimit = 0.1*keV;
G4double deexLimit = 0.1*keV;
if (G4EmParameters::Instance()->DeexcitationIgnoreCut()) deexLimit =0.;
//
atomDeex->GenerateParticles(&armProducts, shell, aZ, deexLimit, deexLimit);
size_t narm = armProducts.size();
if (narm > 0) {
@@ -0,0 +1,136 @@
//
// ********************************************************************
// * 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: G4ProtonDecay.cc //
// Author: L.G. Sarmiento (Lund) //
// Date: 10 March 2015 //
// //
////////////////////////////////////////////////////////////////////////////////
#include "G4ProtonDecay.hh"
#include "G4IonTable.hh"
#include "Randomize.hh"
#include "G4ThreeVector.hh"
#include "G4DynamicParticle.hh"
#include "G4DecayProducts.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include <iostream>
#include <iomanip>
G4ProtonDecay::G4ProtonDecay(const G4ParticleDefinition* theParentNucleus,
const G4double& branch, const G4double& Qvalue,
const G4double& excitationE)
: G4NuclearDecay("proton decay", Proton, excitationE), transitionQ(Qvalue)
{
SetParent(theParentNucleus); // Store name of parent nucleus, delete G4MT_parent
SetBR(branch);
SetNumberOfDaughters(2);
G4IonTable* theIonTable =
(G4IonTable*)(G4ParticleTable::GetParticleTable()->GetIonTable());
G4int daughterZ = theParentNucleus->GetAtomicNumber() - 1;
G4int daughterA = theParentNucleus->GetAtomicMass() - 1;
SetDaughter(0, theIonTable->GetIon(daughterZ, daughterA, excitationE) );
SetDaughter(1, "proton");
}
G4ProtonDecay::~G4ProtonDecay()
{}
G4DecayProducts* G4ProtonDecay::DecayIt(G4double)
{
// Fill G4MT_parent with theParentNucleus (stored by SetParent in ctor)
if (G4MT_parent == 0) FillParent();
// Fill G4MT_daughters with proton and residual nucleus (stored by SetDaughter)
if (G4MT_daughters == 0) FillDaughters();
G4double protonMass = G4MT_daughters[1]->GetPDGMass();
// Excitation energy included in PDG mass
G4double nucleusMass = G4MT_daughters[0]->GetPDGMass();
// Q value was calculated from atomic masses.
// Use it to get correct proton energy.
G4double cmMomentum = std::sqrt(transitionQ*(transitionQ + 2.*protonMass)*
(transitionQ + 2.*nucleusMass)*
(transitionQ + 2.*protonMass + 2.*nucleusMass) )/
(transitionQ + protonMass + nucleusMass)/2.;
// Set up final state
// parentParticle is set at rest here because boost with correct momentum
// is done later
G4DynamicParticle parentParticle(G4MT_parent, G4ThreeVector(0,0,0), 0.0);
G4DecayProducts* products = new G4DecayProducts(parentParticle);
G4double costheta = 2.*G4UniformRand()-1.0;
G4double sintheta = std::sqrt(1.0 - costheta*costheta);
G4double phi = twopi*G4UniformRand()*rad;
G4ThreeVector direction(sintheta*std::cos(phi),sintheta*std::sin(phi),
costheta);
G4double KE = std::sqrt(cmMomentum*cmMomentum + protonMass*protonMass)
- protonMass;
G4DynamicParticle* daughterparticle =
new G4DynamicParticle(G4MT_daughters[1], direction, KE, protonMass);
products->PushProducts(daughterparticle);
KE = std::sqrt(cmMomentum*cmMomentum + nucleusMass*nucleusMass) - nucleusMass;
daughterparticle =
new G4DynamicParticle(G4MT_daughters[0], -1.0*direction, KE, nucleusMass);
products->PushProducts(daughterparticle);
// Energy conservation check
// For proton decays, do final energy check against reaction Q value
// which is well-measured using atomic mass differences. Nuclear masses
// should not be used since they are not usually directly measured and we
// always decay atoms and not fully stripped nuclei.
/*
G4int nProd = products->entries();
G4DynamicParticle* temp = 0;
G4double Esum = 0.0;
for (G4int i = 0; i < nProd; i++) {
temp = products->operator[](i);
Esum += temp->GetKineticEnergy();
}
G4double eCons = (transitionQ - Esum)/keV;
if (eCons > 1.e-07) G4cout << " Proton decay check: Ediff (keV) = " << eCons << G4endl;
*/
return products;
}
void G4ProtonDecay::DumpNuclearInfo()
{
G4cout << " G4ProtonDecay for parent nucleus " << GetParentName() << G4endl;
G4cout << " decays to " << GetDaughterName(0) << " + " << GetDaughterName(1)
<< " with branching ratio " << GetBR() << "% and Q value "
<< transitionQ << G4endl;
}
@@ -81,7 +81,7 @@
const G4double G4RIsotopeTable::levelTolerance = 2.0*keV;
G4RIsotopeTable::G4RIsotopeTable()
G4RIsotopeTable::G4RIsotopeTable():G4VIsotopeTable("RIsotopeTable")
{
// Reset the list of user defined data files
theUserRadioactiveDataFiles.clear();
@@ -209,7 +209,16 @@ G4double G4RIsotopeTable::GetMeanLifeTime(G4int Z, G4int A, G4double& aE)
G4double a(0.0);
G4double b(0.0);
while (!found_in_raddecay_data && !DecaySchemeFile.getline(inputChars, 100).eof()) {
G4int loop = 0;
G4ExceptionDescription ed;
ed << " While count exceeded " << G4endl;
while (!found_in_raddecay_data && !DecaySchemeFile.getline(inputChars, 100).eof()) { /* Loop checking, 01.09.2015, D.Wright */
loop++;
if (loop > 100000) {
G4Exception("G4RIsotopeTable::GetMeanLifeTime()", "HAD_RDM_100", JustWarning, ed);
break;
}
inputLine = inputChars;
inputLine = inputLine.strip(1);
@@ -43,6 +43,9 @@
//
// CHANGE HISTORY
// --------------
//
// 13 Oct 2015, L.G. Sarmiento Neutron emission added
//
// 06 Aug 2014, L.G. Sarmiento Proton decay mode added mimicking the alpha decay
//
// 03 Oct 2012, V. Ivanchenko removed internal table for mean free path
@@ -103,22 +106,20 @@
#include "G4DecayProducts.hh"
#include "G4DecayTable.hh"
#include "G4ParticleChangeForRadDecay.hh"
#include "G4ITDecayChannel.hh"
#include "G4BetaMinusDecayChannel.hh"
#include "G4BetaPlusDecayChannel.hh"
#include "G4KshellECDecayChannel.hh"
#include "G4LshellECDecayChannel.hh"
#include "G4MshellECDecayChannel.hh"
// #include "G4AlphaDecayChannel.hh"
#include "G4ITDecay.hh"
#include "G4BetaDecayType.hh"
#include "G4BetaMinusDecay.hh"
#include "G4BetaPlusDecay.hh"
#include "G4ECDecay.hh"
#include "G4AlphaDecay.hh"
#include "G4ProtonDecayChannel.hh"
#include "G4ProtonDecay.hh"
#include "G4NeutronDecay.hh"
#include "G4VDecayChannel.hh"
#include "G4NuclearDecay.hh"
#include "G4RadioactiveDecayMode.hh"
#include "G4Ions.hh"
#include "G4IonTable.hh"
#include "G4RIsotopeTable.hh"
#include "G4BetaDecayType.hh"
#include "G4BetaDecayCorrections.hh"
#include "Randomize.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4NuclearLevelManager.hh"
@@ -132,8 +133,10 @@
#include "G4Proton.hh"
#include "G4HadronicProcessType.hh"
#include "G4HadronicException.hh"
#include "G4LossTableManager.hh"
#include "G4VAtomDeexcitation.hh"
#include "G4UAtomicDeexcitation.hh"
#include <vector>
#include <sstream>
@@ -142,9 +145,12 @@
using namespace CLHEP;
const G4double G4RadioactiveDecay::levelTolerance = 2.0*keV;
const G4double G4RadioactiveDecay::levelTolerance = 0.1*keV;
const G4ThreeVector G4RadioactiveDecay::origin(0.,0.,0.);
#ifdef G4MULTITHREADED
#include "G4AutoLock.hh"
G4Mutex G4RadioactiveDecay::radioactiveDecayMutex = G4MUTEX_INITIALIZER;
DecayTableMap* G4RadioactiveDecay::master_dkmap = 0;
#endif
@@ -163,23 +169,13 @@ G4RadioactiveDecay::G4RadioactiveDecay(const G4String& processName)
theRadioactiveDecaymessenger = new G4RadioactiveDecaymessenger(this);
pParticleChange = &fParticleChangeForRadDecay;
theIsotopeTable = new G4RIsotopeTable();
// Regsiter the isotope table to the ion table.
// Although we are touching the ion table, which is shared, we are not
// adding particles in this operation. We can therefore do the registration
// for each instance of the RDM process and do not need to restrict it to the
// master process. It's possible that future, more optimized versions of
// G4IonTable will require to test for master.
G4IonTable* theIonTable = G4ParticleTable::GetParticleTable()->GetIonTable();
theIonTable->RegisterIsotopeTable(theIsotopeTable);
// Reset the list of user defined data files
theUserRadioactiveDataFiles.clear();
// Instantiate the map of decay tables
#ifdef G4MULTITHREADED
G4AutoLock lk(&G4RadioactiveDecay::radioactiveDecayMutex);
if(!master_dkmap) master_dkmap = new DecayTableMap;
#endif
dkmap = new DecayTableMap;
@@ -206,7 +202,7 @@ G4RadioactiveDecay::G4RadioactiveDecay(const G4String& processName)
applyARM = true ;
halflifethreshold = nanosecond;
// RDM applies to xall logical volumes as default
// RDM applies to all logical volumes by default
isAllVolumesMode = true;
SelectAllVolumes();
}
@@ -215,7 +211,6 @@ G4RadioactiveDecay::G4RadioactiveDecay(const G4String& processName)
G4RadioactiveDecay::~G4RadioactiveDecay()
{
delete theRadioactiveDecaymessenger;
delete theIsotopeTable;
for (DecayTableMap::iterator i = dkmap->begin(); i != dkmap->end(); i++) {
delete i->second;
}
@@ -385,16 +380,33 @@ G4RadioactiveDecay::GetDecayRateTable(const G4ParticleDefinition& aParticle)
// GetTaoTime performs the convolution of the source time profile function
// with the decay constants in the decay chain.
// The time profile is treated as a step function so that the convolution
// integral can be done bin-by-bin.
// The profile function should be normalized to 1. Is it??
G4double G4RadioactiveDecay::GetTaoTime(const G4double t, const G4double tao)
{
long double taotime = 0.L;
G4int nbin;
if ( t > SBin[NSourceBin]) {
nbin = NSourceBin;}
else {
nbin = NSourceBin;
} else {
nbin = 0;
while (t > SBin[nbin]) nbin++;
nbin--;}
G4int loop = 0;
G4ExceptionDescription ed;
ed << " While count exceeded " << G4endl;
while (t > SBin[nbin]) { /* Loop checking, 01.09.2015, D.Wright */
loop++;
if (loop > 1000) {
G4Exception("G4RadioactiveDecay::GetTaoTime()", "HAD_RDM_100", JustWarning, ed);
break;
}
nbin++;
}
nbin--;
}
long double lt = t ;
long double ltao = tao;
@@ -405,6 +417,9 @@ G4double G4RadioactiveDecay::GetTaoTime(const G4double t, const G4double tao)
}
}
taotime += (long double)SProfile[nbin] * (1.L-std::exp(-(lt-(long double)SBin[nbin])/ltao));
// Is the above line necessary? If so, the 1.L looks incorrect - should be an exp
// Also, it looks like the final integral should be multiplied by ltao
if (taotime < 0.) {
G4cout <<" Tao time =: " <<taotime << " reset to zero!"<<G4endl;
G4cout <<" t = " << t <<" tao = " <<tao <<G4endl;
@@ -541,7 +556,19 @@ G4double G4RadioactiveDecay::GetDecayTime()
G4double decaytime = 0.;
G4double rand = G4UniformRand();
G4int i = 0;
while ( DProfile[i] < rand) i++;
G4int loop = 0;
G4ExceptionDescription ed;
ed << " While count exceeded " << G4endl;
while ( DProfile[i] < rand) { /* Loop checking, 01.09.2015, D.Wright */
i++;
loop++;
if (loop > 100000) {
G4Exception("G4RadioactiveDecay::GetDecayTime()", "HAD_RDM_100", JustWarning, ed);
break;
}
}
rand = G4UniformRand();
decaytime = DBin[i] + rand*(DBin[i+1]-DBin[i]);
#ifdef G4VERBOSE
@@ -555,7 +582,19 @@ G4double G4RadioactiveDecay::GetDecayTime()
G4int G4RadioactiveDecay::GetDecayTimeBin(const G4double aDecayTime)
{
G4int i = 0;
while ( aDecayTime > DBin[i] ) i++;
G4int loop = 0;
G4ExceptionDescription ed;
ed << " While count exceeded " << G4endl;
while ( aDecayTime > DBin[i] ) { /* Loop checking, 01.09.2015, D.Wright */
i++;
loop++;
if (loop > 100000) {
G4Exception("G4RadioactiveDecay::GetDecayTimeBin()", "HAD_RDM_100", JustWarning, ed);
break;
}
}
return i;
}
@@ -577,7 +616,6 @@ G4double G4RadioactiveDecay::GetMeanLifeTime(const G4Track& theTrack,
const G4DynamicParticle* theParticle = theTrack.GetDynamicParticle();
const G4ParticleDefinition* theParticleDef = theParticle->GetDefinition();
G4double theLife = theParticleDef->GetPDGLifeTime();
#ifdef G4VERBOSE
if (GetVerboseLevel() > 2) {
G4cout << "G4RadioactiveDecay::GetMeanLifeTime() " << G4endl;
@@ -679,7 +717,14 @@ void G4RadioactiveDecay::BuildPhysicsTable(const G4ParticleDefinition&)
isInitialised = true;
G4LossTableManager* theManager = G4LossTableManager::Instance();
G4VAtomDeexcitation* p = theManager->AtomDeexcitation();
if(p) { p->InitialiseAtomicDeexcitation(); }
if (!p) {
G4UAtomicDeexcitation* atomDeex = new G4UAtomicDeexcitation();
theManager->SetAtomDeexcitation(atomDeex);
p = theManager->AtomDeexcitation();
}
p->SetFluo(true);
p->SetAuger(true);
p->InitialiseAtomicDeexcitation();
}
}
@@ -690,11 +735,6 @@ void G4RadioactiveDecay::BuildPhysicsTable(const G4ParticleDefinition&)
// //
////////////////////////////////////////////////////////////////////////////////
#ifdef G4MULTITHREADED
#include "G4AutoLock.hh"
G4Mutex G4RadioactiveDecay::radioactiveDecayMutex = G4MUTEX_INITIALIZER;
#endif
G4DecayTable*
G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
{
@@ -702,7 +742,7 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
// file containing radioactive decay data.
G4int A = ((const G4Ions*)(&theParentNucleus))->GetAtomicMass();
G4int Z = ((const G4Ions*)(&theParentNucleus))->GetAtomicNumber();
G4int lvl = ((const G4Ions*)(&theParentNucleus))->GetIsomerLevel();
G4double levelEnergy = ((const G4Ions*)(&theParentNucleus))->GetExcitationEnergy();
G4DecayTable* theDecayTable = 0;
#ifdef G4MULTITHREADED
@@ -740,10 +780,10 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
G4bool found(false);
if (DecaySchemeFile) {
// Initialise variables used for reading in radioactive decay data.
G4int nMode = 8;
G4bool modeFirstRecord[8];
G4double modeTotalBR[8] = {0.0};
G4double modeSumBR[8];
const G4int nMode = 9;
G4bool modeFirstRecord[nMode];
G4double modeTotalBR[nMode] = {0.0};
G4double modeSumBR[nMode];
for (G4int i = 0; i < nMode; i++) {
modeFirstRecord[i] = true;
modeSumBR[i] = 0.0;
@@ -757,14 +797,22 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
G4double a(0.0);
G4double b(0.0);
G4double c(0.0);
G4int levelCounter = 0;
G4BetaDecayType betaType(allowed);
G4double e0;
// Loop through each data file record until you identify the decay
// data relating to the nuclide of concern.
while (!complete && !DecaySchemeFile.getline(inputChars, 100).eof()) {
G4int loop = 0;
G4ExceptionDescription ed;
ed << " While count exceeded " << G4endl;
while (!complete && !DecaySchemeFile.getline(inputChars, 100).eof()) { /* Loop checking, 01.09.2015, D.Wright */
loop++;
if (loop > 100000) {
G4Exception("G4RadioactiveDecay::LoadDecayTable()", "HAD_RDM_100", JustWarning, ed);
break;
}
inputLine = inputChars;
inputLine = inputLine.strip(1);
if (inputChars[0] != '#' && inputLine.length() != 0) {
@@ -776,11 +824,9 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
tmpStream >> recordType >> a >> b;
if (found) {
complete = true;
// else {found = (std::abs(a*keV - E) < levelTolerance);}
} else {
found = (levelCounter == lvl);
}
levelCounter++;
found = (std::abs(a*keV - levelEnergy) < levelTolerance);
}
} else if (found) {
// The right part of the radioactive decay data file has been found. Search
@@ -796,7 +842,6 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
#endif
} else {
tmpStream >> theDecayMode >> a >> b >> c >> betaType;
// Allowed transitions are the default. Forbidden transitions are
// indicated in the last column.
if (inputLine.length() < 80) betaType = allowed;
@@ -807,12 +852,11 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
case IT: // Isomeric transition
{
G4ITDecayChannel* anITChannel =
new G4ITDecayChannel(GetVerboseLevel(),
(const G4Ions*)& theParentNucleus, b);
anITChannel->SetICM(applyICM);
anITChannel->SetARM(applyARM);
G4ITDecay* anITChannel = new G4ITDecay(&theParentNucleus, b,
c*MeV, a*MeV);
// anITChannel->DumpNuclearInfo();
anITChannel->SetHLThreshold(halflifethreshold);
anITChannel->SetARM(applyARM);
theDecayTable->Insert(anITChannel);
}
break;
@@ -824,40 +868,13 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
modeTotalBR[1] = b;
} else {
if (c > 0.) {
e0 = c*MeV/0.511;
G4BetaDecayCorrections corrections(Z+1, A);
// array to store function shape
G4int npti = 100;
G4double* pdf = new G4double[npti];
G4double e; // Total electron energy in units of electron mass
G4double p; // Electron momentum in units of electron mass
G4double f; // Spectral shape function value
for (G4int ptn = 0; ptn < npti; ptn++) {
// Calculate simple phase space spectrum
e = 1. + e0*(ptn+0.5)/100.;
p = std::sqrt(e*e - 1.);
f = p*e*(e0-e+1)*(e0-e+1);
// Apply Fermi factor to get allowed shape
f *= corrections.FermiFunction(e);
// Apply shape factor for forbidden transitions
f *= corrections.ShapeFactor(betaType, p, e0-e+1.);
pdf[ptn] = f;
}
G4RandGeneral* aRandomEnergy = new G4RandGeneral( pdf, npti);
G4BetaMinusDecayChannel *aBetaMinusChannel = new
G4BetaMinusDecayChannel(GetVerboseLevel(), &theParentNucleus,
b, c*MeV, a*MeV, 0, FBeta, aRandomEnergy);
aBetaMinusChannel->SetICM(applyICM);
aBetaMinusChannel->SetARM(applyARM);
G4BetaMinusDecay* aBetaMinusChannel =
new G4BetaMinusDecay(&theParentNucleus, b, c*MeV, a*MeV,
betaType);
// aBetaMinusChannel->DumpNuclearInfo();
aBetaMinusChannel->SetHLThreshold(halflifethreshold);
theDecayTable->Insert(aBetaMinusChannel);
modeSumBR[1] += b;
delete[] pdf;
} // c > 0
} // if not first record
}
@@ -869,45 +886,13 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
modeFirstRecord[2] = false;
modeTotalBR[2] = b;
} else {
e0 = c*MeV/0.510999 - 2.;
// Need to test e0 for nuclei which have Q < 2Me in their
// data files (e.g. z67.a162)
if (e0 > 0.) {
G4BetaDecayCorrections corrections(1-Z, A);
// array to store function shape
G4int npti = 100;
G4double* pdf = new G4double[npti];
G4double e; // Total positron energy in units of electron mass
G4double p; // Positron momentum in units of electron mass
G4double f; // Spectral shape function value
for (G4int ptn = 0; ptn < npti; ptn++) {
// Calculate simple phase space spectrum
e = 1. + e0*(ptn+0.5)/100.;
p = std::sqrt(e*e - 1.);
f = p*e*(e0-e+1)*(e0-e+1);
// Apply Fermi factor to get allowed shape
f *= corrections.FermiFunction(e);
// Apply shape factor for forbidden transitions
f *= corrections.ShapeFactor(betaType, p, e0-e+1.);
pdf[ptn] = f;
}
G4RandGeneral* aRandomEnergy = new G4RandGeneral(pdf, npti);
G4BetaPlusDecayChannel* aBetaPlusChannel = new
G4BetaPlusDecayChannel(GetVerboseLevel(),
&theParentNucleus, b,
(c-1.021998)*MeV, a*MeV, 0,
FBeta, aRandomEnergy);
aBetaPlusChannel->SetICM(applyICM);
aBetaPlusChannel->SetARM(applyARM);
aBetaPlusChannel->SetHLThreshold(halflifethreshold);
theDecayTable->Insert(aBetaPlusChannel);
modeSumBR[2] += b;
delete[] pdf;
} // if e0 > 0
G4BetaPlusDecay* aBetaPlusChannel =
new G4BetaPlusDecay(&theParentNucleus, b, c*MeV, a*MeV,
betaType);
// aBetaPlusChannel->DumpNuclearInfo();
aBetaPlusChannel->SetHLThreshold(halflifethreshold);
theDecayTable->Insert(aBetaPlusChannel);
modeSumBR[2] += b;
} // if not first record
}
break;
@@ -918,13 +903,11 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
modeFirstRecord[3] = false;
modeTotalBR[3] = b;
} else {
G4KshellECDecayChannel* aKECChannel =
new G4KshellECDecayChannel(GetVerboseLevel(),
&theParentNucleus,
b, c*MeV, a*MeV);
aKECChannel->SetICM(applyICM);
aKECChannel->SetARM(applyARM);
G4ECDecay* aKECChannel = new G4ECDecay(&theParentNucleus, b,
c*MeV, a*MeV, KshellEC);
// aKECChannel->DumpNuclearInfo();
aKECChannel->SetHLThreshold(halflifethreshold);
aKECChannel->SetARM(applyARM);
theDecayTable->Insert(aKECChannel);
modeSumBR[3] += b;
}
@@ -936,12 +919,11 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
modeFirstRecord[4] = false;
modeTotalBR[4] = b;
} else {
G4LshellECDecayChannel *aLECChannel = new
G4LshellECDecayChannel (GetVerboseLevel(), &theParentNucleus,
b, c*MeV, a*MeV);
aLECChannel->SetICM(applyICM);
aLECChannel->SetARM(applyARM);
G4ECDecay* aLECChannel = new G4ECDecay(&theParentNucleus, b,
c*MeV, a*MeV, LshellEC);
// aLECChannel->DumpNuclearInfo();
aLECChannel->SetHLThreshold(halflifethreshold);
aLECChannel->SetARM(applyARM);
theDecayTable->Insert(aLECChannel);
modeSumBR[4] += b;
}
@@ -953,13 +935,11 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
modeFirstRecord[5] = false;
modeTotalBR[5] = b;
} else {
G4MshellECDecayChannel* aMECChannel =
new G4MshellECDecayChannel(GetVerboseLevel(),
&theParentNucleus,
b, c*MeV, a*MeV);
aMECChannel->SetICM(applyICM);
aMECChannel->SetARM(applyARM);
G4ECDecay* aMECChannel = new G4ECDecay(&theParentNucleus, b,
c*MeV, a*MeV, MshellEC);
// aMECChannel->DumpNuclearInfo();
aMECChannel->SetHLThreshold(halflifethreshold);
aMECChannel->SetARM(applyARM);
theDecayTable->Insert(aMECChannel);
modeSumBR[5] += b;
}
@@ -972,15 +952,7 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
} else {
G4AlphaDecay* anAlphaChannel =
new G4AlphaDecay(&theParentNucleus, b, c*MeV, a*MeV);
// anAlphaChannel->DumpInfo();
/*
G4AlphaDecayChannel* anAlphaChannel =
new G4AlphaDecayChannel(GetVerboseLevel(),
&theParentNucleus,
b, c*MeV, a*MeV);
anAlphaChannel->SetICM(applyICM);
anAlphaChannel->SetARM(applyARM);
*/
// anAlphaChannel->DumpNuclearInfo();
anAlphaChannel->SetHLThreshold(halflifethreshold);
theDecayTable->Insert(anAlphaChannel);
modeSumBR[6] += b;
@@ -992,33 +964,52 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
modeFirstRecord[7] = false;
modeTotalBR[7] = b;
} else {
G4ProtonDecayChannel* aProtonChannel =
new G4ProtonDecayChannel(GetVerboseLevel(),
&theParentNucleus,
b, c*MeV, a*MeV);
aProtonChannel->SetICM(applyICM);
aProtonChannel->SetARM(applyARM);
G4ProtonDecay* aProtonChannel =
new G4ProtonDecay(&theParentNucleus, b, c*MeV, a*MeV);
// aProtonChannel->DumpNuclearInfo();
aProtonChannel->SetHLThreshold(halflifethreshold);
theDecayTable->Insert(aProtonChannel);
modeSumBR[7] += b;
}
break;
case Neutron:
if (modeFirstRecord[8]) {
modeFirstRecord[8] = false;
modeTotalBR[8] = b;
} else {
G4NeutronDecay* aNeutronChannel =
new G4NeutronDecay(&theParentNucleus, b, c*MeV, a*MeV);
// aNeutronChannel->DumpNuclearInfo();
aNeutronChannel->SetHLThreshold(halflifethreshold);
theDecayTable->Insert(aNeutronChannel);
modeSumBR[8] += b;
}
break;
case BDProton:
// Not yet implemented
// G4cout << " beta-delayed proton decay, a = " << a << ", b = " << b << ", c = " << c << G4endl;
break;
case BDNeutron:
// Not yet implemented
// G4cout << " beta-delayed neutron decay, a = " << a << ", b = " << b << ", c = " << c << G4endl;
break;
case Beta2Minus:
// Not yet implemented
// G4cout << " Double beta- decay, a = " << a << ", b = " << b << ", c = " << c << G4endl;
break;
case Beta2Plus:
// Not yet implemented
// G4cout << " Double beta+ decay, a = " << a << ", b = " << b << ", c = " << c << G4endl;
break;
case Proton2:
// Not yet implemented
// G4cout << " Double proton decay, a = " << a << ", b = " << b << ", c = " << c << G4endl;
break;
case Neutron2:
// Not yet implemented
// G4cout << " Double beta- decay, a = " << a << ", b = " << b << ", c = " << c << G4endl;
break;
case SpFission:
// Not yet implemented
//G4cout<<"Sp fission channel"<<a<<'\t'<<b<<'\t'<<c<<std::endl;
@@ -1030,7 +1021,7 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
FatalException, "Selected decay mode does not exist");
} // switch
} // if char == W
} // if char == P
} // if char == P
} // if char != #
} // While
@@ -1038,38 +1029,32 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
// correctly normalised.
G4VDecayChannel* theChannel = 0;
G4NuclearDecayChannel* theNuclearDecayChannel = 0;
G4NuclearDecay* theNuclearDecayChannel = 0;
G4String mode = "";
G4double theBR = 0.0;
for (G4int i = 0; i < theDecayTable->entries(); i++) {
theChannel = theDecayTable->GetDecayChannel(i);
if (theChannel->GetKinematicsName() == "alpha decay") {
theDecayMode = Alpha;
} else {
theNuclearDecayChannel = static_cast<G4NuclearDecayChannel*>(theChannel);
theDecayMode = theNuclearDecayChannel->GetDecayMode();
}
theNuclearDecayChannel = static_cast<G4NuclearDecay*>(theChannel);
theDecayMode = theNuclearDecayChannel->GetDecayMode();
if (theDecayMode != IT) {
theBR = theChannel->GetBR();
theChannel->SetBR(theBR*modeTotalBR[theDecayMode]/modeSumBR[theDecayMode]);
}
}
}
} // if (DecaySchemeFile)
DecaySchemeFile.close();
if (!found && lvl > 0) {
if (!found && levelEnergy > 0) {
// Case where IT cascade for excited isotopes has no entries in RDM database
// Decay mode is isomeric transition.
G4ITDecayChannel* anITChannel = new G4ITDecayChannel
(GetVerboseLevel(), (const G4Ions*) &theParentNucleus, 1);
anITChannel->SetICM(applyICM);
anITChannel->SetARM(applyARM);
G4ITDecay* anITChannel = new G4ITDecay(&theParentNucleus, 1.0, 0.0, 0.0);
anITChannel->SetHLThreshold(halflifethreshold);
anITChannel->SetARM(applyARM);
theDecayTable->Insert(anITChannel);
}
if (!theDecayTable) {
// There is no radioactive decay data for this nucleus. Return a null
// decay table.
G4cerr << "G4RadoactiveDecay::LoadDecayTable() : cannot find ion radioactive decay file "
@@ -1083,13 +1068,13 @@ G4RadioactiveDecay::LoadDecayTable(const G4ParticleDefinition& theParentNucleus)
}
#ifdef G4MULTITHREADED
(*master_dkmap)[key] = theDecayTable; // store in master library
//(*master_dkmap)[key] = theDecayTable; // store in master library
#endif
return theDecayTable;
}
void G4RadioactiveDecay::AddUserDecayDataFile(G4int Z, G4int A,G4String filename)
void
G4RadioactiveDecay::AddUserDecayDataFile(G4int Z, G4int A, G4String filename)
{
if (Z < 1 || A < 2) G4cout << "Z and A not valid!" << G4endl;
@@ -1097,7 +1082,6 @@ void G4RadioactiveDecay::AddUserDecayDataFile(G4int Z, G4int A,G4String filename
if (DecaySchemeFile) {
G4int ID_ion = A*1000 + Z;
theUserRadioactiveDataFiles[ID_ion] = filename;
theIsotopeTable->AddUserDecayDataFile(Z,A,filename);
} else {
G4cout << "The file " << filename << " does not exist!" << G4endl;
}
@@ -1150,8 +1134,9 @@ G4RadioactiveDecay::AddDecayRateTable(const G4ParticleDefinition& theParentNucle
taos.push_back(tao);
G4int nEntry = 0;
//fill the decay rate with the intial isotope data
SetDecayRate(Z,A,E,nGeneration,rates,taos);
// Fill the decay rate container (G4RadioactiveDecayRate) with the parent
// isotope data
SetDecayRate(Z,A,E,nGeneration,rates,taos); // Fill TP with parent lifetime
// store the decay rate in decay rate vector
theDecayRateVector.push_back(theDecayRate);
@@ -1163,13 +1148,14 @@ G4RadioactiveDecay::AddDecayRateTable(const G4ParticleDefinition& theParentNucle
G4int i;
G4int j;
G4VDecayChannel* theChannel = 0;
G4NuclearDecayChannel* theNuclearDecayChannel = 0;
G4ITDecayChannel* theITChannel = 0;
G4BetaMinusDecayChannel *theBetaMinusChannel = 0;
G4BetaPlusDecayChannel *theBetaPlusChannel = 0;
// G4AlphaDecayChannel *theAlphaChannel = 0;
G4NuclearDecay* theNuclearDecayChannel = 0;
G4ITDecay* theITChannel = 0;
G4BetaMinusDecay* theBetaMinusChannel = 0;
G4BetaPlusDecay* theBetaPlusChannel = 0;
G4AlphaDecay* theAlphaChannel = 0;
G4ProtonDecayChannel *theProtonChannel = 0;
G4ProtonDecay* theProtonChannel = 0;
G4NeutronDecay* theNeutronChannel = 0;
G4RadioactiveDecayMode theDecayMode;
G4double theBR = 0.0;
G4int AP = 0;
@@ -1188,19 +1174,31 @@ G4RadioactiveDecay::AddDecayRateTable(const G4ParticleDefinition& theParentNucle
G4double TaoPlus;
G4int nS = 0;
G4int nT = nEntry;
G4double brs[8];
const G4int nMode = 9;
G4double brs[nMode];
//
theIonTable =
(G4IonTable*)(G4ParticleTable::GetParticleTable()->GetIonTable());
while (!stable) {
G4int loop = 0;
G4ExceptionDescription ed;
ed << " While count exceeded " << G4endl;
while (!stable) { /* Loop checking, 01.09.2015, D.Wright */
loop++;
if (loop > 10000) {
G4Exception("G4RadioactiveDecay::AddDecayRateTable()", "HAD_RDM_100", JustWarning, ed);
break;
}
nGeneration++;
for (j = nS; j < nT; j++) {
// First time through, get data for parent nuclide
ZP = theDecayRateVector[j].GetZ();
AP = theDecayRateVector[j].GetA();
EP = theDecayRateVector[j].GetE();
RP = theDecayRateVector[j].GetDecayRateC();
TP = theDecayRateVector[j].GetTaos();
TP = theDecayRateVector[j].GetTaos();
if (GetVerboseLevel() > 0) {
G4cout << "G4RadioactiveDecay::AddDecayRateTable : daughters of ("
<< ZP << ", " << AP << ", " << EP
@@ -1212,15 +1210,16 @@ G4RadioactiveDecay::AddDecayRateTable(const G4ParticleDefinition& theParentNucle
aTempDecayTable = GetDecayTable(aParentNucleus);
G4DecayTable* theDecayTable = new G4DecayTable();
for (G4int k = 0; k < 8; k++) brs[k] = 0.0;
for (G4int k = 0; k < nMode; k++) brs[k] = 0.0;
// Go through the decay table and to combine the same decay channels
// Go through the decay table and sum all channels having the same decay mode
for (i = 0; i < aTempDecayTable->entries(); i++) {
theChannel = aTempDecayTable->GetDecayChannel(i);
theNuclearDecayChannel = static_cast<G4NuclearDecayChannel*>(theChannel);
theNuclearDecayChannel = static_cast<G4NuclearDecay*>(theChannel);
theDecayMode = theNuclearDecayChannel->GetDecayMode();
daughterExcitation = theNuclearDecayChannel->GetDaughterExcitation();
theDaughterNucleus = theNuclearDecayChannel->GetDaughterNucleus() ;
AD = ((const G4Ions*)(theDaughterNucleus))->GetAtomicMass();
ZD = ((const G4Ions*)(theDaughterNucleus))->GetAtomicNumber();
G4NuclearLevelManager* levelManager =
@@ -1244,53 +1243,53 @@ G4RadioactiveDecay::AddDecayRateTable(const G4ParticleDefinition& theParentNucle
} else {
brs[theDecayMode] += theChannel->GetBR();
}
}
brs[2] = brs[2]+brs[3]+brs[4]+brs[5];
} // Combine decay channels (loop i)
brs[2] = brs[2]+brs[3]+brs[4]+brs[5]; // Combine beta+ and EC
brs[3] = brs[4] =brs[5] = 0.0;
for (i= 0; i<8; i++){
for (i= 0; i<nMode; i++){ // loop over decay modes
if (brs[i] > 0.) {
switch ( i ) {
case 0:
// Decay mode is isomeric transition
theITChannel = new G4ITDecayChannel(0,
(const G4Ions*) aParentNucleus, brs[0]);
theITChannel = new G4ITDecay(aParentNucleus, brs[0], 0.0, 0.0);
theDecayTable->Insert(theITChannel);
break;
case 1:
// Decay mode is beta-
theBetaMinusChannel = new G4BetaMinusDecayChannel(0, aParentNucleus,
brs[1], 0.*MeV, 0.*MeV, 1, false, 0);
theBetaMinusChannel = new G4BetaMinusDecay(aParentNucleus, brs[1],
0.*MeV, 0.*MeV, allowed);
theDecayTable->Insert(theBetaMinusChannel);
break;
case 2:
// Decay mode is beta+ + EC.
theBetaPlusChannel = new G4BetaPlusDecayChannel(GetVerboseLevel(),
aParentNucleus, brs[2], 0.*MeV, 0.*MeV, 1, false, 0);
theBetaPlusChannel = new G4BetaPlusDecay(aParentNucleus, brs[2], // DHW: April 2015
0.*MeV, 0.*MeV, allowed);
theDecayTable->Insert(theBetaPlusChannel);
break;
case 6:
// Decay mode is alpha.
/*
theAlphaChannel = new G4AlphaDecayChannel(GetVerboseLevel(),
aParentNucleus,
brs[6], 0.*MeV, 0.*MeV);
*/
theAlphaChannel = new G4AlphaDecay(aParentNucleus, brs[6], 0.*MeV,
0.*MeV);
theDecayTable->Insert(theAlphaChannel);
break;
case 7:
// Decay mode is proton.
theProtonChannel = new G4ProtonDecayChannel(GetVerboseLevel(),
aParentNucleus,
brs[7], 0.*MeV, 0.*MeV);
theProtonChannel = new G4ProtonDecay(aParentNucleus, brs[7], 0.*MeV,
0.*MeV);
theDecayTable->Insert(theProtonChannel);
break;
case 8:
// Decay mode is neutron.
theNeutronChannel = new G4NeutronDecay(aParentNucleus, brs[8], 0.*MeV,
0.*MeV);
theDecayTable->Insert(theNeutronChannel);
break;
default:
break;
@@ -1302,12 +1301,14 @@ G4RadioactiveDecay::AddDecayRateTable(const G4ParticleDefinition& theParentNucle
//
for (i = 0; i < theDecayTable->entries(); i++){
theChannel = theDecayTable->GetDecayChannel(i);
theNuclearDecayChannel = static_cast<G4NuclearDecayChannel*>(theChannel);
theNuclearDecayChannel = static_cast<G4NuclearDecay*>(theChannel);
theBR = theChannel->GetBR();
theDaughterNucleus = theNuclearDecayChannel->GetDaughterNucleus();
// First check if the decay of the original nucleus is an IT channel,
// if true create a new groud-level nucleus
// if true create a new ground-state nucleus
if (theNuclearDecayChannel->GetDecayMode() == IT && nGeneration == 1) {
A = ((const G4Ions*)(theDaughterNucleus))->GetAtomicMass();
Z = ((const G4Ions*)(theDaughterNucleus))->GetAtomicNumber();
theDaughterNucleus=theIonTable->GetIon(Z,A,0.);
@@ -1327,13 +1328,13 @@ G4RadioactiveDecay::AddDecayRateTable(const G4ParticleDefinition& theParentNucle
// first set the taos, one simply need to add to the parent ones
taos.clear();
taos = TP;
taos = TP; // load lifetimes of all previous generations
size_t k;
//check that TaoPlus differs from other taos from at least 1.e5 relative difference
//for (k = 0; k < TP.size(); k++){
//if (std::abs((TaoPlus-TP[k])/TP[k])<1.e-5 ) TaoPlus=1.00001*TP[k];
//}
taos.push_back(TaoPlus);
taos.push_back(TaoPlus); // add daughter lifetime to list
// now calculate the coefficiencies
//
// they are in two parts, first the less than n ones
@@ -1342,7 +1343,7 @@ G4RadioactiveDecay::AddDecayRateTable(const G4ParticleDefinition& theParentNucle
long double ta1,ta2;
ta2 = (long double)TaoPlus;
for (k = 0; k < RP.size(); k++){
ta1 = (long double)TP[k];
ta1 = (long double)TP[k]; // loop over lifetimes of all previous generations
if (ta1 == ta2) {
theRate = 1.e100;
} else {
@@ -1373,16 +1374,17 @@ G4RadioactiveDecay::AddDecayRateTable(const G4ParticleDefinition& theParentNucle
SetDecayRate (Z,A,E,nGeneration,rates,taos);
theDecayRateVector.push_back(theDecayRate);
nEntry++;
}
} // end of testing daughter nucleus
} // end of i loop( the branches)
} // there are entries in the table
} // nuclide is OK to decay
} // end of loop (i) over decay table branches
// delete theDecayTable;
} //end of for j loop
} // Getting contents of decay rate vector (end loop on j)
nS = nT;
nT = nEntry;
if (nS == nT) stable = true;
}
} // while nuclide is not stable
// end of while loop
// the calculation completed here
@@ -1418,7 +1420,18 @@ void G4RadioactiveDecay::SetSourceTimeProfile(G4String filename)
G4double bin, flux;
NSourceBin = -1;
while (infile >> bin >> flux ) {
G4int loop = 0;
G4ExceptionDescription ed;
ed << " While count exceeded " << G4endl;
while (infile >> bin >> flux ) { /* Loop checking, 01.09.2015, D.Wright */
loop++;
if (loop > 10000) {
G4Exception("G4RadioactiveDecay::SetSourceTimeProfile()", "HAD_RDM_100", JustWarning, ed);
break;
}
NSourceBin++;
if (NSourceBin > 99) {
G4Exception("G4RadioactiveDecay::SetSourceTimeProfile()", "HAD_RDM_002",
@@ -1459,8 +1472,19 @@ void G4RadioactiveDecay::SetDecayBias(G4String filename)
theRadioactivityTables.clear();
NDecayBin = -1;
while (infile >> bin >> flux ) {
G4int loop = 0;
G4ExceptionDescription ed;
ed << " While count exceeded " << G4endl;
while (infile >> bin >> flux ) { /* Loop checking, 01.09.2015, D.Wright */
NDecayBin++;
loop++;
if (loop > 10000) {
G4Exception("G4RadioactiveDecay::SetDecayBias()", "HAD_RDM_100", JustWarning, ed);
break;
}
if (NDecayBin > 99) {
G4Exception("G4RadioactiveDecay::SetDecayBias()", "HAD_RDM_004",
FatalException, "Input bias file too big (>100 rows)" );
@@ -1841,7 +1865,11 @@ G4RadioactiveDecay::DoDecay(const G4ParticleDefinition& theParticleDef)
if (GetVerboseLevel() > 0) G4cout << "Select a channel..." << G4endl;
#endif
G4VDecayChannel* theDecayChannel = theDecayTable->SelectADecayChannel();
// G4DecayTable::SelectADecayChannel checks to see if sum of daughter masses
// exceeds parent mass. Pass it the parent mass + maximum Q value to account
// for difference in mass defect.
G4double parentPlusQ = theParticleDef.GetPDGMass() + 30.*MeV;
G4VDecayChannel* theDecayChannel = theDecayTable->SelectADecayChannel(parentPlusQ);
if (theDecayChannel == 0) {
// Decay channel not found.
@@ -46,10 +46,20 @@ std::istream &operator >> (std::istream& strm, G4RadioactiveDecayMode& q)
{q = Alpha;}
else if (a == "Proton")
{q = Proton;}
else if (a == "Neutron")
{q = Neutron;}
else if (a == "BDProton")
{q = BDProton;}
else if (a == "BDNeutron")
{q = BDNeutron;}
else if (a == "Beta2Minus")
{q = Beta2Minus;}
else if (a == "Beta2Plus")
{q = Beta2Plus;}
else if (a == "Proton2")
{q = Proton2;}
else if (a == "Neutron2")
{q = Neutron2;}
else if (a == "SpFission")
{q = SpFission;}
else