Import Geant4 11.3.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2024-06-28 13:08:51 +02:00
parent f7b23877ed
commit e58e650b32
5232 changed files with 239416 additions and 244360 deletions
@@ -6,6 +6,21 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-04-29 Jose Luis Rodriguez Sanchez (hadr-abla-V11-02-04)
- Added the dissipation parameter for heavy hypernuclei
## 2024-04-19 Jose Luis Rodriguez Sanchez (hadr-abla-V11-02-03)
- Cleaning up the classes doing it more general
## 2024-04-07 Jose Luis Rodriguez Sanchez (hadr-abla-V11-02-02)
- Cleaning up the class G4AblaDataDefs.hh, removed unused data structures
## 2024-03-29 Jose Luis Rodriguez Sanchez (hadr-abla-V11-02-01)
- Changed int, double and bool to G4 format and cleaning up of ABLA classes
## 2024-03-28 Jose Luis Rodriguez Sanchez (hadr-abla-V11-02-00)
- Added pragma once for compilation and array extension for super-heavy nuclei
## 2023-03-24 Alberto Ribon (hadr-abla-V11-01-00)
- G4AblaInterface : implemented method ApplyYourself to allow the coupling
between Binary Cascade (BIC) and Abla, i.e. using BIC for the cascade and
@@ -24,28 +24,20 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#pragma once
#include "globals.hh"
#include <memory>
#ifndef G4Abla_hh
#define G4Abla_hh 1
#ifdef ABLAXX_IN_GEANT4_MODE
#include "globals.hh"
#else
#include "G4INCLGeant4Compat.hh"
#include "G4INCLConfig.hh"
#endif
#include "G4AblaRandom.hh"
#include "G4AblaDataDefs.hh"
#include "G4AblaRandom.hh"
/**
* Class containing ABLA++ de-excitation code.
@@ -55,22 +47,20 @@ class G4Abla {
public:
/**
* This constructor is used by standalone test driver and the Geant4 interface.
* This constructor is used by standalone test driver and the Geant4
* interface.
*
* @param aHazard random seeds
* @param aVolant data structure for ABLA output
* @param aVarNtp data structure for transfering ABLA output to Geant4 interface
* @param aVarNtp data structure for transfering ABLA output to Geant4
* interface
*/
#ifdef ABLAXX_IN_GEANT4_MODE
G4Abla(G4Volant *aVolant, G4VarNtp *aVarntp);
#else
G4Abla(G4INCL::Config *config, G4Volant *aVolant, G4VarNtp *aVarntp);
#endif
G4Abla(G4VarNtp *aVarntp);
/**
* Basic destructor.
*/
~G4Abla();
~G4Abla() = default;
/// \brief Dummy copy constructor
G4Abla(G4Abla const &other);
@@ -83,26 +73,23 @@ public:
*/
void setVerboseLevel(G4int level);
/**
* Get the internal output data structure pointer.
*/
G4Volant* getVolant() {
return volant;
}
/**
* Main interface to the de-excitation code.
*
* @param nucleusA mass number of the nucleus
* @param nucleusZ charge number of the nucleus
* @param excitationEnergy excitation energy of the nucleus
* @param angularMomentum angular momentum of the nucleus (produced as output by INCL4)
* @param angularMomentum angular momentum of the nucleus (produced as output
* by INCL4)
* @param momX momentum x-component
* @param momY momentum y-component
* @param momZ momentum z-component
* @param eventnumber number of the event
*/
void DeexcitationAblaxx(G4int nucleusA, G4int nucleusZ, G4double excitationEnergy, G4double angularMomentum, G4double momX, G4double momY, G4double momZ, G4int eventnumber);
void DeexcitationAblaxx(G4int nucleusA, G4int nucleusZ,
G4double excitationEnergy, G4double angularMomentum,
G4double momX, G4double momY, G4double momZ,
G4int eventnumber);
/**
* Main interface to the de-excitation code for hyper-nuclei.
@@ -110,14 +97,18 @@ public:
* @param nucleusA mass number of the nucleus
* @param nucleusZ charge number of the nucleus
* @param excitationEnergy excitation energy of the nucleus
* @param angularMomentum angular momentum of the nucleus (produced as output by INCL)
* @param angularMomentum angular momentum of the nucleus (produced as output
* by INCL)
* @param momX momentum x-component
* @param momY momentum y-component
* @param momZ momentum z-component
* @param eventnumber number of the event
* @param nucleusS is the strange number
*/
void DeexcitationAblaxx(G4int nucleusA, G4int nucleusZ, G4double excitationEnergy, G4double angularMomentum, G4double momX, G4double momY, G4double momZ, G4int eventnumber, G4int nucleusS);
void DeexcitationAblaxx(G4int nucleusA, G4int nucleusZ,
G4double excitationEnergy, G4double angularMomentum,
G4double momX, G4double momY, G4double momZ,
G4int eventnumber, G4int nucleusS);
// Evaporation
public:
@@ -135,18 +126,19 @@ public:
void SetParametersG4(G4int z, G4int a);
/**
* Coefficient of collective enhancement including damping
* Input: z,a,bet,sig,u
* Output: qr - collective enhancement factor
* See junghans et al., nucl. phys. a 629 (1998) 635
* Coefficient of collective enhancement including damping
* Input: z,a,bet,sig,u
* Output: qr - collective enhancement factor
* See junghans et al., nucl. phys. a 629 (1998) 635
* @param z charge number
* @param a mass number
* @param bet beta deformation
* @param sig perpendicular spin cut-off factor
* @param u Energy
* @return Coefficient of collective enhancement
* @return Coefficient of collective enhancement
*/
void qrot(G4double z, G4double a, G4double bet, G4double sig, G4double u, G4double *qr);
void qrot(G4double z, G4double a, G4double bet, G4double sig, G4double u,
G4double *qr);
/**
* Model de la goutte liquide de c. f. weizsacker.
@@ -167,202 +159,263 @@ public:
/**
* Calculation of fissility parameter
*/
G4double fissility(G4int a, G4int z, G4int ny, G4double sn, G4double slam, G4int optxfis);
G4double fissility(G4int a, G4int z, G4int ny, G4double sn, G4double slam,
G4int optxfis);
/**
* Main evaporation routine.
*/
void evapora(G4double zprf, G4double aprf, G4double *ee_par, G4double jprf,
G4double *zf_par, G4double *af_par, G4double *mtota_par,
G4double *vleva_par, G4double *vxeva_par, G4double *vyeva_par,
G4int *ff_par, G4int *fimf_par, G4double *fzimf, G4double *faimf, G4double *tkeimf_par,G4double *jprfout,G4int *inttype_par, G4int *inum_par,G4double EV_TEMP[200][6],G4int *iev_tab_temp_par, G4int *nblam0);
void evapora(G4double zprf, G4double aprf, G4double *ee_par, G4double jprf,
G4double *zf_par, G4double *af_par, G4double *mtota_par,
G4double *vleva_par, G4double *vxeva_par, G4double *vyeva_par,
G4int *ff_par, G4int *fimf_par, G4double *fzimf, G4double *faimf,
G4double *tkeimf_par, G4double *jprfout, G4int *inttype_par,
G4int *inum_par, G4double EV_TEMP[indexpart][6],
G4int *iev_tab_temp_par, G4int *nblam0);
/**
* Calculation of particle emission probabilities.
*/
void direct(G4double zprf, G4double a, G4double ee, G4double jprf, G4double *probp_par, G4double *probd_par, G4double *probt_par, G4double *probn_par, G4double *probhe_par, G4double *proba_par, G4double *probg_par,G4double *probimf_par,G4double *probf_par,G4double *problamb0_par, G4double *ptotl_par, G4double *sn_par, G4double *sbp_par, G4double *sbd_par, G4double *sbt_par, G4double *sbhe_par, G4double *sba_par,G4double *slamb0_par, G4double *ecn_par, G4double *ecp_par, G4double *ecd_par, G4double *ect_par,G4double *eche_par,G4double *eca_par, G4double *ecg_par, G4double *eclamb0_par, G4double *bp_par, G4double *bd_par, G4double *bt_par, G4double *bhe_par, G4double *ba_par,G4double *sp_par,G4double *sd_par,G4double *st_par,G4double *she_par,G4double *sa_par, G4double *ef_par,G4double *ts1_par, G4int, G4int inum, G4int itest, G4int *sortie, G4double *tcn,G4double *jprfn_par, G4double *jprfp_par, G4double *jprfd_par, G4double *jprft_par, G4double *jprfhe_par, G4double *jprfa_par, G4double *jprflamb0_par, G4double *tsum_par, G4int NbLam0);
void direct(G4double zprf, G4double a, G4double ee, G4double jprf,
G4double *probp_par, G4double *probd_par, G4double *probt_par,
G4double *probn_par, G4double *probhe_par, G4double *proba_par,
G4double *probg_par, G4double *probimf_par, G4double *probf_par,
G4double *problamb0_par, G4double *ptotl_par, G4double *sn_par,
G4double *sbp_par, G4double *sbd_par, G4double *sbt_par,
G4double *sbhe_par, G4double *sba_par, G4double *slamb0_par,
G4double *ecn_par, G4double *ecp_par, G4double *ecd_par,
G4double *ect_par, G4double *eche_par, G4double *eca_par,
G4double *ecg_par, G4double *eclamb0_par, G4double *bp_par,
G4double *bd_par, G4double *bt_par, G4double *bhe_par,
G4double *ba_par, G4double *sp_par, G4double *sd_par,
G4double *st_par, G4double *she_par, G4double *sa_par,
G4double *ef_par, G4double *ts1_par, G4int, G4int inum,
G4int itest, G4int *sortie, G4double *tcn, G4double *jprfn_par,
G4double *jprfp_par, G4double *jprfd_par, G4double *jprft_par,
G4double *jprfhe_par, G4double *jprfa_par,
G4double *jprflamb0_par, G4double *tsum_par, G4int NbLam0);
/**
* Calculation of fission and the particle emission probabilities after fission.
* Calculation of fission and the particle emission probabilities after
* fission.
*/
void fission(G4double AF,G4double ZF,G4double EE,G4double JPRF,
G4double *VX1_FISSION,G4double *VY1_FISSION,G4double *VZ1_FISSION,
G4double *VX2_FISSION,G4double *VY2_FISSION,G4double *VZ2_FISSION,
G4int *ZFP1,G4int *AFP1,G4int *SFP1,G4int *ZFP2,G4int *AFP2,G4int *SFP2,G4int *imode,
G4double *VX_EVA_SC, G4double *VY_EVA_SC, G4double *VZ_EVA_SC,
G4double EV_TEMP[200][6],G4int *IEV_TAB_FIS,G4int *NbLam0);
void fission(G4double AF, G4double ZF, G4double EE, G4double JPRF,
G4double *VX1_FISSION, G4double *VY1_FISSION,
G4double *VZ1_FISSION, G4double *VX2_FISSION,
G4double *VY2_FISSION, G4double *VZ2_FISSION, G4int *ZFP1,
G4int *AFP1, G4int *SFP1, G4int *ZFP2, G4int *AFP2, G4int *SFP2,
G4int *imode, G4double *VX_EVA_SC, G4double *VY_EVA_SC,
G4double *VZ_EVA_SC, G4double EV_TEMP[indexpart][6],
G4int *IEV_TAB_FIS, G4int *NbLam0);
/**
* Calculation of lorentz's boost
*/
void lorentz_boost(G4double VXRIN,G4double VYRIN,G4double VZRIN,G4double VXIN,G4double VYIN,G4double VZIN,G4double *VXOUT,G4double *VYOUT,G4double *VZOUT);
void lorentz_boost(G4double VXRIN, G4double VYRIN, G4double VZRIN,
G4double VXIN, G4double VYIN, G4double VZIN,
G4double *VXOUT, G4double *VYOUT, G4double *VZOUT);
/**
* Calculation of unstable nuclei
*/
void unstable_nuclei(G4int AFP,G4int ZFP,G4int *AFPNEW,G4int *ZFPNEW,G4int &IOUNSTABLE,G4double VX,G4double VY,G4double VZ,G4double *VP1X,G4double *VP1Y,G4double *VP1Z,G4double BU_TAB_TEMP[200][6],G4int *ILOOP);
void unstable_nuclei(G4int AFP, G4int ZFP, G4int *AFPNEW, G4int *ZFPNEW,
G4int &IOUNSTABLE, G4double VX, G4double VY, G4double VZ,
G4double *VP1X, G4double *VP1Y, G4double *VP1Z,
G4double BU_TAB_TEMP[indexpart][6], G4int *ILOOP);
/**
* Calculation of unstable nuclei tke
*/
void unstable_tke(G4double AIN,G4double ZIN,G4double ANEW,G4double ZNEW,G4double VXIN,G4double VYIN,G4double VZIN,G4double *V1X,G4double *V1Y,G4double *V1Z,G4double *V2X,G4double *V2Y,G4double *V2Z);
void unstable_tke(G4double AIN, G4double ZIN, G4double ANEW, G4double ZNEW,
G4double VXIN, G4double VYIN, G4double VZIN, G4double *V1X,
G4double *V1Y, G4double *V1Z, G4double *V2X, G4double *V2Y,
G4double *V2Z);
/**
* Calculation of tke for breakup fragments
*/
void tke_bu(G4double Z,G4double A,G4double ZALL,G4double AAL,G4double *VX,G4double *VY,G4double *VZ);
void tke_bu(G4double Z, G4double A, G4double ZALL, G4double AAL, G4double *VX,
G4double *VY, G4double *VZ);
/**
* Calculation of the angular momentum of breakup fragments
* according to Goldhaber model
*/
void AMOMENT(G4double AABRA,G4double APRF,G4int IMULTIFR,G4double *PX,G4double *PY,G4double *PZ);
void AMOMENT(G4double AABRA, G4double APRF, G4int IMULTIFR, G4double *PX,
G4double *PY, G4double *PZ);
/**
* Calculation of particle emission barriers.
*/
void barrs(G4int Z1,G4int A1,G4int Z2,G4int A2,G4double *sBARR,G4double *sOMEGA);
void barrs(G4int Z1, G4int A1, G4int Z2, G4int A2, G4double *sBARR,
G4double *sOMEGA);
/**
* Calculation of particle emission between the saddle and scission point.
*/
void evap_postsaddle(G4double A, G4double Z, G4double E_scission_pre, G4double *E_scission_post, G4double *A_scission, G4double *Z_scission,
G4double &vx_eva,G4double &vy_eva,G4double &vz_eva,G4int *NbLam0_par);
void evap_postsaddle(G4double A, G4double Z, G4double E_scission_pre,
G4double *E_scission_post, G4double *A_scission,
G4double *Z_scission, G4double &vx_eva, G4double &vy_eva,
G4double &vz_eva, G4int *NbLam0_par);
/**
* Calculation of imfs.
*/
void imf(G4double ACN,G4double ZCN,G4double TEMP,G4double EE,G4double *ZIMF,G4double *AIMF,G4double *BIMF,G4double *SBIMF,G4double *TIMF,G4double JPRF);
void imf(G4double ACN, G4double ZCN, G4double TEMP, G4double EE,
G4double *ZIMF, G4double *AIMF, G4double *BIMF, G4double *SBIMF,
G4double *TIMF, G4double JPRF);
/**
* Calculation of omega at saddle point.
*/
void fomega_sp(G4double AF,G4double Y,G4double *MFCD,G4double *sOMEGA,G4double *sHOMEGA);
void fomega_sp(G4double AF, G4double Y, G4double *MFCD, G4double *sOMEGA,
G4double *sHOMEGA);
/**
* Calculation of omega at ground state.
*/
void fomega_gs(G4double AF,G4double ZF,G4double *K1,G4double *sOMEGA,G4double *sHOMEGA);
void fomega_gs(G4double AF, G4double ZF, G4double *K1, G4double *sOMEGA,
G4double *sHOMEGA);
/**
* Calculation of tunnelling effect in fission.
*/
G4double tunnelling(G4double A,G4double ZPRF,G4double Y,G4double EE,G4double EF,G4double TEMP,G4double DENSG,G4double DENSF,G4double ENH_FACT);
G4double tunnelling(G4double A, G4double ZPRF, G4double Y, G4double EE,
G4double EF, G4double TEMP, G4double DENSG,
G4double DENSF, G4double ENH_FACT);
/**
* Calculation of fission width at the saddle point according to B&W.
*/
void fission_width(G4double ZPRF,G4double A,G4double EE,G4double BS,G4double BK,G4double EF,G4double Y,G4double *GF,G4double *TEMP,G4double JPR,G4int IEROT,G4int FF_ALLOWED,G4int OPTCOL,G4int OPTSHP,G4double DENSG);
void fission_width(G4double ZPRF, G4double A, G4double EE, G4double BS,
G4double BK, G4double EF, G4double Y, G4double *GF,
G4double *TEMP, G4double JPR, G4int IEROT,
G4int FF_ALLOWED, G4int OPTCOL, G4int OPTSHP,
G4double DENSG);
/**
* Calculation of unbound nuclei.
*/
void unbound(G4double SN,G4double SP,G4double SD,G4double ST,G4double SHE,G4double SA,G4double BP,G4double BD,G4double BT,G4double BHE,G4double BA,G4double *PROBF,G4double *PROBN,G4double *PROBP,G4double *PROBD,G4double *PROBT,G4double *PROBHE,G4double *PROBA,G4double *PROBIMF,G4double *PROBG,G4double *ECN,G4double *ECP,G4double *ECD,G4double *ECT,G4double *ECHE,G4double *ECA);
void unbound(G4double SN, G4double SP, G4double SD, G4double ST, G4double SHE,
G4double SA, G4double BP, G4double BD, G4double BT, G4double BHE,
G4double BA, G4double *PROBF, G4double *PROBN, G4double *PROBP,
G4double *PROBD, G4double *PROBT, G4double *PROBHE,
G4double *PROBA, G4double *PROBIMF, G4double *PROBG,
G4double *ECN, G4double *ECP, G4double *ECD, G4double *ECT,
G4double *ECHE, G4double *ECA);
/**
* Calculation of the fission distribution.
*/
void fissionDistri(G4double &a,G4double &z,G4double &e,
G4double &a1,G4double &z1,G4double &e1,G4double &v1,
G4double &a2,G4double &z2,G4double &e2,G4double &v2,
G4double &vx_eva_sc,G4double &vy_eva_sc,
G4double &vz_eva_sc,G4int *NbLam0_par);
void fissionDistri(G4double &a, G4double &z, G4double &e, G4double &a1,
G4double &z1, G4double &e1, G4double &v1, G4double &a2,
G4double &z2, G4double &e2, G4double &v2,
G4double &vx_eva_sc, G4double &vy_eva_sc,
G4double &vz_eva_sc, G4int *NbLam0_par);
/**
* Calculation of even-odd effects in fission.
*/
void even_odd(G4double r_origin,G4double r_even_odd,G4int &i_out);
void even_odd(G4double r_origin, G4double r_even_odd, G4int &i_out);
/**
* Functions for the fission model.
*/
G4double umass(G4double z,G4double n,G4double beta);
G4double ecoul(G4double z1,G4double n1,G4double beta1,G4double z2,G4double n2,G4double beta2,G4double d);
G4double Uwash(G4double E, G4double Ecrit,G4double Freduction,G4double gamma);
G4double frldm(G4double z,G4double n,G4double beta);
G4double eflmac_profi(G4double a,G4double z);
G4double umass(G4double z, G4double n, G4double beta);
G4double ecoul(G4double z1, G4double n1, G4double beta1, G4double z2,
G4double n2, G4double beta2, G4double d);
G4double Uwash(G4double E, G4double Ecrit, G4double Freduction,
G4double gamma);
G4double frldm(G4double z, G4double n, G4double beta);
G4double eflmac_profi(G4double a, G4double z);
G4double gausshaz(G4int k, G4double xmoy, G4double sig);
G4double haz(G4int k);
/**
* Level density parameters.
*/
void densniv(G4double a, G4double z, G4double ee, G4double ef, G4double *dens, G4double bshell, G4double bs, G4double bk,
G4double *temp, G4int optshp, G4int optcol, G4double defbet, G4double *ecor, G4double jprf, G4int ifis,G4double *qr);
void densniv(G4double a, G4double z, G4double ee, G4double ef, G4double *dens,
G4double bshell, G4double bs, G4double bk, G4double *temp,
G4int optshp, G4int optcol, G4double defbet, G4double *ecor,
G4double jprf, G4int ifis, G4double *qr);
/**
* Calculation of the fission probability modified by transient time effects.
*/
void part_fiss(G4double BET,G4double GP,G4double GF,G4double Y,G4double TAUF,G4double TS1,G4double TSUM,G4int *CHOICE,G4double ZF,G4double AF,G4double FT,G4double *T_LAPSE,G4double *GF_LOC);
void part_fiss(G4double BET, G4double GP, G4double GF, G4double Y,
G4double TAUF, G4double TS1, G4double TSUM, G4int *CHOICE,
G4double ZF, G4double AF, G4double FT, G4double *T_LAPSE,
G4double *GF_LOC);
G4double func_trans(G4double TIME,G4double ZF,G4double AF,G4double BET,G4double Y,G4double FT,G4double T_0);
G4double func_trans(G4double TIME, G4double ZF, G4double AF, G4double BET,
G4double Y, G4double FT, G4double T_0);
/**
* This subroutine calculates the ordinary legendre polynomials of
* order 0 to n-1 of argument x and stores them in the vector pl.
* They are calculated by recursion relation from the first two
* polynomials.
* Written by A.J.Sierk LANL t-9 February, 1984
* This subroutine calculates the ordinary legendre polynomials of
* order 0 to n-1 of argument x and stores them in the vector pl.
* They are calculated by recursion relation from the first two
* polynomials.
* Written by A.J.Sierk LANL t-9 February, 1984
*/
void lpoly(G4double x, G4int n, G4double pl[]);
/**
* This function will calculate the liquid-drop nuclear mass for spheri
* configuration according to the preprint NUCLEAR GROUND-STATE
* configuration according to the preprint NUCLEAR GROUND-STATE
* MASSES and DEFORMATIONS by P. Mo"ller et al. from August 16, 1993 p.
* All constants are taken from this publication for consistency.
* All constants are taken from this publication for consistency.
*/
G4double eflmac(G4int ia, G4int iz, G4int flag, G4int optshp);
/**
* Procedure for calculating the pairing correction to the binding
* Procedure for calculating the pairing correction to the binding
* energy of a specific nucleus.
*/
void appariem(G4double a, G4double z, G4double *del);
/**
* PROCEDURE FOR CALCULATING THE PARITY OF THE NUMBER N.
* RETURNS -1 IF N IS ODD AND +1 IF N IS EVEN
* PROCEDURE FOR CALCULATING THE PARITY OF THE NUMBER N.
* RETURNS -1 IF N IS ODD AND +1 IF N IS EVEN
*/
void parite(G4double n, G4double *par);
/**
* RISE TIME IN WHICH THE FISSION WIDTH HAS REACHED
* RISE TIME IN WHICH THE FISSION WIDTH HAS REACHED
* 90 PERCENT OF ITS FINAL VALUE
*/
G4double tau(G4double bet, G4double homega, G4double ef, G4double t);
/**
* KRAMERS FAKTOR - REDUCTION OF THE FISSION PROBABILITY
* INDEPENDENT OF EXCITATION ENERGY
* KRAMERS FAKTOR - REDUCTION OF THE FISSION PROBABILITY
* INDEPENDENT OF EXCITATION ENERGY
*/
G4double cram(G4double bet, G4double homega);
/**
* CALCULATION OF THE SURFACE BS OR CURVATURE BK OF A NUCLEUS
* RELATIVE TO THE SPHERICAL CONFIGURATION
* BASED ON MYERS, DROPLET MODEL FOR ARBITRARY SHAPES
* CALCULATION OF THE SURFACE BS OR CURVATURE BK OF A NUCLEUS
* RELATIVE TO THE SPHERICAL CONFIGURATION
* BASED ON MYERS, DROPLET MODEL FOR ARBITRARY SHAPES
*/
G4double bipol(G4int iflag, G4double y);
/**
* THIS SUBROUTINE RETURNS THE BARRIER HEIGHT BFIS, THE
* GROUND-STATE ENERGY SEGS, IN MEV, AND THE ANGULAR MOMENTUM
* AT WHICH THE FISSION BARRIER DISAPPEARS, LMAX, IN UNITS OF
* H-BAR, WHEN CALLED WITH INTEGER AGUMENTS IZ, THE ATOMIC
* NUMBER, IA, THE ATOMIC MASS NUMBER, AND IL, THE ANGULAR
* MOMENTUM IN UNITS OF H-BAR. (PLANCK'S CONSTANT DIVIDED BY
* 2*PI).
* THIS SUBROUTINE RETURNS THE BARRIER HEIGHT BFIS, THE
* GROUND-STATE ENERGY SEGS, IN MEV, AND THE ANGULAR MOMENTUM
* AT WHICH THE FISSION BARRIER DISAPPEARS, LMAX, IN UNITS OF
* H-BAR, WHEN CALLED WITH INTEGER AGUMENTS IZ, THE ATOMIC
* NUMBER, IA, THE ATOMIC MASS NUMBER, AND IL, THE ANGULAR
* MOMENTUM IN UNITS OF H-BAR. (PLANCK'S CONSTANT DIVIDED BY
* 2*PI).
*/
void barfit(G4int iz, G4int ia, G4int il, G4double *sbfis, G4double *segs, G4double *selmax);
void barfit(G4int iz, G4int ia, G4int il, G4double *sbfis, G4double *segs,
G4double *selmax);
/**
* Calculation of decay widths for light particles.
*/
G4double width(G4double AMOTHER,G4double ZMOTHER,G4double APART,G4double ZPART,G4double TEMP,G4double B1,G4double SB1,G4double EXC);
G4double width(G4double AMOTHER, G4double ZMOTHER, G4double APART,
G4double ZPART, G4double TEMP, G4double B1, G4double SB1,
G4double EXC);
/**
* Calculation of penetration factors for light charged particles.
@@ -372,12 +425,13 @@ void unbound(G4double SN,G4double SP,G4double SD,G4double ST,G4double SHE,G4dou
/**
* Calculation of mean value of orbital angular momentum.
*/
void lorb(G4double AMOTHER,G4double ADAUGHTER,G4double LMOTHER,G4double EEFINAL,G4double *LORBITAL,G4double *SIGMA_LORBITAL);
void lorb(G4double AMOTHER, G4double ADAUGHTER, G4double LMOTHER,
G4double EEFINAL, G4double *LORBITAL, G4double *SIGMA_LORBITAL);
/**
* Calculation of BS and BK for the nuclear-level density.
*/
void bsbkbc(G4double A,G4double Z,G4double *BS,G4double *BK,G4double *BC);
void bsbkbc(G4double A, G4double Z, G4double *BS, G4double *BK, G4double *BC);
/**
* Special functions used for the emission of particles.
@@ -386,9 +440,9 @@ void unbound(G4double SN,G4double SP,G4double SD,G4double ST,G4double SHE,G4dou
G4double gammp(G4double a, G4double x);
void gcf(G4double *gammcf,G4double a,G4double x,G4double gln);
void gcf(G4double *gammcf, G4double a, G4double x, G4double gln);
void gser(G4double *gamser,G4double a,G4double x,G4double gln);
void gser(G4double *gamser, G4double a, G4double x, G4double gln);
G4double fvmaxhaz(G4double T);
@@ -401,7 +455,7 @@ void unbound(G4double SN,G4double SP,G4double SD,G4double ST,G4double SHE,G4dou
/**
* LOGARITHM OF THE GAMM FUNCTION
*/
*/
G4double gammln(G4double xx);
/**
@@ -428,12 +482,7 @@ void unbound(G4double SN,G4double SP,G4double SD,G4double ST,G4double SHE,G4dou
* Random generator according to the
powerfunction y = x**(lambda) in the range from xmin to xmax
*/
G4int IPOWERLIMHAZ(G4double lambda,G4int xmin,G4int xmax);
/**
*
*/
G4double pace2(G4double a, G4double z);
G4int IPOWERLIMHAZ(G4double lambda, G4int xmin, G4int xmax);
/**
*
@@ -448,7 +497,7 @@ void unbound(G4double SN,G4double SP,G4double SD,G4double ST,G4double SHE,G4dou
/**
* Fill the data array for INCL
*/
void FillData(G4int IMULTBU,G4int IEV_TAB);
void FillData(G4int IMULTBU, G4int IEV_TAB);
/**
* Separation energies of lambda
@@ -458,9 +507,9 @@ void unbound(G4double SN,G4double SP,G4double SD,G4double ST,G4double SHE,G4dou
/**
* Separation energies of for other particles for hypernuclei
*/
G4double getdeltabinding(G4double a,G4int nblamb);
G4double getdeltabinding(G4double a, G4int nblamb);
G4double gethyperbinding(G4double A, G4double Z, G4int ny);
public:
// Utils
G4int min(G4int a, G4int b);
@@ -478,33 +527,22 @@ public:
G4int idnint(G4double value);
G4double utilabs(G4double a);
G4double dmin1(G4double a, G4double b, G4double c);
G4Ec2sub* getFrldmTable() {
return ec2sub;
}
private:
G4int verboseLevel;
G4int ilast;
G4double T_freeze_out_in;
G4int IEV_TAB_SSC;
G4double BU_TAB[200][12],EV_TAB[200][6],EV_TAB_SSC[200][6];
G4double BU_TAB[indexpart][12], EV_TAB[indexpart][6], EV_TAB_SSC[indexpart][6];
G4int gammaemission;
G4double T_freeze_out;
G4Pace *pace;
G4Ald *ald;
G4Eenuc *eenuc;
G4Ec2sub *ec2sub;
G4Ecld *ecld;
G4Mexp *masses;
G4Fb *fb;
G4Fiss *fiss;
G4Opt *opt;
G4Volant *volant;
std::unique_ptr<G4Ald> ald;
std::unique_ptr<G4Ec2sub> ec2sub;
std::unique_ptr<G4Ecld> ecld;
std::unique_ptr<G4Mexp> masses;
std::unique_ptr<G4Fb> fb;
std::unique_ptr<G4Fiss> fiss;
std::unique_ptr<G4Opt> opt;
G4VarNtp *varntp;
G4int Ainit,Zinit,Sinit;
#ifndef ABLAXX_IN_GEANT4_MODE
G4INCL::Config *theConfig;
#endif
G4int Ainit, Zinit, Sinit;
};
#endif
@@ -24,161 +24,108 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#pragma once
#include "globals.hh"
// Data structures needed by ABLA evaporation code.
#ifndef G4AblaDataDefs_hh
#define G4AblaDataDefs_hh 1
#ifdef ABLAXX_IN_GEANT4_MODE
#include "globals.hh"
#else
#include "G4INCLGeant4Compat.hh"
#endif
#include <cmath>
#include <vector>
// ABLA
class G4Nevent {
public:
G4Nevent() {};
~G4Nevent() {};
G4int ii;
};
constexpr const G4int nrows = 180;
constexpr const G4int zcols = 122;
// ABLA
#define PACESIZEROWS 500
#define PACESIZECOLS 500
/**
* Masses.
*/
constexpr const G4int lpcols = 13;
constexpr const G4int lprows = 154;
class G4Pace {
constexpr const G4int nrowsbeta = 251;
constexpr const G4int zcolsbeta = 137;
public:
G4Pace() {};
constexpr const G4int indexpart = 300;
~G4Pace() {};
G4double dm[PACESIZEROWS][PACESIZECOLS];
};
#define MASSIZEROWS 154
#define MASSIZECOLS 13
// Data structures needed by ABLA evaporation code
class G4Mexp {
public:
G4Mexp() {};
G4Mexp(){};
~G4Mexp() {};
G4double massexp[MASSIZEROWS][MASSIZECOLS];
G4double bind[MASSIZEROWS][MASSIZECOLS];
G4int mexpiop[MASSIZEROWS][MASSIZECOLS];
virtual ~G4Mexp() = default;
G4double massexp[lprows][lpcols] = {{0.}};
G4double bind[lprows][lpcols] = {{0.}};
G4int mexpiop[lprows][lpcols] = {{0}};
};
#define EC2SUBROWS 154
#define EC2SUBCOLS 99
/**
*
*/
class G4Ec2sub {
public:
G4Ec2sub() {};
G4Ec2sub(){};
~G4Ec2sub() {};
virtual ~G4Ec2sub() = default;
G4double ecnz[EC2SUBROWS][EC2SUBCOLS];
/**
* Dump the contents of the ecnz data table.
*/
void dump() {
for(G4int i = 0; i < EC2SUBROWS; i++) {
for(G4int j = 0; j < EC2SUBCOLS; j++) {
//G4cout << ecnz[i][j] << " ";
}
// G4cout << G4endl;
}
}
G4double ecnz[nrows][zcols] = {{0.}};
};
class G4Ald {
public:
/**
*
*/
G4Ald()
:av(0.0), as(0.0), ak(0.0), optafan(0.0)
{};
~G4Ald() {};
G4double av,as,ak,optafan;
G4Ald() : av(0.0), as(0.0), ak(0.0), optafan(0.0){};
virtual ~G4Ald() = default;
G4double av, as, ak, optafan = 0.;
};
#define ECLDROWS 154
#define ECLDCOLS 99
#define ECLDROWSbeta 251
#define ECLDCOLSbeta 137
/**
* Shell corrections and deformations.
*/
**/
class G4Ecld {
public:
G4Ecld() {};
~G4Ecld() {};
G4Ecld(){};
virtual ~G4Ecld() = default;
/**
* Ground state shell correction frldm for a spherical ground state.
*/
G4double ecgnz[ECLDROWS][ECLDCOLS];
G4double ecgnz[nrows][zcols] = {{0.}};
/**
* Shell correction for the saddle point (now: == 0).
*/
G4double ecfnz[ECLDROWS][ECLDCOLS];
G4double ecfnz[nrows][zcols] = {{0.}};
/**
* Difference between deformed ground state and ldm value.
*/
G4double vgsld[ECLDROWS][ECLDCOLS];
G4double vgsld[nrows][zcols] = {{0.}};
/**
* Alpha ground state deformation (this is not beta2!)
* beta2 = std::sqrt(5/(4pi)) * alpha
* Alpha ground state deformation (this is not beta2!)
* beta2 = std::sqrt(5/(4pi)) * alpha
*/
G4double alpha[ECLDROWS][ECLDCOLS];
G4double alpha[nrows][zcols] = {{0.}};
/**
* RMS function for lcp emission barriers
*/
G4double rms[ECLDROWS][ECLDCOLS];
G4double rms[nrows][zcols] = {{0.}};
/**
* Beta2 deformations
*/
G4double beta2[ECLDROWSbeta][ECLDCOLSbeta];
G4double beta2[nrowsbeta][zcolsbeta] = {{0.}};
/**
* Beta4 deformations
*/
G4double beta4[ECLDROWSbeta][ECLDCOLSbeta];
G4double beta4[nrowsbeta][zcolsbeta] = {{0.}};
};
class G4Fiss {
@@ -188,29 +135,26 @@ class G4Fiss {
public:
G4Fiss()
:bet(0.0), ifis(0.0), ucr(0.0), dcr(0.0), optshp(0), optxfis(0), optct(0), optcol(0),
at(0), zt(0)
{};
~G4Fiss() {};
G4double bet,ifis,ucr,dcr;
G4int optshp, optxfis,optct,optcol,at,zt;
: bet(0.0), bethyp(0.0), ifis(0.0), ucr(0.0), dcr(0.0), optshp(0), optxfis(0),
optct(0), optcol(0), at(0), zt(0){};
virtual ~G4Fiss() = default;
G4double bet, bethyp, ifis, ucr, dcr;
G4int optshp, optxfis, optct, optcol, at, zt;
};
#define FBROWS 101
#define FBCOLS 161
/**
* Fission barriers.
*/
class G4Fb {
public:
G4Fb() {};
~G4Fb() {;}
// G4double efa[FBROWS][FBCOLS];
G4double efa[FBCOLS][FBROWS];
G4Fb(){};
virtual ~G4Fb() = default;
G4double efa[nrows][zcols] = {{0.}};
};
/**
@@ -220,370 +164,32 @@ public:
class G4Opt {
public:
G4Opt()
:optemd(0), optcha(0), optshpimf(0), optimfallowed(0), nblan0(0)
{};
~G4Opt() {};
G4Opt() : optemd(0), optcha(0), optshpimf(0), optimfallowed(0), nblan0(0){};
G4int optemd,optcha,optshpimf,optimfallowed,nblan0;
virtual ~G4Opt() = default;
G4int optemd, optcha, optshpimf, optimfallowed, nblan0;
};
#define EENUCSIZE 2002
#define XHESIZE 50
class G4Eenuc {
public:
G4Eenuc() {
for(G4int i = 0; i < EENUCSIZE; ++i) {
she[i] = 0.0;
}
for(G4int i = 0; i < XHESIZE; ++i) {
for(G4int j = 0; j < EENUCSIZE; ++j) {
xhe[i][j] = 0.0;
}
}
};
~G4Eenuc() {};
G4double she[EENUCSIZE],xhe[XHESIZE][EENUCSIZE];
};
//#define VOLANTSIZE 200
#define VOLANTSIZE 301
/**
* Evaporation and fission output data.
*/
class G4Volant {
public:
G4Volant()
{
clear();
}
~G4Volant() {};
void clear()
{
for(G4int i = 0; i < VOLANTSIZE; i++) {
copied[i] = false;
acv[i] = 0;
zpcv[i] = 0;
pcv[i] = 0;
xcv[i] = 0;
ycv[i] = 0;
zcv[i] = 0;
iv = 0;
}
}
G4double getTotalMass()
{
G4double total = 0.0;
for(G4int i = 0; i <= iv; i++) {
total += acv[i];
}
return total;
}
void dump()
{
/*
G4double totA = 0.0, totZ = 0.0, totP = 0.0;
// G4cout <<"i \t ACV \t ZPCV \t PCV" << G4endl;
for(G4int i = 0; i <= iv; i++) {
if(i == 0 && acv[i] != 0) {
// G4cout <<"G4Volant: Particle stored at index " << i << G4endl;
}
totA += acv[i];
totZ += zpcv[i];
totP += pcv[i];
// G4cout << "volant" << i << "\t" << acv[i] << " \t " << zpcv[i] << " \t " << pcv[i] << G4endl;
}
// G4cout <<"Particle count index (iv) = " << iv << G4endl;
// G4cout <<"ABLA Total: A = " << totA << " Z = " << totZ << " momentum = " << totP << G4endl;
*/
}
G4double acv[VOLANTSIZE],zpcv[VOLANTSIZE],pcv[VOLANTSIZE],xcv[VOLANTSIZE];
G4double ycv[VOLANTSIZE],zcv[VOLANTSIZE];
G4bool copied[VOLANTSIZE];
G4int iv;
};
#define VARNTPSIZE 301
class G4VarNtp {
public:
G4VarNtp() {
clear();
};
G4VarNtp() { clear(); };
~G4VarNtp() {};
virtual ~G4VarNtp() = default;
/**
* Clear and initialize all variables and arrays.
*/
void clear() {
particleIndex = 0;
projType = 0;
projEnergy = 0.0;
targetA = 0;
targetZ = 0;
masp = 0.0; mzsp = 0.0; exsp = 0.0; mrem = 0.0;
// To be deleted?
spectatorA = 0;
spectatorZ = 0;
spectatorEx = 0.0;
spectatorM = 0.0;
spectatorT = 0.0;
spectatorP1 = 0.0;
spectatorP2 = 0.0;
spectatorP3 = 0.0;
massini = 0;
mzini = 0;
exini = 0;
pcorem = 0;
mcorem = 0;
pxrem = 0;
pyrem = 0;
pzrem = 0;
erecrem = 0;
mulncasc = 0;
mulnevap = 0;
mulntot = 0;
bimpact = 0.0;
jremn = 0;
kfis = 0;
estfis = 0;
izfis = 0;
iafis = 0;
ntrack = 0;
needsFermiBreakup = false;
for(G4int i = 0; i < VARNTPSIZE; i++) {
itypcasc[i] = 0;
avv[i] = 0;
zvv[i] = 0;
svv[i] = 0;
enerj[i] = 0.0;
pxlab[i] = 0.0;
pylab[i] = 0.0;
pzlab[i] = 0.0;
full[i] = false;
}
kfis = 0;
itypcasc.clear();
avv.clear();
zvv.clear();
svv.clear();
enerj.clear();
pxlab.clear();
pylab.clear();
pzlab.clear();
}
/**
* Add a particle to the INCL/ABLA final output.
*/
void addParticle(G4double A, G4double Z, G4double E, G4double P, G4double theta, G4double phi) {
if(full[particleIndex]) {
// G4cout <<"A = " << Z << " Z = " << Z << G4endl;
} else {
avv[particleIndex] = (int) A;
zvv[particleIndex] = (int) Z;
enerj[particleIndex] = E;
plab[particleIndex] = P;
tetlab[particleIndex] = theta;
philab[particleIndex] = phi;
full[particleIndex] = true;
ntrack = particleIndex + 1;
particleIndex++;
}
}
/**
* Baryon number conservation check.
*/
G4int getTotalBaryonNumber() {
G4int baryonNumber = 0;
for(G4int i = 0; i < ntrack; i++) {
if(avv[i] > 0) {
baryonNumber += avv[i];
}
}
return baryonNumber;
}
/**
* Return total energy.
*/
G4double getTotalEnergy() {
G4double energy = 0.0;
for(G4int i = 0; i < ntrack; i++) {
energy += std::sqrt(std::pow(plab[i], 2) + std::pow(getMass(i), 2)); // E^2 = p^2 + m^2
}
return energy;
}
/**
* Return total three momentum.
*/
G4double getTotalThreeMomentum() {
G4double momentum = 0;
for(G4int i = 0; i < ntrack; i++) {
momentum += plab[i];
}
return momentum;
}
G4double getMomentumSum() {
G4double momentum = 0;
for(G4int i = 0; i < ntrack; i++) {
momentum += plab[i];
}
return momentum;
}
G4double getMass(G4int particle) {
const G4double protonMass = 938.272;
const G4double neutronMass = 939.565;
const G4double pionMass = 139.57;
G4double mass = 0.0;
if(avv[particle] == 1 && zvv[particle] == 1) mass = protonMass;
if(avv[particle] == 1 && zvv[particle] == 0) mass = neutronMass;
if(avv[particle] == -1) mass = pionMass;
if(avv[particle] > 1)
mass = avv[particle] * protonMass + zvv[particle] * neutronMass;
return mass;
}
/**
* Dump debugging output.
*/
void dump()
{
/*
G4int nProton = 0, nNeutron = 0;
G4int nPiPlus = 0, nPiZero = 0, nPiMinus = 0;
G4int nH2 = 0, nHe3 = 0, nAlpha = 0;
G4int nGamma=0;
G4int nFragments = 0;
G4int nParticles = 0;
for(G4int i = 0; i < ntrack; i++) {
nParticles++;
if(avv[i] == 1 && zvv[i] == 1) nProton++; // Count multiplicities
if(avv[i] == 1 && zvv[i] == 0) nNeutron++;
if(avv[i] == 0 && zvv[i] == 0) nGamma++;
if(avv[i] == -1 && zvv[i] == 1) nPiPlus++;
if(avv[i] == -1 && zvv[i] == 0) nPiZero++;
if(avv[i] == -1 && zvv[i] == -1) nPiMinus++;
if(avv[i] == 2 && zvv[i] == 1) nH2++;
if(avv[i] == 3 && zvv[i] == 2) nHe3++;
if(avv[i] == 4 && zvv[i] == 2) nAlpha++;
if( zvv[i] > 2) nFragments++;
}
*/
}
/**
* Projectile type.
*/
G4int projType;
/**
* Projectile energy.
*/
G4double projEnergy;
/**
* Target mass number.
*/
G4int targetA;
/**
* Target charge number.
*/
G4int targetZ;
/**
* Projectile spectator A, Z, Eex;
*/
G4double masp, mzsp, exsp, mrem;
/**
* Spectator nucleus mass number for light ion projectile support.
*/
G4int spectatorA;
/**
* Spectator nucleus charge number for light ion projectile support.
*/
G4int spectatorZ;
/**
* Spectator nucleus excitation energy for light ion projectile support.
*/
G4double spectatorEx;
/**
* Spectator nucleus mass.
*/
G4double spectatorM;
/**
* Spectator nucleus kinetic energy.
*/
G4double spectatorT;
/**
* Spectator nucleus momentum x-component.
*/
G4double spectatorP1;
/**
* Spectator nucleus momentum y-component.
*/
G4double spectatorP2;
/**
* Spectator nucleus momentum z-component.
*/
G4double spectatorP3;
/**
* A of the remnant.
*/
G4double massini;
/**
* Z of the remnant.
*/
G4double mzini;
/**
* Excitation energy.
*/
G4double exini;
G4double pcorem, mcorem, pxrem, pyrem, pzrem, erecrem;
/**
* Cascade n multip.
*/
G4int mulncasc;
/**
* Evaporation n multip.
*/
G4int mulnevap;
/**
* Total n multip.
*/
G4int mulntot;
/**
* Impact parameter.
*/
G4double bimpact;
/**
* Remnant Intrinsic Spin.
*/
G4int jremn;
/**
* Fission 1/0=Y/N.
*/
@@ -609,13 +215,6 @@ public:
*/
G4int ntrack;
/**
* The state of the index:
* true = reserved
* false = free
*/
G4bool full[VARNTPSIZE];
/**
* Does this nucleus require Fermi break-up treatment? Only
* applicable when used together with Geant4.
@@ -627,49 +226,44 @@ public:
/**
* emitted in cascade (0) or evaporation (1).
*/
G4int itypcasc[VARNTPSIZE];
std::vector<G4int> itypcasc;
/**
* A (-1 for pions).
*/
G4int avv[VARNTPSIZE];
std::vector<G4int> avv;
/**
* Z
*/
G4int zvv[VARNTPSIZE];
std::vector<G4int> zvv;
/**
* S (-1 for lambda_0).
*/
G4int svv[VARNTPSIZE];
std::vector<G4int> svv;
/**
* Kinetic energy.
*/
G4double enerj[VARNTPSIZE];
std::vector<G4double> enerj;
/**
* Momentum.
*/
G4double plab[VARNTPSIZE];
G4double pxlab[VARNTPSIZE];
G4double pylab[VARNTPSIZE];
G4double pzlab[VARNTPSIZE];
std::vector<G4double> plab;
std::vector<G4double> pxlab;
std::vector<G4double> pylab;
std::vector<G4double> pzlab;
/**
* Theta angle.
*/
G4double tetlab[VARNTPSIZE];
std::vector<G4double> tetlab;
/**
* Phi angle.
*/
G4double philab[VARNTPSIZE];
std::vector<G4double> philab;
private:
G4int particleIndex;
};
#endif
@@ -24,20 +24,17 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#include "globals.hh"
#ifndef G4AblaDataFile_hh
#define G4AblaDataFile_hh 1
#pragma once
#include "G4AblaVirtualData.hh"
#include "globals.hh"
/**
* Read ABLA data from files.
@@ -45,23 +42,14 @@
class G4AblaDataFile : public G4AblaVirtualData {
public:
#ifdef ABLAXX_IN_GEANT4_MODE
G4AblaDataFile();
#else
G4AblaDataFile(G4INCL::Config *);
#endif
~G4AblaDataFile();
virtual ~G4AblaDataFile() = default;
/**
* Read all data from files.
*/
bool readData();
G4bool readData();
private:
G4int verboseLevel;
#ifndef ABLAXX_IN_GEANT4_MODE
G4INCL::Config *theConfig;
#endif
};
#endif
@@ -24,63 +24,59 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#ifndef G4AblaInterface_hh
#define G4AblaInterface_hh 1
#pragma once
#include "globals.hh"
#include "G4VPreCompoundModel.hh"
#include "G4ReactionProduct.hh"
#include "G4Abla.hh"
#include "G4Fragment.hh"
#include "G4HadFinalState.hh"
#include "G4HadProjectile.hh"
#include "G4Nucleus.hh"
#include "G4Abla.hh"
#include "G4ReactionProduct.hh"
#include "G4VPreCompoundModel.hh"
class G4ExcitationHandler;
class G4HadFinalState;
class G4AblaInterface : public G4VPreCompoundModel
{
public:
G4AblaInterface(G4ExcitationHandler* ptr = nullptr);
class G4AblaInterface : public G4VPreCompoundModel {
public:
G4AblaInterface(G4ExcitationHandler *ptr = nullptr);
virtual ~G4AblaInterface();
virtual G4ReactionProductVector* DeExcite(G4Fragment& aFragment);
virtual G4ReactionProductVector *DeExcite(G4Fragment &aFragment);
virtual G4HadFinalState* ApplyYourself(G4HadProjectile const&, G4Nucleus&) final;
virtual G4HadFinalState *ApplyYourself(G4HadProjectile const &,
G4Nucleus &) final;
virtual void BuildPhysicsTable(const G4ParticleDefinition&) final;
virtual void BuildPhysicsTable(const G4ParticleDefinition &) final;
virtual void InitialiseModel() final;
virtual void ModelDescription(std::ostream& outFile) const;
virtual void ModelDescription(std::ostream &outFile) const;
virtual void DeExciteModelDescription(std::ostream& outFile) const;
virtual void DeExciteModelDescription(std::ostream &outFile) const;
private:
private:
G4HadFinalState applyYourselfResult;
G4VarNtp* ablaResult;
G4Volant* volant;
G4Abla* theABLAModel;
G4VarNtp *ablaResult;
G4Abla *theABLAModel;
G4long eventNumber;
G4int secID; // Creator model ID for the secondaries created by ABLA
G4int secID; // Creator model ID for the secondaries created by ABLA
G4bool isInitialised;
/// \brief Convert an Abla particle to a G4DynamicParticle
G4ReactionProduct* toG4Particle(G4int A, G4int Z, G4int S, G4double kinE,
G4double px, G4double py, G4double pz) const;
G4ReactionProduct *toG4Particle(G4int A, G4int Z, G4int S, G4double kinE,
G4double px, G4double py, G4double pz) const;
/// \brief Convert A, Z and S to a G4ParticleDefinition
G4ParticleDefinition* toG4ParticleDefinition(G4int A, G4int Z, G4int S) const;
G4ParticleDefinition *toG4ParticleDefinition(G4int A, G4int Z, G4int S) const;
};
#endif
@@ -24,21 +24,17 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#pragma once
#include "globals.hh"
#ifndef G4ABLARANDOM_HH
#define G4ABLARANDOM_HH
namespace G4AblaRandom {
double flat();
G4double flat();
}
#endif
@@ -24,27 +24,17 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#pragma once
#include "globals.hh"
#ifndef G4AblaVirtualData_hh
#define G4AblaVirtualData_hh 1
#ifdef ABLAXX_IN_GEANT4_MODE
#include "globals.hh"
#else
#include "G4INCLGeant4Compat.hh"
#include "G4INCLConfig.hh"
#endif
/**
* An interface to data used by ABLA. This interface allows
* us to abstract the actual source of data. Currently the data is
@@ -54,16 +44,12 @@
class G4AblaVirtualData {
protected:
/**
* Constructor, destructor
*/
#ifdef ABLAXX_IN_GEANT4_MODE
G4AblaVirtualData();
#else
G4AblaVirtualData(G4INCL::Config *);
#endif
virtual ~G4AblaVirtualData();
virtual ~G4AblaVirtualData() = default;
public:
/**
@@ -81,11 +67,6 @@ public:
*/
G4bool setVgsld(G4int A, G4int Z, G4double value);
/**
* Set the value of Pace2.
*/
G4bool setPace2(G4int A, G4int Z, G4double value);
/**
* Set the value of RMS.
*/
@@ -111,7 +92,6 @@ public:
*/
G4bool setBeta4(G4int A, G4int Z, G4double value);
/**
* Get the value of Alpha.
*/
@@ -127,12 +107,7 @@ public:
*/
G4double getVgsld(G4int A, G4int Z);
/**
* Get the value of Pace2.
*/
G4double getPace2(G4int A, G4int Z);
/**
/*
* Get the value of RMS.
*/
G4double getRms(G4int A, G4int Z);
@@ -157,40 +132,21 @@ public:
*/
G4double getBeta4(G4int A, G4int Z);
G4int getAlphaRows();
G4int getAlphaCols();
G4int getPaceRows();
G4int getPaceCols();
virtual G4bool readData() = 0;
private:
static const G4int sRows = 180;
static const G4int sCols = 122;
static const G4int alphaRows = 154;
static const G4int alphaCols = 99;
static const G4int paceRows = 500;
static const G4int paceCols = 500;
static const G4int rmsRows = 154;
static const G4int rmsCols = 99;
static const G4int betaRows = 251;
static const G4int betaRows = sCols + sRows;
static const G4int betaCols = 137;
static const G4int massRows = 154;
static const G4int massCols = 13;
G4double alpha[alphaRows][alphaCols];
G4double ecnz[alphaRows][alphaCols];
G4double vgsld[alphaRows][alphaCols];
G4double pace2[paceRows][paceCols];
G4double rms[rmsRows][rmsCols];
G4double mexp[massRows][massCols];
G4int mexpid[massRows][massCols];
G4double alpha[sRows][sCols];
G4double ecnz[sRows][sCols];
G4double vgsld[sRows][sCols];
G4double rms[sRows][sCols];
G4double mexp[sRows][sCols];
G4int mexpid[sRows][sCols];
G4double beta2[betaRows][betaCols];
G4double beta4[betaRows][betaCols];
};
#endif
@@ -19,7 +19,6 @@ geant4_add_module(G4hadronic_abla
geant4_module_link_libraries(G4hadronic_abla
PUBLIC
G4globman
G4hadronic_inclxx_utils
G4hadronic_mgt
G4hadronic_util
PRIVATE
File diff suppressed because it is too large Load Diff
@@ -24,207 +24,170 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#include "globals.hh"
#include "G4AblaDataFile.hh"
#ifdef ABLAXX_IN_GEANT4_MODE
#include "G4AblaDataDefs.hh"
#include "globals.hh"
#else
#include "G4INCLGeant4Compat.hh"
#endif
#include <fstream>
#include <cmath>
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <iostream>
#ifdef ABLAXX_IN_GEANT4_MODE
G4AblaDataFile::G4AblaDataFile() {
#else
G4AblaDataFile::G4AblaDataFile(G4INCL::Config *config)
: G4AblaVirtualData(config) {
theConfig = config;
#endif
verboseLevel = 0;
}
G4AblaDataFile::~G4AblaDataFile()
{
}
G4AblaDataFile::G4AblaDataFile() { verboseLevel = 0; }
/**
* Read all data from files.
*/
bool G4AblaDataFile::readData()
G4bool G4AblaDataFile::readData()
{
#ifdef ABLAXX_IN_GEANT4_MODE
if(!G4FindDataDir("G4ABLADATA")) {
// throw G4HadronicException(__FILE__, __LINE__, "ERROR: Data
// missing. Set environment variable G4ABLA3.0 to point to the
// directory containing data files needed by INCL and ABLA
// models.");
// G4String errorMessage1 = "ERROR: Data missing. Set environment variable G4ABLADATA\n";
// G4String errorMessage2 = "\t to point to the directory containing data files needed\n";
// G4String errorMessage3 = "\t by INCL and ABLA models.\n";
// G4String errorMessage = errorMessage1 + errorMessage2 + errorMessage3;
// G4Exception(errorMessage);
G4ExceptionDescription ed;
ed << " Data missing: set environment variable G4ABLADATA\n"
<< " to point to the directory containing data files needed\n"
<< " by the ABLA model" << G4endl;
G4Exception("G4AblaDataFile::readData()","ABLA_001",
FatalException, ed);
}
G4String dataPath(G4FindDataDir("G4ABLADATA"));
#else
G4String dataPath(theConfig->getABLAXXDataFilePath().c_str());
#endif
G4String flAlphaFile(dataPath + "/flalpha.dat");
G4String frldmFile( dataPath + "/frldm.dat");
G4String vgsldFile( dataPath + "/vgsld.dat");
G4String pace2File( dataPath + "/pace2.dat");
G4String rmsFile( dataPath + "/rms.dat");
G4String defoFile( dataPath + "/defo.dat");
G4String massFile( dataPath + "/mass2003.dat");
if(verboseLevel > 1) {
// G4cout <<"Data path = " << dataPath << G4endl;
// G4cout <<"FlAlphaFile = " << flAlphaFile << G4endl;
// G4cout <<"FrldmFile = " << frldmFile << G4endl;
// G4cout <<"VgsldFile = " << vgsldFile << G4endl;
// G4cout <<"Pace2File = " << pace2File << G4endl;
}
std::ifstream flalphain(flAlphaFile.c_str());
std::ifstream frldmin(frldmFile.c_str());
std::ifstream vgsldin(vgsldFile.c_str());
std::ifstream pace2in(pace2File.c_str());
std::ifstream rmsin(rmsFile.c_str());
std::ifstream defoin(defoFile.c_str());
std::ifstream massin(massFile.c_str());
std::filebuf *buf1 = flalphain.rdbuf();
std::filebuf *buf2 = frldmin.rdbuf();
std::filebuf *buf3 = vgsldin.rdbuf();
std::filebuf *buf4 = pace2in.rdbuf();
std::filebuf *buf5 = rmsin.rdbuf();
std::filebuf *buf6 = defoin.rdbuf();
std::filebuf *buf7 = massin.rdbuf();
if (!((buf1->is_open()) && (buf2->is_open()) && (buf3->is_open()) && (buf4->is_open()) && (buf5->is_open()) && (buf6->is_open()) && (buf7->is_open()))) {
#ifdef ABLAXX_IN_GEANT4_MODE
G4ExceptionDescription ed;
ed << "Data missing: could not find ABLA data file in " << dataPath
<< "defined by environment variable G4ABLADATA" << G4endl;
G4Exception("G4AblaDataFile::readData()", "ABLA", FatalException, ed);
#else
std::cerr << "Error opening file." << std::endl;
#endif
}
G4double fflalpha, ffrldm, fvgsld, fpace2, frms;
int fj,fk,a2,a3,a4;
G4double fbeta2,fbeta4;
G4double a7;
const G4int rows = 99;
const G4int cols = 154;
const G4int rowsbeta = 137;
const G4int colsbeta = 251;
const G4int rowsmass = 13;
const G4int colsmass = 154;
const G4int massnumbers = 263;
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
setAlpha(j, i, 0.0);
setEcnz( j, i, 0.0);
setVgsld(j, i, 0.0);
setRms(j, i, 0.0);
if (!G4FindDataDir("G4ABLADATA"))
{
G4ExceptionDescription ed;
ed << " Data missing: set environment variable G4ABLADATA\n"
<< " to point to the directory containing data files needed\n"
<< " by the ABLA model" << G4endl;
G4Exception("G4AblaDataFile::readData()", "ABLA_001", FatalException, ed);
}
}
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
flalphain >> fflalpha;
frldmin >> ffrldm;
vgsldin >> fvgsld;
rmsin >> frms;
setAlpha(j, i, fflalpha);
setEcnz( j, i, ffrldm);
setVgsld(j, i, fvgsld);
setRms(j, i, frms);
G4String dataPath(G4FindDataDir("G4ABLADATA"));
G4String flAlphaFile(dataPath + "/flalpha.dat");
G4String frldmFile(dataPath + "/frldm.dat");
G4String vgsldFile(dataPath + "/vgsld.dat");
G4String rmsFile(dataPath + "/rms.dat");
G4String defoFile(dataPath + "/defo.dat");
G4String massFile(dataPath + "/mass2020.dat");
if (verboseLevel > 1)
{
// G4cout <<"Data path = " << dataPath << G4endl;
// G4cout <<"FlAlphaFile = " << flAlphaFile << G4endl;
// G4cout <<"FrldmFile = " << frldmFile << G4endl;
// G4cout <<"VgsldFile = " << vgsldFile << G4endl;
}
}
std::ifstream flalphain(flAlphaFile.c_str());
std::ifstream frldmin(frldmFile.c_str());
std::ifstream vgsldin(vgsldFile.c_str());
std::ifstream rmsin(rmsFile.c_str());
std::ifstream defoin(defoFile.c_str());
std::ifstream massin(massFile.c_str());
for(int i = 0; i < rowsbeta; i++) {
for(int j = 0; j < colsbeta; j++) {
setBeta2(j, i, 0.0);
setBeta4(j, i, 0.0);
if (!massin.is_open())
{
massFile = dataPath + "/mass2016.dat";
massin.close();
massin.open(massFile.c_str());
std::cout << "Mass evaluation file mass2020.dat not found, current file: " << massFile.c_str() << std::endl;
if (!massin.is_open())
{
massFile = dataPath + "/mass2003.dat";
massin.close();
massin.open(massFile.c_str());
std::cout << "Mass evaluation file mass2016.dat not found, current file: " << massFile.c_str() << std::endl;
}
}
}
for(int i = 0; i < 8983; i++) {
defoin >> fj >> fk >> fbeta2 >> fbeta4;
setBeta2(fk, fj, fbeta2);
setBeta4(fk, fj, fbeta4);
}
for(int i = 0; i < rowsmass; i++) {
for(int j = 0; j < colsmass; j++) {
setMexp(j, i, 0.0);
setMexpID(j,i,0);
std::filebuf* buf1 = flalphain.rdbuf();
std::filebuf* buf2 = frldmin.rdbuf();
std::filebuf* buf3 = vgsldin.rdbuf();
std::filebuf* buf4 = rmsin.rdbuf();
std::filebuf* buf5 = defoin.rdbuf();
std::filebuf* buf6 = massin.rdbuf();
if (!((buf1->is_open()) && (buf2->is_open()) && (buf3->is_open()) && (buf4->is_open()) && (buf5->is_open()) &&
(buf6->is_open())))
{
G4ExceptionDescription ed;
ed << "Data missing: could not find ABLA data file in " << dataPath
<< "defined by environment variable G4ABLADATA" << G4endl;
G4Exception("G4AblaDataFile::readData()", "ABLA", FatalException, ed);
}
}
massin >> a2 >> a3 >> a4 >> a7 ;
while(!massin.eof()){
//
if(a3<13.){
setMexpID(a2,a3,1);
setMexp(a2,a3,938.7829835*a3+939.5653301*a2-1.*a4*a7/1000.);
}
massin >> a2 >> a3 >> a4 >> a7 ;
}
flalphain.close();
frldmin.close();
vgsldin.close();
rmsin.close();
defoin.close();
massin.close();
G4double fflalpha, ffrldm, fvgsld, frms;
G4int fj = 0, fk = 0, a2, a3, a4;
G4double fbeta2, fbeta4;
G4double a7;
const G4int rows = 99;
const G4int cols = 154;
const G4int rowsbeta = 137;
const G4int colsbeta = 251;
G4String str1, str2, str3;
for(int i = 0; i < 500; i++) {
for(int j = 0; j < 500; j++) {
setPace2(i, j, 0.0);
for (G4int i = 0; i < zcols; i++)
{
for (G4int j = 0; j < nrows; j++)
{
setAlpha(j, i, 0.0);
setEcnz(j, i, 0.0);
setVgsld(j, i, 0.0);
setRms(j, i, 0.0);
}
}
}
int A = 0, Zbegin = 0, Zend = 0;
for(int i = 0; i < massnumbers; i++) {
pace2in >> str1 >> A >> str2 >> Zbegin >> str3 >> Zend;
if(Zbegin >= 0 && Zbegin < getPaceCols() &&
A >= 0 && A < getPaceRows()) {
for(int j = Zbegin; j <= Zend; j++) {
pace2in >> fpace2;
setPace2(A, j, fpace2);
}
}
}
pace2in.close();
if(std::abs(getPace2(A, Zend) - 114516.10) > 1e-6) {
std::cerr << "ERROR: Problem in parsing datafile " + pace2File << std::endl;
return false;
}
return true;
for (G4int i = 0; i < rows; i++)
{
for (G4int j = 0; j < cols; j++)
{
flalphain >> fflalpha;
frldmin >> ffrldm;
vgsldin >> fvgsld;
rmsin >> frms;
setAlpha(j, i, fflalpha);
setEcnz(j, i, ffrldm);
setVgsld(j, i, fvgsld);
setRms(j, i, frms);
}
}
for (G4int i = 0; i < rowsbeta; i++)
{
for (G4int j = 0; j < colsbeta; j++)
{
setBeta2(j, i, 0.0);
setBeta4(j, i, 0.0);
}
}
defoin >> fj >> fk >> fbeta2 >> fbeta4;
while (!defoin.eof())
{
setBeta2(fk, fj, fbeta2);
setBeta4(fk, fj, fbeta4);
defoin >> fj >> fk >> fbeta2 >> fbeta4;
}
for (G4int i = 0; i < zcols; i++)
{
for (G4int j = 0; j < nrows; j++)
{
setMexp(j, i, 0.0);
setMexpID(j, i, 0);
}
}
massin >> a2 >> a3 >> a4 >> a7;
while (!massin.eof())
{
//
if (a3 < lpcols)
{
setMexpID(a2, a3, 1);
setMexp(a2, a3, 938.7829835 * a3 + 939.5653301 * a2 - 1. * a4 * a7 / 1000.);
}
massin >> a2 >> a3 >> a4 >> a7;
}
flalphain.close();
frldmin.close();
vgsldin.close();
rmsin.close();
defoin.close();
massin.close();
return true;
}
@@ -24,7 +24,7 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
@@ -32,239 +32,255 @@
//
#include "globals.hh"
#include <iostream>
#include <cmath>
#include <iostream>
#include "G4AblaInterface.hh"
#include "G4ParticleDefinition.hh"
#include "G4ReactionProductVector.hh"
#include "G4ReactionProduct.hh"
#include "G4DoubleHyperDoubleNeutron.hh"
#include "G4DoubleHyperH4.hh"
#include "G4DynamicParticle.hh"
#include "G4ExcitationHandler.hh"
#include "G4HyperAlpha.hh"
#include "G4HyperH4.hh"
#include "G4HyperHe5.hh"
#include "G4HyperTriton.hh"
#include "G4IonTable.hh"
#include "G4SystemOfUnits.hh"
#include "G4ParticleDefinition.hh"
#include "G4PhysicalConstants.hh"
#include "G4PhysicsModelCatalog.hh"
#include "G4ExcitationHandler.hh"
#include "G4HyperTriton.hh"
#include "G4HyperH4.hh"
#include "G4HyperAlpha.hh"
#include "G4DoubleHyperH4.hh"
#include "G4DoubleHyperDoubleNeutron.hh"
#include "G4HyperHe5.hh"
#include "G4ReactionProduct.hh"
#include "G4ReactionProductVector.hh"
#include "G4SystemOfUnits.hh"
G4AblaInterface::G4AblaInterface(G4ExcitationHandler* ptr) :
G4VPreCompoundModel(ptr, "ABLAXX"),
ablaResult(new G4VarNtp),
volant(new G4Volant),
theABLAModel(new G4Abla(volant, ablaResult)),
eventNumber(0),
secID(-1),
isInitialised(false)
G4AblaInterface::G4AblaInterface(G4ExcitationHandler* ptr)
: G4VPreCompoundModel(ptr, "ABLAXX")
, ablaResult(new G4VarNtp)
, theABLAModel(new G4Abla(ablaResult))
, eventNumber(0)
, secID(-1)
, isInitialised(false)
{
secID = G4PhysicsModelCatalog::GetModelID("model_" + GetModelName());
// G4cout << "### NEW PrecompoundModel " << this << G4endl;
if (!ptr) SetExcitationHandler(new G4ExcitationHandler);
InitialiseModel();
G4cout << G4endl << "G4AblaInterface::InitialiseModel() was right." << G4endl;
secID = G4PhysicsModelCatalog::GetModelID("model_" + GetModelName());
// G4cout << "### NEW PrecompoundModel " << this << G4endl;
if (!ptr)
SetExcitationHandler(new G4ExcitationHandler);
InitialiseModel();
G4cout << G4endl << "G4AblaInterface::InitialiseModel() was right." << G4endl;
}
G4AblaInterface::~G4AblaInterface()
{
applyYourselfResult.Clear();
delete volant;
delete ablaResult;
delete theABLAModel;
delete GetExcitationHandler();
applyYourselfResult.Clear();
delete ablaResult;
delete theABLAModel;
delete GetExcitationHandler();
}
void G4AblaInterface::BuildPhysicsTable(const G4ParticleDefinition&)
{
InitialiseModel();
}
void G4AblaInterface::BuildPhysicsTable(const G4ParticleDefinition&) { InitialiseModel(); }
void G4AblaInterface::InitialiseModel()
{
if (isInitialised) return;
isInitialised = true;
theABLAModel->initEvapora();
theABLAModel->SetParameters();
GetExcitationHandler()->Initialise();
if (isInitialised)
return;
isInitialised = true;
theABLAModel->initEvapora();
theABLAModel->SetParameters();
GetExcitationHandler()->Initialise();
}
G4HadFinalState* G4AblaInterface::ApplyYourself(const G4HadProjectile & thePrimary,
G4Nucleus & theNucleus)
{
// This method is adapted from G4PreCompoundModel::ApplyYourself,
// and it is used only by Binary Cascade (BIC) when the latter is coupled with Abla
// for nuclear de-excitation.
// This method allows BIC+ABLA to be used also for proton and neutron projectile
// with kinetic energies below 45 MeV, by creating a "compound" nucleus made
// by the system "target nucleus + projectile", before calling the DeExcite
// method.
const G4ParticleDefinition* primary = thePrimary.GetDefinition();
if ( primary != G4Neutron::Definition() && primary != G4Proton::Definition() ) {
G4ExceptionDescription ed;
ed << "G4AblaModel is used for ";
if ( primary ) ed << primary->GetParticleName();
G4Exception( "G4AblaInterface::ApplyYourself()", "had040", FatalException, ed, "" );
return nullptr;
}
G4int Zp = 0;
G4int Ap = 1;
if ( primary == G4Proton::Definition() ) Zp = 1;
G4double timePrimary = thePrimary.GetGlobalTime();
G4int A = theNucleus.GetA_asInt();
G4int Z = theNucleus.GetZ_asInt();
G4LorentzVector p = thePrimary.Get4Momentum();
G4double mass = G4NucleiProperties::GetNuclearMass(A, Z);
p += G4LorentzVector( 0.0, 0.0, 0.0, mass );
G4Fragment anInitialState(A + Ap, Z + Zp, p);
anInitialState.SetNumberOfExcitedParticle(1, Zp);
anInitialState.SetNumberOfHoles(1, Zp);
anInitialState.SetCreationTime( thePrimary.GetGlobalTime() );
anInitialState.SetCreatorModelID( secID );
G4ReactionProductVector* deExciteResult = DeExcite( anInitialState );
applyYourselfResult.Clear();
applyYourselfResult.SetStatusChange( stopAndKill );
for ( auto const & prod : *deExciteResult ) {
G4DynamicParticle * aNewDP =
new G4DynamicParticle( prod->GetDefinition(), prod->GetTotalEnergy(), prod->GetMomentum() );
G4HadSecondary aNew = G4HadSecondary( aNewDP );
G4double time = std::max( prod->GetFormationTime(), 0.0 );
aNew.SetTime( timePrimary + time );
aNew.SetCreatorModelID( prod->GetCreatorModelID() );
delete prod;
applyYourselfResult.AddSecondary( aNew );
}
delete deExciteResult;
return &applyYourselfResult;
}
G4ReactionProductVector *G4AblaInterface::DeExcite(G4Fragment& aFragment) {
if (!isInitialised) InitialiseModel();
volant->clear();
ablaResult->clear();
const G4int ARem = aFragment.GetA_asInt();
const G4int ZRem = aFragment.GetZ_asInt();
const G4int SRem = -aFragment.GetNumberOfLambdas(); // Strangeness = - (Number of lambdas)
const G4double eStarRem = aFragment.GetExcitationEnergy() / MeV;
const G4double jRem = aFragment.GetAngularMomentum().mag() / hbar_Planck;
const G4LorentzVector& pRem = aFragment.GetMomentum();
const G4double pxRem = pRem.x() / MeV;
const G4double pyRem = pRem.y() / MeV;
const G4double pzRem = pRem.z() / MeV;
++eventNumber;
theABLAModel->DeexcitationAblaxx(ARem, ZRem, eStarRem, jRem, pxRem, pyRem,
pzRem, (G4int)eventNumber, SRem);
G4ReactionProductVector* result = new G4ReactionProductVector;
for(G4int j = 0; j < ablaResult->ntrack; ++j)
{ // Copy ABLA result to the EventInfo
G4ReactionProduct* product =
toG4Particle(ablaResult->avv[j], ablaResult->zvv[j], ablaResult->svv[j],
ablaResult->enerj[j], ablaResult->pxlab[j],
ablaResult->pylab[j], ablaResult->pzlab[j]);
if(product)
G4HadFinalState* G4AblaInterface::ApplyYourself(const G4HadProjectile& thePrimary, G4Nucleus& theNucleus)
{
// This method is adapted from G4PreCompoundModel::ApplyYourself,
// and it is used only by Binary Cascade (BIC) when the latter is coupled with
// Abla for nuclear de-excitation. This method allows BIC+ABLA to be used also
// for proton and neutron projectile with kinetic energies below 45 MeV, by
// creating a "compound" nucleus made by the system "target nucleus +
// projectile", before calling the DeExcite method.
const G4ParticleDefinition* primary = thePrimary.GetDefinition();
if (primary != G4Neutron::Definition() && primary != G4Proton::Definition())
{
product->SetCreatorModelID(secID);
result->push_back(product);
G4ExceptionDescription ed;
ed << "G4AblaModel is used for ";
if (primary)
ed << primary->GetParticleName();
G4Exception("G4AblaInterface::ApplyYourself()", "had040", FatalException, ed, "");
return nullptr;
}
}
return result;
G4int Zp = 0;
G4int Ap = 1;
if (primary == G4Proton::Definition())
Zp = 1;
G4double timePrimary = thePrimary.GetGlobalTime();
G4int A = theNucleus.GetA_asInt();
G4int Z = theNucleus.GetZ_asInt();
G4LorentzVector p = thePrimary.Get4Momentum();
G4double mass = G4NucleiProperties::GetNuclearMass(A, Z);
p += G4LorentzVector(0.0, 0.0, 0.0, mass);
G4Fragment anInitialState(A + Ap, Z + Zp, p);
anInitialState.SetNumberOfExcitedParticle(1, Zp);
anInitialState.SetNumberOfHoles(1, Zp);
anInitialState.SetCreationTime(thePrimary.GetGlobalTime());
anInitialState.SetCreatorModelID(secID);
G4ReactionProductVector* deExciteResult = DeExcite(anInitialState);
applyYourselfResult.Clear();
applyYourselfResult.SetStatusChange(stopAndKill);
for (auto const& prod : *deExciteResult)
{
G4DynamicParticle* aNewDP =
new G4DynamicParticle(prod->GetDefinition(), prod->GetTotalEnergy(), prod->GetMomentum());
G4HadSecondary aNew = G4HadSecondary(aNewDP);
G4double time = std::max(prod->GetFormationTime(), 0.0);
aNew.SetTime(timePrimary + time);
aNew.SetCreatorModelID(prod->GetCreatorModelID());
delete prod;
applyYourselfResult.AddSecondary(aNew);
}
delete deExciteResult;
return &applyYourselfResult;
}
G4ParticleDefinition *G4AblaInterface::toG4ParticleDefinition(G4int A, G4int Z, G4int S) const {
if (A == 1 && Z == 1 && S == 0 ) return G4Proton::Proton();
else if(A == 1 && Z == 0 && S == 0 ) return G4Neutron::Neutron();
else if(A == 1 && Z == 0 && S == -1) return G4Lambda::Lambda();
else if(A == -1 && Z == 1 && S == 0 ) return G4PionPlus::PionPlus();
else if(A == -1 && Z == -1 && S == 0 ) return G4PionMinus::PionMinus();
else if(A == -1 && Z == 0 && S == 0 ) return G4PionZero::PionZero();
else if(A == 0 && Z == 0 && S == 0 ) return G4Gamma::Gamma();
else if(A == 2 && Z == 1 && S == 0 ) return G4Deuteron::Deuteron();
else if(A == 3 && Z == 1 && S == 0 ) return G4Triton::Triton();
else if(A == 3 && Z == 2 && S == 0 ) return G4He3::He3();
else if(A == 3 && Z == 1 && S == -1) return G4HyperTriton::Definition();
else if(A == 4 && Z == 2 && S == 0 ) return G4Alpha::Alpha();
else if(A == 4 && Z == 1 && S == -1) return G4HyperH4::Definition();
else if(A == 4 && Z == 2 && S == -1) return G4HyperAlpha::Definition();
else if(A == 4 && Z == 1 && S == -2) return G4DoubleHyperH4::Definition();
else if(A == 4 && Z == 0 && S == -2) return G4DoubleHyperDoubleNeutron::Definition();
else if(A == 5 && Z == 2 && S == -1) return G4HyperHe5::Definition();
else if(A > 0 && Z > 0 && A > Z )
{ // Returns ground state ion definition.
auto ionfromtable = G4IonTable::GetIonTable()->GetIon(Z, A, std::abs(S), 0); // S is the number of lambdas
if(ionfromtable)
return ionfromtable;
G4ReactionProductVector* G4AblaInterface::DeExcite(G4Fragment& aFragment)
{
if (!isInitialised)
InitialiseModel();
ablaResult->clear();
const G4int ARem = aFragment.GetA_asInt();
const G4int ZRem = aFragment.GetZ_asInt();
const G4int SRem = -aFragment.GetNumberOfLambdas(); // Strangeness = - (Number of lambdas)
const G4double eStarRem = aFragment.GetExcitationEnergy() / MeV;
const G4double jRem = aFragment.GetAngularMomentum().mag() / hbar_Planck;
const G4LorentzVector& pRem = aFragment.GetMomentum();
const G4double pxRem = pRem.x() / MeV;
const G4double pyRem = pRem.y() / MeV;
const G4double pzRem = pRem.z() / MeV;
++eventNumber;
theABLAModel->DeexcitationAblaxx(ARem, ZRem, eStarRem, jRem, pxRem, pyRem, pzRem, (G4int)eventNumber, SRem);
G4ReactionProductVector* result = new G4ReactionProductVector;
for (G4int j = 0; j < ablaResult->ntrack; ++j)
{ // Copy ABLA result to the EventInfo
G4ReactionProduct* product = toG4Particle(ablaResult->avv[j],
ablaResult->zvv[j],
ablaResult->svv[j],
ablaResult->enerj[j],
ablaResult->pxlab[j],
ablaResult->pylab[j],
ablaResult->pzlab[j]);
if (product)
{
product->SetCreatorModelID(secID);
result->push_back(product);
}
}
return result;
}
G4ParticleDefinition* G4AblaInterface::toG4ParticleDefinition(G4int A, G4int Z, G4int S) const
{
if (A == 1 && Z == 1 && S == 0)
return G4Proton::Proton();
else if (A == 1 && Z == 0 && S == 0)
return G4Neutron::Neutron();
else if (A == 1 && Z == 0 && S == -1)
return G4Lambda::Lambda();
else if (A == -1 && Z == 1 && S == 0)
return G4PionPlus::PionPlus();
else if (A == -1 && Z == -1 && S == 0)
return G4PionMinus::PionMinus();
else if (A == -1 && Z == 0 && S == 0)
return G4PionZero::PionZero();
else if (A == 0 && Z == 0 && S == 0)
return G4Gamma::Gamma();
else if (A == 2 && Z == 1 && S == 0)
return G4Deuteron::Deuteron();
else if (A == 3 && Z == 1 && S == 0)
return G4Triton::Triton();
else if (A == 3 && Z == 2 && S == 0)
return G4He3::He3();
else if (A == 3 && Z == 1 && S == -1)
return G4HyperTriton::Definition();
else if (A == 4 && Z == 2 && S == 0)
return G4Alpha::Alpha();
else if (A == 4 && Z == 1 && S == -1)
return G4HyperH4::Definition();
else if (A == 4 && Z == 2 && S == -1)
return G4HyperAlpha::Definition();
else if (A == 4 && Z == 1 && S == -2)
return G4DoubleHyperH4::Definition();
else if (A == 4 && Z == 0 && S == -2)
return G4DoubleHyperDoubleNeutron::Definition();
else if (A == 5 && Z == 2 && S == -1)
return G4HyperHe5::Definition();
else if (A > 0 && Z > 0 && A > Z)
{ // Returns ground state ion definition.
auto ionfromtable = G4IonTable::GetIonTable()->GetIon(Z, A, std::abs(S), 0); // S is the number of lambdas
if (ionfromtable)
return ionfromtable;
else
{
G4cout << "Can't convert particle with A=" << A << ", Z=" << Z << ", S=" << S
<< " to G4ParticleDefinition, trouble ahead" << G4endl;
return 0;
}
}
else
{
G4cout << "Can't convert particle with A=" << A << ", Z=" << Z << ", S=" << S
<< " to G4ParticleDefinition, trouble ahead" << G4endl;
return 0;
{ // Error, unrecognized particle
G4cout << "Can't convert particle with A=" << A << ", Z=" << Z << ", S=" << S
<< " to G4ParticleDefinition, trouble ahead" << G4endl;
return 0;
}
}
else
{ // Error, unrecognized particle
G4cout << "Can't convert particle with A=" << A << ", Z=" << Z << ", S=" << S
<< " to G4ParticleDefinition, trouble ahead" << G4endl;
return 0;
}
}
G4ReactionProduct* G4AblaInterface::toG4Particle(G4int A, G4int Z, G4int S,
G4double kinE, G4double px,
G4double py, G4double pz) const {
G4ParticleDefinition* def = toG4ParticleDefinition(A, Z, S);
if(def == 0)
{ // Check if we have a valid particle definition
return 0;
}
G4ReactionProduct*
G4AblaInterface::toG4Particle(G4int A, G4int Z, G4int S, G4double kinE, G4double px, G4double py, G4double pz) const
{
G4ParticleDefinition* def = toG4ParticleDefinition(A, Z, S);
if (def == 0)
{ // Check if we have a valid particle definition
return 0;
}
const G4double energy = kinE * MeV;
const G4ThreeVector momentum(px, py, pz);
const G4ThreeVector momentumDirection = momentum.unit();
G4DynamicParticle p(def, momentumDirection, energy);
G4ReactionProduct* r = new G4ReactionProduct(def);
(*r) = p;
return r;
const G4double energy = kinE * MeV;
const G4ThreeVector momentum(px, py, pz);
const G4ThreeVector momentumDirection = momentum.unit();
G4DynamicParticle p(def, momentumDirection, energy);
G4ReactionProduct* r = new G4ReactionProduct(def);
(*r) = p;
return r;
}
void G4AblaInterface::ModelDescription(std::ostream& outFile) const
{
outFile << "ABLA++ does not provide an implementation of the ApplyYourself method!\n\n";
outFile << "ABLA++ does not provide an implementation of the ApplyYourself "
"method!\n\n";
}
void G4AblaInterface::DeExciteModelDescription(std::ostream& outFile) const
{
outFile
<< "ABLA++ is a statistical model for nuclear de-excitation. It simulates\n"
<< "the gamma emission and the evaporation of neutrons, light charged\n"
<< "particles and IMFs, as well as fission where applicable. The code\n"
<< "included in Geant4 is a C++ translation of the original Fortran\n"
<< "code ABLA07. Although the model has been recently extended to\n"
<< "hypernuclei by including the evaporation of lambda particles.\n"
<< "More details about the physics are available in the Geant4\n"
<< "Physics Reference Manual and in the reference articles.\n\n"
<< "References:\n"
<< "(1) A. Kelic, M. V. Ricciardi, and K. H. Schmidt, in Proceedings of "
"Joint\n"
<< "ICTP-IAEA Advanced Workshop on Model Codes for Spallation Reactions,\n"
<< "ICTP Trieste, Italy, 48 February 2008, edited by D. Filges, S. Leray, "
"Y. Yariv,\n"
<< "A. Mengoni, A. Stanculescu, and G. Mank (IAEA INDC(NDS)-530, Vienna, "
"2008), pp. 181221.\n\n"
<< "(2) J.L. Rodriguez-Sanchez, J.-C. David et al., Phys. Rev. C 98, "
"021602 (2018)\n\n";
outFile << "ABLA++ is a statistical model for nuclear de-excitation. It simulates\n"
<< "the gamma emission and the evaporation of neutrons, light charged\n"
<< "particles and IMFs, as well as fission where applicable. The code\n"
<< "included in Geant4 is a C++ translation of the original Fortran\n"
<< "code ABLA07. Although the model has been recently extended to\n"
<< "hypernuclei by including the evaporation of lambda particles.\n"
<< "More details about the physics are available in the Geant4\n"
<< "Physics Reference Manual and in the reference articles.\n\n"
<< "References:\n"
<< "(1) A. Kelic, M. V. Ricciardi, and K. H. Schmidt, in Proceedings of Joint\n"
<< "ICTP-IAEA Advanced Workshop on Model Codes for Spallation Reactions,\n"
<< "ICTP Trieste, Italy, 48 February 2008, edited by D. Filges, S. "
"Leray, Y. Yariv, A. Mengoni, A. Stanculescu, and G. Mank (IAEA "
"INDC(NDS)-530, Vienna, 2008), pp. 181221.\n\n"
<< "(2) J.L. Rodriguez-Sanchez, J.-C. David et al., Phys. Rev. C 98, 021602R (2018)\n"
<< "(3) J.L. Rodriguez-Sanchez et al., Phys. Rev. C 105, 014623 (2022)\n"
<< "(4) J.L. Rodriguez-Sanchez et al., Phys. Rev. Lett. 130, 132501 (2023)\n\n";
}
@@ -24,33 +24,19 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#include "globals.hh"
#include "G4AblaRandom.hh"
#ifdef ABLAXX_IN_GEANT4_MODE
#include "globals.hh"
#include "Randomize.hh"
#else
#include "G4INCLRandom.hh"
#endif // ABLAXX_IN_GEANT4_MODE
#include "globals.hh"
namespace G4AblaRandom {
double flat() {
#ifdef ABLAXX_IN_GEANT4_MODE
return G4UniformRand();
#else
return G4INCL::Random::shoot();
#endif
}
}
namespace G4AblaRandom
{
G4double flat() { return G4UniformRand(); }
} // namespace G4AblaRandom
@@ -24,149 +24,86 @@
// ********************************************************************
//
// ABLAXX statistical de-excitation model
// Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person)
// Jose Luis Rodriguez, UDC (translation from ABLA07 and contact person)
// Pekka Kaitaniemi, HIP (initial translation of ablav3p)
// Aleksandra Kelic, GSI (ABLA07 code)
// Davide Mancusi, CEA (contact person INCL)
// Aatos Heikkinen, HIP (project coordination)
//
#define ABLAXX_IN_GEANT4_MODE 1
#include "G4AblaVirtualData.hh"
#include "globals.hh"
#include "G4AblaVirtualData.hh"
#ifdef ABLAXX_IN_GEANT4_MODE
G4AblaVirtualData::G4AblaVirtualData() {}
#else
G4AblaVirtualData::G4AblaVirtualData(G4INCL::Config *) {}
#endif
G4AblaVirtualData::~G4AblaVirtualData() {}
bool G4AblaVirtualData::setAlpha(int A, int Z, double value)
G4bool G4AblaVirtualData::setAlpha(G4int A, G4int Z, G4double value)
{
alpha[A][Z] = value;
alpha[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setEcnz(int A, int Z, double value)
G4bool G4AblaVirtualData::setEcnz(G4int A, G4int Z, G4double value)
{
ecnz[A][Z] = value;
ecnz[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setVgsld(int A, int Z, double value)
G4bool G4AblaVirtualData::setVgsld(G4int A, G4int Z, G4double value)
{
vgsld[A][Z] = value;
vgsld[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setPace2(int A, int Z, double value)
G4bool G4AblaVirtualData::setRms(G4int A, G4int Z, G4double value)
{
pace2[A][Z] = value;
rms[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setRms(int A, int Z, double value)
G4bool G4AblaVirtualData::setMexp(G4int A, G4int Z, G4double value)
{
rms[A][Z] = value;
mexp[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setMexp(int A, int Z, double value)
G4bool G4AblaVirtualData::setMexpID(G4int A, G4int Z, G4int value)
{
mexp[A][Z] = value;
mexpid[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setMexpID(int A, int Z, int value)
G4bool G4AblaVirtualData::setBeta2(G4int A, G4int Z, G4double value)
{
mexpid[A][Z] = value;
beta2[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setBeta2(int A, int Z, double value)
G4bool G4AblaVirtualData::setBeta4(G4int A, G4int Z, G4double value)
{
beta2[A][Z] = value;
beta4[A][Z] = value;
return true;
return true;
}
bool G4AblaVirtualData::setBeta4(int A, int Z, double value)
{
beta4[A][Z] = value;
G4double G4AblaVirtualData::getAlpha(G4int A, G4int Z) { return alpha[A][Z]; }
return true;
}
G4double G4AblaVirtualData::getEcnz(G4int A, G4int Z) { return ecnz[A][Z]; }
G4double G4AblaVirtualData::getVgsld(G4int A, G4int Z) { return vgsld[A][Z]; }
double G4AblaVirtualData::getAlpha(int A, int Z)
{
return alpha[A][Z];
}
G4double G4AblaVirtualData::getRms(G4int A, G4int Z) { return rms[A][Z]; }
double G4AblaVirtualData::getEcnz(int A, int Z)
{
return ecnz[A][Z];
}
G4double G4AblaVirtualData::getMexp(G4int A, G4int Z) { return mexp[A][Z]; }
double G4AblaVirtualData::getVgsld(int A, int Z)
{
return vgsld[A][Z];
}
G4int G4AblaVirtualData::getMexpID(G4int A, G4int Z) { return mexpid[A][Z]; }
double G4AblaVirtualData::getPace2(int A, int Z)
{
return pace2[A][Z];
}
G4double G4AblaVirtualData::getBeta2(G4int A, G4int Z) { return beta2[A][Z]; }
double G4AblaVirtualData::getRms(int A, int Z)
{
return rms[A][Z];
}
double G4AblaVirtualData::getMexp(int A, int Z)
{
return mexp[A][Z];
}
int G4AblaVirtualData::getMexpID(int A, int Z)
{
return mexpid[A][Z];
}
double G4AblaVirtualData::getBeta2(int A, int Z)
{
return beta2[A][Z];
}
double G4AblaVirtualData::getBeta4(int A, int Z)
{
return beta4[A][Z];
}
int G4AblaVirtualData::getAlphaRows()
{
return alphaRows;
}
int G4AblaVirtualData::getAlphaCols()
{
return alphaCols;
}
int G4AblaVirtualData::getPaceRows()
{
return paceRows;
}
int G4AblaVirtualData::getPaceCols()
{
return paceCols;
}
G4double G4AblaVirtualData::getBeta4(G4int A, G4int Z) { return beta4[A][Z]; }
@@ -6,7 +6,7 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-05-22 Gunter Folger (had-binary-V11-01-01)
## 2024-05-22 Gunter Folger (had-binary-V11-02-00)
- Address problem reported by Atlas of throwing execption if momentum cannot
be corrected. Problem ocurrs for D + H around 1600 MeV
- The exception is removed,in this rare case the initial state is kept
@@ -5,6 +5,33 @@ which **must** added in reverse chronological order (newest at the top).
It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-01-29 Dennis Wright (hadr-casc-V11-02-02)
- G4CascadeFinalStateAlgorithm::GenerateCosTheta()
For 4-body and higher-body generation of cosTheta, use direct sampling
of exp(1 - cosTheta) instead of previously used rejection method on
sinTheta * exp(-sinTheta). This removes the reflection about cosTheta = 0
that caused a symmetric double bump in the Feynman-x distribution.
## 2024-01-24 Dennis Wright (hadr-casc-V11-02-01)
- G4InuclSpecialFunctions::inuclRndm() is just a wrapper of G4UniformRand()
remove method from class G4InuclSpecialFunctions and replace all
occurrences of inuclRndm() with G4UniformRand() in files
G4BigBanger.cc
G4CascadeFinalStateAlgorithm.cc
G4EquilibriumEvaporator.cc
G4Fissioner.cc
G4IntraNucleiCascader.cc
G4InuclParamAngDst.cc
G4InuclSpecialFunctions.cc
G4NonEquilibriumEvaporator.cc
G4NucleiModel.cc
## 2023-12-11 Dennis Wright (hadr-casc-V11-02-00)
- improved calculation of di-nucleon density using Levinger quasi-deuteron
model proposed by Einar Elen (Lund) and Natalia Toro (SLAC) :
- add method G4NucleiModel::setDinucleonDensityScale() to calculate
correction factor to be applied to dinucleon densities
- modify method G4NucleiModel::getCurrentDensity() to apply this factor
## 2023-11-17 Vladimir Ivantchenko (hadr-casc-V11-01-03)
- G4CascadeParamMessenger - fixed memory leak at exit and simplified the code.
@@ -66,8 +66,6 @@ namespace G4InuclSpecialFunctions {
G4double G4cbrt(G4double x); // Can't use "cbrt" name, clashes with <math.h>
G4double G4cbrt(G4int n); // Use G4Pow::powN() here for speedup
G4double inuclRndm(); // Wrapper for G4UniformRand()
G4double randomInuclPowers(G4double ekin, // Power series in Ekin, S
const G4double (&coeff)[4][4]);
@@ -241,6 +241,9 @@ protected:
G4double generateInteractionLength(const G4CascadParticle& cparticle,
G4double path, G4double invmfp) const;
// Set scaling factor for effective number of di-nucleons in nucleus
void setDinucleonDensityScale();
private:
G4int verboseLevel;
@@ -289,6 +292,11 @@ private:
G4int current_nucl1;
G4int current_nucl2;
G4double dinucleonDensityScale;
// Ratio of naive to effective number of di-nucleons as predicted in
// local density approximation
// O. Benhar et al., arXiv:nucl-th/0301091v1. (2003)
G4CascadeInterpolator<30> gammaQDinterp; // quasideuteron interpolator
// Symbolic names for nuclear potentials
@@ -58,6 +58,7 @@
#include "G4InuclSpecialFunctions.hh"
#include "G4ParticleLargerEkin.hh"
#include "G4Pow.hh"
#include "Randomize.hh"
using namespace G4InuclSpecialFunctions;
@@ -327,12 +328,12 @@ G4double G4BigBanger::generateX(G4int a, G4double promax) const {
G4int itry = 0;
G4double x;
while(itry < itry_max) { /* Loop checking 08.06.2015 MHK */
while(itry < itry_max) { /* Loop checking 08.06.2015 MHK */
itry++;
x = inuclRndm();
x = G4UniformRand();
if(xProbability(x, a) >= promax*G4UniformRand() ) return x;
}
if(xProbability(x, a) >= promax * inuclRndm()) return x;
};
if (verboseLevel > 2) {
G4cout << " BigBanger -> can not generate x " << G4endl;
}
@@ -45,7 +45,6 @@
#include "G4CascadeFinalStateAlgorithm.hh"
#include "G4CascadeParameters.hh"
#include "G4Exp.hh"
#include "G4InuclElementaryParticle.hh"
#include "G4InuclSpecialFunctions.hh"
#include "G4LorentzConvertor.hh"
@@ -413,7 +412,7 @@ G4double G4CascadeFinalStateAlgorithm::
GenerateCosTheta(G4int ptype, G4double pmod) const {
if (GetVerboseLevel() > 2) {
G4cout << " >>> " << GetName() << "::GenerateCosTheta " << ptype
<< " " << pmod << G4endl;
<< " " << pmod << G4endl;
}
if (multiplicity == 3) { // Use distribution for three-body
@@ -421,39 +420,14 @@ GenerateCosTheta(G4int ptype, G4double pmod) const {
}
// Throw multi-body distribution
G4double p0 = ptype<3 ? 0.36 : 0.25; // Nucleon vs. everything else
G4double alf = 1.0 / p0 / (p0 - (pmod+p0)*G4Exp(-pmod / p0));
G4double sinth = 2.0;
G4int itry1 = -1; /* Loop checking 08.06.2015 MHK */
while (std::fabs(sinth) > maxCosTheta && ++itry1 < itry_max) {
G4double s1 = pmod * inuclRndm();
G4double s2 = alf * oneOverE * p0 * inuclRndm();
G4double salf = s1 * alf * G4Exp(-s1 / p0);
if (GetVerboseLevel() > 3) {
G4cout << " s1 * alf * G4Exp(-s1 / p0) " << salf
<< " s2 " << s2 << G4endl;
}
if (salf > s2) sinth = s1 / pmod;
}
if (GetVerboseLevel() > 3)
G4cout << " itry1 " << itry1 << " sinth " << sinth << G4endl;
if (itry1 == itry_max) {
if (GetVerboseLevel() > 2)
G4cout << " high energy angles generation: itry1 " << itry1 << G4endl;
sinth = 0.5 * inuclRndm();
}
// Convert generated sin(theta) to cos(theta) with random sign
G4double costh = std::sqrt(1.0 - sinth * sinth);
if (inuclRndm() > 0.5) costh = -costh;
return costh;
// Sample costheta directly from exp(-a*pmod*(1 - costheta) )
// Previous method sampled from a*sintheta*exp(-a*sintheta),
// converted to costheta and (incorrectly) reflected around 180 degrees
//
G4double p0 = ptype < 3 ? 0.36 : 0.25; // 0.36 for nucleon, 0.25 for all others
G4double alf = 3.*pmod/p0;
return G4Log(G4UniformRand()*(G4Exp(2.*alf) - 1.) + 1.)/alf - 1.;
}
@@ -400,13 +400,13 @@ void G4EquilibriumEvaporator::deExcite(const G4Fragment& target,
G4cout << " T04 " << T04 << " FMAX (EEXS^4) " << FMAX << G4endl;
G4double S(0), X1(0);
while (itry < itry_max) {
itry++;
S = EEXS * inuclRndm();
X1 = (S*S*S*S) * G4Exp((EEXS - S) / T00);
while (itry < itry_max) {
itry++;
S = EEXS*G4UniformRand();
X1 = (S*S*S*S) * G4Exp((EEXS - S) / T00);
if (X1 > FMAX * inuclRndm()) break;
};
if (X1 > FMAX*G4UniformRand() ) break;
}
if (itry == itry_max) { // Maximum attempts exceeded
try_again = false;
@@ -448,7 +448,8 @@ void G4EquilibriumEvaporator::deExcite(const G4Fragment& target,
} // while (EEXS > cut_off
try_again = false;
} else { // if (prob_sum < prob_cut_off)
G4double SL = prob_sum * inuclRndm();
G4double SL = prob_sum*G4UniformRand();
if (verboseLevel > 3) G4cout << " random SL " << SL << G4endl;
G4double S1 = 0.0;
@@ -58,6 +58,7 @@
#include "G4FissionStore.hh"
#include "G4FissionConfiguration.hh"
#include "G4InuclSpecialFunctions.hh"
#include "Randomize.hh"
using namespace G4InuclSpecialFunctions;
@@ -148,7 +149,7 @@ void G4Fissioner::deExcite(const G4Fragment& target,
if (store_size == 0) return; // No fission products
G4FissionConfiguration config =
fissionStore.generateConfiguration(ALMA, inuclRndm());
fissionStore.generateConfiguration(ALMA, G4UniformRand() );
A1 = G4int(config.afirst);
A2 = A - A1;
@@ -346,8 +346,8 @@ void G4IntraNucleiCascader::setupCascade() {
theExitonConfiguration.incrementQP(knd);
};
G4int ihn = G4int(2 * (ab-zb) * inuclRndm() + 0.5);
G4int ihz = G4int(2 * zb * inuclRndm() + 0.5);
G4int ihn = G4int(2 * (ab-zb)*G4UniformRand() + 0.5);
G4int ihz = G4int(2.*zb*G4UniformRand() + 0.5);
for (i = 0; i < ihn; i++) theExitonConfiguration.incrementHoles(2);
for (i = 0; i < ihz; i++) theExitonConfiguration.incrementHoles(1);
@@ -35,6 +35,8 @@
#include "G4InuclParamAngDst.hh"
#include "G4InuclSpecialFunctions.hh"
#include "G4InuclParticleNames.hh"
#include "Randomize.hh"
using namespace G4InuclSpecialFunctions;
using namespace G4InuclParticleNames;
@@ -67,7 +69,7 @@ G4double G4InuclParamAngDst::GetCosTheta(G4int ptype, G4double ekin) const {
<< G4endl;
}
Spow = inuclRndm();
Spow = G4UniformRand();
}
return 2.0*Spow - 1.0; // Convert generated [0..1] to [-1..1]
@@ -121,15 +121,12 @@ G4double G4InuclSpecialFunctions::G4cbrt(G4int n) {
return n==0 ? 0. : (n<0?-1.:1.)*G4Pow::GetInstance()->Z13(std::abs(n));
}
G4double G4InuclSpecialFunctions::inuclRndm() {
return G4UniformRand();
}
G4double G4InuclSpecialFunctions::randomGauss(G4double sigma) {
const G4double eps = 1.0e-6;
G4double r1 = inuclRndm();
G4double r1 = G4UniformRand();
r1 = r1 > eps ? r1 : eps;
G4double r2 = inuclRndm();
G4double r2 = G4UniformRand();
r2 = r2 > eps ? r2 : eps;
r2 = r2 < 1.0 - eps ? r2 : 1.0 - eps;
@@ -137,11 +134,11 @@ G4double G4InuclSpecialFunctions::randomGauss(G4double sigma) {
}
G4double G4InuclSpecialFunctions::randomPHI() {
return twopi * inuclRndm();
return twopi*G4UniformRand();
}
std::pair<G4double, G4double> G4InuclSpecialFunctions::randomCOS_SIN() {
G4double CT = 1.0 - 2.0 * inuclRndm();
G4double CT = 1.0 - 2.0*G4UniformRand();
return std::pair<G4double, G4double>(CT, std::sqrt(1.0 - CT*CT));
}
@@ -61,6 +61,7 @@
#include "G4InuclSpecialFunctions.hh"
#include "G4LorentzConvertor.hh"
#include "G4Pow.hh"
#include "Randomize.hh"
using namespace G4InuclSpecialFunctions;
@@ -222,25 +223,25 @@ void G4NonEquilibriumEvaporator::deExcite(const G4Fragment& target,
try_again = NEX > 1 && (D[1] > width_cut * D[0] ||
D[2] > width_cut * D[0]);
if (try_again) {
G4double D5 = D[0] + D[1] + D[2];
G4double SL = D5 * inuclRndm();
G4double S1 = 0.;
if (try_again) {
G4double D5 = D[0] + D[1] + D[2];
G4double SL = D5*G4UniformRand();
G4double S1 = 0.;
if (verboseLevel > 3)
G4cout << " D5 " << D5 << " SL " << SL << G4endl;
if (verboseLevel > 3)
G4cout << " D5 " << D5 << " SL " << SL << G4endl;
for (G4int i = 0; i < 3; i++) {
S1 += D[i];
if (SL <= S1) {
icase = i;
break;
}
}
for (G4int i = 0; i < 3; i++) {
S1 += D[i];
if (SL <= S1) {
icase = i;
break;
}
}
if (verboseLevel > 3)
G4cout << " got icase " << icase << G4endl;
} // if (try_again)
if (verboseLevel > 3)
G4cout << " got icase " << icase << G4endl;
} // if (try_again)
} // if (NEX >= 2)
} else try_again = false; // if (D[0] > 0)
} else try_again = false; // if (F1>0 && F2>0)
@@ -304,16 +305,16 @@ void G4NonEquilibriumEvaporator::deExcite(const G4Fragment& target,
itry1++;
G4int itry = 0;
/* Loop checking 08.06.2015 MHK */
while (EEXS_new < 0.0 && itry < itry_max) {
itry++;
G4double R = inuclRndm();
G4double X;
/* Loop checking 08.06.2015 MHK */
while (EEXS_new < 0.0 && itry < itry_max) {
itry++;
G4double R = G4UniformRand();
G4double X;
if (NEX == 2) {
X = 1.0 - std::sqrt(R);
if (NEX == 2) {
X = 1.0 - std::sqrt(R);
} else {
} else {
G4double QEX2 = 1.0 / QEX;
G4double QEX1 = 1.0 / (QEX-1);
X = theG4Pow->powA(0.5*R, QEX2);
@@ -441,18 +442,18 @@ void G4NonEquilibriumEvaporator::deExcite(const G4Fragment& target,
QH++;
AR--;
if (AR > 1) {
G4double SL = PW * inuclRndm();
if (AR > 1) {
G4double SL = PW*G4UniformRand();
if (SL > PP) {
QNP++;
QNH++;
} else {
QPP++;
QPH++;
ZR--;
if (ZR < 2) try_again = false;
}
if (SL > PP) {
QNP++;
QNH++;
} else {
QPP++;
QPH++;
ZR--;
if (ZR < 2) try_again = false;
}
} else try_again = false;
} // if (icase==0 && try_again)
} // if (try_again)
@@ -179,6 +179,7 @@
#include "G4Neutron.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleLargerBeta.hh"
#include "G4Pow.hh"
#include "G4PhysicalConstants.hh"
#include "G4Proton.hh"
#include "G4SystemOfUnits.hh"
@@ -378,6 +379,8 @@ void G4NucleiModel::generateModel(G4int a, G4int z) {
zone_potentials.push_back(kp);
zone_potentials.push_back(hp);
setDinucleonDensityScale();
nuclei_radius = zone_radii.back();
nuclei_volume = std::accumulate(zone_volumes.begin(),zone_volumes.end(),0.);
@@ -646,7 +649,7 @@ G4double G4NucleiModel::getFermiKinetic(G4int ip, G4int izone) const {
G4LorentzVector
G4NucleiModel::generateNucleonMomentum(G4int type, G4int zone) const {
G4double pmod = getFermiMomentum(type, zone) * G4cbrt(inuclRndm());
G4double pmod = getFermiMomentum(type, zone) * G4cbrt(G4UniformRand() );
G4double mass = G4InuclElementaryParticle::getParticleMass(type);
return generateWithRandomAngles(pmod, mass);
@@ -830,7 +833,7 @@ G4NucleiModel::generateInteractionPartners(G4CascadParticle& cparticle) {
G4double apath = generateInteractionLength(cparticle, path, tot_invmfp);
if (path<small || apath < path) { // choose the qdeutron
G4double sl = inuclRndm() * tot_invmfp;
G4double sl = G4UniformRand()*tot_invmfp;
G4double as = 0.0;
for (std::size_t i = 0; i < qdeutrons.size(); i++) {
@@ -1394,9 +1397,49 @@ G4double G4NucleiModel::getRatio(G4int ip) const {
return 0.;
}
void G4NucleiModel::setDinucleonDensityScale() {
if (A < 5) {
dinucleonDensityScale = 1.0;
// No scaling for light nuclei
return;
}
// At what A should LDA start to be applied?
// Not satisfactory for medium nuclei according to Benhar et al., and a
// sizable experimental uncertainty
// Levinger factor
const G4double Levinger_LDA {10.83 - 9.73/G4Pow::GetInstance()->A13(A)};
// Effective number of quasi-deuterons in a nucleus according to
// local density approximation
const G4double num_LDA_QDs {(Levinger_LDA*Z*(A-Z))/A};
// Number of quasi-deuterons expected from proton and neutron nuclear
// shell densities alone
G4double num_Naive_QDs{0.};
for (G4int zone = 0; zone < number_of_zones; ++zone) {
num_Naive_QDs += getVolume(zone)*getDensity(proton, zone)*
getVolume(zone)*getDensity(neutron, zone);
}
// Density scaling factor determined for quasi-deuterons to be used
// for pp, nn, pn
dinucleonDensityScale = num_LDA_QDs/num_Naive_QDs;
if (verboseLevel > 4) {
G4cout << " >>> G4NucleiModel::setDinucleonDensityScale()" << G4endl;
G4cout << " >>> Naive number of quasi-deuterons in nucleus ("
<< Z << ", " << A << ") = " << num_Naive_QDs << G4endl;
G4cout << " >>> Number of quasi-deuterons expected from Levinger LDA is "
<< num_LDA_QDs << G4endl;
G4cout << "Rescaling dinucleon densities by " << dinucleonDensityScale << G4endl;
}
}
G4double G4NucleiModel::getCurrentDensity(G4int ip, G4int izone) const {
const G4double pn_spec = 1.0; // Scale factor for pn vs. pp/nn
//const G4double pn_spec = 0.5;
// const G4double pn_spec = 1.0; // Scale factor for pn vs. pp/nn
const G4double combinatoric_factor = 0.5;
G4double dens = 0.;
@@ -1404,13 +1447,16 @@ G4double G4NucleiModel::getCurrentDensity(G4int ip, G4int izone) const {
else { // For dibaryons, remove extra 1/volume term in density product
switch (ip) {
case diproton:
dens = getDensity(proton,izone) * getDensity(proton,izone);
dens = getDensity(proton,izone) * getDensity(proton,izone)
* dinucleonDensityScale * combinatoric_factor;
break;
case unboundPN:
dens = getDensity(proton,izone) * getDensity(neutron,izone) * pn_spec;
dens = getDensity(proton,izone) * getDensity(neutron,izone)
* dinucleonDensityScale;
break;
case dineutron:
dens = getDensity(neutron,izone) * getDensity(neutron,izone);
dens = getDensity(neutron,izone) * getDensity(neutron,izone)
* dinucleonDensityScale * combinatoric_factor;
break;
default: dens = 0.;
}
@@ -1430,7 +1476,7 @@ G4NucleiModel::initializeCascad(G4InuclElementaryParticle* particle) {
// FIXME: Previous version generated random sin(theta), then used -cos(theta)
// Using generateWithRandomAngles changes result!
// G4ThreeVector pos = generateWithRandomAngles(nuclei_radius).vect();
G4double costh = std::sqrt(1.0 - inuclRndm());
G4double costh = std::sqrt(1.0 - G4UniformRand() );
G4ThreeVector pos = generateWithFixedTheta(-costh, nuclei_radius);
// Start particle outside nucleus, unless capture-at-rest
@@ -1490,31 +1536,31 @@ void G4NucleiModel::initializeCascad(G4InuclNuclei* bullet,
if (bullet->getKineticEnergy()/ab > ekin_cut*ben) {
G4int itryg = 0;
/* Loop checking 08.06.2015 MHK */
/* Loop checking 08.06.2015 MHK */
while (casparticles.size() == 0 && itryg < itry_max) {
itryg++;
particles.clear();
itryg++;
particles.clear();
// nucleons coordinates and momenta in nuclei rest frame
coordinates.clear();
momentums.clear();
// nucleons coordinates and momenta in nuclei rest frame
coordinates.clear();
momentums.clear();
if (ab < 3) { // deuteron, simplest case
G4double r = 2.214 - 3.4208 * G4Log(1.0 - 0.981 * inuclRndm());
G4ThreeVector coord1 = generateWithRandomAngles(r).vect();
coordinates.push_back(coord1);
coordinates.push_back(-coord1);
if (ab < 3) { // deuteron, simplest case
G4double r = 2.214 - 3.4208 * G4Log(1.0 - 0.981*G4UniformRand() );
G4ThreeVector coord1 = generateWithRandomAngles(r).vect();
coordinates.push_back(coord1);
coordinates.push_back(-coord1);
G4double p = 0.0;
G4bool bad = true;
G4int itry = 0;
G4double p = 0.0;
G4bool bad = true;
G4int itry = 0;
while (bad && itry < itry_max) { /* Loop checking 08.06.2015 MHK */
itry++;
p = 456.0 * inuclRndm();
while (bad && itry < itry_max) { /* Loop checking 08.06.2015 MHK */
itry++;
p = 456.0*G4UniformRand();
if (p * p / (p * p + 2079.36) / (p * p + 2079.36) > 1.2023e-4 * inuclRndm() &&
p * r > 312.0) bad = false;
if (p*p / (p*p + 2079.36) / (p*p + 2079.36) > 1.2023e-4 *G4UniformRand()
&& p*r > 312.0) bad = false;
}
if (itry == itry_max)
@@ -1540,41 +1586,41 @@ void G4NucleiModel::initializeCascad(G4InuclNuclei* bullet,
G4int itry = 0;
if (ab == 3) {
while (badco && itry < itry_max) {/* Loop checking 08.06.2015 MHK */
if (itry > 0) coordinates.clear();
itry++;
G4int i(0);
if (ab == 3) {
while (badco && itry < itry_max) {/* Loop checking 08.06.2015 MHK */
if (itry > 0) coordinates.clear();
itry++;
G4int i(0);
for (i = 0; i < 2; i++) {
G4int itry1 = 0;
G4double ss, u, rho;
G4double fmax = G4Exp(-0.5) / std::sqrt(0.5);
for (i = 0; i < 2; i++) {
G4int itry1 = 0;
G4double ss, u, rho;
G4double fmax = G4Exp(-0.5) / std::sqrt(0.5);
while (itry1 < itry_max) { /* Loop checking 08.06.2015 MHK */
itry1++;
ss = -G4Log(inuclRndm());
u = fmax * inuclRndm();
rho = std::sqrt(ss) * G4Exp(-ss);
while (itry1 < itry_max) { /* Loop checking 08.06.2015 MHK */
itry1++;
ss = -G4Log(G4UniformRand() );
u = fmax*G4UniformRand();
rho = std::sqrt(ss) * G4Exp(-ss);
if (rho > u && ss < s3max) {
ss = r0forAeq3 * std::sqrt(ss);
coord1 = generateWithRandomAngles(ss).vect();
coordinates.push_back(coord1);
if (rho > u && ss < s3max) {
ss = r0forAeq3 * std::sqrt(ss);
coord1 = generateWithRandomAngles(ss).vect();
coordinates.push_back(coord1);
if (verboseLevel > 2){
G4cout << " i " << i << " r " << coord1.mag() << G4endl;
}
break;
}
}
if (verboseLevel > 2){
G4cout << " i " << i << " r " << coord1.mag() << G4endl;
}
break;
}
}
if (itry1 == itry_max) { // bad case
coord1.set(10000.,10000.,10000.);
coordinates.push_back(coord1);
break;
}
}
if (itry1 == itry_max) { // bad case
coord1.set(10000.,10000.,10000.);
coordinates.push_back(coord1);
break;
}
}
coord1 = -coordinates[0] - coordinates[1];
if (verboseLevel > 2) {
@@ -1623,24 +1669,24 @@ void G4NucleiModel::initializeCascad(G4InuclNuclei* bullet,
G4int itry1 = 0;
G4double ss;
while (itry1 < itry_max) { /* Loop checking 08.06.2015 MHK */
itry1++;
ss = -G4Log(inuclRndm());
u = fmax * inuclRndm();
while (itry1 < itry_max) { /* Loop checking 08.06.2015 MHK */
itry1++;
ss = -G4Log(G4UniformRand() );
u = fmax*G4UniformRand();
if (std::sqrt(ss) * G4Exp(-ss) * (1.0 + ss/b) > u
&& ss < s4max) {
ss = r0forAeq4 * std::sqrt(ss);
coord1 = generateWithRandomAngles(ss).vect();
coordinates.push_back(coord1);
if (std::sqrt(ss) * G4Exp(-ss) * (1.0 + ss/b) > u
&& ss < s4max) {
ss = r0forAeq4 * std::sqrt(ss);
coord1 = generateWithRandomAngles(ss).vect();
coordinates.push_back(coord1);
if (verboseLevel > 2) {
G4cout << " i " << i << " r " << coord1.mag() << G4endl;
}
if (verboseLevel > 2) {
G4cout << " i " << i << " r " << coord1.mag() << G4endl;
}
break;
}
}
break;
}
}
if (itry1 == itry_max) { // bad case
coord1.set(10000.,10000.,10000.);
@@ -1701,10 +1747,10 @@ void G4NucleiModel::initializeCascad(G4InuclNuclei* bullet,
while(itry2 < itry_max) { /* Loop checking 08.06.2015 MHK */
itry2++;
u = -G4Log(0.879853 - 0.8798502 * inuclRndm());
u = -G4Log(0.879853 - 0.8798502*G4UniformRand() );
x = u * G4Exp(-u);
if(x > inuclRndm()) {
if(x > G4UniformRand() ) {
p = std::sqrt(0.01953 * u);
mom = generateWithRandomAngles(p, massb);
momentums.push_back(mom);
@@ -1744,7 +1790,7 @@ void G4NucleiModel::initializeCascad(G4InuclNuclei* bullet,
}
// nuclei i.p. as a whole
G4double s1 = std::sqrt(inuclRndm());
G4double s1 = std::sqrt(G4UniformRand() );
G4double phi = randomPHI();
G4double rz = (nuclei_radius + rb) * s1;
G4ThreeVector global_pos(rz*std::cos(phi), rz*std::sin(phi),
@@ -1905,8 +1951,8 @@ G4NucleiModel::generateInteractionLength(const G4CascadParticle& cparticle,
G4cout << " mfp " << 1./invmfp << " pw " << pw << G4endl;
// Primary particle(s) should always interact at least once
if (forceFirst(cparticle) || (inuclRndm() < pw)) {
spath = -G4Log(1.0 - pw * inuclRndm()) / invmfp;
if (forceFirst(cparticle) || (G4UniformRand() < pw) ) {
spath = -G4Log(1.0 - pw*G4UniformRand() )/invmfp;
if (cparticle.young(young_cut, spath)) spath = large;
if (verboseLevel > 2)
@@ -6,8 +6,8 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-05-02 Gabriele Cosmo (hadr-cohe-V11-01-05)
- Fixed compilation warnings for potentially uninitialised local variables in
## 2024-05-02 Gabriele Cosmo (hadr-cohe-V11-02-00)
- Fixed compilation warnings for potentially initialised local variables in
SampleThetaCMS() for G4DiffuseElastic and G4NuclNuclDiffuseElastic.
## 2023-10-23 Vladimir Ivanchenko (hadr-cohe-V11-01-04)
@@ -6,16 +6,47 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-01-29 Vladimir Ivanchenko (hadr-deex-V11-01-12)
## 2024-05-30 Vladimir Ivanchenko (hadr-deex-V11-02-05)
- G4ExcitationHandle, G4NeutronRadCapture - correct model ID for IC electrons
- G4VCoulombBarrier, G4CoulombBarrier, G4GEMCoulombBarrier,
G4FermiBreakUpUtil - clean-up Coulomb barrier classes, removed unused
headers and variables
- G4GEMChannelVI, G4GEMProbabilityVI - updated interfaces and simplified
algorithm of computation of probability
## 2024-05-16 Vladimir Ivanchenko (hadr-deex-V11-02-04)
- G4NuclearLevelData, G4PairingCorrection, G4CameronGilbertPairingCorrections,
G4CameronGilbertShellCorrections - simplified computation of corrections,
computations are done in one place only, not spreaded between classes.
- G4EvaporationChannel, G4EvaporationProbability - fixed usage of pairing
corrections, agreement with test data is improved.
## 2024-05-09 Vladimir Ivanchenko (hadr-deex-V11-02-03)
- G4DeexPrecoParameters - moved definition of int and bool parameters to
source, improve comments, added default width of nuclear level needed
for selection of final excitation in a decay of an excited state
- G4VEmissionProbability - use the new width parameter
- G4EvaporationChannel - fixed computation of minimal kinetic energy of a
fragment for odd-even residual nucleaus
## 2024-01-29 Vladimir Ivanchenko (hadr-deex-V11-02-02)
- G4StatMFChannel - fixed compilation warnings at alma9-gcc131 seen in CMSSW
by substitution of C-arrays by std::vector
## 2024-01-25 Vladimir Ivanchenko
## 2024-01-25 Vladimir Ivanchenko (hadr-deex-V11-02-01)
- G4FermiBreakUpVI, G4FermiFragmentsPoolVI - fixed problem 2584 (production
of fake excited isomeres) by moving the check on lifetime limit from the
pull (initialized once as a static object) to the Initialise() method of
the model allowing to change this limit in an application, do not consider
decay chains with no final state.
- G4VEmissionProbability - substitute local variable "g" by "gg" to avoid
possible shadowing
- G4ExcitationHandler - improved debug printout
## 2024-01-23 Vladimir Ivanchenko (hadr-deex-V11-02-00)
- G4PhotonEvaporation - use in all computations abs(JP) instead of JP,
because since 11.2 JP may be negative due to parity. This address
problem report 2587.
## 2023-11-15 Vladimir Ivanchenko (hadr-deex-V11-01-11)
- G4FermiChannels - fixed memory leak at exit
@@ -78,6 +78,8 @@ private:
G4double muu;
G4double freeU;
G4double a0;
G4double a1;
G4double delta0;
G4double delta1;
// Gamma is A_f(2S_f+1) factor, where A_f is fragment atomic
@@ -88,18 +88,17 @@ G4double G4EvaporationChannel::GetEmissionProbability(G4Fragment* fragment)
{ return 0.0; }
G4double exEnergy = fragment->GetExcitationEnergy();
G4double delta0 = theLevelData->GetPairingCorrection(fragZ,fragA);
/*
G4cout << "G4EvaporationChannel::Initialize Z= "<<theZ<<" A= "<<theA
<< " FragZ= " << fragZ << " FragA= " << fragA
<< " exEnergy= " << exEnergy << " d0= " << delta0 << G4endl;
*/
if(exEnergy < delta0) { return 0.0; }
G4double fragMass = fragment->GetGroundStateMass();
mass = fragMass + exEnergy;
resMass = G4NucleiProperties::GetNuclearMass(resA, resZ);
if (mass <= evapMass + resMass) { return 0.0; }
ekinmax = 0.5*((mass-resMass)*(mass+resMass) + evapMass2)/mass - evapMass;
G4double elim = 0.0;
@@ -107,7 +106,7 @@ G4double G4EvaporationChannel::GetEmissionProbability(G4Fragment* fragment)
bCoulomb = theCoulombBarrier->GetCoulombBarrier(resA, resZ, 0.0);
// for OPTxs >0 penetration under the barrier is taken into account
elim = (0 != OPTxs) ? bCoulomb*0.6 : bCoulomb;
elim = (0 != OPTxs) ? bCoulomb*0.5 : bCoulomb;
}
/*
G4cout << "exEnergy= " << exEnergy << " Ec= " << bCoulomb
@@ -115,14 +114,12 @@ G4double G4EvaporationChannel::GetEmissionProbability(G4Fragment* fragment)
<< " Free= " << mass - resMass - evapMass
<< G4endl;
*/
if(mass <= resMass + evapMass + elim) { return 0.0; }
// Coulomb barrier compound at rest
G4double resM = mass - evapMass - elim;
if (resM < resMass) { return 0.0; }
G4double ekinmin =
std::max(0.5*((mass-resM)*(mass+resM) + evapMass2)/mass - evapMass, 0.0);
G4double ekinmin = 0.0;
if(elim > 0.0) {
G4double resM = mass - evapMass - elim;
ekinmin =
std::max(0.5*((mass-resM)*(mass+resM) + evapMass2)/mass - evapMass, 0.0);
}
/*
G4cout << "Emin= " <<ekinmin<<" Emax= "<<ekinmax
<< " mass= " << mass << " resM= " << resMass
@@ -133,7 +130,7 @@ G4double G4EvaporationChannel::GetEmissionProbability(G4Fragment* fragment)
theProbability->SetDecayKinematics(resZ, resA, resMass, mass);
G4double prob = theProbability->TotalProbability(*fragment, ekinmin,
ekinmax, bCoulomb,
exEnergy - delta0);
exEnergy);
return prob;
}
@@ -52,13 +52,16 @@
#include "G4Log.hh"
#include "G4Pow.hh"
static const G4double explim = 160.;
namespace
{
const G4double explim = 160.;
}
G4EvaporationProbability::G4EvaporationProbability(G4int anA, G4int aZ,
G4double aGamma)
: G4VEmissionProbability(aZ, anA), fGamma(aGamma)
{
resA13 = lastA = muu = freeU = a0 = delta1 = 0.0;
resA13 = lastA = muu = freeU = a0 = a1 = delta0 = delta1 = 0.0;
pcoeff = fGamma*pEvapMass*CLHEP::millibarn
/((CLHEP::pi*CLHEP::hbarc)*(CLHEP::pi*CLHEP::hbarc));
@@ -87,11 +90,11 @@ G4double G4EvaporationProbability::TotalProbability(
G4double CB, G4double exEnergy)
{
G4int fragA = fragment.GetA_asInt();
G4int fragZ = fragment.GetZ_asInt();
G4double U = fragment.GetExcitationEnergy();
a0 = pNuclearLevelData->GetLevelDensity(fragZ,fragA,U);
G4int fragZ = fragment.GetZ_asInt();
freeU = exEnergy;
delta1 = pNuclearLevelData->GetPairingCorrection(resZ,resA);
a0 = pNuclearLevelData->GetLevelDensity(fragZ, fragA, freeU);
delta0 = pNuclearLevelData->GetPairingCorrection(fragZ, fragA);
delta1 = pNuclearLevelData->GetPairingCorrection(resZ, resA);
resA13 = pG4pow->Z13(resA);
/*
G4cout << "G4EvaporationProbability: Z= " << theZ << " A= " << theA
@@ -112,7 +115,7 @@ G4double G4EvaporationProbability::TotalProbability(
G4double Beta = CalcBetaParam(fragment);
// to be checked where to use a0, where - a1
G4double a1 = pNuclearLevelData->GetLevelDensity(resZ,resA,freeU);
a1 = pNuclearLevelData->GetLevelDensity(resZ,resA,freeU);
G4double GlobalFactor = fGamma*Alpha*pEvapMass*RN2*resA13*resA13/(a1*a1);
G4double maxea = maxEnergy*a1;
@@ -140,20 +143,22 @@ G4double G4EvaporationProbability::TotalProbability(
}
G4double G4EvaporationProbability::ComputeProbability(G4double K, G4double CB)
{
G4double E0 = freeU;
{
// abnormal case - should never happens
if(pMass < pEvapMass + pResMass) { return 0.0; }
G4double m02 = pMass*pMass;
G4double m12 = pEvapMass*pEvapMass;
G4double mres = std::sqrt(m02 + m12 - 2.*pMass*(pEvapMass + K));
G4double pEvapM2 = pEvapMass*pEvapMass;
G4double mres = std::sqrt(pMass*pMass + pEvapM2 - 2.*pMass*(pEvapMass + K));
G4double excRes = mres - pResMass;
G4double E1 = excRes - delta1;
if(E1 <= 0.0) { return 0.0; }
G4double a1 = pNuclearLevelData->GetLevelDensity(resZ,resA,excRes);
G4double xs = CrossSection(K, CB);
if (excRes < 0.0) { return 0.0; }
a1 = pNuclearLevelData->GetLevelDensity(resZ, resA, excRes);
G4double E0 = std::max(freeU - delta0, 0.0);
G4double E1 = std::max(excRes - delta1, 0.0);
G4double erec = (pMass*(K + pEvapMass) - pEvapM2)/mres - pEvapMass;
erec = std::max(erec, 0.0);
G4double xs = CrossSection(erec, CB);
G4double prob = pcoeff*G4Exp(2.0*(std::sqrt(a1*E1) - std::sqrt(a0*E0)))*K*xs;
return prob;
}
@@ -173,7 +178,7 @@ G4EvaporationProbability::CrossSection(G4double K, G4double CB)
index, theZ, resA);
} else {
// added barrier penetration factor
G4double elim = 0.6*CB;
G4double elim = 0.5*CB;
if (K > elim) {
res = G4KalbachCrossSection::ComputeCrossSection(K, CB, resA13, muu,
index, theZ, theA, resA);
@@ -35,16 +35,15 @@
namespace G4FermiBreakUpUtil {
const G4double deltaR = 0.6*CLHEP::fermi;
const G4double coeff = 0.9;
const G4double coeff = 0.6;
// Coulomb barrier
G4double CoulombBarrier(const G4int Z1, const G4int A1,
const G4int Z2, const G4int A2, const G4double exc) {
const G4double r1 = G4NuclearRadii::RadiusCB(Z1, A1);
const G4double r2 = G4NuclearRadii::RadiusCB(Z2, A2);
G4double CB = coeff*CLHEP::elm_coupling*(Z1*Z2)/(r1 + r2 - deltaR);
if(exc > 0.0) { CB /= (1.0 + std::sqrt(exc/((2*(A1 + A2))*CLHEP::MeV))); }
G4double CB = CLHEP::elm_coupling*(Z1*Z2)/(coeff*r1 + r2);
if (exc > 0.0) { CB /= (1.0 + std::sqrt(exc/((2*(A1 + A2))*CLHEP::MeV))); }
return CB;
}
@@ -37,43 +37,60 @@ class G4VCoulombBarrier;
class G4LevelManager;
class G4GEMProbabilityVI;
class G4GEMChannelVI final: public G4VEvaporationChannel
class G4GEMChannelVI : public G4VEvaporationChannel
{
public:
explicit G4GEMChannelVI(G4int theA, G4int theZ);
~G4GEMChannelVI() final;
G4double GetEmissionProbability(G4Fragment* theNucleus) final;
~G4GEMChannelVI() override;
G4Fragment* EmittedFragment(G4Fragment* theNucleus) final;
void Initialise() override;
void Dump() const final;
G4double GetEmissionProbability(G4Fragment* theNucleus) override;
G4Fragment* EmittedFragment(G4Fragment* theNucleus) override;
void Dump() const override;
G4GEMChannelVI(const G4GEMChannelVI & right) = delete;
const G4GEMChannelVI & operator=(const G4GEMChannelVI & right) = delete;
G4bool operator==(const G4GEMChannelVI & right) const = delete;
G4bool operator!=(const G4GEMChannelVI & right) const = delete;
private:
G4GEMChannelVI(const G4GEMChannelVI & right);
const G4GEMChannelVI & operator=(const G4GEMChannelVI & right);
G4bool operator==(const G4GEMChannelVI & right) const;
G4bool operator!=(const G4GEMChannelVI & right) const;
const G4VCoulombBarrier* cBarrier;
const G4PairingCorrection* pairingCorrection;
G4GEMProbabilityVI* fProbability;
G4double fEvapMass;
G4double fEvapMass2;
G4double fMass{0.0};
G4double fResMass{0.0};
G4double fExc{0.0};
G4double bCoulomb{0.0};
G4double fCoeff;
G4int A;
G4int Z;
G4int resA;
G4int resZ;
G4int fragA;
G4int fragZ;
G4int secID; // Creator model ID for the secondaries created by this model
G4int resA{0};
G4int resZ{0};
G4int fragA{0};
G4int fragZ{0};
G4int fVerbose{1};
G4int nProb{1};
G4int secID;
G4int indexC;
G4double mass;
G4double resMass;
G4double evapMass;
G4double evapMass2;
// evaporation fragment data
struct evapData {
G4double exc{0.0}; // excitation
G4double ekin1{0.0}; // min kinetic energy
G4double ekin2{0.0}; // max kinetic energy
G4double prob{0.0}; // probability
};
evapData fEData[10];
};
#endif
@@ -33,6 +33,8 @@
#include "G4CoulombBarrier.hh"
#include "globals.hh"
class G4Pow;
class G4GEMCoulombBarrier : public G4CoulombBarrier
{
public:
@@ -50,6 +52,7 @@ private:
G4double CalcCompoundRadius(G4int ARes) const;
G4Pow* g4calc;
G4double AejectOneThird;
};
#endif
@@ -31,46 +31,35 @@
#include "G4VEmissionProbability.hh"
//const G4int NPOINTSGEM = 10;
class G4LevelManager;
class G4GEMProbabilityVI final: public G4VEmissionProbability
class G4GEMProbabilityVI : public G4VEmissionProbability
{
public:
explicit G4GEMProbabilityVI(G4int anA, G4int aZ, const G4LevelManager*);
~G4GEMProbabilityVI() final;
~G4GEMProbabilityVI() override = default;
G4double ComputeTotalProbability(const G4Fragment&, G4double CB);
G4double TotalProbability(const G4Fragment&,
const G4double tmin, const G4double tmax,
const G4double CB, const G4double exEnergy,
const G4double exEvap);
// compute probability for evaporated fragment in ground state
G4double ComputeProbability(G4double ekin, G4double CB) override;
G4Fragment* SampleEvaporationFragment();
G4double SampleEnergy(const G4double tmin, const G4double tmax,
const G4double CB, const G4double exEnergy,
const G4double exEvap);
G4GEMProbabilityVI(const G4GEMProbabilityVI& right) = delete;
const G4GEMProbabilityVI & operator=(const G4GEMProbabilityVI& right) = delete;
G4bool operator==(const G4GEMProbabilityVI& right) const = delete;
G4bool operator!=(const G4GEMProbabilityVI& right) const = delete;
private:
// compute probability for evaporated fragment may be excited
G4double Integrated2DProbability();
// probability as a function of excitations
G4double ProbabilityDistributionFunction(G4double exc, G4double resExc);
G4Fragment* Sample2DDistribution();
G4double I0(G4double t);
G4double I1(G4double t, G4double tx);
G4double I2(G4double s0, G4double sx);
G4double I3(G4double s0, G4double sx);
// Copy constructor
G4GEMProbabilityVI(const G4GEMProbabilityVI &right);
const G4GEMProbabilityVI & operator=(const G4GEMProbabilityVI &right);
G4bool operator==(const G4GEMProbabilityVI &right) const;
G4bool operator!=(const G4GEMProbabilityVI &right) const;
const G4LevelManager* lManager;
G4int fragA;
@@ -38,23 +38,50 @@
#include "G4NucleiProperties.hh"
#include "G4RandomDirection.hh"
#include "G4PhysicsModelCatalog.hh"
#include "Randomize.hh"
namespace
{
const G4double minExc = 1.0*CLHEP::MeV;
const G4int nProbMax = 10;
}
G4GEMChannelVI::G4GEMChannelVI(G4int theA, G4int theZ)
: A(theA), Z(theZ), secID(-1)
{
: A(theA), Z(theZ)
{
G4NuclearLevelData* nData = G4NuclearLevelData::GetInstance();
pairingCorrection = nData->GetPairingCorrection();
const G4LevelManager* lManager = nullptr;
if(A > 4) { lManager = nData->GetLevelManager(Z, A); }
evapMass = G4NucleiProperties::GetNuclearMass(A, Z);
evapMass2 = evapMass*evapMass;
if (A > 4) { lManager = nData->GetLevelManager(Z, A); }
fEvapMass = G4NucleiProperties::GetNuclearMass(A, Z);
fEvapMass2 = fEvapMass*fEvapMass;
cBarrier = new G4CoulombBarrier(A, Z);
fProbability = new G4GEMProbabilityVI(A, Z, lManager);
resA = resZ = fragZ = fragA = 0;
mass = resMass = 0.0;
fCoeff = CLHEP::millibarn/((CLHEP::pi*CLHEP::hbarc)*(CLHEP::pi*CLHEP::hbarc));
secID = G4PhysicsModelCatalog::GetModelID("model_G4GEMChannelVI");
if (Z == 0 && A == 1) {
indexC = 0;
fCoeff *= 2.0;
} else if (Z == 1 && A == 1) {
indexC = 1;
fCoeff *= 2.0;
} else if (Z == 1 && A == 2) {
indexC = 2;
fCoeff *= 3.0;
} else if (Z == 1 && A == 3) {
indexC = 3;
fCoeff *= 2.0;
} else if (Z == 2 && A == 3) {
indexC = 4;
fCoeff *= 2.0;
} else if (Z == 2 && A == 4) {
indexC = 5;
} else {
indexC = 6;
}
}
G4GEMChannelVI::~G4GEMChannelVI()
@@ -63,6 +90,12 @@ G4GEMChannelVI::~G4GEMChannelVI()
delete fProbability;
}
void G4GEMChannelVI::Initialise()
{
fProbability->Initialise();
G4VEvaporationChannel::Initialise();
}
G4double G4GEMChannelVI::GetEmissionProbability(G4Fragment* fragment)
{
fProbability->ResetProbability();
@@ -74,23 +107,53 @@ G4double G4GEMChannelVI::GetEmissionProbability(G4Fragment* fragment)
return 0.0;
}
const G4double exc = fragment->GetExcitationEnergy();
const G4double delta0 =
std::max(pairingCorrection->GetPairingCorrection(fragA, fragZ),0.0);
if(exc < delta0) { return 0.0; }
resMass = G4NucleiProperties::GetNuclearMass(resA, resZ);
const G4double fragM = fragment->GetGroundStateMass() + exc;
const G4double CB = cBarrier->GetCoulombBarrier(resA, resZ, exc);
const G4double delta1 =
std::max(0.0,pairingCorrection->GetPairingCorrection(resA,resZ));
if(fragM <= resMass + CB + delta1) { return 0.0; }
fExc = fragment->GetExcitationEnergy();
fMass = fragment->GetGroundStateMass() + fExc;
fResMass = G4NucleiProperties::GetNuclearMass(resA, resZ);
fProbability->SetDecayKinematics(resZ, resA, resMass, fragM);
G4double prob = fProbability->ComputeTotalProbability(*fragment, CB);
//G4cout<<"G4EvaporationChannel: probability= "<< prob <<G4endl;
return prob;
// limit for the case when both evaporation and residual
// fragments are in ground states
if (fMass <= fEvapMass + fResMass) { return 0.0; }
if (Z > 0) {
bCoulomb = cBarrier->GetCoulombBarrier(resA, resZ, 0.0);
}
G4double de = fMass - fEvapMass - fResMass - bCoulomb;
nProb = (G4int)(de/minExc);
if (nProb <= 1 || indexC < 6 || resA <= 4) {
nProb = 1;
} else {
nProb = std::min(nProb, nProbMax);
}
if (2 < fVerbose) {
G4cout << "## G4GEMChannelVI::GetEmissionProbability fragZ="
<< fragZ << " fragA=" << fragA << " Z=" << Z << " A=" << A
<< " Eex(MeV)=" << fExc << " nProb=" << nProb
<< G4endl;
}
fProbability->SetDecayKinematics(resZ, resA, fResMass, fMass);
G4double sump = 0.0;
for (G4int i=0; i<nProb; ++i) {
G4double exc = std::min(minExc*i, de);
G4double m1 = fEvapMass + exc;
G4double e2 = 0.5*((fMass-fResMass)*(fMass+fResMass) + m1*m1)/fMass - m1;
G4double m2 = fMass - m1 - 0.5*bCoulomb;
if (m2 < fResMass) {
nProb = i;
break;
}
G4double e1 = std::max(0.5*((fMass-m2)*(fMass+m2) + m1*m1)/fMass - m1, 0.0);
if (e1 >= e2) {
nProb = i;
break;
}
sump += fProbability->TotalProbability(*fragment, e1, e2, bCoulomb, fExc, exc);
fEData[i].exc = exc;
fEData[i].ekin1 = e1;
fEData[i].ekin2 = e2;
fEData[i].prob = sump;
}
return sump;
}
G4Fragment* G4GEMChannelVI::EmittedFragment(G4Fragment* theNucleus)
@@ -99,23 +162,36 @@ G4Fragment* G4GEMChannelVI::EmittedFragment(G4Fragment* theNucleus)
// if value iz zero no possiblity to sample final state
G4Fragment* evFragment = nullptr;
G4LorentzVector lv0 = theNucleus->GetMomentum();
if(resA <= 4 || fProbability->GetProbability() == 0.0) {
G4double ekin =
std::max(0.5*(mass*mass - resMass*resMass + evapMass2)/mass
- evapMass, 0.0);
G4LorentzVector lv(std::sqrt(ekin*(ekin + 2.0*evapMass))
*G4RandomDirection(), ekin + evapMass);
lv.boost(lv0.boostVector());
evFragment = new G4Fragment(A, Z, lv);
lv0 -= lv;
G4double ekin;
G4double exc = 0.0;
G4double probMax = std::max(fEData[nProb - 1].prob, 0.0);
if (0.0 >= probMax) {
ekin = std::max(0.5*(fMass*fMass - fResMass*fResMass + fEvapMass2)
/fMass - fEvapMass, 0.0);
} else if (1 == nProb) {
ekin = fProbability->SampleEnergy(fEData[0].ekin1, fEData[0].ekin2,
bCoulomb, fExc, 0.0);
} else {
evFragment = fProbability->SampleEvaporationFragment();
G4LorentzVector lv = evFragment->GetMomentum();
lv.boost(lv0.boostVector());
evFragment->SetMomentum(lv);
lv0 -= lv;
G4double p = G4UniformRand()*probMax;
G4int i{1};
for (; i<nProb; ++i) {
if (p <= fEData[i].prob) { break; }
}
G4double e1 = fEData[i - 1].exc;
G4double e2 = fEData[i].exc;
G4double p1 = fEData[i - 1].prob;
G4double p2 = fEData[i].prob;
exc = e1 + (e2 - e1)*(p - p1)/(p2 - p1);
ekin = fProbability->SampleEnergy(fEData[i].ekin1, fEData[i].ekin2,
bCoulomb, fExc, exc);
}
if(evFragment != nullptr) { evFragment->SetCreatorModelID(secID); }
G4double m1 = fEvapMass + exc;
G4LorentzVector lv(std::sqrt(ekin*(ekin + 2.0*m1))
*G4RandomDirection(), ekin + m1);
lv.boost(lv0.boostVector());
evFragment = new G4Fragment(A, Z, lv);
lv0 -= lv;
evFragment->SetCreatorModelID(secID);
theNucleus->SetZandA_asInt(resZ, resA);
theNucleus->SetMomentum(lv0);
theNucleus->SetCreatorModelID(secID);
@@ -36,6 +36,7 @@
G4GEMCoulombBarrier::G4GEMCoulombBarrier(G4int anA, G4int aZ) :
G4CoulombBarrier(anA, aZ)
{
g4calc = G4Pow::GetInstance();
AejectOneThird = g4calc->Z13(anA);
}
@@ -44,7 +45,7 @@ G4double G4GEMCoulombBarrier::GetCoulombBarrier(G4int ARes, G4int ZRes,
{
// Calculation of Coulomb potential energy (barrier) for outgoing fragment
G4double Barrier = 0.0;
if (theZ > 0 && ZRes > 0) {
if (theZ > 0) {
G4double CompoundRadius = CalcCompoundRadius(ARes);
Barrier = CLHEP::elm_coupling * (theZ * ZRes)/CompoundRadius;
@@ -38,33 +38,6 @@
#include "G4Pow.hh"
#include "G4Exp.hh"
// 10-Points Gauss-Legendre abcisas and weights
/*
const G4double G4GEMChannelVI::ws[] = {
0.0666713443086881,
0.149451349150581,
0.219086362515982,
0.269266719309996,
0.295524224714753,
0.295524224714753,
0.269266719309996,
0.219086362515982,
0.149451349150581,
0.0666713443086881
};
const G4double G4GEMChannelVI::xs[] = {
-0.973906528517172,
-0.865063366688985,
-0.679409568299024,
-0.433395394129247,
-0.148874338981631,
0.148874338981631,
0.433395394129247,
0.679409568299024,
0.865063366688985,
0.973906528517172
};
*/
G4GEMProbabilityVI::G4GEMProbabilityVI(G4int anA, G4int aZ, const G4LevelManager* p)
: G4VEmissionProbability(aZ, anA), lManager(p)
@@ -87,11 +60,11 @@ G4GEMProbabilityVI::G4GEMProbabilityVI(G4int anA, G4int aZ, const G4LevelManager
}
}
G4GEMProbabilityVI::~G4GEMProbabilityVI()
{}
G4double G4GEMProbabilityVI::ComputeTotalProbability(
const G4Fragment& fragment, G4double CB)
G4double G4GEMProbabilityVI::TotalProbability(
const G4Fragment& fragment,
const G4double tmin, const G4double tmax,
const G4double CB, const G4double exEnergy,
const G4double exEvap)
{
fragA = fragment.GetA_asInt();
fragZ = fragment.GetZ_asInt();
@@ -105,38 +78,15 @@ G4double G4GEMProbabilityVI::ComputeTotalProbability(
resA13 = pG4pow->Z13(resA);
a0 = pNuclearLevelData->GetLevelDensity(fragZ,fragA,U);
G4double C = 0.0;
G4int Z2 = theZ*theZ;
G4int Z3 = Z2*theZ;
G4int Z4 = Z2*Z2;
if(resA >= 50) {
C = -0.10/(G4double)theA;
} else if(resZ > 20) {
C = (0.123482-0.00534691*theZ-0.0000610624*Z2+5.93719*1e-7*Z3+
1.95687*1e-8*Z4)/(G4double)theA;
}
if(0 == theZ) {
alphaP = 0.76+1.93/resA13;
betaP = (1.66/(resA13*resA13)-0.05)*CLHEP::MeV/alphaP;
} else {
alphaP = 1.0 + C;
betaP = - bCoulomb;
}
if(isExcited) {
pProbability = Integrated2DProbability();
} else {
const G4double twoMass = pMass + pMass;
const G4double evapMass2 = pEvapMass*pEvapMass;
G4double ekinmax =
const G4double twoMass = pMass + pMass;
const G4double evapMass2 = pEvapMass*pEvapMass;
G4double ekinmax =
((pMass-pResMass)*(pMass+pResMass) + evapMass2)/twoMass - pEvapMass;
G4double ekinmin =
G4double ekinmin =
std::max((CB*(twoMass - CB) + evapMass2)/twoMass - pEvapMass,0.0);
if(ekinmax <= ekinmin) { return 0.0; }
pProbability = IntegrateProbability(ekinmin, ekinmax, CB);
}
if(ekinmax <= ekinmin) { return 0.0; }
pProbability = IntegrateProbability(ekinmin, ekinmax, CB);
pProbability += tmax - tmin + exEnergy -exEvap;
/*
G4cout << "G4GEMProbabilityVI: Z= " << theZ << " A= " << theA
<< " resZ= " << resZ << " resA= " << resA
@@ -159,141 +109,18 @@ G4double G4GEMProbabilityVI::ComputeProbability(G4double ekin, G4double)
G4double excRes = std::max(mres - pResMass, 0.0);
a1 = pNuclearLevelData->GetLevelDensity(resZ,resA,excRes);
G4double prob = ProbabilityDistributionFunction(0.0, excRes);
G4double prob = 0.5; //CrossSection(0.0, excRes);
//G4cout<<"### G4GEMProbabilityVI::ComputeProbability: Ekin(MeV)= "<<ekin
//<< " excRes(MeV)= " << excRes << " prob= " << prob << << G4endl;
return prob;
}
G4Fragment* G4GEMProbabilityVI::SampleEvaporationFragment()
G4double G4GEMProbabilityVI::SampleEnergy(
const G4double tmin, const G4double tmax,
const G4double CB, const G4double exEnergy,
const G4double exEvap)
{
if(isExcited) { return Sample2DDistribution(); }
G4double ekin = SampleEnergy();
G4LorentzVector lv(std::sqrt(ekin*(ekin + 2.0*pEvapMass))
*G4RandomDirection(), ekin + pEvapMass);
G4Fragment* evFragment = new G4Fragment(theA, theZ, lv);
return evFragment;
G4double ekin = tmax - tmin - CB -exEnergy + exEvap;
return ekin;
}
G4double G4GEMProbabilityVI::Integrated2DProbability()
{
return 0.0;
}
G4double G4GEMProbabilityVI::ProbabilityDistributionFunction(
G4double exc, G4double resExc)
{
G4double Ux = (2.5 + 150.0/G4double(resA))*CLHEP::MeV;
G4double Ex = Ux + delta1;
G4double T = 1.0/(std::sqrt(a0/Ux) - 1.5/Ux);
G4double E0 = Ex - T*(G4Log(T) - G4Log(a0)*0.25
- 1.25*G4Log(Ux) + 2.0*std::sqrt(a0*Ux));
G4double UxCN = (2.5 + 150.0/(G4double)theA)*CLHEP::MeV;
G4double ExCN = UxCN + delta0;
G4double TCN = 1.0/(std::sqrt(a0/UxCN) - 1.5/UxCN);
G4double mass1 = pEvapMass + exc;
G4double mass2 = pResMass + resExc;
G4double maxKinEnergy = std::max(0.5*((pMass - mass2)*(pMass + mass2)
+ mass1*mass1)/pMass - mass1, 0.0);
G4double Width = 0.0;
G4double t = maxKinEnergy/T;
if ( maxKinEnergy < Ex ) {
Width = (I1(t,t)*T + (betaP+bCoulomb)*I0(t))/G4Exp(E0/T);
} else {
G4double tx = Ex/T;
G4double s0 = 2.0*std::sqrt(a0*(maxKinEnergy-delta0));
G4double sx = 2.0*std::sqrt(a0*(Ex-delta0));
// VI: protection against FPE exception
s0 = std::min(s0, 350.);
G4double expE0T = G4Exp(E0/T);
G4double exps0 = G4Exp(s0);
const G4double sqrt2 = std::sqrt(2.0);
Width = I1(t,tx)*T/expE0T + I3(s0,sx)*exps0/(sqrt2*a0);
if (0 == theZ) {
Width += (betaP+bCoulomb)*(I0(tx)/expE0T + 2.0*sqrt2*I2(s0,sx)*exps0);
}
}
Width *= alphaP*pMass;
//JMQ 190709 fix on Rb and geometrical cross sections according to
// Furihata's paper (JAERI-Data/Code 2001-105, p6)
G4double Rb = 0.0;
if (theA > 4) {
Rb = 1.12*(resA13 + A13) - 0.86*((resA13 + A13)/(resA13*A13))+2.85;
} else if (theA > 1) {
Rb=1.5*(resA13 + A13);
} else {
Rb = 1.5*resA13;
}
G4double ild;
if (exc < ExCN ) {
G4double E0CN = ExCN - TCN*(G4Log(TCN) - 0.25*G4Log(a0)
- 1.25*G4Log(UxCN)
+ 2.0*std::sqrt(a0*UxCN));
ild = G4Exp((exc-E0CN)/TCN)/TCN;
} else {
G4double x = exc - delta0;
G4double x1 = std::sqrt(a0*x);
ild = G4Exp(2*x1)/(x*std::sqrt(x1));
}
Width *= (Rb*Rb/ild);
return Width;
}
G4Fragment* G4GEMProbabilityVI::Sample2DDistribution()
{
G4Fragment* aFragment = nullptr;
return aFragment;
}
G4double G4GEMProbabilityVI::I0(G4double t)
{
return G4Exp(t) - 1.0;
}
G4double G4GEMProbabilityVI::I1(G4double t, G4double tx)
{
return (t - tx + 1.0)*G4Exp(tx) - t - 1.0;
}
G4double G4GEMProbabilityVI::I2(G4double s0, G4double sx)
{
G4double S = 1.0/std::sqrt(s0);
G4double Sx = 1.0/std::sqrt(sx);
G4double p1 = S*S*S*( 1.0 + S*S*( 1.5 + 3.75*S*S) );
G4double p2 = Sx*Sx*Sx*( 1.0 + Sx*Sx*( 1.5 + 3.75*Sx*Sx) )*G4Exp(sx-s0);
return p1-p2;
}
G4double G4GEMProbabilityVI::I3(G4double s0, G4double sx)
{
G4double s2 = s0*s0;
G4double sx2 = sx*sx;
G4double S = 1.0/std::sqrt(s0);
G4double S2 = S*S;
G4double Sx = 1.0/std::sqrt(sx);
G4double Sx2 = Sx*Sx;
G4double p1 = S *(2.0 + S2 *( 4.0 + S2 *( 13.5 + S2 *( 60.0 + S2 * 325.125 ))));
G4double p2 = Sx*Sx2 *((s2-sx2) + Sx2 *((1.5*s2+0.5*sx2)
+ Sx2 *((3.75*s2+0.25*sx2) + Sx2 *((12.875*s2+0.625*sx2)
+ Sx2 *((59.0625*s2+0.9375*sx2) + Sx2 *(324.8*s2+3.28*sx2))))));
p2 *= G4Exp(sx-s0);
return p1-p2;
}
@@ -139,7 +139,6 @@ void G4ExcitationHandler::SetParameters()
minEForMultiFrag = param->GetMinExPerNucleounForMF();
minExcitation = param->GetMinExcitation();
maxExcitation = param->GetPrecoHighEnergy();
icID = G4PhysicsModelCatalog::GetModelID("model_e-InternalConversion");
// allowing local debug printout
fVerbose = std::max(fVerbose, param->GetVerbose());
@@ -506,7 +505,7 @@ G4ExcitationHandler::BreakItUp(const G4Fragment & theInitialState)
// in memory for the vector
theReactionProductVector->reserve( theResults.size() );
if (fVerbose > 2) {
if (fVerbose > 1) {
G4cout << "### ExcitationHandler provides " << theResults.size()
<< " evaporated products:" << G4endl;
}
@@ -587,6 +586,7 @@ G4ExcitationHandler::BreakItUp(const G4Fragment & theInitialState)
G4cout << "### EXCH: Find ion Z= " << fragmentZ
<< " A= " << fragmentA
<< " Eexc(MeV)= " << eexc/MeV << " idx= " << idxf
<< " " << theKindOfFragment->GetParticleName()
<< G4endl;
}
}
@@ -608,11 +608,7 @@ G4ExcitationHandler::BreakItUp(const G4Fragment & theInitialState)
}
theNew->SetTotalEnergy(etot);
theNew->SetFormationTime(frag->GetCreationTime());
if (theKindOfFragment == theElectron) {
theNew->SetCreatorModelID(icID);
} else {
theNew->SetCreatorModelID(frag->GetCreatorModelID());
}
theNew->SetCreatorModelID(frag->GetCreatorModelID());
theReactionProductVector->push_back(theNew);
// fragment not found out ground state is created
@@ -86,6 +86,8 @@ public:
inline G4double GetMinExcitation() const;
inline G4double GetNuclearLevelWidth() const;
inline G4double GetMaxLifeTime() const;
inline G4double GetMinExPerNucleounForMF() const;
@@ -150,6 +152,8 @@ public:
void SetMinExcitation(G4double);
void SetNuclearLevelWidth(G4double);
void SetMaxLifeTime(G4double);
void SetMinExPerNucleounForMF(G4double);
@@ -234,47 +238,48 @@ private:
G4double fPrecoHighEnergy;
// Preco phenomenological factor
G4double fPhenoFactor = 1.0;
G4double fPhenoFactor;
// Excitation handler
G4double fMinExcitation;
G4double fNuclearLevelWidth;
G4double fMaxLifeTime;
// Multi-fragmentation model
G4double fMinExPerNucleounForMF;
// Cross section type
G4int fPrecoType = 3;
G4int fDeexType = 3;
G4int fPrecoType;
G4int fDeexType;
G4int fTwoJMAX = 10;
G4int fTwoJMAX;
// Preco model
G4int fMinZForPreco = 3;
G4int fMinAForPreco = 5;
G4int fMinZForPreco;
G4int fMinAForPreco;
G4int fVerbose = 1;
G4int fVerbose;
// Preco flags
G4bool fNeverGoBack = false;
G4bool fUseSoftCutoff = false;
G4bool fUseCEM = true;
G4bool fUseGNASH = false;
G4bool fUseHETC = false;
G4bool fUseAngularGen = true;
G4bool fPrecoDummy = false;
G4bool fNeverGoBack;
G4bool fUseSoftCutoff;
G4bool fUseCEM;
G4bool fUseGNASH;
G4bool fUseHETC;
G4bool fUseAngularGen;
G4bool fPrecoDummy;
// Deex flags
G4bool fCorrelatedGamma = false;
G4bool fStoreAllLevels = false;
G4bool fInternalConversion = true;
G4bool fLD = true; // use simple level density model
G4bool fFD = true; // use transition to discrete level
G4bool fIsomerFlag = true; // enable isomere production
G4bool fIsPrinted = false;
G4bool fCorrelatedGamma;
G4bool fStoreAllLevels;
G4bool fInternalConversion;
G4bool fLD;
G4bool fFD;
G4bool fIsomerFlag;
G4bool fIsPrinted{false};
// type of a set of e-exitation channels
G4DeexChannelType fDeexChannelType = fCombined;
// type of a set of de-exitation channels
G4DeexChannelType fDeexChannelType;
};
inline G4double G4DeexPrecoParameters::GetLevelDensity() const
@@ -322,6 +327,11 @@ inline G4double G4DeexPrecoParameters::GetMinExcitation() const
return fMinExcitation;
}
inline G4double G4DeexPrecoParameters::GetNuclearLevelWidth() const
{
return fNuclearLevelWidth;
}
inline G4double G4DeexPrecoParameters::GetMaxLifeTime() const
{
return fMaxLifeTime;
@@ -112,6 +112,7 @@ protected:
G4double pResMass = 0.0;
G4double pProbability = 0.0;
G4double pTolerance = 0.0;
G4double pWidth = 0.0;
private:
@@ -58,16 +58,47 @@ void G4DeexPrecoParameters::SetDefaults()
void G4DeexPrecoParameters::Initialise()
{
// common parameters
fVerbose = 1;
fLevelDensity = 0.075/CLHEP::MeV;
fR0 = 1.5*CLHEP::fermi;
fTransitionsR0 = 0.6*CLHEP::fermi;
fFBUEnergyLimit = 20.0*CLHEP::MeV;
fFermiEnergy = 35.0*CLHEP::MeV;
// preco parameters
fPrecoLowEnergy = 0.1*CLHEP::MeV;
fPrecoHighEnergy = 30*CLHEP::MeV;
fPhenoFactor = 1.0;
fPrecoType = 3;
fMinZForPreco = 3;
fMinAForPreco = 5;
fNeverGoBack = false;
fUseSoftCutoff = false;
fUseCEM = true;
fUseGNASH = false;
fUseHETC = false;
fUseAngularGen = true;
fPrecoDummy = false;
// de-exitation parameters
fMinExcitation = 10*CLHEP::eV;
fNuclearLevelWidth = 0.2*CLHEP::MeV;
fFBUEnergyLimit = 20.0*CLHEP::MeV;
fFermiEnergy = 35.0*CLHEP::MeV;
fMaxLifeTime = 1*CLHEP::nanosecond;
fMinExPerNucleounForMF = 200*CLHEP::GeV;
fDeexChannelType = fCombined;
fDeexType = 3;
fTwoJMAX = 10;
fCorrelatedGamma = false;
fStoreAllLevels = false;
fInternalConversion = true;
fLD = true; // use simple level density model
fFD = false; // use transition to discrete level
fIsomerFlag = true; // enable isomere production
}
void G4DeexPrecoParameters::SetLevelDensity(G4double val)
@@ -124,6 +155,12 @@ void G4DeexPrecoParameters::SetMinExcitation(G4double val)
fMinExcitation = val;
}
void G4DeexPrecoParameters::SetNuclearLevelWidth(G4double val)
{
if(IsLocked() || val < 0.0) { return; }
fNuclearLevelWidth = val;
}
void G4DeexPrecoParameters::SetMaxLifeTime(G4double val)
{
if(IsLocked() || val < 0.0) { return; }
@@ -620,30 +620,24 @@ G4ShellCorrection* G4NuclearLevelData::GetShellCorrection()
G4double G4NuclearLevelData::GetLevelDensity(G4int Z, G4int A, G4double U)
{
if(fDeexPrecoParameters->GetLevelDensityFlag()) {
if (fDeexPrecoParameters->GetLevelDensityFlag()) {
return A*fDeexPrecoParameters->GetLevelDensity();
}
const G4LevelManager* man = GetLevelManager(Z, A);
return (man) ? man->LevelDensity(U)
return (nullptr != man) ? man->LevelDensity(U)
: 0.058025*A*(1.0 + 5.9059/fG4calc->Z13(A));
}
G4double G4NuclearLevelData::GetPairingCorrection(G4int Z, G4int A)
{
if(fDeexPrecoParameters->GetLevelDensityFlag()) {
return fPairingCorrection->GetPairingCorrection(A, Z);
}
G4int N = A - Z;
const G4double par = 12.*CLHEP::MeV;
G4double x = (A <= 36) ? 6.0 : std::sqrt((G4double)A);
return (2 - Z + (Z/2)*2 - N + (N/2)*2)*par/x;
return fPairingCorrection->GetPairingCorrection(A, Z);
}
void G4NuclearLevelData::StreamLevels(std::ostream& os,
G4int Z, G4int A)
{
const G4LevelManager* man = GetLevelManager(Z, A);
if(man) {
if (man) {
os << "Level data for Z= " << Z << " A= " << A << " "
<< man->NumberOfTransitions() + 1 << " levels \n";
man->StreamInfo(os);
@@ -53,6 +53,7 @@ void G4VEmissionProbability::Initialise()
pVerbose = param->GetVerbose();
fFD = param->GetDiscreteExcitationFlag();
pTolerance = param->GetMinExcitation();
pWidth = param->GetNuclearLevelWidth();
}
void G4VEmissionProbability::ResetIntegrator(size_t, G4double de, G4double eps)
@@ -185,7 +186,7 @@ G4double G4VEmissionProbability::SampleEnergy()
CLHEP::HepRandomEngine* rndm = G4Random::getTheEngine();
const G4int nmax = 1000;
G4double ekin, g, gmax;
G4double ekin, gg, gmax;
G4int n = 0;
do {
++n;
@@ -201,22 +202,22 @@ G4double G4VEmissionProbability::SampleEnergy()
gmax = probmax*((x > alim) ? G4Exp(-x) : 1.0 - x*(1.0 - 0.5*x));
}
}
g = ComputeProbability(ekin, eCoulomb);
gg = ComputeProbability(ekin, eCoulomb);
if(pVerbose > 2) {
G4cout << " " << n
<< ". prob= " << g << " probmax= " << probmax
<< ". prob= " << gg << " probmax= " << probmax
<< " Ekin= " << ekin << G4endl;
}
if((g > gmax || n > nmax) && pVerbose > 1) {
if((gg > gmax || n > nmax) && pVerbose > 1) {
G4cout << "### G4VEmissionProbability::SampleEnergy for Z= " << theZ
<< " A= " << theA << " Eex(MeV)=" << fExc << " p1=" << p1
<< "\n Warning n= " << n
<< " prob/gmax=" << g/gmax
<< " prob=" << g << " gmax=" << gmax << " probmax=" << probmax
<< " prob/gmax=" << gg/gmax
<< " prob=" << gg << " gmax=" << gmax << " probmax=" << probmax
<< "\n Ekin= " << ekin << " Emin= " << emin
<< " Emax= " << emax << G4endl;
}
} while(gmax*rndm->flat() > g && n < nmax);
} while(gmax*rndm->flat() > gg && n < nmax);
G4double enew = FindRecoilExcitation(ekin);
if(pVerbose > 1) {
G4cout << "### SampleEnergy: Efinal= "
@@ -258,15 +259,21 @@ G4double G4VEmissionProbability::FindRecoilExcitation(const G4double e)
if(fExcRes > lManager->MaxLevelEnergy() + pTolerance) { return e; }
// find level
G4double elevel = lManager->NearestLevelEnergy(fExcRes);
std::size_t idx = lManager->NearestLevelIndex(fExcRes);
auto level = lManager->GetLevel(idx);
// excited level
if(pMass > mass + pResMass + elevel &&
std::abs(elevel - fExcRes) <= pTolerance) {
G4double massR = pResMass + elevel;
G4double mr2 = massR*massR;
fExcRes = elevel;
return std::max(0.5*(m02 + m12 - mr2)/pMass - mass, 0.0);
// unstable level
if (level->GetTimeGamma() == 0.0) { return e; }
// is possible to use level energy?
G4double elevel = lManager->LevelEnergy(idx);
if (std::abs(elevel - fExcRes) > pWidth || pMass < mass + pResMass + elevel) {
return e;
}
return e;
// long-lived level
G4double massR = pResMass + elevel;
G4double mr2 = massR*massR;
fExcRes = elevel;
return std::max(0.5*(m02 + m12 - mr2)/pMass - mass, 0.0);
}
@@ -52,27 +52,25 @@ class G4NeutronRadCapture : public G4HadronicInteraction
{
public:
explicit G4NeutronRadCapture();
G4NeutronRadCapture();
virtual ~G4NeutronRadCapture();
~G4NeutronRadCapture() override;
virtual G4HadFinalState* ApplyYourself(const G4HadProjectile & aTrack,
G4Nucleus & targetNucleus) final;
G4HadFinalState* ApplyYourself(const G4HadProjectile & aTrack,
G4Nucleus & targetNucleus) override;
virtual void InitialiseModel() final;
private:
void InitialiseModel() override;
G4NeutronRadCapture & operator=(const G4NeutronRadCapture &right) = delete;
G4NeutronRadCapture(const G4NeutronRadCapture&) = delete;
G4int icID; // creator model ID for electrons produced by internal conversion
G4int secID; // creator model ID for the other secondaries produced by this model
const G4ParticleDefinition* electron;
private:
G4int secID; // creator model ID for secondaries produced by this model
G4double lowestEnergyLimit;
G4double minExcitation;
G4VEvaporationChannel* photonEvaporation;
G4IonTable* theTableOfIons;
G4IonTable* theTableOfIons;
G4LorentzVector lab4mom;
};
@@ -59,11 +59,6 @@ G4NeutronRadCapture::G4NeutronRadCapture()
{
lowestEnergyLimit = 10*CLHEP::eV;
minExcitation = 0.1*CLHEP::keV;
SetMinEnergy( 0.0*CLHEP::GeV );
SetMaxEnergy( G4HadronicParameters::Instance()->GetMaxEnergy() );
electron = G4Electron::Electron();
icID = -1;
secID = -1;
theTableOfIons = G4ParticleTable::GetParticleTable()->GetIonTable();
}
@@ -79,7 +74,6 @@ void G4NeutronRadCapture::InitialiseModel()
G4DeexPrecoParameters* param =
G4NuclearLevelData::GetInstance()->GetParameters();
minExcitation = param->GetMinExcitation();
icID = G4PhysicsModelCatalog::GetModelID("model_e-InternalConversion");
secID = G4PhysicsModelCatalog::GetModelID("model_" + GetModelName());
photonEvaporation = new G4PhotonEvaporation();
photonEvaporation->Initialise();
@@ -101,7 +95,7 @@ G4HadFinalState* G4NeutronRadCapture::ApplyYourself(
lab4mom.set(0.,0.,0.,G4NucleiProperties::GetNuclearMass(A, Z));
lab4mom += aTrack.Get4Momentum();
G4double M = lab4mom.mag();
G4double M = lab4mom.mag();
++A;
G4double mass = G4NucleiProperties::GetNuclearMass(A, Z);
//G4cout << "Capture start: Z= " << Z << " A= " << A
@@ -176,14 +170,14 @@ G4HadFinalState* G4NeutronRadCapture::ApplyYourself(
// Sample final state
//
G4FragmentVector* fv = photonEvaporation->BreakUpFragment(aFragment);
if(!fv) { fv = new G4FragmentVector(); }
if (nullptr == fv) { fv = new G4FragmentVector(); }
fv->push_back(aFragment);
size_t n = fv->size();
std::size_t n = fv->size();
if (verboseLevel > 1) {
G4cout << "G4NeutronRadCapture: " << n << " final particle icID= " << icID << G4endl;
G4cout << "G4NeutronRadCapture: " << n << " final particles" << G4endl;
}
for(size_t i=0; i<n; ++i) {
for(std::size_t i=0; i<n; ++i) {
G4Fragment* f = (*fv)[i];
G4double etot = f->GetMomentum().e();
@@ -221,11 +215,7 @@ G4HadFinalState* G4NeutronRadCapture::ApplyYourself(
G4double timeF = f->GetCreationTime();
if(timeF < 0.0) { timeF = 0.0; }
news->SetTime(time + timeF);
if(theDef == electron) {
news->SetCreatorModelID(icID);
} else {
news->SetCreatorModelID(secID);
}
news->SetCreatorModelID(secID);
theParticleChange.AddSecondary(*news);
delete news;
delete f;
@@ -396,7 +396,7 @@ G4PhotonEvaporation::GenerateGamma(G4Fragment* nucleus)
ntrans = level->NumberOfTransitions();
}
}
JP1 = fLevelManager->TwoSpinParity(fIndex);
JP1 = std::abs(fLevelManager->TwoSpinParity(fIndex));
}
}
// if a level has no defined transitions
@@ -500,7 +500,7 @@ G4PhotonEvaporation::GenerateGamma(G4Fragment* nucleus)
}
if(fVerbose > 2) {
G4cout << "Ntrans= " << ntrans << " idx= " << idx
<< " ICM= " << fICM << " JP1= " << JP1 << G4endl;
<< " ICM= " << fICM << " abs(JP1)= " << JP1 << G4endl;
}
G4double prob = level->GammaProbability(idx);
// prob = 0 means that there is only internal conversion
@@ -518,7 +518,7 @@ G4PhotonEvaporation::GenerateGamma(G4Fragment* nucleus)
ratio = level->MultipolarityRatio(idx);
multiP = level->TransitionType(idx);
fIndex = level->FinalExcitationIndex(idx);
JP2 = fLevelManager->TwoSpinParity(fIndex);
JP2 = std::abs(fLevelManager->TwoSpinParity(fIndex));
// final energy and time
efinal = fLevelManager->LevelEnergy(fIndex);
@@ -561,7 +561,7 @@ G4PhotonEvaporation::GenerateGamma(G4Fragment* nucleus)
<< " idxFinal= " << fIndex << " isDiscrete: " << isDiscrete
<< " isGamma: " << isGamma << " multiP= " << multiP
<< " shell= " << vShellNumber
<< " JP1= " << JP1 << " JP2= " << JP2 << G4endl;
<< " abs(JP1)= " << JP1 << " abs(JP2)= " << JP2 << G4endl;
}
return result;
}
@@ -40,25 +40,31 @@ class G4CameronGilbertPairingCorrections
{
public:
explicit G4CameronGilbertPairingCorrections();
G4CameronGilbertPairingCorrections();
inline G4bool GetPairingCorrection(G4int N, G4int Z, G4double& result) const
~G4CameronGilbertPairingCorrections() = default;
G4bool GetPairingCorrection(G4int N, G4int Z, G4double& result) const
{
G4bool res = false;
if(Z >= ZTableMin && Z <= ZTableMax && N >= NTableMin && N <= NTableMax) {
result = PairingZTable[Z-ZTableMin] + PairingNTable[N-NTableMin];
if (Z >= TableMin && Z <= ZTableMax && N >= TableMin && N <= NTableMax) {
result = PairingZTable[Z - TableMin] + PairingNTable[N - TableMin];
res = true;
}
return res;
}
enum { ZTableSize = 88, NTableSize = 140, ZTableMin = 11, ZTableMax = 98,
NTableMin = 11, NTableMax = 150 };
G4CameronGilbertPairingCorrections(const G4CameronGilbertPairingCorrections& right) = delete;
const G4CameronGilbertPairingCorrections& operator=
(const G4CameronGilbertPairingCorrections& right) = delete;
private:
G4CameronGilbertPairingCorrections(const G4CameronGilbertPairingCorrections & right) = delete;
const G4CameronGilbertPairingCorrections & operator=(const G4CameronGilbertPairingCorrections & right) = delete;
const G4int TableMin{11};
const G4int ZTableMax{98};
const G4int NTableMax{150};
static const G4int ZTableSize{88};
static const G4int NTableSize{140};
static G4double PairingZTable[ZTableSize];
static G4double PairingNTable[NTableSize];
@@ -43,18 +43,15 @@ public:
~G4CameronGilbertShellCorrections() = default;
inline G4bool GetShellCorrection(G4int N, G4int Z, G4double& result) const
G4bool GetShellCorrection(G4int N, G4int Z, G4double& result) const
{
G4bool res = false;
if(Z >= ZTableMin && Z <= ZTableMax && N >= NTableMin && N <= NTableMax) {
result = ShellZTable[Z-ZTableMin] + ShellNTable[N-NTableMin];
if (Z >= TableMin && Z <= ZTableMax && N >= TableMin && N <= NTableMax) {
result = ShellZTable[Z - TableMin] + ShellNTable[N - TableMin];
res = true;
}
return res;
}
enum { ZTableSize = 88, NTableSize = 140, ZTableMin = 11, ZTableMax = 98,
NTableMin = 11, NTableMax = 150 };
G4CameronGilbertShellCorrections(const G4CameronGilbertShellCorrections & right) = delete;
const G4CameronGilbertShellCorrections & operator=
@@ -62,6 +59,13 @@ public:
private:
const G4int TableMin{11};
const G4int ZTableMax{98};
const G4int NTableMax{150};
static const G4int ZTableSize{88};
static const G4int NTableSize{140};
static G4double ShellZTable[ZTableSize];
static G4double ShellNTable[NTableSize];
@@ -32,7 +32,6 @@
#ifndef G4CoulombBarrier_h
#define G4CoulombBarrier_h 1
#include "globals.hh"
#include "G4VCoulombBarrier.hh"
class G4CoulombBarrier : public G4VCoulombBarrier
@@ -36,14 +36,12 @@
#include "globals.hh"
#include "G4CameronGilbertPairingCorrections.hh"
#include "G4CameronGilbertShellCorrections.hh"
#include "G4CameronShellPlusPairingCorrections.hh"
class G4PairingCorrection
{
public:
explicit G4PairingCorrection();
G4PairingCorrection();
~G4PairingCorrection() = default;
@@ -58,8 +56,6 @@ public:
private:
G4CameronGilbertPairingCorrections theCameronGilbertPairingCorrections;
G4CameronGilbertShellCorrections theCameronGilbertShellCorrections;
G4CameronShellPlusPairingCorrections theCorr;
};
#endif
@@ -33,8 +33,6 @@
#include "globals.hh"
class G4Pow;
class G4VCoulombBarrier
{
public:
@@ -54,14 +52,11 @@ public:
protected:
G4Pow* g4calc;
G4int theA;
G4int theZ;
G4double theR0;
G4double theRho = 0.0;
G4double factor = 0.0;
G4double theRho{0.0};
G4double factor{0.0};
};
#endif
@@ -70,8 +70,8 @@ G4double G4CameronGilbertPairingCorrections::PairingNTable[] =
G4CameronGilbertPairingCorrections::G4CameronGilbertPairingCorrections()
{
for(size_t i=0; i<ZTableSize; ++i) { PairingZTable[i] *= CLHEP::MeV; }
for(size_t i=0; i<NTableSize; ++i) { PairingNTable[i] *= CLHEP::MeV; }
for (G4int i=0; i<ZTableSize; ++i) { PairingZTable[i] *= CLHEP::MeV; }
for (G4int i=0; i<NTableSize; ++i) { PairingNTable[i] *= CLHEP::MeV; }
}
@@ -70,8 +70,8 @@ G4double G4CameronGilbertShellCorrections::ShellNTable[] =
G4CameronGilbertShellCorrections::G4CameronGilbertShellCorrections()
{
for(size_t i=0; i<ZTableSize; ++i) { ShellZTable[i] *= CLHEP::MeV; }
for(size_t i=0; i<NTableSize; ++i) { ShellNTable[i] *= CLHEP::MeV; }
for (G4int i=0; i<ZTableSize; ++i) { ShellZTable[i] *= CLHEP::MeV; }
for (G4int i=0; i<NTableSize; ++i) { ShellNTable[i] *= CLHEP::MeV; }
}
@@ -39,15 +39,15 @@ G4CoulombBarrier::G4CoulombBarrier(G4int A, G4int Z)
: G4VCoulombBarrier(A, Z)
{
factor = CLHEP::elm_coupling*Z;
SetParameters(0.4*G4NuclearRadii::RadiusCB(Z, A), 1.5*CLHEP::fermi);
SetParameters(0.6*G4NuclearRadii::RadiusCB(Z, A), 1.5*CLHEP::fermi);
}
G4double G4CoulombBarrier::GetCoulombBarrier(
G4int ARes, G4int ZRes, G4double U) const
{
if(0 == theZ) { return 0.0; }
if (0 == theZ) { return 0.0; }
G4double cb = factor*ZRes/(G4NuclearRadii::RadiusCB(ZRes,ARes) + theRho);
if(U > 0.0) { cb /= (1.0 + std::sqrt( U/((2*ARes)*CLHEP::MeV) )); }
if (U > 0.0) { cb /= (1.0 + std::sqrt( U/((2*(ARes + theA))*CLHEP::MeV) )); }
return cb;
}
@@ -33,7 +33,10 @@
#include "G4PairingCorrection.hh"
#include "G4SystemOfUnits.hh"
const G4double PairingConstant = 12.0*CLHEP::MeV;
namespace
{
const G4double PairingConstant = 12.0*CLHEP::MeV;
}
G4PairingCorrection::G4PairingCorrection()
{}
@@ -43,20 +46,18 @@ G4double G4PairingCorrection::GetPairingCorrection(G4int A, G4int Z) const
G4double pairCorr = 0.0;
G4int N = A - Z;
if(!theCameronGilbertPairingCorrections.GetPairingCorrection(N,Z,pairCorr)) {
pairCorr = ((1 - Z + 2*(Z/2)) + (1 - N + 2*(N/2)))
if (!theCameronGilbertPairingCorrections.GetPairingCorrection(N, Z, pairCorr) ) {
pairCorr = (2 - A + 2*(Z/2) + 2*(N/2))
*PairingConstant/std::sqrt(static_cast<G4double>(A));
}
//theCorr.GetPairingCorrection(N,Z,pairCorr);
return std::max(pairCorr, 0.0);
return pairCorr;
}
G4double
G4PairingCorrection::GetFissionPairingCorrection(G4int A, G4int Z) const
{
G4int N = A - Z;
G4double pairCorr = ((1 - Z + 2*(Z/2)) + (1 - N + 2*(N/2)))
G4double pairCorr = (2 - A + 2*(Z/2) + 2*(N/2))
*PairingConstant/std::sqrt(static_cast<G4double>(A));
return pairCorr;
}
@@ -29,20 +29,16 @@
#include "G4VCoulombBarrier.hh"
#include "G4PhysicalConstants.hh"
#include "G4Pow.hh"
G4VCoulombBarrier::G4VCoulombBarrier(G4int anA, G4int aZ)
: g4calc(G4Pow::GetInstance())
{
theA = anA;
theZ = aZ;
theR0 = 1.5*CLHEP::fermi;
}
void G4VCoulombBarrier::SetParameters(G4double rho, G4double r0)
void G4VCoulombBarrier::SetParameters(G4double rho, G4double)
{
theRho = rho;
theR0 = r0;
}
G4double G4VCoulombBarrier::BarrierPenetrationFactor(G4int) const
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-02-12 Gabriele Cosmo (hadr-fission-V11-02-00)
- G4FissLib: fixed compilation warning on gcc when LTO settings are enabled.
## 2022-11-26 Gabriele Cosmo (hadr-fission-V11-00-03)
- Fixed compilation warnings for implicit type conversions on macOS/XCode 14.1.
@@ -146,7 +146,7 @@ class G4FissLib : public G4HadronicInteraction
G4double* xSec;
G4ParticleHPChannel* theFission;
G4String dirName;
G4int numEle;
std::size_t numEle;
};
#endif
@@ -73,12 +73,11 @@ G4FissLib::G4FissLib()
dirName = G4FindDataDir("G4NEUTRONHPDATA");
G4String tString = "/Fission/";
dirName = dirName + tString;
numEle = (G4int)G4Element::GetNumberOfElements();
numEle = G4Element::GetNumberOfElements();
theFission = new G4ParticleHPChannel[numEle];
for (G4int i=0; i<numEle; ++i)
for (std::size_t i=0; i<numEle; ++i)
{
// G4cout << "G4FissLib::G4FissLib(): element "<< i << " : " << (*(G4Element::GetElementTable()))[i]->GetZ()<< G4endl;
if((*(G4Element::GetElementTable()))[i]->GetZ()>89)
{
theFission[i].Init((*(G4Element::GetElementTable()))[i], dirName);
@@ -6,7 +6,7 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-04-12 Jean-Christophe David (hadr-inclxx-V11-01-05)
## 2024-04-12 Jean-Christophe David (hadr-inclxx-V11-02-00)
- Fix in G4INCLInteractionAvatar to not use local energy for all antibaryons.
## 2023-12-01 Ben Morgan (hadr-inclxx-V11-01-04)
@@ -6,21 +6,21 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-05-02 Gabriele Cosmo (hadr-lend-V11-01-04)
## 2024-05-02 Gabriele Cosmo (hadr-lend-V11-02-03)
- Fixed compilation warnings for potentially initialised local variables in
ptwXY_createFromFunctionZeroCrossing().
## 2024-04-24 Pere Mato
## 2024-04-24 Pere Mato (hadr-lend-V11-02-02)
- Math macros such as M_PI are not standard. To define them the macro
_USE_MATH_DEFINES needs to be defined before including <cmath>.
- macro WIN32 is not standard, the correect macro is _WIN32.
- <BaseTsd.h> should be <basetsd.h> for MinGW.
## 2024-01-29 Vladimir Ivanchenko (hadr-lend-V11-01-03)
## 2024-01-29 Vladimir Ivanchenko (hadr-lend-V11-02-01)
- MCGIDI_product, MCGIDI_outputChannel, MCGIDI_distribution - fixed alma9-gcc131
compilation warnings seen in CMSSW
compilation warnings seen in CMSSW.
## 2023-12-18 Gabriele Cosmo
## 2023-12-18 Gabriele Cosmo (hadr-lend-V11-02-00)
- Fixed compilation error on latest Windows VC++ compiler 17.8.3 for use of
std::isfinite() in nf_specialFunctions_h and in nf_floatToShortestString().
Addressing problem report #2582.
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-02-01 Vladimir Ivanchenko (hadr-lepnuc-V11-02-00)
- Fixed Coverity warning on unused variable in neutrino models
## 2023-09-04 Vladimir Ivanchenko (hadr-lepnuc-V11-01-00)
- G4ElectroVDNuclearModel : updated initialisation of data tables
@@ -425,15 +425,13 @@ G4HadFinalState* G4ANuElNucleusCcModel::ApplyYourself(
}
*/
G4Nucleus recoil;
G4double rM(0.), ratio = G4double(Z)/G4double(A);
G4double ratio = G4double(Z)/G4double(A);
if( ratio > G4UniformRand() ) // proton is excited
{
fProton = true;
recoil = G4Nucleus(A-1,Z-1);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z-1);
if( pName == "anti_nu_e" ) // (++) state -> p + pi+
{
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2212)->GetPDGMass()
@@ -450,8 +448,6 @@ G4HadFinalState* G4ANuElNucleusCcModel::ApplyYourself(
fProton = false;
recoil = G4Nucleus(A-1,Z);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z);
if( pName == "anti_nu_e" ) // (+) state -> n + pi+
{
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2112)->GetPDGMass()
@@ -479,6 +475,7 @@ G4HadFinalState* G4ANuElNucleusCcModel::ApplyYourself(
{
fString = false;
G4double rM;
if( fProton )
{
fPDGencoding = 2212;
@@ -383,15 +383,13 @@ G4HadFinalState* G4ANuElNucleusNcModel::ApplyYourself(
return &theParticleChange;
}
G4Nucleus recoil;
G4double rM(0.), ratio = G4double(Z)/G4double(A);
G4double ratio = G4double(Z)/G4double(A);
if( ratio > G4UniformRand() ) // proton is excited
{
fProton = true;
recoil = G4Nucleus(A-1,Z-1);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z-1);
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2212)->GetPDGMass()
+ G4ParticleTable::GetParticleTable()->FindParticle(111)->GetPDGMass();
}
@@ -400,8 +398,6 @@ G4HadFinalState* G4ANuElNucleusNcModel::ApplyYourself(
fProton = false;
recoil = G4Nucleus(A-1,Z);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z);
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2112)->GetPDGMass()
+ G4ParticleTable::GetParticleTable()->FindParticle(111)->GetPDGMass();
}
@@ -419,6 +415,7 @@ G4HadFinalState* G4ANuElNucleusNcModel::ApplyYourself(
{
fString = false;
G4double rM;
if( fProton )
{
fPDGencoding = 2212;
@@ -422,15 +422,13 @@ G4HadFinalState* G4ANuMuNucleusCcModel::ApplyYourself(
}
*/
G4Nucleus recoil;
G4double rM(0.), ratio = G4double(Z)/G4double(A);
G4double ratio = G4double(Z)/G4double(A);
if( ratio > G4UniformRand() ) // proton is excited
{
fProton = true;
recoil = G4Nucleus(A-1,Z-1);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z-1);
if( pName == "anti_nu_mu" ) // (0) state -> p + pi-
{
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2212)->GetPDGMass()
@@ -447,8 +445,6 @@ G4HadFinalState* G4ANuMuNucleusCcModel::ApplyYourself(
fProton = false;
recoil = G4Nucleus(A-1,Z);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z);
if( pName == "anti_nu_mu" ) // (+) state -> n + pi+
{
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2112)->GetPDGMass()
@@ -476,6 +472,7 @@ G4HadFinalState* G4ANuMuNucleusCcModel::ApplyYourself(
{
fString = false;
G4double rM;
if( fProton )
{
fPDGencoding = 2212;
@@ -383,15 +383,13 @@ G4HadFinalState* G4ANuMuNucleusNcModel::ApplyYourself(
return &theParticleChange;
}
G4Nucleus recoil;
G4double rM(0.), ratio = G4double(Z)/G4double(A);
G4double ratio = G4double(Z)/G4double(A);
if( ratio > G4UniformRand() ) // proton is excited
{
fProton = true;
recoil = G4Nucleus(A-1,Z-1);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z-1);
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2212)->GetPDGMass()
+ G4ParticleTable::GetParticleTable()->FindParticle(111)->GetPDGMass();
}
@@ -400,8 +398,6 @@ G4HadFinalState* G4ANuMuNucleusNcModel::ApplyYourself(
fProton = false;
recoil = G4Nucleus(A-1,Z);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z);
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2112)->GetPDGMass()
+ G4ParticleTable::GetParticleTable()->FindParticle(111)->GetPDGMass();
}
@@ -419,6 +415,7 @@ G4HadFinalState* G4ANuMuNucleusNcModel::ApplyYourself(
{
fString = false;
G4double rM;
if( fProton )
{
fPDGencoding = 2212;
@@ -428,15 +428,13 @@ G4HadFinalState* G4NuTauNucleusCcModel::ApplyYourself(
}
*/
G4Nucleus recoil;
G4double rM(0.), ratio = G4double(Z)/G4double(A);
G4double ratio = G4double(Z)/G4double(A);
if( ratio > G4UniformRand() ) // proton is excited
{
fProton = true;
recoil = G4Nucleus(A-1,Z-1);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z-1);
if( pName == "nu_tau" ) // (++) state -> p + pi+
{
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2212)->GetPDGMass()
@@ -453,8 +451,6 @@ G4HadFinalState* G4NuTauNucleusCcModel::ApplyYourself(
fProton = false;
recoil = G4Nucleus(A-1,Z);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z);
if( pName == "nu_tau" ) // (+) state -> n + pi+
{
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2112)->GetPDGMass()
@@ -482,6 +478,7 @@ G4HadFinalState* G4NuTauNucleusCcModel::ApplyYourself(
{
fString = false;
G4double rM;
if( fProton )
{
fPDGencoding = 2212;
@@ -383,15 +383,13 @@ G4HadFinalState* G4NuTauNucleusNcModel::ApplyYourself(
return &theParticleChange;
}
G4Nucleus recoil;
G4double rM(0.), ratio = G4double(Z)/G4double(A);
G4double ratio = G4double(Z)/G4double(A);
if( ratio > G4UniformRand() ) // proton is excited
{
fProton = true;
recoil = G4Nucleus(A-1,Z-1);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z-1);
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2212)->GetPDGMass()
+ G4ParticleTable::GetParticleTable()->FindParticle(111)->GetPDGMass();
}
@@ -400,8 +398,6 @@ G4HadFinalState* G4NuTauNucleusNcModel::ApplyYourself(
fProton = false;
recoil = G4Nucleus(A-1,Z);
fRecoil = &recoil;
rM = recoil.AtomicMass(A-1,Z);
fMt = G4ParticleTable::GetParticleTable()->FindParticle(2112)->GetPDGMass()
+ G4ParticleTable::GetParticleTable()->FindParticle(111)->GetPDGMass();
}
@@ -419,6 +415,7 @@ G4HadFinalState* G4NuTauNucleusNcModel::ApplyYourself(
{
fString = false;
G4double rM;
if( fProton )
{
fPDGencoding = 2212;
@@ -0,0 +1,21 @@
# Category hadr-nudex History
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
which **must** added in reverse chronological order (newest at the top).
It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-06-23 vladimir Ivantchenko (hadr-nudex-V11-02-03)
- G4NuDEXNeutronCaptureModel : fixed access to the data
## 2024-06-07 Emilio Mendoza (hadr-nudex-V11-02-02)
- G4NuDEXNeutronCaptureModel : few corrections.
## 2024-06-04 Gabriele Cosmo (hadr-nudex-V11-02-01)
- Fixed compilation warnings on macOS/XCode for implicit type conversion.
- Attempt fix for compilation warning on G4NuDEXStatisticalNucleus source
on alma9 with LTO settings.
## 2024-05-29 Emilio Mendoza (hadr-nudex-V11-02-00)
- First version of NuDEX in Geant4.
@@ -0,0 +1,105 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 header file
//
// File name: G4NuDEXNeutronCaptureModel
//
// Author: E.Mendoza & A.Ribon
//
// Creation date: 29 May 2024
//
// Description: This class (a proxy of the class G4NuDEX) uses
// the NuDEX model to produce gammas and internal
// conversion electrons from neutron capture.
// Whenever NuDEX is not applicable, G4PhotonEvaporation
// is used.
// The implementation of this class follows the code
// of the class G4NeutronRadCapture.
//
// Modifications:
//
// -------------------------------------------------------------------
//
// Class to use NuDEX model inside Geant4
//
#ifndef G4NUDEXNEUTRONCAPTUREMODEL_HH
#define G4NUDEXNEUTRONCAPTUREMODEL_HH 1
#include "globals.hh"
#include "G4HadronicInteraction.hh"
#include "G4HadProjectile.hh"
#include "G4Nucleus.hh"
class G4NuDEXStatisticalNucleus;
class G4VEvaporationChannel;
#define G4NUDEX_MAXZA 120000
class G4NuDEXNeutronCaptureModel : public G4HadronicInteraction {
public:
explicit G4NuDEXNeutronCaptureModel();
virtual ~G4NuDEXNeutronCaptureModel();
virtual G4HadFinalState* ApplyYourself( const G4HadProjectile &aTrack, G4Nucleus &targetNucleus ) final;
virtual void InitialiseModel() final;
private:
G4NuDEXNeutronCaptureModel & operator=( const G4NuDEXNeutronCaptureModel &right ) = delete;
G4NuDEXNeutronCaptureModel( const G4NuDEXNeutronCaptureModel& ) = delete;
G4int GenerateNeutronCaptureCascade( G4int theZ, G4int theA, G4double NeutronEnergy, G4int InitialLevel,
std::vector< char >& pType, std::vector< G4double >& pEnergy, std::vector< G4double >& pTime );
// Initial level for neutron capture. If jspinx2v < 0 it is sampled according to the 2J+1 rule
// l-spin = 0, 1, 2 --> s-wave, p-wave, d-wave ...
G4int SelectInitialLevel( G4int theCompoundZ, G4int theCompoundA, G4double NeutronEnergy, G4int lspin, G4int jspinx2 );
G4int SampleJ( G4int theCompoundZ, G4int theCompoundA, G4int lspin );
G4int GetAllowedJx2values( G4int theCompoundZ, G4int theCompoundA, G4int lspin, G4int* jx2vals );
const G4NuDEXStatisticalNucleus* GetStatisticalNucleus( G4int za ) { return theStatisticalNucleus[za]; }
G4int Init( G4int theZA, unsigned int seed1 = 0, unsigned int seed2 = 0, unsigned int seed3 = 0 );
void SetBandWidth( G4double bandWidth ) { BandWidth = bandWidth; }
void SetBrOption( G4int brOption ) { BrOption = brOption; }
G4NuDEXStatisticalNucleus* theStatisticalNucleus[G4NUDEX_MAXZA];
G4int HasData[G4NUDEX_MAXZA]; // -1:no; 0:don't know; 1:yes
G4String NuDEXLibDirectory;
G4int BrOption;
G4double BandWidth;
G4int secID; // creator model ID for the other secondaries produced by this model
G4double lowestEnergyLimit;
G4double minExcitation;
G4VEvaporationChannel* photonEvaporation; // Needed when NuDEX is not applicable
};
#endif
@@ -0,0 +1,99 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Author: E.Mendoza
//
// Creation date: May 2024
//
// Modifications:
//
// -------------------------------------------------------------------
//
// NuDEX code (https://doi.org/10.1016/j.nima.2022.167894)
//
#ifndef NUDEXINTERNALCONVERSION_HH
#define NUDEXINTERNALCONVERSION_HH 1
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstring>
#include "G4NuDEXRandom.hh"
#define ICC_MAXNSHELLS 40
#define ICC_NMULTIP 5
#define MINZINTABLES 10 //below this value, the alpha is always 0
/*
Class to manage the internal conversion factors and the generation of converted-e-
Still not included the fluorescence-auger effects, i.e., what happens with the hole
We read the occ factors from a file, and they are stored in a matrix
The total Icc are in index=0 (data from the libraries) and index=NShells (sum of the partials)
Data are taken from: https://doi.org/10.1006/adnd.2002.0884
*/
class G4NuDEXInternalConversion{
public:
G4NuDEXInternalConversion(G4int Z);
~G4NuDEXInternalConversion();
void Init(const char* fname);
void PrintICC(std::ostream &out);
G4double GetICC(G4double Ene,G4int multipolarity,G4int i_shell=-1);
G4bool SampleInternalConversion(G4double Ene,G4int multipolarity,G4double alpha=-1,G4bool CalculateProducts=true);
void FillElectronHole(G4int i_shell); //Fluorescence/auger
void SetRandom4Seed(unsigned int seed){theRandom4->SetSeed(seed);}
private:
G4double Interpolate(G4double val,G4int npoints,G4double* x,G4double* y);
void MakeTotal();
private:
G4int theZ,NShells;
G4double BindingEnergy[ICC_MAXNSHELLS];
G4double *Eg[ICC_MAXNSHELLS],*Icc_E[ICC_NMULTIP][ICC_MAXNSHELLS],*Icc_M[ICC_NMULTIP][ICC_MAXNSHELLS];
G4int np[ICC_MAXNSHELLS];
std::string OrbitalName[ICC_MAXNSHELLS];
G4NuDEXRandom* theRandom4;
public:
G4int Ne,Ng;
G4double Eele[100],Egam[100];
};
#endif
@@ -0,0 +1,97 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Author: E.Mendoza
//
// Creation date: May 2024
//
// Modifications:
//
// -------------------------------------------------------------------
//
// NuDEX code (https://doi.org/10.1016/j.nima.2022.167894)
//
#ifndef NUDEXLEVELDENSITY_HH
#define NUDEXLEVELDENSITY_HH 1
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cmath>
//Level densities as they are defined in the RIPL-3 manual
//LDTYPE=1,2,3 --> Back-Shifted-Fermi-Gas model, Constant Temperature, Back-shifted: Egidy
#define DEFAULTLDTYPE 1
//using namespace std;
class G4NuDEXLevelDensity{
public:
G4NuDEXLevelDensity(G4int aZ,G4int aA,G4int ldtype=DEFAULTLDTYPE);
~G4NuDEXLevelDensity(){}
G4int ReadLDParameters(const char* dirname,const char* inputfname=0,const char* defaultinputfname=0);
G4int CalculateLDParameters_BSFG(const char* dirname);
G4int SearchLDParametersInInputFile(const char* inputfname);
void GetSnD0I0Vals(G4double &aSn,G4double &aD0,G4double &aI0){aSn=Sn; aD0=D0; aI0=I0;}
G4int GetLDType(){return LDType;}
G4double GetNucleusTemperature(G4double ExcEnergy);
G4double GetLevelDensity(G4double ExcEnergy_MeV,G4double spin,G4bool parity,G4bool TotalLevelDensity=false);
G4double EstimateInverse(G4double LevDen_iMeV,G4double spin,G4bool parity); //an approximate value of ExcEnergy(rho), the inverse function of rho(ExcEnergy) - iMeV means 1/MeV
G4double Integrate(G4double Emin,G4double Emax,G4double spin,G4bool parity);
void PrintParameters(std::ostream &out);
void PrintParametersInInputFileFormat(std::ostream &out);
private:
//General info:
G4int A_Int,Z_Int;
G4int LDType; //=1,2,3 --> Back-Shifted-Fermi-Gas model, Constant Temperature, Back-shifted: Egidy
G4double Sn,D0,I0; //I0 es el del nucleo A-1 (el que captura)
G4double Ed;
G4bool HasData;
//Level density parameters:
G4double A_mass,ainf_ldpar,gamma_ldpar,dW_ldpar,Delta_ldpar,T_ldpar,E0_ldpar,Ex_ldpar;
};
#endif
@@ -0,0 +1,163 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Author: E.Mendoza
//
// Creation date: May 2024
//
// Modifications:
//
// -------------------------------------------------------------------
//
// NuDEX code (https://doi.org/10.1016/j.nima.2022.167894)
//
#ifndef NUDEXPSF_HH
#define NUDEXPSF_HH 1
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cmath>
//using namespace std;
class G4NuDEXLevelDensity;
/*
All energies in MeV
PSF are defined as in RIPL-3: PSF=Eg**(-2L-1) x Gamma width x level density
JL defines PSF x Eg**(2L+1) instead
PSFType=0 --> SLO
PSFType=1 --> EGLO, as defined in RIPL-3, but using always Tf in the formula
PSFType=2 --> SMLO, as defined in RIPL-3
PSFType=3 --> GLO (like EGLO, but k1=k2=1)
PSFType=4 --> MGLO (like EGLO, but k2=1)
PSFType=5 --> KMF
PSFType=6 --> GH
PSFType=7 --> EGLO, but the k parameter is provided (MEGLO)
PSFType=8 --> EGLO, but the "k1" and "k2" parameters are provided (MEGLO)
PSFType=9 --> EGLO, but the k parameter and a constant temperature of the nucleus is provided (MEGLO)
PSFType=10 --> EGLO, but the "k1" and "k2" parameters and a constant temperature of the nucleus are provided (MEGLO)
PSFType=11 --> SMLO, as defined in Eur. Phys. J. A (2019) 55: 172
PSFType=20 --> gaussian (to simulate small bumps or resonances)
PSFType=21 --> expo --> C*exp(-eta*Eg). It is defined with three entries: C eta dummy
PSFType=40 --> pointwise function type 1 (only input file)
PSFType=41 --> pointwise function type 2 (only input file)
Procedure to obtain the PSF, in order of hierarchy:
- Get the data from inputfname
- Get the data from PSF_param.dat file
- Get the data from IAEA-2019 PSF values (if PSFflag==0)
- Get the data from RIPL-3 experimental MLO values --> gdr-parameters&errors-exp-MLO.dat
- Get the data from RIPL-3 Theorethical values --> gdr-parameters-theor.dat
- Use RIPL-3 and RIPL-2 theoretical formulas
*/
class G4NuDEXPSF{
public:
G4NuDEXPSF(G4int aZ,G4int aA);
~G4NuDEXPSF();
G4int Init(const char* dirname,G4NuDEXLevelDensity* aLD,const char* inputfname=0,const char* defaultinputfname=0,G4int PSFflag=0);
G4double GetE1(G4double Eg,G4double ExcitationEnergy);
G4double GetM1(G4double Eg,G4double ExcitationEnergy);
G4double GetE2(G4double Eg,G4double ExcitationEnergy);
void PrintPSFParameters(std::ostream &out);
void PrintPSFParametersInInputFileFormat(std::ostream &out);
private:
G4bool TakePSFFromInputFile(const char* fname);
G4bool TakePSFFromDetailedParFile(const char* fname);
G4bool TakePSFFromIAEA01(const char* fname); // IAEA - PSF values 2019
G4bool TakePSFFromRIPL01(const char* fname); // RIPL3-MLO values
G4bool TakePSFFromRIPL02(const char* fname); // RIPL3-Theorethical values
void GenerateM1AndE2FromE1(); // From RIPL-3 and RIPL-2 recommendations
//Shapes:
//Typical ones:
G4double SLO(G4double Eg,G4double Er,G4double Gr,G4double sr); //PSFType=0
G4double EGLO(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy); //PSFType=1
G4double SMLO(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy); //PSFType=2
G4double GLO(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy); //PSFType=3
G4double MGLO(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy); //PSFType=4
G4double KMF(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy); //PSFType=5
G4double GH(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy); //PSFType=6
G4double MEGLO(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy,G4double k_param1,G4double k_param2,G4double Temp=-1);//PSFType=6,7,8,9,10
G4double SMLO_v2(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy); //PSFType=11
G4double Gauss(G4double Eg,G4double Er,G4double Gr,G4double sr); //PSFType=20
G4double Expo(G4double Eg,G4double C,G4double eta); //PSFType=21
//PSFType=40, PSFType=41 are pointwise defined functions
//------------------------------
G4double EGLO_GLO_MGLO(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy,G4int Opt);
G4double FlexibleGLOType(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double Temp1,G4double k_param1,G4double Temp2,G4double k_param2);
G4double Gamma_k(G4double Eg,G4double Er,G4double Gr,G4double Temp,G4double k_param);
private:
G4int Z_Int,A_Int;
G4int nR_E1,nR_M1,nR_E2;
G4int PSFType_E1[10], PSFType_M1[10], PSFType_E2[10];
G4double E_E1[10],G_E1[10],s_E1[10],p1_E1[10],p2_E1[10],p3_E1[10];
G4double E_M1[10],G_M1[10],s_M1[10],p1_M1[10],p2_M1[10],p3_M1[10];
G4double E_E2[10],G_E2[10],s_E2[10],p1_E2[10],p2_E2[10],p3_E2[10];
//-----------------------------------------------
//PSF pointwise defined PSF --> PSFType=3,4,6
G4int np_E1,np_M1,np_E2;
G4double *x_E1,*y_E1;
G4double *x_M1,*y_M1;
G4double *x_E2,*y_E2;
G4double E1_normFac,M1_normFac,E2_normFac;
G4double NormEmin,NormEmax;
//-----------------------------------------------
G4double ScaleFactor_E1,ScaleFactor_M1,ScaleFactor_E2;
G4double EvaluateFunction(G4double xval,G4int np,G4double* x,G4double* y);
void Renormalize();
G4NuDEXLevelDensity* theLD;
};
#endif
@@ -0,0 +1,108 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Author: E.Mendoza
//
// Creation date: May 2024
//
// Modifications:
//
// -------------------------------------------------------------------
//
// NuDEX code (https://doi.org/10.1016/j.nima.2022.167894)
//
#ifndef NUDEXRANDOM_HH
#define NUDEXRANDOM_HH 1
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cmath>
//COMPILATIONTYPE==1 compile with ROOT
//COMPILATIONTYPE==2 compile with GEANT4
#define COMPILATIONTYPE 2
#if COMPILATIONTYPE == 1
//------------------------------------------------------------
// ROOT
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#include "TRandom2.h"
#pragma GCC diagnostic pop
//------------------------------------------------------------
#elif COMPILATIONTYPE == 2
//------------------------------------------------------------
// GEANT4
#include "Randomize.hh"
#include "globals.hh"
#include "G4Exception.hh"
//------------------------------------------------------------
#else
#error Unsupported COMPILATIONTYPE setting
#endif
void NuDEXException(const char* originOfException,const char* exceptionCode,const char* description);
class G4NuDEXRandom{
public:
G4NuDEXRandom(unsigned int seed);
~G4NuDEXRandom();
public:
void SetSeed(unsigned int seed);
unsigned int GetSeed();
G4double Uniform(G4double Xmin=0,G4double Xmax=1);
unsigned int Integer(unsigned int IntegerMax);
G4double Exp(G4double tau);
G4double Gaus(G4double mean=0,G4double sigma=1);
G4long Poisson(G4double mean);
private:
#if COMPILATIONTYPE == 1
TRandom2* theRandom;
#elif COMPILATIONTYPE == 2
CLHEP::HepJamesRandom* theEngine;
CLHEP::RandFlat* theRandFlat;
CLHEP::RandExponential* theRandExponential;
CLHEP::RandGauss* theRandGauss;
CLHEP::RandPoisson* theRandPoisson;
#endif
};
#endif
@@ -0,0 +1,263 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Author: E.Mendoza
//
// Creation date: May 2024
//
// Modifications:
//
// -------------------------------------------------------------------
//
// NuDEX code (https://doi.org/10.1016/j.nima.2022.167894)
//
#ifndef NUDEXSTATISTICALNUCLEUS_HH
#define NUDEXSTATISTICALNUCLEUS_HH 1
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include "G4NuDEXRandom.hh"
class G4NuDEXLevelDensity;
class G4NuDEXInternalConversion;
class G4NuDEXPSF;
//This define remains:
//#define GENERATEEXPLICITLYALLLEVELSCHEME 1
//Class to obtain the level density for each excitation energy, spin, and parity
//All energies in MeV, all times in s
//Some of the class methods could be functions out of the class
struct Level{
G4double Energy;
G4int spinx2;
G4bool parity; //true/false --> positive,negative
unsigned int seed;
G4int KnownLevelID;
G4int NLevels;
G4double Width;
};
//multipolarity of a transition is ...,-2,-1,0,1,2,... --> ...,M2,M1,Unk,E1,E2,...
struct KnownLevel{
G4int id;
G4double Energy;
G4int spinx2;
G4bool parity; //true/false --> positive,negative
G4double T12; //half life - seconds
G4int Ndecays;
G4double* decayFraction;
std::string* decayMode;
G4int NGammas;
G4int *FinalLevelID,*multipolarity;
G4double *Eg,*cumulPtot,*Pg,*Pe,*Icc;
};
G4int ComparisonLevels(const void* va, const void* vb);
void CopyLevel(Level* a,Level* b);
void CopyLevel(KnownLevel* a,Level* b);
class G4NuDEXStatisticalNucleus{
public:
G4NuDEXStatisticalNucleus(G4int Z,G4int A);
~G4NuDEXStatisticalNucleus();
public:
//Initialize everything. All the required files should be in dirname.
//some of the data could also be in inputfname
G4int Init(const char* dirname,const char* inputfname=0);
//If InitialLevel==-1 then we start from the thermal capture level
//If ExcitationEnergy>0 then is the excitation energy of the nucleus
//If ExcitationEnergy<0 then is a capture reaction of a neutron with energy -ExcitationEnergy (MeV)
G4int GenerateCascade(G4int InitialLevel,G4double ExcitationEnergy,std::vector<char>& pType,std::vector<double>& pEnergy,std::vector<double>& pTime);
G4int GetClosestLevel(G4double Energy,G4int spinx2,G4bool parity); //if spinx2<0, then retrieves the closest level of any spin and parity
G4double GetLevelEnergy(G4int i_level);
void GetSnAndI0(G4double &sn,G4double &i0){sn=Sn; i0=I0;}
Level* GetLevel(G4int i_level);
void ChangeLevelSpinParityAndBR(G4int i_level,G4int newspinx2,G4bool newParity,G4int nlevels,G4double width,unsigned int seed=0); //if nlevels or width are negative they don't change. If seed (to generate the BR) is 0 it does not change.
void ChangeThermalCaptureLevelBR(G4double LevelEnergy,G4double absoluteIntensity);
void SetSomeInitalParameters(G4int LDtype=-1,G4int PSFFlag=-1,G4double MaxSpin=-1,G4int minlevelsperband=-1,G4double BandWidth_MeV=0,G4double maxExcEnergy=0,G4int BrOption=-1,G4int sampleGammaWidths=-1,unsigned int aseed1=0,unsigned int aseed2=0,unsigned int aseed3=0);
void SetInitialParameters02(G4int knownLevelsFlag=-1,G4int electronConversionFlag=-1,G4double primGamNormFactor=-1,G4double primGamEcut=-1,G4double ecrit=-1);
void SetBandWidth(G4double bandWidth){ if(bandWidth==0){bandWidth=-1;} BandWidth=bandWidth;} //So it is not re-written with the lib-params.
void SetBrOption(G4int BrOption){BROpt=BrOption;}
void SetRandom1Seed(unsigned int seed){theRandom1->SetSeed(seed); Rand1seedProvided=true;}
void SetRandom2Seed(unsigned int seed){theRandom2->SetSeed(seed); Rand2seedProvided=true;}
void SetRandom3Seed(unsigned int seed){theRandom3->SetSeed(seed); Rand3seedProvided=true;}
G4NuDEXRandom* GetRandom3(){return theRandom3;}
G4bool HasBeenInitialized(){return hasBeenInitialized;}
//-------------------------------------------------------
//Print:
void PrintAll(std::ostream &out);
void PrintParameters(std::ostream &out);
void PrintKnownLevels(std::ostream &out);
void PrintLevelDensity(std::ostream &out);
void PrintLevelScheme(std::ostream &out);
void PrintThermalPrimaryTransitions(std::ostream &out);
void PrintPSF(std::ostream &out);
void PrintICC(std::ostream &out);
void PrintTotalCumulBR(G4int i_level,std::ostream &out);
void PrintBR(G4int i_level,G4double MaxExcEneToPrint_MeV,std::ostream &out);
void PrintInput01(std::ostream &out);
//----------------
void PrintKnownLevelsInDEGENformat(std::ostream &out);
void PrintLevelSchemeInDEGENformat(const char* fname,G4int MaxLevelID=-1);
//-------------------------------------------------------
private:
//-------------------------------------------------------
//Used by Init():
//Read different data from files (do it in this order). If returnval<0 --> error reading file or nucleus not present in the file:
G4int ReadSpecialInputFile(const char* fname);
G4int ReadGeneralStatNuclParameters(const char* fname);
G4double ReadEcrit(const char* fname);
G4double ReadKnownLevels(const char* fname);
void CreateLevelScheme();
G4int InsertHighEnergyKnownLevels();
void ComputeKnownLevelsMissingBR();
void MakeSomeParameterChecks01();
//-------------------------------------------------------
G4double TakeTargetNucleiI0(const char* fname,G4int& check);
void CreateThermalCaptureLevel(unsigned int seed=0); //If seed (to generate the BR) is 0 it does not change.
void GenerateThermalCaptureLevelBR(const char* dirname);
//-------------------------------------------------------
//-------------------------------------------------------
//cascade generation:
G4double ComputeDecayIntensities(G4int i_level,G4double* cumulativeBR=0,G4double randnumber=-1,G4double TotGR=-1,G4bool AllowE1=false);
G4int SampleFinalLevel(G4int i_level,G4int& multipolarity,G4double &icc_fac,G4int nTransition);
G4int GetMultipolarity(Level* theInitialLevel,Level* theFinalLevel);
//-------------------------------------------------------
private:
//-------------------------------------------------------
//Used to create the unknown Levels:
G4int GenerateLevelsInBigRange(G4double Emin,G4double Emax,G4int spinx2,G4bool parity,Level* someLevels,G4int MaxNLevelsToFill); //salen sin ordenar
G4int GenerateLevelsInSmallRange(G4double Emin,G4double Emax,G4int spinx2,G4bool parity,Level* someLevels,G4int MaxNLevelsToFill); //salen sin ordenar
G4int GenerateWignerLevels(G4double Emin,G4double Emax,G4int spinx2,G4bool parity,Level* someLevels,G4int MaxNLevelsToFill); //salen ordenados
G4int GenerateBandLevels(G4int bandmin,G4int bandmax,G4int spinx2,G4bool parity,Level* someLevels,G4int MaxNLevelsToFill);
G4int GenerateAllUnknownLevels(Level* someLevels,G4int MaxNLevelsToFill); //salen ordenados
G4int CreateBandsFromLevels(G4int thisNLevels,Level* someLevels,G4int spinx2,G4bool parity);
G4int EstimateNumberOfLevelsToFill(); //to estimate the length of "theLevels" vector
//-------------------------------------------------------
private:
//General info:
G4int A_Int,Z_Int;
G4double Sn,D0,I0; //I0 es el del nucleo A-1 (el que captura)
G4bool hasBeenInitialized;
std::string theLibDir;
G4NuDEXRandom* theRandom1; //To generate the unknown level scheme
G4NuDEXRandom* theRandom2; //To calculate the Gamma-rho values (i.e. to generate the branching ratios)
G4NuDEXRandom* theRandom3; //To generate the cascades
unsigned int seed1,seed2,seed3;
G4bool Rand1seedProvided,Rand2seedProvided,Rand3seedProvided;
//--------------------------------------------------------------------------
//Parameters which will define how the level scheme will be created:
G4double Ecrit; //Energy between the known and unknown levels
G4double MaxExcEnergy,BandWidth;
G4int maxspinx2,NBands,MinLevelsPerBand; //maximum spin (x2) to consider, number of bands used to "rebin" the stat. part
G4int LevelDensityType; //if negative or cero, use the default one.
G4int PSFflag; // use IAEA PSF-data (PSFflag==0), use RIPL-3 data (PSFflag==1)
G4double E_unk_min,E_unk_max; //min and max energy where the statistical part will be generated
G4double Emin_bands,Emax_bands; //limites de energia para calcular las bandas de niveles
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//Level scheme:
Level* theLevels; //known+unknown levels
KnownLevel* theKnownLevels; // known levels
G4int NKnownLevels,NUnknownLevels,NLevels,KnownLevelsVectorSize;
Level theThermalCaptureLevel;
G4int NLevelsBelowThermalCaptureLevel; //excluding the last one
G4int KnownLevelsFlag;
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//Branching ratios:
G4int BROpt,SampleGammaWidths;
G4double* TotalGammaRho;
G4double* theThermalCaptureLevelCumulBR;
G4double** TotalCumulBR; //all BR
G4double PrimaryGammasIntensityNormFactor;
G4double PrimaryGammasEcut; //This variable can be used to avoid generating transitions close to the "Primary Gammas" region
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//LD,ICC, PSF:
G4int ElectronConversionFlag;
G4NuDEXLevelDensity* theLD;
G4NuDEXInternalConversion* theICC;
G4NuDEXPSF* thePSF;
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//for internal use, when generating the cascades:
G4int theSampledLevel,theSampledMultipolarity;
//--------------------------------------------------------------------------
};
//***************************************************************************************************************
//***************************************************************************************************************
#endif
@@ -0,0 +1,34 @@
# - G4hadronic_nudex module build definition
# Define the Geant4 Module.
geant4_add_module(G4hadronic_nudex
PUBLIC_HEADERS
G4NuDEXNeutronCaptureModel.hh
PRIVATE_HEADERS
G4NuDEXInternalConversion.hh
G4NuDEXLevelDensity.hh
G4NuDEXPSF.hh
G4NuDEXRandom.hh
G4NuDEXStatisticalNucleus.hh
SOURCES
G4NuDEXInternalConversion.cc
G4NuDEXLevelDensity.cc
G4NuDEXNeutronCaptureModel.cc
G4NuDEXPSF.cc
G4NuDEXRandom.cc
G4NuDEXStatisticalNucleus.cc)
geant4_module_link_libraries(G4hadronic_nudex
PUBLIC
G4globman
G4hadronic_mgt
G4hadronic_util
PRIVATE
G4bosons
G4ions
G4leptons
G4partman
G4hadronic_deex_management
G4hadronic_deex_photon_evaporation
G4hepgeometry
G4heprandom)
@@ -0,0 +1,439 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Author: E.Mendoza
//
// Creation date: May 2024
//
// Modifications:
//
// -------------------------------------------------------------------
//
// NuDEX code (https://doi.org/10.1016/j.nima.2022.167894)
//
#include "G4NuDEXInternalConversion.hh"
//If alpha>0, use that value
G4bool G4NuDEXInternalConversion::SampleInternalConversion(G4double Ene,G4int multipolarity,G4double alpha,G4bool CalculateProducts){
if(theZ<MINZINTABLES){ //then we have no info
if(alpha<0){
Ne=0;
Ng=0;
return false;
}
else{
G4double rand=theRandom4->Uniform(0,alpha+1);
if(rand<alpha){ //then electron conversion
Ne=1;
Ng=0;
Eele[0]=Ene; //which is not correct, but we don't know the binding energy
return true;
}
return false;
}
}
Ne=0;
Ng=0;
if(multipolarity==0){ //maybe it is better to return true ... ?? --> no
//return true;
if(alpha<=0){
return false;
}
//NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
G4bool usegivenalpha=true;
if(NShells==0 || std::abs(multipolarity)>ICC_NMULTIP){return false;}
if(alpha<0){
usegivenalpha=false;
alpha=GetICC(Ene,multipolarity);
}
G4double rand=theRandom4->Uniform(0,alpha+1);
if(rand<alpha){ //then electron conversion
if(!CalculateProducts){return true;}
//Select the orbital:
if(usegivenalpha){rand=rand*GetICC(Ene,multipolarity)/alpha;} //renormalize rand to our alpha
G4double cumul=0;
for(G4int i=1;i<NShells;i++){
cumul+=GetICC(Ene,multipolarity,i);
//std::cout<<Ene<<" "<<multipolarity<<" "<<i<<" "<<GetICC(Ene,multipolarity,i)<<" "<<rand-1<<std::endl;
if(cumul>=rand || multipolarity==0){ //then is this orbital
Ne=1;
Eele[0]=Ene-BindingEnergy[i];
FillElectronHole(i); //now there is a hole there, in the filling procedure we emitt gammas and/or electrons
if(Eele[0]<0){
std::cout<<" For Z = "<<theZ<<" and orbital "<<OrbitalName[i]<<" --> Ene = "<<Ene<<" and BindingEnergy = "<<BindingEnergy[i]<<std::endl;
std::cout<<" Given alpha is "<<alpha<<" ("<<usegivenalpha<<"), rand = "<<rand<<" and tabulated alpha for Ene = "<<Ene<<" and mult = "<<multipolarity<<" is "<<GetICC(Ene,multipolarity)<<" -- cumul = "<<cumul<<std::endl;
for(G4int j=1;j<=NShells;j++){
std::cout<<j<<" "<<GetICC(Ene,multipolarity,j)<<std::endl;
}
Eele[0]=0;
}
return true;
}
}
std::cout<<" ############ Warning in "<<__FILE__<<", line "<<__LINE__<<" ############"<<std::endl;
std::cout<<" Given alpha is "<<alpha<<" and tabulated alpha for Ene = "<<Ene<<" and mult = "<<multipolarity<<" is "<<GetICC(Ene,multipolarity)<<" -- cumul = "<<cumul<<std::endl;
for(G4int i=1;i<=NShells;i++){
std::cout<<i<<" "<<GetICC(Ene,multipolarity,i)<<std::endl;
}
Ne=1;
Eele[0]=Ene-BindingEnergy[NShells-1];
return true;
}
return false;
}
void G4NuDEXInternalConversion::FillElectronHole(G4int i_shell){
//A very simplified version of the process (... and false). It can be done with accuracy with G4AtomicTransitionManager
G4double fluoyield=0;
if(i_shell==1){ //K-shell
//Hubbell et al. (1994) formula for the fluorescence yield:
G4double C0=0.0370,C1=0.03112,C2=5.44e-5,C3=-1.25e-6;
G4double w_fac=std::pow(C0+C1*theZ+C2*theZ*theZ+C3*theZ*theZ*theZ,4);
fluoyield=w_fac/(1.+w_fac);
}
else if(i_shell>=2 && i_shell<=4){ //L-shell
//Hubbell et al. (1994) formula for the fluorescence yield:
if(theZ>=3 && theZ<=36){
fluoyield=1.939e-8*std::pow(theZ,3.8874);
}
else if(theZ>36){
G4double C0=0.17765,C1=0.00298937,C2=8.91297e-5,C3=-2.67184e-7;
G4double w_fac=std::pow(C0+C1*theZ+C2*theZ*theZ+C3*theZ*theZ*theZ,4);
fluoyield=w_fac/(1.+w_fac);
}
}
G4double rand=theRandom4->Uniform(0,1);
if(rand<fluoyield){ //gamma emission
Egam[Ng]=BindingEnergy[i_shell];
Ng++;
}
else{ //electron emission
Eele[Ne]=BindingEnergy[i_shell];
Ne++;
}
}
//If i_shell<0 --> the total alpha
G4double G4NuDEXInternalConversion::GetICC(G4double Ene,G4int multipolarity,G4int i_shell){
if(theZ<MINZINTABLES){ //then we have no info
return 0;
}
if(NShells==0 || std::abs(multipolarity)>ICC_NMULTIP){return 0;}
//-----------------------------------------
//Total:
//The following line does not work, due to interpolation below binding energies:
//if(i_shell<0){i_shell=NShells;}
if(i_shell<0){
G4double result=0;
for(G4int i=1;i<NShells;i++){
result+=GetICC(Ene,multipolarity,i);
}
return result;
}
//-----------------------------------------
if(Ene<BindingEnergy[i_shell]){return 0;}
if(np[i_shell]==0){
std::cout<<" shell "<<i_shell<<" has not been initialized"<<std::endl;
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
if(i_shell==NShells && Ene<Eg[i_shell][0]){ //then we cannot extrapolate, because of the binding energies of the different shells
G4double total=0;
for(G4int i=1;i<NShells;i++){total+=GetICC(Ene,multipolarity,i);}
return total;
}
if(multipolarity>0){
return Interpolate(Ene,np[i_shell],Eg[i_shell],Icc_E[multipolarity-1][i_shell]);
}
else if(multipolarity<0){
return Interpolate(Ene,np[i_shell],Eg[i_shell],Icc_M[(-multipolarity)-1][i_shell]);
}
return 0;
}
G4NuDEXInternalConversion::G4NuDEXInternalConversion(G4int Z){
theZ=Z;
NShells=0;
for(G4int i=0;i<ICC_MAXNSHELLS;i++){
Eg[i]=0; np[i]=0; BindingEnergy[i]=0;
for(G4int j=0;j<ICC_NMULTIP;j++){
Icc_E[j][i]=0; Icc_M[j][i]=0;
}
}
theRandom4= new G4NuDEXRandom(1234567);
}
G4NuDEXInternalConversion::~G4NuDEXInternalConversion(){
for(G4int i=0;i<ICC_MAXNSHELLS;i++){
if(Eg[i]!=0){delete [] Eg[i];}
for(G4int j=0;j<ICC_NMULTIP;j++){
if(Icc_E[j][i]!=0){delete [] Icc_E[j][i];}
if(Icc_M[j][i]!=0){delete [] Icc_M[j][i];}
}
}
delete theRandom4;
}
void G4NuDEXInternalConversion::PrintICC(std::ostream &out){
char word[1000];
out<<" ######################################################################################################################################### "<<std::endl;
out<<" ICC"<<std::endl;
out<<" Z = "<<theZ<<std::endl;
out<<" NShells = "<<NShells<<std::endl;
out<<" ----------------------------------------------------------------------------------------------------------------------------------------"<<std::endl;
out<<" Total calculated from the sum of the partials:"<<std::endl;
out<<" E_g E1 E2 E3 E4 E5 M1 M2 M3 M4 M5 "<<std::endl;
for(G4int j=0;j<np[NShells];j++){
snprintf(word,1000,"%10.4g",Eg[NShells][j]); out<<word;
for(G4int k=0;k<ICC_NMULTIP;k++){
snprintf(word,1000," %10.4g",Icc_E[k][NShells][j]); out<<word;
}
for(G4int k=0;k<ICC_NMULTIP;k++){
snprintf(word,1000," %10.4g",Icc_M[k][NShells][j]); out<<word;
}
out<<std::endl;
}
out<<" ----------------------------------------------------------------------------------------------------------------------------------------"<<std::endl;
for(G4int i=0;i<NShells;i++){
out<<" ----------------------------------------------------------------------------------------------------------------------------------------"<<std::endl;
out<<" Binding energy = "<<BindingEnergy[i]<<" MeV - OrbitalName = "<<OrbitalName[i]<<" - np = "<<np[i]<<std::endl;
out<<" E_g E1 E2 E3 E4 E5 M1 M2 M3 M4 M5 "<<std::endl;
for(G4int j=0;j<np[i];j++){
snprintf(word,1000,"%10.4g",Eg[i][j]); out<<word;
for(G4int k=0;k<ICC_NMULTIP;k++){
snprintf(word,1000," %10.4g",Icc_E[k][i][j]); out<<word;
}
for(G4int k=0;k<ICC_NMULTIP;k++){
snprintf(word,1000," %10.4g",Icc_M[k][i][j]); out<<word;
}
out<<std::endl;
}
out<<" ----------------------------------------------------------------------------------------------------------------------------------------"<<std::endl;
}
out<<" ########################################################################################################################################## "<<std::endl;
}
void G4NuDEXInternalConversion::Init(const char* fname){
if(theZ<MINZINTABLES){ //then we have no info
return;
}
if(NShells!=0){ //Init only once
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
std::ifstream in(fname);
if(!in.good()){
std::cout<<" ################ Error opening "<<fname<<" ################"<<std::endl;
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
std::string word;
NShells=1;
while(in>>word){
if(word.c_str()[0]=='Z' && word.c_str()[1]=='='){
if(std::atoi(&(word.c_str()[2]))==theZ){
in>>word>>word;
G4int orbindex;
if(word==std::string("Total")){
in.ignore(1000,'\n');
in.ignore(1000,'\n');
orbindex=0;
}
else{
orbindex=NShells;
in>>word>>word>>BindingEnergy[NShells]>>word;
BindingEnergy[NShells]*=1.e-6; // all in MeV
in.ignore(1000,'\n');
in.ignore(1000,'\n');
}
//--------------------------------------------------------------------------------
size_t sz,sz2;
G4int np_tmp=0;
G4double Eg_tmp[1000],Icc_E_tmp[ICC_NMULTIP][100],Icc_M_tmp[ICC_NMULTIP][100];
while(getline(in,word)){
if(word.size()<100){
np[orbindex]=np_tmp;
Eg[orbindex]=new G4double[np_tmp];
for(G4int j=0;j<np_tmp;j++){
Eg[orbindex][j]=Eg_tmp[j];
}
for(G4int i=0;i<ICC_NMULTIP;i++){
Icc_E[i][orbindex]=new G4double[np_tmp];
Icc_M[i][orbindex]=new G4double[np_tmp];
}
for(G4int i=0;i<ICC_NMULTIP;i++){
for(G4int j=0;j<np_tmp;j++){
Icc_E[i][orbindex][j]=Icc_E_tmp[i][j];
Icc_M[i][orbindex][j]=Icc_M_tmp[i][j];
}
}
if(orbindex!=0){NShells++;}
break;
}
else{
sz=0;
Eg_tmp[np_tmp]=std::stof(word,&sz2);
Eg_tmp[np_tmp]*=1.e-3; //all to MeV
sz+=sz2;
for(G4int i=0;i<ICC_NMULTIP;i++){
Icc_E_tmp[i][np_tmp]=std::stof(word.substr(sz),&sz2); sz+=sz2;
}
for(G4int i=0;i<ICC_NMULTIP;i++){
Icc_M_tmp[i][np_tmp]=std::stof(word.substr(sz),&sz2); sz+=sz2;
}
if((G4int)(std::stof(word.substr(sz),&sz2)+0.01)!=theZ){
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
sz+=sz2;
sz2=word.find_first_not_of(' ',sz);
if(np_tmp==0){OrbitalName[orbindex]=word.substr(sz2,word.substr(sz2).size()-1);}
np_tmp++;
}
}
if(orbindex==0){break;}
//--------------------------------------------------------------------------------
}
}
}
if(!in.good()){
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
in.close();
MakeTotal();
}
// Total Icc goes to nShell=NShells
void G4NuDEXInternalConversion::MakeTotal(){
if(np[0]==0 || Eg[0]==0){
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
//We evaluate it in the same frame as the total given by the data:
BindingEnergy[NShells]=0;
np[NShells]=np[0];
Eg[NShells]=new G4double[np[NShells]];
for(G4int i=0;i<ICC_NMULTIP;i++){
Icc_E[i][NShells]=new G4double[np[NShells]];
Icc_M[i][NShells]=new G4double[np[NShells]];
}
for(G4int k=0;k<np[NShells];k++){
for(G4int j=0;j<ICC_NMULTIP;j++){
Icc_E[j][NShells][k]=0;
Icc_M[j][NShells][k]=0;
}
}
for(G4int k=0;k<np[NShells];k++){
Eg[NShells][k]=Eg[0][k];
for(G4int i=1;i<NShells;i++){
for(G4int j=0;j<ICC_NMULTIP;j++){
Icc_E[j][NShells][k]+=GetICC(Eg[NShells][k],j+1,i);
Icc_M[j][NShells][k]+=GetICC(Eg[NShells][k],-j-1,i);
}
}
}
}
//if val>x[npmax] then ---> return 0
G4double G4NuDEXInternalConversion::Interpolate(G4double val,G4int npoints,G4double* x,G4double* y){
G4int i_interp=-1;
for(G4int i=1;i<npoints;i++){
if(x[i]>=val){i_interp=i-1; break;}
}
if(i_interp<0){return 0;}
/*
//y=a0+a1*x
G4double a1=(y[i_interp+1]-y[i_interp])/(x[i_interp+1]-x[i_interp]);
G4double a0=y[i_interp]-a1*x[i_interp];
return (a0+a1*val);
*/
//It is better a log-log interpolation:
if(y[i_interp+1]<=0 || y[i_interp]<=0 || x[i_interp+1]<=0 || x[i_interp]<=0){
//y=a0+a1*x
G4double a1=(y[i_interp+1]-y[i_interp])/(x[i_interp+1]-x[i_interp]);
G4double a0=y[i_interp]-a1*x[i_interp];
return (a0+a1*val);
}
//log(y)=a0+a1*log(x)
G4double a1=std::log(y[i_interp+1]/y[i_interp])/std::log(x[i_interp+1]/x[i_interp]);
G4double a0=std::log(y[i_interp])-a1*std::log(x[i_interp]);
G4double result=std::exp(a0+a1*std::log(val));
return result;
}
@@ -0,0 +1,400 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Author: E.Mendoza
//
// Creation date: May 2024
//
// Modifications:
//
// -------------------------------------------------------------------
//
// NuDEX code (https://doi.org/10.1016/j.nima.2022.167894)
//
#include "G4NuDEXRandom.hh"
#include "G4NuDEXLevelDensity.hh"
G4NuDEXLevelDensity::G4NuDEXLevelDensity(G4int aZ,G4int aA,G4int ldtype){
Z_Int=aZ;
A_Int=aA;
LDType=ldtype;
if(LDType<0){LDType=DEFAULTLDTYPE;}
A_mass=A_Int;
if(LDType!=1 && LDType!=2 && LDType!=3){
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
HasData=false;
Sn=-1; D0=-1; I0=-1000;
Ed=0;
ainf_ldpar=0; gamma_ldpar=0; dW_ldpar=0; Delta_ldpar=0; T_ldpar=0; E0_ldpar=0; Ex_ldpar=0;
}
G4int G4NuDEXLevelDensity::ReadLDParameters(const char* dirname,const char* inputfname,const char* defaultinputfname){
char fname[100];
if(LDType==1 || LDType==3){ // Back-Shifted-Fermi-Gas model
snprintf(fname,100,"%s/LevelDensities/level-densities-bfmeff.dat",dirname);
}
else{ // Constant Temperature
snprintf(fname,100,"%s/LevelDensities/level-densities-ctmeff.dat",dirname);
}
G4double EL=0,EU=0;
std::ifstream in(fname);
if(!in.good()){
std::cout<<" ######## Error opening file "<<fname<<" ########"<<std::endl;
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
G4int aZ,aA;
char word[200];
in.ignore(10000,'\n');
//std::cout<<" LDType="<<LDType<<" "<<fname<<" "<<Z_Int<<" "<<A_Int<<std::endl;
while(in>>aZ>>aA){
if(aZ==Z_Int && aA==A_Int){
if(LDType==1 || LDType==3){
in>>word>>I0>>Sn>>D0>>word>>word>>EL>>word>>EU>>dW_ldpar>>gamma_ldpar>>ainf_ldpar>>word>>Delta_ldpar;
Ex_ldpar=0; E0_ldpar=0; T_ldpar=0;
Ed=(EL+EU)/2.;
}
else if(LDType==2){
in>>word>>I0>>Sn>>D0>>word>>word>>EL>>word>>EU>>dW_ldpar>>gamma_ldpar>>ainf_ldpar>>word>>Delta_ldpar>>Ex_ldpar>>E0_ldpar>>T_ldpar;
Ed=(EL+EU)/2.;
}
else{
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
if(in.good()){
HasData=true;
break;
}
}
in.ignore(10000,'\n');
}
in.close();
//Re-write some parameters if inputfname!=0
if(defaultinputfname!=0){
SearchLDParametersInInputFile(defaultinputfname);
}
if(inputfname!=0){
SearchLDParametersInInputFile(inputfname);
}
if(!HasData){ //no data
G4int check=CalculateLDParameters_BSFG(dirname);
if(check==0){
HasData=true;
if(LDType==2){
LDType=1;
std::cout<<" ##### WARNING: level density model for ZA="<<Z_Int*1000+A_Int<<" changed to Back-Shifted-Fermi-Gas model #####"<<std::endl;
}
}
}
if(HasData){return 0;}
//else, some problem reading ...
return -1;
}
G4int G4NuDEXLevelDensity::CalculateLDParameters_BSFG(const char* dirname){
//Eq. 61 of RIPL-3:
G4double alpha=0.0722396; //MeV^{-1}
G4double beta= 0.195267; //MeV^{-1}
G4double gamma0=0.410289; //MeV^{-1}
G4double delta=0.173015; //MeV
//Delta_ldpar: Eq. 50 of RIPL-3:
G4double n_par=0;
if((Z_Int%2)==1 && ((A_Int-Z_Int)%2)==1){n_par=-1;} //odd-odd (impar-impar)
if((Z_Int%2)==0 && ((A_Int-Z_Int)%2)==0){n_par=1;} //even-even (par-par)
Delta_ldpar=n_par*12/std::sqrt(A_mass)+delta;
//ainf_ldpar: Eq. 52 of RIPL-3:
ainf_ldpar=alpha*A_Int+beta*std::pow(A_mass,2./3.);
//gamma_ldpar: Eq. 53 of RIPL-3:
gamma_ldpar=gamma0/std::pow(A_mass,1./3.);
//dW_ldpar --> from data file
char fname[100];
snprintf(fname,100,"%s/LevelDensities/shellcor-ms.dat",dirname);
std::ifstream in(fname);
if(!in.good()){
std::cout<<" ######## Error opening file "<<fname<<" ########"<<std::endl;
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
G4int aZ,aA;
char word[200];
in.ignore(10000,'\n');
in.ignore(10000,'\n');
in.ignore(10000,'\n');
in.ignore(10000,'\n');
while(in>>aZ>>aA){
if(aZ==Z_Int && aA==A_Int){
in>>word>>dW_ldpar;
if(in.good()){break;}
}
in.ignore(10000,'\n');
}
if(!in.good()){//no data found
return -1;
}
in.close();
Ex_ldpar=0; E0_ldpar=0; T_ldpar=0;
Ed=0;
return 0;
}
G4int G4NuDEXLevelDensity::SearchLDParametersInInputFile(const char* inputfname){
if(inputfname!=0){
std::ifstream in2(inputfname);
if(!in2.good()){
std::cout<<" ############## Error opening "<<inputfname<<" ##############"<<std::endl;
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
std::string word_tmp;
while(in2>>word_tmp){
if(word_tmp[0]=='#'){in2.ignore(10000,'\n');}
if(word_tmp==std::string("END")){break;}
if(word_tmp==std::string("LDPARAMETERS")){
in2>>LDType;
if(LDType==1){
in2>>dW_ldpar>>gamma_ldpar>>ainf_ldpar>>Delta_ldpar;
}
else if(LDType==2){
in2>>dW_ldpar>>gamma_ldpar>>ainf_ldpar>>Delta_ldpar>>Ex_ldpar>>E0_ldpar>>T_ldpar;
}
else if(LDType==3){
in2>>ainf_ldpar>>Delta_ldpar;
}
else{
std::cout<<" ############## Error: Unknown LDType="<<LDType<<" in "<<inputfname<<" ##############"<<std::endl;
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
if(!in2.good()){
std::cout<<" ############## Error reading "<<inputfname<<" ##############"<<std::endl;
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
HasData=true;
break;
}
}
in2.close();
}
return 0;
}
void G4NuDEXLevelDensity::PrintParametersInInputFileFormat(std::ostream &out){
out<<"LDPARAMETERS"<<std::endl;
out<<LDType<<std::endl;
out.precision(15);
if(LDType==1){
out<<dW_ldpar<<" "<<gamma_ldpar<<" "<<ainf_ldpar<<" "<<Delta_ldpar<<std::endl;
}
else if(LDType==2){
out<<dW_ldpar<<" "<<gamma_ldpar<<" "<<ainf_ldpar<<" "<<Delta_ldpar<<" "<<Ex_ldpar<<" "<<E0_ldpar<<" "<<T_ldpar<<std::endl;
}
else if(LDType==3){
out<<ainf_ldpar<<" "<<Delta_ldpar<<std::endl;
}
out<<std::endl;
}
G4double G4NuDEXLevelDensity::GetNucleusTemperature(G4double ExcEnergy){
if(!HasData){
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
if(ExcEnergy<Ex_ldpar && LDType==2){
return T_ldpar;
}
G4double Uval=ExcEnergy-Delta_ldpar;
if(Uval<=0){return 0;}
G4double a_ldpar=ainf_ldpar*(1.+dW_ldpar/Uval*(1.-std::exp(-gamma_ldpar*Uval)));
if(LDType==3){
a_ldpar=ainf_ldpar;
}
return std::sqrt(Uval/a_ldpar);
}
//Gilbert-Cameron:
G4double G4NuDEXLevelDensity::GetLevelDensity(G4double ExcEnergy,G4double spin,G4bool ,G4bool TotalLevelDensity){
if(!HasData){
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
//If A_Int even/odd --> spinx2 (spin_val*2) should be even/odd
if(((A_Int+(G4int)(spin*2+0.01))%2)!=0 && (TotalLevelDensity==false)){
return 0;
}
G4double Uval=ExcEnergy-Delta_ldpar;
if(Uval<0){Uval=1.e-6;}
//----------------------------------------------------------------
// Back shifted: von Egidy et al., NP A481 (1988) 189
if(LDType==3){
G4double sig2=0.0888*std::pow(A_mass,2./3.)*std::sqrt(ainf_ldpar*Uval);
G4double sig=std::sqrt(sig2);
G4double rho=0.05893*std::exp(2.*std::sqrt(ainf_ldpar*Uval))/sig/std::pow(ainf_ldpar,0.25)/std::pow(Uval,1.25);
G4double xj2=(spin+0.5)*(spin+0.5);
G4double fj=(2.*spin+1.)/2./sig2*std::exp(-xj2/2./sig2);
return 0.5*fj*rho;
}
//----------------------------------------------------------------
//--------------------------------------------------------------------------------
//statistical factor from eq. 39 of RIPL-3 manual, and sigma2 from eqs. 57-60
G4double Uval_Sn=Sn-Delta_ldpar;
G4double a_ldpar=ainf_ldpar*(1.+dW_ldpar/Uval*(1.-std::exp(-gamma_ldpar*Uval)));
G4double a_ldpar_Sn=ainf_ldpar*(1.+dW_ldpar/Uval_Sn*(1.-std::exp(-gamma_ldpar*Uval_Sn)));
G4double sigma2_f=0.01389*std::pow(A_mass,5./3.)/ainf_ldpar*std::sqrt(a_ldpar*Uval);
G4double sigma2_f_Sn=0.01389*std::pow(A_mass,5./3.)/ainf_ldpar*std::sqrt(a_ldpar_Sn*Uval);
G4double sigma2_d=(0.83*std::pow(A_mass,0.26))*(0.83*std::pow(A_mass,0.26));
G4double sigma2;
if(ExcEnergy<=Ed){
sigma2=sigma2_d;//if ExcEnergy<Ed
}
else if(ExcEnergy<=Sn){
sigma2=sigma2_d+(ExcEnergy-Ed)/(Sn-Ed)*(sigma2_f_Sn-sigma2_d);
}
else{
sigma2=sigma2_f;
}
G4double statfactor=1./2.*(2.*spin+1.)/(2.*sigma2)*std::exp(-(spin+1/2.)*(spin+1/2.)/2./sigma2);
if(TotalLevelDensity==true){
statfactor=1;
}
//--------------------------------------------------------------------------------
//CT + BSFG: Gilbert & Cameron, Can.J.Phys. 43 (1965) 1446
if(LDType==2 && ExcEnergy<Ex_ldpar){
G4double totalrho=std::exp((ExcEnergy-E0_ldpar)/T_ldpar)/T_ldpar;
return totalrho*statfactor;
}
//Else: BSFGM (LDType==1 or ExcEnergy>Ex_ldpar)
G4double rhotot_f=1./std::sqrt(2.*sigma2)/12.*std::exp(2.*std::sqrt(a_ldpar*Uval))/std::pow(a_ldpar,1./4.)/std::pow(Uval,5./4.);
G4double rhotot_0=std::exp(1.)*a_ldpar/12./std::sqrt(sigma2)*std::exp(a_ldpar*Uval);
G4double totalrho=1./(1./rhotot_f+1./rhotot_0);
return totalrho*statfactor;
}
G4double G4NuDEXLevelDensity::EstimateInverse(G4double LevDen_iMeV,G4double spin,G4bool parity){
//We assume that rho is a monotonically increasing function
G4double tolerance=0.001; //the result will have this relative tolerance. 0.01 means 1%
G4double xmin=0;
G4double xmax=1;
while(GetLevelDensity(xmax,spin,parity)<LevDen_iMeV){
xmax*=2;
}
while(xmin/xmax<1-tolerance){
G4double x0=(xmin+xmax)/2.;
if(GetLevelDensity(x0,spin,parity)<LevDen_iMeV){
xmin=x0;
}
else{
xmax=x0;
}
}
return (xmin+xmax)/2.;
}
G4double G4NuDEXLevelDensity::Integrate(G4double Emin,G4double Emax,G4double spin,G4bool parity){
G4int nb=1000;
G4double Integral=0,x1,x2,y1,y2;
for(G4int i=0;i<nb;i++){
x1=Emin+(Emax-Emin)*i/(G4double)(nb-1.);
x2=Emin+(Emax-Emin)*(i+1.)/(G4double)(nb-1.);
y1=GetLevelDensity(x1,spin,parity);
y2=GetLevelDensity(x2,spin,parity);
Integral+=(y1+y2)/2.*(x2-x1);
}
return Integral;
}
void G4NuDEXLevelDensity::PrintParameters(std::ostream &out){
out<<" Level density type: "<<LDType<<std::endl;
if(LDType==1){ // Back-Shifted-Fermi-Gas model
out<<" ainf = "<<ainf_ldpar<<" gamma = "<<gamma_ldpar<<" dW = "<<dW_ldpar<<" Delta = "<<Delta_ldpar<<std::endl;
}
else{
out<<" ainf = "<<ainf_ldpar<<" gamma = "<<gamma_ldpar<<" dW = "<<dW_ldpar<<" Delta = "<<Delta_ldpar<<" T = "<<T_ldpar<<" E0 = "<<E0_ldpar<<" Ex = "<<Ex_ldpar<<std::endl;
}
}
@@ -0,0 +1,351 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 source file
//
// File name: G4NuDEXNeutronCaptureModel
//
// Author: E.Mendoza & A.Ribon
//
// Creation date: 29 May 2024
//
// Description: This class (a proxy of the class G4NuDEX) uses
// the NuDEX model to produce gammas and internal
// conversion electrons from neutron capture.
// Whenever NuDEX is not applicable, G4PhotonEvaporation
// is used.
// The implementation of this class follows the code
// of the class G4NeutronRadCapture.
//
// Modifications:
//
// -------------------------------------------------------------------
//
#include "G4NuDEXNeutronCaptureModel.hh"
#include "G4NuDEXStatisticalNucleus.hh"
#include "Randomize.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
#include "G4LorentzVector.hh"
#include "G4Gamma.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
#include "G4Deuteron.hh"
#include "G4Triton.hh"
#include "G4He3.hh"
#include "G4Alpha.hh"
#include "G4NucleiProperties.hh"
#include "G4IonTable.hh"
#include "G4ParticleTable.hh"
#include "G4HadronicParameters.hh"
#include "G4DeexPrecoParameters.hh"
#include "G4NuclearLevelData.hh"
#include "G4PhotonEvaporation.hh"
#include "G4PhysicsModelCatalog.hh"
G4NuDEXNeutronCaptureModel::G4NuDEXNeutronCaptureModel() : G4HadronicInteraction( "nuDEX_neutronCapture" ) {
for ( G4int i = 0; i < G4NUDEX_MAXZA; i++ ) {
theStatisticalNucleus[i] = nullptr;
HasData[i] = 0;
}
BrOption = -1;
BandWidth = 0;
NuDEXLibDirectory = "";
photonEvaporation = nullptr;
auto ch = G4FindDataDir( "G4NUDEXLIBDATA" );
if ( ch == nullptr ) {
G4Exception( "G4NuDEXNeutronCaptureModel()", "had0707", FatalException, "Environment variable G4NUDEXLIBDATA is not defined" );
} else {
NuDEXLibDirectory = G4String(ch);
}
}
void G4NuDEXNeutronCaptureModel::InitialiseModel() {
if ( photonEvaporation != nullptr ) return;
G4DeexPrecoParameters* param = G4NuclearLevelData::GetInstance()->GetParameters();
minExcitation = param->GetMinExcitation();
photonEvaporation = new G4PhotonEvaporation;
photonEvaporation->Initialise();
photonEvaporation->SetICM( true );
secID = G4PhysicsModelCatalog::GetModelID( "model_" + GetModelName() );
lowestEnergyLimit = 10.0*CLHEP::eV;
minExcitation = 0.1*CLHEP::keV;
}
G4NuDEXNeutronCaptureModel::~G4NuDEXNeutronCaptureModel(){
for ( G4int i = 0; i < G4NUDEX_MAXZA; i++ ) {
if ( theStatisticalNucleus[i] ) delete theStatisticalNucleus[i];
}
}
G4HadFinalState* G4NuDEXNeutronCaptureModel::ApplyYourself( const G4HadProjectile &aTrack, G4Nucleus &theNucleus ) {
theParticleChange.Clear();
theParticleChange.SetStatusChange( stopAndKill );
G4int A = theNucleus.GetA_asInt();
G4int Z = theNucleus.GetZ_asInt();
G4double time = aTrack.GetGlobalTime(); // Time in the lab frame
// Create initial state
G4LorentzVector lab4mom( 0.0, 0.0, 0.0, G4NucleiProperties::GetNuclearMass(A, Z) );
lab4mom += aTrack.Get4Momentum();
G4double systemMass = lab4mom.mag();
++A; // Compound nucleus: target nucleus + neutron
G4double compoundMass = G4NucleiProperties::GetNuclearMass(A, Z);
// If the energy available is to small to do anything interesting, gives up
if ( systemMass - compoundMass <= lowestEnergyLimit ) return &theParticleChange;
G4ThreeVector boostFromCMtoLAB = lab4mom.boostVector();
G4double neutronEnergy = aTrack.GetKineticEnergy();
// Try to apply NuDEX
//G4int lspin = 0; // l-spin = 0, 1, 2 --> s-wave, p-wave, d-wave ...
//G4int jspinx2 = -1; // A negative value of jspinx2 means that is sampled according to the 2J+1 rule.
//G4int initialLevel = SelectInitialLevel( Z, A, neutronEnergy, lspin, jspinx2 );
G4int initialLevel = -1; // thermal neutron capture
std::vector< char > pType;
std::vector< G4double > pEnergy, pTime;
G4int npar = GenerateNeutronCaptureCascade( Z, A, neutronEnergy, initialLevel, pType, pEnergy, pTime );
if ( npar > 0 ) { // NuDEX can be applied
G4LorentzVector remainingLab4mom = lab4mom;
G4double latestEmission = time;
// Loop over the EM particles produced by 'GenerateNeutronCaptureCascade' and add them to the
// theParticleChange as secondaries. These particles are produced by NuDEX in the nucleus' rest-frame.
for ( G4int i = 0; i < npar; i++ ) {
G4ParticleDefinition* particleDef = nullptr;
if ( pType.at(i) == 'g' ) {
particleDef = G4Gamma::Definition();
} else if (pType.at(i) == 'e' ) {
particleDef = G4Electron::Definition();
} else if ( pType.at(i) == 'p' ) {
particleDef = G4Positron::Definition();
} else {
G4Exception( "G4NUDEXNeutronCaptureModel::ApplyYourself()", "had0707", FatalException, "Unknown particle type" );
}
G4double phi = G4UniformRand()*twopi;
G4double costheta = 2.0*G4UniformRand() - 1.0;
G4double sintheta = std::sqrt( 1.0 - costheta*costheta );
G4ThreeVector direction( sintheta*std::cos(phi), sintheta*std::sin(phi), costheta );
G4double mass = particleDef->GetPDGMass();
G4double particle3momMod = std::sqrt( pEnergy.at(i) * ( pEnergy.at(i) + 2.0*mass ) );
G4LorentzVector particle4mom( particle3momMod*direction, mass + pEnergy.at(i) ); // In the center-of-mass frame
particle4mom.boost( boostFromCMtoLAB ); // Now in the Lab frame
G4HadSecondary* secondary = new G4HadSecondary( new G4DynamicParticle( particleDef, particle4mom ) );
remainingLab4mom -= particle4mom;
// For simplicity, we neglect below the different frames of time (Lab) and pTime (center-of-mass)
secondary->SetTime( time + pTime.at(i) );
if ( latestEmission < time + pTime.at(i) ) latestEmission = time + pTime.at(i);
secondary->SetCreatorModelID( secID );
theParticleChange.AddSecondary( *secondary );
delete secondary;
}
// Treat now the residual nucleus (which is neglected by NuDEX)
const G4ParticleDefinition* resNuclDef = nullptr;
if ( Z == 1 && A == 2 ) resNuclDef = G4Deuteron::Definition();
else if ( Z == 1 && A == 3 ) resNuclDef = G4Triton::Definition();
else if ( Z == 2 && A == 3 ) resNuclDef = G4He3::Definition();
else if ( Z == 2 && A == 4 ) resNuclDef = G4Alpha::Alpha();
else resNuclDef = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon( Z, A, 0.0, noFloat, 0 );
if ( resNuclDef ) {
// To conserve energy-momentum, remainingLab4mom should be the Lorentz 4-momentum of the residual nucleus.
// Imposing the mass 'compoundMass' to the residual nucleus, and trying to conserve the total energy
// while keeping as low as possible the violation of the 3-momentum; in the case that the total energy
// cannot be conserved, the residual nucleus is produced at rest (in the Lab frame).
G4double resNuclLabEkin = std::max( remainingLab4mom.e() - compoundMass, 0.0 );
G4double resNuclLab3momMod = 0.0;
G4ThreeVector resNuclLabDir( 0.0, 0.0, 0.0 );
if ( resNuclLabEkin > 0.0 ) {
resNuclLab3momMod = std::sqrt( resNuclLabEkin * ( resNuclLabEkin + 2.0*compoundMass ) );
resNuclLabDir = remainingLab4mom.vect().unit();
}
G4LorentzVector resNuclLab4mom( resNuclLab3momMod*resNuclLabDir, resNuclLabEkin + compoundMass );
G4HadSecondary* secondary = new G4HadSecondary( new G4DynamicParticle( resNuclDef, resNuclLab4mom ) );
secondary->SetTime( latestEmission );
secondary->SetCreatorModelID( secID );
theParticleChange.AddSecondary( *secondary );
delete secondary;
}
} else { // NuDEX cannot be applied: use G4PhotonEvaporation
// Code taken from G4NeutronRadCapture
G4Fragment* aFragment = new G4Fragment( A, Z, lab4mom );
G4FragmentVector* fv = photonEvaporation->BreakUpFragment( aFragment );
if ( fv == nullptr ) fv = new G4FragmentVector;
fv->push_back( aFragment );
size_t n = fv->size();
for ( size_t i = 0; i < n; ++i ) {
G4Fragment* f = (*fv)[i];
G4double etot = f->GetMomentum().e();
Z = f->GetZ_asInt();
A = f->GetA_asInt();
const G4ParticleDefinition* theDef = nullptr;
if ( Z == 0 && A == 0 ) { theDef = f->GetParticleDefinition(); }
else if ( Z == 1 && A == 2 ) { theDef = G4Deuteron::Definition(); }
else if ( Z == 1 && A == 3 ) { theDef = G4Triton::Definition(); }
else if ( Z == 2 && A == 3 ) { theDef = G4He3::Definition(); }
else if ( Z == 2 && A == 4 ) { theDef = G4Alpha::Definition(); }
else {
G4double eexc = f->GetExcitationEnergy();
if ( eexc <= minExcitation ) eexc = 0.0;
theDef = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon( Z, A, eexc, noFloat, 0 );
}
G4double ekin = std::max( 0.0, etot - theDef->GetPDGMass() );
G4HadSecondary* news = new G4HadSecondary( new G4DynamicParticle( theDef, f->GetMomentum().vect().unit(), ekin ) );
G4double timeF = f->GetCreationTime();
if ( timeF < 0.0 ) timeF = 0.0;
news->SetTime( time + timeF );
news->SetCreatorModelID( secID );
theParticleChange.AddSecondary( *news );
delete news;
delete f;
}
delete fv;
}
return &theParticleChange;
}
G4int G4NuDEXNeutronCaptureModel::GenerateNeutronCaptureCascade( G4int theZ, G4int theA, G4double NeutronEnergy, G4int InitialLevel,
std::vector< char >& pType, std::vector< G4double >& pEnergy,
std::vector< G4double >& pTime ) {
// Returns the number of emitted particles. Returns -1 if the nucleus is not in the database.
G4int theZA = 1000*theZ + theA;
G4int check = Init( theZA );
if ( check < 0 ) return -1;
G4double Sn, I0;
theStatisticalNucleus[theZA]->GetSnAndI0( Sn, I0 ); Sn *= MeV; // I0 is the spin of the A-1 nucleus in the g.s.
G4double ExcitationEnergy = Sn + (theA-1.0)/(G4double)theA*NeutronEnergy;
G4int nPar = theStatisticalNucleus[theZA]->GenerateCascade( InitialLevel, ExcitationEnergy/MeV, pType, pEnergy, pTime );
for ( G4int i = 0; i < nPar; i++ ) {
pEnergy.at(i) *= MeV;
pTime.at(i) *= s;
}
return nPar;
}
G4int G4NuDEXNeutronCaptureModel::Init( G4int theZA, unsigned int seed1, unsigned int seed2, unsigned int seed3 ) {
if ( HasData[theZA] == -1 ) return -1;
if ( HasData[theZA] == 1 ) return 0;
if ( theStatisticalNucleus[theZA] == 0 ) {
G4int theZ = theZA/1000;
G4int theA = theZA-1000*theZ;
theStatisticalNucleus[theZA] = new G4NuDEXStatisticalNucleus( theZ, theA );
if ( BandWidth != 0 ) theStatisticalNucleus[theZA]->SetBandWidth( BandWidth );
theStatisticalNucleus[theZA]->SetBrOption( BrOption );
if ( seed1 > 0 ) theStatisticalNucleus[theZA]->SetRandom1Seed( seed1 );
if ( seed2 > 0 ) theStatisticalNucleus[theZA]->SetRandom1Seed( seed2 );
if ( seed3 > 0 ) theStatisticalNucleus[theZA]->SetRandom1Seed( seed3 );
G4int check = theStatisticalNucleus[theZA]->Init( NuDEXLibDirectory.c_str() );
if ( check < 0 ) {
HasData[theZA] = -1;
return -1;
} else {
HasData[theZA] = 1;
}
}
return 0;
}
G4int G4NuDEXNeutronCaptureModel::SelectInitialLevel( G4int theCompoundZ, G4int theCompoundA, G4double NeutronEnergy, G4int lspin, G4int jspinx2 ) {
// Initial level for neutron capture. If jspinx2 < 0 it is sampled according to the 2J+1 rule.
// l-spin = 0, 1, 2 --> s-wave, p-wave, d-wave ...
G4int theZ = theCompoundZ;
G4int theA = theCompoundA;
G4int theZA = 1000*theZ + theA;
G4int check = Init( theZA );
if ( check < 0 ) return -1;
G4double Sn, I0;
theStatisticalNucleus[theZA]->GetSnAndI0( Sn, I0 ); Sn *= MeV; // I0 is the spin of the A-1 nucleus in the g.s.
G4double ExcitationEnergy = Sn + (theA-1.0)/(G4double)theA*NeutronEnergy;
if ( lspin < 0 ) lspin = 0;
if ( jspinx2 < 0 ) jspinx2 = SampleJ( theZ, theA, lspin );
G4bool parity = false;
if ( ( I0 >= 0 && (lspin%2) == 0 ) || ( I0 < 0 && (lspin%2) == 1 ) ) parity = true;
G4int InitialLevel = theStatisticalNucleus[theZA]->GetClosestLevel( ExcitationEnergy/MeV, jspinx2, parity );
return InitialLevel;
}
G4int G4NuDEXNeutronCaptureModel ::SampleJ( G4int theCompoundZ, G4int theCompoundA, G4int lspin ) {
// Samples J for this l-spin (l-spin = 0, 1, 2 --> s-wave, p-wave, d-wave ...)
// The probability will be proportional to 2J+1
// Returns Jx2
G4int AllowedJx2[100];
G4int NAllowedJvals = GetAllowedJx2values( theCompoundZ, theCompoundA, lspin, AllowedJx2 );
G4double AllowedJx2CumulProb[100], TotalCumul = 0.0;
for ( G4int i = 0; i < NAllowedJvals; i++ ) {
AllowedJx2CumulProb[i] = AllowedJx2[i] + 1.0;
TotalCumul += AllowedJx2CumulProb[i];
}
for ( G4int i = 0; i < NAllowedJvals; i++ ) {
AllowedJx2CumulProb[i] /= TotalCumul;
if ( i > 0 ) AllowedJx2CumulProb[i] += AllowedJx2CumulProb[i-1];
}
G4double rand = G4UniformRand();
G4int i_result = -1;
for ( G4int i = 0; i < NAllowedJvals; i++ ) {
if ( rand < AllowedJx2CumulProb[i] ) {
i_result = i; break;
}
}
if ( i_result < 0 ) {
G4cerr << " ############ Error in " << __FILE__ << ", line " << __LINE__ << " ############"<< G4endl;
exit(1);
}
G4int jspinx2 = AllowedJx2[i_result];
return jspinx2;
}
G4int G4NuDEXNeutronCaptureModel::GetAllowedJx2values( G4int theCompoundZ, G4int theCompoundA, G4int lspin, G4int* jx2vals ) {
// Provides the allowed jx2 values in neutron capture for a certain l-spin (l-spin = 0, 1, 2 --> s-wave, p-wave, d-wave ...)
G4int theZA = 1000*theCompoundZ + theCompoundA;
G4int check = Init( theZA );
if ( check < 0 ) return -1;
G4double Sn, I0;
theStatisticalNucleus[theZA]->GetSnAndI0( Sn, I0 ); Sn *= MeV; // I0 is the spin of the A-1 nucleus in the g.s.
G4int Ix2 = (G4int)( ( std::fabs(I0) + 0.1 )*2.0 );
G4int Jx2min = std::min( std::abs( Ix2-1-2*lspin ), std::abs( Ix2+1-2*lspin ) );
G4int Jx2max = Ix2 + 1 + 2*lspin;
G4int NAllowedJvals = 0;
for ( G4int Jx2 = Jx2min; Jx2 <= Jx2max; Jx2 += 2 ) {
if ( Jx2 >= 0 ) {
jx2vals[NAllowedJvals] = Jx2;
NAllowedJvals++;
}
}
return NAllowedJvals;
}
@@ -0,0 +1,942 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Author: E.Mendoza
//
// Creation date: May 2024
//
// Modifications:
//
// -------------------------------------------------------------------
//
// NuDEX code (https://doi.org/10.1016/j.nima.2022.167894)
//
#include "G4NuDEXRandom.hh"
#include "G4NuDEXLevelDensity.hh"
#include "G4NuDEXPSF.hh"
G4NuDEXPSF::G4NuDEXPSF(G4int aZ,G4int aA){
Z_Int=aZ;
A_Int=aA;
nR_E1=0; nR_M1=0; nR_E2=0;
x_E1=0; y_E1=0;
x_M1=0; y_M1=0;
x_E2=0; y_E2=0;
E1_normFac=-1; M1_normFac=-1; E2_normFac=-1;
NormEmin=0; NormEmax=6; //Integral between 0 and 6 MeV
ScaleFactor_E1=1;
ScaleFactor_M1=1;
ScaleFactor_E2=1;
}
G4NuDEXPSF::~G4NuDEXPSF(){
if(x_E1!=0){delete [] x_E1;}
if(y_E1!=0){delete [] y_E1;}
if(x_M1!=0){delete [] x_M1;}
if(y_M1!=0){delete [] y_M1;}
if(x_E2!=0){delete [] x_E2;}
if(y_E2!=0){delete [] y_E2;}
}
//If inputfname!=0 then we take the PSF data from the inputfname instead of the dirname
G4int G4NuDEXPSF::Init(const char* dirname,G4NuDEXLevelDensity* aLD,const char* inputfname,const char* defaultinputfname,G4int PSFflag){
theLD=aLD;
//Three options: very detailed model, if not --> gdr-parameters&errors-exp-MLO.dat (RIPL-3), if not --> theorethical values
char fname[500];
G4bool IsDone=false;
//input:
if(inputfname!=0){
IsDone=TakePSFFromInputFile(inputfname);
if(IsDone){return 0;}
}
//default input:
if(defaultinputfname!=0){
IsDone=TakePSFFromInputFile(defaultinputfname);
if(IsDone){return 0;}
}
//Detailed model
snprintf(fname,500,"%s/PSF/PSF_param.dat",dirname);
IsDone=TakePSFFromDetailedParFile(fname);
if(IsDone){return 0;}
//IAEA - 2019 values:
if(PSFflag==0){
snprintf(fname,500,"%s/PSF/CRP_IAEA_SMLO_E1_v01.dat",dirname);
IsDone=TakePSFFromIAEA01(fname);
if(IsDone){return 0;}
}
else if(PSFflag!=1){
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
//RIPL-MLO values:
snprintf(fname,500,"%s/PSF/gdr-parameters&errors-exp-MLO.dat",dirname);
IsDone=TakePSFFromRIPL01(fname);
if(IsDone){return 0;}
//RIPL-Theorethical values:
snprintf(fname,500,"%s/PSF/gdr-parameters-theor.dat",dirname);
IsDone=TakePSFFromRIPL02(fname);
if(IsDone){return 0;}
//Theorethical values:
// E1 for spherical nucleus:
nR_E1=0;
PSFType_E1[nR_E1]=2;
//G4double a=31.2,b=20.6,c=0.026,d=1.05; //SLO-old (RIPL-2)
//G4double a=27.47,b=22.063,c=0.0277,d=1.222;//SLO (RIPL-3)
G4double a=28.69,b=21.731,c=0.0285,d=1.267;//MLO (RIPL-3)
E_E1[nR_E1]=a*std::pow(A_Int,-1./3.)+b*std::pow(A_Int,-1./6.);
G_E1[nR_E1]=c*std::pow(E_E1[nR_E1],1.9);
s_E1[nR_E1]=120/3.141592*d*(A_Int-Z_Int)*Z_Int/(G4double)A_Int/G_E1[nR_E1];
nR_E1++;
GenerateM1AndE2FromE1();
return 0;
}
void G4NuDEXPSF::GenerateM1AndE2FromE1(){
//M1:
nR_M1=0;
E_M1[nR_M1]=41*std::pow(A_Int,-1./3.);
G_M1[nR_M1]=4;
s_M1[nR_M1]=1;
PSFType_M1[nR_M1]=0;
nR_M1++;
//f(E1)/f(M1) = 0.0588*A**0.878 at +-7 MeV
G4double fE1=GetE1(7,7);
G4double fM1=GetM1(7,7);
s_M1[0]=fE1/0.0588/std::pow(A_Int,0.878)/fM1;
//E2:
nR_E2=0;
E_E2[nR_E2]=63*std::pow(A_Int,-1./3.);
G_E2[nR_E2]=6.11-0.021*A_Int;
s_E2[nR_E2]=0.00014*Z_Int*Z_Int*E_E2[nR_E2]/std::pow(A_Int,1./3)/G_E2[nR_E2];
PSFType_E2[nR_E2]=0;
nR_E2++;
}
G4bool G4NuDEXPSF::TakePSFFromRIPL02(const char* fname){
G4bool result=false;
G4int aA,aZ;
std::ifstream in(fname);
char dum[200];
for(G4int i=0;i<4;i++){in.ignore(10000,'\n');}
while(in>>aZ>>aA){
if(aZ==Z_Int && aA==A_Int){
result=true;
in>>dum>>dum;
nR_E1=2;
in>>E_E1[0]>>G_E1[0]>>E_E1[1]>>G_E1[1];
PSFType_E1[0]=2; PSFType_E1[1]=2; //SMLO
G4double a=28.69,b=21.731,c=0.0285,d=1.267;//MLO
G4double E_E1_0=a*std::pow(A_Int,-1./3.)+b*std::pow(A_Int,-1./6.);
G4double G_E1_0=c*std::pow(E_E1_0,1.9);
G4double s_E1_0=120/3.141592*d*(A_Int-Z_Int)*Z_Int/(G4double)A_Int/G_E1_0;
s_E1[0]=s_E1_0/3.;
s_E1[1]=2.*s_E1_0/3.;
break;
}
in.ignore(10000,'\n');
}
in.close();
if(result){GenerateM1AndE2FromE1();}
return result;
}
G4bool G4NuDEXPSF::TakePSFFromRIPL01(const char* fname){
G4bool result=false;
G4int aA,aZ;
std::ifstream in(fname);
char dum[200];
for(G4int i=0;i<7;i++){in.ignore(10000,'\n');}
while(in>>aZ>>aA){
if(aZ==Z_Int && aA==A_Int){
result=true;
in>>dum>>dum;
nR_E1=0;
in>>E_E1[nR_E1]>>s_E1[nR_E1]>>G_E1[nR_E1];
PSFType_E1[nR_E1]=2; //SMLO
nR_E1++;
//sometimes there is a second resonance:
in>>E_E1[nR_E1]>>dum>>G_E1[nR_E1];
if(dum[0]!='-'){ //there is a second resonance
s_E1[nR_E1]=std::atof(dum);
PSFType_E1[nR_E1]=2;
nR_E1++;
}
break;
}
in.ignore(10000,'\n');
}
in.close();
if(result){GenerateM1AndE2FromE1();}
return result;
}
G4bool G4NuDEXPSF::TakePSFFromIAEA01(const char* fname){
G4bool result=false;
G4int aA,aZ;
char dum[200];
G4double beta=0;
std::ifstream in(fname);
while(in>>aZ>>aA){
if(aZ==Z_Int && aA==A_Int){
result=true;
nR_E1=0;
in>>dum>>dum>>E_E1[nR_E1]>>dum>>dum>>G_E1[nR_E1]>>dum>>dum>>s_E1[nR_E1];
PSFType_E1[nR_E1]=11;
nR_E1++;
in>>dum;
if(std::string(dum)==std::string("beta=")){
in>>beta;
break;
}
else if(std::string(dum)==std::string("Er2")){
in>>dum>>E_E1[nR_E1]>>dum>>dum>>G_E1[nR_E1]>>dum>>dum>>s_E1[nR_E1]>>dum>>beta;
PSFType_E1[nR_E1]=11;
nR_E1++;
}
else{
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
break;
}
in.ignore(10000,'\n');
}
if(!result){
return result;
}
//---------------------------------------------------
//Now M1 (https://doi.org/10.1140/epja/i2019-12840-1)
nR_M1=0;
//Spin-flip:
PSFType_M1[nR_M1]=0;
E_M1[nR_M1]=18.0*std::pow(A_Int,-1./6.);
G_M1[nR_M1]=4;
s_M1[nR_M1]=0.03*std::pow(A_Int,5./6.);
nR_M1++;
//Scissors-mode:
PSFType_M1[nR_M1]=0;
E_M1[nR_M1]=5.0*std::pow(A_Int,-1./10.);
G_M1[nR_M1]=1.5;
s_M1[nR_M1]=0.02*std::fabs(beta)*std::pow(A_Int,9./10.);
nR_M1++;
//upbend:
PSFType_M1[nR_M1]=21;
E_M1[nR_M1]=0.4035*std::exp(-6.0*std::fabs(beta));
G_M1[nR_M1]=0.8;
s_M1[nR_M1]=0;
nR_M1++;
//---------------------------------------------------
//---------------------------------------------------
//E2 same as in the old RIPL recommendations:
nR_E2=0;
E_E2[nR_E2]=63*std::pow(A_Int,-1./3.);
G_E2[nR_E2]=6.11-0.021*A_Int;
s_E2[nR_E2]=0.00014*Z_Int*Z_Int*E_E2[nR_E2]/std::pow(A_Int,1./3)/G_E2[nR_E2];
PSFType_E2[nR_E2]=0;
nR_E2++;
//---------------------------------------------------
return result;
}
G4bool G4NuDEXPSF::TakePSFFromInputFile(const char* fname){
G4bool result=false;
char word[1000];
std::ifstream in(fname);
while(in>>word){
if(word[0]=='#'){in.ignore(10000,'\n');}
if(std::string(word)==std::string("END")){break;}
if(std::string(word)==std::string("PSF")){
result=true;
in>>nR_E1;
for(G4int i=0;i<nR_E1;i++){
in>>PSFType_E1[i]>>E_E1[i]>>G_E1[i]>>s_E1[i];
if(PSFType_E1[i]==7){in>>p1_E1[i];}
if(PSFType_E1[i]==8){in>>p1_E1[i]>>p2_E1[i];}
if(PSFType_E1[i]==9){in>>p1_E1[i]>>p2_E1[i];}
if(PSFType_E1[i]==10){in>>p1_E1[i]>>p2_E1[i]>>p3_E1[i];}
if(PSFType_E1[i]==40 || PSFType_E1[i]==41){ //only one pointwise function is allowed
if(x_E1!=0){NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");}
in>>np_E1;
x_E1=new G4double[np_E1]; y_E1=new G4double[np_E1];
for(G4int j=0;j<np_E1;j++){in>>x_E1[j]>>y_E1[j];}
in>>E1_normFac;
}
}
in>>nR_M1;
for(G4int i=0;i<nR_M1;i++){
in>>PSFType_M1[i]>>E_M1[i]>>G_M1[i]>>s_M1[i];
if(PSFType_M1[i]==7){in>>p1_M1[i];}
if(PSFType_M1[i]==8){in>>p1_M1[i]>>p2_M1[i];}
if(PSFType_M1[i]==9){in>>p1_M1[i]>>p2_M1[i];}
if(PSFType_M1[i]==10){in>>p1_M1[i]>>p2_M1[i]>>p3_M1[i];}
if(PSFType_M1[i]==40 || PSFType_M1[i]==41){//only one pointwise function is allowed
if(x_M1!=0){NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");}
in>>np_M1;
x_M1=new G4double[np_M1]; y_M1=new G4double[np_M1];
for(G4int j=0;j<np_M1;j++){in>>x_M1[j]>>y_M1[j];}
in>>M1_normFac;
}
}
in>>nR_E2;
for(G4int i=0;i<nR_E2;i++){
in>>PSFType_E2[i]>>E_E2[i]>>G_E2[i]>>s_E2[i];
if(PSFType_E2[i]==7){in>>p1_E2[i];}
if(PSFType_E2[i]==8){in>>p1_E2[i]>>p2_E2[i];}
if(PSFType_E2[i]==9){in>>p1_E2[i]>>p2_E2[i];}
if(PSFType_E2[i]==10){in>>p1_E2[i]>>p2_E2[i]>>p3_E2[i];}
if(PSFType_E2[i]==40 || PSFType_E2[i]==41){//only one pointwise function is allowed
if(x_E2!=0){NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");}
in>>np_E2;
x_E2=new G4double[np_E2]; y_E2=new G4double[np_E2];
for(G4int j=0;j<np_E2;j++){in>>x_E2[j]>>y_E2[j];}
in>>E2_normFac;
}
}
break;
}
}
Renormalize(); // if XX_normFac>0 --> renormalization of the PSF
return result;
}
void G4NuDEXPSF::Renormalize(){
G4int npIntegral=1000;
G4double Integral=0,x_eval,y_eval;
G4double binWidth=(NormEmax-NormEmin)/npIntegral;
//-------------------------------------------------
if(E1_normFac>0){
Integral=0;
for(G4int i=0;i<npIntegral;i++){
x_eval=NormEmin+binWidth*(i+0.5);
y_eval=GetE1(x_eval,NormEmax);
Integral+=y_eval;
}
Integral*=binWidth;
ScaleFactor_E1=E1_normFac/Integral;
}
//-------------------------------------------------
//-------------------------------------------------
if(M1_normFac>0){
Integral=0;
for(G4int i=0;i<npIntegral;i++){
x_eval=NormEmin+binWidth*(i+0.5);
y_eval=GetM1(x_eval,NormEmax);
Integral+=y_eval;
}
Integral*=binWidth;
ScaleFactor_M1=M1_normFac/Integral;
//std::cout<<M1_normFac<<" "<<Integral<<" "<<ScaleFactor_M1<<std::endl; getchar();
}
//-------------------------------------------------
//-------------------------------------------------
if(E2_normFac>0){
Integral=0;
for(G4int i=0;i<npIntegral;i++){
x_eval=NormEmin+binWidth*(i+0.5);
y_eval=GetE2(x_eval,NormEmax);
Integral+=y_eval;
}
Integral*=binWidth;
ScaleFactor_E2=E2_normFac/Integral;
}
//-------------------------------------------------
}
G4bool G4NuDEXPSF::TakePSFFromDetailedParFile(const char* fname){
G4bool result=false;
G4int aA,aZ;
std::ifstream in(fname);
while(in>>aZ>>aA){
if(aZ==Z_Int && aA==A_Int){
result=true;
in>>nR_E1;
for(G4int i=0;i<nR_E1;i++){
in>>PSFType_E1[i]>>E_E1[i]>>G_E1[i]>>s_E1[i];
if(PSFType_E1[i]==7){in>>p1_E1[i];}
if(PSFType_E1[i]==8){in>>p1_E1[i]>>p2_E1[i];}
if(PSFType_E1[i]==9){in>>p1_E1[i]>>p2_E1[i];}
if(PSFType_E1[i]==10){in>>p1_E1[i]>>p2_E1[i]>>p3_E1[i];}
}
in>>nR_M1;
for(G4int i=0;i<nR_M1;i++){
in>>PSFType_M1[i]>>E_M1[i]>>G_M1[i]>>s_M1[i];
if(PSFType_M1[i]==7){in>>p1_M1[i];}
if(PSFType_M1[i]==8){in>>p1_M1[i]>>p2_M1[i];}
if(PSFType_M1[i]==9){in>>p1_M1[i]>>p2_M1[i];}
if(PSFType_M1[i]==10){in>>p1_M1[i]>>p2_M1[i]>>p3_M1[i];}
}
in>>nR_E2;
for(G4int i=0;i<nR_E2;i++){
in>>PSFType_E2[i]>>E_E2[i]>>G_E2[i]>>s_E2[i];
if(PSFType_E2[i]==7){in>>p1_E2[i];}
if(PSFType_E2[i]==8){in>>p1_E2[i]>>p2_E2[i];}
if(PSFType_E2[i]==9){in>>p1_E2[i]>>p2_E2[i];}
if(PSFType_E2[i]==10){in>>p1_E2[i]>>p2_E2[i]>>p3_E2[i];}
}
break;
}
in.ignore(10000,'\n');
}
in.close();
return result;
}
G4double G4NuDEXPSF::GetE1(G4double Eg,G4double ExcitationEnergy){
G4double result=0;
for(G4int i=0;i<nR_E1;i++){
if(PSFType_E1[i]==0){
result+=8.674E-8*SLO(Eg,E_E1[i],G_E1[i],s_E1[i]);
}
else if(PSFType_E1[i]==1){
result+=8.674E-8*EGLO(Eg,E_E1[i],G_E1[i],s_E1[i],ExcitationEnergy);
}
else if(PSFType_E1[i]==2){
result+=8.674E-8*SMLO(Eg,E_E1[i],G_E1[i],s_E1[i],ExcitationEnergy);
}
else if(PSFType_E1[i]==3){
result+=8.674E-8*GLO(Eg,E_E1[i],G_E1[i],s_E1[i],ExcitationEnergy);
}
else if(PSFType_E1[i]==4){
result+=8.674E-8*MGLO(Eg,E_E1[i],G_E1[i],s_E1[i],ExcitationEnergy);
}
else if(PSFType_E1[i]==5){
result+=8.674E-8*KMF(Eg,E_E1[i],G_E1[i],s_E1[i],ExcitationEnergy);
}
else if(PSFType_E1[i]==6){
result+=8.674E-8*GH(Eg,E_E1[i],G_E1[i],s_E1[i],ExcitationEnergy);
}
else if(PSFType_E1[i]==7){
result+=8.674E-8*MEGLO(Eg,E_E1[i],G_E1[i],s_E1[i],ExcitationEnergy,p1_E1[i],p1_E1[i]);
}
else if(PSFType_E1[i]==8){
result+=8.674E-8*MEGLO(Eg,E_E1[i],G_E1[i],s_E1[i],ExcitationEnergy,p1_E1[i],p2_E1[i]);
}
else if(PSFType_E1[i]==9){
result+=8.674E-8*MEGLO(Eg,E_E1[i],G_E1[i],s_E1[i],ExcitationEnergy,p1_E1[i],p1_E1[i],p2_E1[i]);
}
else if(PSFType_E1[i]==10){
result+=8.674E-8*MEGLO(Eg,E_E1[i],G_E1[i],s_E1[i],ExcitationEnergy,p1_E1[i],p2_E1[i],p3_E1[i]);
}
else if(PSFType_E1[i]==11){
result+=8.674E-8*SMLO_v2(Eg,E_E1[i],G_E1[i],s_E1[i],ExcitationEnergy);
}
else if(PSFType_E1[i]==20){
result+=8.674E-8*Gauss(Eg,E_E1[i],G_E1[i],s_E1[i]);
}
else if(PSFType_E1[i]==21){
result+=8.674E-8*Expo(Eg,E_E1[i],G_E1[i]);
}
else if(PSFType_E1[i]==40){
result+=EvaluateFunction(Eg,np_E1,x_E1,y_E1);
}
else if(PSFType_E1[i]==41){
result+=std::pow(10.,EvaluateFunction(Eg,np_E1,x_E1,y_E1));
}
else{
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
}
if(result!=result){ // nan
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
return result*ScaleFactor_E1;
}
G4double G4NuDEXPSF::GetM1(G4double Eg,G4double ExcitationEnergy){
G4double result=0;
for(G4int i=0;i<nR_M1;i++){
if(PSFType_M1[i]==0){
result+=8.674E-8*SLO(Eg,E_M1[i],G_M1[i],s_M1[i]);
}
else if(PSFType_M1[i]==1){
result+=8.674E-8*EGLO(Eg,E_M1[i],G_M1[i],s_M1[i],ExcitationEnergy);
}
else if(PSFType_M1[i]==2){
result+=8.674E-8*SMLO(Eg,E_M1[i],G_M1[i],s_M1[i],ExcitationEnergy);
}
else if(PSFType_M1[i]==3){
result+=8.674E-8*GLO(Eg,E_M1[i],G_M1[i],s_M1[i],ExcitationEnergy);
}
else if(PSFType_M1[i]==4){
result+=8.674E-8*MGLO(Eg,E_M1[i],G_M1[i],s_M1[i],ExcitationEnergy);
}
else if(PSFType_M1[i]==5){
result+=8.674E-8*KMF(Eg,E_M1[i],G_M1[i],s_M1[i],ExcitationEnergy);
}
else if(PSFType_M1[i]==6){
result+=8.674E-8*GH(Eg,E_M1[i],G_M1[i],s_M1[i],ExcitationEnergy);
}
else if(PSFType_M1[i]==7){
result+=8.674E-8*MEGLO(Eg,E_M1[i],G_M1[i],s_M1[i],ExcitationEnergy,p1_M1[i],p1_M1[i]);
}
else if(PSFType_M1[i]==8){
result+=8.674E-8*MEGLO(Eg,E_M1[i],G_M1[i],s_M1[i],ExcitationEnergy,p1_M1[i],p2_M1[i]);
}
else if(PSFType_M1[i]==9){
result+=8.674E-8*MEGLO(Eg,E_M1[i],G_M1[i],s_M1[i],ExcitationEnergy,p1_M1[i],p1_M1[i],p2_M1[i]);
}
else if(PSFType_M1[i]==10){
result+=8.674E-8*MEGLO(Eg,E_M1[i],G_M1[i],s_M1[i],ExcitationEnergy,p1_M1[i],p2_M1[i],p3_M1[i]);
}
else if(PSFType_M1[i]==11){
result+=8.674E-8*SMLO_v2(Eg,E_M1[i],G_M1[i],s_M1[i],ExcitationEnergy);
}
else if(PSFType_M1[i]==20){
result+=8.674E-8*Gauss(Eg,E_M1[i],G_M1[i],s_M1[i]);
}
else if(PSFType_M1[i]==21){
result+=8.674E-8*Expo(Eg,E_M1[i],G_M1[i]);
}
else if(PSFType_M1[i]==40){
result+=EvaluateFunction(Eg,np_M1,x_M1,y_M1);
}
else if(PSFType_M1[i]==41){
result+=std::pow(10.,EvaluateFunction(Eg,np_M1,x_M1,y_M1));
}
else{
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
}
if(result!=result){ // nan
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
return result*ScaleFactor_M1;
}
G4double G4NuDEXPSF::GetE2(G4double Eg,G4double ExcitationEnergy){
G4double result=0;
for(G4int i=0;i<nR_E2;i++){
if(PSFType_E2[i]==0){
result+=5.22E-8*SLO(Eg,E_E2[i],G_E2[i],s_E2[i]);
}
else if(PSFType_E2[i]==1){
result+=5.22E-8*EGLO(Eg,E_E2[i],G_E2[i],s_E2[i],ExcitationEnergy);
}
else if(PSFType_E2[i]==2){
result+=5.22E-8*SMLO(Eg,E_E2[i],G_E2[i],s_E2[i],ExcitationEnergy);
}
else if(PSFType_E2[i]==3){
result+=5.22E-8*GLO(Eg,E_E2[i],G_E2[i],s_E2[i],ExcitationEnergy);
}
else if(PSFType_E2[i]==4){
result+=5.22E-8*MGLO(Eg,E_E2[i],G_E2[i],s_E2[i],ExcitationEnergy);
}
else if(PSFType_E2[i]==5){
result+=5.22E-8*KMF(Eg,E_E2[i],G_E2[i],s_E2[i],ExcitationEnergy);
}
else if(PSFType_E2[i]==6){
result+=5.22E-8*GH(Eg,E_E2[i],G_E2[i],s_E2[i],ExcitationEnergy);
}
else if(PSFType_E2[i]==7){
result+=5.22E-8*MEGLO(Eg,E_E2[i],G_E2[i],s_E2[i],ExcitationEnergy,p1_E2[i],p1_E2[i]);
}
else if(PSFType_E2[i]==8){
result+=5.22E-8*MEGLO(Eg,E_E2[i],G_E2[i],s_E2[i],ExcitationEnergy,p1_E2[i],p2_E2[i]);
}
else if(PSFType_E2[i]==9){
result+=5.22E-8*MEGLO(Eg,E_E2[i],G_E2[i],s_E2[i],ExcitationEnergy,p1_E2[i],p1_E2[i],p2_E2[i]);
}
else if(PSFType_E2[i]==10){
result+=5.22E-8*MEGLO(Eg,E_E2[i],G_E2[i],s_E2[i],ExcitationEnergy,p1_E2[i],p2_E2[i],p3_E2[i]);
}
else if(PSFType_E2[i]==11){
result+=5.22E-8*SMLO_v2(Eg,E_E2[i],G_E2[i],s_E2[i],ExcitationEnergy);
}
else if(PSFType_E2[i]==20){
result+=5.22E-8*Gauss(Eg,E_E2[i],G_E2[i],s_E2[i]);
}
else if(PSFType_E2[i]==21){
result+=5.22E-8*Expo(Eg,E_E2[i],G_E2[i]);
}
else if(PSFType_E2[i]==40){
result+=EvaluateFunction(Eg,np_E2,x_E2,y_E2);
}
else if(PSFType_E2[i]==41){
result+=std::pow(10.,EvaluateFunction(Eg,np_E2,x_E2,y_E2));
}
else{
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
}
if(result!=result){ // nan
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
return result*ScaleFactor_E2;
}
//**********************************************************************************************************
//**********************************************************************************************************
//**********************************************************************************************************
//Defined as in RIPL-3 when possible. Some of them come from other references:
//http://dx.doi.org/10.1103/PhysRevC.88.034317
G4double G4NuDEXPSF::SLO(G4double Eg,G4double Er,G4double Gr,G4double sr){
return sr*Gr*Eg*Gr/((Eg*Eg-Er*Er)*(Eg*Eg-Er*Er)+Eg*Eg*Gr*Gr);
}
//Kadmenskij-Markushev-Furman model (KMF) --> not well described in RIPL-3 manual, taken from another document
G4double G4NuDEXPSF::KMF(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy){
G4double Tf=0;
if(theLD!=0){
Tf=theLD->GetNucleusTemperature(ExcitationEnergy-Eg);
}
G4double Gc=Gr/Er/Er*(Eg*Eg+4*3.141592*3.141592*Tf*Tf);
if(Eg==Er){return 0;}
return 0.7*Er*Gr*sr*Gc/((Eg*Eg-Er*Er)*(Eg*Eg-Er*Er));
}
G4double G4NuDEXPSF::EGLO(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy){
G4double result=EGLO_GLO_MGLO(Eg,Er,Gr,sr,ExcitationEnergy,0);
return result;
}
G4double G4NuDEXPSF::GLO(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy){
G4double result=EGLO_GLO_MGLO(Eg,Er,Gr,sr,ExcitationEnergy,1);
return result;
}
G4double G4NuDEXPSF::MGLO(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy){
G4double result=EGLO_GLO_MGLO(Eg,Er,Gr,sr,ExcitationEnergy,2);
return result;
}
//Hybrid model
G4double G4NuDEXPSF::GH(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy){
G4double Tf=0;
if(theLD!=0){
Tf=theLD->GetNucleusTemperature(ExcitationEnergy-Eg);
}
G4double Gamma_h=0.63*Gr/Eg/Er*(Eg*Eg+4*3.141592*3.141592*Tf*Tf);
return sr*Gr*Eg*Gamma_h/((Eg*Eg-Er*Er)*(Eg*Eg-Er*Er)+Eg*Eg*Gr*Gamma_h);
}
G4double G4NuDEXPSF::SMLO(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy){
G4double Tf=0;
if(theLD!=0){
Tf=theLD->GetNucleusTemperature(ExcitationEnergy-Eg);
}
G4double Lambda=1/(1.-std::exp(-Eg/Tf));
G4double Gk_Eg=Gr/Er*ExcitationEnergy;
return Lambda*sr*Gr*Eg*Gk_Eg/((Eg*Eg-Er*Er)*(Eg*Eg-Er*Er)+Eg*Eg*Gk_Eg*Gk_Eg);
}
G4double G4NuDEXPSF::SMLO_v2(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy){
G4double Tf=0;
if(Eg<ExcitationEnergy){
Tf=std::sqrt((ExcitationEnergy-Eg)/(A_Int/10.));
}
G4double Lambda=1/(1.-std::exp(-Eg/Tf));
G4double sig_trk=60.*(A_Int-Z_Int)*Z_Int/(G4double)A_Int;
G4double Gk_Eg=Gr/Er*(Eg+4*3.141592*3.141592*Tf*Tf/Er);
return Lambda*sig_trk*2./3.141592*sr*Eg*Gk_Eg/((Eg*Eg-Er*Er)*(Eg*Eg-Er*Er)+Eg*Eg*Gk_Eg*Gk_Eg);
}
G4double G4NuDEXPSF::Gauss(G4double Eg,G4double Er,G4double sigma,G4double Area){
return Area*(1./(sigma*std::sqrt(2.*3.141592)))*std::exp(-0.5*std::pow((Eg-Er)/sigma,2.));
}
G4double G4NuDEXPSF::Expo(G4double Eg,G4double C,G4double eta){
return C*std::exp(-eta*Eg);
}
G4double G4NuDEXPSF::MEGLO(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy,G4double k_param1,G4double k_param2,G4double Temp){
G4double /*Ti=0,*/Tf=0;
if(Temp>=0){
//Ti=Temp;
Tf=Temp;
}
else if(theLD!=0){
//Ti=theLD->GetNucleusTemperature(ExcitationEnergy);
Tf=theLD->GetNucleusTemperature(ExcitationEnergy-Eg);
}
G4double Gk_Eg=Gamma_k(Eg,Er,Gr,Tf,k_param1);
//G4double Gk_0=Gamma_k(0,Er,Gr,Ti,k_param2);
G4double Gk_0=Gamma_k(0,Er,Gr,Tf,k_param2); // in most of the references they use just one temperature
return sr*Gr*(Eg*Gk_Eg/((Eg*Eg-Er*Er)*(Eg*Eg-Er*Er)+Eg*Eg*Gk_Eg*Gk_Eg)+0.7*Gk_0/Er/Er/Er);
}
//Ti, Tf --> initial/final temperature of the nucleus
//Opt = 0,1,2 --> EGLO, GLO, MGLO
G4double G4NuDEXPSF::EGLO_GLO_MGLO(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double ExcitationEnergy,G4int Opt){
G4double Ti=0,Tf=0;
if(theLD!=0){
Ti=theLD->GetNucleusTemperature(ExcitationEnergy);
Tf=theLD->GetNucleusTemperature(ExcitationEnergy-Eg);
}
//k_param could be modified according to experimental data.
//The following expression is just a general recomendation
//If k_param==1 --> GLO
G4double k_param=1;
if(A_Int>=148){
k_param=1+0.09*(A_Int-148)*(A_Int-148)*std::exp(-0.18*(A_Int-148));
}
G4double result=0;
if(Opt==0){//EGLO
result=FlexibleGLOType(Eg,Er,Gr,sr,Tf,k_param,Ti,k_param);
}
else if(Opt==1){//GLO --> same as EGLO, but k_param=1
result=FlexibleGLOType(Eg,Er,Gr,sr,Tf,1,Ti,1);
}
else if(Opt==2){//MGLO --> same as EGLO, but k_param2=1
result=FlexibleGLOType(Eg,Er,Gr,sr,Tf,k_param,Ti,1);
}
else{
NuDEXException(__FILE__,std::to_string(__LINE__).c_str(),"##### Error in NuDEX #####");
}
return result;
}
G4double G4NuDEXPSF::FlexibleGLOType(G4double Eg,G4double Er,G4double Gr,G4double sr,G4double Temp1,G4double k_param1,G4double /*Temp2*/,G4double k_param2){
G4double Gk_Eg=Gamma_k(Eg,Er,Gr,Temp1,k_param1);
//G4double Gk_0=Gamma_k(0,Er,Gr,Temp2,k_param2);
G4double Gk_0=Gamma_k(0,Er,Gr,Temp1,k_param2); // in most of the references they use just one temperature
return sr*Gr*(Eg*Gk_Eg/((Eg*Eg-Er*Er)*(Eg*Eg-Er*Er)+Eg*Eg*Gk_Eg*Gk_Eg)+0.7*Gk_0/Er/Er/Er);
}
G4double G4NuDEXPSF::Gamma_k(G4double Eg,G4double Er,G4double Gr,G4double Temp,G4double k_param){
G4double eps0_param=4.5;
G4double Chi=1;
if(Er>eps0_param){
Chi=k_param+(1-k_param)*(Eg-eps0_param)/(Er-eps0_param);
}
G4double C_coll=Gr/Er/Er*Chi;
G4double Gamma_k=C_coll*(Eg*Eg+4*3.141592*3.141592*Temp*Temp);
return Gamma_k;
}
//**********************************************************************************************************
//**********************************************************************************************************
//**********************************************************************************************************
void G4NuDEXPSF::PrintPSFParameters(std::ostream &out){
out<<" ###################################################################################### "<<std::endl;
out<<" PSF_PARAMS"<<std::endl;
out<<" E1: nRes = "<<nR_E1<<std::endl;
for(G4int i=0;i<nR_E1;i++){
out<<" "<<PSFType_E1[i]<<" "<<E_E1[i]<<" "<<G_E1[i]<<" "<<s_E1[i]<<std::endl;
if(PSFType_E1[i]==7){out<<" "<<p1_E1[i]<<std::endl;}
if(PSFType_E1[i]==8){out<<" "<<p1_E1[i]<<" "<<p2_E1[i]<<std::endl;}
if(PSFType_E1[i]==9){out<<" "<<p1_E1[i]<<" "<<p2_E1[i]<<std::endl;}
if(PSFType_E1[i]==10){out<<" "<<p1_E1[i]<<" "<<p2_E1[i]<<" "<<p3_E1[i]<<std::endl;}
if(PSFType_E1[i]==40 || PSFType_E1[i]==41){out<<np_E1; for(G4int j=0;j<np_E1;j++){out<<" "<<x_E1[j]<<" "<<y_E1[j];} out<<std::endl;}
}
out<<" M1: nRes = "<<nR_M1<<std::endl;
for(G4int i=0;i<nR_M1;i++){
out<<" "<<PSFType_M1[i]<<" "<<E_M1[i]<<" "<<G_M1[i]<<" "<<s_M1[i]<<std::endl;
if(PSFType_M1[i]==7){out<<" "<<p1_M1[i]<<std::endl;}
if(PSFType_M1[i]==8){out<<" "<<p1_M1[i]<<" "<<p2_M1[i]<<std::endl;}
if(PSFType_M1[i]==9){out<<" "<<p1_M1[i]<<" "<<p2_M1[i]<<std::endl;}
if(PSFType_M1[i]==10){out<<" "<<p1_M1[i]<<" "<<p2_M1[i]<<" "<<p3_M1[i]<<std::endl;}
if(PSFType_M1[i]==40 || PSFType_M1[i]==41){out<<np_M1; for(G4int j=0;j<np_M1;j++){out<<" "<<x_M1[j]<<" "<<y_M1[j];} out<<std::endl;}
}
out<<" E2: nRes = "<<nR_E2<<std::endl;
for(G4int i=0;i<nR_E2;i++){
out<<" "<<PSFType_E2[i]<<" "<<E_E2[i]<<" "<<G_E2[i]<<" "<<s_E2[i]<<std::endl;
if(PSFType_E2[i]==7){out<<" "<<p1_E2[i]<<std::endl;}
if(PSFType_E2[i]==8){out<<" "<<p1_E2[i]<<" "<<p2_E2[i]<<std::endl;}
if(PSFType_E2[i]==9){out<<" "<<p1_E2[i]<<" "<<p2_E2[i]<<std::endl;}
if(PSFType_E2[i]==10){out<<" "<<p1_E2[i]<<" "<<p2_E2[i]<<" "<<p3_E2[i]<<std::endl;}
if(PSFType_E2[i]==40 || PSFType_E2[i]==41){out<<np_E2; for(G4int j=0;j<np_E2;j++){out<<" "<<x_E2[j]<<" "<<y_E2[j];} out<<std::endl;}
}
out<<" ###################################################################################### "<<std::endl;
}
void G4NuDEXPSF::PrintPSFParametersInInputFileFormat(std::ostream &out){
out<<" PSF"<<std::endl;
out.precision(15);
out<<nR_E1<<std::endl;
for(G4int i=0;i<nR_E1;i++){
out<<" "<<PSFType_E1[i]<<" "<<E_E1[i]<<" "<<G_E1[i]<<" "<<s_E1[i];
if(PSFType_E1[i]==7){out<<" "<<p1_E1[i];}
if(PSFType_E1[i]==8){out<<" "<<p1_E1[i]<<" "<<p2_E1[i];}
if(PSFType_E1[i]==9){out<<" "<<p1_E1[i]<<" "<<p2_E1[i];}
if(PSFType_E1[i]==10){out<<" "<<p1_E1[i]<<" "<<p2_E1[i]<<" "<<p3_E1[i];}
if(PSFType_E1[i]==40 || PSFType_E1[i]==41){out<<np_E1; for(G4int j=0;j<np_E1;j++){out<<" "<<x_E1[j]<<" "<<y_E1[j];} }
out<<std::endl;
}
out<<nR_M1<<std::endl;
for(G4int i=0;i<nR_M1;i++){
out<<" "<<PSFType_M1[i]<<" "<<E_M1[i]<<" "<<G_M1[i]<<" "<<s_M1[i];
if(PSFType_M1[i]==7){out<<" "<<p1_M1[i];}
if(PSFType_M1[i]==8){out<<" "<<p1_M1[i]<<" "<<p2_M1[i];}
if(PSFType_M1[i]==9){out<<" "<<p1_M1[i]<<" "<<p2_M1[i];}
if(PSFType_M1[i]==10){out<<" "<<p1_M1[i]<<" "<<p2_M1[i]<<" "<<p3_M1[i];}
if(PSFType_M1[i]==40 || PSFType_M1[i]==41){out<<np_M1; for(G4int j=0;j<np_M1;j++){out<<" "<<x_M1[j]<<" "<<y_M1[j];}}
out<<std::endl;
}
out<<nR_E2<<std::endl;
for(G4int i=0;i<nR_E2;i++){
out<<" "<<PSFType_E2[i]<<" "<<E_E2[i]<<" "<<G_E2[i]<<" "<<s_E2[i];
if(PSFType_E2[i]==7){out<<" "<<p1_E2[i];}
if(PSFType_E2[i]==8){out<<" "<<p1_E2[i]<<" "<<p2_E2[i];}
if(PSFType_E2[i]==9){out<<" "<<p1_E2[i]<<" "<<p2_E2[i];}
if(PSFType_E2[i]==10){out<<" "<<p1_E2[i]<<" "<<p2_E2[i]<<" "<<p3_E2[i];}
if(PSFType_E2[i]==40 || PSFType_E2[i]==41){out<<np_E2; for(G4int j=0;j<np_E2;j++){out<<" "<<x_E2[j]<<" "<<y_E2[j];}}
out<<std::endl;
}
}
G4double G4NuDEXPSF::EvaluateFunction(G4double xval,G4int np,G4double* x,G4double* y){
if(xval<x[0]){return y[0];}
if(xval>x[np-1]){return y[np-1];}
G4double m,b;
G4int i_eval=np-1;
for(G4int i=1;i<np;i++){
if(x[i]>=xval){
i_eval=i;
break;
}
}
m=(y[i_eval]-y[i_eval-1])/(x[i_eval]-x[i_eval-1]);
b=y[i_eval]-m*x[i_eval];
return m*xval+b;
}
@@ -0,0 +1,124 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Author: E.Mendoza
//
// Creation date: May 2024
//
// Modifications:
//
// -------------------------------------------------------------------
//
// NuDEX code (https://doi.org/10.1016/j.nima.2022.167894)
//
#include "G4NuDEXRandom.hh"
#if COMPILATIONTYPE == 1
//==============================================================================
G4NuDEXRandom::G4NuDEXRandom(unsigned int seed){
theRandom=new TRandom2(seed);
}
G4NuDEXRandom::~G4NuDEXRandom(){
delete theRandom;
}
void G4NuDEXRandom::SetSeed(unsigned int seed){
theRandom->SetSeed(seed);
}
unsigned int G4NuDEXRandom::GetSeed(){
return theRandom->GetSeed();
}
G4double G4NuDEXRandom::Uniform(G4double Xmin,G4double Xmax){
return theRandom->Uniform(Xmin,Xmax);
}
unsigned int G4NuDEXRandom::Integer(unsigned int IntegerMax){
return theRandom->Integer(IntegerMax);
}
G4double G4NuDEXRandom::Exp(G4double tau){
return theRandom->Exp(tau);
}
G4double G4NuDEXRandom::Gaus(G4double mean,G4double sigma){
return theRandom->Gaus(mean,sigma);
}
G4int G4NuDEXRandom::Poisson(G4double mean){
return theRandom->Poisson(mean);
}
//==============================================================================
void NuDEXException(const char* originOfException, const char* exceptionCode,const char* ){
std::cout<<" ############## Error in "<<originOfException<<", line "<<exceptionCode<<" ##############"<<std::endl; exit(1);
}
//==============================================================================
#elif COMPILATIONTYPE == 2
//==============================================================================
G4NuDEXRandom::G4NuDEXRandom(unsigned int seed){
theEngine=new CLHEP::HepJamesRandom(seed);
theRandFlat=new CLHEP::RandFlat(theEngine);
theRandExponential=new CLHEP::RandExponential(theEngine);
theRandGauss=new CLHEP::RandGauss(theEngine);
theRandPoisson=new CLHEP::RandPoisson(theEngine);
}
G4NuDEXRandom::~G4NuDEXRandom(){
//delete theRandFlat;
//delete theRandExponential;
//delete theRandGauss;
//delete theRandPoisson;
//delete theEngine;
}
void G4NuDEXRandom::SetSeed(unsigned int seed){
theEngine->setSeed(seed);
theRandGauss->setF(false);
}
unsigned int G4NuDEXRandom::GetSeed(){
return (unsigned int)theEngine->getSeed();
}
G4double G4NuDEXRandom::Uniform(G4double Xmin,G4double Xmax){
return theRandFlat->fire(Xmin,Xmax);
}
unsigned int G4NuDEXRandom::Integer(unsigned int IntegerMax){
return (unsigned int)theRandFlat->fireInt(IntegerMax); //bikerful!!!
}
G4double G4NuDEXRandom::Exp(G4double tau){
return theRandExponential->fire(tau);
}
G4double G4NuDEXRandom::Gaus(G4double mean,G4double sigma){
return theRandGauss->fire(mean,sigma);
}
G4long G4NuDEXRandom::Poisson(G4double mean){
return theRandPoisson->fire(mean);
}
//==============================================================================
void NuDEXException(const char* originOfException, const char* exceptionCode,const char* description){
G4Exception(originOfException,exceptionCode,FatalException,description);
}
//==============================================================================
#endif
File diff suppressed because it is too large Load Diff
@@ -6,12 +6,40 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-04-21 Gabriele Cosmo (hadr-hpp-V11-01-26)
## 2024-06-17 Gabriele Cosmo (hadr-hpp-V11-02-07)
- Fixed compilation warnings for implicit type conversions on macOS/XCode.
## 2024-06-09 Alberto Ribon (hadr-hpp-V11-02-06)
- G4ParticleHPProbabilityTablesStore : replaced the environmental variable
G4NEUTRONHPDATA with the new one G4URRPTDATA.
- G4ParticleHPProbabilityTablesStore, G4ParticleHPIsoProbabilityTable_NJOY,
G4ParticleHPIsoProbabilityTable_CALENDF : read in particle table files in
compressed format (i.e. `.z`, whereas before they were uncompressed).
## 2024-06-04 Alberto Ribon (hadr-hpp-V11-02-05)
- Introduced for neutron in ParticleHP the treatment of the
Unresolved Resonance Region (URR) via Particle Table (PT).
This is a major physics development made by Marek Zmeskal and Loic Thulliez
(CEA Saclay), relevant for more precise simulations of nuclear reactor
criticality and shielding applications.
The following existing classes have been modified:
G4ParticleHPChannel, G4ParticleHPChannelList, G4ParticleHPElementData,
G4ParticleHPManager, G4ParticleHPMessenger, G4ParticleHPVector.
The following new classes have been introduced:
G4ParticleHPCaptureDataPT, G4ParticleHPCaptureURR,
G4ParticleHPElasticDataPT, G4ParticleHPElasticURR,
G4ParticleHPFissionDataPT, G4ParticleHPFissionURR,
G4ParticleHPInelasticDataPT, G4ParticleHPInelasticURR,
G4ParticleHPProbabilityTablesStore, G4ParticleHPIsoProbabilityTable,
G4ParticleHPIsoProbabilityTable_CALENDF,
G4ParticleHPIsoProbabilityTable_NJOY.
## 2024-04-21 Gabriele Cosmo (hadr-hpp-V11-02-04)
- Fixed compilation error in G4ParticleHPManager and G4ParticleHPNames on
Windows VC++ with C++20 Standard enabled.
Based on [GitHub PR#69](https://github.com/Geant4/geant4/pull/69).
## 2024-02-26 Vladimir Ivanchenko
## 2024-02-26 Vladimir Ivanchenko (hadr-hpp-V11-02-03)
- G4CrossSectionHP - fixed method takeing into account temperatue effect
(the difference due to this fix is small), fixed elastic and capture
cross-sections in Argon by using only the main isotope Z=18, A=40 (there
@@ -19,25 +47,25 @@ It must **not** be used as a substitute for writing good git commit messages!
rare isotopes of argon); fixed cross sections for rare target atoms
Promethium, Astatine, Radon, Francium.
## 2024-02-12 Gabriele Cosmo
## 2024-02-12 Gabriele Cosmo (hadr-hpp-V11-02-02)
- Fixed remaining compilation warnings on gcc compiler when LTO settings
are enabled.
## 2024-01-30 Vladimir Ivanchenko (hadr-hpp-V11-01-25)
## 2024-01-30 Vladimir Ivanchenko (hadr-hpp-V11-02-01)
- G4ParticleHPFSFissionFS, G4ParticleHPFissionBaseFS - substitute
C-arrays with std::vector in order to reduce compilation warnings on gcc
with LTO settings.
C-arrays with std::vector in order to reduce compilation warnings on gcc
with LTO settings.
## 2024-01-26 Vladimir Ivanchenko
## 2024-01-26 Vladimir Ivanchenko (hadr-hpp-V11-02-00)
- G4ParticleHPFissionFS, G4ParticleHPFFFissionFS - added extra protections
against cases when fission data are not available for some isotopes
(fixed problem #2590)
against cases when fission data are not available for some isotopes
(fixed problem #2590)
## 2023-11-04 Vladimir Ivanchenko (hadr-hpp-V11-01-24)
- G4ParticleHPManager - set default upper limit on Doppler broading
30 keV instead of 100 keV
30 keV instead of 100 keV
- G4ParticleHPInelasticXS - set upper limit of x-section 30 MeV
instead of 20 MeV
instead of 20 MeV
- G4CrossSectionHP - removed not needed G4Exception
## 2023-11-03 Ben Morgan (hadr-hpp-V11-01-23)
@@ -60,7 +88,7 @@ It must **not** be used as a substitute for writing good git commit messages!
## 2023-10-12 Gabriele Cosmo (hadr-hpp-V11-01-19)
- In G4CrossSectionHP, fixed compilation warnings for implicit type conversions
on macOS/XCode
on macOS/XCode.
## 2023-10-02 Vladimir Ivanchenko (hadr-hpp-V11-01-18)
- G4CrossSectionHP - removed debug printout
@@ -0,0 +1,84 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Geant4 header file
//
// File name: G4ParticleHPCaptureDataPT.hh
//
// Authors: Marek Zmeskal (CTU, Czech Technical University in Prague, Czech Republic)
// Loic Thulliez (CEA France)
//
// Creation date: 4 June 2024
//
// Description: Class for utilization of cross-sections from
// probability tables in the unresolved resonance region
// for capture channel.
// Cross-section data set for a high precision
// (based on evaluated data libraries) description of
// neutron Capture scattering below 20 MeV.
// To be used in your physics list in case you need
// this physics.
// In this case you want to register an object of this
// class with the corresponding process.
//
// Modifications:
//
// -------------------------------------------------------------------
//
//
#ifndef G4ParticleHPCaptureDataPT_h
#define G4ParticleHPCaptureDataPT_h 1
#include "G4VCrossSectionDataSet.hh"
#include <vector>
class G4DynamicParticle;
class G4ParticleDefinition;
class G4Element;
class G4ParticleHPCaptureDataPT : public G4VCrossSectionDataSet {
public:
G4ParticleHPCaptureDataPT();
~G4ParticleHPCaptureDataPT();
void BuildPhysicsTable( const G4ParticleDefinition& );
G4bool IsIsoApplicable( const G4DynamicParticle* , G4int /*Z*/ , G4int /*A*/ ,
const G4Element* /*elm*/ , const G4Material* /*mat*/ );
G4double GetIsoCrossSection( const G4DynamicParticle* , G4int /*Z*/ , G4int /*A*/ ,
const G4Isotope* /*iso*/ , const G4Element* /*elm*/ , const G4Material* /*mat*/ );
void SetVerboseLevel( G4int );
G4int GetVerboseLevel() const;
virtual void CrossSectionDescription( std::ostream& ) const;
private:
std::vector< std::pair< G4double, G4double > >* URRlimits;
};
#endif
@@ -0,0 +1,79 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Geant4 header file
//
// File name: G4ParticleHPCaptureURR.hh
//
// Authors: Marek Zmeskal (CTU, Czech Technical University in Prague, Czech Republic)
// Loic Thulliez (CEA France)
//
// Creation date: 4 June 2024
//
// Description: Final state production model for a high precision
// (based on evaluated data libraries) description of
// neutron Capture scattering below 20 MeV.
// To be used in your physics list in case you need
// this physics.
// In this case you want to register an object of this
// class with the corresponding process.
//
// Modifications:
//
// -------------------------------------------------------------------
//
//
#ifndef G4ParticleHPCaptureURR_h
#define G4ParticleHPCaptureURR_h 1
#include "globals.hh"
#include "G4HadronicInteraction.hh"
#include <vector>
class G4NeutronHPCapture;
class G4ParticleHPCaptureURR : public G4HadronicInteraction {
public:
G4ParticleHPCaptureURR();
~G4ParticleHPCaptureURR();
G4HadFinalState* ApplyYourself( const G4HadProjectile& aTrack, G4Nucleus& aTargetNucleus );
virtual const std::pair< G4double, G4double > GetFatalEnergyCheckLevels() const;
G4int GetVerboseLevel() const;
void SetVerboseLevel( G4int );
void BuildPhysicsTable( const G4ParticleDefinition& );
virtual void ModelDescription( std::ostream& outFile ) const;
private:
G4NeutronHPCapture* neutronHPcapture;
std::vector< std::pair< G4double, G4double > >* URRlimits{ nullptr };
};
#endif
@@ -127,6 +127,9 @@ public:
G4ParticleHPFinalState** GetFinalStates() const { return theFinalStates; }
// method added by M.Zmeskal 02/2024 - to be used in G4ParticleHPFissionURR
G4WendtFissionFragmentGenerator* GetWendtFissionGenerator();
G4ParticleHPChannel(G4ParticleHPChannel &) = delete;
G4ParticleHPChannel & operator=
(const G4ParticleHPChannel &right) = delete;
@@ -55,6 +55,9 @@ class G4ParticleHPChannelList
G4HadFinalState* ApplyYourself(const G4Element* theElement,
const G4HadProjectile& aTrack);
// method added by M.Zmeskal 02/2024 - to be used in G4ParticleHPInelasticURR
G4HadFinalState * ApplyYourself(G4int, G4int, G4int, const G4HadProjectile & aTrack);
void Init(G4Element* anElement, const G4String& dirName,
G4ParticleDefinition* projectile);
@@ -69,6 +72,18 @@ class G4ParticleHPChannelList
return result;
}
// method added by M.Zmeskal 02/2024 - to be used in G4ParticleHPIsoProbabilityTable
inline G4double GetWeightedXsec( G4double anEnergy, G4int isotopeJ ) {
G4double result = 0.0;
G4int i;
for ( i = 0; i < nChannels; i++ ) {
if ( theChannels[i]->HasAnyData( isotopeJ ) ) {
result += std::max( 0.0, theChannels[i]->GetWeightedXsec( anEnergy, isotopeJ ) );
}
}
return result;
}
G4int GetNumberOfChannels() { return nChannels; }
G4bool HasDataInAnyFinalState()
@@ -0,0 +1,84 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Geant4 header file
//
// File name: G4ParticleHPElasticDataPT.hh
//
// Authors: Marek Zmeskal (CTU, Czech Technical University in Prague, Czech Republic)
// Loic Thulliez (CEA France)
//
// Creation date: 4 June 2024
//
// Description: Class for utilization of cross-sections from
// probability tables in the unresolved resonance region
// for elastic channel.
// Cross-section data set for a high precision
// (based on evaluated data libraries) description of
// neutron elastic scattering below 20 MeV.
// To be used in your physics list in case you need
// this physics.
// In this case you want to register an object of this
// class with the corresponding process.
//
// Modifications:
//
// -------------------------------------------------------------------
//
//
#ifndef G4ParticleHPElasticDataPT_h
#define G4ParticleHPElasticDataPT_h 1
#include "G4VCrossSectionDataSet.hh"
#include <vector>
class G4DynamicParticle;
class G4ParticleDefinition;
class G4Element;
class G4ParticleHPElasticDataPT : public G4VCrossSectionDataSet {
public:
G4ParticleHPElasticDataPT();
~G4ParticleHPElasticDataPT();
void BuildPhysicsTable( const G4ParticleDefinition& );
G4bool IsIsoApplicable( const G4DynamicParticle* , G4int /*Z*/ , G4int /*A*/ ,
const G4Element* /*elm*/ , const G4Material* /*mat*/ );
G4double GetIsoCrossSection( const G4DynamicParticle* , G4int /*Z*/ , G4int /*A*/ ,
const G4Isotope* /*iso*/ , const G4Element* /*elm*/ , const G4Material* /*mat*/ );
void SetVerboseLevel( G4int );
G4int GetVerboseLevel() const;
virtual void CrossSectionDescription( std::ostream& ) const;
private:
std::vector< std::pair< G4double, G4double > >* URRlimits;
};
#endif
@@ -0,0 +1,79 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Geant4 header file
//
// File name: G4ParticleHPElasticURR.hh
//
// Authors: Marek Zmeskal (CTU, Czech Technical University in Prague, Czech Republic)
// Loic Thulliez (CEA France)
//
// Creation date: 4 June 2024
//
// Description: Final state production model for a high precision
// (based on evaluated data libraries) description of
// neutron elastic scattering below 20 MeV.
// To be used in your physics list in case you need
// this physics.
// In this case you want to register an object of this
// class with the corresponding process.
//
// Modifications:
//
// -------------------------------------------------------------------
//
//
#ifndef G4ParticleHPElasticURR_h
#define G4ParticleHPElasticURR_h 1
#include "globals.hh"
#include "G4HadronicInteraction.hh"
#include <vector>
class G4ParticleHPElastic;
class G4ParticleHPElasticURR : public G4HadronicInteraction {
public:
G4ParticleHPElasticURR();
~G4ParticleHPElasticURR();
G4HadFinalState* ApplyYourself( const G4HadProjectile& aTrack, G4Nucleus& aTargetNucleus );
virtual const std::pair< G4double, G4double > GetFatalEnergyCheckLevels() const;
G4int GetVerboseLevel() const;
void SetVerboseLevel( G4int );
void BuildPhysicsTable( const G4ParticleDefinition& );
virtual void ModelDescription( std::ostream& outFile ) const;
private:
G4ParticleHPElastic* particleHPelastic;
std::vector< std::pair< G4double, G4double > >* URRlimits{ nullptr };
};
#endif
@@ -0,0 +1,84 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Geant4 header file
//
// File name: G4ParticleHPFissionDataPT.hh
//
// Authors: Marek Zmeskal (CTU, Czech Technical University in Prague, Czech Republic)
// Loic Thulliez (CEA France)
//
// Creation date: 4 June 2024
//
// Description: Class for utilization of cross-sections from
// probability tables in the unresolved resonance region
// for fission channel.
// Cross-section data set for a high precision
// (based on evaluated data libraries) description of
// neutron Fission scattering below 20 MeV.
// To be used in your physics list in case you need
// this physics.
// In this case you want to register an object of this
// class with the corresponding process.
//
// Modifications:
//
// -------------------------------------------------------------------
//
//
#ifndef G4ParticleHPFissionDataPT_h
#define G4ParticleHPFissionDataPT_h 1
#include "G4VCrossSectionDataSet.hh"
#include <vector>
class G4DynamicParticle;
class G4ParticleDefinition;
class G4Element;
class G4ParticleHPFissionDataPT : public G4VCrossSectionDataSet {
public:
G4ParticleHPFissionDataPT();
~G4ParticleHPFissionDataPT();
void BuildPhysicsTable( const G4ParticleDefinition& );
G4bool IsIsoApplicable( const G4DynamicParticle* , G4int /*Z*/ , G4int /*A*/ ,
const G4Element* /*elm*/ , const G4Material* /*mat*/ );
G4double GetIsoCrossSection( const G4DynamicParticle* , G4int /*Z*/ , G4int /*A*/ ,
const G4Isotope* /*iso*/ , const G4Element* /*elm*/ , const G4Material* /*mat*/ );
void SetVerboseLevel( G4int );
G4int GetVerboseLevel() const;
virtual void CrossSectionDescription( std::ostream& ) const;
private:
std::vector< std::pair< G4double, G4double > >* URRlimits;
};
#endif
@@ -0,0 +1,78 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Geant4 header file
//
// File name: G4ParticleHPFissionURR.hh
//
// Authors: Marek Zmeskal (CTU, Czech Technical University in Prague, Czech Republic)
// Loic Thulliez (CEA France)
//
// Creation date: 4 June 2024
//
// Description: Final state production model for a high precision
// (based on evaluated data libraries) description of
// neutron Fission scattering below 20 MeV.
// To be used in your physics list in case you need
// this physics.
// In this case you want to register an object of this
// class with the corresponding process.
//
// Modifications:
//
// -------------------------------------------------------------------
//
//
#ifndef G4ParticleHPFissionURR_h
#define G4ParticleHPFissionURR_h 1
#include "globals.hh"
#include "G4HadronicInteraction.hh"
#include <vector>
class G4ParticleHPFission;
class G4ParticleHPFissionURR : public G4HadronicInteraction {
public:
G4ParticleHPFissionURR();
~G4ParticleHPFissionURR();
G4HadFinalState* ApplyYourself( const G4HadProjectile& aTrack, G4Nucleus& aTargetNucleus );
virtual const std::pair< G4double, G4double > GetFatalEnergyCheckLevels() const;
G4int GetVerboseLevel() const;
void SetVerboseLevel( G4int );
void BuildPhysicsTable( const G4ParticleDefinition& );
virtual void ModelDescription( std::ostream& outFile ) const;
private:
G4ParticleHPFission* particleHPfission;
std::vector< std::pair< G4double, G4double > >* URRlimits{ nullptr };
};
#endif
@@ -0,0 +1,84 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Geant4 header file
//
// File name: G4ParticleHPInelasticDataPT.hh
//
// Authors: Marek Zmeskal (CTU, Czech Technical University in Prague, Czech Republic)
// Loic Thulliez (CEA France)
//
// Creation date: 4 June 2024
//
// Description: Class for utilization of cross-sections from
// probability tables in the unresolved resonance region
// for inelastic channel.
// Cross-section data set for a high precision
// (based on evaluated data libraries) description of
// neutron Inelastic scattering below 20 MeV.
// To be used in your physics list in case you need
// this physics.
// In this case you want to register an object of this
// class with the corresponding process.
//
// Modifications:
//
// -------------------------------------------------------------------
//
//
#ifndef G4ParticleHPInelasticDataPT_h
#define G4ParticleHPInelasticDataPT_h 1
#include "G4VCrossSectionDataSet.hh"
#include <vector>
class G4DynamicParticle;
class G4ParticleDefinition;
class G4Element;
class G4ParticleHPInelasticDataPT : public G4VCrossSectionDataSet {
public:
G4ParticleHPInelasticDataPT();
~G4ParticleHPInelasticDataPT();
void BuildPhysicsTable( const G4ParticleDefinition& );
G4bool IsIsoApplicable( const G4DynamicParticle* , G4int /*Z*/ , G4int /*A*/ ,
const G4Element* /*elm*/ , const G4Material* /*mat*/ );
G4double GetIsoCrossSection( const G4DynamicParticle* , G4int /*Z*/ , G4int /*A*/ ,
const G4Isotope* /*iso*/ , const G4Element* /*elm*/ , const G4Material* /*mat*/ );
void SetVerboseLevel( G4int );
G4int GetVerboseLevel() const;
virtual void CrossSectionDescription( std::ostream& ) const;
private:
std::vector< std::pair< G4double, G4double > >* URRlimits;
};
#endif
@@ -0,0 +1,80 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Geant4 header file
//
// File name: G4ParticleHPInelasticURR.hh
//
// Authors: Marek Zmeskal (CTU, Czech Technical University in Prague, Czech Republic)
// Loic Thulliez (CEA France)
//
// Creation date: 4 June 2024
//
// Description: Final state production model for a high precision
// (based on evaluated data libraries) description of
// neutron Inelastic scattering below 20 MeV.
// To be used in your physics list in case you need
// this physics.
// In this case you want to register an object of this
// class with the corresponding process.
//
// Modifications:
//
// -------------------------------------------------------------------
//
//
#ifndef G4ParticleHPInelasticURR_h
#define G4ParticleHPInelasticURR_h 1
#include "globals.hh"
#include "G4HadronicInteraction.hh"
#include <vector>
class G4ParticleHPInelastic;
class G4ParticleHPInelasticURR : public G4HadronicInteraction {
public:
G4ParticleHPInelasticURR();
~G4ParticleHPInelasticURR();
G4HadFinalState* ApplyYourself( const G4HadProjectile& aTrack, G4Nucleus& aTargetNucleus );
virtual const std::pair< G4double, G4double > GetFatalEnergyCheckLevels() const;
G4int GetVerboseLevel() const;
void SetVerboseLevel( G4int );
void BuildPhysicsTable( const G4ParticleDefinition& );
virtual void ModelDescription( std::ostream& outFile ) const;
private:
G4ParticleHPInelastic* particleHPinelastic;
std::vector< std::pair< G4double, G4double > >* URRlimits{ nullptr };
G4bool doNOTusePTforInelastic{ true };
};
#endif
@@ -0,0 +1,101 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Geant4 header file
//
// File name: G4ParticleHPIsoProbabilityTable.hh
//
// Authors: Marek Zmeskal (CTU, Czech Technical University in Prague, Czech Republic)
// Loic Thulliez (CEA France)
//
// Creation date: 4 June 2024
//
// Description: Class for the probability table of the given isotope
// and for the given temperature.
// It reads the files with probability tables and
// finds the correct cross-section.
//
// Modifications:
//
// -------------------------------------------------------------------
//
//
#ifndef G4ParticleHPIsoProbabilityTable_h
#define G4ParticleHPIsoProbabilityTable_h 1
#include "globals.hh"
#include <vector>
#include <thread>
#include <map>
class G4ParticleHPVector;
class G4DynamicParticle;
class G4Element;
class G4ParticleHPIsoProbabilityTable {
public:
G4ParticleHPIsoProbabilityTable();
virtual ~G4ParticleHPIsoProbabilityTable();
virtual void Init( G4int, G4int, G4int, G4double, G4String );
virtual G4double GetCorrelatedIsoCrossSectionPT( const G4DynamicParticle*, G4int, const G4Element*,
G4double&, G4double&, std::thread::id& );
virtual G4double GetIsoCrossSectionPT( const G4DynamicParticle*, G4int, const G4Element*, G4double&,
std::map< std::thread::id, G4double >&, std::thread::id& );
protected:
G4double GetDopplerBroadenedElasticXS( const G4DynamicParticle*, G4int, G4int );
G4double GetDopplerBroadenedCaptureXS( const G4DynamicParticle*, G4int, G4int );
G4double GetDopplerBroadenedFissionXS( const G4DynamicParticle*, G4int, G4int );
G4double GetDopplerBroadenedInelasticXS( const G4DynamicParticle*, G4int, G4int );
G4int Z;
G4int A;
G4int m;
G4double T;
G4double Emin;
G4double Emax;
G4int nEnergies;
std::map< std::thread::id, G4double > energy_cache;
std::map< std::thread::id, G4double > xsela_cache;
std::map< std::thread::id, G4double > xscap_cache;
std::map< std::thread::id, G4double > xsfiss_cache;
G4ParticleHPVector* theEnergies;
std::vector< std::vector< G4double >* >* theProbabilities;
std::vector< std::vector< G4double >* >* theElasticData;
std::vector< std::vector< G4double >* >* theCaptureData;
std::vector< std::vector< G4double >* >* theFissionData;
std::vector< std::vector< G4double >* >* theInelasticData;
G4String filename;
};
#endif
@@ -0,0 +1,75 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Geant4 header file
//
// File name: G4ParticleHPIsoProbabilityTable_CALENDF.hh
//
// Authors: Marek Zmeskal (CTU, Czech Technical University in Prague, Czech Republic)
// Loic Thulliez (CEA France)
//
// Creation date: 4 June 2024
//
// Description: Class for the probability table of the given isotope
// and for the given temperature generated with CALENDF.
// It reads the files with probability tables and
// finds the correct cross-section.
//
// Modifications:
//
// -------------------------------------------------------------------
//
//
#ifndef G4ParticleHPIsoProbabilityTable_CALENDF_h
#define G4ParticleHPIsoProbabilityTable_CALENDF_h 1
#include "globals.hh"
#include "G4ParticleHPIsoProbabilityTable.hh"
#include <vector>
#include <thread>
#include <map>
class G4DynamicParticle;
class G4Element;
class G4ParticleHPIsoProbabilityTable_CALENDF : public G4ParticleHPIsoProbabilityTable {
public:
G4ParticleHPIsoProbabilityTable_CALENDF();
~G4ParticleHPIsoProbabilityTable_CALENDF();
void Init( G4int, G4int, G4int, G4double, G4String ) override;
G4double GetCorrelatedIsoCrossSectionPT( const G4DynamicParticle*, G4int, const G4Element*, G4double&, G4double&,
std::thread::id& ) override;
G4double GetIsoCrossSectionPT( const G4DynamicParticle*, G4int, const G4Element*, G4double&,
std::map< std::thread::id, G4double >&, std::thread::id& ) override;
private:
std::map< std::thread::id, G4double > xsinela_cache;
std::vector< std::vector< G4double >* >* theInelasticData;
};
#endif
@@ -0,0 +1,77 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Geant4 header file
//
// File name: G4ParticleHPIsoProbabilityTable_NJOY.hh
//
// Authors: Marek Zmeskal (CTU, Czech Technical University in Prague, Czech Republic)
// Loic Thulliez (CEA France)
//
// Creation date: 4 June 2024
//
// Description: Class for the probability table of the given isotope
// and for the given temperature generated with NJOY.
// It reads the files with probability tables and
// finds the correct cross-section.
//
// Modifications:
//
// -------------------------------------------------------------------
//
//
#ifndef G4ParticleHPIsoProbabilityTable_NJOY_h
#define G4ParticleHPIsoProbabilityTable_NJOY_h 1
#include "globals.hh"
#include "G4ParticleHPInterpolator.hh"
#include "G4ParticleHPIsoProbabilityTable.hh"
#include <vector>
#include <thread>
#include <map>
class G4DynamicParticle;
class G4Element;
class G4ParticleHPIsoProbabilityTable_NJOY : public G4ParticleHPIsoProbabilityTable {
public:
G4ParticleHPIsoProbabilityTable_NJOY();
~G4ParticleHPIsoProbabilityTable_NJOY();
void Init( G4int, G4int, G4int, G4double, G4String ) override;
G4double GetCorrelatedIsoCrossSectionPT( const G4DynamicParticle*, G4int, const G4Element*, G4double&, G4double&,
std::thread::id& ) override;
G4double GetIsoCrossSectionPT( const G4DynamicParticle*, G4int, const G4Element*, G4double&,
std::map< std::thread::id, G4double >&, std::thread::id& ) override;
private:
G4int tableOrder;
G4int lssf_flag;
G4ParticleHPInterpolator theInt;
};
#endif
@@ -42,6 +42,7 @@ class G4ParticleHPChannel;
class G4ParticleHPChannelList;
class G4ParticleHPMessenger;
class G4ParticleHPVector;
class G4ParticleHPIsoProbabilityTable;
class G4PhysicsTable;
struct E_isoAng;
struct E_P_E_isoAng;
@@ -205,6 +206,17 @@ class G4ParticleHPManager
theTSInelasticFinalStates = val;
};
std::vector< std::map< G4int, G4ParticleHPIsoProbabilityTable* > >* GetProbabilityTables()
{ return theProbabilityTables; };
void RegisterProbabilityTables( std::vector< std::map< G4int, G4ParticleHPIsoProbabilityTable* > >* val )
{ theProbabilityTables = val; };
std::vector< std::pair< G4double, G4double > >* GetURRlimits() { return theURRlimits; };
void RegisterURRlimits( std::vector< std::pair< G4double, G4double > >* val ) { theURRlimits = val; };
G4String GetUsedPTformat() { return USE_PROBABILITY_TABLE_FROM; };
void SetUsedPTformat( G4String val ) { USE_PROBABILITY_TABLE_FROM = val; };
G4double GetMinADBRC() const { return theMinADBRC; };
G4double GetMinEnergyDBRC() const { return theMinEnergyDBRC; };
G4double GetMaxEnergyDBRC() const { return theMaxEnergyDBRC; };
@@ -271,5 +283,10 @@ class G4ParticleHPManager
G4double theMaxEnergyDoppler;
G4String fDataPath[6]{""};
std::vector< std::map< G4int, G4ParticleHPIsoProbabilityTable* > >* theProbabilityTables{ nullptr };
std::vector< std::pair< G4double, G4double > >* theURRlimits{ nullptr };
G4String USE_PROBABILITY_TABLE_FROM{ "njoy" };
};
#endif
@@ -62,6 +62,7 @@ class G4ParticleHPMessenger : public G4UImessenger
G4UIcmdWithADouble* MinADBRCCmd;
G4UIcmdWithADoubleAndUnit* MinEnergyDBRCCmd;
G4UIcmdWithADoubleAndUnit* MaxEnergyDBRCCmd;
G4UIcmdWithAString* PTformatCmd;
};
#endif
@@ -0,0 +1,92 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// Geant4 header file
//
// File name: G4ParticleHPProbabilityTablesStore.hh
//
// Authors: Marek Zmeskal (CTU, Czech Technical University in Prague, Czech Republic)
// Loic Thulliez (CEA France)
//
// Creation date: 4 June 2024
//
// Description: Class to store all probability tables for different isotopes
// and in future also for different temperatures.
//
// Modifications:
//
// -------------------------------------------------------------------
//
//
#ifndef G4ParticleHPProbabilityTablesStore_h
#define G4ParticleHPProbabilityTablesStore_h 1
#include "globals.hh"
#include <map>
#include <vector>
#include <thread>
class G4Material;
class G4Element;
class G4Isotope;
class G4DynamicParticle;
class G4ParticleHPIsoProbabilityTable;
class G4ParticleHPProbabilityTablesStore {
public:
static G4ParticleHPProbabilityTablesStore * GetInstance();
void Init();
void InitURRlimits();
std::vector< std::map< G4int, G4ParticleHPIsoProbabilityTable* > >* GetProbabilityTables() { return ProbabilityTables; };
std::vector< std::pair< G4double, G4double > >* GetURRlimits(){ return URRlimits; };
G4double GetIsoCrossSectionPT( const G4DynamicParticle*, G4int, const G4Isotope*, const G4Element*, const G4Material* );
std::vector< std::map< std::thread::id, G4double > > random_number_cache;
private:
static G4ParticleHPProbabilityTablesStore* instance;
G4ParticleHPProbabilityTablesStore();
G4ParticleHPProbabilityTablesStore( const G4ParticleHPProbabilityTablesStore& ){};
~G4ParticleHPProbabilityTablesStore();
std::vector< std::vector< G4int > >* Temperatures;
std::vector< std::map< G4int, G4ParticleHPIsoProbabilityTable* > >* ProbabilityTables;
std::vector< std::pair< G4double, G4double > >* URRlimits;
std::vector< std::map< std::thread::id, G4double > > energy_cache;
G4String dirName;
G4String filename;
G4int numIso;
G4bool usedNjoy;
G4bool usedCalendf;
};
#endif

Some files were not shown because too many files have changed in this diff Show More