Import Geant4 11.4.0 source tree
This commit is contained in:
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-08-03 Jose Luis Rodriguez Sanchez (hadr-abla-V11-03-00)
|
||||
- Added a new description for fission barriers based on PRC 111, 064606 (2025).
|
||||
|
||||
## 2024-09-02 Gabriele Cosmo (hadr-abla-V11-02-06)
|
||||
- Fixed reported Coverity defects for uninitialised data in G4Abla.
|
||||
|
||||
|
||||
@@ -33,516 +33,482 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "globals.hh"
|
||||
#include <memory>
|
||||
|
||||
#include "G4AblaDataDefs.hh"
|
||||
#include "G4AblaRandom.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* Class containing ABLA++ de-excitation code.
|
||||
*/
|
||||
|
||||
class G4Abla {
|
||||
|
||||
public:
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
G4Abla(G4VarNtp *aVarntp);
|
||||
|
||||
/**
|
||||
* Basic destructor.
|
||||
*/
|
||||
~G4Abla() = default;
|
||||
|
||||
/// \brief Dummy copy constructor
|
||||
G4Abla(G4Abla const &other);
|
||||
|
||||
/// \brief Dummy assignment operator
|
||||
G4Abla &operator=(G4Abla const &other);
|
||||
|
||||
/**
|
||||
* Set verbosity level.
|
||||
*/
|
||||
void setVerboseLevel(G4int level);
|
||||
|
||||
/**
|
||||
* 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 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);
|
||||
|
||||
/**
|
||||
* Main interface to the de-excitation code for hyper-nuclei.
|
||||
*
|
||||
* @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 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);
|
||||
|
||||
// Evaporation
|
||||
public:
|
||||
/**
|
||||
* Initialize ABLA evaporation code.
|
||||
*
|
||||
*/
|
||||
void initEvapora();
|
||||
|
||||
/**
|
||||
* Initialize ABLA parameters.
|
||||
*
|
||||
*/
|
||||
void SetParameters();
|
||||
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
|
||||
* @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
|
||||
*/
|
||||
void qrot(G4double z, G4double a, G4double bet, G4double sig, G4double u,
|
||||
G4double *qr);
|
||||
|
||||
/**
|
||||
* Model de la goutte liquide de c. f. weizsacker.
|
||||
* usually an obsolete option
|
||||
*/
|
||||
void mglw(G4double a, G4double z, G4double *el);
|
||||
|
||||
/**
|
||||
* Mglms
|
||||
*/
|
||||
void mglms(G4double a, G4double z, G4int refopt4, G4double *el);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
G4double spdef(G4int a, G4int z, G4int optxfis);
|
||||
|
||||
/**
|
||||
* Calculation of fissility parameter
|
||||
*/
|
||||
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[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);
|
||||
|
||||
/**
|
||||
* 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[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);
|
||||
|
||||
/**
|
||||
* 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[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);
|
||||
|
||||
/**
|
||||
* Calculation of tke for breakup fragments
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Calculation of particle emission barriers.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Calculation of omega at saddle point.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Calculation of even-odd effects in fission.
|
||||
*/
|
||||
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 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
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
|
||||
*/
|
||||
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
|
||||
* MASSES and DEFORMATIONS by P. Mo"ller et al. from August 16, 1993 p.
|
||||
* 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
|
||||
* 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
|
||||
*/
|
||||
void parite(G4double n, G4double *par);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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).
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Calculation of penetration factors for light charged particles.
|
||||
*/
|
||||
G4double pen(G4double A, G4double ap, G4double omega, G4double T);
|
||||
|
||||
/**
|
||||
* Calculation of mean value of orbital angular momentum.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Special functions used for the emission of particles.
|
||||
*/
|
||||
G4double erf(G4double x);
|
||||
|
||||
G4double gammp(G4double a, G4double x);
|
||||
|
||||
void gcf(G4double *gammcf, G4double a, G4double x, G4double gln);
|
||||
|
||||
void gser(G4double *gamser, G4double a, G4double x, G4double gln);
|
||||
|
||||
G4double fvmaxhaz(G4double T);
|
||||
|
||||
G4double fvmaxhaz_neut(G4double x);
|
||||
|
||||
/**
|
||||
* Random numbers.
|
||||
*/
|
||||
void standardRandom(G4double *rndm, G4long *seed);
|
||||
|
||||
/**
|
||||
* LOGARITHM OF THE GAMM FUNCTION
|
||||
*/
|
||||
G4double gammln(G4double xx);
|
||||
|
||||
/**
|
||||
* DISTRIBUTION DE MAXWELL
|
||||
*/
|
||||
G4double fd(G4double E);
|
||||
|
||||
/**
|
||||
*FONCTION INTEGRALE DE FD(E)
|
||||
*/
|
||||
G4double f(G4double E);
|
||||
|
||||
/**
|
||||
* tirage aleatoire dans une maxwellienne
|
||||
*/
|
||||
G4double fmaxhaz(G4double T);
|
||||
|
||||
/**
|
||||
* tirage aleatoire dans une maxwellienne
|
||||
*/
|
||||
G4double fmaxhaz_old(G4double T);
|
||||
|
||||
/**
|
||||
* Random generator according to the
|
||||
powerfunction y = x**(lambda) in the range from xmin to xmax
|
||||
*/
|
||||
G4int IPOWERLIMHAZ(G4double lambda, G4int xmin, G4int xmax);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void guet(G4double *x_par, G4double *z_par, G4double *find_par);
|
||||
|
||||
/**
|
||||
* Limits of existing nuclei
|
||||
*/
|
||||
void isostab_lim(G4int z, G4int *nmin, G4int *nmax);
|
||||
|
||||
/**
|
||||
* Fill the data array for INCL
|
||||
*/
|
||||
void FillData(G4int IMULTBU, G4int IEV_TAB);
|
||||
|
||||
/**
|
||||
* Separation energies of lambda
|
||||
*/
|
||||
G4double gethyperseparation(G4double A, G4double Z, G4int ny);
|
||||
|
||||
/**
|
||||
* Separation energies of for other particles for hypernuclei
|
||||
*/
|
||||
G4double getdeltabinding(G4double a, G4int nblamb);
|
||||
G4double gethyperbinding(G4double A, G4double Z, G4int ny);
|
||||
|
||||
public:
|
||||
// Utils
|
||||
G4int min(G4int a, G4int b);
|
||||
G4double min(G4double a, G4double b);
|
||||
G4int max(G4int a, G4int b);
|
||||
G4double max(G4double a, G4double b);
|
||||
G4double DSIGN(G4double a, G4double b);
|
||||
G4int ISIGN(G4int a, G4int b);
|
||||
G4int nint(G4double number);
|
||||
G4int secnds(G4int x);
|
||||
G4int mod(G4int a, G4int b);
|
||||
G4double dmod(G4double a, G4double b);
|
||||
G4double dint(G4double a);
|
||||
G4int idint(G4double a);
|
||||
G4int idnint(G4double value);
|
||||
G4double utilabs(G4double a);
|
||||
G4double dmin1(G4double a, G4double b, G4double c);
|
||||
|
||||
private:
|
||||
G4int verboseLevel;
|
||||
G4int ilast;
|
||||
G4double T_freeze_out_in;
|
||||
G4int IEV_TAB_SSC;
|
||||
G4double BU_TAB[indexpart][12], EV_TAB[indexpart][6], EV_TAB_SSC[indexpart][6];
|
||||
G4int gammaemission;
|
||||
G4double T_freeze_out;
|
||||
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;
|
||||
class G4Abla
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
G4Abla(G4VarNtp* aVarntp);
|
||||
|
||||
/**
|
||||
* Basic destructor.
|
||||
*/
|
||||
~G4Abla() = default;
|
||||
|
||||
/// \brief Dummy copy constructor
|
||||
G4Abla(G4Abla const& other);
|
||||
|
||||
/// \brief Dummy assignment operator
|
||||
G4Abla& operator=(G4Abla const& other);
|
||||
|
||||
/**
|
||||
* Set verbosity level.
|
||||
*/
|
||||
void setVerboseLevel(G4int level);
|
||||
|
||||
/**
|
||||
* 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 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);
|
||||
|
||||
/**
|
||||
* Main interface to the de-excitation code for hyper-nuclei.
|
||||
*
|
||||
* @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 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);
|
||||
|
||||
// Evaporation
|
||||
public:
|
||||
/**
|
||||
* Initialize ABLA evaporation code.
|
||||
*
|
||||
*/
|
||||
void initEvapora();
|
||||
|
||||
/**
|
||||
* Initialize ABLA parameters.
|
||||
*
|
||||
*/
|
||||
void SetParameters();
|
||||
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
|
||||
* @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
|
||||
*/
|
||||
void qrot(G4double z, G4double a, G4double bet, G4double sig, G4double u, G4double* qr);
|
||||
|
||||
/**
|
||||
* Model de la goutte liquide de c. f. weizsacker.
|
||||
* usually an obsolete option
|
||||
*/
|
||||
void mglw(G4double a, G4double z, G4double* el);
|
||||
|
||||
/**
|
||||
* Mglms
|
||||
*/
|
||||
void mglms(G4double a, G4double z, G4int refopt4, G4double* el);
|
||||
|
||||
/**
|
||||
* Calculation of fissility parameter
|
||||
*/
|
||||
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[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);
|
||||
|
||||
/**
|
||||
* 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[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);
|
||||
|
||||
/**
|
||||
* 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[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);
|
||||
|
||||
/**
|
||||
* Calculation of tke for breakup fragments
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Calculation of particle emission barriers.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Calculation of omega at saddle point.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Calculation of even-odd effects in fission.
|
||||
*/
|
||||
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 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
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
|
||||
*/
|
||||
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
|
||||
* MASSES and DEFORMATIONS by P. Mo"ller et al. from August 16, 1993 p.
|
||||
* 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
|
||||
* 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
|
||||
*/
|
||||
void parite(G4double n, G4double* par);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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).
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Calculation of penetration factors for light charged particles.
|
||||
*/
|
||||
G4double pen(G4double A, G4double ap, G4double omega, G4double T);
|
||||
|
||||
/**
|
||||
* Calculation of mean value of orbital angular momentum.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Special functions used for the emission of particles.
|
||||
*/
|
||||
G4double erf(G4double x);
|
||||
|
||||
G4double gammp(G4double a, G4double x);
|
||||
|
||||
void gcf(G4double* gammcf, G4double a, G4double x, G4double gln);
|
||||
|
||||
void gser(G4double* gamser, G4double a, G4double x, G4double gln);
|
||||
|
||||
G4double fvmaxhaz(G4double T);
|
||||
|
||||
G4double fvmaxhaz_neut(G4double x);
|
||||
|
||||
/**
|
||||
* Random numbers.
|
||||
*/
|
||||
void standardRandom(G4double* rndm, G4long* seed);
|
||||
|
||||
/**
|
||||
* LOGARITHM OF THE GAMM FUNCTION
|
||||
*/
|
||||
G4double gammln(G4double xx);
|
||||
|
||||
/**
|
||||
* DISTRIBUTION DE MAXWELL
|
||||
*/
|
||||
G4double fd(G4double E);
|
||||
|
||||
/**
|
||||
*FONCTION INTEGRALE DE FD(E)
|
||||
*/
|
||||
G4double f(G4double E);
|
||||
|
||||
/**
|
||||
* tirage aleatoire dans une maxwellienne
|
||||
*/
|
||||
G4double fmaxhaz(G4double T);
|
||||
|
||||
/**
|
||||
* tirage aleatoire dans une maxwellienne
|
||||
*/
|
||||
G4double fmaxhaz_old(G4double T);
|
||||
|
||||
/**
|
||||
* Random generator according to the
|
||||
powerfunction y = x**(lambda) in the range from xmin to xmax
|
||||
*/
|
||||
G4int IPOWERLIMHAZ(G4double lambda, G4int xmin, G4int xmax);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void guet(G4double* x_par, G4double* z_par, G4double* find_par);
|
||||
|
||||
/**
|
||||
* Limits of existing nuclei
|
||||
*/
|
||||
void isostab_lim(G4int z, G4int* nmin, G4int* nmax);
|
||||
|
||||
/**
|
||||
* Fill the data array for INCL
|
||||
*/
|
||||
void FillData(G4int IMULTBU, G4int IEV_TAB);
|
||||
|
||||
/**
|
||||
* Separation energies of lambda
|
||||
*/
|
||||
G4double gethyperseparation(G4double A, G4double Z, G4int ny);
|
||||
|
||||
/**
|
||||
* Separation energies of for other particles for hypernuclei
|
||||
*/
|
||||
G4double getdeltabinding(G4double a, G4int nblamb);
|
||||
G4double gethyperbinding(G4double A, G4double Z, G4int ny);
|
||||
|
||||
public:
|
||||
// Utils
|
||||
G4int min(G4int a, G4int b);
|
||||
G4double min(G4double a, G4double b);
|
||||
G4int max(G4int a, G4int b);
|
||||
G4double max(G4double a, G4double b);
|
||||
G4double DSIGN(G4double a, G4double b);
|
||||
G4int ISIGN(G4int a, G4int b);
|
||||
G4int nint(G4double number);
|
||||
G4int secnds(G4int x);
|
||||
G4int mod(G4int a, G4int b);
|
||||
G4double dmod(G4double a, G4double b);
|
||||
G4double dint(G4double a);
|
||||
G4int idint(G4double a);
|
||||
G4int idnint(G4double value);
|
||||
G4double utilabs(G4double a);
|
||||
G4double dmin1(G4double a, G4double b, G4double c);
|
||||
|
||||
private:
|
||||
G4int verboseLevel;
|
||||
G4int ilast;
|
||||
G4double T_freeze_out_in;
|
||||
G4int IEV_TAB_SSC;
|
||||
G4double BU_TAB[indexpart][12], EV_TAB[indexpart][6], EV_TAB_SSC[indexpart][6];
|
||||
G4int gammaemission;
|
||||
G4double T_freeze_out;
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -34,10 +34,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
|
||||
constexpr const G4int nrows = 180;
|
||||
constexpr const G4int zcols = 122;
|
||||
|
||||
@@ -51,219 +51,232 @@ constexpr const G4int indexpart = 300;
|
||||
|
||||
// Data structures needed by ABLA evaporation code
|
||||
|
||||
class G4Mexp {
|
||||
class G4Mexp
|
||||
{
|
||||
public:
|
||||
G4Mexp() {};
|
||||
|
||||
public:
|
||||
G4Mexp(){};
|
||||
~G4Mexp() = default;
|
||||
|
||||
virtual ~G4Mexp() = default;
|
||||
|
||||
G4double massexp[lprows][lpcols] = {{0.}};
|
||||
G4double bind[lprows][lpcols] = {{0.}};
|
||||
G4int mexpiop[lprows][lpcols] = {{0}};
|
||||
G4double massexp[lprows][lpcols] = {{0.}};
|
||||
G4double bind[lprows][lpcols] = {{0.}};
|
||||
G4int mexpiop[lprows][lpcols] = {{0}};
|
||||
};
|
||||
|
||||
class G4Ec2sub {
|
||||
public:
|
||||
G4Ec2sub(){};
|
||||
class G4Ec2sub
|
||||
{
|
||||
public:
|
||||
G4Ec2sub() {};
|
||||
|
||||
virtual ~G4Ec2sub() = default;
|
||||
~G4Ec2sub() = default;
|
||||
|
||||
G4double ecnz[nrows][zcols] = {{0.}};
|
||||
G4double ecnz[nrows][zcols] = {{0.}};
|
||||
};
|
||||
|
||||
class G4Ald {
|
||||
public:
|
||||
G4Ald() : av(0.0), as(0.0), ak(0.0), optafan(0.0){};
|
||||
class G4Ald
|
||||
{
|
||||
public:
|
||||
G4Ald() : av(0.0), as(0.0), ak(0.0), optafan(0.0) {};
|
||||
|
||||
virtual ~G4Ald() = default;
|
||||
~G4Ald() = default;
|
||||
|
||||
G4double av, as, ak, optafan = 0.;
|
||||
G4double av, as, ak, optafan = 0.;
|
||||
};
|
||||
|
||||
/**
|
||||
* Shell corrections and deformations.
|
||||
**/
|
||||
|
||||
class G4Ecld {
|
||||
class G4Ecld
|
||||
{
|
||||
public:
|
||||
G4Ecld() {};
|
||||
~G4Ecld() = default;
|
||||
|
||||
public:
|
||||
G4Ecld(){};
|
||||
virtual ~G4Ecld() = default;
|
||||
/**
|
||||
* Ground state shell correction frldm for a spherical ground state.
|
||||
*/
|
||||
G4double ecgnz[nrows][zcols] = {{0.}};
|
||||
|
||||
/**
|
||||
* Ground state shell correction frldm for a spherical ground state.
|
||||
*/
|
||||
G4double ecgnz[nrows][zcols] = {{0.}};
|
||||
/**
|
||||
* Shell correction for the saddle point (now: == 0).
|
||||
*/
|
||||
G4double ecfnz[nrows][zcols] = {{0.}};
|
||||
|
||||
/**
|
||||
* Shell correction for the saddle point (now: == 0).
|
||||
*/
|
||||
G4double ecfnz[nrows][zcols] = {{0.}};
|
||||
/**
|
||||
* Difference between deformed ground state and ldm value.
|
||||
*/
|
||||
G4double vgsld[nrows][zcols] = {{0.}};
|
||||
|
||||
/**
|
||||
* Difference between deformed ground state and ldm value.
|
||||
*/
|
||||
G4double vgsld[nrows][zcols] = {{0.}};
|
||||
/**
|
||||
* Alpha ground state deformation (this is not beta2!)
|
||||
* beta2 = std::sqrt(5/(4pi)) * alpha
|
||||
*/
|
||||
G4double alpha[nrows][zcols] = {{0.}};
|
||||
|
||||
/**
|
||||
* Alpha ground state deformation (this is not beta2!)
|
||||
* beta2 = std::sqrt(5/(4pi)) * alpha
|
||||
*/
|
||||
G4double alpha[nrows][zcols] = {{0.}};
|
||||
/**
|
||||
* RMS function for lcp emission barriers
|
||||
*/
|
||||
G4double rms[nrows][zcols] = {{0.}};
|
||||
|
||||
/**
|
||||
* RMS function for lcp emission barriers
|
||||
*/
|
||||
G4double rms[nrows][zcols] = {{0.}};
|
||||
/**
|
||||
* Beta2 deformations
|
||||
*/
|
||||
G4double beta2[nrowsbeta][zcolsbeta] = {{0.}};
|
||||
|
||||
/**
|
||||
* Beta2 deformations
|
||||
*/
|
||||
G4double beta2[nrowsbeta][zcolsbeta] = {{0.}};
|
||||
|
||||
/**
|
||||
* Beta4 deformations
|
||||
*/
|
||||
G4double beta4[nrowsbeta][zcolsbeta] = {{0.}};
|
||||
/**
|
||||
* Beta4 deformations
|
||||
*/
|
||||
G4double beta4[nrowsbeta][zcolsbeta] = {{0.}};
|
||||
};
|
||||
|
||||
class G4Fiss {
|
||||
/**
|
||||
* Options and parameters for fission channel.
|
||||
*/
|
||||
class G4Fiss
|
||||
{
|
||||
/**
|
||||
* Options and parameters for fission channel.
|
||||
*/
|
||||
|
||||
public:
|
||||
G4Fiss()
|
||||
: 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){};
|
||||
public:
|
||||
G4Fiss()
|
||||
: 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;
|
||||
~G4Fiss() = default;
|
||||
|
||||
G4double bet, bethyp, ifis, ucr, dcr;
|
||||
G4int optshp, optxfis, optct, optcol, at, zt;
|
||||
G4double bet, bethyp, ifis, ucr, dcr;
|
||||
G4int optshp, optxfis, optct, optcol, at, zt;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fission barriers.
|
||||
*/
|
||||
|
||||
class G4Fb {
|
||||
class G4Fb
|
||||
{
|
||||
public:
|
||||
G4Fb() {};
|
||||
~G4Fb() = default;
|
||||
|
||||
public:
|
||||
G4Fb(){};
|
||||
virtual ~G4Fb() = default;
|
||||
|
||||
G4double efa[nrows][zcols] = {{0.}};
|
||||
G4double efa[nrows][zcols] = {{0.}};
|
||||
};
|
||||
|
||||
/**
|
||||
* Options
|
||||
*/
|
||||
|
||||
class G4Opt {
|
||||
class G4Opt
|
||||
{
|
||||
public:
|
||||
G4Opt() : optemd(0), optcha(0), optshpimf(0), optimfallowed(0), nblan0(0) {};
|
||||
|
||||
public:
|
||||
G4Opt() : optemd(0), optcha(0), optshpimf(0), optimfallowed(0), nblan0(0){};
|
||||
|
||||
virtual ~G4Opt() = default;
|
||||
~G4Opt() = default;
|
||||
|
||||
G4int optemd, optcha, optshpimf, optimfallowed, nblan0;
|
||||
G4int optemd, optcha, optshpimf, optimfallowed, nblan0;
|
||||
};
|
||||
|
||||
class G4VarNtp {
|
||||
public:
|
||||
G4VarNtp() { clear(); };
|
||||
class G4VarNtp
|
||||
{
|
||||
public:
|
||||
G4VarNtp() { clear(); };
|
||||
|
||||
virtual ~G4VarNtp() = default;
|
||||
~G4VarNtp() = default;
|
||||
|
||||
void clear() {
|
||||
ntrack = 0;
|
||||
kfis = 0;
|
||||
itypcasc.clear();
|
||||
avv.clear();
|
||||
zvv.clear();
|
||||
svv.clear();
|
||||
enerj.clear();
|
||||
pxlab.clear();
|
||||
pylab.clear();
|
||||
pzlab.clear();
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
ntrack = 0;
|
||||
kfis = 0;
|
||||
itypcasc.clear();
|
||||
avv.clear();
|
||||
zvv.clear();
|
||||
svv.clear();
|
||||
enerj.clear();
|
||||
pxlab.clear();
|
||||
pylab.clear();
|
||||
pzlab.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fission 1/0=Y/N.
|
||||
*/
|
||||
G4int kfis;
|
||||
/**
|
||||
* Fission 1/0=Y/N.
|
||||
*/
|
||||
G4int kfis;
|
||||
|
||||
/**
|
||||
* Excit energy at fis.
|
||||
*/
|
||||
G4double estfis = 0.;
|
||||
/**
|
||||
* Excit energy at fis.
|
||||
*/
|
||||
G4double estfis = 0.;
|
||||
|
||||
/**
|
||||
* Z of fiss nucleus.
|
||||
*/
|
||||
G4int izfis = 0;
|
||||
/**
|
||||
* Z of fiss nucleus.
|
||||
*/
|
||||
G4int izfis = 0;
|
||||
|
||||
/**
|
||||
* A of fiss nucleus.
|
||||
*/
|
||||
G4int iafis = 0;
|
||||
/**
|
||||
* A of fiss nucleus.
|
||||
*/
|
||||
G4int iafis = 0;
|
||||
|
||||
/**
|
||||
* Number of particles.
|
||||
*/
|
||||
G4int ntrack;
|
||||
/**
|
||||
* Number of particles.
|
||||
*/
|
||||
G4int ntrack;
|
||||
|
||||
/**
|
||||
* Does this nucleus require Fermi break-up treatment? Only
|
||||
* applicable when used together with Geant4.
|
||||
* true = do fermi break-up (and skip ABLA part)
|
||||
* false = use ABLA
|
||||
*/
|
||||
G4bool needsFermiBreakup = false;
|
||||
/**
|
||||
* Does this nucleus require Fermi break-up treatment? Only
|
||||
* applicable when used together with Geant4.
|
||||
* true = do fermi break-up (and skip ABLA part)
|
||||
* false = use ABLA
|
||||
*/
|
||||
G4bool needsFermiBreakup = false;
|
||||
|
||||
/**
|
||||
* emitted in cascade (0) or evaporation (1).
|
||||
*/
|
||||
std::vector<G4int> itypcasc;
|
||||
/**
|
||||
* emitted in cascade (0) or evaporation (1).
|
||||
*/
|
||||
std::vector<G4int> itypcasc;
|
||||
|
||||
/**
|
||||
* A (-1 for pions).
|
||||
*/
|
||||
std::vector<G4int> avv;
|
||||
/**
|
||||
* A (-1 for pions).
|
||||
*/
|
||||
std::vector<G4int> avv;
|
||||
|
||||
/**
|
||||
* Z
|
||||
*/
|
||||
std::vector<G4int> zvv;
|
||||
/**
|
||||
* Z
|
||||
*/
|
||||
std::vector<G4int> zvv;
|
||||
|
||||
/**
|
||||
* S (-1 for lambda_0).
|
||||
*/
|
||||
std::vector<G4int> svv;
|
||||
/**
|
||||
* S (-1 for lambda_0).
|
||||
*/
|
||||
std::vector<G4int> svv;
|
||||
|
||||
/**
|
||||
* Kinetic energy.
|
||||
*/
|
||||
std::vector<G4double> enerj;
|
||||
/**
|
||||
* Kinetic energy.
|
||||
*/
|
||||
std::vector<G4double> enerj;
|
||||
|
||||
/**
|
||||
* Momentum.
|
||||
*/
|
||||
std::vector<G4double> plab;
|
||||
std::vector<G4double> pxlab;
|
||||
std::vector<G4double> pylab;
|
||||
std::vector<G4double> pzlab;
|
||||
/**
|
||||
* Momentum.
|
||||
*/
|
||||
std::vector<G4double> plab;
|
||||
std::vector<G4double> pxlab;
|
||||
std::vector<G4double> pylab;
|
||||
std::vector<G4double> pzlab;
|
||||
|
||||
/**
|
||||
* Theta angle.
|
||||
*/
|
||||
std::vector<G4double> tetlab;
|
||||
|
||||
/**
|
||||
* Phi angle.
|
||||
*/
|
||||
std::vector<G4double> philab;
|
||||
/**
|
||||
* Theta angle.
|
||||
*/
|
||||
std::vector<G4double> tetlab;
|
||||
|
||||
/**
|
||||
* Phi angle.
|
||||
*/
|
||||
std::vector<G4double> philab;
|
||||
};
|
||||
|
||||
@@ -39,17 +39,17 @@
|
||||
/**
|
||||
* Read ABLA data from files.
|
||||
*/
|
||||
class G4AblaDataFile : public G4AblaVirtualData {
|
||||
class G4AblaDataFile : public G4AblaVirtualData
|
||||
{
|
||||
public:
|
||||
G4AblaDataFile();
|
||||
virtual ~G4AblaDataFile() = default;
|
||||
|
||||
public:
|
||||
G4AblaDataFile();
|
||||
virtual ~G4AblaDataFile() = default;
|
||||
/**
|
||||
* Read all data from files.
|
||||
*/
|
||||
G4bool readData();
|
||||
|
||||
/**
|
||||
* Read all data from files.
|
||||
*/
|
||||
G4bool readData();
|
||||
|
||||
private:
|
||||
G4int verboseLevel;
|
||||
private:
|
||||
G4int verboseLevel;
|
||||
};
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
#include "G4Abla.hh"
|
||||
#include "G4Fragment.hh"
|
||||
#include "G4HadFinalState.hh"
|
||||
@@ -42,41 +40,42 @@
|
||||
#include "G4Nucleus.hh"
|
||||
#include "G4ReactionProduct.hh"
|
||||
#include "G4VPreCompoundModel.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
class G4ExcitationHandler;
|
||||
class G4HadFinalState;
|
||||
|
||||
class G4AblaInterface : public G4VPreCompoundModel {
|
||||
public:
|
||||
G4AblaInterface(G4ExcitationHandler *ptr = nullptr);
|
||||
virtual ~G4AblaInterface();
|
||||
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 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:
|
||||
G4HadFinalState applyYourselfResult;
|
||||
G4VarNtp *ablaResult;
|
||||
G4Abla *theABLAModel;
|
||||
G4long eventNumber;
|
||||
G4int secID; // Creator model ID for the secondaries created by ABLA
|
||||
private:
|
||||
G4HadFinalState applyYourselfResult;
|
||||
G4VarNtp* ablaResult;
|
||||
G4Abla* theABLAModel;
|
||||
G4long eventNumber;
|
||||
G4int secID; // Creator model ID for the secondaries created by ABLA
|
||||
|
||||
G4bool isInitialised;
|
||||
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;
|
||||
/// \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;
|
||||
|
||||
/// \brief Convert A, Z and S to a G4ParticleDefinition
|
||||
G4ParticleDefinition *toG4ParticleDefinition(G4int A, G4int Z, G4int S) const;
|
||||
/// \brief Convert A, Z and S to a G4ParticleDefinition
|
||||
G4ParticleDefinition* toG4ParticleDefinition(G4int A, G4int Z, G4int S) const;
|
||||
};
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
namespace G4AblaRandom {
|
||||
namespace G4AblaRandom
|
||||
{
|
||||
G4double flat();
|
||||
}
|
||||
|
||||
@@ -42,111 +42,112 @@
|
||||
* G4AblaDataFile
|
||||
*/
|
||||
|
||||
class G4AblaVirtualData {
|
||||
protected:
|
||||
/**
|
||||
* Constructor, destructor
|
||||
*/
|
||||
G4AblaVirtualData();
|
||||
class G4AblaVirtualData
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* Constructor, destructor
|
||||
*/
|
||||
G4AblaVirtualData();
|
||||
|
||||
virtual ~G4AblaVirtualData() = default;
|
||||
virtual ~G4AblaVirtualData() = default;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Set the value of Alpha.
|
||||
*/
|
||||
G4bool setAlpha(G4int A, G4int Z, G4double value);
|
||||
public:
|
||||
/**
|
||||
* Set the value of Alpha.
|
||||
*/
|
||||
G4bool setAlpha(G4int A, G4int Z, G4double value);
|
||||
|
||||
/**
|
||||
* Set the value of Ecnz.
|
||||
*/
|
||||
G4bool setEcnz(G4int A, G4int Z, G4double value);
|
||||
/**
|
||||
* Set the value of Ecnz.
|
||||
*/
|
||||
G4bool setEcnz(G4int A, G4int Z, G4double value);
|
||||
|
||||
/**
|
||||
* Set the value of Vgsld.
|
||||
*/
|
||||
G4bool setVgsld(G4int A, G4int Z, G4double value);
|
||||
/**
|
||||
* Set the value of Vgsld.
|
||||
*/
|
||||
G4bool setVgsld(G4int A, G4int Z, G4double value);
|
||||
|
||||
/**
|
||||
* Set the value of RMS.
|
||||
*/
|
||||
G4bool setRms(G4int A, G4int Z, G4double value);
|
||||
/**
|
||||
* Set the value of RMS.
|
||||
*/
|
||||
G4bool setRms(G4int A, G4int Z, G4double value);
|
||||
|
||||
/**
|
||||
* Set the value of experimental masses.
|
||||
*/
|
||||
G4bool setMexp(G4int A, G4int Z, G4double value);
|
||||
/**
|
||||
* Set the value of experimental masses.
|
||||
*/
|
||||
G4bool setMexp(G4int A, G4int Z, G4double value);
|
||||
|
||||
/**
|
||||
* Set the value of experimental masses ID.
|
||||
*/
|
||||
G4bool setMexpID(G4int A, G4int Z, G4int value);
|
||||
/**
|
||||
* Set the value of experimental masses ID.
|
||||
*/
|
||||
G4bool setMexpID(G4int A, G4int Z, G4int value);
|
||||
|
||||
/**
|
||||
* Set the value of beta2 deformation.
|
||||
*/
|
||||
G4bool setBeta2(G4int A, G4int Z, G4double value);
|
||||
/**
|
||||
* Set the value of beta2 deformation.
|
||||
*/
|
||||
G4bool setBeta2(G4int A, G4int Z, G4double value);
|
||||
|
||||
/**
|
||||
* Set the value of beta4 deformation.
|
||||
*/
|
||||
G4bool setBeta4(G4int A, G4int Z, G4double value);
|
||||
/**
|
||||
* Set the value of beta4 deformation.
|
||||
*/
|
||||
G4bool setBeta4(G4int A, G4int Z, G4double value);
|
||||
|
||||
/**
|
||||
* Get the value of Alpha.
|
||||
*/
|
||||
G4double getAlpha(G4int A, G4int Z);
|
||||
/**
|
||||
* Get the value of Alpha.
|
||||
*/
|
||||
G4double getAlpha(G4int A, G4int Z);
|
||||
|
||||
/**
|
||||
* Get the value of Ecnz.
|
||||
*/
|
||||
G4double getEcnz(G4int A, G4int Z);
|
||||
/**
|
||||
* Get the value of Ecnz.
|
||||
*/
|
||||
G4double getEcnz(G4int A, G4int Z);
|
||||
|
||||
/**
|
||||
* Get the value of Vgsld.
|
||||
*/
|
||||
G4double getVgsld(G4int A, G4int Z);
|
||||
/**
|
||||
* Get the value of Vgsld.
|
||||
*/
|
||||
G4double getVgsld(G4int A, G4int Z);
|
||||
|
||||
/*
|
||||
* Get the value of RMS.
|
||||
*/
|
||||
G4double getRms(G4int A, G4int Z);
|
||||
/*
|
||||
* Get the value of RMS.
|
||||
*/
|
||||
G4double getRms(G4int A, G4int Z);
|
||||
|
||||
/**
|
||||
* Get the value of experimental masses.
|
||||
*/
|
||||
G4double getMexp(G4int A, G4int Z);
|
||||
/**
|
||||
* Get the value of experimental masses.
|
||||
*/
|
||||
G4double getMexp(G4int A, G4int Z);
|
||||
|
||||
/**
|
||||
* Get the value of experimental masses ID.
|
||||
*/
|
||||
G4int getMexpID(G4int A, G4int Z);
|
||||
/**
|
||||
* Get the value of experimental masses ID.
|
||||
*/
|
||||
G4int getMexpID(G4int A, G4int Z);
|
||||
|
||||
/**
|
||||
* Get the value of beta2 deformation.
|
||||
*/
|
||||
G4double getBeta2(G4int A, G4int Z);
|
||||
/**
|
||||
* Get the value of beta2 deformation.
|
||||
*/
|
||||
G4double getBeta2(G4int A, G4int Z);
|
||||
|
||||
/**
|
||||
* Get the value of beta4 deformation.
|
||||
*/
|
||||
G4double getBeta4(G4int A, G4int Z);
|
||||
/**
|
||||
* Get the value of beta4 deformation.
|
||||
*/
|
||||
G4double getBeta4(G4int A, G4int Z);
|
||||
|
||||
virtual G4bool readData() = 0;
|
||||
virtual G4bool readData() = 0;
|
||||
|
||||
private:
|
||||
static const G4int sRows = 180;
|
||||
static const G4int sCols = 122;
|
||||
private:
|
||||
static const G4int sRows = 180;
|
||||
static const G4int sCols = 122;
|
||||
|
||||
static const G4int betaRows = sCols + sRows;
|
||||
static const G4int betaCols = 137;
|
||||
static const G4int betaRows = sCols + sRows;
|
||||
static const G4int betaCols = 137;
|
||||
|
||||
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];
|
||||
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];
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,7 @@
|
||||
//
|
||||
|
||||
#include "G4AblaDataFile.hh"
|
||||
|
||||
#include "G4AblaDataDefs.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
@@ -40,154 +41,144 @@
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
G4AblaDataFile::G4AblaDataFile() { verboseLevel = 0; }
|
||||
G4AblaDataFile::G4AblaDataFile()
|
||||
{
|
||||
verboseLevel = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all data from files.
|
||||
*/
|
||||
G4bool G4AblaDataFile::readData()
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
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());
|
||||
|
||||
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;
|
||||
}
|
||||
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");
|
||||
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);
|
||||
}
|
||||
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
// G4cout <<"Data path = " << dataPath << G4endl;
|
||||
// G4cout <<"FlAlphaFile = " << flAlphaFile << G4endl;
|
||||
// G4cout <<"FrldmFile = " << frldmFile << G4endl;
|
||||
// G4cout <<"VgsldFile = " << vgsldFile << G4endl;
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
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 (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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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;
|
||||
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);
|
||||
}
|
||||
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;
|
||||
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();
|
||||
flalphain.close();
|
||||
frldmin.close();
|
||||
vgsldin.close();
|
||||
rmsin.close();
|
||||
defoin.close();
|
||||
massin.close();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -31,11 +31,8 @@
|
||||
// Aatos Heikkinen, HIP (project coordination)
|
||||
//
|
||||
|
||||
#include "globals.hh"
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
#include "G4AblaInterface.hh"
|
||||
|
||||
#include "G4DoubleHyperDoubleNeutron.hh"
|
||||
#include "G4DoubleHyperH4.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
@@ -51,236 +48,229 @@
|
||||
#include "G4ReactionProduct.hh"
|
||||
#include "G4ReactionProductVector.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
G4AblaInterface::G4AblaInterface(G4ExcitationHandler* ptr)
|
||||
: G4VPreCompoundModel(ptr, "ABLAXX")
|
||||
, ablaResult(new G4VarNtp)
|
||||
, theABLAModel(new G4Abla(ablaResult))
|
||||
, eventNumber(0)
|
||||
, secID(-1)
|
||||
, isInitialised(false)
|
||||
: 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 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)
|
||||
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;
|
||||
}
|
||||
// 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);
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
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();
|
||||
if (!isInitialised) InitialiseModel();
|
||||
|
||||
ablaResult->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;
|
||||
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;
|
||||
++eventNumber;
|
||||
|
||||
theABLAModel->DeexcitationAblaxx(ARem, ZRem, eStarRem, jRem, pxRem, pyRem, pzRem, (G4int)eventNumber, SRem);
|
||||
theABLAModel->DeexcitationAblaxx(ARem, ZRem, eStarRem, jRem, pxRem, pyRem, pzRem,
|
||||
(G4int)eventNumber, SRem);
|
||||
|
||||
G4ReactionProductVector* result = new G4ReactionProductVector;
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
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
|
||||
{ // Error, unrecognized particle
|
||||
G4cout << "Can't convert particle with A=" << A << ", Z=" << Z << ", S=" << S
|
||||
<< " to G4ParticleDefinition, trouble ahead" << G4endl;
|
||||
return 0;
|
||||
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 { // 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
|
||||
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;
|
||||
}
|
||||
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, 4–8 February 2008, edited by D. Filges, S. "
|
||||
"Leray, Y. Yariv, A. Mengoni, A. Stanculescu, and G. Mank (IAEA "
|
||||
"INDC(NDS)-530, Vienna, 2008), pp. 181–221.\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";
|
||||
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, 4–8 February 2008, edited by D. Filges, S. "
|
||||
"Leray, Y. Yariv, A. Mengoni, A. Stanculescu, and G. Mank (IAEA "
|
||||
"INDC(NDS)-530, Vienna, 2008), pp. 181–221.\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";
|
||||
}
|
||||
|
||||
@@ -32,11 +32,15 @@
|
||||
//
|
||||
|
||||
#include "G4AblaRandom.hh"
|
||||
|
||||
#include "Randomize.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
namespace G4AblaRandom
|
||||
{
|
||||
|
||||
G4double flat() { return G4UniformRand(); }
|
||||
} // namespace G4AblaRandom
|
||||
G4double flat()
|
||||
{
|
||||
return G4UniformRand();
|
||||
}
|
||||
} // namespace G4AblaRandom
|
||||
|
||||
@@ -32,78 +32,103 @@
|
||||
//
|
||||
|
||||
#include "G4AblaVirtualData.hh"
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
G4AblaVirtualData::G4AblaVirtualData() {}
|
||||
|
||||
G4bool G4AblaVirtualData::setAlpha(G4int A, G4int Z, G4double value)
|
||||
{
|
||||
alpha[A][Z] = value;
|
||||
alpha[A][Z] = value;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
G4bool G4AblaVirtualData::setEcnz(G4int A, G4int Z, G4double value)
|
||||
{
|
||||
ecnz[A][Z] = value;
|
||||
ecnz[A][Z] = value;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
G4bool G4AblaVirtualData::setVgsld(G4int A, G4int Z, G4double value)
|
||||
{
|
||||
vgsld[A][Z] = value;
|
||||
vgsld[A][Z] = value;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
G4bool G4AblaVirtualData::setRms(G4int A, G4int Z, G4double value)
|
||||
{
|
||||
rms[A][Z] = value;
|
||||
rms[A][Z] = value;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
G4bool G4AblaVirtualData::setMexp(G4int A, G4int Z, G4double value)
|
||||
{
|
||||
mexp[A][Z] = value;
|
||||
mexp[A][Z] = value;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
G4bool G4AblaVirtualData::setMexpID(G4int A, G4int Z, G4int value)
|
||||
{
|
||||
mexpid[A][Z] = value;
|
||||
mexpid[A][Z] = value;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
G4bool G4AblaVirtualData::setBeta2(G4int A, G4int Z, G4double value)
|
||||
{
|
||||
beta2[A][Z] = value;
|
||||
beta2[A][Z] = value;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
G4bool G4AblaVirtualData::setBeta4(G4int A, G4int Z, G4double value)
|
||||
{
|
||||
beta4[A][Z] = value;
|
||||
beta4[A][Z] = value;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
G4double G4AblaVirtualData::getAlpha(G4int A, G4int Z) { return alpha[A][Z]; }
|
||||
G4double G4AblaVirtualData::getAlpha(G4int A, G4int Z)
|
||||
{
|
||||
return alpha[A][Z];
|
||||
}
|
||||
|
||||
G4double G4AblaVirtualData::getEcnz(G4int A, G4int Z) { return ecnz[A][Z]; }
|
||||
G4double G4AblaVirtualData::getEcnz(G4int A, G4int Z)
|
||||
{
|
||||
return ecnz[A][Z];
|
||||
}
|
||||
|
||||
G4double G4AblaVirtualData::getVgsld(G4int A, G4int Z) { return vgsld[A][Z]; }
|
||||
G4double G4AblaVirtualData::getVgsld(G4int A, G4int Z)
|
||||
{
|
||||
return vgsld[A][Z];
|
||||
}
|
||||
|
||||
G4double G4AblaVirtualData::getRms(G4int A, G4int Z) { return rms[A][Z]; }
|
||||
G4double G4AblaVirtualData::getRms(G4int A, G4int Z)
|
||||
{
|
||||
return rms[A][Z];
|
||||
}
|
||||
|
||||
G4double G4AblaVirtualData::getMexp(G4int A, G4int Z) { return mexp[A][Z]; }
|
||||
G4double G4AblaVirtualData::getMexp(G4int A, G4int Z)
|
||||
{
|
||||
return mexp[A][Z];
|
||||
}
|
||||
|
||||
G4int G4AblaVirtualData::getMexpID(G4int A, G4int Z) { return mexpid[A][Z]; }
|
||||
G4int G4AblaVirtualData::getMexpID(G4int A, G4int Z)
|
||||
{
|
||||
return mexpid[A][Z];
|
||||
}
|
||||
|
||||
G4double G4AblaVirtualData::getBeta2(G4int A, G4int Z) { return beta2[A][Z]; }
|
||||
G4double G4AblaVirtualData::getBeta2(G4int A, G4int Z)
|
||||
{
|
||||
return beta2[A][Z];
|
||||
}
|
||||
|
||||
G4double G4AblaVirtualData::getBeta4(G4int A, G4int Z) { return beta4[A][Z]; }
|
||||
G4double G4AblaVirtualData::getBeta4(G4int A, G4int Z)
|
||||
{
|
||||
return beta4[A][Z];
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-11-26 Vladimir ivanchenko (hadr-casc-V11-03-01)
|
||||
- G4BigBanger - fixed typo in the computation of probability, which is
|
||||
identified by the new compiler and should not change any result.
|
||||
|
||||
## 2025-04-22 Alberto Ribon (hadr-casc-V11-03-00)
|
||||
- G4CascadeFinalStateAlgorithm, G4NucleiModel : introduced the possibility to
|
||||
retrieve either the behavior of these classes as in Geant4 version 11.3
|
||||
|
||||
@@ -299,7 +299,7 @@ G4double G4BigBanger::xProbability(G4double x, G4int a) const {
|
||||
G4Pow* theG4Pow = G4Pow::GetInstance(); // For convenience
|
||||
|
||||
G4double ekpr = 0.0;
|
||||
if(x < 1.0 || x > 0.0) {
|
||||
if (x < 1.0 && x > 0.0) {
|
||||
ekpr = x * x;
|
||||
|
||||
if (a%2 == 0) { // even A
|
||||
|
||||
@@ -6,6 +6,15 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-11-25 Vladimir Ivanchenko (hadr-cohe-V11-03-05)
|
||||
- G4NuclNuclDiffuseElastic, G4DiffuseElastic, G4AntiNuclElastic - fixed
|
||||
compilation warnings.
|
||||
|
||||
## 2025-10-27 Vladimir Ivanchenko (hadr-cohe-V11-03-04)
|
||||
- G4ChargeExchange - implemented angular distribution of pion charge exchange
|
||||
according to the V. Lubovitsky parameterisation for different reaction
|
||||
channels.
|
||||
|
||||
## 2025-05-15 Vladimir Ivanchenko (hadr-cohe-V11-03-03)
|
||||
- G4ChargeExchange, G4HadronElastic - cleanup final state generation: use
|
||||
the numerical limit for argument of the exponent to avoid precision loss;
|
||||
|
||||
@@ -368,34 +368,23 @@ G4double G4AntiNuclElastic::SampleInvariantT(const G4ParticleDefinition* particl
|
||||
G4double G4AntiNuclElastic::SampleThetaCMS(const G4ParticleDefinition* p, G4double plab,
|
||||
G4int Z, G4int A)
|
||||
{
|
||||
G4double T;
|
||||
T = SampleInvariantT( p, plab, Z, A);
|
||||
G4double T = SampleInvariantT( p, plab, Z, A);
|
||||
if (T <= 0.0 || fTmax <= 0.0) { return 1.0; }
|
||||
|
||||
// NaN finder
|
||||
if(!(T < 0.0 || T >= 0.0))
|
||||
// NaN finder substituted by simple check
|
||||
if (T > fTmax)
|
||||
{
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << "G4DiffuseElastic:WARNING: A = " << A
|
||||
<< " mom(GeV)= " << plab/GeV
|
||||
<< " S-wave will be sampled"
|
||||
G4cout << "G4AntiNuclElastic::SampleThetaCMS WARNING: A = " << A
|
||||
<< " mom(GeV)=" << plab/GeV << " t(GeV2)=" << T/(GeV*GeV)
|
||||
<< " > Tmax(GeV2)=" << fTmax/(GeV*GeV) << " S-wave will be sampled"
|
||||
<< G4endl;
|
||||
}
|
||||
T = G4UniformRand()*fTmax;
|
||||
|
||||
}
|
||||
|
||||
if(fptot > 0.)
|
||||
{
|
||||
G4double cosTet=1.0-T/(2.*fptot*fptot);
|
||||
if(cosTet > 1.0 ) cosTet= 1.;
|
||||
if(cosTet < -1.0 ) cosTet=-1.;
|
||||
fTetaCMS=std::acos(cosTet);
|
||||
return fTetaCMS;
|
||||
} else
|
||||
{
|
||||
return 2.*G4UniformRand()-1.;
|
||||
}
|
||||
G4double cosTet = 1.0 - 2*T/fTmax;
|
||||
return cosTet;
|
||||
}
|
||||
|
||||
|
||||
@@ -404,42 +393,25 @@ G4double G4AntiNuclElastic::SampleInvariantT(const G4ParticleDefinition* particl
|
||||
G4double G4AntiNuclElastic::SampleThetaLab(const G4ParticleDefinition* p, G4double plab,
|
||||
G4int Z, G4int A)
|
||||
{
|
||||
G4double T;
|
||||
T = SampleInvariantT( p, plab, Z, A);
|
||||
G4double T = SampleInvariantT( p, plab, Z, A);
|
||||
if (T <= 0.0 || fTmax <= 0.0) { return 1.0; }
|
||||
|
||||
// NaN finder
|
||||
if(!(T < 0.0 || T >= 0.0))
|
||||
// NaN finder substituted by simple check
|
||||
if (T > fTmax)
|
||||
{
|
||||
if (verboseLevel > 0)
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << "G4DiffuseElastic:WARNING: A = " << A
|
||||
<< " mom(GeV)= " << plab/GeV
|
||||
<< " S-wave will be sampled"
|
||||
G4cout << "G4AntiNuclElastic::SampleThetaLab WARNING: A = " << A
|
||||
<< " mom(GeV)=" << plab/GeV << " t(GeV2)=" << T/(GeV*GeV)
|
||||
<< " > Tmax(GeV2)=" << fTmax/(GeV*GeV) << " S-wave will be sampled"
|
||||
<< G4endl;
|
||||
}
|
||||
T = G4UniformRand()*fTmax;
|
||||
}
|
||||
|
||||
G4double phi = G4UniformRand()*twopi;
|
||||
|
||||
G4double cost(1.);
|
||||
if(fTmax > 0.) {cost = 1. - 2.0*T/fTmax;}
|
||||
|
||||
G4double sint;
|
||||
if( cost >= 1.0 )
|
||||
{
|
||||
cost = 1.0;
|
||||
sint = 0.0;
|
||||
}
|
||||
else if( cost <= -1.0)
|
||||
{
|
||||
cost = -1.0;
|
||||
sint = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sint = std::sqrt((1.0-cost)*(1.0+cost));
|
||||
}
|
||||
G4double cost = 1.0 - 2*T/fTmax;
|
||||
G4double phi = G4UniformRand()*twopi;
|
||||
G4double sint = std::sqrt((1.0-cost)*(1.0+cost));
|
||||
|
||||
G4double m1 = p->GetPDGMass();
|
||||
G4ThreeVector v(sint*std::cos(phi),sint*std::sin(phi),cost);
|
||||
|
||||
@@ -89,14 +89,13 @@ G4HadFinalState* G4ChargeExchange::ApplyYourself(
|
||||
|
||||
G4int A = targetNucleus.GetA_asInt();
|
||||
G4int Z = targetNucleus.GetZ_asInt();
|
||||
|
||||
|
||||
if (ekin <= lowEnergyLimit) {
|
||||
return &theParticleChange;
|
||||
}
|
||||
theParticleChange.SetWeightChange(fXSWeightFactor);
|
||||
|
||||
G4int projPDG = part->GetPDGEncoding();
|
||||
|
||||
// for hydrogen targets and positive projectile change exchange
|
||||
// is not possible on proton, only on deuteron
|
||||
if (1 == Z && (211 == projPDG || 321 == projPDG)) { A = 2; }
|
||||
@@ -196,14 +195,20 @@ G4HadFinalState* G4ChargeExchange::ApplyYourself(
|
||||
// not possible kinematically
|
||||
if (!ok) { return &theParticleChange; }
|
||||
|
||||
// tmax = 4*momCMS^2
|
||||
G4double e2 = (m0*m0 + mass2*mass2 - mass3*mass3)/(2*m0);
|
||||
G4double momentumCMS = std::sqrt(e2*e2 - mass2*mass2);
|
||||
|
||||
G4double tmax = 4*(momentumCMS*momentumCMS);
|
||||
G4double t = SampleT(theSecondary, A, tmax);
|
||||
|
||||
G4double phi = G4UniformRand()*CLHEP::twopi;
|
||||
G4double tmax = 4*momentumCMS*momentumCMS;
|
||||
|
||||
// for projectile pion t depends on final state
|
||||
G4double t;
|
||||
if (fXSection->isPion()) {
|
||||
t = fXSection->SampleTforPion(aTrack.GetTotalEnergy(), tmax);
|
||||
}
|
||||
else {
|
||||
t = SampleT(theSecondary, A, tmax);
|
||||
}
|
||||
|
||||
G4double phi = G4UniformRand()*CLHEP::twopi;
|
||||
G4double cost = 1. - 2.0*t/tmax;
|
||||
|
||||
// if cos(theta) negative, there is a numerical problem
|
||||
@@ -211,7 +216,7 @@ G4HadFinalState* G4ChargeExchange::ApplyYourself(
|
||||
// no scattering
|
||||
if (std::abs(cost) > 1.0) { cost = 1.0; }
|
||||
|
||||
G4double sint = std::sqrt((1.0-cost)*(1.0+cost));
|
||||
G4double sint = std::sqrt((1.0 - cost)*(1.0 + cost));
|
||||
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << " t= " << t << " tmax(GeV^2)= " << tmax/(GeV*GeV)
|
||||
|
||||
@@ -1158,9 +1158,10 @@ G4DiffuseElastic::SampleThetaLab( const G4HadProjectile* aParticle,
|
||||
//
|
||||
|
||||
t = SampleT( theParticle, ptot, A);
|
||||
if (t <= 0.0) { return 0.0; }
|
||||
|
||||
// NaN finder
|
||||
if(!(t < 0.0 || t >= 0.0))
|
||||
// NaN finder substituted
|
||||
if (t > tmax)
|
||||
{
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
@@ -1180,22 +1181,8 @@ G4DiffuseElastic::SampleThetaLab( const G4HadProjectile* aParticle,
|
||||
|
||||
G4double phi = G4UniformRand()*twopi;
|
||||
G4double cost = 1. - 2.0*t/tmax;
|
||||
G4double sint;
|
||||
|
||||
if( cost >= 1.0 )
|
||||
{
|
||||
cost = 1.0;
|
||||
sint = 0.0;
|
||||
}
|
||||
else if( cost <= -1.0)
|
||||
{
|
||||
cost = -1.0;
|
||||
sint = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sint = std::sqrt((1.0-cost)*(1.0+cost));
|
||||
}
|
||||
G4double sint = std::sqrt((1.0-cost)*(1.0+cost));
|
||||
|
||||
if (verboseLevel>1)
|
||||
{
|
||||
G4cout << "cos(t)=" << cost << " std::sin(t)=" << sint << G4endl;
|
||||
|
||||
@@ -1119,13 +1119,9 @@ G4NuclNuclDiffuseElastic:: GetScatteringAngle( G4int iMomentum, G4int iAngle, G4
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Return scattering angle sampled in lab system (target at rest)
|
||||
|
||||
|
||||
|
||||
G4double
|
||||
G4NuclNuclDiffuseElastic::SampleThetaLab( const G4HadProjectile* aParticle,
|
||||
G4double tmass, G4double A)
|
||||
@@ -1145,15 +1141,15 @@ G4NuclNuclDiffuseElastic::SampleThetaLab( const G4HadProjectile* aParticle,
|
||||
G4double tmax = 4.0*ptot*ptot;
|
||||
G4double t = 0.0;
|
||||
|
||||
|
||||
//
|
||||
// Sample t
|
||||
//
|
||||
|
||||
t = SampleT( theParticle, ptot, A);
|
||||
if (t <= 0.0) { return 0.0; }
|
||||
|
||||
// NaN finder
|
||||
if(!(t < 0.0 || t >= 0.0))
|
||||
if (t > tmax)
|
||||
{
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
@@ -1173,22 +1169,8 @@ G4NuclNuclDiffuseElastic::SampleThetaLab( const G4HadProjectile* aParticle,
|
||||
|
||||
G4double phi = G4UniformRand()*twopi;
|
||||
G4double cost = 1. - 2.0*t/tmax;
|
||||
G4double sint;
|
||||
G4double sint = std::sqrt((1.0-cost)*(1.0+cost));
|
||||
|
||||
if( cost >= 1.0 )
|
||||
{
|
||||
cost = 1.0;
|
||||
sint = 0.0;
|
||||
}
|
||||
else if( cost <= -1.0)
|
||||
{
|
||||
cost = -1.0;
|
||||
sint = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sint = std::sqrt((1.0-cost)*(1.0+cost));
|
||||
}
|
||||
if (verboseLevel>1)
|
||||
{
|
||||
G4cout << "cos(t)=" << cost << " std::sin(t)=" << sint << G4endl;
|
||||
|
||||
@@ -6,6 +6,70 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-11-09 Vladimir Ivanchenko (hadr-deex-V11-03-25)
|
||||
- G4LevelReader, G4GammaTransition, G4photonEvaporation - fixed Bugzilla
|
||||
problems #2672, #2588, #2451. The vector of IC probabilities is limited by
|
||||
number of levels in an atom; if in gamma level data all IC transitions are
|
||||
zero, then instead of K-shell probability 1.0 is assigned to the last
|
||||
existing level; electron emission is sampled if nuclear excitation is above
|
||||
the bound level and if number of electrons on electron shell is above 1;
|
||||
more accurate sampling of final state using masses of the nucleus plus
|
||||
masses of electrons from electron shells.
|
||||
|
||||
## 2025-11-04 Vladimir Ivanchenko (hadr-deex-V11-03-24)
|
||||
- G4StatMFMicroCanonical - N. Chalyi fixed computation of temperature
|
||||
- G4DeexPrecoParameters - upper limit of energy per nucleon for the
|
||||
pre-compound model is reduced from 30 to 15 MeV according to the
|
||||
prescription of Botvina A. S. et al. Nucl. Phys. A, 475:663, 1987.
|
||||
|
||||
## 2025-10-18 Vladimir Ivanchenko (hadr-deex-V11-03-23)
|
||||
- G4StatMFMicroCanonical - hard-coded solver was implemented inside the class,
|
||||
which is substituted by usage of G4FunctionSolver, surface energy computation
|
||||
bug is fixed, unnecessary computations are removed.
|
||||
|
||||
## 2025-10-12 Vladimir Ivanchenko (hadr-deex-V11-03-22)
|
||||
- multifragmentation models are using G4FunctionSolver instead of G4Solver
|
||||
- G4CoulombBarrier, G4DeexPrecoUtils, G4EvaporationFragment, G4EvaporationProbability
|
||||
- G4EvaporationGEMFactoryVI - use the default evaporation for neutrons, protons,
|
||||
and light ions
|
||||
- G4GEMChannelVI - used G4DeexPrecoUtils
|
||||
|
||||
## 2025-10-08 Ben Morgan (hadr-deex-V11-03-21)
|
||||
- Emit fatal exception in G4LevelReader if path to G4LEVELGAMMADATA is empty
|
||||
- Addresses Issue #236
|
||||
|
||||
## 2025-09-09 Vladimir Ivanchenko (hadr-deex-V11-03-20)
|
||||
- G4StatMF, G4StatMFMicroCanonical, G4Evaporation - fixed Coverity warnings.
|
||||
|
||||
## 2025-08-31 Vladimir Ivanchenko (hadr-deex-V11-03-19)
|
||||
- G4FermiBreakUpVI - removed the limit on excitation energy from the condition
|
||||
of the model applicability, the model become similar to G4FermiBreakUpAN
|
||||
in this respect.
|
||||
- G4DeexPrecoParameters - define limits maxZ=9, maxA=17 instead of maxZ=3
|
||||
maxA=5. This means that Fermi BreakUp models will be used for light fragment
|
||||
de-excitation, which happens in high energy ion collision with light targets.
|
||||
|
||||
## 2025-08-15 Vladimir Ivanchenko (hadr-deex-V11-03-18)
|
||||
- General clean-up of the multifragmentation model: fixed equation solver,
|
||||
make uniform headers and source, reduced number of new/delete operations.
|
||||
|
||||
## 2025-08-03 Vladimir Ivanchenko (hadr-deex-V11-03-17)
|
||||
- G4StatMF, G4FermiSplitter - fixed Coverity warnings
|
||||
|
||||
## 2025-07-08 Vladimir Ivanchenko (hadr-deex-V11-03-16)
|
||||
- G4VEmissionProbability, G4EvaporationChannel, G4GEMChannelVI - use optimazed
|
||||
parameters for G4VSIntegrator - initial step 0.15 MeV for neutrons, 0.2 MeV
|
||||
for charged, tolerance from 1.05 to 1.25. Avoid precision
|
||||
loss for computation of minimal energy of emitted fragment.
|
||||
|
||||
## 2025-07-04 Vladimir Ivanchenko (hadr-deex-V11-03-15)
|
||||
- G4ExcitationHandler - moved multi-fragmentation model to be called before
|
||||
the pre-compound model and not inside G4ExcitationHandler. The interfaces
|
||||
are preserved, warnings are added to obsolete methods
|
||||
- G4StatMF - always return non-empty vector of final fragments, if
|
||||
multi-fragmentation is not possible, then it returns the primary fragment.
|
||||
Cleaned up method of final state energy correction and Lorentz boost.
|
||||
|
||||
## 2025-06-18 Vladimir Ivanchenko (hadr-deex-V11-03-14)
|
||||
- G4ExcitationHandler - fix initialisation of the new Fermi-BreakUp model
|
||||
- G4FermiBreakUpAN - delete primary fragment, if decay is sucsessful - fixed
|
||||
|
||||
@@ -11,6 +11,7 @@ geant4_add_module(G4hadronic_deex_evaporation
|
||||
G4EvaporationChannel.hh
|
||||
G4EvaporationDefaultGEMFactory.hh
|
||||
G4EvaporationFactory.hh
|
||||
G4EvaporationGEMFactoryVI.hh
|
||||
G4EvaporationProbability.hh
|
||||
G4He3EvaporationChannel.hh
|
||||
G4He3EvaporationProbability.hh
|
||||
@@ -31,6 +32,7 @@ geant4_add_module(G4hadronic_deex_evaporation
|
||||
G4EvaporationChannel.cc
|
||||
G4EvaporationDefaultGEMFactory.cc
|
||||
G4EvaporationFactory.cc
|
||||
G4EvaporationGEMFactoryVI.cc
|
||||
G4EvaporationProbability.cc
|
||||
G4He3EvaporationChannel.cc
|
||||
G4He3EvaporationProbability.cc
|
||||
|
||||
@@ -111,6 +111,10 @@ void G4Evaporation::InitialiseChannelFactory()
|
||||
theFBU = new G4FermiBreakUpVI();
|
||||
theFBU->Initialise();
|
||||
}
|
||||
if (nullptr == theChannelFactory) {
|
||||
channelType = fEvaporation;
|
||||
theChannelFactory = new G4EvaporationFactory(thePhotonEvaporation);
|
||||
}
|
||||
theChannels = theChannelFactory->GetChannel();
|
||||
nChannels = theChannels->size();
|
||||
probabilities.resize(nChannels, 0.0);
|
||||
|
||||
+6
-18
@@ -94,31 +94,19 @@ G4double G4EvaporationChannel::GetEmissionProbability(G4Fragment* fragment)
|
||||
if (mass <= evapMass + resMass) { return 0.0; }
|
||||
|
||||
ekinmax = 0.5*((mass-resMass)*(mass+resMass) + evapMass2)/mass - evapMass;
|
||||
G4double ekinmin = 0.0;
|
||||
|
||||
// for OPTxs=1 elim=0 for all fragments - x-section include the CoulombBarrier
|
||||
G4double elim = 0.0;
|
||||
if(theZ > 0) {
|
||||
if (theZ > 0) {
|
||||
bCoulomb = theCoulombBarrier->GetCoulombBarrier(resA, resZ, 0.0);
|
||||
|
||||
// for OPTxs >0 penetration under the barrier is taken into account
|
||||
elim = (0 < OPTxs) ? bCoulomb*0.5 : bCoulomb;
|
||||
ekinmin = bCoulomb*0.5;
|
||||
}
|
||||
/*
|
||||
/*
|
||||
G4cout << "G4EvaporationChannel::Initialize Z=" << theZ <<" A=" << theA
|
||||
<< " FragZ=" << fragZ << " FragA=" << fragA << G4endl;
|
||||
G4cout << " Eex=" << exEnergy << " CB=" << bCoulomb
|
||||
<< " Elim=" << elim << " Efree=" << mass - resMass - evapMass
|
||||
<< G4endl;
|
||||
*/
|
||||
// Coulomb barrier compound at rest
|
||||
G4double resM = mass - evapMass - elim;
|
||||
if (resM < resMass) { return 0.0; }
|
||||
G4double ekinmin = 0.5*((mass-resM)*(mass+resM) + evapMass2)/mass - evapMass;
|
||||
|
||||
/*
|
||||
G4cout << "Emin= " <<ekinmin<<" Emax= "<<ekinmax
|
||||
<< " mass= " << mass << " resM= " << resMass
|
||||
<< " evapM= " << evapMass << G4endl;
|
||||
<< " Efree=" << mass - resMass - evapMass << " emin=" << ekinmin
|
||||
<< " emax=" << ekinmax << G4endl;
|
||||
*/
|
||||
if(ekinmax <= ekinmin) { return 0.0; }
|
||||
|
||||
|
||||
+13
-6
@@ -30,6 +30,12 @@
|
||||
#include "G4EvaporationGEMFactoryVI.hh"
|
||||
#include "G4GEMChannelVI.hh"
|
||||
#include "G4CompetitiveFission.hh"
|
||||
#include "G4NeutronEvaporationChannel.hh"
|
||||
#include "G4ProtonEvaporationChannel.hh"
|
||||
#include "G4DeuteronEvaporationChannel.hh"
|
||||
#include "G4TritonEvaporationChannel.hh"
|
||||
#include "G4He3EvaporationChannel.hh"
|
||||
#include "G4AlphaEvaporationChannel.hh"
|
||||
|
||||
G4EvaporationGEMFactoryVI::G4EvaporationGEMFactoryVI(G4VEvaporationChannel* ptr)
|
||||
: G4VEvaporationFactory(ptr)
|
||||
@@ -44,12 +50,13 @@ std::vector<G4VEvaporationChannel*>* G4EvaporationGEMFactoryVI::GetChannel()
|
||||
theChannel->push_back( thePhotonEvaporation ); // Photon Channel
|
||||
theChannel->push_back( new G4CompetitiveFission() ); // Fission Channel
|
||||
|
||||
theChannel->push_back( new G4GEMChannelVI( 1, 0) );// n
|
||||
theChannel->push_back( new G4GEMChannelVI( 1, 1) );// p
|
||||
theChannel->push_back( new G4GEMChannelVI( 2, 1) );// Deuteron
|
||||
theChannel->push_back( new G4GEMChannelVI( 3, 1) );// Triton
|
||||
theChannel->push_back( new G4GEMChannelVI( 3, 2) );// He3
|
||||
theChannel->push_back( new G4GEMChannelVI( 4, 2) );// Alpha
|
||||
// Standard evaporation channels (Z<3,A<5)
|
||||
theChannel->push_back( new G4NeutronEvaporationChannel() ); // n
|
||||
theChannel->push_back( new G4ProtonEvaporationChannel() ); // p
|
||||
theChannel->push_back( new G4DeuteronEvaporationChannel() ); // Deuteron
|
||||
theChannel->push_back( new G4TritonEvaporationChannel() ); // Triton
|
||||
theChannel->push_back( new G4He3EvaporationChannel() ); // He3
|
||||
theChannel->push_back( new G4AlphaEvaporationChannel() ); // Alpha
|
||||
theChannel->push_back( new G4GEMChannelVI( 5, 2) );// He5
|
||||
theChannel->push_back( new G4GEMChannelVI( 5, 3) );// Li5
|
||||
theChannel->push_back( new G4GEMChannelVI( 6, 3) );// Li6
|
||||
+22
-11
@@ -49,6 +49,7 @@
|
||||
#include "G4ChatterjeeCrossSection.hh"
|
||||
#include "G4InterfaceToXS.hh"
|
||||
#include "G4IsotopeList.hh"
|
||||
#include "G4DeexPrecoUtility.hh"
|
||||
#include "G4Neutron.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4Deuteron.hh"
|
||||
@@ -62,7 +63,9 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
const G4double explim = 160.;
|
||||
const G4double explim = 160.; // limit of G4Exp argument, OPTxs = 0
|
||||
const G4double lim = 2*CLHEP::MeV; // limit on x-section interface, OPTxs = 1
|
||||
const G4double kmin = 20*CLHEP::keV; // low-energy limit on primary kinetic energy
|
||||
}
|
||||
|
||||
G4EvaporationProbability::G4EvaporationProbability(G4int anA, G4int aZ,
|
||||
@@ -123,7 +126,7 @@ G4double G4EvaporationProbability::TotalProbability(
|
||||
delta0 = pNuclearLevelData->GetPairingCorrection(fragZ, fragA);
|
||||
delta1 = pNuclearLevelData->GetPairingCorrection(resZ, resA);
|
||||
resA13 = pG4pow->Z13(resA);
|
||||
/*
|
||||
/*
|
||||
G4cout << "G4EvaporationProbability: Z= " << theZ << " A= " << theA
|
||||
<< " resZ= " << resZ << " resA= " << resA
|
||||
<< " fragZ= " << fragZ << " fragA= " << fragA
|
||||
@@ -171,8 +174,7 @@ G4double G4EvaporationProbability::TotalProbability(
|
||||
|
||||
G4double G4EvaporationProbability::ComputeProbability(G4double kinE, G4double CB)
|
||||
{
|
||||
const G4double Kmin = 20*CLHEP::keV;
|
||||
G4double K = std::max(kinE, Kmin);
|
||||
G4double K = std::max(kinE, kmin);
|
||||
// abnormal case - should never happens
|
||||
if(pMass < pEvapMass + pResMass + K) { return 0.0; }
|
||||
|
||||
@@ -195,19 +197,28 @@ G4double G4EvaporationProbability::ComputeProbability(G4double kinE, G4double CB
|
||||
G4double
|
||||
G4EvaporationProbability::CrossSection(G4double kine, G4double CB)
|
||||
{
|
||||
const G4double Kmin = 20*CLHEP::keV;
|
||||
G4double K = std::max(kine, Kmin);
|
||||
G4double K = std::max(kine, kmin);
|
||||
// compute power once
|
||||
if (OPTxs > 1 && 0 < index && resA != lastA) {
|
||||
lastA = resA;
|
||||
muu = G4KalbachCrossSection::ComputePowerParameter(resA, index);
|
||||
}
|
||||
// In the case of OPTxs = 0 this method is not called
|
||||
if (OPTxs == 1) {
|
||||
const G4double lim = 2*CLHEP::MeV;
|
||||
G4double e1 = lowEnergyLimitMeV[theZ];
|
||||
if (e1 == 0.0) { e1 = lim; }
|
||||
K = std::max(K, e1);
|
||||
recentXS = fXSection->GetElementCrossSection(K, resZ)/CLHEP::millibarn;
|
||||
G4int Z = std::min(resZ, ZMAXNUCLEARDATA);
|
||||
if (0 == index) {
|
||||
G4double e1 = lowEnergyLimitMeV[Z];
|
||||
if (e1 == 0.0) { e1 = lim; }
|
||||
K = std::max(K, e1);
|
||||
} else {
|
||||
if (K < 0.5*CB) {
|
||||
recentXS = 0.0;
|
||||
return recentXS;
|
||||
}
|
||||
K = std::max(K, 2*CB);
|
||||
}
|
||||
G4double corr = G4DeexPrecoUtility::CorrectionFactor(index, theZ, resA13, CB, kine);
|
||||
recentXS = corr*fXSection->GetElementCrossSection(K, Z)/CLHEP::millibarn;
|
||||
|
||||
} else if (OPTxs == 2) {
|
||||
recentXS = G4ChatterjeeCrossSection::ComputeCrossSection(K, CB, resA13, muu,
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ void G4FermiBreakUpVI::Initialise()
|
||||
|
||||
G4bool G4FermiBreakUpVI::IsApplicable(G4int Z, G4int A, G4double eexc) const
|
||||
{
|
||||
return (Z < maxZ && A < maxA && eexc <= fElim && fPool->HasDecay(Z, A, eexc));
|
||||
return (Z < maxZ && A < maxA && fPool->HasDecay(Z, A, eexc));
|
||||
}
|
||||
|
||||
void G4FermiBreakUpVI::BreakFragment(G4FragmentVector* theResult,
|
||||
|
||||
@@ -107,6 +107,7 @@ G4double MassFactor(const G4FermiFragmentVector& split)
|
||||
massProduct *= fragmentMass;
|
||||
massSum += fragmentMass;
|
||||
}
|
||||
if (0.0 >= massSum) { return 1.0; }
|
||||
auto massFactor = massProduct / massSum;
|
||||
massFactor *= std::sqrt(massFactor);
|
||||
return massFactor;
|
||||
|
||||
+1
-3
@@ -37,7 +37,6 @@ class G4PairingCorrection;
|
||||
class G4VCoulombBarrier;
|
||||
class G4LevelManager;
|
||||
class G4NuclearLevelData;
|
||||
class G4HadronNucleonXsc;
|
||||
class G4InterfaceToXS;
|
||||
class G4ParticleDefinition;
|
||||
class G4Pow;
|
||||
@@ -80,7 +79,6 @@ private:
|
||||
const G4PairingCorrection* pairingCorrection;
|
||||
const G4LevelManager* lManagerEvap{nullptr};
|
||||
const G4LevelManager* lManagerRes{nullptr};
|
||||
G4HadronNucleonXsc* fHNXsc{nullptr};
|
||||
G4InterfaceToXS* fXSection{nullptr};
|
||||
G4Pow* g4pow;
|
||||
const G4ParticleDefinition* fProton;
|
||||
@@ -95,7 +93,6 @@ private:
|
||||
G4double fEvapExc{0.0}; // excitation energy of the evaporated fragment
|
||||
G4double fResExc{0.0}; // excitation energy of the residual fragment
|
||||
G4double bCoulomb{0.0};
|
||||
G4double fLimEXS{0.0};
|
||||
G4double fDeltaEvap{0.0};
|
||||
G4double fE0{0.0};
|
||||
G4double fE1{0.0};
|
||||
@@ -105,6 +102,7 @@ private:
|
||||
G4double delta1{0.0};
|
||||
G4double recentXS{0.0};
|
||||
G4double fEnergyLimitXS{0.0};
|
||||
G4double xsfactor{1.0};
|
||||
G4double fTolerance;
|
||||
G4double fCoeff;
|
||||
|
||||
|
||||
@@ -93,7 +93,6 @@ geant4_add_module(G4hadronic_deex_gem_evaporation
|
||||
G4DeuteronGEMChannel.hh
|
||||
G4DeuteronGEMProbability.hh
|
||||
G4EvaporationGEMFactory.hh
|
||||
G4EvaporationGEMFactoryVI.hh
|
||||
G4F17GEMProbability.hh
|
||||
G4F18GEMProbability.hh
|
||||
G4F19GEMProbability.hh
|
||||
@@ -169,7 +168,6 @@ geant4_add_module(G4hadronic_deex_gem_evaporation
|
||||
G4DeuteronGEMChannel.cc
|
||||
G4DeuteronGEMProbability.cc
|
||||
G4EvaporationGEMFactory.cc
|
||||
G4EvaporationGEMFactoryVI.cc
|
||||
G4F17GEMProbability.cc
|
||||
G4F18GEMProbability.cc
|
||||
G4F19GEMProbability.cc
|
||||
|
||||
+58
-56
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// GEM de-excitation model
|
||||
// by V. Ivanchenko (July 2019)
|
||||
//
|
||||
@@ -52,12 +51,13 @@
|
||||
#include "G4Alpha.hh"
|
||||
#include "G4InterfaceToXS.hh"
|
||||
#include "G4IsotopeList.hh"
|
||||
#include "G4HadronNucleonXsc.hh"
|
||||
#include "G4NuclearRadii.hh"
|
||||
|
||||
namespace
|
||||
{
|
||||
const G4double minExc = 1.0*CLHEP::MeV;
|
||||
const G4double dExc = 1.0*CLHEP::MeV;
|
||||
const G4double limE = 1.0*CLHEP::MeV; // low-energy limit for neutrons
|
||||
const G4double kmin = 20*CLHEP::keV; // low-energy limit on primary kinetic energy
|
||||
const G4int nProbMax = 10;
|
||||
G4double prob[nProbMax] = {0.0};
|
||||
}
|
||||
@@ -73,9 +73,8 @@ G4GEMChannelVI::G4GEMChannelVI(G4int theA, G4int theZ)
|
||||
|
||||
cBarrier = new G4CoulombBarrier(evapA, evapZ);
|
||||
|
||||
fTolerance = 50*CLHEP::keV;
|
||||
fCoeff = fEvapMass*CLHEP::millibarn
|
||||
/((CLHEP::pi*CLHEP::hbarc)*(CLHEP::pi*CLHEP::hbarc));
|
||||
fTolerance = 10*CLHEP::keV;
|
||||
fCoeff = fEvapMass/((CLHEP::pi*CLHEP::hbarc)*(CLHEP::pi*CLHEP::hbarc));
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << "GEMVI_" << "Z" << evapZ << "_A" << evapA;
|
||||
@@ -109,21 +108,21 @@ G4GEMChannelVI::G4GEMChannelVI(G4int theA, G4int theZ)
|
||||
} else if (evapZ == 2 && evapA == 4) {
|
||||
indexC = 5;
|
||||
part = G4Alpha::Alpha();
|
||||
} else {
|
||||
G4int N = evapA - evapZ;
|
||||
fCoeff *= (1 + (evapZ - 2*(evapZ/2)))*(1 + (N - 2*(N/2)));
|
||||
}
|
||||
g4pow = G4Pow::GetInstance();
|
||||
|
||||
//G4double de = (0 == indexC) ? 0.15*CLHEP::MeV : 0.25*CLHEP::MeV;
|
||||
G4double de = 0.125*CLHEP::MeV;
|
||||
InitialiseIntegrator(0.01, 0.25, 1.1, de, 0.1*CLHEP::MeV, 2*CLHEP::MeV);
|
||||
G4double de = (0 == indexC) ? 0.15*CLHEP::MeV : 0.25*CLHEP::MeV;
|
||||
InitialiseIntegrator(0.01, 0.25, 1.3, de, 0.1*CLHEP::MeV, 2*CLHEP::MeV);
|
||||
|
||||
if (indexC <= 6) { fXSection = new G4InterfaceToXS(part, indexC); }
|
||||
else { fHNXsc = new G4HadronNucleonXsc(); }
|
||||
}
|
||||
|
||||
G4GEMChannelVI::~G4GEMChannelVI()
|
||||
{
|
||||
delete cBarrier;
|
||||
delete fHNXsc;
|
||||
delete fXSection;
|
||||
}
|
||||
|
||||
@@ -138,6 +137,7 @@ G4double G4GEMChannelVI::GetEmissionProbability(G4Fragment* fragment)
|
||||
fragA = fragment->GetA_asInt();
|
||||
resZ = fragZ - evapZ;
|
||||
resA = fragA - evapA;
|
||||
// G4cout << "G4GEMChannelVI::GetEmissionProbability Z=" << evapZ << " A=" << evapA << " resZ=" << resZ << " resA=" << resA << G4endl;
|
||||
// to avoid double counting
|
||||
if (resA < evapA || resA < resZ || resZ < 1 ||
|
||||
(resA == evapA && resZ < evapZ)) { return 0.0; }
|
||||
@@ -146,29 +146,27 @@ G4double G4GEMChannelVI::GetEmissionProbability(G4Fragment* fragment)
|
||||
fMass = fragment->GetGroundStateMass() + fFragExc;
|
||||
fResMass = G4NucleiProperties::GetNuclearMass(resA, resZ);
|
||||
fResA13 = g4pow->Z13(resA);
|
||||
xsfactor = g4pow->Z23(fragA)/g4pow->Z23(resA);
|
||||
|
||||
// limit for the case when both evaporation and residual
|
||||
// fragments are in ground states
|
||||
if (fMass <= fEvapMass + fResMass) { return 0.0; }
|
||||
|
||||
a0 = nData->GetLevelDensity(fragZ, fragA, fFragExc);
|
||||
a0 = G4DeexPrecoUtility::LevelDensity(fragZ, fragA, indexC);
|
||||
delta0 = nData->GetPairingCorrection(fragZ, fragA);
|
||||
delta1 = nData->GetPairingCorrection(resZ, resA);
|
||||
fE0 = std::max(fFragExc - delta0, 0.0);
|
||||
|
||||
if (indexC > 0) {
|
||||
bCoulomb = cBarrier->GetCoulombBarrier(resA, resZ, 0.0);
|
||||
fLimEXS = 2*bCoulomb;
|
||||
} else {
|
||||
fLimEXS = lowEnergyLimitMeV[resZ];
|
||||
if (0.0 == fLimEXS) { fLimEXS = CLHEP::MeV; }
|
||||
bCoulomb = cBarrier->GetCoulombBarrier(resA, resZ, fFragExc);
|
||||
}
|
||||
G4double de = fMass - fEvapMass - fResMass - 0.5*bCoulomb;
|
||||
if (de <= 0.0) { return 0.0; }
|
||||
G4double elim = 0.5*bCoulomb;
|
||||
G4double de = fMass - fEvapMass - fResMass - elim;
|
||||
if (de < fTolerance) { return 0.0; }
|
||||
nProbEvap = 1;
|
||||
fDeltaEvap = de;
|
||||
if (7 == indexC) {
|
||||
G4int n = (G4int)(de/minExc) + 1;
|
||||
G4int n = (G4int)(de/dExc) + 1;
|
||||
nProbEvap = std::min(n, nProbMax);
|
||||
if (nProbEvap > 1) { fDeltaEvap /= (G4double)(nProbEvap - 1); }
|
||||
}
|
||||
@@ -178,22 +176,32 @@ G4double G4GEMChannelVI::GetEmissionProbability(G4Fragment* fragment)
|
||||
<< fragZ << " fragA=" << fragA << " Z=" << evapZ << " A=" << evapA
|
||||
<< " Eex(MeV)=" << fFragExc << " nProbEvap=" << nProbEvap
|
||||
<< " nProbRes=" << nProbRes << " CB=" << bCoulomb
|
||||
<< " Elim=" << fEnergyLimitXS << G4endl;
|
||||
<< " Elim=" << fEnergyLimitXS << " XSfac=" << xsfactor << G4endl;
|
||||
}
|
||||
|
||||
// m1 is the mass of emitted excited fragment
|
||||
// e2 - free energy in the 2-body decay
|
||||
G4double sump = 0.0;
|
||||
for (G4int i=0; i<nProbEvap; ++i) {
|
||||
for (G4int i = 0; i < nProbEvap; ++i) {
|
||||
fEvapExc = fDeltaEvap*i;
|
||||
G4double m1 = fEvapMass + fEvapExc;
|
||||
G4double e2 = fMass - m1 - fResMass;
|
||||
e2 = std::max(e2, 0.0);
|
||||
G4double p = (e2 > 0.5*bCoulomb) ? ComputeIntegral(0.5*bCoulomb, e2) : 0.0;
|
||||
if (e2 <= elim + fTolerance) {
|
||||
nProbEvap = i + 1;
|
||||
prob[i] = sump;
|
||||
break;
|
||||
}
|
||||
G4double p = ComputeIntegral(elim, e2);
|
||||
sump += p;
|
||||
prob[i] = sump;
|
||||
if (2 < fVerbose) {
|
||||
G4cout << i << ". e1=" << elim << " e2=" << e2 << " e2-e1="
|
||||
<< e2 - elim << " fEvapExc=" << fEvapExc
|
||||
<< " Probability=" << p << G4endl;
|
||||
}
|
||||
}
|
||||
sump /= (G4double)nProbEvap;
|
||||
if (nProbEvap > 1) { sump /= (G4double)nProbEvap; }
|
||||
return sump;
|
||||
}
|
||||
|
||||
@@ -202,53 +210,47 @@ G4double G4GEMChannelVI::ProbabilityDensityFunction(G4double e)
|
||||
// e is free energy
|
||||
G4double m1 = fEvapMass + fEvapExc;
|
||||
fResExc = fMass - m1 - fResMass - e;
|
||||
if (fResExc <= 0.0 || 0.0 == e) { return 0.0; }
|
||||
if (fResExc < 0.0 || 0.0 == e) { return 0.0; }
|
||||
fE1 = std::max(fResExc - delta1, 0.0);
|
||||
a1 = nData->GetLevelDensity(resZ, resA, fResExc);
|
||||
a1 = G4DeexPrecoUtility::LevelDensity(resZ, resA, indexC);
|
||||
G4double m2 = fResMass + fResExc;
|
||||
G4double elab = 0.5*(fMass + m1 + m2)*(fMass - m1 - m2)/m2;
|
||||
G4double xs = CrossSection(elab);
|
||||
G4double res =
|
||||
fCoeff*G4Exp(2.0*(std::sqrt(a1*fE1) - std::sqrt(a0*fE0)))*elab*xs;
|
||||
fCoeff*G4Exp(2.0*(std::sqrt(a1*fE1) - std::sqrt(a0*fE0)))*e*xs;
|
||||
|
||||
//G4cout << "e=" << e << " elab=" << elab << " xs=" << xs << " sig=" << res << G4endl;
|
||||
//G4cout << "e=" << e << " elab=" << elab << " xs(mb)="
|
||||
// << xs/CLHEP::millibarn << " prob=" << res << G4endl;
|
||||
return res;
|
||||
}
|
||||
|
||||
G4double G4GEMChannelVI::CrossSection(G4double e)
|
||||
{
|
||||
G4int Z = std::min(resZ, ZMAXNUCLEARDATA);
|
||||
G4double corr;
|
||||
G4double e1 = std::max(e, kmin);
|
||||
if (e1 < 0.5*bCoulomb) {
|
||||
recentXS = 0.0;
|
||||
return recentXS;
|
||||
}
|
||||
if (indexC <= 5) {
|
||||
G4int Z = std::min(resZ, ZMAXNUCLEARDATA);
|
||||
G4double e1 = std::max(e, fLimEXS);
|
||||
recentXS = fXSection->GetElementCrossSection(e1, Z)/CLHEP::millibarn;
|
||||
if (e1 > e) {
|
||||
recentXS *= (e1/e) *
|
||||
G4DeexPrecoUtility::CorrectionFactor(indexC, Z, fResA13, bCoulomb, e, e1);
|
||||
G4double e2 = 2*bCoulomb;
|
||||
if (0 == indexC) {
|
||||
e2 = lowEnergyLimitMeV[Z];
|
||||
if (e2 == 0.0) { e2 = limE; }
|
||||
}
|
||||
e1 = std::max(e1, e2);
|
||||
corr = G4DeexPrecoUtility::CorrectionFactor(indexC, evapZ, fResA13, bCoulomb, e);
|
||||
recentXS = fXSection->GetElementCrossSection(e1, Z)/CLHEP::millibarn;
|
||||
} else {
|
||||
const G4double cInel = 2.4;
|
||||
const G4double cTotal = 2.0;
|
||||
|
||||
if (e <= 0.5*bCoulomb) { return 0.0; }
|
||||
|
||||
G4double pTkin = e/(G4double)evapA;
|
||||
|
||||
G4int evapN = evapA - evapZ;
|
||||
G4int resN = resA - resZ;
|
||||
|
||||
G4double tR = G4NuclearRadii::Radius(resZ, resA);
|
||||
G4double pR = G4NuclearRadii::Radius(evapZ, evapA);
|
||||
corr = G4DeexPrecoUtility::CorrectionFactor(indexC, Z, fResA13, bCoulomb, e);
|
||||
|
||||
fHNXsc->HadronNucleonXscNS(fProton, fProton, pTkin);
|
||||
G4double xs1 = fHNXsc->GetInelasticHadronNucleonXsc();
|
||||
fHNXsc->HadronNucleonXscNS(fNeutron, fProton, pTkin);
|
||||
G4double xs2 = fHNXsc->GetInelasticHadronNucleonXsc();
|
||||
// nn x-section assumed to be the same as pp
|
||||
G4double xs = (evapZ*resZ + evapN*resN)*xs1 + (evapZ*resN + evapN*resZ)*xs2;
|
||||
|
||||
G4double R2 = cTotal*CLHEP::pi*( pR*pR + tR*tR ); // basically 2piRR
|
||||
recentXS = R2*G4Log(1.0 + cInel*xs/R2)*(1. - 0.5*bCoulomb/e)/cInel;
|
||||
// geometrical x-section
|
||||
recentXS = CLHEP::pi*(pR + tR)*(pR + tR);
|
||||
}
|
||||
recentXS *= corr;
|
||||
return recentXS;
|
||||
}
|
||||
|
||||
@@ -268,8 +270,8 @@ G4Fragment* G4GEMChannelVI::EmittedFragment(G4Fragment* theNucleus)
|
||||
q *= G4UniformRand();
|
||||
for (G4int i=0; i < nProbEvap; ++i) {
|
||||
if (q <= prob[i]) {
|
||||
G4double e1 = (0 == i) ? 0.0 :
|
||||
fDeltaEvap*((i - 1) + (q - prob[i - 1])/(prob[i] - prob[i - 1]));
|
||||
if (0 == i) { break; }
|
||||
G4double e1 = fDeltaEvap*((i - 1) + (q - prob[i - 1])/(prob[i] - prob[i - 1]));
|
||||
fEvapExc = CorrectExcitation(e1, lManagerEvap);
|
||||
e2 -= fEvapExc;
|
||||
e2 = std::max(e2, 0.0);
|
||||
@@ -277,7 +279,7 @@ G4Fragment* G4GEMChannelVI::EmittedFragment(G4Fragment* theNucleus)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ComputeIntegral(bCoulomb, e2) <= 0.0) { return evFragment; }
|
||||
if (ComputeIntegral(0.5*bCoulomb, e2) <= 0.0) { return evFragment; }
|
||||
|
||||
// sample free energy
|
||||
G4double e = SampleValue();
|
||||
|
||||
+2
-9
@@ -88,7 +88,7 @@ public:
|
||||
inline void SetMaxZForFermiBreakUp(G4int aZ);
|
||||
inline void SetMaxAForFermiBreakUp(G4int anA);
|
||||
inline void SetMaxAandZForFermiBreakUp(G4int anA,G4int aZ);
|
||||
inline void SetMinEForMultiFrag(G4double anE);
|
||||
void SetMinEForMultiFrag(G4double anE);
|
||||
|
||||
// access methods
|
||||
G4VEvaporation* GetEvaporation();
|
||||
@@ -116,7 +116,7 @@ private:
|
||||
inline void SortSecondaryFragment(G4Fragment*);
|
||||
|
||||
G4VEvaporation* theEvaporation{nullptr};
|
||||
G4VMultiFragmentation* theMultiFragmentation;
|
||||
G4VMultiFragmentation* theMultiFragmentation{nullptr};
|
||||
G4VFermiBreakUp* theFermiModel;
|
||||
G4VEvaporationChannel* thePhotonEvaporation;
|
||||
G4ParticleTable* thePartTable;
|
||||
@@ -140,9 +140,7 @@ private:
|
||||
G4int fVerbose{1};
|
||||
G4int fWarnings{0};
|
||||
|
||||
G4double minEForMultiFrag;
|
||||
G4double minExcitation;
|
||||
G4double maxExcitation;
|
||||
G4double fLambdaMass;
|
||||
|
||||
G4bool isInitialised{false};
|
||||
@@ -175,11 +173,6 @@ inline void G4ExcitationHandler::SetMaxAandZForFermiBreakUp(G4int anA, G4int aZ)
|
||||
SetMaxZForFermiBreakUp(aZ);
|
||||
}
|
||||
|
||||
inline void G4ExcitationHandler::SetMinEForMultiFrag(G4double anE)
|
||||
{
|
||||
minEForMultiFrag = anE;
|
||||
}
|
||||
|
||||
inline void G4ExcitationHandler::SortSecondaryFragment(G4Fragment* frag)
|
||||
{
|
||||
G4int A = frag->GetA_asInt();
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
#include "G4Lambda.hh"
|
||||
|
||||
#include "G4VMultiFragmentation.hh"
|
||||
#include "G4StatMF.hh"
|
||||
#include "G4VFermiBreakUp.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "G4ElementTable.hh"
|
||||
@@ -79,21 +80,18 @@
|
||||
#include "G4VEvaporationChannel.hh"
|
||||
#include "G4Evaporation.hh"
|
||||
#include "G4PhotonEvaporation.hh"
|
||||
#include "G4StatMF.hh"
|
||||
#include "G4FermiBreakUpAN.hh"
|
||||
#include "G4FermiBreakUpVI.hh"
|
||||
#include "G4NuclearLevelData.hh"
|
||||
#include "G4PhysicsModelCatalog.hh"
|
||||
|
||||
G4ExcitationHandler::G4ExcitationHandler()
|
||||
: minEForMultiFrag(1.*CLHEP::TeV), minExcitation(1.*CLHEP::eV),
|
||||
maxExcitation(100.*CLHEP::MeV)
|
||||
: minExcitation(1.*CLHEP::eV)
|
||||
{
|
||||
thePartTable = G4ParticleTable::GetParticleTable();
|
||||
theTableOfIons = thePartTable->GetIonTable();
|
||||
nist = G4NistManager::Instance();
|
||||
|
||||
theMultiFragmentation = new G4StatMF();
|
||||
theFermiModel = nullptr;
|
||||
thePhotonEvaporation = new G4PhotonEvaporation();
|
||||
SetEvaporation(new G4Evaporation(thePhotonEvaporation), true);
|
||||
@@ -140,9 +138,7 @@ void G4ExcitationHandler::SetParameters()
|
||||
for (auto const & elm : *table) { Zmax = std::max(Zmax, elm->GetZasInt()); }
|
||||
ndata->UploadNuclearLevelData(Zmax+1);
|
||||
}
|
||||
minEForMultiFrag = param->GetMinExPerNucleounForMF();
|
||||
minExcitation = param->GetMinExcitation();
|
||||
maxExcitation = param->GetPrecoHighEnergy();
|
||||
|
||||
// allowing local debug printout
|
||||
fVerbose = std::max(fVerbose, param->GetVerbose());
|
||||
@@ -167,11 +163,6 @@ void G4ExcitationHandler::SetParameters()
|
||||
}
|
||||
theFermiModel->Initialise();
|
||||
|
||||
// multi-fragmentation initialisation
|
||||
if (nullptr == theMultiFragmentation) {
|
||||
SetMultiFragmentation(new G4StatMF());
|
||||
}
|
||||
|
||||
// evaporation initialisation
|
||||
if (nullptr == theEvaporation) {
|
||||
SetEvaporation(new G4Evaporation(thePhotonEvaporation), true);
|
||||
@@ -215,13 +206,18 @@ void G4ExcitationHandler::SetEvaporation(G4VEvaporation* ptr, G4bool flag)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
G4ExcitationHandler::SetMultiFragmentation(G4VMultiFragmentation* ptr)
|
||||
void G4ExcitationHandler::SetMultiFragmentation(G4VMultiFragmentation* ptr)
|
||||
{
|
||||
if (!isInitialised && nullptr != ptr && ptr != theMultiFragmentation) {
|
||||
delete theMultiFragmentation;
|
||||
theMultiFragmentation = ptr;
|
||||
}
|
||||
G4cout << "### G4ExcitationHandler::SetMultiFragmentation() is obsolete and "
|
||||
<< "will be removed in the next major release" << G4endl;
|
||||
delete theMultiFragmentation;
|
||||
theMultiFragmentation = ptr;
|
||||
}
|
||||
|
||||
void G4ExcitationHandler::SetMinEForMultiFrag(G4double)
|
||||
{
|
||||
G4cout << "### G4ExcitationHandler::SetMinEForMultiFrag() is obsolete and "
|
||||
<< "will be removed in the next major release" << G4endl;
|
||||
}
|
||||
|
||||
void G4ExcitationHandler::SetFermiModel(G4VFermiBreakUp* ptr)
|
||||
@@ -285,7 +281,9 @@ G4VEvaporation* G4ExcitationHandler::GetEvaporation()
|
||||
|
||||
G4VMultiFragmentation* G4ExcitationHandler::GetMultiFragmentation()
|
||||
{
|
||||
if (nullptr != theMultiFragmentation) { SetParameters(); }
|
||||
G4cout << "### G4ExcitationHandler::GetMultiFragmentation() is obsolete and "
|
||||
<< "will be removed in the next major release" << G4endl;
|
||||
if (nullptr == theMultiFragmentation) { theMultiFragmentation = new G4StatMF(); }
|
||||
return theMultiFragmentation;
|
||||
}
|
||||
|
||||
@@ -297,24 +295,21 @@ G4VFermiBreakUp* G4ExcitationHandler::GetFermiModel()
|
||||
|
||||
G4VEvaporationChannel* G4ExcitationHandler::GetPhotonEvaporation()
|
||||
{
|
||||
if(nullptr != thePhotonEvaporation) { SetParameters(); }
|
||||
if (nullptr != thePhotonEvaporation) { SetParameters(); }
|
||||
return thePhotonEvaporation;
|
||||
}
|
||||
|
||||
G4ReactionProductVector *
|
||||
G4ReactionProductVector*
|
||||
G4ExcitationHandler::BreakItUp(const G4Fragment & theInitialState)
|
||||
{
|
||||
// Variables existing until end of method
|
||||
G4Fragment * theInitialStatePtr = new G4Fragment(theInitialState);
|
||||
if (fVerbose > 1) {
|
||||
G4cout << "@@@@@@@@@@ Start G4Excitation Handler @@@@@@@@@@@@@ " << G4endl;
|
||||
G4cout << theInitialState << G4endl;
|
||||
G4cout << theInitialState << G4endl;
|
||||
}
|
||||
if (!isInitialised) { Initialise(); }
|
||||
|
||||
// pointer to fragment vector which receives temporal results
|
||||
G4FragmentVector * theTempResult = nullptr;
|
||||
|
||||
|
||||
theResults.clear();
|
||||
theEvapList.clear();
|
||||
|
||||
@@ -324,17 +319,6 @@ G4ExcitationHandler::BreakItUp(const G4Fragment & theInitialState)
|
||||
G4int Z = theInitialState.GetZ_asInt();
|
||||
G4int nL = theInitialState.GetNumberOfLambdas();
|
||||
|
||||
// too much excitation
|
||||
if (exEnergy > A*maxExcitation && A > 0) {
|
||||
++fWarnings;
|
||||
if(fWarnings < 0) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << "High excitation Fragment Z= " << Z << " A= " << A
|
||||
<< " Eex/A(MeV)= " << exEnergy/A;
|
||||
G4Exception("G4ExcitationHandler::BreakItUp()","had0034",JustWarning,ed,"");
|
||||
}
|
||||
}
|
||||
|
||||
// for hyper-nuclei subtract lambdas from the projectile fragment
|
||||
G4double lambdaF = 0.0;
|
||||
G4LorentzVector lambdaLV = theInitialStatePtr->GetMomentum();
|
||||
@@ -409,34 +393,7 @@ G4ExcitationHandler::BreakItUp(const G4Fragment & theInitialState)
|
||||
// JMQ 150909: first step in de-excitation is treated separately
|
||||
// Fragments after the first step are stored in theEvapList
|
||||
} else {
|
||||
if ((A<maxAForFermiBreakUp && Z<maxZForFermiBreakUp)
|
||||
|| exEnergy <= minEForMultiFrag*A) {
|
||||
theEvapList.push_back(theInitialStatePtr);
|
||||
|
||||
// Statistical Multifragmentation will take place only once
|
||||
} else {
|
||||
theTempResult = theMultiFragmentation->BreakItUp(theInitialState);
|
||||
if (nullptr == theTempResult) {
|
||||
theEvapList.push_back(theInitialStatePtr);
|
||||
} else {
|
||||
std::size_t nsec = theTempResult->size();
|
||||
|
||||
// no fragmentation
|
||||
if (0 == nsec) {
|
||||
theEvapList.push_back(theInitialStatePtr);
|
||||
|
||||
// secondary are produced - sort out secondary fragments
|
||||
} else {
|
||||
G4bool deletePrimary = true;
|
||||
for (auto const & ptr : *theTempResult) {
|
||||
if (ptr == theInitialStatePtr) { deletePrimary = false; }
|
||||
SortSecondaryFragment(ptr);
|
||||
}
|
||||
if (deletePrimary) { delete theInitialStatePtr; }
|
||||
}
|
||||
delete theTempResult; // end multifragmentation
|
||||
}
|
||||
}
|
||||
theEvapList.push_back(theInitialStatePtr);
|
||||
}
|
||||
if (fVerbose > 2) {
|
||||
G4cout << "## After first step of handler " << theEvapList.size()
|
||||
@@ -521,10 +478,9 @@ G4ExcitationHandler::BreakItUp(const G4Fragment & theInitialState)
|
||||
G4ReactionProductVector * theReactionProductVector =
|
||||
new G4ReactionProductVector();
|
||||
|
||||
// MAC (24/07/08)
|
||||
// To optimise the storing speed, we reserve space
|
||||
// in memory for the vector
|
||||
theReactionProductVector->reserve( theResults.size() );
|
||||
theReactionProductVector->reserve(theResults.size());
|
||||
|
||||
if (fVerbose > 1) {
|
||||
G4cout << "### ExcitationHandler provides " << theResults.size()
|
||||
|
||||
+11
-13
@@ -66,12 +66,12 @@ void G4DeexPrecoParameters::Initialise()
|
||||
|
||||
// preco parameters
|
||||
fPrecoLowEnergy = 0.1*CLHEP::MeV;
|
||||
fPrecoHighEnergy = 30*CLHEP::MeV;
|
||||
fPrecoHighEnergy = 15*CLHEP::MeV;
|
||||
fPhenoFactor = 1.0;
|
||||
|
||||
fPrecoType = 1;
|
||||
fMinZForPreco = 3;
|
||||
fMinAForPreco = 5;
|
||||
fMinZForPreco = 9;
|
||||
fMinAForPreco = 17;
|
||||
|
||||
fNeverGoBack = false;
|
||||
fUseSoftCutoff = false;
|
||||
@@ -328,10 +328,10 @@ std::ostream& G4DeexPrecoParameters::StreamInfo(std::ostream& os) const
|
||||
os << "Type of pre-compound model " << fPreCompoundType << "\n";
|
||||
os << "Type of pre-compound inverse x-section " << fPrecoType << "\n";
|
||||
os << "Pre-compound model active " << (!fPrecoDummy) << "\n";
|
||||
os << "Pre-compound excitation low energy "
|
||||
<< G4BestUnit(fPrecoLowEnergy, "Energy") << "\n";
|
||||
os << "Pre-compound excitation high energy "
|
||||
<< G4BestUnit(fPrecoHighEnergy, "Energy") << "\n";
|
||||
os << "Pre-compound excitation low energy "
|
||||
<< fPrecoLowEnergy/CLHEP::MeV << " MeV \n";
|
||||
os << "Pre-compound excitation high energy "
|
||||
<< fPrecoHighEnergy/CLHEP::MeV << " MeV \n";
|
||||
os << "Angular generator for pre-compound model " << fUseAngularGen << "\n";
|
||||
os << "Use NeverGoBack option for pre-compound model " << fNeverGoBack << "\n";
|
||||
os << "Use SoftCutOff option for pre-compound model " << fUseSoftCutoff << "\n";
|
||||
@@ -345,18 +345,16 @@ std::ostream& G4DeexPrecoParameters::StreamInfo(std::ostream& os) const
|
||||
os << "Type of de-excitation factory " << namm[idx] << "\n";
|
||||
os << "Number of de-excitation channels " << nmm[idx] << "\n";
|
||||
os << "Type of Fermi BreakUp model " << nfbu[jdx] << "\n";
|
||||
os << "Min excitation energy "
|
||||
<< G4BestUnit(fMinExcitation, "Energy") << "\n";
|
||||
os << "Min excitation energy "
|
||||
<< fMinExcitation/CLHEP::keV << " keV \n";
|
||||
os << "Min energy per nucleon for multifragmentation "
|
||||
<< G4BestUnit(fMinExPerNucleounForMF, "Energy") << "\n";
|
||||
os << "Limit excitation energy for Fermi BreakUp "
|
||||
<< G4BestUnit(fFBUEnergyLimit, "Energy") << "\n";
|
||||
<< fMinExPerNucleounForMF/CLHEP::MeV << " MeV\n";
|
||||
os << "Level density (1/MeV) "
|
||||
<< fLevelDensity*CLHEP::MeV << "\n";
|
||||
os << "Use simple level density model " << fLD << "\n";
|
||||
os << "Use discrete excitation energy of the residual " << fFD << "\n";
|
||||
os << "Time limit for long lived isomeres "
|
||||
<< G4BestUnit(fMaxLifeTime, "Time") << "\n";
|
||||
<< fMaxLifeTime/CLHEP::ns << " ns \n";
|
||||
os << "Isomer production flag " << fIsomerFlag << "\n";
|
||||
os << "Internal e- conversion flag "
|
||||
<< fInternalConversion << "\n";
|
||||
|
||||
@@ -63,6 +63,10 @@ G4LevelReader::G4LevelReader(G4NuclearLevelData* ptr)
|
||||
fAlphaMax = (G4float)1.e15;
|
||||
fTimeFactor = CLHEP::second/G4Pow::GetInstance()->logZ(2);
|
||||
fDirectory = G4String(G4FindDataDir("G4LEVELGAMMADATA"));
|
||||
if (fDirectory.empty()) {
|
||||
G4Exception("G4LevelReader::G4LevelReader()", "had014", FatalException,
|
||||
"G4LEVELGAMMADATA environment variable not set");
|
||||
}
|
||||
|
||||
vTrans.resize(fTransMax,0);
|
||||
vRatio.resize(fTransMax,0.0f);
|
||||
@@ -122,19 +126,26 @@ const std::vector<G4float>* G4LevelReader::NormalizedICCProbability(G4int Z)
|
||||
G4int LL = 3;
|
||||
G4int M = 5;
|
||||
G4int N = 1;
|
||||
G4int Kmax = 9;
|
||||
if(Z <= 27) {
|
||||
M = N = 0;
|
||||
if(Z <= 4) {
|
||||
LL = 1;
|
||||
Kmax = 2;
|
||||
} else if(Z <= 6) {
|
||||
LL = 2;
|
||||
Kmax = 3;
|
||||
} else if(Z <= 10) {
|
||||
Kmax = 4;
|
||||
} else if(Z <= 12) {
|
||||
M = 1;
|
||||
Kmax = 8;
|
||||
} else if(Z <= 17) {
|
||||
M = 2;
|
||||
Kmax = 8;
|
||||
} else if(Z == 18) {
|
||||
M = 3;
|
||||
Kmax = 8;
|
||||
} else if(Z <= 20) {
|
||||
M = 3;
|
||||
N = 1;
|
||||
@@ -147,33 +158,24 @@ const std::vector<G4float>* G4LevelReader::NormalizedICCProbability(G4int Z)
|
||||
if(N < 1) { fICC[9] = 0.0f; }
|
||||
}
|
||||
G4float norm = 0.0f;
|
||||
for(G4int i=0; i<10; ++i) {
|
||||
for (G4int i = 0; i <= Kmax; ++i) {
|
||||
norm += fICC[i];
|
||||
fICC[i] = norm;
|
||||
}
|
||||
if(norm == 0.0f && fAlpha > 0.0f) {
|
||||
fICC[0] = norm = 1.0f;
|
||||
}
|
||||
if(norm > 0.0f) {
|
||||
if (norm > 0.0f) {
|
||||
norm = 1.0f/norm;
|
||||
vec = new std::vector<G4float>;
|
||||
G4float x;
|
||||
for(G4int i=0; i<10; ++i) {
|
||||
x = fICC[i]*norm;
|
||||
if(x > 0.995f || 9 == i) {
|
||||
vec->push_back(1.0f);
|
||||
break;
|
||||
}
|
||||
vec->push_back(x);
|
||||
}
|
||||
if (fVerbose > 3) {
|
||||
G4long prec = G4cout.precision(3);
|
||||
G4cout << "# InternalConv: ";
|
||||
std::size_t nn = vec->size();
|
||||
for(std::size_t i=0; i<nn; ++i) { G4cout << " " << (*vec)[i]; }
|
||||
G4cout << G4endl;
|
||||
G4cout.precision(prec);
|
||||
}
|
||||
}
|
||||
vec = new std::vector<G4float>(Kmax + 1, 0.0f);
|
||||
for (G4int i = 0; i < Kmax; ++i) {
|
||||
(*vec)[i] = fICC[i]*norm;
|
||||
}
|
||||
(*vec)[Kmax] = 1.0f;
|
||||
if (fVerbose > 3) {
|
||||
G4long prec = G4cout.precision(3);
|
||||
G4cout << "# InternalConv: ";
|
||||
for (G4int i = 0; i <= Kmax; ++i) { G4cout << " " << (*vec)[i]; }
|
||||
G4cout << G4endl;
|
||||
G4cout.precision(prec);
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ void G4VEmissionProbability::Initialise()
|
||||
|
||||
void G4VEmissionProbability::ResetIntegrator(G4double de, G4double eps)
|
||||
{
|
||||
InitialiseIntegrator(eps, 0.25, 1.10, de, 0.1*CLHEP::MeV, 2*CLHEP::MeV);
|
||||
InitialiseIntegrator(eps, 0.25, 1.25, de, 0.1*CLHEP::MeV, 2*CLHEP::MeV);
|
||||
}
|
||||
|
||||
G4double G4VEmissionProbability::EmissionProbability(const G4Fragment&, G4double)
|
||||
|
||||
-111
@@ -1,111 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
|
||||
#ifndef G4Solver_h
|
||||
#define G4Solver_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#define DefaultTolerance 5.0e-14
|
||||
|
||||
template <class Function> class G4Solver
|
||||
{
|
||||
public:
|
||||
enum {DefaultMaxIter = 100};
|
||||
|
||||
// default constructor
|
||||
G4Solver() : MaxIter(DefaultMaxIter), tolerance(DefaultTolerance),
|
||||
a(0.0), b(0.0), root(0.0) {};
|
||||
|
||||
G4Solver(const G4int iterations, const G4double tol) :
|
||||
MaxIter(iterations), tolerance(tol),
|
||||
a(0.0), b(0.0), root(0.0) {};
|
||||
|
||||
// copy constructor
|
||||
G4Solver(const G4Solver & right);
|
||||
|
||||
// destructor
|
||||
~G4Solver() {};
|
||||
|
||||
// operators
|
||||
G4Solver & operator=(const G4Solver & right);
|
||||
G4bool operator==(const G4Solver & right) const;
|
||||
G4bool operator!=(const G4Solver & right) const;
|
||||
|
||||
G4int GetMaxIterations(void) const {return MaxIter;}
|
||||
void SetMaxIterations(const G4int iterations) {MaxIter=iterations;}
|
||||
|
||||
G4double GetTolerance(void) const {return tolerance;}
|
||||
void SetTolerance(const G4double epsilon) {tolerance = epsilon;}
|
||||
|
||||
|
||||
G4double GetIntervalLowerLimit(void) const {return a;}
|
||||
G4double GetIntervalUpperLimit(void) const {return b;}
|
||||
|
||||
void SetIntervalLimits(const G4double Limit1, const G4double Limit2);
|
||||
|
||||
G4double GetRoot(void) const {return root;}
|
||||
|
||||
// Calculates the root by the Bisection method
|
||||
G4bool Bisection(Function & theFunction);
|
||||
|
||||
// Calculates the root by the Regula-Falsi method
|
||||
G4bool RegulaFalsi(Function & theFunction);
|
||||
|
||||
|
||||
// Calculates the root by the Brent's method
|
||||
G4bool Brent(Function & theFunction);
|
||||
|
||||
// Calculates the root by the Inverse Parabolic Interpolation method
|
||||
// due to Jack Crenshaw
|
||||
G4bool Crenshaw(Function & theFunction);
|
||||
|
||||
private:
|
||||
|
||||
// Maximum number of iterations
|
||||
G4int MaxIter;
|
||||
|
||||
//
|
||||
G4double tolerance;
|
||||
|
||||
// interval limits [a,b] which should bracket the root
|
||||
G4double a;
|
||||
G4double b;
|
||||
|
||||
// The root
|
||||
G4double root;
|
||||
|
||||
};
|
||||
|
||||
#include "G4Solver.icc"
|
||||
|
||||
#endif
|
||||
-352
@@ -1,352 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
template <class Function>
|
||||
G4bool G4Solver<Function>::Bisection(Function & theFunction)
|
||||
{
|
||||
// Check the interval before start
|
||||
if (a > b || std::abs(a-b) <= tolerance)
|
||||
{
|
||||
G4cerr << "G4Solver::Bisection: The interval must be properly set." << G4endl;
|
||||
return false;
|
||||
}
|
||||
G4double fa = theFunction(a);
|
||||
G4double fb = theFunction(b);
|
||||
if (fa*fb > 0.0)
|
||||
{
|
||||
G4cerr << "G4Solver::Bisection: The interval must include a root." << G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
G4double eps=tolerance*(b-a);
|
||||
|
||||
|
||||
// Finding the root
|
||||
for (G4int i = 0; i < MaxIter; i++)
|
||||
{
|
||||
G4double c = (a+b)/2.0;
|
||||
if ((b-a) < eps)
|
||||
{
|
||||
root = c;
|
||||
return true;
|
||||
}
|
||||
G4double fc = theFunction(c);
|
||||
if (fc == 0.0)
|
||||
{
|
||||
root = c;
|
||||
return true;
|
||||
}
|
||||
if (fa*fc < 0.0)
|
||||
{
|
||||
a=c;
|
||||
fa=fc;
|
||||
}
|
||||
else
|
||||
{
|
||||
b=c;
|
||||
fb=fc;
|
||||
}
|
||||
}
|
||||
G4cerr << "G4Solver::Bisection: Exceeded maximum number of iterations without convergence." << G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <class Function>
|
||||
G4bool G4Solver<Function>::RegulaFalsi(Function & theFunction)
|
||||
{
|
||||
// Check the interval before start
|
||||
if (a > b || std::abs(a-b) <= tolerance)
|
||||
{
|
||||
G4cerr << "G4Solver::RegulaFalsi: The interval must be properly set." << G4endl;
|
||||
return false;
|
||||
}
|
||||
G4double fa = theFunction(a);
|
||||
G4double fb = theFunction(b);
|
||||
if (fa*fb > 0.0)
|
||||
{
|
||||
G4cerr << "G4Solver::RegulaFalsi: The interval must include a root." << G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
G4double eps=tolerance*(b-a);
|
||||
|
||||
|
||||
// Finding the root
|
||||
for (G4int i = 0; i < MaxIter; i++)
|
||||
{
|
||||
G4double c = (a*fb-b*fa)/(fb-fa);
|
||||
G4double delta = std::min(std::abs(c-a),std::abs(b-c));
|
||||
if (delta < eps)
|
||||
{
|
||||
root = c;
|
||||
return true;
|
||||
}
|
||||
G4double fc = theFunction(c);
|
||||
if (fc == 0.0)
|
||||
{
|
||||
root = c;
|
||||
return true;
|
||||
}
|
||||
if (fa*fc < 0.0)
|
||||
{
|
||||
b=c;
|
||||
fb=fc;
|
||||
}
|
||||
else
|
||||
{
|
||||
a=c;
|
||||
fa=fc;
|
||||
}
|
||||
}
|
||||
G4cerr << "G4Solver::Bisection: Exceeded maximum number of iterations without convergence." << G4endl;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
G4bool G4Solver<Function>::Brent(Function & theFunction)
|
||||
{
|
||||
|
||||
const G4double precision = 3.0e-8;
|
||||
|
||||
// Check the interval before start
|
||||
if (a > b || std::abs(a-b) <= tolerance)
|
||||
{
|
||||
G4cerr << "G4Solver::Brent: The interval must be properly set." << G4endl;
|
||||
return false;
|
||||
}
|
||||
G4double fa = theFunction(a);
|
||||
G4double fb = theFunction(b);
|
||||
if (fa*fb > 0.0)
|
||||
{
|
||||
G4cerr << "G4Solver::Brent: The interval must include a root." << G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
G4double c = b;
|
||||
G4double fc = fb;
|
||||
G4double d = 0.0;
|
||||
G4double e = 0.0;
|
||||
|
||||
for (G4int i=0; i < MaxIter; i++)
|
||||
{
|
||||
// Rename a,b,c and adjust bounding interval d
|
||||
if (fb*fc > 0.0)
|
||||
{
|
||||
c = a;
|
||||
fc = fa;
|
||||
d = b - a;
|
||||
e = d;
|
||||
}
|
||||
if (std::abs(fc) < std::abs(fb))
|
||||
{
|
||||
a = b;
|
||||
b = c;
|
||||
c = a;
|
||||
fa = fb;
|
||||
fb = fc;
|
||||
fc = fa;
|
||||
}
|
||||
G4double Tol1 = 2.0*precision*std::abs(b) + 0.5*tolerance;
|
||||
G4double xm = 0.5*(c-b);
|
||||
if (std::abs(xm) <= Tol1 || fb == 0.0)
|
||||
{
|
||||
root = b;
|
||||
return true;
|
||||
}
|
||||
// Inverse quadratic interpolation
|
||||
if (std::abs(e) >= Tol1 && std::abs(fa) > std::abs(fb))
|
||||
{
|
||||
G4double ss = fb/fa;
|
||||
G4double p = 0.0;
|
||||
G4double q = 0.0;
|
||||
if (a == c)
|
||||
{
|
||||
p = 2.0*xm*ss;
|
||||
q = 1.0 - ss;
|
||||
}
|
||||
else
|
||||
{
|
||||
q = fa/fc;
|
||||
G4double r = fb/fc;
|
||||
p = ss*(2.0*xm*q*(q-r)-(b-a)*(r-1.0));
|
||||
q = (q-1.0)*(r-1.0)*(ss-1.0);
|
||||
}
|
||||
// Check bounds
|
||||
if (p > 0.0) q = -q;
|
||||
p = std::abs(p);
|
||||
G4double min1 = 3.0*xm*q-std::abs(Tol1*q);
|
||||
G4double min2 = std::abs(e*q);
|
||||
if (2.0*p < std::min(min1,min2))
|
||||
{
|
||||
// Interpolation
|
||||
e = d;
|
||||
d = p/q;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bisection
|
||||
d = xm;
|
||||
e = d;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bounds decreasing too slowly, use bisection
|
||||
d = xm;
|
||||
e = d;
|
||||
}
|
||||
// Move last guess to a
|
||||
a = b;
|
||||
fa = fb;
|
||||
if (std::abs(d) > Tol1) b += d;
|
||||
else
|
||||
{
|
||||
if (xm >= 0.0) b += std::abs(Tol1);
|
||||
else b -= std::abs(Tol1);
|
||||
}
|
||||
fb = theFunction(b);
|
||||
}
|
||||
G4cerr << "G4Solver::Brent: Number of iterations exceeded." << G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class Function>
|
||||
G4bool G4Solver<Function>::Crenshaw(Function & theFunction)
|
||||
{
|
||||
// Check the interval before start
|
||||
if (a > b || std::abs(a-b) <= tolerance)
|
||||
{
|
||||
G4cerr << "G4Solver::Crenshaw: The interval must be properly set." << G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
G4double fa = theFunction(a);
|
||||
if (fa == 0.0)
|
||||
{
|
||||
root = a;
|
||||
return true;
|
||||
}
|
||||
|
||||
G4double Mlast = a;
|
||||
|
||||
G4double fb = theFunction(b);
|
||||
if (fb == 0.0)
|
||||
{
|
||||
root = b;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fa*fb > 0.0)
|
||||
{
|
||||
G4cerr << "G4Solver::Crenshaw: The interval must include a root." << G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for (G4int i=0; i < MaxIter; i++)
|
||||
{
|
||||
G4double c = 0.5 * (b + a);
|
||||
G4double fc = theFunction(c);
|
||||
if (fc == 0.0 || std::abs(c - a) < tolerance)
|
||||
{
|
||||
root = c;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fc * fa > 0.0)
|
||||
{
|
||||
G4double tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
tmp = fa;
|
||||
fa = fb;
|
||||
fb = tmp;
|
||||
}
|
||||
|
||||
G4double fc0 = fc - fa;
|
||||
G4double fb1 = fb - fc;
|
||||
G4double fb0 = fb - fa;
|
||||
if (fb * fb0 < 2.0 * fc * fc0)
|
||||
{
|
||||
b = c;
|
||||
fb = fc;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double B = (c - a) / fc0;
|
||||
G4double C = (fc0 - fb1) / (fb1 * fb0);
|
||||
G4double M = a - B * fa * (1.0 - C * fc);
|
||||
G4double fM = theFunction(M);
|
||||
if (fM == 0.0 || std::abs(M - Mlast) < tolerance)
|
||||
{
|
||||
root = M;
|
||||
return true;
|
||||
}
|
||||
Mlast = M;
|
||||
if (fM * fa < 0.0)
|
||||
{
|
||||
b = M;
|
||||
fb = fM;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = M;
|
||||
fa = fM;
|
||||
b = c;
|
||||
fb = fc;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <class Function>
|
||||
void G4Solver<Function>::SetIntervalLimits(const G4double Limit1, const G4double Limit2)
|
||||
{
|
||||
if (std::abs(Limit1-Limit2) <= tolerance)
|
||||
{
|
||||
G4cerr << "G4Solver::SetIntervalLimits: Interval must be wider than tolerance." << G4endl;
|
||||
return;
|
||||
}
|
||||
if (Limit1 < Limit2)
|
||||
{
|
||||
a = Limit1;
|
||||
b = Limit2;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = Limit2;
|
||||
b = Limit1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
+17
-36
@@ -23,8 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
|
||||
@@ -38,52 +36,35 @@
|
||||
#include "G4StatMFMacroCanonical.hh"
|
||||
#include "G4StatMFChannel.hh"
|
||||
#include "G4Fragment.hh"
|
||||
#include "G4ParticleTable.hh"
|
||||
#include "G4IonTable.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
class G4StatMF : public G4VMultiFragmentation
|
||||
{
|
||||
public:
|
||||
|
||||
G4StatMF();
|
||||
~G4StatMF();
|
||||
G4StatMF();
|
||||
~G4StatMF() override;
|
||||
|
||||
// Copy constructor
|
||||
G4StatMF(const G4StatMF & right) = delete;
|
||||
G4FragmentVector* BreakItUp(const G4Fragment &theNucleus) override;
|
||||
|
||||
// Operators
|
||||
G4StatMF & operator=(const G4StatMF & right) = delete;
|
||||
G4bool operator==(const G4StatMF & right) = delete;
|
||||
G4bool operator!=(const G4StatMF & right) = delete;
|
||||
|
||||
G4FragmentVector* BreakItUp(const G4Fragment &theNucleus) override;
|
||||
G4StatMF(const G4StatMF & right) = delete;
|
||||
G4StatMF & operator=(const G4StatMF & right) = delete;
|
||||
G4bool operator==(const G4StatMF & right) = delete;
|
||||
G4bool operator!=(const G4StatMF & right) = delete;
|
||||
|
||||
private:
|
||||
|
||||
// This finds temperature of breaking channel.
|
||||
G4bool FindTemperatureOfBreakingChannel(const G4Fragment & theFragment,
|
||||
const G4StatMFChannel * aChannel,
|
||||
G4double & Temperature);
|
||||
// This finds temperature of breaking channel.
|
||||
G4bool FindTemperatureOfBreakingChannel(const G4Fragment & theFragment,
|
||||
const G4StatMFChannel * aChannel,
|
||||
G4double & Temperature);
|
||||
|
||||
G4double CalcEnergy(G4int A, G4int Z,
|
||||
const G4StatMFChannel * aChannel,
|
||||
G4double T);
|
||||
G4double CalcEnergy(G4int A, G4int Z, const G4StatMFChannel* aChannel,
|
||||
G4double T);
|
||||
|
||||
G4VStatMFEnsemble* _theEnsemble = nullptr;
|
||||
G4int _secID = -1; // Creator model ID for the secondaries created by this model
|
||||
G4StatMFMicroCanonical* theMicrocanonicalEnsemble{nullptr};
|
||||
G4StatMFMacroCanonical* theMacrocanonicalEnsemble{nullptr};
|
||||
|
||||
G4VStatMFEnsemble* fEnsemble{nullptr};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -88,8 +88,8 @@ private:
|
||||
void FragmentsMomenta(G4int NF, G4int idx, G4double T);
|
||||
|
||||
// Rotates a 3-vector P to close momentum triangle Pa + V + P = 0
|
||||
G4ThreeVector RotateMomentum(G4ThreeVector Pa, G4ThreeVector V,
|
||||
G4ThreeVector P);
|
||||
G4ThreeVector RotateMomentum(G4ThreeVector& Pa, G4ThreeVector& V,
|
||||
G4ThreeVector& P);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
+28
-58
@@ -23,10 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
//
|
||||
// Modification: 13.08.2025 V.Ivanchenko rewrite
|
||||
|
||||
#ifndef G4StatMFMacroCanonical_h
|
||||
#define G4StatMFMacroCanonical_h 1
|
||||
@@ -50,73 +50,43 @@ class G4StatMFMacroCanonical : public G4VStatMFEnsemble {
|
||||
|
||||
public:
|
||||
|
||||
// G4StatMFMacroCanonical class must be initialized with a G4Fragment.
|
||||
G4StatMFMacroCanonical(G4Fragment const & theFragment);
|
||||
G4StatMFMacroCanonical();
|
||||
|
||||
// destructor
|
||||
~G4StatMFMacroCanonical();
|
||||
~G4StatMFMacroCanonical() override;
|
||||
|
||||
private:
|
||||
// default constructor
|
||||
G4StatMFMacroCanonical() {};
|
||||
// Initialise for a given G4Fragment
|
||||
void Initialise(const G4Fragment& theFragment) override;
|
||||
|
||||
// Choice of the channel
|
||||
G4StatMFChannel* ChooseAandZ(const G4Fragment &theFragment) override;
|
||||
|
||||
// copy constructor
|
||||
G4StatMFMacroCanonical(const G4StatMFMacroCanonical &) : G4VStatMFEnsemble() {};
|
||||
|
||||
|
||||
// operators
|
||||
G4StatMFMacroCanonical & operator=(const G4StatMFMacroCanonical & right);
|
||||
G4bool operator==(const G4StatMFMacroCanonical & right) const;
|
||||
G4bool operator!=(const G4StatMFMacroCanonical & right) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Choice of fragment atomic numbers and charges.
|
||||
G4StatMFChannel * ChooseAandZ(const G4Fragment &theFragment);
|
||||
G4StatMFMacroCanonical(const G4StatMFMacroCanonical&) = delete;
|
||||
G4StatMFMacroCanonical& operator=(const G4StatMFMacroCanonical& right) = delete;
|
||||
G4bool operator==(const G4StatMFMacroCanonical& right) const = delete;
|
||||
G4bool operator!=(const G4StatMFMacroCanonical& right) const = delete;
|
||||
|
||||
private:
|
||||
|
||||
// Initailization method
|
||||
void Initialize(const G4Fragment & theFragment);
|
||||
|
||||
//
|
||||
void CalculateTemperature(const G4Fragment & theFragment);
|
||||
|
||||
// Determines fragments multiplicities and compute total fragment multiplicity
|
||||
G4double ChooseA(G4int A, std::vector<G4int> & ANumbers);
|
||||
// Determines fragments multiplicities and compute total fragment multiplicity
|
||||
G4double ChooseA(G4int A, std::vector<G4int>& ANumbers);
|
||||
|
||||
// Samples charges of fragments
|
||||
G4StatMFChannel * ChooseZ(G4int & Z,
|
||||
std::vector<G4int> & FragmentsA);
|
||||
// Samples charges of fragments
|
||||
G4StatMFChannel* ChooseZ(G4int Z, std::vector<G4int>& FragmentsA);
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
|
||||
// Chemical Potential \mu
|
||||
G4double _ChemPotentialMu;
|
||||
|
||||
// Chemical Potential \nu
|
||||
G4double _ChemPotentialNu;
|
||||
|
||||
|
||||
// Parameter Kappa
|
||||
G4double _Kappa;
|
||||
|
||||
// Clusters
|
||||
std::vector<G4VStatMFMacroCluster*> _theClusters;
|
||||
|
||||
struct DeleteFragment
|
||||
{
|
||||
template<typename T>
|
||||
void operator()(const T* ptr) const
|
||||
{
|
||||
delete ptr;
|
||||
}
|
||||
};
|
||||
G4StatMFMacroTemperature* theTemp{nullptr};
|
||||
|
||||
// Chemical Potential \mu
|
||||
G4double fChemPotentialMu{0.0};
|
||||
|
||||
// Chemical Potential \nu
|
||||
G4double fChemPotentialNu{0.0};
|
||||
|
||||
// Parameter Kappa
|
||||
G4double fKappa{0.0};
|
||||
|
||||
// Clusters
|
||||
std::vector<G4VStatMFMacroCluster*> fClusters;
|
||||
std::vector<G4double> fAcumMultiplicity;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+33
-63
@@ -23,93 +23,63 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
//
|
||||
// Modification: 13.08.2025 V.Ivanchenko rewrite
|
||||
|
||||
#ifndef G4StatMFMacroChemicalPotential_h
|
||||
#define G4StatMFMacroChemicalPotential_h 1
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "G4StatMFParameters.hh"
|
||||
#include "G4VStatMFMacroCluster.hh"
|
||||
#include "G4StatMFMacroMultiplicity.hh"
|
||||
#include "G4Solver.hh"
|
||||
|
||||
#include "G4FunctionSolver.hh"
|
||||
|
||||
class G4StatMFMacroMultiplicity;
|
||||
|
||||
class G4StatMFMacroChemicalPotential {
|
||||
|
||||
public:
|
||||
|
||||
G4StatMFMacroChemicalPotential(const G4double anA, const G4double aZ,
|
||||
const G4double kappa,
|
||||
const G4double temp,
|
||||
std::vector<G4VStatMFMacroCluster*> * ClusterVector) :
|
||||
theA(anA),
|
||||
theZ(aZ),
|
||||
_Kappa(kappa),
|
||||
_MeanMultiplicity(0.0),
|
||||
_MeanTemperature(temp),
|
||||
_ChemPotentialMu(0.0),
|
||||
_ChemPotentialNu(0.0),
|
||||
_theClusters(ClusterVector)
|
||||
{};
|
||||
|
||||
~G4StatMFMacroChemicalPotential() {};
|
||||
|
||||
G4double operator()(const G4double nu)
|
||||
{ return (theZ - this->CalcMeanZ(nu))/theZ; }
|
||||
G4StatMFMacroChemicalPotential();
|
||||
|
||||
private:
|
||||
// Default constructor
|
||||
G4StatMFMacroChemicalPotential() {};
|
||||
~G4StatMFMacroChemicalPotential();
|
||||
|
||||
// copy constructor
|
||||
G4StatMFMacroChemicalPotential(const G4StatMFMacroChemicalPotential &) {};
|
||||
void Initialise(const G4int anA, const G4int aZ,
|
||||
const G4double kappa, const G4double temp,
|
||||
std::vector<G4VStatMFMacroCluster*>* cVector);
|
||||
|
||||
G4double Function(G4double nu)
|
||||
{ return (theZ - CalcMeanZ(nu)); }
|
||||
|
||||
// operators
|
||||
G4StatMFMacroChemicalPotential & operator=(const G4StatMFMacroChemicalPotential & right);
|
||||
G4bool operator==(const G4StatMFMacroChemicalPotential & right) const;
|
||||
G4bool operator!=(const G4StatMFMacroChemicalPotential & right) const;
|
||||
G4double CalcChemicalPotentialNu();
|
||||
|
||||
public:
|
||||
G4double GetMeanMultiplicity() const {return fMeanMultiplicity;}
|
||||
G4double GetChemicalPotentialMu() const {return fChemPotentialMu;}
|
||||
G4double GetChemicalPotentialNu() const {return fChemPotentialNu;}
|
||||
|
||||
G4double GetMeanMultiplicity(void) const {return _MeanMultiplicity;}
|
||||
|
||||
G4double GetChemicalPotentialMu(void) const {return _ChemPotentialMu;}
|
||||
|
||||
G4double GetChemicalPotentialNu(void) const {return _ChemPotentialNu;}
|
||||
|
||||
G4double CalcChemicalPotentialNu(void);
|
||||
G4StatMFMacroChemicalPotential(const G4StatMFMacroChemicalPotential &) = delete;
|
||||
G4StatMFMacroChemicalPotential& operator=
|
||||
(const G4StatMFMacroChemicalPotential & right) = delete;
|
||||
G4bool operator==(const G4StatMFMacroChemicalPotential & right) const = delete;
|
||||
G4bool operator!=(const G4StatMFMacroChemicalPotential & right) const = delete;
|
||||
|
||||
private:
|
||||
|
||||
G4double CalcMeanZ(const G4double nu);
|
||||
G4double CalcMeanZ(const G4double nu);
|
||||
void CalcChemicalPotentialMu(const G4double nu);
|
||||
|
||||
void CalcChemicalPotentialMu(const G4double nu);
|
||||
|
||||
private:
|
||||
|
||||
G4double theA;
|
||||
|
||||
G4double theZ;
|
||||
|
||||
G4double _Kappa;
|
||||
|
||||
G4double _MeanMultiplicity;
|
||||
|
||||
G4double _MeanTemperature;
|
||||
G4FunctionSolver<G4StatMFMacroChemicalPotential>* fSolver;
|
||||
G4StatMFMacroMultiplicity* theMultip;
|
||||
|
||||
G4int theA{0};
|
||||
G4int theZ{0};
|
||||
G4double fKappa{0.0};
|
||||
G4double fMeanTemperature{0.0};
|
||||
G4double fMeanMultiplicity{0.0};
|
||||
G4double fChemPotentialMu{0.0};
|
||||
G4double fChemPotentialNu{0.0};
|
||||
|
||||
G4double _ChemPotentialMu;
|
||||
|
||||
G4double _ChemPotentialNu;
|
||||
|
||||
std::vector<G4VStatMFMacroCluster*> * _theClusters;
|
||||
|
||||
|
||||
std::vector<G4VStatMFMacroCluster*>* fClusters{nullptr};
|
||||
};
|
||||
#endif
|
||||
|
||||
+30
-55
@@ -23,86 +23,61 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
//
|
||||
// Modification: 13.08.2025 V.Ivanchenko rewrite
|
||||
|
||||
#ifndef G4StatMFMacroMultiplicity_h
|
||||
#define G4StatMFMacroMultiplicity_h 1
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "G4StatMFParameters.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4VStatMFMacroCluster.hh"
|
||||
#include "G4Solver.hh"
|
||||
|
||||
|
||||
#include "G4FunctionSolver.hh"
|
||||
|
||||
class G4StatMFMacroMultiplicity {
|
||||
|
||||
public:
|
||||
|
||||
G4StatMFMacroMultiplicity(const G4double anA,
|
||||
const G4double kappa,
|
||||
const G4double temp,
|
||||
const G4double nu,
|
||||
std::vector<G4VStatMFMacroCluster*> * ClusterVector) :
|
||||
theA(anA),
|
||||
_Kappa(kappa),
|
||||
_MeanMultiplicity(0.0),
|
||||
_MeanTemperature(temp),
|
||||
_ChemPotentialMu(0.0),
|
||||
_ChemPotentialNu(nu),
|
||||
_theClusters(ClusterVector)
|
||||
{};
|
||||
|
||||
~G4StatMFMacroMultiplicity() {};
|
||||
|
||||
G4double operator()(const G4double mu)
|
||||
{ return (theA - this->CalcMeanA(mu))/theA; }
|
||||
G4StatMFMacroMultiplicity();
|
||||
|
||||
private:
|
||||
// Default constructor
|
||||
G4StatMFMacroMultiplicity() {};
|
||||
~G4StatMFMacroMultiplicity();
|
||||
|
||||
// copy constructor
|
||||
G4StatMFMacroMultiplicity(const G4StatMFMacroMultiplicity &) {};
|
||||
void Initialise(const G4int anA, const G4double kappa,
|
||||
const G4double temp, const G4double nu,
|
||||
std::vector<G4VStatMFMacroCluster*>* cVector);
|
||||
|
||||
G4double Function(G4double mu)
|
||||
{ return (theA - CalcMeanA(mu)); };
|
||||
|
||||
// operators
|
||||
G4StatMFMacroMultiplicity & operator=(const G4StatMFMacroMultiplicity & right);
|
||||
G4bool operator==(const G4StatMFMacroMultiplicity & right) const;
|
||||
G4bool operator!=(const G4StatMFMacroMultiplicity & right) const;
|
||||
G4double CalcChemicalPotentialMu();
|
||||
|
||||
public:
|
||||
G4double GetMeanMultiplicity() const { return fMeanMultiplicity; }
|
||||
|
||||
G4double GetMeanMultiplicity(void) const {return _MeanMultiplicity;}
|
||||
|
||||
G4double GetChemicalPotentialMu(void) const {return _ChemPotentialMu;}
|
||||
G4double GetChemicalPotentialMu() const { return fChemPotentialMu; }
|
||||
|
||||
G4double CalcChemicalPotentialMu(void);
|
||||
G4StatMFMacroMultiplicity(const G4StatMFMacroMultiplicity&) = delete;
|
||||
G4StatMFMacroMultiplicity& operator=
|
||||
(const G4StatMFMacroMultiplicity& right) = delete;
|
||||
G4bool operator==(const G4StatMFMacroMultiplicity& right) const = delete;
|
||||
G4bool operator!=(const G4StatMFMacroMultiplicity& right) const = delete;
|
||||
|
||||
private:
|
||||
|
||||
G4double CalcMeanA(const G4double mu);
|
||||
G4double CalcMeanA(const G4double mu);
|
||||
|
||||
private:
|
||||
|
||||
G4double theA;
|
||||
|
||||
G4double _Kappa;
|
||||
|
||||
G4double _MeanMultiplicity;
|
||||
|
||||
G4double _MeanTemperature;
|
||||
|
||||
G4double _ChemPotentialMu;
|
||||
|
||||
G4double _ChemPotentialNu;
|
||||
|
||||
std::vector<G4VStatMFMacroCluster*> * _theClusters;
|
||||
G4int A{0};
|
||||
G4double theA{0};
|
||||
G4double fKappa{0.0};
|
||||
G4double fMeanTemperature{0.0};
|
||||
G4double fChemPotentialNu{0.0};
|
||||
|
||||
G4double fMeanMultiplicity{0.0};
|
||||
G4double fChemPotentialMu{0.0};
|
||||
|
||||
std::vector<G4VStatMFMacroCluster*>* fClusters{nullptr};
|
||||
G4FunctionSolver<G4StatMFMacroMultiplicity>* fSolver;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+43
-59
@@ -23,93 +23,77 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
//
|
||||
// Modification: 13.08.2025 V.Ivanchenko rewrite
|
||||
|
||||
#ifndef G4StatMFMacroTemperature_h
|
||||
#define G4StatMFMacroTemperature_h 1
|
||||
|
||||
#include "G4StatMFParameters.hh"
|
||||
#include <vector>
|
||||
#include "globals.hh"
|
||||
#include "G4VStatMFMacroCluster.hh"
|
||||
#include "G4StatMFMacroChemicalPotential.hh"
|
||||
#include "G4Solver.hh"
|
||||
|
||||
#include "G4FunctionSolver.hh"
|
||||
|
||||
class G4StatMFMacroChemicalPotential;
|
||||
|
||||
class G4StatMFMacroTemperature {
|
||||
|
||||
public:
|
||||
|
||||
G4StatMFMacroTemperature(const G4double anA, const G4double aZ,
|
||||
const G4double ExEnergy, const G4double FreeE0,
|
||||
const G4double kappa,
|
||||
std::vector<G4VStatMFMacroCluster*> * ClusterVector);
|
||||
G4StatMFMacroTemperature();
|
||||
~G4StatMFMacroTemperature();
|
||||
|
||||
void Initialise(const G4int anA, const G4int aZ,
|
||||
const G4double ExEnergy, const G4double FreeE0,
|
||||
const G4double kappa,
|
||||
std::vector<G4VStatMFMacroCluster*>* ClusterVector);
|
||||
|
||||
~G4StatMFMacroTemperature();
|
||||
|
||||
G4double operator()(const G4double T)
|
||||
{ return (_ExEnergy - this->FragsExcitEnergy(T))/_ExEnergy; }
|
||||
G4double Function(G4double T)
|
||||
{ return (fExEnergy - FragsExcitEnergy(T)); }
|
||||
|
||||
private:
|
||||
// copy constructor
|
||||
G4StatMFMacroTemperature(const G4StatMFMacroTemperature&) = delete;
|
||||
G4StatMFMacroTemperature& operator=
|
||||
(const G4StatMFMacroTemperature& right) = delete;
|
||||
G4bool operator==(const G4StatMFMacroTemperature& right) const = delete;
|
||||
G4bool operator!=(const G4StatMFMacroTemperature& right) const = delete;
|
||||
|
||||
// Default constructor
|
||||
G4StatMFMacroTemperature();
|
||||
|
||||
// copy constructor
|
||||
G4StatMFMacroTemperature(const G4StatMFMacroTemperature &) {};
|
||||
|
||||
|
||||
// operators
|
||||
G4StatMFMacroTemperature & operator=(const G4StatMFMacroTemperature & right);
|
||||
G4bool operator==(const G4StatMFMacroTemperature & right) const;
|
||||
G4bool operator!=(const G4StatMFMacroTemperature & right) const;
|
||||
|
||||
public:
|
||||
|
||||
inline G4double GetMeanMultiplicity(void) const {return _MeanMultiplicity;}
|
||||
G4double GetMeanMultiplicity(void) const {return fMeanMultiplicity;}
|
||||
|
||||
inline G4double GetChemicalPotentialMu(void) const {return _ChemPotentialMu;}
|
||||
G4double GetChemicalPotentialMu(void) const {return fChemPotentialMu;}
|
||||
|
||||
inline G4double GetChemicalPotentialNu(void) const {return _ChemPotentialNu;}
|
||||
G4double GetChemicalPotentialNu(void) const {return fChemPotentialNu;}
|
||||
|
||||
inline G4double GetTemperature(void) const {return _MeanTemperature;}
|
||||
G4double GetTemperature(void) const {return fMeanTemperature;}
|
||||
|
||||
inline G4double GetEntropy(void) const {return _MeanEntropy;}
|
||||
G4double GetEntropy(void) const {return fMeanEntropy;}
|
||||
|
||||
G4double CalcTemperature(void);
|
||||
G4double CalcTemperature(void);
|
||||
|
||||
private:
|
||||
|
||||
G4double FragsExcitEnergy(const G4double T);
|
||||
G4double FragsExcitEnergy(const G4double T);
|
||||
|
||||
void CalcChemicalPotentialNu(const G4double T);
|
||||
void CalcChemicalPotentialNu(const G4double T);
|
||||
|
||||
private:
|
||||
G4FunctionSolver<G4StatMFMacroTemperature>* fSolver;
|
||||
G4StatMFMacroChemicalPotential* theChemPot;
|
||||
|
||||
G4double theA;
|
||||
|
||||
G4double theZ;
|
||||
|
||||
G4double _ExEnergy;
|
||||
G4int theA{0};
|
||||
G4int theZ{0};
|
||||
G4double fExEnergy{0.0};
|
||||
G4double fFreeInternalE0{0.0};
|
||||
G4double fKappa{0.0};
|
||||
G4double fMeanMultiplicity{0.0};
|
||||
G4double fMeanTemperature{0.0};
|
||||
G4double fChemPotentialMu{0.0};
|
||||
G4double fChemPotentialNu{0.0};
|
||||
G4double fMeanEntropy{0.0};
|
||||
|
||||
G4double _FreeInternalE0;
|
||||
|
||||
G4double _Kappa;
|
||||
|
||||
G4double _MeanMultiplicity;
|
||||
|
||||
G4double _MeanTemperature;
|
||||
|
||||
G4double _ChemPotentialMu;
|
||||
|
||||
G4double _ChemPotentialNu;
|
||||
|
||||
G4double _MeanEntropy;
|
||||
|
||||
std::vector<G4VStatMFMacroCluster*> * _theClusters;
|
||||
|
||||
|
||||
std::vector<G4VStatMFMacroCluster*>* fClusters{nullptr};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+36
-52
@@ -23,16 +23,17 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
//
|
||||
// Modification: 13.08.2025 V.Ivanchenko rewrite
|
||||
|
||||
#ifndef G4StatMFMicroCanonical_h
|
||||
#define G4StatMFMicroCanonical_h 1
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4VStatMFEnsemble.hh"
|
||||
#include "G4StatMFMicroPartition.hh"
|
||||
#include "G4StatMFMicroManager.hh"
|
||||
@@ -40,74 +41,57 @@
|
||||
#include "G4StatMFChannel.hh"
|
||||
|
||||
#include "G4Fragment.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4VStatMFMacroCluster.hh"
|
||||
#include "G4FunctionSolver.hh"
|
||||
|
||||
class G4Pow;
|
||||
|
||||
class G4StatMFMicroCanonical : public G4VStatMFEnsemble {
|
||||
|
||||
public:
|
||||
|
||||
// G4StatMFMicroCanonical class must be initialized with a G4Fragment.
|
||||
G4StatMFMicroCanonical(const G4Fragment & theFragment);
|
||||
G4StatMFMicroCanonical();
|
||||
|
||||
// destructor
|
||||
~G4StatMFMicroCanonical();
|
||||
~G4StatMFMicroCanonical() override;
|
||||
|
||||
private:
|
||||
// default constructor
|
||||
G4StatMFMicroCanonical() {};
|
||||
// Initialise for a given G4Fragment
|
||||
void Initialise(const G4Fragment& theFragment) override;
|
||||
|
||||
// Choice of the channel
|
||||
G4StatMFChannel* ChooseAandZ(const G4Fragment &theFragment) override;
|
||||
|
||||
// copy constructor
|
||||
G4StatMFMicroCanonical(const G4StatMFMicroCanonical &right);
|
||||
G4double Function(G4double T)
|
||||
{ return (fExEnergy + pFreeInternalE0 - CalcFreeInternalEnergy(T)); }
|
||||
|
||||
|
||||
// operators
|
||||
G4StatMFMicroCanonical & operator=(const G4StatMFMicroCanonical & right);
|
||||
G4bool operator==(const G4StatMFMicroCanonical & right) const;
|
||||
G4bool operator!=(const G4StatMFMicroCanonical & right) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Choice of fragment atomic numbers and charges.
|
||||
G4StatMFChannel * ChooseAandZ(const G4Fragment & theFragment);
|
||||
|
||||
enum {MaxAllowedMultiplicity = 4};
|
||||
// copy constructor
|
||||
G4StatMFMicroCanonical(const G4StatMFMicroCanonical& right) = delete;
|
||||
G4StatMFMicroCanonical& operator=(const G4StatMFMicroCanonical& right) = delete;
|
||||
G4bool operator==(const G4StatMFMicroCanonical& right) const = delete;
|
||||
G4bool operator!=(const G4StatMFMicroCanonical& right) const = delete;
|
||||
|
||||
private:
|
||||
|
||||
// Initailization method
|
||||
void Initialize(const G4Fragment & theFragment);
|
||||
// Calculate Entropy of Compound Nucleus
|
||||
G4double CalcEntropyOfCompoundNucleus(G4double& T);
|
||||
|
||||
// Calculate Entropy of Compound Nucleus
|
||||
G4double CalcEntropyOfCompoundNucleus(const G4Fragment & theFragment, G4double & TConf);
|
||||
G4double CalcFreeInternalEnergy(G4double T);
|
||||
|
||||
G4double CalcFreeInternalEnergy(const G4Fragment & theFragment, G4double T);
|
||||
|
||||
G4double CalcInvLevelDensity(G4int anA);
|
||||
G4int Z{0};
|
||||
G4int A{0};
|
||||
|
||||
|
||||
// Data members
|
||||
private:
|
||||
|
||||
// This is a vector of partitions managers for partitions of different
|
||||
// multiplicities:
|
||||
|
||||
std::vector<G4StatMFMicroManager*> _ThePartitionManagerVector;
|
||||
|
||||
// Statistical weight of compound nucleus
|
||||
G4double _WCompoundNucleus;
|
||||
// Statistical weight of compound nucleus
|
||||
G4double fWCompoundNucleus{0.0};
|
||||
G4double fExEnergy{0.0};
|
||||
|
||||
|
||||
struct DeleteFragment
|
||||
{
|
||||
template<typename T>
|
||||
void operator()(const T* ptr) const
|
||||
{
|
||||
delete ptr;
|
||||
}
|
||||
};
|
||||
G4double A13{0.0};
|
||||
G4double fInvLevelDensity{1.0};
|
||||
G4double fSymmetryTerm{1.0};
|
||||
G4double fCoulombTerm{0.0};
|
||||
|
||||
G4Pow* g4calc;
|
||||
G4FunctionSolver<G4StatMFMicroCanonical>* fSolver;
|
||||
// This is a vector of partitions provided different multiplicities
|
||||
std::vector<G4StatMFMicroManager*> fPartitionManagerVector;
|
||||
|
||||
};
|
||||
|
||||
|
||||
+28
-65
@@ -44,85 +44,48 @@ class G4StatMFMicroManager {
|
||||
|
||||
public:
|
||||
|
||||
// G4StatMFMicroManager class must be initialized with a G4Fragment, multiplicity,
|
||||
// free internal energy and the entropy of the compund nucleus.
|
||||
G4StatMFMicroManager(const G4Fragment & theFragment, G4int multiplicity,
|
||||
G4double FreeIntE, G4double SCompNuc);
|
||||
// G4StatMFMicroManager class must be initialized with a G4Fragment, multiplicity,
|
||||
// free internal energy and the entropy of the compund nucleus.
|
||||
G4StatMFMicroManager(const G4Fragment& theFragment, G4int multiplicity,
|
||||
G4double FreeIntE, G4double SCompNuc);
|
||||
|
||||
// destructor
|
||||
~G4StatMFMicroManager();
|
||||
~G4StatMFMicroManager();
|
||||
|
||||
private:
|
||||
// default constructor
|
||||
G4StatMFMicroManager() {};
|
||||
// copy constructor
|
||||
G4StatMFMicroManager(const G4StatMFMicroManager& right) = delete;
|
||||
G4StatMFMicroManager & operator=(const G4StatMFMicroManager& right) = delete;
|
||||
G4bool operator==(const G4StatMFMicroManager & right) const = delete;
|
||||
G4bool operator!=(const G4StatMFMicroManager & right) const = delete;
|
||||
|
||||
|
||||
// copy constructor
|
||||
G4StatMFMicroManager(const G4StatMFMicroManager &right);
|
||||
|
||||
|
||||
// operators
|
||||
G4StatMFMicroManager & operator=(const G4StatMFMicroManager & right);
|
||||
|
||||
public:
|
||||
G4bool operator==(const G4StatMFMicroManager & right) const;
|
||||
G4bool operator!=(const G4StatMFMicroManager & right) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Choice of fragment atomic numbers and charges.
|
||||
G4StatMFChannel * ChooseChannel(G4int A0, G4int Z0, G4double MeanT);
|
||||
// Choice of fragment atomic numbers and charges.
|
||||
G4StatMFChannel* ChooseChannel(G4int A0, G4int Z0, G4double MeanT);
|
||||
|
||||
G4double GetProbability(void) const {return _WW;}
|
||||
G4double GetProbability(void) const {return _WW;}
|
||||
|
||||
void Normalize(G4double Norm);
|
||||
void Normalize(G4double Norm);
|
||||
|
||||
G4double GetMeanMultiplicity(void) const {return _MeanMultiplicity; }
|
||||
G4double GetMeanMultiplicity(void) const {return _MeanMultiplicity; }
|
||||
|
||||
G4double GetMeanTemperature(void) const {return _MeanTemperature; }
|
||||
G4double GetMeanTemperature(void) const {return _MeanTemperature; }
|
||||
|
||||
G4double GetMeanEntropy(void) const {return _MeanEntropy; }
|
||||
G4double GetMeanEntropy(void) const {return _MeanEntropy; }
|
||||
|
||||
private:
|
||||
|
||||
// Initailization method
|
||||
void Initialize(const G4Fragment & theFragment, G4int m,
|
||||
G4double FreeIntE, G4double SCompNuc);
|
||||
// Initailization method
|
||||
void Initialize(const G4Fragment & theFragment, G4int m,
|
||||
G4double FreeIntE, G4double SCompNuc);
|
||||
|
||||
G4bool MakePartition(G4int k, G4int * ANumbers);
|
||||
G4bool MakePartition(G4int k, G4int* ANumbers);
|
||||
|
||||
// Partitions vector
|
||||
std::vector<G4StatMFMicroPartition*> _Partition;
|
||||
|
||||
|
||||
|
||||
// Data members
|
||||
private:
|
||||
|
||||
|
||||
// Partitions vector
|
||||
std::vector<G4StatMFMicroPartition*> _Partition;
|
||||
|
||||
|
||||
// Statistical weight
|
||||
G4double _WW;
|
||||
|
||||
G4double _Normalization;
|
||||
|
||||
G4double _MeanMultiplicity;
|
||||
|
||||
G4double _MeanTemperature;
|
||||
|
||||
G4double _MeanEntropy;
|
||||
|
||||
struct DeleteFragment
|
||||
{
|
||||
template<typename T>
|
||||
void operator()(const T* ptr) const
|
||||
{
|
||||
delete ptr;
|
||||
}
|
||||
};
|
||||
|
||||
G4double _WW;
|
||||
G4double _Normalization;
|
||||
G4double _MeanMultiplicity;
|
||||
G4double _MeanTemperature;
|
||||
G4double _MeanEntropy;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+21
-37
@@ -23,11 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
|
||||
// 13.08.2025 V.Ivanchenko rewrite
|
||||
|
||||
#ifndef G4VStatMFEnsemble_h
|
||||
#define G4VStatMFEnsemble_h 1
|
||||
@@ -38,50 +36,36 @@
|
||||
class G4VStatMFEnsemble {
|
||||
|
||||
public:
|
||||
// Default Constructor
|
||||
G4VStatMFEnsemble() :
|
||||
__FreeInternalE0(0.0),
|
||||
__MeanTemperature(0.0),
|
||||
__MeanEntropy(0.0),
|
||||
__MeanMultiplicity(0.0)
|
||||
{};
|
||||
|
||||
G4VStatMFEnsemble() = default;
|
||||
virtual ~G4VStatMFEnsemble() = default;
|
||||
|
||||
// Destructor
|
||||
virtual ~G4VStatMFEnsemble() {};
|
||||
virtual void Initialise(const G4Fragment& aFragment) = 0;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Copy constructor
|
||||
G4VStatMFEnsemble(const G4VStatMFEnsemble & right);
|
||||
|
||||
// operators
|
||||
G4VStatMFEnsemble & operator=(const G4VStatMFEnsemble & right);
|
||||
G4bool operator==(const G4VStatMFEnsemble & right) const;
|
||||
G4bool operator!=(const G4VStatMFEnsemble & right) const;
|
||||
|
||||
public:
|
||||
|
||||
virtual G4StatMFChannel * ChooseAandZ(const G4Fragment & aFragment) = 0;
|
||||
virtual G4StatMFChannel* ChooseAandZ(const G4Fragment& aFragment) = 0;
|
||||
|
||||
G4double GetMeanMultiplicity(void) const {return __MeanMultiplicity;}
|
||||
G4double GetMeanMultiplicity() const { return pMeanMultiplicity; }
|
||||
|
||||
G4double GetMeanTemperature(void) const {return __MeanTemperature;}
|
||||
G4double GetMeanTemperature() const { return pMeanTemperature; }
|
||||
|
||||
G4VStatMFEnsemble(const G4VStatMFEnsemble & right) = delete;
|
||||
G4VStatMFEnsemble & operator=(const G4VStatMFEnsemble & right) = delete;
|
||||
G4bool operator==(const G4VStatMFEnsemble & right) const = delete;
|
||||
G4bool operator!=(const G4VStatMFEnsemble & right) const = delete;
|
||||
|
||||
protected:
|
||||
|
||||
// Free internal energy at temperature T = 0
|
||||
G4double __FreeInternalE0;
|
||||
// Free internal energy at temperature T = 0
|
||||
G4double pFreeInternalE0{0.0};
|
||||
|
||||
// Mean temperature
|
||||
G4double pMeanTemperature{0.0};
|
||||
|
||||
// Mean temperature
|
||||
G4double __MeanTemperature;
|
||||
// Mean Entropy
|
||||
G4double pMeanEntropy{0.0};
|
||||
|
||||
// Mean Entropy
|
||||
G4double __MeanEntropy;
|
||||
|
||||
// Mean Multiplicity
|
||||
G4double __MeanMultiplicity;
|
||||
// Mean Multiplicity
|
||||
G4double pMeanMultiplicity{0.0};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
# Define the Geant4 Module.
|
||||
geant4_add_module(G4hadronic_deex_multifragmentation
|
||||
PUBLIC_HEADERS
|
||||
G4Solver.hh
|
||||
G4Solver.icc
|
||||
G4StatMF.hh
|
||||
G4StatMFChannel.hh
|
||||
G4StatMFFragment.hh
|
||||
@@ -25,7 +23,6 @@ geant4_add_module(G4hadronic_deex_multifragmentation
|
||||
G4VStatMFEnsemble.hh
|
||||
G4VStatMFMacroCluster.hh
|
||||
SOURCES
|
||||
G4Solver.cc
|
||||
G4StatMF.cc
|
||||
G4StatMFChannel.cc
|
||||
G4StatMFFragment.cc
|
||||
@@ -43,12 +40,12 @@ geant4_add_module(G4hadronic_deex_multifragmentation
|
||||
G4StatMFMicroPartition.cc
|
||||
G4StatMFParameters.cc
|
||||
G4VMultiFragmentation.cc
|
||||
G4VStatMFEnsemble.cc
|
||||
G4VStatMFMacroCluster.cc)
|
||||
|
||||
geant4_module_link_libraries(G4hadronic_deex_multifragmentation
|
||||
PUBLIC
|
||||
G4globman
|
||||
G4hadronic_util
|
||||
G4hepnumerics
|
||||
G4heprandom
|
||||
G4partman)
|
||||
|
||||
+106
-112
@@ -23,168 +23,165 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// Multi-fragmentation
|
||||
// by V. Lara
|
||||
//
|
||||
|
||||
#include "G4StatMF.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4Pow.hh"
|
||||
#include "G4PhysicsModelCatalog.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4RandomDirection.hh"
|
||||
|
||||
G4StatMF::G4StatMF()
|
||||
{
|
||||
_secID = G4PhysicsModelCatalog::GetModelID("model_G4StatMF");
|
||||
theMicrocanonicalEnsemble = new G4StatMFMicroCanonical();
|
||||
theMacrocanonicalEnsemble = new G4StatMFMacroCanonical();
|
||||
//fSecID = G4PhysicsModelCatalog::GetModelID("model_G4StatMF");
|
||||
}
|
||||
|
||||
G4StatMF::~G4StatMF() {}
|
||||
|
||||
G4FragmentVector* G4StatMF::BreakItUp(const G4Fragment &theFragment)
|
||||
G4StatMF::~G4StatMF()
|
||||
{
|
||||
if (theFragment.GetExcitationEnergy() <= 0.0) {
|
||||
return nullptr;
|
||||
}
|
||||
delete theMicrocanonicalEnsemble;
|
||||
delete theMacrocanonicalEnsemble;
|
||||
}
|
||||
|
||||
G4FragmentVector* G4StatMF::BreakItUp(const G4Fragment& theFragment)
|
||||
{
|
||||
// Maximun average multiplicity: M_0 = 2.6 for A ~ 200
|
||||
// and M_0 = 3.3 for A <= 110
|
||||
G4double MaxAverageMultiplicity =
|
||||
G4StatMFParameters::GetMaxAverageMultiplicity(theFragment.GetA_asInt());
|
||||
|
||||
|
||||
// We'll use two kinds of ensembles
|
||||
G4StatMFMicroCanonical * theMicrocanonicalEnsemble = 0;
|
||||
G4StatMFMacroCanonical * theMacrocanonicalEnsemble = 0;
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Direct simulation part (Microcanonical ensemble)
|
||||
//-------------------------------------------------------
|
||||
G4int A = theFragment.GetA_asInt();
|
||||
G4double MaxAverageMultiplicity = G4StatMFParameters::GetMaxAverageMultiplicity(A);
|
||||
|
||||
// Microcanonical ensemble initialization
|
||||
theMicrocanonicalEnsemble = new G4StatMFMicroCanonical(theFragment);
|
||||
|
||||
G4int Iterations = 0;
|
||||
G4int IterationsLimit = 100000;
|
||||
// Microcanonical ensemble - direct simulation
|
||||
theMicrocanonicalEnsemble->Initialise(theFragment);
|
||||
|
||||
const G4int iLimit = 20;
|
||||
G4double Temperature = 0.0;
|
||||
|
||||
G4bool FirstTime = true;
|
||||
G4StatMFChannel * theChannel = 0;
|
||||
G4StatMFChannel* theChannel = nullptr;
|
||||
|
||||
G4bool ChannelOk;
|
||||
do { // Try to de-excite as much as IterationLimit permits
|
||||
do {
|
||||
for (G4int i=0; i<iLimit; ++i) {
|
||||
for (G4int j=0; j<iLimit; ++j) {
|
||||
|
||||
G4double theMeanMult = theMicrocanonicalEnsemble->GetMeanMultiplicity();
|
||||
if (theMeanMult <= MaxAverageMultiplicity) {
|
||||
// G4cout << "MICROCANONICAL" << G4endl;
|
||||
//G4cout << "MICROCANONICAL Nmean=" << theMeanMult
|
||||
// << " i=" << i << " j=" << j << G4endl;
|
||||
// Choose fragments atomic numbers and charges from direct simulation
|
||||
theChannel = theMicrocanonicalEnsemble->ChooseAandZ(theFragment);
|
||||
_theEnsemble = theMicrocanonicalEnsemble;
|
||||
fEnsemble = theMicrocanonicalEnsemble;
|
||||
} else {
|
||||
//-----------------------------------------------------
|
||||
// Non direct simulation part (Macrocanonical Ensemble)
|
||||
//-----------------------------------------------------
|
||||
if (FirstTime) {
|
||||
// Macrocanonical ensemble initialization
|
||||
theMacrocanonicalEnsemble = new G4StatMFMacroCanonical(theFragment);
|
||||
_theEnsemble = theMacrocanonicalEnsemble;
|
||||
FirstTime = false;
|
||||
}
|
||||
// G4cout << "MACROCANONICAL" << G4endl;
|
||||
// Macrocanonical ensemble initialization
|
||||
theMacrocanonicalEnsemble->Initialise(theFragment);
|
||||
fEnsemble = theMacrocanonicalEnsemble;
|
||||
//G4cout << "MACROCANONICAL Nmean=" << theMeanMult
|
||||
// << " i=" << i << " j=" << j << G4endl;
|
||||
// Select calculated fragment total multiplicity,
|
||||
// fragment atomic numbers and fragment charges.
|
||||
theChannel = theMacrocanonicalEnsemble->ChooseAandZ(theFragment);
|
||||
}
|
||||
|
||||
ChannelOk = theChannel->CheckFragments();
|
||||
if (!ChannelOk) delete theChannel;
|
||||
|
||||
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
|
||||
} while (!ChannelOk);
|
||||
|
||||
|
||||
if (theChannel->GetMultiplicity() <= 1) {
|
||||
G4FragmentVector * theResult = new G4FragmentVector;
|
||||
theResult->push_back(new G4Fragment(theFragment));
|
||||
delete theMicrocanonicalEnsemble;
|
||||
if (theMacrocanonicalEnsemble != 0) delete theMacrocanonicalEnsemble;
|
||||
delete theChannel;
|
||||
return theResult;
|
||||
if (theChannel->CheckFragments()) { break; }
|
||||
delete theChannel;
|
||||
theChannel = nullptr;
|
||||
}
|
||||
|
||||
|
||||
if (nullptr == theChannel || theChannel->GetMultiplicity() <= 1) {
|
||||
delete theChannel;
|
||||
theChannel = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
// G4cout << " multiplicity=" << theChannel->GetMultiplicity() << G4endl;
|
||||
//--------------------------------------
|
||||
// Second part of simulation procedure.
|
||||
//--------------------------------------
|
||||
|
||||
// Find temperature of breaking channel.
|
||||
Temperature = _theEnsemble->GetMeanTemperature(); // Initial guess for Temperature
|
||||
Temperature = fEnsemble->GetMeanTemperature(); // Initial guess for Temperature
|
||||
|
||||
if (FindTemperatureOfBreakingChannel(theFragment,theChannel,Temperature)) break;
|
||||
if (FindTemperatureOfBreakingChannel(theFragment, theChannel, Temperature)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Do not forget to delete this unusable channel, for which we failed to find the temperature,
|
||||
// otherwise for very proton-reach nuclei it would lead to memory leak due to large
|
||||
// number of iterations. N.B. "theChannel" is created in G4StatMFMacroCanonical::ChooseZ()
|
||||
|
||||
// G4cout << " Iteration # " << Iterations << " Mean Temperature = " << Temperature << G4endl;
|
||||
// G4cout << " Iteration # " << Iterations << " Mean Temperature = " << Temperature << G4endl;
|
||||
delete theChannel;
|
||||
theChannel = nullptr;
|
||||
}
|
||||
|
||||
delete theChannel;
|
||||
|
||||
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
|
||||
} while (Iterations++ < IterationsLimit );
|
||||
|
||||
// If Iterations >= IterationsLimit means that we couldn't solve for temperature
|
||||
if (Iterations >= IterationsLimit)
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMF::BreakItUp: Was not possible to solve for temperature of breaking channel");
|
||||
|
||||
G4FragmentVector * theResult = theChannel->
|
||||
GetFragments(theFragment.GetA_asInt(),theFragment.GetZ_asInt(),Temperature);
|
||||
|
||||
// ~~~~~~ Energy conservation Patch !!!!!!!!!!!!!!!!!!!!!!
|
||||
// Original nucleus 4-momentum in CM system
|
||||
G4LorentzVector InitialMomentum(theFragment.GetMomentum());
|
||||
InitialMomentum.boost(-InitialMomentum.boostVector());
|
||||
G4double ScaleFactor = 0.0;
|
||||
G4double SavedScaleFactor = 0.0;
|
||||
do {
|
||||
G4double FragmentsEnergy = 0.0;
|
||||
for (auto const & ptr : *theResult) {
|
||||
FragmentsEnergy += ptr->GetMomentum().e();
|
||||
}
|
||||
if (0.0 == FragmentsEnergy) { break; }
|
||||
SavedScaleFactor = ScaleFactor;
|
||||
ScaleFactor = InitialMomentum.e()/FragmentsEnergy;
|
||||
G4ThreeVector ScaledMomentum(0.0,0.0,0.0);
|
||||
for (auto const & ptr : *theResult) {
|
||||
ScaledMomentum = ScaleFactor * ptr->GetMomentum().vect();
|
||||
G4double Mass = ptr->GetMomentum().mag();
|
||||
G4LorentzVector NewMomentum;
|
||||
NewMomentum.setVect(ScaledMomentum);
|
||||
NewMomentum.setE(std::sqrt(ScaledMomentum.mag2()+Mass*Mass));
|
||||
ptr->SetMomentum(NewMomentum);
|
||||
}
|
||||
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
|
||||
} while (ScaleFactor > 1.0+1.e-5 && std::abs(ScaleFactor-SavedScaleFactor)/ScaleFactor > 1.e-10);
|
||||
// ~~~~~~ End of patch !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// primary
|
||||
G4FragmentVector* theResult = nullptr;
|
||||
|
||||
// Perform Lorentz boost
|
||||
G4FragmentVector::iterator i;
|
||||
for (i = theResult->begin(); i != theResult->end(); i++) {
|
||||
G4LorentzVector FourMom = (*i)->GetMomentum();
|
||||
FourMom.boost(theFragment.GetMomentum().boostVector());
|
||||
(*i)->SetMomentum(FourMom);
|
||||
(*i)->SetCreatorModelID(_secID);
|
||||
// no multi-fragmentation
|
||||
if (nullptr == theChannel || theChannel->GetMultiplicity() <= 1) {
|
||||
theResult = new G4FragmentVector();
|
||||
theResult->push_back(new G4Fragment(theFragment));
|
||||
delete theChannel;
|
||||
return theResult;
|
||||
}
|
||||
|
||||
// garbage collection
|
||||
delete theMicrocanonicalEnsemble;
|
||||
if (theMacrocanonicalEnsemble != 0) delete theMacrocanonicalEnsemble;
|
||||
G4int Z = theFragment.GetZ_asInt();
|
||||
G4double m0 = theFragment.GetGroundStateMass() + theFragment.GetExcitationEnergy();
|
||||
auto bs = theFragment.GetMomentum().boostVector();
|
||||
|
||||
G4double etot = 0.0;
|
||||
G4double ekin = 0.0;
|
||||
for (G4int i=0; i<iLimit; ++i) {
|
||||
theResult = theChannel->GetFragments(A, Z, Temperature);
|
||||
if (nullptr == theResult) { continue; }
|
||||
etot = 0.0;
|
||||
ekin = 0.0;
|
||||
for (auto const & ptr : *theResult) {
|
||||
G4double e = ptr->GetMomentum().e();
|
||||
G4double m1 = ptr->GetGroundStateMass() + ptr->GetExcitationEnergy();
|
||||
etot += e;
|
||||
ekin += std::max(e - m1, 0.0);
|
||||
}
|
||||
// correction possible
|
||||
if (etot - m0 + ekin > 0.0 && ekin > 0.0) { break; }
|
||||
|
||||
// new attemt required
|
||||
for (auto const & ptr : *theResult) {
|
||||
delete ptr;
|
||||
}
|
||||
delete theResult;
|
||||
theResult = nullptr;
|
||||
}
|
||||
delete theChannel;
|
||||
|
||||
// no multi-fragmentation
|
||||
if (nullptr == theResult || ekin <= 0.0) {
|
||||
theResult = new G4FragmentVector();
|
||||
theResult->push_back(new G4Fragment(theFragment));
|
||||
return theResult;
|
||||
}
|
||||
|
||||
G4double x = 1.0 + (etot - m0)/ekin;
|
||||
G4LorentzVector lv1;
|
||||
|
||||
// scale and boost
|
||||
for (auto const & ptr : *theResult) {
|
||||
G4double m1 = ptr->GetGroundStateMass() + ptr->GetExcitationEnergy();
|
||||
G4double ek = std::max((ptr->GetMomentum().e() - m1)*x, 0.0);
|
||||
auto mom = ptr->GetMomentum().vect().unit();
|
||||
mom *= std::sqrt(ek * (ek + 2.0*m1));
|
||||
lv1.set(mom.x(), mom.y(), mom.z(), ek + m1);
|
||||
lv1.boost(bs);
|
||||
ptr->SetMomentum(lv1);
|
||||
}
|
||||
return theResult;
|
||||
}
|
||||
|
||||
|
||||
G4bool G4StatMF::FindTemperatureOfBreakingChannel(const G4Fragment & theFragment,
|
||||
const G4StatMFChannel * aChannel,
|
||||
G4double & Temperature)
|
||||
@@ -194,7 +191,7 @@ G4bool G4StatMF::FindTemperatureOfBreakingChannel(const G4Fragment & theFragment
|
||||
G4int Z = theFragment.GetZ_asInt();
|
||||
G4double U = theFragment.GetExcitationEnergy();
|
||||
|
||||
G4double T = std::max(Temperature,0.0012*MeV);
|
||||
G4double T = std::max(Temperature, 0.0012*CLHEP::MeV);
|
||||
G4double Ta = T;
|
||||
G4double TotalEnergy = CalcEnergy(A,Z,aChannel,T);
|
||||
|
||||
@@ -259,13 +256,10 @@ G4bool G4StatMF::FindTemperatureOfBreakingChannel(const G4Fragment & theFragment
|
||||
return false;
|
||||
}
|
||||
|
||||
G4double G4StatMF::CalcEnergy(G4int A, G4int Z, const G4StatMFChannel * aChannel,
|
||||
G4double G4StatMF::CalcEnergy(G4int A, G4int Z, const G4StatMFChannel* aChannel,
|
||||
G4double T)
|
||||
{
|
||||
G4double MassExcess0 = G4NucleiProperties::GetMassExcess(A,Z);
|
||||
G4double ChannelEnergy = aChannel->GetFragmentsEnergy(T);
|
||||
return -MassExcess0 + G4StatMFParameters::GetCoulomb() + ChannelEnergy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -420,8 +420,8 @@ void G4StatMFChannel::SolveEqOfMotion(G4int anA, G4int anZ, G4double T)
|
||||
return;
|
||||
}
|
||||
|
||||
G4ThreeVector G4StatMFChannel::RotateMomentum(G4ThreeVector Pa,
|
||||
G4ThreeVector V, G4ThreeVector P)
|
||||
G4ThreeVector G4StatMFChannel::RotateMomentum(G4ThreeVector& Pa,
|
||||
G4ThreeVector& V, G4ThreeVector& P)
|
||||
// Rotates a 3-vector P to close momentum triangle Pa + V + P = 0
|
||||
{
|
||||
G4ThreeVector U = Pa.unit();
|
||||
|
||||
+92
-117
@@ -23,8 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// by V. Lara
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
@@ -33,6 +31,8 @@
|
||||
// Mishustin (FIAS, Frankfurt, INR, Moscow and Kurchatov Institute,
|
||||
// Moscow, pshenich@fias.uni-frankfurt.de) fixed infinite loop for
|
||||
// a fagment with Z=A; fixed memory leak
|
||||
// 13.08.25 V.Ivanchenko rewrite
|
||||
|
||||
|
||||
#include "G4StatMFMacroCanonical.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
@@ -40,86 +40,74 @@
|
||||
#include "G4Pow.hh"
|
||||
|
||||
// constructor
|
||||
G4StatMFMacroCanonical::G4StatMFMacroCanonical(const G4Fragment & theFragment)
|
||||
G4StatMFMacroCanonical::G4StatMFMacroCanonical()
|
||||
{
|
||||
theTemp = new G4StatMFMacroTemperature();
|
||||
fClusters.reserve(220);
|
||||
fAcumMultiplicity.reserve(220);
|
||||
|
||||
// Get memory for clusters
|
||||
_theClusters.push_back(new G4StatMFMacroNucleon); // Size 1
|
||||
_theClusters.push_back(new G4StatMFMacroBiNucleon); // Size 2
|
||||
_theClusters.push_back(new G4StatMFMacroTriNucleon); // Size 3
|
||||
_theClusters.push_back(new G4StatMFMacroTetraNucleon); // Size 4
|
||||
for (G4int i = 4; i < theFragment.GetA_asInt(); i++)
|
||||
_theClusters.push_back(new G4StatMFMacroMultiNucleon(i+1)); // Size 5 ... A
|
||||
|
||||
// Perform class initialization
|
||||
Initialize(theFragment);
|
||||
|
||||
fClusters.push_back(new G4StatMFMacroNucleon);
|
||||
fClusters.push_back(new G4StatMFMacroBiNucleon);
|
||||
fClusters.push_back(new G4StatMFMacroTriNucleon);
|
||||
fClusters.push_back(new G4StatMFMacroTetraNucleon);
|
||||
}
|
||||
|
||||
// destructor
|
||||
G4StatMFMacroCanonical::~G4StatMFMacroCanonical()
|
||||
{
|
||||
// garbage collection
|
||||
if (!_theClusters.empty())
|
||||
{
|
||||
std::for_each(_theClusters.begin(),_theClusters.end(),DeleteFragment());
|
||||
}
|
||||
if (!fClusters.empty()) {
|
||||
for(auto const & p : fClusters) { delete p; }
|
||||
}
|
||||
delete theTemp;
|
||||
}
|
||||
|
||||
// Initialization method
|
||||
void G4StatMFMacroCanonical::Initialize(const G4Fragment & theFragment)
|
||||
void G4StatMFMacroCanonical::Initialise(const G4Fragment& theFragment)
|
||||
{
|
||||
|
||||
const G4double R0 = G4StatMFParameters::Getr0();
|
||||
const G4double E0 = G4StatMFParameters::GetE0();
|
||||
const G4double Beta0 = G4StatMFParameters::GetBeta0();
|
||||
const G4double Gamma0 = G4StatMFParameters::GetGamma0();
|
||||
|
||||
G4int A = theFragment.GetA_asInt();
|
||||
G4int Z = theFragment.GetZ_asInt();
|
||||
G4double x = 1.0 - 2.0*Z/G4double(A);
|
||||
G4double x = 1.0 - (2*Z)/G4double(A);
|
||||
G4Pow* g4calc = G4Pow::GetInstance();
|
||||
G4double a13 = g4calc->Z13(A);
|
||||
|
||||
// Free Internal energy at T = 0
|
||||
__FreeInternalE0 = A*( -G4StatMFParameters::GetE0() + // Volume term (for T = 0)
|
||||
G4StatMFParameters::GetGamma0()*x*x) // Symmetry term
|
||||
+ G4StatMFParameters::GetBeta0()*g4calc->Z23(A) + // Surface term (for T = 0)
|
||||
0.6*elm_coupling*Z*Z/(G4StatMFParameters::Getr0()* // Coulomb term
|
||||
g4calc->Z13(A));
|
||||
|
||||
CalculateTemperature(theFragment);
|
||||
return;
|
||||
}
|
||||
pFreeInternalE0 = A*(Gamma0*x*x - E0) // Symmetry term & Volume term (for T = 0)
|
||||
+ Beta0*a13*a13 + // Surface term (for T = 0)
|
||||
0.6*CLHEP::elm_coupling*(Z*Z)/(R0*a13); // Coulomb term
|
||||
|
||||
void G4StatMFMacroCanonical::CalculateTemperature(const G4Fragment & theFragment)
|
||||
{
|
||||
G4int n = (G4int)fClusters.size();
|
||||
for (G4int i = n; i < A; ++i) {
|
||||
fClusters.push_back(new G4StatMFMacroMultiNucleon(i+1)); // Size 5 ... A
|
||||
}
|
||||
// Excitation Energy
|
||||
G4double U = theFragment.GetExcitationEnergy();
|
||||
|
||||
G4int A = theFragment.GetA_asInt();
|
||||
G4int Z = theFragment.GetZ_asInt();
|
||||
|
||||
// Fragment Multiplicity
|
||||
G4double FragMult = std::max((1.0+(2.31/MeV)*(U/A - 3.5*MeV))*A/100.0, 2.0);
|
||||
G4double FragMult = std::max((1.0+2.31*(U/CLHEP::MeV - 3.5*A))/100.0, 2.0);
|
||||
|
||||
// Parameter Kappa
|
||||
G4Pow* g4calc = G4Pow::GetInstance();
|
||||
_Kappa = (1.0+elm_coupling*(g4calc->A13(FragMult)-1)/
|
||||
(G4StatMFParameters::Getr0()*g4calc->Z13(A)));
|
||||
_Kappa = _Kappa*_Kappa*_Kappa - 1.0;
|
||||
fKappa = (1.0 + CLHEP::elm_coupling*(g4calc->A13(FragMult) - 1.0)/(R0*a13));
|
||||
fKappa = fKappa*fKappa*fKappa - 1.0;
|
||||
|
||||
G4StatMFMacroTemperature * theTemp = new
|
||||
G4StatMFMacroTemperature(A,Z,U,__FreeInternalE0,_Kappa,&_theClusters);
|
||||
theTemp->Initialise(A, Z, U, pFreeInternalE0, fKappa, &fClusters);
|
||||
|
||||
__MeanTemperature = theTemp->CalcTemperature();
|
||||
_ChemPotentialNu = theTemp->GetChemicalPotentialNu();
|
||||
_ChemPotentialMu = theTemp->GetChemicalPotentialMu();
|
||||
__MeanMultiplicity = theTemp->GetMeanMultiplicity();
|
||||
__MeanEntropy = theTemp->GetEntropy();
|
||||
|
||||
delete theTemp;
|
||||
|
||||
return;
|
||||
pMeanTemperature = theTemp->CalcTemperature();
|
||||
fChemPotentialNu = theTemp->GetChemicalPotentialNu();
|
||||
fChemPotentialMu = theTemp->GetChemicalPotentialMu();
|
||||
pMeanMultiplicity = theTemp->GetMeanMultiplicity();
|
||||
pMeanEntropy = theTemp->GetEntropy();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
G4StatMFChannel * G4StatMFMacroCanonical::ChooseAandZ(const G4Fragment &theFragment)
|
||||
G4StatMFChannel* G4StatMFMacroCanonical::ChooseAandZ(const G4Fragment& theFragment)
|
||||
// Calculate total fragments multiplicity, fragment atomic numbers and charges
|
||||
{
|
||||
G4int A = theFragment.GetA_asInt();
|
||||
@@ -127,7 +115,7 @@ G4StatMFChannel * G4StatMFMacroCanonical::ChooseAandZ(const G4Fragment &theFragm
|
||||
|
||||
std::vector<G4int> ANumbers(A);
|
||||
|
||||
G4double Multiplicity = ChooseA(A,ANumbers);
|
||||
G4double Multiplicity = ChooseA(A, ANumbers);
|
||||
|
||||
std::vector<G4int> FragmentsA;
|
||||
|
||||
@@ -143,7 +131,7 @@ G4StatMFChannel * G4StatMFMacroCanonical::ChooseAandZ(const G4Fragment &theFragm
|
||||
{
|
||||
G4int FragmentsAMax = 0;
|
||||
im = j;
|
||||
for (i = j; i < Multiplicity; i++)
|
||||
for (i = j; i < Multiplicity; ++i)
|
||||
{
|
||||
if (FragmentsA[i] <= FragmentsAMax) { continue; }
|
||||
else
|
||||
@@ -161,21 +149,17 @@ G4StatMFChannel * G4StatMFMacroCanonical::ChooseAandZ(const G4Fragment &theFragm
|
||||
return ChooseZ(Z,FragmentsA);
|
||||
}
|
||||
|
||||
G4double G4StatMFMacroCanonical::ChooseA(G4int A, std::vector<G4int> & ANumbers)
|
||||
G4double G4StatMFMacroCanonical::ChooseA(G4int A, std::vector<G4int>& ANumbers)
|
||||
// Determines fragments multiplicities and compute total fragment multiplicity
|
||||
{
|
||||
G4double multiplicity = 0.0;
|
||||
G4int i;
|
||||
|
||||
std::vector<G4double> AcumMultiplicity;
|
||||
AcumMultiplicity.reserve(A);
|
||||
|
||||
AcumMultiplicity.push_back((*(_theClusters.begin()))->GetMeanMultiplicity());
|
||||
for (std::vector<G4VStatMFMacroCluster*>::iterator it = _theClusters.begin()+1;
|
||||
it != _theClusters.end(); ++it)
|
||||
{
|
||||
AcumMultiplicity.push_back((*it)->GetMeanMultiplicity()+AcumMultiplicity.back());
|
||||
}
|
||||
fAcumMultiplicity.resize(A);
|
||||
for (G4int i=0; i<A; ++i) {
|
||||
G4double x = fClusters[i]->GetMeanMultiplicity();
|
||||
multiplicity += x;
|
||||
fAcumMultiplicity[i] = multiplicity;
|
||||
}
|
||||
|
||||
G4int CheckA;
|
||||
do {
|
||||
@@ -183,11 +167,11 @@ G4double G4StatMFMacroCanonical::ChooseA(G4int A, std::vector<G4int> & ANumbers)
|
||||
G4int SumA = 0;
|
||||
G4int ThisOne = 0;
|
||||
multiplicity = 0.0;
|
||||
for (i = 0; i < A; i++) ANumbers[i] = 0;
|
||||
ANumbers.resize(A, 0);
|
||||
do {
|
||||
G4double RandNumber = G4UniformRand()*__MeanMultiplicity;
|
||||
for (i = 0; i < A; i++) {
|
||||
if (RandNumber < AcumMultiplicity[i]) {
|
||||
G4double RandNumber = G4UniformRand()*pMeanMultiplicity;
|
||||
for (G4int i = 0; i < A; ++i) {
|
||||
if (RandNumber < fAcumMultiplicity[i]) {
|
||||
ThisOne = i;
|
||||
break;
|
||||
}
|
||||
@@ -201,14 +185,12 @@ G4double G4StatMFMacroCanonical::ChooseA(G4int A, std::vector<G4int> & ANumbers)
|
||||
} while (CheckA > 0);
|
||||
|
||||
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
|
||||
} while (CheckA < 0 || std::abs(__MeanMultiplicity - multiplicity) > std::sqrt(__MeanMultiplicity) + 0.5);
|
||||
} while (CheckA < 0 || std::abs(pMeanMultiplicity - multiplicity) > std::sqrt(pMeanMultiplicity) + 0.5);
|
||||
|
||||
return multiplicity;
|
||||
}
|
||||
|
||||
G4StatMFChannel * G4StatMFMacroCanonical::ChooseZ(G4int & Z,
|
||||
std::vector<G4int> & FragmentsA)
|
||||
//
|
||||
G4StatMFChannel* G4StatMFMacroCanonical::ChooseZ(G4int Z, std::vector<G4int>& FragmentsA)
|
||||
{
|
||||
G4Pow* g4calc = G4Pow::GetInstance();
|
||||
std::vector<G4int> FragmentsZ;
|
||||
@@ -220,59 +202,52 @@ G4StatMFChannel * G4StatMFMacroCanonical::ChooseZ(G4int & Z,
|
||||
do {
|
||||
FragmentsZ.clear();
|
||||
G4int SumZ = 0;
|
||||
for (G4int i = 0; i < multiplicity; ++i)
|
||||
{
|
||||
G4int A = FragmentsA[i];
|
||||
if (A <= 1)
|
||||
{
|
||||
G4double RandNumber = G4UniformRand();
|
||||
if (RandNumber < (*_theClusters.begin())->GetZARatio())
|
||||
{
|
||||
FragmentsZ.push_back(1);
|
||||
SumZ += FragmentsZ[i];
|
||||
}
|
||||
else FragmentsZ.push_back(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double RandZ;
|
||||
G4double CC = 8.0*G4StatMFParameters::GetGamma0()
|
||||
+ 2*CP*g4calc->Z23(FragmentsA[i]);
|
||||
G4double ZMean;
|
||||
if (FragmentsA[i] > 1 && FragmentsA[i] < 5) { ZMean = 0.5*FragmentsA[i]; }
|
||||
else {
|
||||
ZMean = FragmentsA[i]*(4.0*G4StatMFParameters::GetGamma0()
|
||||
+ _ChemPotentialNu)/CC;
|
||||
}
|
||||
G4double ZDispersion = std::sqrt(FragmentsA[i]*__MeanTemperature/CC);
|
||||
G4int z;
|
||||
do
|
||||
{
|
||||
RandZ = G4RandGauss::shoot(ZMean,ZDispersion);
|
||||
z = G4lrint(RandZ+0.5);
|
||||
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
|
||||
} while (z < 0 || z > A);
|
||||
FragmentsZ.push_back(z);
|
||||
SumZ += z;
|
||||
}
|
||||
for (G4int i = 0; i < multiplicity; ++i) {
|
||||
G4int A = FragmentsA[i];
|
||||
if (A <= 1) {
|
||||
G4double RandNumber = G4UniformRand();
|
||||
if (RandNumber < fClusters[0]->GetZARatio()) {
|
||||
FragmentsZ.push_back(1);
|
||||
SumZ += FragmentsZ[i];
|
||||
}
|
||||
else FragmentsZ.push_back(0);
|
||||
}
|
||||
else {
|
||||
G4double RandZ;
|
||||
G4double CC = 8.0*G4StatMFParameters::GetGamma0()
|
||||
+ 2*CP*g4calc->Z23(FragmentsA[i]);
|
||||
G4double ZMean;
|
||||
if (FragmentsA[i] > 1 && FragmentsA[i] < 5) { ZMean = 0.5*FragmentsA[i]; }
|
||||
else {
|
||||
ZMean = FragmentsA[i]*(4.0*G4StatMFParameters::GetGamma0()
|
||||
+ fChemPotentialNu)/CC;
|
||||
}
|
||||
G4double ZDispersion = std::sqrt(FragmentsA[i]*pMeanTemperature/CC);
|
||||
G4int z;
|
||||
do {
|
||||
RandZ = G4RandGauss::shoot(ZMean,ZDispersion);
|
||||
z = G4lrint(RandZ);
|
||||
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
|
||||
} while (z < 0 || z > A);
|
||||
FragmentsZ.push_back(z);
|
||||
SumZ += z;
|
||||
}
|
||||
}
|
||||
DeltaZ = Z - SumZ;
|
||||
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
|
||||
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
|
||||
} while (std::abs(DeltaZ) > 1);
|
||||
|
||||
// DeltaZ can be 0, 1 or -1
|
||||
G4int idx = 0;
|
||||
if (DeltaZ < 0.0)
|
||||
{
|
||||
while (FragmentsZ[idx] < 1) { ++idx; }
|
||||
}
|
||||
if (DeltaZ < 0.0) {
|
||||
while (FragmentsZ[idx] < 1) { ++idx; }
|
||||
}
|
||||
FragmentsZ[idx] += DeltaZ;
|
||||
|
||||
G4StatMFChannel * theChannel = new G4StatMFChannel;
|
||||
for (G4int i = multiplicity-1; i >= 0; --i)
|
||||
{
|
||||
theChannel->CreateFragment(FragmentsA[i],FragmentsZ[i]);
|
||||
}
|
||||
G4StatMFChannel* theChannel = new G4StatMFChannel();
|
||||
for (G4int i = multiplicity-1; i >= 0; --i) {
|
||||
theChannel->CreateFragment(FragmentsA[i], FragmentsZ[i]);
|
||||
}
|
||||
|
||||
return theChannel;
|
||||
}
|
||||
|
||||
+40
-79
@@ -23,107 +23,74 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
//
|
||||
// Modification: 13.08.2025 V.Ivanchenko rewrite
|
||||
|
||||
#include "G4StatMFMacroChemicalPotential.hh"
|
||||
#include "G4StatMFParameters.hh"
|
||||
#include "G4StatMFMacroMultiplicity.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4Pow.hh"
|
||||
|
||||
// operators definitions
|
||||
G4StatMFMacroChemicalPotential &
|
||||
G4StatMFMacroChemicalPotential::operator=(const G4StatMFMacroChemicalPotential & )
|
||||
G4StatMFMacroChemicalPotential::G4StatMFMacroChemicalPotential()
|
||||
{
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMacroChemicalPotential::operator= meant to not be accessible");
|
||||
return *this;
|
||||
}
|
||||
|
||||
G4bool G4StatMFMacroChemicalPotential::operator==(const G4StatMFMacroChemicalPotential & ) const
|
||||
{
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMacroChemicalPotential::operator== meant to not be accessible");
|
||||
return false;
|
||||
theMultip = new G4StatMFMacroMultiplicity();
|
||||
fSolver = new G4FunctionSolver<G4StatMFMacroChemicalPotential>(this, 100, 5.e-4);
|
||||
}
|
||||
|
||||
|
||||
G4bool G4StatMFMacroChemicalPotential::operator!=(const G4StatMFMacroChemicalPotential & ) const
|
||||
G4StatMFMacroChemicalPotential::~G4StatMFMacroChemicalPotential()
|
||||
{
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMacroChemicalPotential::operator!= meant to not be accessible");
|
||||
return true;
|
||||
delete fSolver;
|
||||
delete theMultip;
|
||||
}
|
||||
|
||||
G4double G4StatMFMacroChemicalPotential::CalcChemicalPotentialNu(void)
|
||||
void G4StatMFMacroChemicalPotential::Initialise(
|
||||
const G4int anA, const G4int aZ,
|
||||
const G4double kappa,
|
||||
const G4double temp,
|
||||
std::vector<G4VStatMFMacroCluster*>* v)
|
||||
{
|
||||
theA = anA;
|
||||
theZ = aZ;
|
||||
fKappa = kappa;
|
||||
fMeanTemperature = temp;
|
||||
fClusters = v;
|
||||
}
|
||||
|
||||
G4double G4StatMFMacroChemicalPotential::CalcChemicalPotentialNu()
|
||||
// Calculate Chemical potential \nu
|
||||
{
|
||||
G4Pow* g4calc = G4Pow::GetInstance();
|
||||
G4double CP = G4StatMFParameters::GetCoulomb();
|
||||
|
||||
// Initial value for _ChemPotentialNu
|
||||
_ChemPotentialNu = (theZ/theA)*(8.0*G4StatMFParameters::GetGamma0()
|
||||
+2.0*CP*g4calc->Z23(theA))
|
||||
// Initial value for fChemPotentialNu
|
||||
fChemPotentialNu = (theZ/(G4double)theA)*
|
||||
(8.0*G4StatMFParameters::GetGamma0() + 2.0*CP*g4calc->Z23(theA))
|
||||
- 4.0*G4StatMFParameters::GetGamma0();
|
||||
|
||||
G4double ChemPa = _ChemPotentialNu;
|
||||
G4double ChemPb = 0.5*_ChemPotentialNu;
|
||||
|
||||
G4double fChemPa = this->operator()(ChemPa);
|
||||
G4double fChemPb = this->operator()(ChemPb);
|
||||
|
||||
if (fChemPa*fChemPb > 0.0) {
|
||||
// bracketing the solution
|
||||
if (fChemPa < 0.0) {
|
||||
do {
|
||||
ChemPb -= 1.5*std::abs(ChemPb-ChemPa);
|
||||
fChemPb = this->operator()(ChemPb);
|
||||
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
|
||||
} while (fChemPb < 0.0);
|
||||
} else {
|
||||
do {
|
||||
ChemPb += 1.5*std::abs(ChemPb-ChemPa);
|
||||
fChemPb = this->operator()(ChemPb);
|
||||
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
|
||||
} while (fChemPb > 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
G4Solver<G4StatMFMacroChemicalPotential> * theSolver =
|
||||
new G4Solver<G4StatMFMacroChemicalPotential>(100,1.e-4);
|
||||
theSolver->SetIntervalLimits(ChemPa,ChemPb);
|
||||
// if (!theSolver->Crenshaw(*this))
|
||||
if (!theSolver->Brent(*this)){
|
||||
G4cout <<"G4StatMFMacroChemicalPotential:"<<" ChemPa="<<ChemPa
|
||||
<<" ChemPb="<<ChemPb<< G4endl;
|
||||
G4cout <<"G4StatMFMacroChemicalPotential:"<<" fChemPa="<<fChemPa
|
||||
<<" fChemPb="<<fChemPb<< G4endl;
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMacroChemicalPotential::CalcChemicalPotentialNu: I couldn't find the root.");
|
||||
}
|
||||
_ChemPotentialNu = theSolver->GetRoot();
|
||||
delete theSolver;
|
||||
return _ChemPotentialNu;
|
||||
fSolver->SetIntervalLimits(0.5*fChemPotentialNu, 2*fChemPotentialNu);
|
||||
fSolver->FindRoot(fChemPotentialNu);
|
||||
return fChemPotentialNu;
|
||||
}
|
||||
|
||||
|
||||
|
||||
G4double G4StatMFMacroChemicalPotential::CalcMeanZ(const G4double nu)
|
||||
{
|
||||
std::vector<G4VStatMFMacroCluster*>::iterator i;
|
||||
for (i= _theClusters->begin()+1; i != _theClusters->end(); ++i)
|
||||
{
|
||||
(*i)->CalcZARatio(nu);
|
||||
}
|
||||
CalcChemicalPotentialMu(nu);
|
||||
// This is important, the Z over A ratio for proton and neutron depends on the
|
||||
// chemical potential Mu, while for the first guess for Chemical potential mu
|
||||
// some values of Z over A ratio. This is the reason for that.
|
||||
(*_theClusters->begin())->CalcZARatio(nu);
|
||||
|
||||
G4double MeanZ = 0.0;
|
||||
G4int n = 1;
|
||||
for (i = _theClusters->begin(); i != _theClusters->end(); ++i)
|
||||
{
|
||||
MeanZ += (n++) * (*i)->GetZARatio() * (*i)->GetMeanMultiplicity();
|
||||
}
|
||||
G4int n = 0;
|
||||
G4int nn = (G4int)fClusters->size();
|
||||
nn = std::min(nn, theA);
|
||||
for (G4int i = 0; i < nn; ++i) {
|
||||
G4double x = (*fClusters)[i]->CalcZARatio(nu);
|
||||
MeanZ += (n++) * x * (*fClusters)[i]->GetMeanMultiplicity();
|
||||
}
|
||||
return MeanZ;
|
||||
}
|
||||
|
||||
@@ -131,13 +98,7 @@ void G4StatMFMacroChemicalPotential::CalcChemicalPotentialMu(const G4double nu)
|
||||
// Calculate Chemical potential \mu
|
||||
// For that is necesary to calculate mean multiplicities
|
||||
{
|
||||
G4StatMFMacroMultiplicity * theMultip = new
|
||||
G4StatMFMacroMultiplicity(theA,_Kappa,_MeanTemperature,nu,_theClusters);
|
||||
|
||||
_ChemPotentialMu = theMultip->CalcChemicalPotentialMu();
|
||||
_MeanMultiplicity = theMultip->GetMeanMultiplicity();
|
||||
|
||||
delete theMultip;
|
||||
|
||||
return;
|
||||
theMultip->Initialise(theA, fKappa, fMeanTemperature, nu, fClusters);
|
||||
fChemPotentialMu = theMultip->CalcChemicalPotentialMu();
|
||||
fMeanMultiplicity = theMultip->GetMeanMultiplicity();
|
||||
}
|
||||
|
||||
+42
-89
@@ -23,8 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
//
|
||||
@@ -33,34 +31,40 @@
|
||||
// Mishustin (FIAS, Frankfurt, INR, Moscow and Kurchatov Institute,
|
||||
// Moscow, pshenich@fias.uni-frankfurt.de) additional checks in
|
||||
// solver of equation for the chemical potential
|
||||
//
|
||||
// 13.08.2025 V.Ivanchenko rewrite
|
||||
|
||||
#include "G4StatMFMacroMultiplicity.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4StatMFParameters.hh"
|
||||
#include "G4Pow.hh"
|
||||
|
||||
// operators definitions
|
||||
G4StatMFMacroMultiplicity &
|
||||
G4StatMFMacroMultiplicity::operator=(const G4StatMFMacroMultiplicity & )
|
||||
G4StatMFMacroMultiplicity::G4StatMFMacroMultiplicity()
|
||||
{
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMacroMultiplicity::operator= meant to not be accessible");
|
||||
return *this;
|
||||
fSolver = new G4FunctionSolver<G4StatMFMacroMultiplicity>(this, 100, 5.e-4);
|
||||
}
|
||||
|
||||
G4bool G4StatMFMacroMultiplicity::operator==(const G4StatMFMacroMultiplicity & ) const
|
||||
G4StatMFMacroMultiplicity::~G4StatMFMacroMultiplicity()
|
||||
{
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMacroMultiplicity::operator== meant to not be accessible");
|
||||
return false;
|
||||
delete fSolver;
|
||||
}
|
||||
|
||||
|
||||
G4bool G4StatMFMacroMultiplicity::operator!=(const G4StatMFMacroMultiplicity & ) const
|
||||
void G4StatMFMacroMultiplicity::Initialise(const G4int anA,
|
||||
const G4double kappa,
|
||||
const G4double temp,
|
||||
const G4double nu,
|
||||
std::vector<G4VStatMFMacroCluster*>* v)
|
||||
{
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMacroMultiplicity::operator!= meant to not be accessible");
|
||||
return true;
|
||||
A = anA;
|
||||
theA = anA;
|
||||
fKappa = kappa;
|
||||
fMeanTemperature = temp;
|
||||
fChemPotentialNu = nu;
|
||||
fClusters = v;
|
||||
}
|
||||
|
||||
G4double G4StatMFMacroMultiplicity::CalcChemicalPotentialMu(void)
|
||||
// Calculate Chemical potential \mu
|
||||
G4double G4StatMFMacroMultiplicity::CalcChemicalPotentialMu()
|
||||
// Calculate Chemical potential \mu
|
||||
// For that is necesary to calculate mean multiplicities
|
||||
{
|
||||
G4Pow* g4calc = G4Pow::GetInstance();
|
||||
@@ -68,74 +72,22 @@ G4double G4StatMFMacroMultiplicity::CalcChemicalPotentialMu(void)
|
||||
|
||||
// starting value for chemical potential \mu
|
||||
// it is the derivative of F(T,V)-\nu*Z w.r.t. Af in Af=5
|
||||
G4double ZA5 = _theClusters->operator[](4)->GetZARatio();
|
||||
G4double ILD5 = _theClusters->operator[](4)->GetInvLevelDensity();
|
||||
_ChemPotentialMu = -G4StatMFParameters::GetE0()-
|
||||
_MeanTemperature*_MeanTemperature/ILD5 -
|
||||
_ChemPotentialNu*ZA5 +
|
||||
G4double ZA5 = (*fClusters)[4]->GetZARatio();
|
||||
G4double ILD5 = (*fClusters)[4]->GetInvLevelDensity();
|
||||
fChemPotentialMu = -G4StatMFParameters::GetE0()-
|
||||
fMeanTemperature*fMeanTemperature/ILD5 -
|
||||
fChemPotentialNu*ZA5 +
|
||||
G4StatMFParameters::GetGamma0()*(1.0-2.0*ZA5)*(1.0-2.0*ZA5) +
|
||||
(2.0/3.0)*G4StatMFParameters::Beta(_MeanTemperature)/g4calc->Z13(5) +
|
||||
(2.0/3.0)*G4StatMFParameters::Beta(fMeanTemperature)/g4calc->Z13(5) +
|
||||
(5.0/3.0)*CP*ZA5*ZA5*g4calc->Z23(5) -
|
||||
1.5*_MeanTemperature/5.0;
|
||||
1.5*fMeanTemperature/5.0;
|
||||
|
||||
G4double ChemPa = _ChemPotentialMu;
|
||||
if (ChemPa/_MeanTemperature > 10.0) ChemPa = 10.0*_MeanTemperature;
|
||||
G4double ChemPa = fChemPotentialMu;
|
||||
if (ChemPa > 10*fMeanTemperature) { ChemPa = 10*fMeanTemperature; }
|
||||
G4double ChemPb = ChemPa - 0.5*std::abs(ChemPa);
|
||||
|
||||
G4double fChemPa = this->operator()(ChemPa);
|
||||
G4double fChemPb = this->operator()(ChemPb);
|
||||
|
||||
// Set the precision level for locating the root.
|
||||
// If the root is inside this interval, then it's done!
|
||||
const G4double intervalWidth = 1.e-4;
|
||||
|
||||
// bracketing the solution
|
||||
G4int iterations = 0;
|
||||
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
|
||||
while (fChemPa*fChemPb > 0.0 && iterations < 100)
|
||||
{
|
||||
iterations++;
|
||||
if (std::abs(fChemPa) <= std::abs(fChemPb))
|
||||
{
|
||||
ChemPa += 0.6*(ChemPa-ChemPb);
|
||||
fChemPa = this->operator()(ChemPa);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChemPb += 0.6*(ChemPb-ChemPa);
|
||||
fChemPb = this->operator()(ChemPb);
|
||||
}
|
||||
}
|
||||
|
||||
if (fChemPa*fChemPb > 0.0) // the bracketing failed, complain
|
||||
{
|
||||
G4cout <<"G4StatMFMacroMultiplicity:"<<" ChemPa="<<ChemPa
|
||||
<<" ChemPb="<<ChemPb<< G4endl;
|
||||
G4cout <<"G4StatMFMacroMultiplicity:"<<" fChemPa="<<fChemPa
|
||||
<<" fChemPb="<<fChemPb<< G4endl;
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMacroMultiplicity::CalcChemicalPotentialMu: I couldn't bracket the root.");
|
||||
}
|
||||
else if (fChemPa*fChemPb < 0.0 && std::abs(ChemPa-ChemPb) > intervalWidth)
|
||||
{
|
||||
G4Solver<G4StatMFMacroMultiplicity> * theSolver =
|
||||
new G4Solver<G4StatMFMacroMultiplicity>(100,intervalWidth);
|
||||
theSolver->SetIntervalLimits(ChemPa,ChemPb);
|
||||
// if (!theSolver->Crenshaw(*this))
|
||||
if (!theSolver->Brent(*this))
|
||||
{
|
||||
G4cout <<"G4StatMFMacroMultiplicity:"<<" ChemPa="<<ChemPa
|
||||
<<" ChemPb="<<ChemPb<< G4endl;
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMacroMultiplicity::CalcChemicalPotentialMu: I couldn't find the root.");
|
||||
}
|
||||
_ChemPotentialMu = theSolver->GetRoot();
|
||||
delete theSolver;
|
||||
}
|
||||
else // the root is within the interval, which is shorter then the precision level - all done
|
||||
{
|
||||
_ChemPotentialMu = ChemPa;
|
||||
}
|
||||
|
||||
return _ChemPotentialMu;
|
||||
fSolver->SetIntervalLimits(ChemPa, ChemPb);
|
||||
fSolver->FindRoot(fChemPotentialMu);
|
||||
return fChemPotentialMu;
|
||||
}
|
||||
|
||||
G4double G4StatMFMacroMultiplicity::CalcMeanA(const G4double mu)
|
||||
@@ -145,17 +97,18 @@ G4double G4StatMFMacroMultiplicity::CalcMeanA(const G4double mu)
|
||||
|
||||
G4double MeanA = 0.0;
|
||||
|
||||
_MeanMultiplicity = 0.0;
|
||||
fMeanMultiplicity = 0.0;
|
||||
|
||||
G4int n = 1;
|
||||
for (std::vector<G4VStatMFMacroCluster*>::iterator i = _theClusters->begin();
|
||||
i != _theClusters->end(); ++i)
|
||||
{
|
||||
G4double multip = (*i)->CalcMeanMultiplicity(V0*_Kappa,mu,_ChemPotentialNu,
|
||||
_MeanTemperature);
|
||||
MeanA += multip*(n++);
|
||||
_MeanMultiplicity += multip;
|
||||
}
|
||||
G4int nn = (G4int)fClusters->size();
|
||||
nn = std::min(nn, A);
|
||||
for (G4int i=0; i<nn; ++i) {
|
||||
G4double multip =
|
||||
(*fClusters)[i]->CalcMeanMultiplicity(V0*fKappa,mu,fChemPotentialNu,
|
||||
fMeanTemperature);
|
||||
MeanA += multip*(++n);
|
||||
fMeanMultiplicity += multip;
|
||||
}
|
||||
|
||||
return MeanA;
|
||||
}
|
||||
|
||||
+51
-126
@@ -23,8 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
//
|
||||
@@ -37,113 +35,52 @@
|
||||
// to protect code from rare unwanted exception; moved constructor
|
||||
// and destructor to source
|
||||
// 28.10.10 V.Ivanchenko defined members in constructor and cleaned up
|
||||
// 13.08.2025 V.Ivanchenko rewrite
|
||||
|
||||
#include "G4StatMFMacroTemperature.hh"
|
||||
#include "G4StatMFParameters.hh"
|
||||
#include "G4StatMFMacroChemicalPotential.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4Pow.hh"
|
||||
|
||||
G4StatMFMacroTemperature::G4StatMFMacroTemperature(const G4double anA, const G4double aZ,
|
||||
const G4double ExEnergy, const G4double FreeE0, const G4double kappa,
|
||||
std::vector<G4VStatMFMacroCluster*> * ClusterVector) :
|
||||
theA(anA),
|
||||
theZ(aZ),
|
||||
_ExEnergy(ExEnergy),
|
||||
_FreeInternalE0(FreeE0),
|
||||
_Kappa(kappa),
|
||||
_MeanMultiplicity(0.0),
|
||||
_MeanTemperature(0.0),
|
||||
_ChemPotentialMu(0.0),
|
||||
_ChemPotentialNu(0.0),
|
||||
_MeanEntropy(0.0),
|
||||
_theClusters(ClusterVector)
|
||||
{}
|
||||
|
||||
G4StatMFMacroTemperature::~G4StatMFMacroTemperature()
|
||||
{}
|
||||
namespace {
|
||||
const G4double t1 = 1*CLHEP::MeV;
|
||||
const G4double t2 = 50*CLHEP::MeV;
|
||||
}
|
||||
|
||||
G4StatMFMacroTemperature::G4StatMFMacroTemperature()
|
||||
{
|
||||
fSolver = new G4FunctionSolver<G4StatMFMacroTemperature>(this, 100, 5.e-4);
|
||||
fSolver->SetIntervalLimits(t1, t2);
|
||||
theChemPot = new G4StatMFMacroChemicalPotential();
|
||||
}
|
||||
|
||||
G4StatMFMacroTemperature::~G4StatMFMacroTemperature()
|
||||
{
|
||||
delete fSolver;
|
||||
delete theChemPot;
|
||||
}
|
||||
|
||||
void G4StatMFMacroTemperature::Initialise(const G4int anA, const G4int aZ,
|
||||
const G4double ExEnergy,
|
||||
const G4double FreeE0,
|
||||
const G4double kappa,
|
||||
std::vector<G4VStatMFMacroCluster*>* v)
|
||||
{
|
||||
theA = anA;
|
||||
theZ = aZ;
|
||||
fExEnergy = ExEnergy;
|
||||
fFreeInternalE0 = FreeE0;
|
||||
fKappa = kappa;
|
||||
fClusters = v;
|
||||
}
|
||||
|
||||
G4double G4StatMFMacroTemperature::CalcTemperature(void)
|
||||
{
|
||||
// Inital guess for the interval of the ensemble temperature values
|
||||
G4double Ta = 0.5;
|
||||
G4double Tb = std::max(std::sqrt(_ExEnergy/(theA*0.12)),0.01*MeV);
|
||||
|
||||
G4double fTa = this->operator()(Ta);
|
||||
G4double fTb = this->operator()(Tb);
|
||||
|
||||
// Bracketing the solution
|
||||
// T should be greater than 0.
|
||||
// The interval is [Ta,Tb]
|
||||
// We start with a value for Ta = 0.5 MeV
|
||||
// it should be enough to have fTa > 0 If it isn't
|
||||
// the case, we decrease Ta. But carefully, because
|
||||
// fTa growes very fast when Ta is near 0 and we could have
|
||||
// an overflow.
|
||||
|
||||
G4int iterations = 0;
|
||||
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
|
||||
while (fTa < 0.0 && ++iterations < 10) {
|
||||
Ta -= 0.5*Ta;
|
||||
fTa = this->operator()(Ta);
|
||||
}
|
||||
// Usually, fTb will be less than 0, but if it is not the case:
|
||||
iterations = 0;
|
||||
// Loop checking, 05-Aug-2015, Vladimir Ivanchenko
|
||||
while (fTa*fTb > 0.0 && iterations++ < 10) {
|
||||
Tb += 2.*std::fabs(Tb-Ta);
|
||||
fTb = this->operator()(Tb);
|
||||
}
|
||||
|
||||
if (fTa*fTb > 0.0) {
|
||||
G4cerr <<"G4StatMFMacroTemperature:"<<" Ta="<<Ta<<" Tb="<<Tb<< G4endl;
|
||||
G4cerr <<"G4StatMFMacroTemperature:"<<" fTa="<<fTa<<" fTb="<<fTb<< G4endl;
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMacroTemperature::CalcTemperature: I couldn't bracket the solution.");
|
||||
}
|
||||
|
||||
G4Solver<G4StatMFMacroTemperature> * theSolver =
|
||||
new G4Solver<G4StatMFMacroTemperature>(100,1.e-4);
|
||||
theSolver->SetIntervalLimits(Ta,Tb);
|
||||
if (!theSolver->Crenshaw(*this)){
|
||||
G4cout <<"G4StatMFMacroTemperature, Crenshaw method failed:"<<" Ta="
|
||||
<<Ta<<" Tb="<<Tb<< G4endl;
|
||||
G4cout <<"G4StatMFMacroTemperature, Crenshaw method failed:"<<" fTa="
|
||||
<<fTa<<" fTb="<<fTb<< G4endl;
|
||||
}
|
||||
_MeanTemperature = theSolver->GetRoot();
|
||||
G4double FunctionValureAtRoot = this->operator()(_MeanTemperature);
|
||||
delete theSolver;
|
||||
|
||||
// Verify if the root is found and it is indeed within the physical domain,
|
||||
// say, between 1 and 50 MeV, otherwise try Brent method:
|
||||
if (std::fabs(FunctionValureAtRoot) > 5.e-2) {
|
||||
if (_MeanTemperature < 1. || _MeanTemperature > 50.) {
|
||||
G4cout << "Crenshaw method failed; function = " << FunctionValureAtRoot
|
||||
<< " solution? = " << _MeanTemperature << " MeV " << G4endl;
|
||||
G4Solver<G4StatMFMacroTemperature> * theSolverBrent =
|
||||
new G4Solver<G4StatMFMacroTemperature>(200,1.e-3);
|
||||
theSolverBrent->SetIntervalLimits(Ta,Tb);
|
||||
if (!theSolverBrent->Brent(*this)){
|
||||
G4cout <<"G4StatMFMacroTemperature, Brent method failed:"
|
||||
<<" Ta="<<Ta<<" Tb="<<Tb<< G4endl;
|
||||
G4cout <<"G4StatMFMacroTemperature, Brent method failed:"
|
||||
<<" fTa="<<fTa<<" fTb="<<fTb<< G4endl;
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMacroTemperature::CalcTemperature: I couldn't find the root with any method.");
|
||||
}
|
||||
|
||||
_MeanTemperature = theSolverBrent->GetRoot();
|
||||
FunctionValureAtRoot = this->operator()(_MeanTemperature);
|
||||
delete theSolverBrent;
|
||||
}
|
||||
if (std::abs(FunctionValureAtRoot) > 5.e-2) {
|
||||
G4cout << "Brent method failed; function = " << FunctionValureAtRoot
|
||||
<< " solution? = " << _MeanTemperature << " MeV " << G4endl;
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMacroTemperature::CalcTemperature: I couldn't find the root with any method.");
|
||||
}
|
||||
}
|
||||
//G4cout << "G4StatMFMacroTemperature::CalcTemperature: function = "
|
||||
//<< FunctionValureAtRoot
|
||||
// << " T(MeV)= " << _MeanTemperature << G4endl;
|
||||
return _MeanTemperature;
|
||||
fMeanTemperature = std::max(std::min(std::sqrt(fExEnergy/(theA*0.12)), t2), t1);
|
||||
fSolver->FindRoot(fMeanTemperature);
|
||||
return fMeanTemperature;
|
||||
}
|
||||
|
||||
G4double G4StatMFMacroTemperature::FragsExcitEnergy(const G4double T)
|
||||
@@ -153,47 +90,35 @@ G4double G4StatMFMacroTemperature::FragsExcitEnergy(const G4double T)
|
||||
// Model Parameters
|
||||
G4Pow* g4calc = G4Pow::GetInstance();
|
||||
G4double R0 = G4StatMFParameters::Getr0()*g4calc->Z13(theA);
|
||||
G4double R = R0*g4calc->A13(1.0+G4StatMFParameters::GetKappaCoulomb());
|
||||
G4double FreeVol = _Kappa*(4.*pi/3.)*R0*R0*R0;
|
||||
G4double R = R0*g4calc->A13(1.0 + G4StatMFParameters::GetKappaCoulomb());
|
||||
G4double FreeVol = fKappa*(4.*CLHEP::pi/3.)*R0*R0*R0;
|
||||
|
||||
// Calculate Chemical potentials
|
||||
CalcChemicalPotentialNu(T);
|
||||
|
||||
|
||||
// Average total fragment energy
|
||||
// Average total fragment energy and mean entropy
|
||||
G4double AverageEnergy = 0.0;
|
||||
std::vector<G4VStatMFMacroCluster*>::iterator i;
|
||||
for (i = _theClusters->begin(); i != _theClusters->end(); ++i)
|
||||
{
|
||||
AverageEnergy += (*i)->GetMeanMultiplicity() * (*i)->CalcEnergy(T);
|
||||
}
|
||||
fMeanEntropy = 0.0;
|
||||
for (auto const ptr : *fClusters) {
|
||||
fMeanEntropy += ptr->CalcEntropy(T, FreeVol);
|
||||
AverageEnergy += ptr->GetMeanMultiplicity() * ptr->CalcEnergy(T);
|
||||
}
|
||||
|
||||
// Add Coulomb energy
|
||||
AverageEnergy += 0.6*elm_coupling*theZ*theZ/R;
|
||||
|
||||
// Calculate mean entropy
|
||||
_MeanEntropy = 0.0;
|
||||
for (i = _theClusters->begin(); i != _theClusters->end(); ++i)
|
||||
{
|
||||
_MeanEntropy += (*i)->CalcEntropy(T,FreeVol);
|
||||
}
|
||||
AverageEnergy += 0.6*CLHEP::elm_coupling*(theZ*theZ)/R;
|
||||
|
||||
// Excitation energy per nucleon
|
||||
return AverageEnergy - _FreeInternalE0;
|
||||
return AverageEnergy - fFreeInternalE0;
|
||||
}
|
||||
|
||||
void G4StatMFMacroTemperature::CalcChemicalPotentialNu(const G4double T)
|
||||
// Calculates the chemical potential \nu
|
||||
{
|
||||
G4StatMFMacroChemicalPotential * theChemPot = new
|
||||
G4StatMFMacroChemicalPotential(theA,theZ,_Kappa,T,_theClusters);
|
||||
theChemPot->Initialise(theA, theZ, fKappa, T, fClusters);
|
||||
|
||||
_ChemPotentialNu = theChemPot->CalcChemicalPotentialNu();
|
||||
_ChemPotentialMu = theChemPot->GetChemicalPotentialMu();
|
||||
_MeanMultiplicity = theChemPot->GetMeanMultiplicity();
|
||||
delete theChemPot;
|
||||
|
||||
return;
|
||||
fChemPotentialNu = theChemPot->CalcChemicalPotentialNu();
|
||||
fChemPotentialMu = theChemPot->GetChemicalPotentialMu();
|
||||
fMeanMultiplicity = theChemPot->GetMeanMultiplicity();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+89
-187
@@ -23,12 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
|
||||
#include <numeric>
|
||||
//
|
||||
// Modification: 13.08.2025 V.Ivanchenko rewrite
|
||||
|
||||
#include "G4StatMFMicroCanonical.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
@@ -36,237 +34,141 @@
|
||||
#include "G4HadronicException.hh"
|
||||
#include "G4Pow.hh"
|
||||
|
||||
// constructor
|
||||
G4StatMFMicroCanonical::G4StatMFMicroCanonical(G4Fragment const & theFragment)
|
||||
namespace
|
||||
{
|
||||
// Perform class initialization
|
||||
Initialize(theFragment);
|
||||
constexpr G4int fMaxMultiplicity = 4;
|
||||
constexpr G4double t1 = 1*CLHEP::MeV;
|
||||
constexpr G4double t2 = 50*CLHEP::MeV;
|
||||
}
|
||||
|
||||
// constructor
|
||||
G4StatMFMicroCanonical::G4StatMFMicroCanonical()
|
||||
{
|
||||
fSolver = new G4FunctionSolver<G4StatMFMicroCanonical>(this, 100, 5.e-4);
|
||||
fSolver->SetIntervalLimits(t1, t2);
|
||||
fPartitionManagerVector.reserve(fMaxMultiplicity);
|
||||
g4calc = G4Pow::GetInstance();
|
||||
}
|
||||
|
||||
// destructor
|
||||
G4StatMFMicroCanonical::~G4StatMFMicroCanonical()
|
||||
{
|
||||
// garbage collection
|
||||
if (!_ThePartitionManagerVector.empty()) {
|
||||
std::for_each(_ThePartitionManagerVector.begin(),
|
||||
_ThePartitionManagerVector.end(),
|
||||
DeleteFragment());
|
||||
delete fSolver;
|
||||
if (!fPartitionManagerVector.empty()) {
|
||||
for (auto const & p : fPartitionManagerVector) { delete p; }
|
||||
}
|
||||
}
|
||||
|
||||
void G4StatMFMicroCanonical::Initialize(const G4Fragment & theFragment)
|
||||
void G4StatMFMicroCanonical::Initialise(const G4Fragment& theFragment)
|
||||
{
|
||||
|
||||
std::vector<G4StatMFMicroManager*>::iterator it;
|
||||
|
||||
fPartitionManagerVector.clear();
|
||||
// Excitation Energy
|
||||
G4double U = theFragment.GetExcitationEnergy();
|
||||
fExEnergy = theFragment.GetExcitationEnergy();
|
||||
|
||||
A = theFragment.GetA_asInt();
|
||||
Z = theFragment.GetZ_asInt();
|
||||
A13 = g4calc->Z13(A);
|
||||
|
||||
fInvLevelDensity = G4StatMFParameters::GetEpsilon0()*(1.0 + 3.0/G4double(A-1));
|
||||
|
||||
fSymmetryTerm = G4StatMFParameters::GetGamma0()*(A - 2*Z)*(A - 2*Z)/(G4double)A;
|
||||
|
||||
fCoulombTerm = elm_coupling*0.6*Z*Z/(G4StatMFParameters::Getr0()*A13);
|
||||
|
||||
G4int A = theFragment.GetA_asInt();
|
||||
G4int Z = theFragment.GetZ_asInt();
|
||||
G4double x = 1.0 - 2.0*Z/G4double(A);
|
||||
G4Pow* g4calc = G4Pow::GetInstance();
|
||||
|
||||
// Configuration temperature
|
||||
G4double TConfiguration = std::sqrt(8.0*U/G4double(A));
|
||||
G4double TConf = std::sqrt(8.0*fExEnergy/(G4double)A);
|
||||
|
||||
// Free internal energy at Temperature T = 0
|
||||
__FreeInternalE0 = A*(
|
||||
// Volume term (for T = 0)
|
||||
-G4StatMFParameters::GetE0() +
|
||||
// Symmetry term
|
||||
G4StatMFParameters::GetGamma0()*x*x
|
||||
) +
|
||||
// Surface term (for T = 0)
|
||||
G4StatMFParameters::GetBeta0()*g4calc->Z23(A) +
|
||||
// Coulomb term
|
||||
elm_coupling*0.6*Z*Z/(G4StatMFParameters::Getr0()*g4calc->Z13(A));
|
||||
|
||||
// Statistical weight
|
||||
G4double W = 0.0;
|
||||
// Free internal energy at Temperature T = 0 (SurfaceTerm at T = 0)
|
||||
pFreeInternalE0 = -G4StatMFParameters::GetE0()*A + fSymmetryTerm
|
||||
+ G4StatMFParameters::GetBeta0()*A13*A13 + fCoulombTerm;
|
||||
|
||||
//G4cout << "Tconf=" << TConf << " freeE=" << pFreeInternalE0 << G4endl;
|
||||
|
||||
// Mean breakup multiplicity
|
||||
__MeanMultiplicity = 0.0;
|
||||
pMeanMultiplicity = 0.0;
|
||||
|
||||
// Mean channel temperature
|
||||
__MeanTemperature = 0.0;
|
||||
pMeanTemperature = 0.0;
|
||||
|
||||
// Mean channel entropy
|
||||
__MeanEntropy = 0.0;
|
||||
pMeanEntropy = 0.0;
|
||||
|
||||
// Calculate entropy of compound nucleus
|
||||
G4double SCompoundNucleus = CalcEntropyOfCompoundNucleus(theFragment,TConfiguration);
|
||||
G4double SCompoundNucleus = CalcEntropyOfCompoundNucleus(TConf);
|
||||
|
||||
// Statistical weight of compound nucleus
|
||||
_WCompoundNucleus = 1.0;
|
||||
fWCompoundNucleus = 1.0;
|
||||
|
||||
W += _WCompoundNucleus;
|
||||
|
||||
// Maximal fragment multiplicity allowed in direct simulation
|
||||
G4int MaxMult = G4StatMFMicroCanonical::MaxAllowedMultiplicity;
|
||||
if (A > 110) MaxMult -= 1;
|
||||
|
||||
for (G4int im = 2; im <= MaxMult; im++) {
|
||||
G4StatMFMicroManager * aMicroManager =
|
||||
new G4StatMFMicroManager(theFragment,im,__FreeInternalE0,SCompoundNucleus);
|
||||
_ThePartitionManagerVector.push_back(aMicroManager);
|
||||
// Statistical weight
|
||||
G4double W = fWCompoundNucleus;
|
||||
// Maximal fragment multiplicity allowed in direct simulation
|
||||
|
||||
for (G4int im = 2; im <= fMaxMultiplicity; ++im) {
|
||||
auto ptr = new G4StatMFMicroManager(theFragment, im, pFreeInternalE0, SCompoundNucleus);
|
||||
fPartitionManagerVector.push_back(ptr);
|
||||
W += ptr->GetProbability();
|
||||
}
|
||||
|
||||
// W is the total probability
|
||||
W = std::accumulate(_ThePartitionManagerVector.begin(),
|
||||
_ThePartitionManagerVector.end(),
|
||||
W, [](const G4double& running_total,
|
||||
G4StatMFMicroManager*& manager)
|
||||
{
|
||||
return running_total + manager->GetProbability();
|
||||
} );
|
||||
|
||||
// Normalization of statistical weights
|
||||
for (it = _ThePartitionManagerVector.begin(); it != _ThePartitionManagerVector.end(); ++it)
|
||||
{
|
||||
(*it)->Normalize(W);
|
||||
}
|
||||
for (auto & ptr : fPartitionManagerVector) {
|
||||
ptr->Normalize(W);
|
||||
pMeanMultiplicity += ptr->GetMeanMultiplicity();
|
||||
pMeanTemperature += ptr->GetMeanTemperature();
|
||||
pMeanEntropy += ptr->GetMeanEntropy();
|
||||
}
|
||||
|
||||
_WCompoundNucleus /= W;
|
||||
fWCompoundNucleus /= W;
|
||||
|
||||
__MeanMultiplicity += 1.0 * _WCompoundNucleus;
|
||||
__MeanTemperature += TConfiguration * _WCompoundNucleus;
|
||||
__MeanEntropy += SCompoundNucleus * _WCompoundNucleus;
|
||||
|
||||
for (it = _ThePartitionManagerVector.begin(); it != _ThePartitionManagerVector.end(); ++it)
|
||||
{
|
||||
__MeanMultiplicity += (*it)->GetMeanMultiplicity();
|
||||
__MeanTemperature += (*it)->GetMeanTemperature();
|
||||
__MeanEntropy += (*it)->GetMeanEntropy();
|
||||
}
|
||||
|
||||
return;
|
||||
pMeanMultiplicity += fWCompoundNucleus;
|
||||
pMeanTemperature += TConf * fWCompoundNucleus;
|
||||
pMeanEntropy += SCompoundNucleus * fWCompoundNucleus;
|
||||
}
|
||||
|
||||
G4double G4StatMFMicroCanonical::CalcFreeInternalEnergy(const G4Fragment & theFragment,
|
||||
G4double T)
|
||||
G4double G4StatMFMicroCanonical::CalcFreeInternalEnergy(G4double T)
|
||||
{
|
||||
G4int A = theFragment.GetA_asInt();
|
||||
G4int Z = theFragment.GetZ_asInt();
|
||||
G4double A13 = G4Pow::GetInstance()->Z13(A);
|
||||
G4double VolumeTerm = (-G4StatMFParameters::GetE0()+T*T/fInvLevelDensity)*A;
|
||||
G4double SurfaceTerm = (G4StatMFParameters::Beta(T) - T*G4StatMFParameters::DBetaDT(T))*A13*A13;
|
||||
G4double sum = VolumeTerm + fSymmetryTerm + SurfaceTerm + fCoulombTerm;
|
||||
|
||||
G4double InvLevelDensityPar = G4StatMFParameters::GetEpsilon0()
|
||||
*(1.0 + 3.0/G4double(A-1));
|
||||
|
||||
G4double VolumeTerm = (-G4StatMFParameters::GetE0()+T*T/InvLevelDensityPar)*A;
|
||||
|
||||
G4double SymmetryTerm = G4StatMFParameters::GetGamma0()
|
||||
*(A - 2*Z)*(A - 2*Z)/G4double(A);
|
||||
|
||||
G4double SurfaceTerm = (G4StatMFParameters::Beta(T)
|
||||
- T*G4StatMFParameters::DBetaDT(T))*A13*A13;
|
||||
|
||||
G4double CoulombTerm = elm_coupling*0.6*Z*Z/(G4StatMFParameters::Getr0()*A13);
|
||||
|
||||
return VolumeTerm + SymmetryTerm + SurfaceTerm + CoulombTerm;
|
||||
// G4cout << "G4StatMFMicroCanonical::CalcFreeInternalEnergy " << sum
|
||||
// << " " << VolumeTerm << " " << fSymmetryTerm << " " << SurfaceTerm
|
||||
// << " " << fCoulombTerm << G4endl;
|
||||
return sum;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4StatMFMicroCanonical::CalcEntropyOfCompoundNucleus(const G4Fragment & theFragment,
|
||||
G4double & TConf)
|
||||
G4double G4StatMFMicroCanonical::CalcEntropyOfCompoundNucleus(G4double& TConf)
|
||||
// Calculates Temperature and Entropy of compound nucleus
|
||||
{
|
||||
G4int A = theFragment.GetA_asInt();
|
||||
G4double U = theFragment.GetExcitationEnergy();
|
||||
G4double A13 = G4Pow::GetInstance()->Z13(A);
|
||||
|
||||
G4double Ta = std::max(std::sqrt(U/(0.125*A)),0.0012*MeV);
|
||||
G4double Tb = Ta;
|
||||
|
||||
G4double ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Ta);
|
||||
G4double Da = (U+__FreeInternalE0-ECompoundNucleus)/U;
|
||||
G4double Db = 0.0;
|
||||
|
||||
G4double InvLevelDensity = CalcInvLevelDensity(A);
|
||||
|
||||
// bracketing the solution
|
||||
if (Da == 0.0) {
|
||||
TConf = Ta;
|
||||
return 2*Ta*A/InvLevelDensity - G4StatMFParameters::DBetaDT(Ta)*A13*A13;
|
||||
} else if (Da < 0.0) {
|
||||
do {
|
||||
Tb -= 0.5*Tb;
|
||||
ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Tb);
|
||||
Db = (U+__FreeInternalE0-ECompoundNucleus)/U;
|
||||
} while (Db < 0.0);
|
||||
} else {
|
||||
do {
|
||||
Tb += 0.5*Tb;
|
||||
ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Tb);
|
||||
Db = (U+__FreeInternalE0-ECompoundNucleus)/U;
|
||||
} while (Db > 0.0);
|
||||
}
|
||||
|
||||
G4double eps = 1.0e-14 * std::abs(Tb-Ta);
|
||||
|
||||
for (G4int i = 0; i < 1000; i++) {
|
||||
G4double Tc = (Ta+Tb)*0.5;
|
||||
if (std::abs(Ta-Tb) <= eps) {
|
||||
TConf = Tc;
|
||||
return 2*Tc*A/InvLevelDensity - G4StatMFParameters::DBetaDT(Tc)*A13*A13;
|
||||
}
|
||||
ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Tc);
|
||||
G4double Dc = (U+__FreeInternalE0-ECompoundNucleus)/U;
|
||||
|
||||
if (Dc == 0.0) {
|
||||
TConf = Tc;
|
||||
return 2*Tc*A/InvLevelDensity - G4StatMFParameters::DBetaDT(Tc)*A13*A13;
|
||||
}
|
||||
|
||||
if (Da*Dc < 0.0) {
|
||||
Tb = Tc;
|
||||
Db = Dc;
|
||||
} else {
|
||||
Ta = Tc;
|
||||
Da = Dc;
|
||||
}
|
||||
}
|
||||
|
||||
G4cout <<
|
||||
"G4StatMFMicrocanoncal::CalcEntropyOfCompoundNucleus: I can't calculate the temperature"
|
||||
<< G4endl;
|
||||
|
||||
return 0.0;
|
||||
G4double T = std::max(std::min(std::max(TConf,std::sqrt(fExEnergy/(A*0.125))), t2), t1);\
|
||||
fSolver->FindRoot(T);
|
||||
TConf = T;
|
||||
// G4cout << "=== FindRoot T= " << T << G4endl;
|
||||
auto S = (2*A)*T/fInvLevelDensity - G4StatMFParameters::DBetaDT(T)*A13*A13;
|
||||
return S;
|
||||
}
|
||||
|
||||
G4StatMFChannel * G4StatMFMicroCanonical::ChooseAandZ(const G4Fragment & theFragment)
|
||||
// Choice of fragment atomic numbers and charges
|
||||
G4StatMFChannel* G4StatMFMicroCanonical::ChooseAandZ(const G4Fragment& theFragment)
|
||||
{
|
||||
// Choice of fragment atomic numbers and charges
|
||||
// We choose a multiplicity (1,2,3,...) and then a channel
|
||||
G4double RandNumber = G4UniformRand();
|
||||
|
||||
if (RandNumber < _WCompoundNucleus) {
|
||||
G4int AA = theFragment.GetA_asInt();
|
||||
G4int ZZ = theFragment.GetZ_asInt();
|
||||
|
||||
if (G4UniformRand() < fWCompoundNucleus) {
|
||||
|
||||
G4StatMFChannel * aChannel = new G4StatMFChannel;
|
||||
aChannel->CreateFragment(theFragment.GetA_asInt(),theFragment.GetZ_asInt());
|
||||
aChannel->CreateFragment(AA, ZZ);
|
||||
return aChannel;
|
||||
|
||||
} else {
|
||||
|
||||
G4double AccumWeight = _WCompoundNucleus;
|
||||
std::vector<G4StatMFMicroManager*>::iterator it;
|
||||
for (it = _ThePartitionManagerVector.begin(); it != _ThePartitionManagerVector.end(); ++it) {
|
||||
AccumWeight += (*it)->GetProbability();
|
||||
if (RandNumber < AccumWeight) {
|
||||
return (*it)->ChooseChannel(theFragment.GetA_asInt(),theFragment.GetZ_asInt(),__MeanTemperature);
|
||||
G4double rand = G4UniformRand();
|
||||
G4double AccumWeight = fWCompoundNucleus;
|
||||
for (auto & ptr : fPartitionManagerVector) {
|
||||
AccumWeight += ptr->GetProbability();
|
||||
if (rand <= AccumWeight) {
|
||||
return ptr->ChooseChannel(A, Z, pMeanTemperature);
|
||||
}
|
||||
}
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMicroCanonical::ChooseAandZ: wrong normalization!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
G4double G4StatMFMicroCanonical::CalcInvLevelDensity(G4int anA)
|
||||
{
|
||||
G4double res = 0.0;
|
||||
if (anA > 1) {
|
||||
res = G4StatMFParameters::GetEpsilon0()*(1.0+3.0/(anA - 1.0));
|
||||
}
|
||||
return res;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
+10
-41
@@ -31,33 +31,6 @@
|
||||
#include "G4StatMFMicroManager.hh"
|
||||
#include "G4HadronicException.hh"
|
||||
|
||||
// Copy constructor
|
||||
G4StatMFMicroManager::G4StatMFMicroManager(const G4StatMFMicroManager & )
|
||||
{
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMicroManager::copy_constructor meant to not be accessible");
|
||||
}
|
||||
|
||||
// Operators
|
||||
|
||||
G4StatMFMicroManager & G4StatMFMicroManager::
|
||||
operator=(const G4StatMFMicroManager & )
|
||||
{
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMicroManager::operator= meant to not be accessible");
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
G4bool G4StatMFMicroManager::operator==(const G4StatMFMicroManager & ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
G4bool G4StatMFMicroManager::operator!=(const G4StatMFMicroManager & ) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// constructor
|
||||
G4StatMFMicroManager::G4StatMFMicroManager(const G4Fragment & theFragment,
|
||||
G4int multiplicity,
|
||||
@@ -71,11 +44,9 @@ G4StatMFMicroManager::G4StatMFMicroManager(const G4Fragment & theFragment,
|
||||
// destructor
|
||||
G4StatMFMicroManager::~G4StatMFMicroManager()
|
||||
{
|
||||
if (!_Partition.empty())
|
||||
{
|
||||
std::for_each(_Partition.begin(),_Partition.end(),
|
||||
DeleteFragment());
|
||||
}
|
||||
if (!_Partition.empty()) {
|
||||
for (auto & p : _Partition) { delete p; }
|
||||
}
|
||||
}
|
||||
|
||||
void G4StatMFMicroManager::Initialize(const G4Fragment & theFragment, G4int im,
|
||||
@@ -172,15 +143,13 @@ G4StatMFMicroManager::ChooseChannel(G4int A0, G4int Z0, G4double MeanT)
|
||||
G4double RandNumber = _Normalization * _WW * G4UniformRand();
|
||||
G4double AccumWeight = 0.0;
|
||||
|
||||
for (std::vector<G4StatMFMicroPartition*>::iterator i = _Partition.begin();
|
||||
i != _Partition.end(); ++i)
|
||||
{
|
||||
AccumWeight += (*i)->GetProbability();
|
||||
if (RandNumber < AccumWeight)
|
||||
return (*i)->ChooseZ(A0,Z0,MeanT);
|
||||
}
|
||||
for (auto & p : _Partition) {
|
||||
AccumWeight += p->GetProbability();
|
||||
if (RandNumber <= AccumWeight)
|
||||
return p->ChooseZ(A0,Z0,MeanT);
|
||||
}
|
||||
|
||||
throw G4HadronicException(__FILE__, __LINE__,
|
||||
"G4StatMFMicroCanonical::ChooseChannel: Couldn't find a channel.");
|
||||
return 0;
|
||||
"G4StatMFMicroManager::ChooseChannel: Couldn't find a channel.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ const G4double G4StatMFParameters::fKappa = 1.0; // dimensionless
|
||||
|
||||
const G4double G4StatMFParameters::fKappaCoulomb = 2.0; // dimensionless
|
||||
|
||||
const G4double G4StatMFParameters::fEpsilon0 = 16.0*MeV;
|
||||
const G4double G4StatMFParameters::fEpsilon0 = 16.0*CLHEP::MeV;
|
||||
|
||||
// Bethe-Weizsacker coefficients
|
||||
const G4double G4StatMFParameters::fE0 = 16.0*MeV;
|
||||
|
||||
+39
-32
@@ -61,78 +61,85 @@ G4GammaTransition::SampleTransition(G4Fragment* nucleus,
|
||||
G4int MP,
|
||||
G4int shell,
|
||||
G4bool isDiscrete,
|
||||
G4bool isGamma)
|
||||
G4bool gamma)
|
||||
{
|
||||
G4Fragment* result = nullptr;
|
||||
G4double bond_energy = 0.0;
|
||||
G4double bondEnergy = 0.0;
|
||||
G4bool isGamma = gamma;
|
||||
if (!isDiscrete) { isGamma = true; }
|
||||
|
||||
G4double excEnergy = nucleus->GetExcitationEnergy();
|
||||
|
||||
// check is IC electron can be emitted
|
||||
if (!isGamma) {
|
||||
if(0 <= shell) {
|
||||
G4int Z = nucleus->GetZ_asInt();
|
||||
if(Z <= 104) {
|
||||
G4int idx = std::min(shell, G4AtomicShells::GetNumberOfShells(Z)-1);
|
||||
bond_energy = G4AtomicShells::GetBindingEnergy(Z, idx);
|
||||
bondEnergy = G4AtomicShells::GetBindingEnergy(Z, idx);
|
||||
if (bondEnergy > excEnergy) {
|
||||
isGamma = true;
|
||||
}
|
||||
} else {
|
||||
isGamma = true;
|
||||
}
|
||||
} else {
|
||||
isGamma = true;
|
||||
}
|
||||
}
|
||||
G4double etrans = nucleus->GetExcitationEnergy() - newExcEnergy
|
||||
- bond_energy;
|
||||
if(fVerbose > 2) {
|
||||
G4cout << "G4GammaTransition::GenerateGamma - Etrans(MeV)= "
|
||||
<< etrans << " Eexnew= " << newExcEnergy
|
||||
<< " Ebond= " << bond_energy << G4endl;
|
||||
if (fVerbose > 2) {
|
||||
G4cout << "G4GammaTransition::GenerateGamma " << " Eexnew=" << newExcEnergy
|
||||
<< " Ebond=" << bondEnergy << G4endl;
|
||||
}
|
||||
if(etrans <= 0.0) {
|
||||
etrans += bond_energy;
|
||||
bond_energy = 0.0;
|
||||
}
|
||||
|
||||
// Do complete Lorentz computation
|
||||
G4LorentzVector lv = nucleus->GetMomentum();
|
||||
|
||||
// final mass
|
||||
G4double mass = nucleus->GetGroundStateMass() + newExcEnergy;
|
||||
|
||||
// select secondary
|
||||
// complete selection of secondary
|
||||
G4ParticleDefinition* part;
|
||||
G4int ne = nucleus->GetNumberOfElectrons();
|
||||
if (0 == ne) { isGamma = true; }
|
||||
|
||||
if(isGamma) { part = G4Gamma::Gamma(); }
|
||||
if ( isGamma ) { part = G4Gamma::Gamma(); }
|
||||
else {
|
||||
part = G4Electron::Electron();
|
||||
G4int ne = std::max(nucleus->GetNumberOfElectrons() - 1, 0);
|
||||
--ne;
|
||||
nucleus->SetNumberOfElectrons(ne);
|
||||
}
|
||||
|
||||
if(polarFlag && isDiscrete && JP1 <= fTwoJMAX) {
|
||||
if (isGamma && polarFlag && isDiscrete && JP1 <= fTwoJMAX) {
|
||||
SampleDirection(nucleus, mpRatio, JP1, JP2, MP);
|
||||
} else {
|
||||
fDirection = G4RandomDirection();
|
||||
}
|
||||
|
||||
// 4-vector of initial fragnet
|
||||
G4LorentzVector lv = nucleus->GetMomentum();
|
||||
|
||||
// kinematics of the decay
|
||||
G4double emass = part->GetPDGMass();
|
||||
G4double m0 = nucleus->GetGroundStateMass() + excEnergy;
|
||||
G4double m1 = nucleus->GetGroundStateMass() + newExcEnergy;
|
||||
if (!isGamma) {
|
||||
m0 += (ne + 1)*CLHEP::electron_mass_c2 - bondEnergy;
|
||||
m1 += ne*CLHEP::electron_mass_c2;
|
||||
}
|
||||
|
||||
// 2-body decay in rest frame
|
||||
G4double ecm = lv.mag();
|
||||
const G4double elim2 = 100.*CLHEP::eV*CLHEP::eV;
|
||||
G4bool atRest = (lv.vect().mag2() < elim2);
|
||||
G4ThreeVector bst(0.0, 0.0, 0.0);
|
||||
if (!atRest) { bst = lv.boostVector(); }
|
||||
if(!isGamma) { ecm += (CLHEP::electron_mass_c2 - bond_energy); }
|
||||
if (!atRest) { bst = lv.boostVector(); }
|
||||
|
||||
//G4cout << "Ecm= " << ecm << " mass= " << mass << " emass= " << emass << G4endl;
|
||||
|
||||
ecm = std::max(ecm, mass + emass);
|
||||
G4double energy = 0.5*((ecm - mass)*(ecm + mass) + emass*emass)/ecm;
|
||||
G4double mom = (emass > 0.0) ? std::sqrt((energy - emass)*(energy + emass))
|
||||
: energy;
|
||||
G4double energy = 0.5*((m0 - m1)*(m0 + m1) + emass*emass)/m0;
|
||||
G4double mom = (isGamma) ? energy : std::sqrt((energy - emass)*(energy + emass));
|
||||
|
||||
// emitted gamma or e-
|
||||
G4LorentzVector res4mom(mom * fDirection.x(),
|
||||
mom * fDirection.y(),
|
||||
mom * fDirection.z(), energy);
|
||||
// residual
|
||||
energy = std::max(ecm - energy, mass);
|
||||
mom = std::sqrt(energy*energy - mass*mass);
|
||||
energy = m0 - energy;
|
||||
mom = std::sqrt((energy - m1)*(energy + m1));
|
||||
lv.set(-mom*fDirection.x(), -mom*fDirection.y(), -mom*fDirection.z(), energy);
|
||||
|
||||
// Lab system transform for short lived level
|
||||
|
||||
+3
@@ -119,6 +119,9 @@ G4PhotonEvaporation::EmittedFragment(G4Fragment* nucleus)
|
||||
{
|
||||
if(!isInitialised) { Initialise(); }
|
||||
fSampleTime = !fRDM;
|
||||
if (fRDM) {
|
||||
nucleus->SetNumberOfElectrons(nucleus->GetZ_asInt());
|
||||
}
|
||||
|
||||
// potentially external code may set initial polarization
|
||||
// but only for radioactive decay nuclear polarization is considered
|
||||
|
||||
@@ -40,14 +40,15 @@ class G4DeexPrecoUtility
|
||||
{
|
||||
public:
|
||||
|
||||
// compute correction factor
|
||||
static G4double CorrectionFactor(const G4int index, const G4int Z,
|
||||
const G4double A13, const G4double CB,
|
||||
const G4double eKin, const G4double eKin0);
|
||||
|
||||
// Compute correction factor
|
||||
// Data comes from Dostrovsky, Fraenkel and Friedlander
|
||||
// Physical Review, vol 116, num. 3 1959
|
||||
|
||||
static G4double CorrectionFactor(const G4int index, const G4int Z,
|
||||
const G4double A13,
|
||||
const G4double bCoulomb,
|
||||
const G4double ekin);
|
||||
|
||||
static G4double ProtonKValue(const G4int Z);
|
||||
|
||||
static G4double AlphaKValue(const G4int Z);
|
||||
@@ -56,6 +57,8 @@ public:
|
||||
|
||||
static G4double AlphaCValue(const G4int Z);
|
||||
|
||||
static G4double LevelDensity(const G4int Z, const G4int A, const G4int index);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4NuclearRadii.hh"
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr G4double e0 = 2*CLHEP::MeV;
|
||||
}
|
||||
|
||||
G4CoulombBarrier::G4CoulombBarrier(G4int A, G4int Z)
|
||||
: G4VCoulombBarrier(A, Z)
|
||||
{
|
||||
@@ -45,9 +50,8 @@ G4CoulombBarrier::G4CoulombBarrier(G4int A, G4int Z)
|
||||
G4double G4CoulombBarrier::GetCoulombBarrier(
|
||||
G4int ARes, G4int ZRes, G4double U) const
|
||||
{
|
||||
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 + theA))*CLHEP::MeV) )); }
|
||||
cb /= (1.0 + std::sqrt( U / ((ARes + theA)*e0)));
|
||||
return cb;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,50 +30,51 @@
|
||||
//
|
||||
|
||||
#include "G4DeexPrecoUtility.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
namespace
|
||||
{
|
||||
const G4double elim = 0.2*CLHEP::MeV; // low-energy limit for neutrons
|
||||
const G4double alpha = 2.0; // extra factor for neutrons
|
||||
const G4double beta = 1.0; // extra factor for the Coulomb barrier
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4DeexPrecoUtility::CorrectionFactor(const G4int index, const G4int Z,
|
||||
const G4double A13,
|
||||
const G4double CB,
|
||||
const G4double eKin,
|
||||
const G4double eKin0)
|
||||
const G4double ekin)
|
||||
{
|
||||
G4double res = 1.0;
|
||||
|
||||
G4double e = std::max(ekin, elim);
|
||||
G4double x;
|
||||
switch (index) {
|
||||
case 0:
|
||||
x = (2.12*A13 - 0.05)/(2.2*A13 + 0.76);
|
||||
res = (eKin + x)/(eKin0 + x);
|
||||
x = alpha*(0.76 + 2.2/A13 + (2.12/(A13*A13) - 0.05)*CLHEP::MeV/e);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
x = ProtonKValue(Z);
|
||||
res = std::max(eKin - x*CB, 0.0)/(eKin0 - x*CB);
|
||||
x = (1. + ProtonCValue(Z))*(1. - beta*ProtonKValue(Z)*CB/e);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
x = ProtonKValue(Z) + 0.06;
|
||||
res = std::max(eKin - x*CB, 0.0)/(eKin0 - x*CB);
|
||||
x = (1. + ProtonCValue(Z)*0.5)*(1. - beta*(ProtonKValue(Z) + 0.06)*CB/e);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
x = ProtonKValue(Z) + 0.12;
|
||||
res = std::max(eKin - x*CB, 0.0)/(eKin0 - x*CB);
|
||||
x = (1. + ProtonCValue(Z)/3.)*(1. - beta*(ProtonKValue(Z) + 0.12)*CB/e);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
x = AlphaKValue(Z) + 0.12;
|
||||
res = std::max(eKin - x*CB, 0.0)/(eKin0 - x*CB);
|
||||
x = (1. + AlphaCValue(Z)*4./3.)*(1. - beta*(AlphaKValue(Z) - 0.06)*CB/e);
|
||||
break;
|
||||
|
||||
default:
|
||||
x = AlphaKValue(Z);
|
||||
res = std::max(eKin - x*CB, 0.0)/(eKin0 - x*CB);
|
||||
x = (1. + AlphaCValue(Z))*(1. - beta*AlphaKValue(Z)*CB/e);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
x = std::max(x, 0.0);
|
||||
return x;
|
||||
}
|
||||
|
||||
G4double G4DeexPrecoUtility::ProtonKValue(const G4int Z)
|
||||
@@ -122,6 +123,39 @@ G4double G4DeexPrecoUtility::AlphaCValue(const G4int Z)
|
||||
return res;
|
||||
}
|
||||
|
||||
G4double
|
||||
G4DeexPrecoUtility::LevelDensity(const G4int Z, const G4int A, const G4int idx)
|
||||
{
|
||||
G4double a = 0.05*A;
|
||||
G4double x = (A - Z)*1.3/(G4double)A;
|
||||
switch (idx) {
|
||||
case 0:
|
||||
a *= (1. - x/A)*(1. - x/A);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
a *= (1. + x/A)*(1. + x/A);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
a *= (1. - 0.5/A)*(1. - 0.5/A);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
a *= (1. - (1. + x)/A)*(1. - (1. + x)/A);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
a *= (1. - (1. - x)/A)*(1. - (1. - x)/A);
|
||||
break;
|
||||
|
||||
default:
|
||||
a *= (1. - 1.5/A)*(1. - 1.5/A);
|
||||
break;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,16 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-11-06 Gabriele Cosmo (hadr-inclxx-V11-03-03)
|
||||
- Fixed compilation warning for implicit type conversion on macOS/XCode
|
||||
in G4INCLAntinucleiAtrestEntryChannel::getAnnihilationPosition().
|
||||
|
||||
## 2025-10-01 Jean-Christophe David (hadr-inclxx-V11-03-02)
|
||||
- Extension of the INCLXX model to handle antineutron (at rest and in-flight).
|
||||
- Fix the use of INCL for the reactions antineutron + H1/H2 and decay omega/eta
|
||||
- Forbid the use of SRC
|
||||
- back to no hyperremnant.
|
||||
|
||||
## 2025-05-16 Ben Morgan (hadr-inclxx-V11-03-01)
|
||||
- Replace the URL root.cern.ch with canonical root.cern
|
||||
- Fixes [GitHub PR 87](https://github.com/Geant4/geant4/pull/87)
|
||||
|
||||
+75
@@ -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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// INCL++ intra-nuclear cascade model
|
||||
// Alain Boudard, CEA-Saclay, France
|
||||
// Joseph Cugnon, University of Liege, Belgium
|
||||
// Jean-Christophe David, CEA-Saclay, France
|
||||
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
|
||||
// Sylvie Leray, CEA-Saclay, France
|
||||
// Davide Mancusi, CEA-Saclay, France
|
||||
//
|
||||
#define INCLXX_IN_GEANT4_MODE 1
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
#include "G4INCLParticle.hh"
|
||||
#include "G4INCLIChannel.hh"
|
||||
#include "G4INCLNucleus.hh"
|
||||
#include "G4INCLAllocationPool.hh"
|
||||
#include "G4INCLFinalState.hh"
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef G4INCAntinucleiAtrestEntry_hh
|
||||
#define G4INCLAntinucleiAtrestEntry_hh 1
|
||||
|
||||
namespace G4INCL{
|
||||
class FinalState;
|
||||
|
||||
class AntinucleiAtrestEntryChannel: public IChannel{
|
||||
public :
|
||||
AntinucleiAtrestEntryChannel(Nucleus *n, Cluster *ac, ThreeVector pos1, ThreeVector pos2);
|
||||
AntinucleiAtrestEntryChannel(Nucleus *n, Particle *p);
|
||||
virtual ~AntinucleiAtrestEntryChannel();
|
||||
void fillFinalState(FinalState *fs);
|
||||
ThreeVector getAnnihilationPosition(ThreeVector nbarPos, ThreeVector pbarPos);
|
||||
ParticleList makeMesonStar();
|
||||
IAvatarList bringMesonStar(ParticleList const &pL, Nucleus * const n);
|
||||
|
||||
private:
|
||||
Nucleus *theNucleus;
|
||||
Cluster *theantiComposite;
|
||||
ThreeVector Posnbar; //Position of the annihilation from PbarAtrestEntryChannel
|
||||
ThreeVector Pospbar; //Position of the annihilation from NbarAtrestEntryChannel
|
||||
Particle *Meson; // For fillFinalState
|
||||
G4int pbarListSize; //To know who is coming from pbar annihilation
|
||||
|
||||
INCL_DECLARE_ALLOCATION_POOL(AntinucleiAtrestEntryChannel)
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
+2
@@ -97,6 +97,8 @@ namespace G4INCL {
|
||||
G4bool isElastic;
|
||||
G4bool isStrangeProduction;
|
||||
|
||||
void generateSrcPairsMethod(ParticleList &theList, const int then, const int thez, G4INCL::Particle*, G4INCL::Particle*);
|
||||
|
||||
INCL_DECLARE_ALLOCATION_POOL(BinaryCollisionAvatar)
|
||||
};
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace G4INCL {
|
||||
particleKineticEnergies.push_back((*p)->getKineticEnergy());
|
||||
}
|
||||
ProjectileRemnant * const aPR = n->getProjectileRemnant();
|
||||
if(aPR && aPR->getA()>0) {
|
||||
if(aPR && (aPR->getA()>0 || aPR->getA()<0)) {
|
||||
particleMomenta.push_back(aPR->getMomentum());
|
||||
particleKineticEnergies.push_back(aPR->getKineticEnergy());
|
||||
outgoingParticles.push_back(aPR);
|
||||
@@ -218,7 +218,7 @@ namespace G4INCL {
|
||||
particleCMMomenta.push_back((*p)->getMomentum());
|
||||
}
|
||||
ProjectileRemnant * const aPR = n->getProjectileRemnant();
|
||||
if(aPR && aPR->getA()>0) {
|
||||
if(aPR && aPR->getA()!=0) {
|
||||
aPR->boost(thePTBoostVector);
|
||||
particleCMMomenta.push_back(aPR->getMomentum());
|
||||
outgoingParticles.push_back(aPR);
|
||||
@@ -375,10 +375,16 @@ namespace G4INCL {
|
||||
/// \brief Initialise the "cascade" for pbar on H2
|
||||
void preCascade_pbarH2(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy);
|
||||
|
||||
/// \brief Finalise the "cascade" and clean up for pbar on H1
|
||||
/// \brief Initialise the "cascade" for nbar on H1
|
||||
void preCascade_nbarH1(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy);
|
||||
|
||||
/// \brief Initialise the "cascade" for nbar on H2
|
||||
void preCascade_nbarH2(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy);
|
||||
|
||||
/// \brief Finalise the "cascade" and clean up for pbar/nbar on H1
|
||||
void postCascade_pbarH1(ParticleList const &outgoingParticles);
|
||||
|
||||
/// \brief Finalise the "cascade" and clean up for pbar on H2
|
||||
/// \brief Finalise the "cascade" and clean up for pbar/nbar on H2
|
||||
void postCascade_pbarH2(ParticleList const &outgoingParticles, ParticleList const &H2Particles);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ namespace G4INCL {
|
||||
theSpin(0.,0.,0.),
|
||||
theParticleSampler(NULL)
|
||||
{
|
||||
if(A >= 0){
|
||||
setType(Composite);
|
||||
theZ = Z;
|
||||
theA = A;
|
||||
@@ -71,6 +72,16 @@ namespace G4INCL {
|
||||
if(createParticleSampler)
|
||||
theParticleSampler = new ParticleSampler(A,Z,S);
|
||||
}
|
||||
else {
|
||||
setType(antiComposite);
|
||||
theZ = Z;
|
||||
theA = A;
|
||||
theS = S;
|
||||
setINCLMass();
|
||||
if(createParticleSampler)
|
||||
theParticleSampler = new ParticleSampler(A,Z,S);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A cluster can be directly built from a list of particles.
|
||||
@@ -86,6 +97,11 @@ namespace G4INCL {
|
||||
for(Iterator i = begin; i != end; ++i) {
|
||||
addParticle(*i);
|
||||
}
|
||||
if (theA < 0){
|
||||
setType(antiComposite);
|
||||
thePosition /= (-theA);
|
||||
}
|
||||
else
|
||||
thePosition /= theA;
|
||||
setINCLMass();
|
||||
adjustMomentumFromEnergy();
|
||||
@@ -260,8 +276,13 @@ namespace G4INCL {
|
||||
theTotalMomentum += (*p)->getMomentum();
|
||||
//theTotalEnergy += (*p)->getEnergy();
|
||||
}
|
||||
if(theA>=0){
|
||||
theCMPosition /= theA;
|
||||
// assert((unsigned int)theA==particles.size());
|
||||
} else if (theA < 0){
|
||||
theCMPosition /= -theA;
|
||||
//assert(-theA==particles.size());
|
||||
}
|
||||
|
||||
// Now determine the CM velocity of the particles
|
||||
// commented out because currently unused, see below
|
||||
@@ -270,7 +291,13 @@ namespace G4INCL {
|
||||
// The new particle positions and momenta are scaled by a factor of
|
||||
// \f$\sqrt{A/(A-1)}\f$, so that the resulting density distributions in
|
||||
// the CM have the same variance as the one we started with.
|
||||
const G4double rescaling = std::sqrt(((G4double)theA)/((G4double)(theA-1)));
|
||||
G4double rescaling;
|
||||
if (theA>0)
|
||||
rescaling = std::sqrt(((G4double)theA)/((G4double)(theA-1)));
|
||||
else if (theA<0)
|
||||
rescaling = std::sqrt(((G4double)(-theA))/((G4double)((-theA)-1)));
|
||||
else
|
||||
rescaling = 0 ;
|
||||
|
||||
// Loop again to boost and reposition
|
||||
for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
|
||||
@@ -278,7 +305,10 @@ namespace G4INCL {
|
||||
// does not!
|
||||
// (*p)->boost(betaCM);
|
||||
// Here is what the Fortran version does:}
|
||||
(*p)->setMomentum(((*p)->getMomentum()-theTotalMomentum/theA)*rescaling);
|
||||
if (theA>0)
|
||||
(*p)->setMomentum(((*p)->getMomentum()-theTotalMomentum/theA)*rescaling);
|
||||
else if (theA<0)
|
||||
(*p)->setMomentum(((*p)->getMomentum()-theTotalMomentum/(-theA))*rescaling);
|
||||
|
||||
// Set the CM position of the particles
|
||||
(*p)->setPosition(((*p)->getPosition()-theCMPosition)*rescaling);
|
||||
@@ -441,7 +471,7 @@ namespace G4INCL {
|
||||
theDynamicalPotential += (*p)->getEnergy();
|
||||
}
|
||||
theDynamicalPotential -= getTableMass();
|
||||
theDynamicalPotential /= theA;
|
||||
theDynamicalPotential /= std::abs(theA);
|
||||
|
||||
return theDynamicalPotential;
|
||||
}
|
||||
|
||||
+2
@@ -76,6 +76,8 @@ namespace G4INCL {
|
||||
* \return the ParticleEntryAvatar for the projectile particle
|
||||
**/
|
||||
ParticleEntryAvatar *bringToSurface(Particle *p, Nucleus * const n);
|
||||
|
||||
ParticleEntryAvatar *bringToSurfaceAbar(Particle *p, Nucleus * const n);
|
||||
|
||||
/** \brief Modify the momentum of an incoming cluster and position it on
|
||||
* the surface of the target.
|
||||
|
||||
+2
@@ -67,6 +67,8 @@ namespace G4INCL {
|
||||
* \param n distorting nucleus
|
||||
**/
|
||||
ParticleEntryAvatar *bringToSurface(Particle * const p, Nucleus * const n) const;
|
||||
|
||||
ParticleEntryAvatar *bringToSurfaceAbar(Particle * const p, Nucleus * const n) const;
|
||||
|
||||
/** \brief Modify the momentum of the incoming cluster and position it on
|
||||
* the surface of the nucleus.
|
||||
|
||||
@@ -66,6 +66,15 @@ namespace G4INCL {
|
||||
* \param n distorting nucleus
|
||||
**/
|
||||
ParticleEntryAvatar *bringToSurface(Particle * const p, Nucleus * const n) const;
|
||||
|
||||
/** \brief Position the particle on the surface of the nucleus.
|
||||
* ONLY FOR ANTIDEUTERON !!!
|
||||
* This method does not perform any distortion.
|
||||
*
|
||||
* \param p incoming particle
|
||||
* \param n distorting nucleus
|
||||
**/
|
||||
ParticleEntryAvatar *bringToSurfaceAbar(Particle * const p, Nucleus * const n) const;
|
||||
|
||||
/** \brief Position the cluster on the surface of the nucleus.
|
||||
*
|
||||
@@ -86,7 +95,7 @@ namespace G4INCL {
|
||||
* trajectories. **/
|
||||
G4double maxImpactParameter(ParticleSpecies const &p, const G4double /*kinE*/, Nucleus const *
|
||||
const n) const {
|
||||
if(p.theType == Composite)
|
||||
if(p.theType == Composite || p.theType == antiComposite)
|
||||
return 2.*ParticleTable::getLargestNuclearRadius(p.theA, p.theZ)
|
||||
+ n->getUniverseRadius();
|
||||
else
|
||||
|
||||
@@ -54,10 +54,14 @@ namespace G4INCL {
|
||||
G4double piNToEtaN(Particle const * const p1, Particle const * const p2);
|
||||
G4double piNToOmegaN(Particle const * const p1, Particle const * const p2);
|
||||
G4double piNToEtaPrimeN(Particle const * const p1, Particle const * const p2);
|
||||
G4double etaNToPiN(Particle const * const p1, Particle const * const p2);
|
||||
G4double etaNToPiPiN(Particle const * const p1, Particle const * const p2);
|
||||
G4double etaNToPiN(Particle const * const p1, Particle const * const p2);
|
||||
G4double etaNToPiPiN(Particle const * const p1, Particle const * const p2);
|
||||
G4double etaNToLK(Particle const * const p1, Particle const * const p2);
|
||||
G4double etaNToSK(Particle const * const p1, Particle const * const p2);
|
||||
G4double omegaNToPiN(Particle const * const p1, Particle const * const p2);
|
||||
G4double omegaNToPiPiN(Particle const * const p1, Particle const * const p2);
|
||||
G4double omegaNToLK(Particle const * const p1, Particle const * const p2);
|
||||
G4double omegaNToSK(Particle const * const p1, Particle const * const p2);
|
||||
G4double etaPrimeNToPiN(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
G4double NNToNNEta(Particle const * const p1, Particle const * const p2);
|
||||
@@ -143,7 +147,8 @@ namespace G4INCL {
|
||||
* \return the interaction distance
|
||||
*/
|
||||
G4double interactionDistanceNN(const ParticleSpecies &aSpecies, const G4double kineticEnergy);
|
||||
|
||||
G4double interactionDistanceNbarN(const ParticleSpecies &aSpecies, const G4double kineticEnergy);
|
||||
G4double interactionDistancenbarN(const ParticleSpecies &aSpecies, const G4double kineticEnergy);
|
||||
/** \brief Compute the "interaction distance".
|
||||
*
|
||||
* Defined on the basis of the average value of the pi-N cross sections at
|
||||
|
||||
+6
@@ -88,6 +88,12 @@ namespace G4INCL {
|
||||
virtual G4double etaNToPiPiN(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double omegaNToPiPiN(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief Cross sections for mesonic resonance absorption on nucleon - LK/SK Channel
|
||||
virtual G4double etaNToLK(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double omegaNToLK(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double etaNToSK(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double omegaNToSK(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief Cross section for Eta production - NN entrance channel
|
||||
virtual G4double NNToNNEta(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
|
||||
+7
-1
@@ -98,7 +98,13 @@ namespace G4INCL {
|
||||
virtual G4double etaNToPiN(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double omegaNToPiN(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double etaPrimeNToPiN(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
|
||||
/// \brief Cross sections for mesonic resonance absorption on nucleon - LK/SKChannel
|
||||
virtual G4double etaNToLK(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double omegaNToLK(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double etaNToSK(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double omegaNToSK(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief Cross section for Eta production - NN entrance channel
|
||||
virtual G4double NNToNNEta(Particle const * const particle1, Particle const * const particle2);
|
||||
|
||||
|
||||
+31
-25
@@ -74,8 +74,12 @@ namespace G4INCL {
|
||||
virtual G4double omegaNToPiN(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double etaPrimeNToPiN(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief Cross sections for mesonic resonance absorption on nucleon - pipiN Channel
|
||||
virtual G4double etaNToPiPiN(Particle const * const p1, Particle const * const p2);
|
||||
/// \brief Cross sections for mesonic resonance absorption on nucleon - pipiN Channel
|
||||
virtual G4double etaNToPiPiN(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief Cross sections for eta-N --> LK/SK
|
||||
virtual G4double etaNToLK(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double etaNToSK(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief Cross section for Eta production (inclusive) - NN entrance channel
|
||||
virtual G4double NNToNNEta(Particle const * const particle1, Particle const * const particle2);
|
||||
@@ -92,11 +96,11 @@ namespace G4INCL {
|
||||
/// \brief Cross section for X pion production - NN Channel
|
||||
virtual G4double NNToxPiNN(const G4int xpi, Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief Cross section for X pion production - NNEta Channel
|
||||
virtual G4double NNToNNEtaxPi(const G4int xpi, Particle const * const p1, Particle const * const p2);
|
||||
/// \brief Cross section for X pion production - NNEta Channel
|
||||
virtual G4double NNToNNEtaxPi(const G4int xpi, Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief Cross section for N-Delta-Eta production - NNEta Channel
|
||||
virtual G4double NNToNDeltaEta(Particle const * const p1, Particle const * const p2);
|
||||
/// \brief Cross section for N-Delta-Eta production - NNEta Channel
|
||||
virtual G4double NNToNDeltaEta(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief Cross section for X pion production - NNOmega Channel
|
||||
virtual G4double NNToNNOmegaxPi(const G4int xpi, Particle const * const p1, Particle const * const p2);
|
||||
@@ -161,9 +165,9 @@ namespace G4INCL {
|
||||
G4double piMinuspToOmegaN(Particle const * const p1, Particle const * const p2);
|
||||
G4double piMinuspToOmegaN(const G4double ECM);
|
||||
// G4double piPluspOnePi(Particle const * const p1, Particle const * const p2);
|
||||
// G4double piMinuspOnePi(Particle const * const p1, Particle const * const p2);
|
||||
// G4double piMinuspOnePi(Particle const * const p1, Particle const * const p2);
|
||||
// G4double piPluspTwoPi(Particle const * const p1, Particle const * const p2);
|
||||
// G4double piMinuspTwoPi(Particle const * const p1, Particle const * const p2);
|
||||
// G4double piMinuspTwoPi(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief Cross section for One (more) pion production - piN entrance channel
|
||||
// virtual G4double piNOnePi(Particle const * const p1, Particle const * const p2);
|
||||
@@ -174,22 +178,22 @@ namespace G4INCL {
|
||||
/// \brief Cross section for Three (more) pion production - piN entrance channel
|
||||
///virtual G4double piNThreePi(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief Isotopic Cross section for Eta production (inclusive) - NN entrance channel
|
||||
virtual G4double NNToNNEtaIso(const G4double ener, const G4int iso);
|
||||
/// \brief Isotopic Cross section for Eta production (inclusive) - NN entrance channel
|
||||
virtual G4double NNToNNEtaIso(const G4double ener, const G4int iso);
|
||||
|
||||
/// \brief Isotopic Cross section for Eta production (exclusive) - NN entrance channel
|
||||
virtual G4double NNToNNEtaExcluIso(const G4double ener, const G4int iso);
|
||||
/// \brief Isotopic Cross section for Eta production (exclusive) - NN entrance channel
|
||||
virtual G4double NNToNNEtaExcluIso(const G4double ener, const G4int iso);
|
||||
|
||||
/// \brief Cross section for direct 1-pion production - NNEta channel
|
||||
virtual G4double NNToNNEtaOnePi(Particle const * const part1, Particle const * const part2);
|
||||
/// \brief Cross section for direct 1-pion production - NNEta channel
|
||||
virtual G4double NNToNNEtaOnePiOrDelta(Particle const * const part1, Particle const * const part2);
|
||||
/// \brief Cross section for direct 2-pion production - NNEta channel
|
||||
virtual G4double NNToNNEtaTwoPi(Particle const * const part1, Particle const * const part2);
|
||||
/// \brief Cross section for direct 3-pion production - NNEta channel
|
||||
virtual G4double NNToNNEtaThreePi(Particle const * const part1, Particle const * const part2);
|
||||
/// \brief Cross section for direct 4-pion production - NNEta channel
|
||||
virtual G4double NNToNNEtaFourPi(Particle const * const part1, Particle const * const part2);
|
||||
/// \brief Cross section for direct 1-pion production - NNEta channel
|
||||
virtual G4double NNToNNEtaOnePi(Particle const * const part1, Particle const * const part2);
|
||||
/// \brief Cross section for direct 1-pion production - NNEta channel
|
||||
virtual G4double NNToNNEtaOnePiOrDelta(Particle const * const part1, Particle const * const part2);
|
||||
/// \brief Cross section for direct 2-pion production - NNEta channel
|
||||
virtual G4double NNToNNEtaTwoPi(Particle const * const part1, Particle const * const part2);
|
||||
/// \brief Cross section for direct 3-pion production - NNEta channel
|
||||
virtual G4double NNToNNEtaThreePi(Particle const * const part1, Particle const * const part2);
|
||||
/// \brief Cross section for direct 4-pion production - NNEta channel
|
||||
virtual G4double NNToNNEtaFourPi(Particle const * const part1, Particle const * const part2);
|
||||
|
||||
|
||||
/// \brief Isotopic Cross section for Omega production (inclusive) - NN entrance channel
|
||||
@@ -210,8 +214,8 @@ namespace G4INCL {
|
||||
virtual G4double NNToNNOmegaFourPi(Particle const * const part1, Particle const * const part2);
|
||||
|
||||
|
||||
/// \brief Cross sections for mesonic resonance absorption on nucleon - elastic Channel
|
||||
virtual G4double etaNElastic(Particle const * const p1, Particle const * const p2);
|
||||
/// \brief Cross sections for mesonic resonance absorption on nucleon - elastic Channel
|
||||
virtual G4double etaNElastic(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double omegaNElastic(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
|
||||
@@ -219,7 +223,9 @@ namespace G4INCL {
|
||||
virtual G4double omegaNInelastic(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief Cross sections for omega-induced 2Pi emission on nucleon
|
||||
virtual G4double omegaNToPiPiN(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double omegaNToPiPiN(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double omegaNToLK(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double omegaNToSK(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
+10
-1
@@ -90,7 +90,7 @@ namespace G4INCL {
|
||||
|
||||
virtual G4double NDeltaToNNKKb(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief Nucleon-Pion to Stange particles cross sections
|
||||
/// \brief Nucleon-Pion to Strange particles cross sections
|
||||
virtual G4double NpiToLK(Particle const * const p1, Particle const * const p2);
|
||||
G4double p_pimToLK0(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double NpiToSK(Particle const * const p1, Particle const * const p2);
|
||||
@@ -126,6 +126,15 @@ namespace G4INCL {
|
||||
virtual G4double p_kmToL_pp_pm(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double NKbToNKbpi(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double NKbToNKb2pi(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief eta-Nucleon cross sections
|
||||
virtual G4double etaNToLK(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double etaNToSK(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
/// \brief Omega-Nucleon cross sections
|
||||
virtual G4double omegaNToLK(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double omegaNToSK(Particle const * const p1, Particle const * const p2);
|
||||
virtual G4double omegaNToPiPiN(Particle const * const p1, Particle const * const p2);
|
||||
|
||||
protected:
|
||||
/// \brief Maximum number of outgoing pions in NN collisions
|
||||
|
||||
+4
-1
@@ -43,11 +43,12 @@
|
||||
#include "G4INCLIChannel.hh"
|
||||
#include "G4INCLFinalState.hh"
|
||||
#include "G4INCLAllocationPool.hh"
|
||||
#include "G4INCLSrcChannel.hh"
|
||||
|
||||
namespace G4INCL {
|
||||
class DeltaProductionChannel : public IChannel {
|
||||
public:
|
||||
DeltaProductionChannel(Particle *, Particle *);
|
||||
DeltaProductionChannel(Particle *, Particle *, Nucleus *n = nullptr);
|
||||
virtual ~DeltaProductionChannel();
|
||||
|
||||
void fillFinalState(FinalState *fs);
|
||||
@@ -56,6 +57,8 @@ namespace G4INCL {
|
||||
G4double sampleDeltaMass(G4double ecm);
|
||||
|
||||
Particle *particle1, *particle2;
|
||||
Nucleus *thenucleus;
|
||||
SrcChannel *srcChannel;
|
||||
|
||||
static const G4int maxTries;
|
||||
INCL_DECLARE_ALLOCATION_POOL(DeltaProductionChannel)
|
||||
|
||||
+9
-6
@@ -36,11 +36,12 @@
|
||||
#include "globals.hh"
|
||||
|
||||
|
||||
#include "G4INCLParticle.hh"
|
||||
#include "G4INCLNucleus.hh"
|
||||
#include "G4INCLIChannel.hh"
|
||||
#include "G4INCLFinalState.hh"
|
||||
#include "G4INCLAllocationPool.hh"
|
||||
#include "G4INCLFinalState.hh"
|
||||
#include "G4INCLIChannel.hh"
|
||||
#include "G4INCLNucleus.hh"
|
||||
#include "G4INCLParticle.hh"
|
||||
#include "G4INCLSrcChannel.hh"
|
||||
|
||||
#ifndef G4INCLElasticChannel_HH_
|
||||
#define G4INCLElasticChannel_HH_ 1
|
||||
@@ -49,17 +50,19 @@ namespace G4INCL {
|
||||
class ElasticChannel : public IChannel {
|
||||
|
||||
public:
|
||||
ElasticChannel(Particle *p1, Particle *p2);
|
||||
ElasticChannel(Particle *p1, Particle *p2, Nucleus *n = nullptr);
|
||||
virtual ~ElasticChannel();
|
||||
|
||||
void fillFinalState(FinalState *fs);
|
||||
|
||||
private:
|
||||
Particle *particle1, *particle2;
|
||||
Nucleus *thenucleus;
|
||||
SrcChannel *srcChannel;
|
||||
|
||||
INCL_DECLARE_ALLOCATION_POOL(ElasticChannel)
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace G4INCL
|
||||
|
||||
#endif
|
||||
|
||||
+30
-40
@@ -23,49 +23,39 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// INCL++ intra-nuclear cascade model
|
||||
// Alain Boudard, CEA-Saclay, France
|
||||
// Joseph Cugnon, University of Liege, Belgium
|
||||
// Jean-Christophe David, CEA-Saclay, France
|
||||
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
|
||||
// Sylvie Leray, CEA-Saclay, France
|
||||
// Davide Mancusi, CEA-Saclay, France
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
#define INCLXX_IN_GEANT4_MODE 1
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
#include "G4Solver.hh"
|
||||
#ifndef G4INCLEtaOrOmegaNToLKChannel_hh
|
||||
#define G4INCLEtaOrOmegaNToLKChannel_hh 1
|
||||
|
||||
template <class Function>
|
||||
G4Solver<Function>::G4Solver(const G4Solver & right)
|
||||
{
|
||||
MaxIter = right.MaxIter;
|
||||
tolerance = right.tolerance;
|
||||
a = right.a;
|
||||
b = right.b;
|
||||
root = right.root;
|
||||
#include "G4INCLParticle.hh"
|
||||
#include "G4INCLIChannel.hh"
|
||||
#include "G4INCLFinalState.hh"
|
||||
#include "G4INCLAllocationPool.hh"
|
||||
|
||||
namespace G4INCL {
|
||||
class EtaOrOmegaNToLKChannel : public IChannel {
|
||||
public:
|
||||
EtaOrOmegaNToLKChannel(Particle *, Particle *);
|
||||
virtual ~EtaOrOmegaNToLKChannel();
|
||||
|
||||
void fillFinalState(FinalState *fs);
|
||||
|
||||
private:
|
||||
Particle *particle1, *particle2;
|
||||
|
||||
INCL_DECLARE_ALLOCATION_POOL(EtaOrOmegaNToLKChannel);
|
||||
};
|
||||
}
|
||||
|
||||
// operators
|
||||
template <class Function>
|
||||
G4Solver<Function> & G4Solver<Function>::operator=(const G4Solver & right)
|
||||
{
|
||||
MaxIter = right.MaxIter;
|
||||
tolerance = right.tolerance;
|
||||
a = right.a;
|
||||
b = right.b;
|
||||
root = right.root;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
G4bool G4Solver<Function>::operator==(const G4Solver & right) const
|
||||
{
|
||||
if (this == &right) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
G4bool G4Solver<Function>::operator!=(const G4Solver & right) const
|
||||
{
|
||||
return !operator==(right);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
+31
-32
@@ -23,40 +23,39 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// INCL++ intra-nuclear cascade model
|
||||
// Alain Boudard, CEA-Saclay, France
|
||||
// Joseph Cugnon, University of Liege, Belgium
|
||||
// Jean-Christophe David, CEA-Saclay, France
|
||||
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
|
||||
// Sylvie Leray, CEA-Saclay, France
|
||||
// Davide Mancusi, CEA-Saclay, France
|
||||
//
|
||||
//
|
||||
// Hadronic Process: Nuclear De-excitations
|
||||
// by V. Lara
|
||||
#define INCLXX_IN_GEANT4_MODE 1
|
||||
|
||||
#include "G4VStatMFEnsemble.hh"
|
||||
#include "G4HadronicException.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
// Copy constructor
|
||||
G4VStatMFEnsemble::G4VStatMFEnsemble(const G4VStatMFEnsemble & )
|
||||
{
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4VStatMFEnsemble::copy_constructor meant to not be accessible");
|
||||
}
|
||||
|
||||
// Operators
|
||||
|
||||
G4VStatMFEnsemble & G4VStatMFEnsemble::
|
||||
operator=(const G4VStatMFEnsemble & )
|
||||
{
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4VStatMFEnsemble::operator= meant to not be accessible");
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
G4bool G4VStatMFEnsemble::operator==(const G4VStatMFEnsemble & ) const
|
||||
{
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4VStatMFEnsemble::operator== meant to not be accessible");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
G4bool G4VStatMFEnsemble::operator!=(const G4VStatMFEnsemble & ) const
|
||||
{
|
||||
throw G4HadronicException(__FILE__, __LINE__, "G4VStatMFEnsemble::operator!= meant to not be accessible");
|
||||
return true;
|
||||
#ifndef G4INCLEtaOrOmegaNToSKChannel_hh
|
||||
#define G4INCLEtaOrOmegaNToSKChannel_hh 1
|
||||
|
||||
#include "G4INCLParticle.hh"
|
||||
#include "G4INCLIChannel.hh"
|
||||
#include "G4INCLFinalState.hh"
|
||||
#include "G4INCLAllocationPool.hh"
|
||||
|
||||
namespace G4INCL {
|
||||
class EtaOrOmegaNToSKChannel : public IChannel {
|
||||
public:
|
||||
EtaOrOmegaNToSKChannel(Particle *, Particle *);
|
||||
virtual ~EtaOrOmegaNToSKChannel();
|
||||
|
||||
void fillFinalState(FinalState *fs);
|
||||
|
||||
private:
|
||||
Particle *particle1, *particle2;
|
||||
|
||||
INCL_DECLARE_ALLOCATION_POOL(EtaOrOmegaNToSKChannel);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -77,6 +77,8 @@ namespace G4INCL {
|
||||
* \return the ParticleEntryAvatar for the projectile particle
|
||||
**/
|
||||
virtual ParticleEntryAvatar *bringToSurface(Particle * const p, Nucleus * const n) const = 0;
|
||||
|
||||
virtual ParticleEntryAvatar *bringToSurfaceAbar(Particle * const p, Nucleus * const n) const = 0;
|
||||
|
||||
/** \brief Modify the momentum of an incoming cluster and position it on
|
||||
* the surface of the target.
|
||||
|
||||
@@ -90,12 +90,20 @@ namespace G4INCL {
|
||||
|
||||
/// \brief Cross section for EtaN->PiPiN
|
||||
virtual G4double etaNToPiPiN(Particle const * const p1, Particle const * const p2) = 0;
|
||||
|
||||
/// \brief Cross section for EtaN->LK/SK
|
||||
virtual G4double etaNToLK(Particle const * const p1, Particle const * const p2) = 0;
|
||||
virtual G4double etaNToSK(Particle const * const p1, Particle const * const p2) = 0;
|
||||
|
||||
/// \brief Cross section for OmegaN->PiN
|
||||
virtual G4double omegaNToPiN(Particle const * const p1, Particle const * const p2) = 0;
|
||||
|
||||
/// \brief Cross section for OmegaN->PiPiN
|
||||
virtual G4double omegaNToPiPiN(Particle const * const p1, Particle const * const p2) = 0;
|
||||
|
||||
/// \brief Cross section for OmegaN->LK/SK
|
||||
virtual G4double omegaNToLK(Particle const * const p1, Particle const * const p2) = 0;
|
||||
virtual G4double omegaNToSK(Particle const * const p1, Particle const * const p2) = 0;
|
||||
|
||||
/// \brief Cross section for EtaPrimeN->PiN
|
||||
virtual G4double etaPrimeNToPiN(Particle const * const p1, Particle const * const p2) = 0;
|
||||
|
||||
+1
@@ -85,6 +85,7 @@ namespace G4INCL {
|
||||
virtual G4double shootAtrest(ParticleType const t, const G4double kineticEnergy) = 0;
|
||||
virtual G4double shootParticle(ParticleType const t, const G4double kineticEnergy, const G4double impactParameter, const G4double phi) = 0;
|
||||
virtual G4double shootComposite(ParticleSpecies const &s, const G4double kineticEnergy, const G4double impactParameter, const G4double phi) = 0;
|
||||
virtual G4double shootCompositeAtrest(ParticleSpecies const &s, const G4double kineticEnergy) = 0;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
+23
-4
@@ -71,17 +71,30 @@ namespace G4INCL {
|
||||
|
||||
/// \brief Release the memory allocated for the backup particles
|
||||
static void deleteBackupParticles();
|
||||
|
||||
/**
|
||||
* static instance
|
||||
*/
|
||||
static InteractionAvatar* Instance();
|
||||
|
||||
protected:
|
||||
virtual G4INCL::IChannel* getChannel() = 0;
|
||||
|
||||
G4bool bringParticleInside(Particle * const p);
|
||||
void setSrcPartner(Particle *p /*, const ThreeVector m*/);
|
||||
|
||||
/** \brief Apply local-energy transformation, if appropriate
|
||||
*
|
||||
* \param p particle to apply the transformation to
|
||||
*/
|
||||
void preInteractionLocalEnergy(Particle * const p);
|
||||
|
||||
ThreeVector getboostVector(){return boostVector;}
|
||||
|
||||
void setboostVector(ThreeVector& v){boostVector = v;}
|
||||
|
||||
protected:
|
||||
virtual G4INCL::IChannel* getChannel() = 0;
|
||||
|
||||
G4bool bringParticleInside(Particle * const p);
|
||||
|
||||
EventInfo theEventInfo;
|
||||
|
||||
/** \brief Store the state of the particles before the interaction
|
||||
*
|
||||
@@ -99,6 +112,8 @@ namespace G4INCL {
|
||||
* The state must first be stored by calling preInteractionBlocking().
|
||||
*/
|
||||
void restoreParticles() const;
|
||||
|
||||
void restoreSrcPartner(FinalState * fs);
|
||||
|
||||
/// \brief true if the given avatar should use local energy
|
||||
G4bool shouldUseLocalEnergy() const;
|
||||
@@ -112,6 +127,10 @@ namespace G4INCL {
|
||||
G4double weight;
|
||||
|
||||
private:
|
||||
static G4ThreadLocal InteractionAvatar* interactionAvatar;
|
||||
static G4ThreadLocal Particle *backupPartner;
|
||||
static ThreeVector mbackupPartner;
|
||||
|
||||
/// \brief RootFunctor-derived object for enforcing energy conservation in N-N.
|
||||
class ViolationEMomentumFunctor : public RootFunctor {
|
||||
public:
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// INCL++ intra-nuclear cascade model
|
||||
// Alain Boudard, CEA-Saclay, France
|
||||
// Joseph Cugnon, University of Liege, Belgium
|
||||
// Jean-Christophe David, CEA-Saclay, France
|
||||
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
|
||||
// Sylvie Leray, CEA-Saclay, France
|
||||
// Davide Mancusi, CEA-Saclay, France
|
||||
//
|
||||
#define INCLXX_IN_GEANT4_MODE 1
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
/*
|
||||
* G4INCLNbarAtrestEntryChannel.hh
|
||||
*
|
||||
* \date Aug 21, 2024
|
||||
* \author Olivier Lourgo
|
||||
*/
|
||||
#include "G4INCLParticle.hh"
|
||||
#include "G4INCLIChannel.hh"
|
||||
#include "G4INCLNucleus.hh"
|
||||
#include "G4INCLAllocationPool.hh"
|
||||
#include "G4INCLFinalState.hh"
|
||||
#include "G4INCLICoulomb.hh"
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
#ifndef G4INCLNbarAtrestEntry_hh
|
||||
#define G4INCLNbarAtrestEntry_hh 1
|
||||
|
||||
namespace G4INCL{
|
||||
class FinalState;
|
||||
|
||||
class NbarAtrestEntryChannel :public IChannel {
|
||||
public :
|
||||
NbarAtrestEntryChannel(Nucleus *n, Particle *p);
|
||||
virtual ~NbarAtrestEntryChannel();
|
||||
|
||||
void fillFinalState(FinalState *fs);
|
||||
|
||||
ParticleList makeMesonStar();
|
||||
IAvatarList bringMesonStar(ParticleList const &pL, Nucleus * const n);
|
||||
G4bool ProtonIsTheVictim();
|
||||
ThreeVector getAnnihilationPosition();
|
||||
|
||||
G4double Pabs(G4double x, G4double value);
|
||||
G4double densityP();
|
||||
G4double densityN();
|
||||
G4double overlapP(G4double &x);
|
||||
G4double overlapN(G4double &x);
|
||||
G4double read_file(std::string filename, std::vector<G4double>& probabilities, std::vector<std::vector<std::string>>& particle_types);
|
||||
G4int findStringNumber(G4double rdm, std::vector<G4double> yields);
|
||||
|
||||
private:
|
||||
Nucleus *theNucleus;
|
||||
Particle *theParticle;
|
||||
|
||||
INCL_DECLARE_ALLOCATION_POOL(NbarAtrestEntryChannel)
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -87,6 +87,8 @@ namespace G4INCL {
|
||||
if(t==Composite) {
|
||||
return transmissionRadius[t] +
|
||||
ParticleTable::getNuclearRadius(t, p->getA(), p->getZ());
|
||||
} else if(t==antiComposite){
|
||||
return transmissionRadius[t] + ParticleTable::getNuclearRadius(t,-(p->getA()),-(p->getZ()));
|
||||
} else
|
||||
return transmissionRadius[t];
|
||||
};
|
||||
@@ -97,6 +99,7 @@ namespace G4INCL {
|
||||
*/
|
||||
G4double getTransmissionRadius(ParticleType type) const {
|
||||
// assert(type!=Composite);
|
||||
// assert(type!=antiComposite);
|
||||
return transmissionRadius[type];
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ namespace G4INCL {
|
||||
G4double vProton, vNeutron;
|
||||
G4double vDeltaPlusPlus, vDeltaPlus, vDeltaZero, vDeltaMinus;
|
||||
G4double vSigmaPlus, vSigmaZero, vSigmaMinus, vLambda;
|
||||
G4double vantiProton;
|
||||
G4double vantiProton, vantiNeutron;
|
||||
|
||||
void initialize();
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
namespace G4INCL {
|
||||
|
||||
enum AnnihilationType {Def=0, PType, NType, PTypeInFlight, NTypeInFlight, NbarPTypeInFlight, NbarNTypeInFlight};
|
||||
enum AnnihilationType {Def=0, PType, NType, PTypeInFlight, NTypeInFlight, NbarPTypeInFlight, NbarNTypeInFlight, DNbarNPbarPType, DNbarNPbarNType, DNbarPPbarPType, DNbarPPbarNType};
|
||||
|
||||
class Nucleus : public Cluster {
|
||||
public:
|
||||
@@ -94,6 +94,15 @@ namespace G4INCL {
|
||||
theNpInitial += Math::heaviside(ParticleTable::getIsospin(p->getType()));
|
||||
theNnInitial += Math::heaviside(-ParticleTable::getIsospin(p->getType()));
|
||||
}
|
||||
if(p->isLambda())
|
||||
theNlInitial++;
|
||||
if(p->getType() == SigmaPlus)
|
||||
theNSpInitial++;
|
||||
if(p->getType() == SigmaZero)
|
||||
theNSzInitial++;
|
||||
if(p->getType() == SigmaMinus)
|
||||
theNSmInitial++;
|
||||
|
||||
if(p->isPion()) {
|
||||
theNpionplusInitial += Math::heaviside(ParticleTable::getIsospin(p->getType()));
|
||||
theNpionminusInitial += Math::heaviside(-ParticleTable::getIsospin(p->getType()));
|
||||
@@ -103,7 +112,8 @@ namespace G4INCL {
|
||||
theNkaonminusInitial += Math::heaviside(-ParticleTable::getIsospin(p->getType()));
|
||||
}
|
||||
if(p->isAntiNucleon()) {
|
||||
theNantiprotonInitial += Math::heaviside(ParticleTable::getIsospin(p->getType()));
|
||||
if (p->getZ()<0) theNantiprotonInitial += Math::heaviside(-ParticleTable::getIsospin(p->getType()));
|
||||
else theNantineutronInitial += Math::heaviside(ParticleTable::getIsospin(p->getType()));
|
||||
}
|
||||
if(!p->isTargetSpectator()) theStore->getBook().incrementCascading();
|
||||
};
|
||||
@@ -129,6 +139,7 @@ namespace G4INCL {
|
||||
G4int getNumberOfEnteringPions() const { return theNpionplusInitial+theNpionminusInitial; };
|
||||
G4int getNumberOfEnteringKaons() const { return theNkaonplusInitial+theNkaonminusInitial; };
|
||||
G4int getNumberOfEnteringantiProtons() const { return theNantiprotonInitial; };
|
||||
G4int getNumberOfEnteringantiNeutrons() const { return theNantineutronInitial; };
|
||||
|
||||
/** \brief Outgoing - incoming separation energies.
|
||||
*
|
||||
@@ -158,16 +169,25 @@ namespace G4INCL {
|
||||
case SigmaPlus:
|
||||
case SigmaZero:
|
||||
case SigmaMinus:
|
||||
case antiProton:
|
||||
//case antiNeutron:
|
||||
//case antiLambda:
|
||||
S += thePotential->getSeparationEnergy(*i);
|
||||
break;
|
||||
case antiSigmaPlus:
|
||||
case antiSigmaZero:
|
||||
case antiSigmaMinus:
|
||||
case antiLambda:
|
||||
case antiProton:
|
||||
case antiNeutron:
|
||||
S -= thePotential->getSeparationEnergy(*i);
|
||||
break;
|
||||
case Composite:
|
||||
S += (*i)->getZ() * thePotential->getSeparationEnergy(Proton)
|
||||
+ ((*i)->getA() + (*i)->getS() - (*i)->getZ()) * thePotential->getSeparationEnergy(Neutron)
|
||||
- (*i)->getS() * thePotential->getSeparationEnergy(Lambda);
|
||||
break;
|
||||
case antiComposite:
|
||||
S -= (*i)->getZ() * thePotential->getSeparationEnergy(antiProton)
|
||||
+ ((*i)->getA() + (*i)->getS() - (*i)->getZ()) * thePotential->getSeparationEnergy(antiNeutron);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -175,11 +195,16 @@ namespace G4INCL {
|
||||
|
||||
S -= theNpInitial * thePotential->getSeparationEnergy(Proton);
|
||||
S -= theNnInitial * thePotential->getSeparationEnergy(Neutron);
|
||||
S -= theNlInitial * thePotential->getSeparationEnergy(Lambda);
|
||||
S -= theNSpInitial * thePotential->getSeparationEnergy(SigmaPlus);
|
||||
S -= theNSzInitial * thePotential->getSeparationEnergy(SigmaZero);
|
||||
S -= theNSmInitial * thePotential->getSeparationEnergy(SigmaMinus);
|
||||
S -= theNpionplusInitial*thePotential->getSeparationEnergy(PiPlus);;
|
||||
S -= theNkaonplusInitial*thePotential->getSeparationEnergy(KPlus);
|
||||
S -= theNpionminusInitial*thePotential->getSeparationEnergy(PiMinus);
|
||||
S -= theNkaonminusInitial*thePotential->getSeparationEnergy(KMinus);
|
||||
S -= theNantiprotonInitial*thePotential->getSeparationEnergy(antiProton);
|
||||
S += theNantiprotonInitial*thePotential->getSeparationEnergy(antiProton);
|
||||
S += theNantineutronInitial*thePotential->getSeparationEnergy(antiNeutron);
|
||||
return S;
|
||||
}
|
||||
|
||||
@@ -241,9 +266,15 @@ namespace G4INCL {
|
||||
|
||||
/// \brief Force emission of all Lambda (desexitation code with strangeness not implanted yet)
|
||||
G4int emitInsideLambda();
|
||||
|
||||
/// \brief Force emission of all Antilambda
|
||||
G4int emitInsideAntilambda();
|
||||
|
||||
/// \brief Force emission of all Kaon inside the nucleus
|
||||
G4bool emitInsideKaon();
|
||||
|
||||
/// \brief Force emission of all Antinucleon inside the nucleus
|
||||
G4bool emitInsideAnnihilationProducts();
|
||||
|
||||
/** \brief Compute the recoil momentum and spin of the nucleus. */
|
||||
void computeRecoilKinematics();
|
||||
@@ -319,6 +350,14 @@ namespace G4INCL {
|
||||
if((*i)->isLambda()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
///\brief Returns true if the nucleus contains any Antilambda.
|
||||
inline G4bool containsAntilambda() {
|
||||
ParticleList const &inside = theStore->getParticles();
|
||||
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
|
||||
if((*i)->isAntiLambda()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
///\brief Returns true if the nucleus contains any Sigma.
|
||||
inline G4bool containsSigma() {
|
||||
@@ -335,22 +374,50 @@ namespace G4INCL {
|
||||
if((*i)->isKaon()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
///\brief Returns true if the nucleus contains any Antinucleons.
|
||||
inline G4bool containsAntinucleon() {
|
||||
ParticleList const &inside = theStore->getParticles();
|
||||
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
|
||||
if((*i)->isAntiNucleon()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
///\brief Returns true if the nucleus contains any etas.
|
||||
inline G4bool containsEtas() {
|
||||
ParticleList const &inside = theStore->getParticles();
|
||||
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
|
||||
if((*i)->isEta()) return true;
|
||||
return false;
|
||||
}
|
||||
///\brief Returns true if the nucleus contains any etas.
|
||||
inline G4bool containsEtas() {
|
||||
ParticleList const &inside = theStore->getParticles();
|
||||
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
|
||||
if((*i)->isEta()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
///\brief Returns true if the nucleus contains any omegas.
|
||||
inline G4bool containsOmegas() {
|
||||
ParticleList const &inside = theStore->getParticles();
|
||||
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
|
||||
if((*i)->isOmega()) return true;
|
||||
return false;
|
||||
}
|
||||
///\brief Returns true if the nucleus contains any omegas.
|
||||
inline G4bool containsOmegas() {
|
||||
ParticleList const &inside = theStore->getParticles();
|
||||
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
|
||||
if((*i)->isOmega()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
///\brief Resets the src partners.
|
||||
inline void resetSrc(){
|
||||
ParticleList const &inside = theStore->getParticles();
|
||||
for(ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
|
||||
(*i)->resetSrcPartner();
|
||||
}
|
||||
|
||||
inline void setSrcInternalEnergy(double value){
|
||||
srcInternalEnergy = value;
|
||||
}
|
||||
|
||||
inline void updateInternalEnergy(double value){
|
||||
initialInternalEnergy += value;
|
||||
}
|
||||
|
||||
G4double getSrcInternalEnergy() const {
|
||||
return srcInternalEnergy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -398,6 +465,8 @@ namespace G4INCL {
|
||||
G4double energy;
|
||||
G4int Z, A, S;
|
||||
};
|
||||
|
||||
void restoreSrcPartner(Particle *particle, ThreeVector m);
|
||||
|
||||
/// \brief Compute charge, mass, energy and momentum balance
|
||||
ConservationBalance getConservationBalance(EventInfo const &theEventInfo, const G4bool afterRecoil) const;
|
||||
@@ -509,6 +578,11 @@ namespace G4INCL {
|
||||
G4int theNpInitial;
|
||||
/// \brief The number of entering neutrons
|
||||
G4int theNnInitial;
|
||||
/// \brief The number of entering hyperons
|
||||
G4int theNlInitial;
|
||||
G4int theNSpInitial;
|
||||
G4int theNSzInitial;
|
||||
G4int theNSmInitial;
|
||||
/// \brief The number of entering pions
|
||||
G4int theNpionplusInitial;
|
||||
G4int theNpionminusInitial;
|
||||
@@ -517,8 +591,11 @@ namespace G4INCL {
|
||||
G4int theNkaonminusInitial;
|
||||
/// \brief The number of entering antiprotons
|
||||
G4int theNantiprotonInitial;
|
||||
/// \brief The number of entering antineutrons
|
||||
G4int theNantineutronInitial;
|
||||
|
||||
G4double initialInternalEnergy;
|
||||
G4double srcInternalEnergy;
|
||||
ThreeVector incomingAngularMomentum, incomingMomentum;
|
||||
ThreeVector initialCenterOfMass;
|
||||
G4bool remnant;
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@
|
||||
|
||||
namespace G4INCL {
|
||||
|
||||
enum EntryType{Default, APAR}; //D
|
||||
enum EntryType{Default, APAR, ANAR, ADAR}; //D
|
||||
|
||||
class ParticleEntryAvatar: public G4INCL::IAvatar {
|
||||
public:
|
||||
|
||||
+1
-1
@@ -197,7 +197,7 @@ namespace G4INCL {
|
||||
}
|
||||
|
||||
std::sort(energies.begin(), energies.end());
|
||||
// assert(energies.size()==(unsigned int)theA);
|
||||
//assert(energies.size()==(unsigned int)theA || energies.size()== (unsigned int)-theA);
|
||||
theGroundStateEnergies.resize(energies.size());
|
||||
// Compute the partial sums of the CM energies -- they are our reference
|
||||
// ground-state energies for any number of nucleons
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// INCL++ intra-nuclear cascade model
|
||||
// Alain Boudard, CEA-Saclay, France
|
||||
// Joseph Cugnon, University of Liege, Belgium
|
||||
// Jean-Christophe David, CEA-Saclay, France
|
||||
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
|
||||
// Sylvie Leray, CEA-Saclay, France
|
||||
// Davide Mancusi, CEA-Saclay, France
|
||||
//
|
||||
#define INCLXX_IN_GEANT4_MODE 1
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
/*
|
||||
* \file G4INCLSrcChannel.hh
|
||||
*
|
||||
* \date Feb 24, 2022
|
||||
* \author Jose Luis Rodriguez-Sanchez
|
||||
*/
|
||||
|
||||
#include "G4INCLAllocationPool.hh"
|
||||
#include "G4INCLFinalState.hh"
|
||||
#include "G4INCLIChannel.hh"
|
||||
#include "G4INCLNucleus.hh"
|
||||
#include "G4INCLParticle.hh"
|
||||
|
||||
#include "G4INCLEventInfo.hh"
|
||||
|
||||
#ifndef G4INCLSrcChannel_HH
|
||||
#define G4INCLSrcChannel_HH 1
|
||||
|
||||
namespace G4INCL {
|
||||
class SrcChannel : public IChannel {
|
||||
|
||||
public:
|
||||
SrcChannel(Particle *p1, Particle *p2, Nucleus *n);
|
||||
virtual ~SrcChannel();
|
||||
|
||||
void fillFinalState(FinalState *fs);
|
||||
void fillFinalState(FinalState *fs, ParticleType , ParticleType);
|
||||
|
||||
private:
|
||||
Particle *particle1, *particle2;
|
||||
ParticleType ftype1, ftype2;
|
||||
Particle *srcpartner;
|
||||
Nucleus *thenucleus;
|
||||
double fDistSrc;
|
||||
|
||||
EventInfo theEventInfo;
|
||||
|
||||
/**
|
||||
* Compute the current number of src pairs.
|
||||
*/
|
||||
Particle *findpairpartner(Particle *pt);
|
||||
|
||||
INCL_DECLARE_ALLOCATION_POOL(SrcChannel)
|
||||
};
|
||||
|
||||
} // namespace G4INCL
|
||||
|
||||
#endif /* G4INCLSrcChannel_HH */
|
||||
+2
-1
@@ -85,7 +85,8 @@ namespace G4INCL {
|
||||
G4double shoot(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy, const G4double impactParameter, const G4double phi);
|
||||
G4double shootParticle(ParticleType const t, const G4double kineticEnergy, const G4double impactParameter, const G4double phi);
|
||||
G4double shootComposite(ParticleSpecies const &s, const G4double kineticEnergy, const G4double impactParameter, const G4double phi);
|
||||
G4double shootAtrest(ParticleType const t, const G4double kineticEnergy);
|
||||
G4double shootAtrest(ParticleType const t, const G4double kineticEnergy);
|
||||
G4double shootCompositeAtrest(ParticleSpecies const &s, const G4double kineticEnergy);
|
||||
|
||||
/**
|
||||
* Set the stopping time of the simulation.
|
||||
|
||||
@@ -197,6 +197,12 @@ namespace G4INCL {
|
||||
for(ParticleIter p=pl.begin(), e=pl.end(); p!=e; ++p)
|
||||
addToOutgoing(*p);
|
||||
}
|
||||
|
||||
/** \brief add the particle to the missed particle list (for dbar).
|
||||
*
|
||||
* \param p pointer to the particle to be added
|
||||
*/
|
||||
void addToMissed(Particle *p) { missed.push_back(p); }
|
||||
|
||||
/**
|
||||
* Remove the particle from the system. This also removes all
|
||||
@@ -221,6 +227,12 @@ namespace G4INCL {
|
||||
* cascade).
|
||||
*/
|
||||
ParticleList const & getOutgoingParticles() const { return outgoing; }
|
||||
|
||||
/**
|
||||
* Return the list of missed particles (i.e. particles that have missed the
|
||||
* nucleus and so do not participate in the cascade, only for dbar).
|
||||
*/
|
||||
ParticleList const & getMissedParticles() const { return missed; }
|
||||
|
||||
/** \brief Returns a list of dynamical spectators
|
||||
*
|
||||
@@ -233,7 +245,7 @@ namespace G4INCL {
|
||||
ParticleList spectators;
|
||||
for(ParticleIter p=outgoing.begin(), e=outgoing.end(); p!=e; ++p) {
|
||||
if((*p)->isProjectileSpectator()) {
|
||||
// assert((*p)->isNucleon() || (*p)->isLambda());
|
||||
// assert((*p)->isNucleon() || (*p)->isLambda() || (*p)->isAntiNucleon());
|
||||
spectators.push_back(*p); // add them to the list we will return
|
||||
}
|
||||
}
|
||||
@@ -251,6 +263,12 @@ namespace G4INCL {
|
||||
* participate in collisions).
|
||||
*/
|
||||
ParticleList const & getParticles() const { return inside; }
|
||||
|
||||
/**
|
||||
* Return the list of "active" particles (i.e. particles that can
|
||||
* participate in collisions) to define the src-pairs.
|
||||
*/
|
||||
ParticleList & getParticlesforSrc() { return inside; }
|
||||
|
||||
/**
|
||||
* Return the pointer to the Book object which keeps track of
|
||||
@@ -425,6 +443,11 @@ namespace G4INCL {
|
||||
* List of outgoing particles
|
||||
*/
|
||||
ParticleList outgoing;
|
||||
|
||||
/**
|
||||
* List of missed particles (for dbar)
|
||||
*/
|
||||
ParticleList missed;
|
||||
|
||||
/**
|
||||
* List of geometrical spectators
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Define the Geant4 Module.
|
||||
geant4_add_module(G4hadronic_inclxx_physics
|
||||
PUBLIC_HEADERS
|
||||
G4INCLAntinucleiAtrestEntryChannel.hh
|
||||
G4INCLAvatarDumpAction.hh
|
||||
G4INCLBinaryCollisionAvatar.hh
|
||||
G4INCLCascade.hh
|
||||
@@ -33,6 +34,8 @@ geant4_add_module(G4hadronic_inclxx_physics
|
||||
G4INCLEtaNElasticChannel.hh
|
||||
G4INCLEtaNToPiNChannel.hh
|
||||
G4INCLEtaNToPiPiNChannel.hh
|
||||
G4INCLEtaOrOmegaNToLKChannel.hh
|
||||
G4INCLEtaOrOmegaNToSKChannel.hh
|
||||
G4INCLIClusteringModel.hh
|
||||
G4INCLICoulomb.hh
|
||||
G4INCLICrossSections.hh
|
||||
@@ -42,6 +45,7 @@ geant4_add_module(G4hadronic_inclxx_physics
|
||||
G4INCLIPhaseSpaceGenerator.hh
|
||||
G4INCLIPropagationModel.hh
|
||||
G4INCLKinematicsUtils.hh
|
||||
G4INCLNbarAtrestEntryChannel.hh
|
||||
G4INCLNDeltaEtaProductionChannel.hh
|
||||
G4INCLNDeltaOmegaProductionChannel.hh
|
||||
G4INCLNDeltaToDeltaLKChannel.hh
|
||||
@@ -131,12 +135,14 @@ geant4_add_module(G4hadronic_inclxx_physics
|
||||
G4INCLRecombinationChannel.hh
|
||||
G4INCLReflectionChannel.hh
|
||||
G4INCLSigmaZeroDecayChannel.hh
|
||||
G4INCLSrcChannel.hh
|
||||
G4INCLStandardPropagationModel.hh
|
||||
G4INCLStore.hh
|
||||
G4INCLStrangeAbsorbtionChannel.hh
|
||||
G4INCLSurfaceAvatar.hh
|
||||
G4INCLTransmissionChannel.hh
|
||||
SOURCES
|
||||
G4INCLAntinucleiAtrestEntryChannel.cc
|
||||
G4INCLAvatarDumpAction.cc
|
||||
G4INCLBinaryCollisionAvatar.cc
|
||||
G4INCLCascade.cc
|
||||
@@ -165,9 +171,12 @@ geant4_add_module(G4hadronic_inclxx_physics
|
||||
G4INCLEtaNElasticChannel.cc
|
||||
G4INCLEtaNToPiNChannel.cc
|
||||
G4INCLEtaNToPiPiNChannel.cc
|
||||
G4INCLEtaOrOmegaNToLKChannel.cc
|
||||
G4INCLEtaOrOmegaNToSKChannel.cc
|
||||
G4INCLInteractionAvatar.cc
|
||||
G4INCLINuclearPotential.cc
|
||||
G4INCLKinematicsUtils.cc
|
||||
G4INCLNbarAtrestEntryChannel.cc
|
||||
G4INCLNDeltaEtaProductionChannel.cc
|
||||
G4INCLNDeltaOmegaProductionChannel.cc
|
||||
G4INCLNDeltaToDeltaLKChannel.cc
|
||||
@@ -252,6 +261,7 @@ geant4_add_module(G4hadronic_inclxx_physics
|
||||
G4INCLRecombinationChannel.cc
|
||||
G4INCLReflectionChannel.cc
|
||||
G4INCLSigmaZeroDecayChannel.cc
|
||||
G4INCLSrcChannel.cc
|
||||
G4INCLStandardPropagationModel.cc
|
||||
G4INCLStore.cc
|
||||
G4INCLStrangeAbsorbtionChannel.cc
|
||||
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// INCL++ intra-nuclear cascade model
|
||||
// Alain Boudard, CEA-Saclay, France
|
||||
// Joseph Cugnon, University of Liege, Belgium
|
||||
// Jean-Christophe David, CEA-Saclay, France
|
||||
// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
|
||||
// Sylvie Leray, CEA-Saclay, France
|
||||
// Davide Mancusi, CEA-Saclay, France
|
||||
//
|
||||
#define INCLXX_IN_GEANT4_MODE 1
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
/*
|
||||
* G4INCLAntinucleiAtrestEntryChannel.cc
|
||||
*
|
||||
*
|
||||
* \author Olivier Lourgo
|
||||
*/
|
||||
#include "G4INCLAntinucleiAtrestEntryChannel.hh"
|
||||
#include "G4INCLNbarAtrestEntryChannel.hh"
|
||||
#include "G4INCLPbarAtrestEntryChannel.hh"
|
||||
#include "G4INCLPhaseSpaceGenerator.hh"
|
||||
|
||||
|
||||
namespace G4INCL{
|
||||
|
||||
AntinucleiAtrestEntryChannel::AntinucleiAtrestEntryChannel(Nucleus *n, Cluster *ac, ThreeVector pos1, ThreeVector pos2)
|
||||
:theNucleus(n), theantiComposite(ac), Posnbar(pos1), Pospbar(pos2){}
|
||||
|
||||
AntinucleiAtrestEntryChannel::AntinucleiAtrestEntryChannel(Nucleus *n, Particle *p):theNucleus(n),Meson(p){}
|
||||
|
||||
AntinucleiAtrestEntryChannel::~AntinucleiAtrestEntryChannel(){}
|
||||
|
||||
ThreeVector AntinucleiAtrestEntryChannel::getAnnihilationPosition(ThreeVector nbarPos, ThreeVector pbarPos){ //Choose between the pbar or nbar annihilation position
|
||||
if((nbarPos - pbarPos).mag2() <= ParticleTable::getLargestNuclearRadius(-theantiComposite->getA(),- theantiComposite->getZ())){
|
||||
//If the annihilions positions are close (the radius of a deuteron) then we have 2 sources for the meson star
|
||||
return ThreeVector(999.,999.,999.);
|
||||
}
|
||||
if(nbarPos.mag2() <= pbarPos.mag2())
|
||||
return nbarPos;
|
||||
else
|
||||
return pbarPos;
|
||||
}
|
||||
|
||||
ParticleList AntinucleiAtrestEntryChannel::makeMesonStar(){
|
||||
ParticleList Antiparticles = theantiComposite->getParticles();
|
||||
Particle *nbar=nullptr;
|
||||
Particle *pbar=nullptr;
|
||||
for(ParticleIter p =Antiparticles.begin(), e=Antiparticles.end(); p!=e; ++p){
|
||||
if((*p)->getType()==antiProton)
|
||||
pbar = *p;
|
||||
else if((*p)->getType()==antiNeutron)
|
||||
nbar = *p;
|
||||
else
|
||||
INCL_ERROR("ERROR : something else than antiNeutron or antiProton in antiComposite");
|
||||
}
|
||||
PbarAtrestEntryChannel *pbarChannel = new PbarAtrestEntryChannel(theNucleus, pbar);
|
||||
NbarAtrestEntryChannel *nbarChannel = new NbarAtrestEntryChannel(theNucleus, nbar);
|
||||
|
||||
ParticleList TotalStarList = pbarChannel->makeMesonStar(); //pbar in first because polarisation of the dbar (Coulomb)
|
||||
ParticleList nbarMesonStar = nbarChannel->makeMesonStar();
|
||||
pbarListSize = (G4int)TotalStarList.size();
|
||||
|
||||
for(ParticleIter p=nbarMesonStar.begin(), e=nbarMesonStar.end(); p!=e; ++p){
|
||||
TotalStarList.push_back(*p);
|
||||
}
|
||||
Pospbar = pbarChannel->getAnnihilationPosition();
|
||||
Posnbar = nbarChannel->getAnnihilationPosition();
|
||||
|
||||
G4double EnergyofFinalMesonStar = 0;
|
||||
G4int a=theNucleus->getA();
|
||||
G4int z=theNucleus->getZ();
|
||||
G4int stra=theNucleus->getS();
|
||||
if(theNucleus->getAnnihilationType()==DNbarPPbarPType){
|
||||
EnergyofFinalMesonStar = theantiComposite->getMass() + (ParticleTable::getTableMass(a+2,z+2,stra)- ParticleTable::getTableMass(a,z+1,stra));
|
||||
}
|
||||
else if(theNucleus->getAnnihilationType()==DNbarPPbarNType || theNucleus->getAnnihilationType()==DNbarNPbarPType){
|
||||
//Correction for all but they all cancel out !
|
||||
EnergyofFinalMesonStar = theantiComposite->getMass() + (ParticleTable::getTableMass(a+2,z+1,stra)- ParticleTable::getTableMass(a,z,stra));
|
||||
|
||||
}
|
||||
else if(theNucleus->getAnnihilationType()==DNbarNPbarNType){
|
||||
EnergyofFinalMesonStar = theantiComposite->getMass() + (ParticleTable::getTableMass(a+2,z,stra) - ParticleTable::getTableMass(a,z-1,stra));
|
||||
}
|
||||
PhaseSpaceGenerator::generate(EnergyofFinalMesonStar, TotalStarList);
|
||||
|
||||
return TotalStarList;
|
||||
}
|
||||
|
||||
IAvatarList AntinucleiAtrestEntryChannel::bringMesonStar(ParticleList const &pL, Nucleus * const n){
|
||||
ThreeVector ann_position = getAnnihilationPosition(Posnbar,Pospbar);
|
||||
IAvatarList theAvatarList;
|
||||
G4int cnt=1;
|
||||
if (ann_position.getX() == 999. && ann_position.getY() == 999. && ann_position.getZ() == 999.){
|
||||
INCL_DEBUG("Particle are close to each other : 2 sources of annihilation "<< '\n');
|
||||
for(ParticleIter p=pL.begin(), e=pL.end(); p!=e; ++p){
|
||||
if(cnt <= pbarListSize){
|
||||
(*p)->setPosition(Pospbar);
|
||||
}
|
||||
else
|
||||
(*p)->setPosition(Posnbar);
|
||||
theAvatarList.push_back(new ParticleEntryAvatar(0.0, n, *p, ADAR));
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(ParticleIter p=pL.begin(), e=pL.end(); p!=e; ++p){
|
||||
(*p)->setPosition(ann_position);
|
||||
theAvatarList.push_back(new ParticleEntryAvatar(0.0, n, *p, ADAR));
|
||||
}
|
||||
}
|
||||
return theAvatarList;
|
||||
}
|
||||
|
||||
void AntinucleiAtrestEntryChannel::fillFinalState(FinalState *fs){
|
||||
const G4double energyBefore = Meson->getEnergy();
|
||||
fs->addEnteringParticle(Meson);
|
||||
INCL_DEBUG("Entering antiComposite annihilation product added " << '\n');
|
||||
fs->setTotalEnergyBeforeInteraction(energyBefore);
|
||||
}
|
||||
}
|
||||
|
||||
+214
-7
@@ -68,6 +68,8 @@
|
||||
#include "G4INCLEtaNToPiPiNChannel.hh"
|
||||
#include "G4INCLOmegaNElasticChannel.hh"
|
||||
#include "G4INCLOmegaNToPiNChannel.hh"
|
||||
#include "G4INCLEtaOrOmegaNToLKChannel.hh"
|
||||
#include "G4INCLEtaOrOmegaNToSKChannel.hh"
|
||||
#include "G4INCLNNToNLKChannel.hh"
|
||||
#include "G4INCLNNToNSKChannel.hh"
|
||||
#include "G4INCLNNToNLKpiChannel.hh"
|
||||
@@ -141,6 +143,67 @@ namespace G4INCL {
|
||||
|
||||
BinaryCollisionAvatar::~BinaryCollisionAvatar() {
|
||||
}
|
||||
|
||||
void BinaryCollisionAvatar::generateSrcPairsMethod(ParticleList &theList,
|
||||
const G4int theN,
|
||||
const G4int theZ,
|
||||
G4INCL::Particle *p1,
|
||||
G4INCL::Particle *p2) {
|
||||
|
||||
std::vector<ThreeVector> posp;
|
||||
std::vector<ThreeVector> posn;
|
||||
posp.resize(theZ);
|
||||
posn.resize(theN);
|
||||
|
||||
for (int i = 0; i < theZ + theN; ++i) {
|
||||
theList[i]->setNumberOfSrcPair(0);
|
||||
}
|
||||
theNucleus->getStore()->getBook().setSrcPairs(0);
|
||||
|
||||
// Check that the loops in theZ and theN do what we wish!
|
||||
G4int npairs = 0;
|
||||
for (G4int i = 0; i < theZ; ++i) {
|
||||
Particle *ap = theList[i];
|
||||
posp[i] = ap->getPosition();
|
||||
for (G4int j = 0; j < theN; ++j) {
|
||||
Particle *an = theList[j + theZ];
|
||||
posn[j] = an->getPosition();
|
||||
if ((posn[j] - posp[i]).mag() < ParticleTable::getsrcPairDistance() &&
|
||||
ap->getSrcPair() == 0 && an->getSrcPair() == 0 &&
|
||||
ap->getType() != an->getType() && ap->isTargetSpectator() == 1 &&
|
||||
an->isTargetSpectator() == 1) {
|
||||
npairs++;
|
||||
theNucleus->getStore()->getBook().incrementSrcPairs();
|
||||
if (an == p1 || an == p2 || ap == p1 || ap == p2) {
|
||||
theList[i]->setNumberOfSrcPair(npairs);
|
||||
theList[j + theZ]->setNumberOfSrcPair(npairs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
G4int nbp = 0, nbn = 0;
|
||||
for (G4int i = 0; i < theZ + theN; ++i) {
|
||||
|
||||
if (theList[i]->getSrcPair() > 0 && theList[i]->getType() == Proton)
|
||||
nbp++;
|
||||
|
||||
if (theList[i]->getSrcPair() > 0 && theList[i]->getType() == Neutron)
|
||||
nbn++;
|
||||
}
|
||||
|
||||
if (nbp != nbn) {
|
||||
INCL_DEBUG("Pairs: " << nbp << " " << nbn << '\n');
|
||||
for (G4int i = 0; i < theZ; ++i) {
|
||||
INCL_DEBUG(ParticleTable::getName(theList[i]->getType())
|
||||
<< " " << theList[i]->isTargetSpectator() << " "
|
||||
<< theList[i]->getSrcPair());
|
||||
}
|
||||
INCL_DEBUG("----------- End ------------------" << '\n');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
G4INCL::IChannel* BinaryCollisionAvatar::getChannel() {
|
||||
// We already check cutNN at avatar creation time, but we have to check it
|
||||
@@ -182,12 +245,21 @@ namespace G4INCL {
|
||||
minimumDistance -= particle2->getPosition();
|
||||
const G4double betaDotX = boostVector.dot(minimumDistance);
|
||||
const G4double minDist = Math::tenPi*(minimumDistance.mag2() + betaDotX*betaDotX / (1.-boostVector.mag2()));
|
||||
if(minDist > theCrossSection) {
|
||||
|
||||
Config const *theConfig=theNucleus->getStore()->getConfig();
|
||||
if ((minDist > theCrossSection) &&
|
||||
(!((particle1->getType()==antiProton && particle1->getKineticEnergy() <= theConfig->getAtrestThreshold()) ||
|
||||
(particle2->getType()==antiProton && particle2->getKineticEnergy() <= theConfig->getAtrestThreshold()) ||
|
||||
(particle1->getType()==antiNeutron && particle1->getKineticEnergy() <= particle1->getPotentialEnergy()) ||
|
||||
(particle2->getType()==antiNeutron && particle2->getKineticEnergy() <= particle2->getPotentialEnergy())))) {
|
||||
if(!((particle1->isAntiNucleon() && particle1->getEnergy() <= particle1->getINCLMass()) ||
|
||||
(particle2->isAntiNucleon() && particle2->getEnergy() <= particle2->getINCLMass()))){
|
||||
INCL_DEBUG("CM distance of approach is too small: " << minDist << ">" <<
|
||||
theCrossSection <<"; returning a NULL channel" << '\n');
|
||||
InteractionAvatar::restoreParticles();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/** Bias apply for this reaction in order to get the same
|
||||
* ParticleBias for all stange particles.
|
||||
@@ -261,15 +333,50 @@ namespace G4INCL {
|
||||
if(elasticCX > rChannel) {
|
||||
// Elastic NN channel
|
||||
isElastic = true;
|
||||
weight = counterweight;
|
||||
if (theNucleus->getStore()->getBook().getAcceptedCollisions() == 0 &&
|
||||
theNucleus->getStore()->getBook().getAcceptedSrcCollisions() == 0 &&
|
||||
ParticleTable::getsrcPairConfig()) {
|
||||
INCL_DEBUG("NN-SRC interaction: elastic channel chosen" << '\n');
|
||||
ParticleList &inside = theNucleus->getStore()->getParticlesforSrc();
|
||||
G4int zz = theNucleus->getZ();
|
||||
generateSrcPairsMethod(inside, theNucleus->getA() - zz, zz, particle1,
|
||||
particle2);
|
||||
if ((particle1->getSrcPair() > 0 || particle2->getSrcPair() > 0)) {
|
||||
return new ElasticChannel(particle1, particle2, theNucleus);
|
||||
} else {
|
||||
INCL_DEBUG("NN interaction: elastic channel chosen" << '\n');
|
||||
theNucleus->resetSrc();
|
||||
return new ElasticChannel(particle1, particle2);
|
||||
}
|
||||
} else {
|
||||
INCL_DEBUG("NN interaction: elastic channel chosen" << '\n');
|
||||
weight = counterweight;
|
||||
return new ElasticChannel(particle1, particle2);
|
||||
}
|
||||
} else if((elasticCX + deltaProductionCX) > rChannel) {
|
||||
isElastic = false;
|
||||
// NN -> N Delta channel is chosen
|
||||
weight = counterweight;
|
||||
if (theNucleus->getStore()->getBook().getAcceptedCollisions() == 0 &&
|
||||
theNucleus->getStore()->getBook().getAcceptedSrcCollisions() == 0 &&
|
||||
ParticleTable::getsrcPairConfig()) {
|
||||
INCL_DEBUG("NN-SRC interaction: Delta channel chosen" << '\n');
|
||||
ParticleList &inside = theNucleus->getStore()->getParticlesforSrc();
|
||||
G4int zz = theNucleus->getZ();
|
||||
generateSrcPairsMethod(inside, theNucleus->getA() - zz, zz, particle1,
|
||||
particle2);
|
||||
|
||||
if ((particle1->getSrcPair() > 0 || particle2->getSrcPair() > 0)) {
|
||||
return new DeltaProductionChannel(particle1, particle2, theNucleus);
|
||||
} else {
|
||||
INCL_DEBUG("NN interaction: Delta channel chosen" << '\n');
|
||||
theNucleus->resetSrc();
|
||||
return new DeltaProductionChannel(particle1, particle2);
|
||||
}
|
||||
} else {
|
||||
INCL_DEBUG("NN interaction: Delta channel chosen" << '\n');
|
||||
weight = counterweight;
|
||||
return new DeltaProductionChannel(particle1, particle2);
|
||||
}
|
||||
} else if(elasticCX + deltaProductionCX + onePiProductionCX > rChannel) {
|
||||
isElastic = false;
|
||||
// NN -> PiNN channel is chosen
|
||||
@@ -948,8 +1055,10 @@ namespace G4INCL {
|
||||
const G4double elasticCX = CrossSections::elastic(particle1, particle2);
|
||||
const G4double onePiProductionCX = CrossSections::etaNToPiN(particle1, particle2);
|
||||
const G4double twoPiProductionCX = CrossSections::etaNToPiPiN(particle1, particle2);
|
||||
const G4double LKProductionCX = CrossSections::etaNToLK(particle1, particle2);
|
||||
const G4double SKProductionCX = CrossSections::etaNToSK(particle1, particle2);
|
||||
const G4double totCX=CrossSections::total(particle1, particle2);
|
||||
// assert(std::fabs(totCX-elasticCX-onePiProductionCX-twoPiProductionCX)<1.);
|
||||
// assert(std::fabs(totCX-elasticCX-onePiProductionCX-twoPiProductionCX)-LKProductionCX-SKProductionCX<1.);
|
||||
|
||||
const G4double rChannel=Random::shoot() * totCX;
|
||||
|
||||
@@ -968,11 +1077,29 @@ namespace G4INCL {
|
||||
// EtaN -> EtaPiPiN channel is chosen
|
||||
INCL_DEBUG("EtaN interaction: PiPiN channel chosen" << '\n');
|
||||
return new EtaNToPiPiNChannel(particle1, particle2);
|
||||
} else if(elasticCX + onePiProductionCX + twoPiProductionCX + LKProductionCX > rChannel) {
|
||||
isElastic = false;
|
||||
// EtaN -> LK channel is chosen
|
||||
INCL_DEBUG("EtaN interaction: LK channel chosen" << '\n');
|
||||
return new EtaOrOmegaNToLKChannel(particle1, particle2);
|
||||
} else if(elasticCX + onePiProductionCX + twoPiProductionCX + LKProductionCX + SKProductionCX > rChannel) {
|
||||
isElastic = false;
|
||||
// EtaN -> SK channel is chosen
|
||||
INCL_DEBUG("EtaN interaction: SK channel chosen" << '\n');
|
||||
return new EtaOrOmegaNToSKChannel(particle1, particle2);
|
||||
}
|
||||
|
||||
else {
|
||||
INCL_WARN("inconsistency within the EtaN Cross Sections (sum!=inelastic)" << '\n');
|
||||
if(twoPiProductionCX>0.) {
|
||||
if(SKProductionCX>0.) {
|
||||
INCL_WARN("Returning a SK channel" << '\n');
|
||||
isElastic = false;
|
||||
return new EtaOrOmegaNToSKChannel(particle1, particle2);
|
||||
} else if(LKProductionCX>0.) {
|
||||
INCL_WARN("Returning a LK channel" << '\n');
|
||||
isElastic = false;
|
||||
return new EtaOrOmegaNToLKChannel(particle1, particle2);
|
||||
} else if(twoPiProductionCX>0.) {
|
||||
INCL_WARN("Returning a PiPiN channel" << '\n');
|
||||
isElastic = false;
|
||||
return new EtaNToPiPiNChannel(particle1, particle2);
|
||||
@@ -993,8 +1120,10 @@ namespace G4INCL {
|
||||
const G4double elasticCX = CrossSections::elastic(particle1, particle2);
|
||||
const G4double onePiProductionCX = CrossSections::omegaNToPiN(particle1, particle2);
|
||||
const G4double twoPiProductionCX = CrossSections::omegaNToPiPiN(particle1, particle2);
|
||||
const G4double LKProductionCX = CrossSections::omegaNToLK(particle1, particle2);
|
||||
const G4double SKProductionCX = CrossSections::omegaNToSK(particle1, particle2);
|
||||
const G4double totCX=CrossSections::total(particle1, particle2);
|
||||
// assert(std::fabs(totCX-elasticCX-onePiProductionCX-twoPiProductionCX)<1.);
|
||||
// assert(std::fabs(totCX-elasticCX-onePiProductionCX-twoPiProductionCX + LKProductionCX + SKProductionCX)<1.);
|
||||
|
||||
const G4double rChannel=Random::shoot() * totCX;
|
||||
|
||||
@@ -1013,10 +1142,28 @@ namespace G4INCL {
|
||||
// OmegaN -> PiPiN channel is chosen
|
||||
INCL_DEBUG("OmegaN interaction: PiPiN channel chosen" << '\n');
|
||||
return new OmegaNToPiPiNChannel(particle1, particle2);
|
||||
} else if(elasticCX + onePiProductionCX + twoPiProductionCX + LKProductionCX > rChannel) {
|
||||
isElastic = false;
|
||||
// OmegaN -> LK channel is chosen
|
||||
INCL_DEBUG("EtaN interaction: LK channel chosen" << '\n');
|
||||
return new EtaOrOmegaNToLKChannel(particle1, particle2);
|
||||
} else if(elasticCX + onePiProductionCX + twoPiProductionCX + LKProductionCX + SKProductionCX > rChannel) {
|
||||
isElastic = false;
|
||||
// OmegaN -> SK channel is chosen
|
||||
INCL_DEBUG("EtaN interaction: SK channel chosen" << '\n');
|
||||
return new EtaOrOmegaNToSKChannel(particle1, particle2);
|
||||
}
|
||||
else {
|
||||
INCL_WARN("inconsistency within the OmegaN Cross Sections (sum!=inelastic)" << '\n');
|
||||
if(twoPiProductionCX>0.) {
|
||||
if(SKProductionCX>0.) {
|
||||
INCL_WARN("Returning a SK channel" << '\n');
|
||||
isElastic = false;
|
||||
return new EtaOrOmegaNToSKChannel(particle1, particle2);
|
||||
} else if(LKProductionCX>0.) {
|
||||
INCL_WARN("Returning a LK channel" << '\n');
|
||||
isElastic = false;
|
||||
return new EtaOrOmegaNToLKChannel(particle1, particle2);
|
||||
} else if(twoPiProductionCX>0.) {
|
||||
INCL_WARN("Returning a PiPiN channel" << '\n');
|
||||
isElastic = false;
|
||||
return new OmegaNToPiPiNChannel(particle1, particle2);
|
||||
@@ -1242,6 +1389,66 @@ namespace G4INCL {
|
||||
}
|
||||
} else if ((particle1->isNucleon() && particle2->isAntiNucleon()) || (particle2->isNucleon() && particle1->isAntiNucleon())) {
|
||||
//// NNbar
|
||||
|
||||
//Forcing annihilationfor emitInsideAntinucleon at the end of cascade && annihilation if E <= M + p_threhsold (from antideuteron in generateBinaryCollisionAvatar())
|
||||
/*const Particle *antinucleon;
|
||||
const Particle *nucleon;
|
||||
|
||||
if (particle1->isAntiNucleon()) {
|
||||
antinucleon = particle1;
|
||||
nucleon = particle2;
|
||||
}
|
||||
else {
|
||||
antinucleon = particle2;
|
||||
nucleon = particle1;
|
||||
}
|
||||
double Esquared = antinucleon->getEnergy() * antinucleon->getEnergy();
|
||||
double antinucleon_threshold=0;
|
||||
if(antinucleon->getType()==antiNeutron)
|
||||
antinucleon_threshold = theNucleus->getStore()->getConfig()->getnbAtrestThreshold();
|
||||
else if(antinucleon->getType() == antiProton)
|
||||
antinucleon_threshold = theNucleus->getStore()->getConfig()->getAtrestThreshold();
|
||||
else
|
||||
INCL_ERROR("neither antiproton nor antineutron");*/
|
||||
//double Sum_at_rest = antinucleon->getINCLMass() * antinucleon->getINCLMass() + antinucleon_threshold*antinucleon_threshold;
|
||||
// Force the annihilation when T < Threshold (at rest)
|
||||
//Config const *theConfig=theNucleus->getStore()->getConfig();
|
||||
|
||||
if ((theCrossSection == 9999.) || // XS=9999. means force annihilation
|
||||
((particle1->getType()==antiProton && particle1->getKineticEnergy() <= theConfig->getAtrestThreshold()) ||
|
||||
(particle2->getType()==antiProton && particle2->getKineticEnergy() <= theConfig->getAtrestThreshold()) ||
|
||||
(particle1->getType()==antiNeutron && particle1->getKineticEnergy() <= particle1->getPotentialEnergy()) ||
|
||||
(particle2->getType()==antiNeutron && particle2->getKineticEnergy() <= particle2->getPotentialEnergy())) ||
|
||||
((particle1->getType()==antiProton && particle1->getEnergy() <= particle1->getINCLMass()) ||
|
||||
(particle2->getType()==antiProton && particle2->getEnergy() <= particle2->getINCLMass()) ||
|
||||
(particle1->getType()==antiNeutron && particle1->getEnergy() <= particle1->getINCLMass()) ||
|
||||
(particle2->getType()==antiNeutron && particle2->getEnergy() <= particle2->getINCLMass())))
|
||||
{
|
||||
isElastic = false;
|
||||
AnnihilationType atype0;
|
||||
if((particle1->getType()==antiProton && particle2->getType()==Proton) || (particle2->getType()==antiProton && particle1->getType()==Proton)){
|
||||
atype0 = PTypeInFlight;
|
||||
}
|
||||
else if((particle1->getType()==antiProton && particle2->getType()==Neutron) || (particle2->getType()==antiProton && particle1->getType()==Neutron)){
|
||||
atype0 = NTypeInFlight;
|
||||
}
|
||||
else if((particle1->getType()==antiNeutron && particle2->getType()==Proton) || (particle2->getType()==antiNeutron && particle1->getType()==Proton)){
|
||||
atype0 = NbarPTypeInFlight;
|
||||
}
|
||||
else if((particle1->getType()==antiNeutron && particle2->getType()==Neutron) || (particle2->getType()==antiNeutron && particle1->getType()==Neutron)){
|
||||
atype0 = NbarNTypeInFlight;
|
||||
}
|
||||
else{
|
||||
atype0 = Def;
|
||||
INCL_ERROR("Annihilation type problem " << '\n');
|
||||
}
|
||||
theNucleus->setAType(atype0);
|
||||
return new NNbarToAnnihilationChannel(theNucleus, particle1, particle2);
|
||||
}
|
||||
//delete antinucleon;
|
||||
//delete nucleon;
|
||||
|
||||
// Usual interactions
|
||||
const G4double totCX = CrossSections::total(particle1, particle2);
|
||||
const G4double NNbElasticCX = CrossSections::NNbarElastic(particle1,particle2);
|
||||
const G4double NNbCEXCX = CrossSections::NNbarCEX(particle1,particle2);
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
#include "G4INCLNuclearMassTable.hh"
|
||||
#include "G4INCLGlobalInfo.hh"
|
||||
#include "G4INCLNucleus.hh"
|
||||
#include "G4INCLDecayAvatar.hh"
|
||||
#include "G4INCLStore.hh"
|
||||
|
||||
#include "G4INCLPauliBlocking.hh"
|
||||
|
||||
@@ -191,7 +193,7 @@ namespace G4INCL {
|
||||
<< "Target configuration rejected." << '\n');
|
||||
return false;
|
||||
}
|
||||
if(projectileSpecies.theType==Composite &&
|
||||
if((projectileSpecies.theType==Composite || projectileSpecies.theType == antiComposite)&&
|
||||
(projectileSpecies.theZ==projectileSpecies.theA || projectileSpecies.theZ==0)) {
|
||||
INCL_ERROR("Unsupported projectile: A = " << projectileSpecies.theA << " Z = " << projectileSpecies.theZ << " S = " << projectileSpecies.theS << '\n'
|
||||
<< "Projectile configuration rejected." << '\n');
|
||||
@@ -209,12 +211,23 @@ namespace G4INCL {
|
||||
//reset
|
||||
G4bool ProtonIsTheVictim = false;
|
||||
G4bool NeutronIsTheVictim = false;
|
||||
G4bool DNbProtonIsTheVictim = false;
|
||||
G4bool DPbProtonIsTheVictim = false;
|
||||
theEventInfo.annihilationP = false;
|
||||
theEventInfo.annihilationN = false;
|
||||
G4bool isModelA = true; //Antideuteron
|
||||
|
||||
//G4double AnnihilationBarrier = kineticEnergy;
|
||||
if(projectileSpecies.theType == antiProton && kineticEnergy <= theConfig->getAtrestThreshold()){
|
||||
G4double SpOverSn = 1.331;//from experiments with deuteron (E.Klempt)
|
||||
if((projectileSpecies.theType == antiProton && kineticEnergy <= theConfig->getAtrestThreshold()) || (projectileSpecies.theType == antiNeutron && kineticEnergy <= theConfig->getnbAtrestThreshold())){
|
||||
double SpOverSn;
|
||||
if(projectileSpecies.theType == antiProton)
|
||||
SpOverSn = 1.331;//from experiments with deuteron (E.Klempt)
|
||||
else if(projectileSpecies.theType == antiNeutron)
|
||||
SpOverSn = 1./1.331; //Opposite for antineutron
|
||||
else{
|
||||
SpOverSn = 1;
|
||||
INCL_ERROR("Neither antiProton nor antiNeutron annihilated");
|
||||
}
|
||||
//INCL_WARN("theA number set to A-1 from " << A <<'\n');
|
||||
|
||||
G4double neutronprob;
|
||||
@@ -241,8 +254,78 @@ namespace G4INCL {
|
||||
theZ = Z;
|
||||
NeutronIsTheVictim = true;
|
||||
}
|
||||
} else if(projectileSpecies.theType == antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold()){
|
||||
if(Z > 30)
|
||||
isModelA=false;
|
||||
else if(Z > 9 && Z <=30){ //Maybe change and add another dependance than Z
|
||||
double rndmA = Random::shoot();
|
||||
if(rndmA > 0.5)//Random threshold : should be improved to take into account the orbit in which the separation takes place.
|
||||
isModelA=false;
|
||||
}
|
||||
if(isModelA){
|
||||
//Antideuteron Model A case : 2 annihilation at the same time
|
||||
double pbarSpOverSn = 1.331;
|
||||
double nbarSpOverSn = 1./1.331;
|
||||
double pbarneutronprob;
|
||||
double nbarneutronprob;
|
||||
if(theConfig->isNaturalTarget()){
|
||||
theA = ParticleTable::drawRandomNaturalIsotope(Z) - 2;
|
||||
nbarneutronprob = (theA + 2 - Z)/(theA + 2 - Z + nbarSpOverSn*Z);
|
||||
pbarneutronprob = (theA + 2 - Z)/(theA + 2 - Z + pbarSpOverSn*Z);
|
||||
}
|
||||
else{
|
||||
theA = A - 2;
|
||||
nbarneutronprob = (A - Z)/(A - Z + nbarSpOverSn*Z);
|
||||
pbarneutronprob = (A - Z)/(A - Z + pbarSpOverSn*Z);
|
||||
}
|
||||
else{ // not annihilation of pbar
|
||||
theS = S;
|
||||
G4double rndm = Random::shoot(); //for nbar
|
||||
G4double rndm2 = Random::shoot(); //for pbar
|
||||
|
||||
if (rndm >= nbarneutronprob){ // nbarp
|
||||
DNbProtonIsTheVictim = true;
|
||||
if(rndm2 >= pbarneutronprob){ // pbarp
|
||||
theZ = Z - 2;
|
||||
DPbProtonIsTheVictim = true;
|
||||
} else if(rndm2 < pbarneutronprob){ //pbarn
|
||||
theZ = Z - 1;
|
||||
}
|
||||
} else if(rndm < nbarneutronprob){//nbarn
|
||||
if(rndm2 >= pbarneutronprob){ // pbarp
|
||||
theZ = Z - 1;
|
||||
DPbProtonIsTheVictim = true;
|
||||
} else if(rndm2 < pbarneutronprob){ //pbarn
|
||||
theZ = Z;
|
||||
}
|
||||
}
|
||||
} else if (!isModelA){//Model B : Antiproton is detached from antideuteron
|
||||
double SpOverSn = 1.331;
|
||||
double neutronprob;
|
||||
if(theConfig->isNaturalTarget()){
|
||||
theA = ParticleTable::drawRandomNaturalIsotope(Z) - 1;
|
||||
neutronprob = (theA + 1 - Z)/(theA + 1 - Z + SpOverSn*Z);
|
||||
}
|
||||
else{
|
||||
theA = A - 1;
|
||||
neutronprob = (A - Z)/(A - Z + SpOverSn*Z);
|
||||
}
|
||||
|
||||
theS = S;
|
||||
|
||||
double rndm = Random::shoot();
|
||||
if(rndm >= neutronprob){ //proton is annihilated
|
||||
theEventInfo.annihilationP = true;
|
||||
theZ = Z - 1;
|
||||
ProtonIsTheVictim = true;
|
||||
}
|
||||
else{ //neutron is annihilated
|
||||
theEventInfo.annihilationN = true;
|
||||
theZ = Z;
|
||||
NeutronIsTheVictim = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{ // not annihilation of pbar, nbar, dbar
|
||||
theZ = Z;
|
||||
theS = S;
|
||||
if(theConfig->isNaturalTarget())
|
||||
@@ -256,6 +339,21 @@ namespace G4INCL {
|
||||
theAType = PType;
|
||||
if(NeutronIsTheVictim == true && ProtonIsTheVictim == false)
|
||||
theAType = NType;
|
||||
if(projectileSpecies.theType == antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold() && isModelA){
|
||||
if(DNbProtonIsTheVictim == true && DPbProtonIsTheVictim ==true)
|
||||
theAType = DNbarPPbarPType;
|
||||
else if(DNbProtonIsTheVictim == false && DPbProtonIsTheVictim ==true)
|
||||
theAType = DNbarNPbarPType;
|
||||
else if(DNbProtonIsTheVictim == false && DPbProtonIsTheVictim == false)
|
||||
theAType = DNbarNPbarNType;
|
||||
else if(DNbProtonIsTheVictim == true && DPbProtonIsTheVictim ==false)
|
||||
theAType = DNbarPPbarNType;
|
||||
} else if (projectileSpecies.theType == antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold() && !isModelA){
|
||||
if(ProtonIsTheVictim == true && NeutronIsTheVictim == false)
|
||||
theAType = PType;
|
||||
if(NeutronIsTheVictim == true && ProtonIsTheVictim == false)
|
||||
theAType = NType;
|
||||
}
|
||||
|
||||
//D
|
||||
|
||||
@@ -268,7 +366,8 @@ namespace G4INCL {
|
||||
// For forced CN events
|
||||
initMaxInteractionDistance(projectileSpecies, kineticEnergy);
|
||||
// Set the geometric cross sectiony section
|
||||
if(projectileSpecies.theType == antiProton && kineticEnergy <= theConfig->getAtrestThreshold()){
|
||||
if((projectileSpecies.theType == antiProton && kineticEnergy <= theConfig->getAtrestThreshold()) || (projectileSpecies.theType == antiNeutron && kineticEnergy <= theConfig->getnbAtrestThreshold())
|
||||
|| (projectileSpecies.theType == antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold()) ){
|
||||
G4int currentA = A;
|
||||
if(theConfig->isNaturalTarget()){
|
||||
currentA = ParticleTable::drawRandomNaturalIsotope(Z);
|
||||
@@ -296,10 +395,13 @@ namespace G4INCL {
|
||||
G4bool INCL::initializeTarget(const G4int A, const G4int Z, const G4int S, AnnihilationType theAType) {
|
||||
delete nucleus;
|
||||
|
||||
if (theAType==PType || theAType==NType) {
|
||||
if (theAType==PType || theAType==NType || theAType==DNbarNPbarPType || theAType==DNbarNPbarNType ||theAType==DNbarPPbarPType || theAType==DNbarPPbarNType) {
|
||||
G4double newmaxUniverseRadius=0.;
|
||||
if (theAType==PType) newmaxUniverseRadius=initUniverseRadiusForAntiprotonAtRest(A+1, Z+1);
|
||||
else newmaxUniverseRadius=initUniverseRadiusForAntiprotonAtRest(A+1, Z);
|
||||
else if (theAType==NType) newmaxUniverseRadius=initUniverseRadiusForAntiprotonAtRest(A+1, Z);
|
||||
else if (theAType==DNbarPPbarPType) newmaxUniverseRadius=initUniverseRadiusForAntiprotonAtRest(A+2, Z+2);
|
||||
else if (theAType==DNbarNPbarNType) newmaxUniverseRadius=initUniverseRadiusForAntiprotonAtRest(A+2, Z);
|
||||
else if (theAType==DNbarNPbarPType || theAType==DNbarPPbarNType) newmaxUniverseRadius=initUniverseRadiusForAntiprotonAtRest(A+2, Z+1);
|
||||
nucleus = new Nucleus(A, Z, S, theConfig, newmaxUniverseRadius, theAType);
|
||||
}
|
||||
else{
|
||||
@@ -358,9 +460,12 @@ namespace G4INCL {
|
||||
}
|
||||
const G4String& dataPath0(G4FindDataDir("G4INCLDATA"));
|
||||
const G4String& dataPathppbar(dataPath0 + "/rawppbarFS.dat");
|
||||
// const G4String& dataPathnpbar(dataPath0 + "/rawnpbarFS.dat"); // NOT used!
|
||||
const G4String& dataPathnpbar(dataPath0 + "/rawnpbarFS.dat");
|
||||
const G4String& dataPathppbark(dataPath0 + "/rawppbarFSkaonic.dat");
|
||||
// const G4String& dataPathnpbark(dataPath0 + "/rawnpbarFSkaonic.dat"); // NOT used!
|
||||
const G4String& dataPathnpbark(dataPath0 + "/rawnpbarFSkaonic.dat");
|
||||
|
||||
const G4String dataPathnbarp(dataPath0 + "/rawnbarpFS.dat");
|
||||
const G4String dataPathnbarn(dataPath0 + "/rawnbarnFS.dat");
|
||||
#else
|
||||
std::string path;
|
||||
if (theConfig) path = theConfig->getINCLXXDataFilePath();
|
||||
@@ -372,6 +477,13 @@ namespace G4INCL {
|
||||
INCL_DEBUG("Reading https://doi.org/10.1016/j.physrep.2005.03.002 ppbar kaonic final states" << dataPathppbark << '\n');
|
||||
const std::string& dataPathnpbark(path + "/rawnpbarFSkaonic.dat");
|
||||
INCL_DEBUG("Reading https://doi.org/10.1007/BF02818764 and https://link.springer.com/article/10.1007/BF02754930 npbar kaonic final states" << dataPathnpbark << '\n');
|
||||
|
||||
const std::string& dataPathnbarp(path + "/rawnnbarpFS.dat ");
|
||||
INCL_DEBUG("Reading nbarp final states" << dataPathnbarp << '\n');
|
||||
const std::string& dataPathnbarpk(path + "/rawnbarpFSkaonic.dat");
|
||||
INCL_DEBUG("Reading nbarp kaonic final states");
|
||||
const std::string& dataPathnbarn(path + "/rawnbarnFS.dat");
|
||||
INCL_DEBUG("Reading nbarn final states" << dataPathnbarn << '\n');
|
||||
#endif
|
||||
|
||||
//read probabilities and particle types from file
|
||||
@@ -387,7 +499,10 @@ namespace G4INCL {
|
||||
ThreeVector annihilationPosition(0.,0.,0.);
|
||||
if (rdm < (1.-kaonicFSprob)) { // pionic FS was chosen
|
||||
INCL_DEBUG("pionic pp final state chosen" << '\n');
|
||||
sum = read_file(dataPathppbar, probabilities, particle_types);
|
||||
if (targetA==1 || (targetA==2 && theEventInfo.annihilationP))
|
||||
{sum = read_file(dataPathppbar, probabilities, particle_types);}
|
||||
else
|
||||
{sum = read_file(dataPathnpbar, probabilities, particle_types);}
|
||||
rdm = (rdm/(1.-kaonicFSprob))*sum; //99.88 normalize by the sum of probabilities in the file
|
||||
//now get the line number in the file where the FS particles are stored:
|
||||
G4int n = findStringNumber(rdm, std::move(probabilities))-1;
|
||||
@@ -441,7 +556,10 @@ namespace G4INCL {
|
||||
}
|
||||
} else {
|
||||
INCL_DEBUG("kaonic pp final state chosen" << '\n');
|
||||
sum = read_file(dataPathppbark, probabilities, particle_types);
|
||||
if (targetA==1 || (targetA==2 && theEventInfo.annihilationP))
|
||||
{sum = read_file(dataPathppbark, probabilities, particle_types);}
|
||||
else
|
||||
{sum = read_file(dataPathnpbark, probabilities, particle_types);}
|
||||
rdm = ((1.-rdm)/kaonicFSprob)*sum; //2670 normalize by the sum of probabilities in the file
|
||||
//now get the line number in the file where the FS particles are stored:
|
||||
G4int n = findStringNumber(rdm, std::move(probabilities))-1;
|
||||
@@ -493,7 +611,7 @@ namespace G4INCL {
|
||||
}
|
||||
|
||||
//compute energies of mesons with a phase-space model
|
||||
G4double energyOfMesonStar=ParticleTable::getRealMass(Proton)+ParticleTable::getRealMass(antiProton);
|
||||
G4double energyOfMesonStar=ParticleTable::getRealMass(Proton)+ParticleTable::getRealMass(antiProton)+kineticEnergy;
|
||||
if (starlist.size() < 2) {
|
||||
INCL_ERROR("should never happen, at least 2 final state particles!" << '\n');
|
||||
} else if (starlist.size() == 2) {
|
||||
@@ -517,7 +635,210 @@ namespace G4INCL {
|
||||
|
||||
theGlobalInfo.nShots++;
|
||||
return theEventInfo;
|
||||
} // pbar on H1
|
||||
} // pbar on H1/H2
|
||||
|
||||
if ((projectileSpecies.theType==antiNeutron)&& (targetA==1 || targetA==2) && targetZ==1 && targetS==0) {
|
||||
|
||||
if (targetA==1) {
|
||||
preCascade_nbarH1(projectileSpecies, kineticEnergy);
|
||||
} else {
|
||||
preCascade_nbarH2(projectileSpecies, kineticEnergy);
|
||||
theEventInfo.annihilationP = false;
|
||||
theEventInfo.annihilationN = false;
|
||||
|
||||
G4double SpOverSn = 1./1.331; //from experiments with deuteron (E.Klempt)
|
||||
|
||||
ThreeVector dummy(0.,0.,0.);
|
||||
double rndm = Random::shoot()*(SpOverSn+1);
|
||||
if (rndm <= SpOverSn) { //proton is annihilated
|
||||
theEventInfo.annihilationP = true;
|
||||
Particle *p2 = new Particle(Neutron, dummy, dummy);
|
||||
starlistH2.push_back(p2);
|
||||
//delete p2;
|
||||
} else { //neutron is annihilated
|
||||
theEventInfo.annihilationN = true;
|
||||
Particle *p2 = new Particle(Proton, dummy, dummy);
|
||||
starlistH2.push_back(p2);
|
||||
//delete p2;
|
||||
}
|
||||
}
|
||||
|
||||
// File names
|
||||
#ifdef INCLXX_IN_GEANT4_MODE
|
||||
if (!G4FindDataDir("G4INCLDATA") ) {
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Data missing: set environment variable G4INCLDATA\n"
|
||||
<< " to point to the directory containing data files needed\n"
|
||||
<< " by the INCL++ model" << G4endl;
|
||||
G4Exception("G4INCLDataFile::readData()","rawpnbarFS.dat, ...", FatalException, ed);
|
||||
}
|
||||
G4String dataPath0{G4FindDataDir("G4INCLDATA")};
|
||||
G4String dataPathnbarp(dataPath0 + "/rawnbarpFS.dat");
|
||||
G4String dataPathnbarn(dataPath0 + "/rawnbarnFS.dat");
|
||||
G4String dataPathnbarnk(dataPath0 + "/rawppbarFSkaonic.dat");
|
||||
G4String dataPathnbarpk(dataPath0 + "/rawnbarpFSkaonic.dat");
|
||||
#else
|
||||
G4String path;
|
||||
if (theConfig) path = theConfig->getINCLXXDataFilePath();
|
||||
std::string dataPathnbarn(path + "/rawnbarnFS.dat");
|
||||
INCL_DEBUG("Reading nbarn final states" << dataPathnbarn << '\n');
|
||||
std::string dataPathnbarp(path + "/rawnbarpFS.dat");
|
||||
INCL_DEBUG("Reading nbarp final states" << dataPathnbarp << '\n');
|
||||
std::string dataPathnbarnk(path + "/rawppbarFSkaonic.dat");
|
||||
INCL_DEBUG("Reading nbarn kaonic final states" << dataPathnbarnk << '\n');
|
||||
std::string dataPathnbarpk(path + "/rawnbarpFSkaonic.dat");
|
||||
INCL_DEBUG("Reading nbarp kaonic final states" << dataPathnbarpk << '\n');
|
||||
#endif
|
||||
//read probabilities and particle types from file
|
||||
std::vector<double> probabilities; //will store each FS yield
|
||||
std::vector<std::vector<G4String>> particle_types; //will store particle names
|
||||
double sum = 0.0; //will contain a sum of probabilities of all FS in the file
|
||||
double kaonicFSprob=0.05; //probability to kave kaonic FS
|
||||
|
||||
ParticleList starlist;
|
||||
ThreeVector mommy; //momentum to be assigned later
|
||||
|
||||
double rdm = Random::shoot();
|
||||
ThreeVector annihilationPosition(0.,0.,0.);
|
||||
if (rdm < (1.-kaonicFSprob)) { // pionic FS was chosen
|
||||
INCL_DEBUG("pionic nn final state chosen" << '\n');
|
||||
if (targetA==1 || (targetA==2 && theEventInfo.annihilationP))
|
||||
{sum = read_file(dataPathnbarp, probabilities, particle_types);}
|
||||
else
|
||||
{sum = read_file(dataPathnbarn, probabilities, particle_types);}
|
||||
rdm = (rdm/(1.-kaonicFSprob))*sum; //99.88 normalize by the sum of probabilities in the file
|
||||
//now get the line number in the file where the FS particles are stored:
|
||||
G4int n = findStringNumber(rdm, probabilities)-1;
|
||||
if ( n < 0 ) return theEventInfo;
|
||||
for (G4int j = 0; j < static_cast<int>(particle_types[n].size()); j++) {
|
||||
if (particle_types[n][j] == "pi0") {
|
||||
Particle *p = new Particle(PiZero, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
} else if (particle_types[n][j] == "pi-") {
|
||||
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
} else if (particle_types[n][j] == "pi+") {
|
||||
Particle *p = new Particle(PiPlus, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
} else if (particle_types[n][j] == "omega") {
|
||||
Particle *p = new Particle(Omega, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
} else if (particle_types[n][j] == "eta") {
|
||||
Particle *p = new Particle(Eta, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
} else if (particle_types[n][j] == "rho-") {
|
||||
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
Particle *pp = new Particle(PiZero, mommy, annihilationPosition);
|
||||
starlist.push_back(pp);
|
||||
} else if (particle_types[n][j] == "rho+") {
|
||||
Particle *p = new Particle(PiPlus, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
Particle *pp = new Particle(PiZero, mommy, annihilationPosition);
|
||||
starlist.push_back(pp);
|
||||
} else if (particle_types[n][j] == "rho0") {
|
||||
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
Particle *pp = new Particle(PiPlus, mommy, annihilationPosition);
|
||||
starlist.push_back(pp);
|
||||
} else {
|
||||
INCL_ERROR("Some non-existing FS particle detected when reading pbar FS files");
|
||||
for (int jj = 0; jj < static_cast<int>(particle_types[n].size()); jj++) {
|
||||
#ifdef INCLXX_IN_GEANT4_MODE
|
||||
G4cout << "gotcha! " << particle_types[n][jj] << G4endl;
|
||||
#else
|
||||
std::cout << "gotcha! " << particle_types[n][jj] << std::endl;
|
||||
#endif
|
||||
}
|
||||
#ifdef INCLXX_IN_GEANT4_MODE
|
||||
G4cout << "Some non-existing FS particle detected when reading pbar FS files" << G4endl;
|
||||
#else
|
||||
std::cout << "Some non-existing FS particle detected when reading pbar FS files" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else {
|
||||
INCL_DEBUG("kaonic pp final state chosen" << '\n');
|
||||
if (targetA==1 || (targetA==2 && theEventInfo.annihilationP))
|
||||
{sum = read_file(dataPathnbarpk, probabilities, particle_types);}
|
||||
else
|
||||
{sum = read_file(dataPathnbarnk, probabilities, particle_types);}
|
||||
rdm = ((1.-rdm)/kaonicFSprob)*sum; //2670 normalize by the sum of probabilities in the file
|
||||
//now get the line number in the file where the FS particles are stored:
|
||||
G4int n = findStringNumber(rdm, probabilities)-1;
|
||||
if ( n < 0 ) return theEventInfo;
|
||||
for (G4int j = 0; j < static_cast<int>(particle_types[n].size()); j++) {
|
||||
if (particle_types[n][j] == "pi0") {
|
||||
Particle *p = new Particle(PiZero, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
} else if (particle_types[n][j] == "pi-") {
|
||||
Particle *p = new Particle(PiMinus, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
} else if (particle_types[n][j] == "pi+") {
|
||||
Particle *p = new Particle(PiPlus, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
} else if (particle_types[n][j] == "omega") {
|
||||
Particle *p = new Particle(Omega, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
} else if (particle_types[n][j] == "eta") {
|
||||
Particle *p = new Particle(Eta, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
} else if (particle_types[n][j] == "K-") {
|
||||
Particle *p = new Particle(KMinus, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
} else if (particle_types[n][j] == "K+") {
|
||||
Particle *p = new Particle(KPlus, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
} else if (particle_types[n][j] == "K0") {
|
||||
Particle *p = new Particle(KZero, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
} else if (particle_types[n][j] == "K0b") {
|
||||
Particle *p = new Particle(KZeroBar, mommy, annihilationPosition);
|
||||
starlist.push_back(p);
|
||||
} else {
|
||||
INCL_ERROR("Some non-existing FS particle detected when reading pbar FS files");
|
||||
for (int jj = 0; jj < static_cast<int>(particle_types[n].size()); jj++) {
|
||||
#ifdef INCLXX_IN_GEANT4_MODE
|
||||
G4cout << "gotcha! " << particle_types[n][jj] << G4endl;
|
||||
#else
|
||||
std::cout << "gotcha! " << particle_types[n][jj] << std::endl;
|
||||
#endif
|
||||
}
|
||||
#ifdef INCLXX_IN_GEANT4_MODE
|
||||
G4cout << "Some non-existing FS particle detected when reading pbar FS files" << G4endl;
|
||||
#else
|
||||
std::cout << "Some non-existing FS particle detected when reading pbar FS files" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//compute energies of mesons with a phase-space model
|
||||
G4double energyOfMesonStar=ParticleTable::getRealMass(Proton)+ParticleTable::getRealMass(antiProton)+kineticEnergy;
|
||||
if (starlist.size() < 2) {
|
||||
INCL_ERROR("should never happen, at least 2 final state particles!" << '\n');
|
||||
} else if (starlist.size() == 2) {
|
||||
ParticleIter first = starlist.begin();
|
||||
ParticleIter last = std::next(first, 1);
|
||||
G4double m1 = (*first)->getMass();
|
||||
G4double m2 = (*last)->getMass();
|
||||
G4double s = energyOfMesonStar*energyOfMesonStar;
|
||||
G4double mom1 = std::sqrt(s/4. - (std::pow(m1,2) + std::pow(m2,2))/2. - std::pow(m1,2)*std::pow(m2,2)/s + (std::pow(m1,4) + 2.*std::pow(m1*m2,2) + std::pow(m2,4))/(4.*s));
|
||||
ThreeVector momentello = Random::normVector(mom1);
|
||||
(*first)->setMomentum(momentello);
|
||||
(*first)->adjustEnergyFromMomentum();
|
||||
(*last)->setMomentum(-momentello);
|
||||
(*last)->adjustEnergyFromMomentum();
|
||||
} else {
|
||||
PhaseSpaceGenerator::generate(energyOfMesonStar, starlist);
|
||||
}
|
||||
|
||||
if (targetA==1) postCascade_pbarH1(starlist);
|
||||
else postCascade_pbarH2(starlist,starlistH2);
|
||||
|
||||
theGlobalInfo.nShots++;
|
||||
return theEventInfo;
|
||||
} // nbar on H1/H2
|
||||
|
||||
// ReInitialize the bias vector
|
||||
Particle::INCLBiasVector.clear();
|
||||
@@ -569,6 +890,22 @@ namespace G4INCL {
|
||||
theEventInfo.At = (Short_t)nucleus->getA()+1;
|
||||
theEventInfo.Zt = (Short_t)nucleus->getZ();
|
||||
}
|
||||
else if(nucleus->getAnnihilationType()==DNbarNPbarNType ){
|
||||
theEventInfo.annihilationN = true;
|
||||
theEventInfo.At = (Short_t)nucleus->getA()+2;
|
||||
theEventInfo.Zt = (Short_t)nucleus->getZ();
|
||||
}
|
||||
else if(nucleus->getAnnihilationType()==DNbarPPbarPType ){
|
||||
theEventInfo.annihilationP = true;
|
||||
theEventInfo.At = (Short_t)nucleus->getA()+2;
|
||||
theEventInfo.Zt = (Short_t)nucleus->getZ()+2;
|
||||
}
|
||||
else if(nucleus->getAnnihilationType()==DNbarPPbarNType || nucleus->getAnnihilationType()==DNbarNPbarPType ){
|
||||
theEventInfo.annihilationN = true;
|
||||
theEventInfo.annihilationP = true;
|
||||
theEventInfo.At = (Short_t)nucleus->getA()+2;
|
||||
theEventInfo.Zt = (Short_t)nucleus->getZ()+1;
|
||||
}
|
||||
else {
|
||||
theEventInfo.At = (Short_t)nucleus->getA();
|
||||
theEventInfo.Zt = (Short_t)nucleus->getZ();
|
||||
@@ -578,7 +915,8 @@ namespace G4INCL {
|
||||
// Fill in the event information
|
||||
//Particle *pbar = new Particle;
|
||||
//PbarAtrestEntryChannel *obj = new PbarAtrestEntryChannel(nucleus, pbar);
|
||||
if(projectileSpecies.theType == antiProton && kineticEnergy <= theConfig->getAtrestThreshold()){ //D
|
||||
if((projectileSpecies.theType == antiProton && kineticEnergy <= theConfig->getAtrestThreshold()) || (projectileSpecies.theType==antiNeutron && kineticEnergy <= theConfig->getnbAtrestThreshold())
|
||||
|| (projectileSpecies.theType == antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold())){ //D
|
||||
INCL_DEBUG("at rest annihilation" << '\n');
|
||||
//theEventInfo.transparent = false;
|
||||
} else {
|
||||
@@ -671,7 +1009,8 @@ namespace G4INCL {
|
||||
theEventInfo.eventBias = (Double_t) Particle::getTotalBias();
|
||||
|
||||
// Forced CN?
|
||||
if(!(projectileSpecies.theType==antiProton && kineticEnergy<=theConfig->getAtrestThreshold())){
|
||||
if(!(projectileSpecies.theType==antiProton && kineticEnergy<=theConfig->getAtrestThreshold()) && !(projectileSpecies.theType == antiNeutron && kineticEnergy<=theConfig->getnbAtrestThreshold())
|
||||
&& !(projectileSpecies.theType==antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold()) ){
|
||||
if(nucleus->getTryCompoundNucleus()) {
|
||||
INCL_DEBUG("Trying compound nucleus" << '\n');
|
||||
makeCompoundNucleus();
|
||||
@@ -684,7 +1023,8 @@ namespace G4INCL {
|
||||
}
|
||||
}
|
||||
|
||||
if(!(projectileSpecies.theType==antiProton && kineticEnergy<=theConfig->getAtrestThreshold())){
|
||||
if(!(projectileSpecies.theType==antiProton && kineticEnergy<=theConfig->getAtrestThreshold()) && !(projectileSpecies.theType == antiNeutron && kineticEnergy<=theConfig->getnbAtrestThreshold())
|
||||
&& !(projectileSpecies.theType==antiComposite && kineticEnergy <= theConfig->getdbAtrestThreshold())){
|
||||
theEventInfo.transparent = forceTransparent || nucleus->isEventTransparent();
|
||||
}
|
||||
|
||||
@@ -698,6 +1038,13 @@ namespace G4INCL {
|
||||
nucleus->getStore()->deleteIncoming();
|
||||
}
|
||||
} else {
|
||||
//Check if the nucleus contains antinucleons
|
||||
theEventInfo.antinucleonsInside = nucleus->containsAntinucleon();
|
||||
//Annihilate antiparticles still inside the nucleus & emit the resulting particles
|
||||
if(nucleus->containsAntinucleon())
|
||||
theEventInfo.emitAntinucleon = nucleus->emitInsideAnnihilationProducts();
|
||||
if(nucleus->containsAntilambda())
|
||||
theEventInfo.emitAntilambda = nucleus->emitInsideAntilambda();
|
||||
|
||||
// Check if the nucleus contains strange particles
|
||||
theEventInfo.sigmasInside = nucleus->containsSigma();
|
||||
@@ -986,7 +1333,8 @@ namespace G4INCL {
|
||||
pTransThreshold = 0.1; // MeV/c
|
||||
}
|
||||
if(std::abs(theBalance.energy)>EThreshold) {
|
||||
INCL_WARN("Violation of energy conservation > " << EThreshold << " MeV. EBalance = " << theBalance.energy << " Emit Lambda=" << theEventInfo.emitLambda << " afterRecoil = " << afterRecoil << " eventNumber=" << theEventInfo.eventNumber << '\n');
|
||||
INCL_WARN("Violation of energy conservation > " << EThreshold << " MeV. EBalance = " << theBalance.energy << " Emit Lambda=" << theEventInfo.emitLambda << " afterRecoil = " << afterRecoil << " SRCevent ="
|
||||
<< nucleus->getStore()->getBook().getAcceptedSrcCollisions()<< " eventNumber=" << theEventInfo.eventNumber << '\n');
|
||||
}
|
||||
if(std::abs(pLongBalance)>pLongThreshold) {
|
||||
INCL_WARN("Violation of longitudinal momentum conservation > " << pLongThreshold << " MeV/c. pLongBalance = " << pLongBalance << " afterRecoil = " << afterRecoil << " eventNumber=" << theEventInfo.eventNumber << '\n');
|
||||
@@ -1023,6 +1371,12 @@ namespace G4INCL {
|
||||
<< "), stopping cascade" << '\n');
|
||||
return false;
|
||||
}
|
||||
if((nucleus->getZ() <= 2) && (propagationModel->getCurrentTime() != 0)) {
|
||||
INCL_DEBUG("Remnant size (" << nucleus->getZ()
|
||||
<< ") smaller than or equal to minimum (" << "2"
|
||||
<< "), stopping cascade" << '\n');
|
||||
return false;
|
||||
}
|
||||
// Stop if we have to try and make a compound nucleus or if we have to
|
||||
// force a transparent
|
||||
if(nucleus->getTryCompoundNucleus()) {
|
||||
@@ -1098,19 +1452,29 @@ namespace G4INCL {
|
||||
}
|
||||
|
||||
void INCL::initMaxInteractionDistance(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy) {
|
||||
if(projectileSpecies.theType != Composite) {
|
||||
if(projectileSpecies.theType != Composite && projectileSpecies.theType != antiComposite) {
|
||||
maxInteractionDistance = 0.;
|
||||
return;
|
||||
}
|
||||
|
||||
const G4double r0 = std::max(ParticleTable::getNuclearRadius(Proton, theA, theZ),
|
||||
ParticleTable::getNuclearRadius(Neutron, theA, theZ));
|
||||
if (projectileSpecies.theType == Composite){
|
||||
|
||||
const G4double theNNDistance = CrossSections::interactionDistanceNN(projectileSpecies, kineticEnergy);
|
||||
maxInteractionDistance = r0 + theNNDistance;
|
||||
INCL_DEBUG("Initialised interaction distance: r0 = " << r0 << '\n'
|
||||
<< " theNNDistance = " << theNNDistance << '\n'
|
||||
<< " maxInteractionDistance = " << maxInteractionDistance << '\n');
|
||||
}
|
||||
else if (projectileSpecies.theType == antiComposite){
|
||||
const G4double theNbarNDistance = CrossSections::interactionDistanceNbarN(projectileSpecies, kineticEnergy);
|
||||
maxInteractionDistance = r0 + theNbarNDistance;
|
||||
INCL_DEBUG("Initialised interaction distance: r0 = " << r0 << '\n'
|
||||
<< " theNbarNDistance = " << theNbarNDistance << '\n'
|
||||
<< " maxInteractionDistance = " << maxInteractionDistance << '\n');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void INCL::initUniverseRadius(ParticleSpecies const &p, const G4double kineticEnergy, const G4int A, const G4int Z) {
|
||||
@@ -1156,6 +1520,12 @@ namespace G4INCL {
|
||||
}
|
||||
else if(p.theType==antiProton) {
|
||||
maxUniverseRadius = rMax; //check interaction distance!!!
|
||||
} else if (p.theType==antiNeutron){
|
||||
const G4double interactionDistancenbarN = CrossSections::interactionDistancenbarN(p,kineticEnergy);
|
||||
maxUniverseRadius = rMax+ interactionDistancenbarN;
|
||||
} else if (p.theType==antiComposite){
|
||||
const G4double interactionDistanceNbarN = CrossSections::interactionDistanceNbarN(p,kineticEnergy);
|
||||
maxUniverseRadius =rMax + interactionDistanceNbarN;
|
||||
}
|
||||
INCL_DEBUG("Initialised universe radius: " << maxUniverseRadius << '\n');
|
||||
}
|
||||
@@ -1284,15 +1654,100 @@ namespace G4INCL {
|
||||
theEventInfo.Zt = 1;
|
||||
}
|
||||
|
||||
void INCL::preCascade_nbarH1(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy) {
|
||||
// Reset theEventInfo
|
||||
theEventInfo.reset();
|
||||
|
||||
EventInfo::eventNumber++;
|
||||
|
||||
// Fill in the event information
|
||||
theEventInfo.projectileType = projectileSpecies.theType;
|
||||
theEventInfo.Ap = -1;
|
||||
theEventInfo.Zp = 0;
|
||||
theEventInfo.Sp = 0;
|
||||
theEventInfo.Ep = kineticEnergy;
|
||||
theEventInfo.St = 0;
|
||||
theEventInfo.At = 1;
|
||||
theEventInfo.Zt = 1;
|
||||
}
|
||||
|
||||
void INCL::postCascade_pbarH1(ParticleList const &outgoingParticles) {
|
||||
theEventInfo.nParticles = 0;
|
||||
|
||||
ParticleList outgoingParticles2;
|
||||
// Reset the remnant counter
|
||||
theEventInfo.nRemnants = 0;
|
||||
theEventInfo.history.clear();
|
||||
|
||||
// Decay eta and omega
|
||||
for(ParticleIter i=outgoingParticles.begin(), e=outgoingParticles.end(); i!=e; ++i) {
|
||||
if( (*i)->isEta() || (*i)->isOmega() ) {
|
||||
INCL_DEBUG("Decay outgoing eta/omega particle:" << '\n'
|
||||
<< (*i)->print() << '\n');
|
||||
const ThreeVector beta = -(*i)->boostVector();
|
||||
const G4double pionResonanceMass = (*i)->getMass();
|
||||
|
||||
// Set the pionResonance momentum to zero and sample the decay in the CM frame.
|
||||
// This makes life simpler if we are using real particle masses.
|
||||
(*i)->setMomentum(ThreeVector());
|
||||
(*i)->setEnergy((*i)->getMass());
|
||||
|
||||
// Use a DecayAvatar
|
||||
IAvatar *decay = new DecayAvatar((*i), 0.0, NULL);
|
||||
FinalState *fs = decay->getFinalState();
|
||||
|
||||
Particle * const theModifiedParticle = fs->getModifiedParticles().front();
|
||||
ParticleList const &created = fs->getCreatedParticles();
|
||||
Particle * const theCreatedParticle1 = created.front();
|
||||
|
||||
if (created.size() == 1) {
|
||||
|
||||
// Adjust the decay momentum if we are using the real masses
|
||||
const G4double decayMomentum = KinematicsUtils::momentumInCM(pionResonanceMass,theModifiedParticle->getTableMass(),theCreatedParticle1->getTableMass());
|
||||
ThreeVector newMomentum = theCreatedParticle1->getMomentum();
|
||||
newMomentum *= decayMomentum / newMomentum.mag();
|
||||
|
||||
theCreatedParticle1->setTableMass();
|
||||
theCreatedParticle1->setMomentum(newMomentum);
|
||||
theCreatedParticle1->adjustEnergyFromMomentum();
|
||||
theCreatedParticle1->setEmissionTime((*i)->getEmissionTime());
|
||||
theCreatedParticle1->boost(beta);
|
||||
theCreatedParticle1->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
|
||||
|
||||
theModifiedParticle->setTableMass();
|
||||
theModifiedParticle->setMomentum(-newMomentum);
|
||||
theModifiedParticle->adjustEnergyFromMomentum();
|
||||
theModifiedParticle->boost(beta);
|
||||
|
||||
outgoingParticles2.push_back(theCreatedParticle1);
|
||||
outgoingParticles2.push_back(theModifiedParticle);
|
||||
}
|
||||
else if (created.size() == 2) {
|
||||
Particle * const theCreatedParticle2 = created.back();
|
||||
|
||||
theCreatedParticle1->boost(beta);
|
||||
theCreatedParticle1->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
|
||||
theCreatedParticle1->setEmissionTime((*i)->getEmissionTime());
|
||||
theCreatedParticle2->boost(beta);
|
||||
theCreatedParticle2->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
|
||||
theCreatedParticle2->setEmissionTime((*i)->getEmissionTime());
|
||||
theModifiedParticle->boost(beta);
|
||||
|
||||
outgoingParticles2.push_back(theCreatedParticle1);
|
||||
outgoingParticles2.push_back(theCreatedParticle2);
|
||||
outgoingParticles2.push_back(theModifiedParticle);
|
||||
}
|
||||
else {
|
||||
INCL_ERROR("Wrong number (< 2) of created particles during the decay of a pion resonance");
|
||||
}
|
||||
delete fs;
|
||||
delete decay;
|
||||
}
|
||||
else {
|
||||
outgoingParticles2.push_back(*i);
|
||||
}
|
||||
}// End of Decay eta and omega
|
||||
|
||||
for(ParticleIter i=outgoingParticles.begin(), e=outgoingParticles.end(); i!=e; ++i ) {
|
||||
for(ParticleIter i=outgoingParticles2.begin(), e=outgoingParticles2.end(); i!=e; ++i ) {
|
||||
theEventInfo.A[theEventInfo.nParticles] = (Short_t)(*i)->getA();
|
||||
theEventInfo.Z[theEventInfo.nParticles] = (Short_t)(*i)->getZ();
|
||||
theEventInfo.S[theEventInfo.nParticles] = (Short_t)(*i)->getS();
|
||||
@@ -1334,15 +1789,101 @@ namespace G4INCL {
|
||||
theEventInfo.Zt = 1;
|
||||
}
|
||||
|
||||
void INCL::preCascade_nbarH2(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy) {
|
||||
// Reset theEventInfo
|
||||
theEventInfo.reset();
|
||||
|
||||
EventInfo::eventNumber++;
|
||||
|
||||
// Fill in the event information
|
||||
theEventInfo.projectileType = projectileSpecies.theType;
|
||||
theEventInfo.Ap = -1;
|
||||
theEventInfo.Zp = 0;
|
||||
theEventInfo.Sp = 0;
|
||||
theEventInfo.Ep = kineticEnergy;
|
||||
theEventInfo.St = 0;
|
||||
theEventInfo.At = 2;
|
||||
theEventInfo.Zt = 1;
|
||||
}
|
||||
|
||||
void INCL::postCascade_pbarH2(ParticleList const &outgoingParticles, ParticleList const &H2Particles) {
|
||||
theEventInfo.nParticles = 0;
|
||||
ParticleList outgoingParticles2;
|
||||
|
||||
// Reset the remnant counter
|
||||
theEventInfo.nRemnants = 0;
|
||||
theEventInfo.history.clear();
|
||||
|
||||
// Decay eta and omega
|
||||
for(ParticleIter i=outgoingParticles.begin(), e=outgoingParticles.end(); i!=e; ++i) {
|
||||
if( (*i)->isEta() || (*i)->isOmega() ) {
|
||||
INCL_DEBUG("Decay outgoing eta/omega particle:" << '\n'
|
||||
<< (*i)->print() << '\n');
|
||||
const ThreeVector beta = -(*i)->boostVector();
|
||||
const G4double pionResonanceMass = (*i)->getMass();
|
||||
|
||||
// Set the pionResonance momentum to zero and sample the decay in the CM frame.
|
||||
// This makes life simpler if we are using real particle masses.
|
||||
(*i)->setMomentum(ThreeVector());
|
||||
(*i)->setEnergy((*i)->getMass());
|
||||
|
||||
// Use a DecayAvatar
|
||||
IAvatar *decay = new DecayAvatar((*i), 0.0, NULL);
|
||||
FinalState *fs = decay->getFinalState();
|
||||
|
||||
Particle * const theModifiedParticle = fs->getModifiedParticles().front();
|
||||
ParticleList const &created = fs->getCreatedParticles();
|
||||
Particle * const theCreatedParticle1 = created.front();
|
||||
|
||||
if (created.size() == 1) {
|
||||
|
||||
// Adjust the decay momentum if we are using the real masses
|
||||
const G4double decayMomentum = KinematicsUtils::momentumInCM(pionResonanceMass,theModifiedParticle->getTableMass(),theCreatedParticle1->getTableMass());
|
||||
ThreeVector newMomentum = theCreatedParticle1->getMomentum();
|
||||
newMomentum *= decayMomentum / newMomentum.mag();
|
||||
|
||||
theCreatedParticle1->setTableMass();
|
||||
theCreatedParticle1->setMomentum(newMomentum);
|
||||
theCreatedParticle1->adjustEnergyFromMomentum();
|
||||
theCreatedParticle1->setEmissionTime((*i)->getEmissionTime());
|
||||
theCreatedParticle1->boost(beta);
|
||||
theCreatedParticle1->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
|
||||
|
||||
theModifiedParticle->setTableMass();
|
||||
theModifiedParticle->setMomentum(-newMomentum);
|
||||
theModifiedParticle->adjustEnergyFromMomentum();
|
||||
theModifiedParticle->boost(beta);
|
||||
|
||||
outgoingParticles2.push_back(theCreatedParticle1);
|
||||
outgoingParticles2.push_back(theModifiedParticle);
|
||||
}
|
||||
else if (created.size() == 2) {
|
||||
Particle * const theCreatedParticle2 = created.back();
|
||||
|
||||
theCreatedParticle1->boost(beta);
|
||||
theCreatedParticle1->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
|
||||
theCreatedParticle1->setEmissionTime((*i)->getEmissionTime());
|
||||
theCreatedParticle2->boost(beta);
|
||||
theCreatedParticle2->setBiasCollisionVector(theModifiedParticle->getBiasCollisionVector());
|
||||
theCreatedParticle2->setEmissionTime((*i)->getEmissionTime());
|
||||
theModifiedParticle->boost(beta);
|
||||
|
||||
outgoingParticles2.push_back(theCreatedParticle1);
|
||||
outgoingParticles2.push_back(theCreatedParticle2);
|
||||
outgoingParticles2.push_back(theModifiedParticle);
|
||||
}
|
||||
else {
|
||||
INCL_ERROR("Wrong number (< 2) of created particles during the decay of a pion resonance");
|
||||
}
|
||||
delete fs;
|
||||
delete decay;
|
||||
}
|
||||
else {
|
||||
outgoingParticles2.push_back(*i);
|
||||
}
|
||||
}// End of Decay eta and omega
|
||||
|
||||
for(ParticleIter i=outgoingParticles.begin(), e=outgoingParticles.end(); i!=e; ++i ) {
|
||||
for(ParticleIter i=outgoingParticles2.begin(), e=outgoingParticles2.end(); i!=e; ++i ) {
|
||||
theEventInfo.A[theEventInfo.nParticles] = (Short_t)(*i)->getA();
|
||||
theEventInfo.Z[theEventInfo.nParticles] = (Short_t)(*i)->getZ();
|
||||
theEventInfo.S[theEventInfo.nParticles] = (Short_t)(*i)->getS();
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
namespace G4INCL {
|
||||
|
||||
void Cluster::initializeParticles() {
|
||||
// assert(theA>=2);
|
||||
// assert(theA>=2 || theA<=-2);
|
||||
const ThreeVector oldPosition = thePosition;
|
||||
theParticleSampler->sampleParticlesIntoList(thePosition, particles);
|
||||
#if !defined(NDEBUG) && !defined(INCLXX_IN_GEANT4_MODE)
|
||||
|
||||
@@ -57,6 +57,10 @@ namespace G4INCL {
|
||||
ParticleEntryAvatar *bringToSurface(Particle *p, Nucleus * const n) {
|
||||
return theCoulomb->bringToSurface(p, n);
|
||||
}
|
||||
|
||||
ParticleEntryAvatar *bringToSurfaceAbar(Particle *p, Nucleus * const n) {
|
||||
return theCoulomb->bringToSurfaceAbar(p, n);
|
||||
}
|
||||
|
||||
IAvatarList bringToSurface(Cluster * const c, Nucleus * const n) {
|
||||
return theCoulomb->bringToSurface(c, n);
|
||||
|
||||
+25
-4
@@ -59,6 +59,19 @@ namespace G4INCL {
|
||||
// and actually bring the particle to the surface of the nucleus
|
||||
return theCoulombNoneSlave.bringToSurface(p,n);
|
||||
}
|
||||
|
||||
ParticleEntryAvatar *CoulombNonRelativistic::bringToSurfaceAbar(Particle * const p, Nucleus * const n) const {
|
||||
// No distortion for neutral particles
|
||||
if(p->getZ()!=0) {
|
||||
const G4bool success = coulombDeviation(p, n);
|
||||
if(!success) // transparent
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Rely on the CoulombNone slave to compute the straight-line intersection
|
||||
// and actually bring the particle to the surface of the nucleus
|
||||
return theCoulombNoneSlave.bringToSurfaceAbar(p,n);
|
||||
}
|
||||
|
||||
IAvatarList CoulombNonRelativistic::bringToSurface(Cluster * const c, Nucleus * const n) const {
|
||||
// Neutral clusters?!
|
||||
@@ -125,8 +138,12 @@ namespace G4INCL {
|
||||
Nucleus const * const n) const {
|
||||
const G4double theMinimumDistance = minimumDistance(p, kinE, n);
|
||||
G4double rMax = n->getUniverseRadius();
|
||||
if(p.theType == Composite)
|
||||
if(p.theType == Composite){
|
||||
rMax += 2.*ParticleTable::getLargestNuclearRadius(p.theA, p.theZ);
|
||||
}
|
||||
if (p.theType == antiComposite){
|
||||
rMax += 2.*ParticleTable::getLargestNuclearRadius(-(p.theA), -(p.theZ));
|
||||
}
|
||||
const G4double theMaxImpactParameterSquared = rMax*(rMax-theMinimumDistance);
|
||||
if(theMaxImpactParameterSquared<=0.)
|
||||
return 0.;
|
||||
@@ -194,12 +211,16 @@ namespace G4INCL {
|
||||
}
|
||||
|
||||
G4double CoulombNonRelativistic::getCoulombRadius(ParticleSpecies const &p, Nucleus const * const n) const {
|
||||
if(p.theType == Composite) {
|
||||
const G4int Zp = p.theZ;
|
||||
const G4int Ap = p.theA;
|
||||
if(p.theType == Composite || p.theType == antiComposite) {
|
||||
G4int Zp = p.theZ;
|
||||
G4int Ap = p.theA;
|
||||
const G4int Zt = n->getZ();
|
||||
const G4int At = n->getA();
|
||||
G4double barr, radius = 0.;
|
||||
if(p.theType == antiComposite){
|
||||
Zp = -Zp;
|
||||
Ap = -Ap;
|
||||
}
|
||||
if(Zp==1 && Ap==2) { // d
|
||||
barr = 0.2565*Math::pow23((G4double)At)-0.78;
|
||||
radius = PhysicalConstants::eSquared*Zp*Zt/barr - 2.5;
|
||||
|
||||
@@ -55,6 +55,15 @@ namespace G4INCL {
|
||||
} else // If the particle does NOT enter the nucleus
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ParticleEntryAvatar *CoulombNone::bringToSurfaceAbar(Particle * const p, Nucleus * const n) const {
|
||||
Intersection intersection = IntersectionFactory::getEarlierTrajectoryIntersection(p->getPosition(), p->getPropagationVelocity(), n->getUniverseRadius());
|
||||
if(intersection.exists) { // If the particle enters the nucleus
|
||||
p->setPosition(intersection.position);
|
||||
return new ParticleEntryAvatar(0.001, n, p);
|
||||
} else // If the particle does NOT enter the nucleus
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IAvatarList CoulombNone::bringToSurface(Cluster * const c, Nucleus * const n) const {
|
||||
// The avatar list that we will return
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user