Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F8309472
CNucleus.cpp
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
124 KB
Subscribers
None
CNucleus.cpp
View Options
#include
"CNucleus.h"
bool
const
Isig
=
1
;
//in weisskopf, use parametrized Inverse Section
// otherwise calculated them from transmission coeff.
int
CNucleus
::
iHF
=
2
;
//1=Hauser Feshback,0= Weisskopf,2=switches from 0 to 1
bool
const
fissionMassScission
=
0
;
//1=scission-point fission mass dist
//0=saddle-point fission mass dist
float
const
scaleImf
=
1.
;
bool
const
Isaddle
=
0
;
bool
const
Iscission
=
1
;
//float const WignerScaled = 0.; //scaling factor for the Wigner Energy
float
const
WignerAdd
=
7.
;
//adding factor for the Wigner Energy
//the following line needed in the ROOT version
//ClassImp(CNucleus)
bool
CNucleus
::
noIMF
=
0
;
bool
CNucleus
::
BohrWheeler
=
1
;
CRandom
CNucleus
::
ran
;
CYrast
CNucleus
::
yrast
;
CScission
CNucleus
::
scission
;
CLevelDensity
CNucleus
::
levelDensity
;
CAngleDist
CNucleus
::
angleDist
;
float
CNucleus
::
de
=
1.0
;
int
const
CNucleus
::
nStore
=
5000
;
int
const
CNucleus
::
nSub
=
800
;
int
const
CNucleus
::
nSubTl
=
80
;
int
const
CNucleus
::
Nproducts
=
180
;
int
const
CNucleus
::
Nstable
=
100
;
CNucleus
*
CNucleus
::
allProducts
[
Nproducts
]
=
{
0
};
CNucleus
*
CNucleus
::
stableProducts
[
Nstable
]
=
{
0
};
int
CNucleus
::
iProducts
=
0
;
int
CNucleus
::
iStable
=
0
;
float
const
CNucleus
::
r0
=
1.16
;
float
const
CNucleus
::
sep
=
2.
;
float
const
CNucleus
::
pi
=
acos
(
-
1.
);
short
unsigned
CNucleus
::
Zshell
=
2
;
short
unsigned
const
CNucleus
::
lMaxQuantum
=
50
;
CEvap
CNucleus
::
evap
;
float
const
CNucleus
::
gammaInhibition
[
3
]
=
{
0.
,
.025
,
9.
};
float
const
CNucleus
::
wue
[
3
]
=
{
0.
,
6.8e-8
,
4.9e-14
};
//gives weisskopf units in MeV
int
const
CNucleus
::
nGamma
=
4000
;
float
const
CNucleus
::
viscosity_scission
=
1.
;
float
const
CNucleus
::
viscosity_saddle
=
1.5
;
float
CNucleus
::
timeTransient
=
0.
;
//float CNucleus::fissionScaleFactor = 2.46;
float
CNucleus
::
fissionScaleFactor
=
1.00
;
float
CNucleus
::
sumGammaEnergy
=
0.
;
float
CNucleus
::
barAdd
=
0.
;
float
const
CNucleus
::
kRotate
=
41.563
;
bool
const
CNucleus
::
noSymmetry
=
1
;
// no symmetric fission calculated in
// asyFissionWidth if there is a fission peak
int
CNucleus
::
iPoint
=
-
1
;
float
CNucleus
::
threshold
=
.001
;
//*******************************************
/**
* constructor specifies the isotope.
\param iZ0 is the proton number
\param iA0 is the mass number
*/
CNucleus
::
CNucleus
(
int
iZ0
,
int
iA0
)
:
CNuclide
(
iZ0
,
iA0
)
{
bStable
=
0
;
saddleToSciss
=
0
;
timeSinceSaddle
=
0.
;
velocity
[
0
]
=
0.
;
velocity
[
1
]
=
0.
;
velocity
[
2
]
=
0.
;
spin
=
CAngle
((
float
)
0.
,(
float
)
0.
);
daughterLight
=
NULL
;
daughterHeavy
=
NULL
;
parent
=
NULL
;
abortEvent
=
0
;
}
//*******************************************************
/**
* destructor
*/
CNucleus
::~
CNucleus
()
{
//destructor
if
(
daughterLight
!=
NULL
)
{
delete
daughterLight
;
daughterLight
=
NULL
;
}
if
(
daughterHeavy
!=
NULL
)
{
delete
daughterHeavy
;
daughterHeavy
=
NULL
;
}
}
//**************************************************
/**
* Constructor specifying more parameters
\param iZ0 is proton number
\param iA0 is mass number
\param fEx0 is excitation energy in MeV
\param fJ0 is spin in hbar
*/
CNucleus
::
CNucleus
(
int
iZ0
,
int
iA0
,
float
fEx0
,
float
fJ0
)
:
CNuclide
(
iZ0
,
iA0
)
{
//alternative constructor
bStable
=
0
;
saddleToSciss
=
0
;
timeSinceSaddle
=
0.
;
velocity
[
0
]
=
0.
;
velocity
[
1
]
=
0.
;
velocity
[
2
]
=
0.
;
spin
=
CAngle
((
float
)
0.
,(
float
)
0.
);
daughterLight
=
NULL
;
daughterHeavy
=
NULL
;
parent
=
NULL
;
abortEvent
=
0
;
setCompoundNucleus
(
fEx0
,
fJ0
);
}
//**************************************************
/**
* prints out the parameters of the nucleus
*/
void
CNucleus
::
print
()
{
//prints out paramters of nucleus
cout
<<
strName
<<
endl
;
cout
<<
"Z= "
<<
iZ
<<
" A= "
<<
iA
<<
endl
;
cout
<<
"mass excess = "
<<
fExpMass
<<
endl
;
cout
<<
strChemName
<<
endl
;
cout
<<
"Ex= "
<<
fEx
<<
" J= "
<<
fJ
<<
endl
;
cout
<<
"velocity= "
<<
velocity
[
0
]
<<
" "
<<
velocity
[
1
]
<<
" "
<<
velocity
[
2
]
<<
" cm/ns"
<<
endl
;
cout
<<
"KE= "
<<
getKE
()
<<
" MeV"
<<
endl
;
cout
<<
"Ex = "
<<
fEx
<<
endl
;
cout
<<
"spin axis, theta = "
<<
spin
.
theta
*
180.
/
pi
<<
" phi= "
<<
spin
.
phi
*
180
/
pi
<<
" deg"
<<
endl
;
if
(
origin
==
0
)
cout
<<
" preSaddle emission"
<<
endl
;
else
if
(
origin
==
1
)
cout
<<
"saddle-to-scission emission"
<<
endl
;
else
if
(
origin
==
2
)
cout
<<
"from light fission fragment"
<<
endl
;
else
if
(
origin
==
3
)
cout
<<
"from heavy fission fragment"
<<
endl
;
cout
<<
"emission time = "
<<
timeSinceStart
<<
" zs"
<<
endl
;
}
//******************************************************
/**
* produces a single binary decay of the nucleus from statistical-model widths
*/
void
CNucleus
::
binaryDecay
()
{
if
(
bStable
)
return
;
//decay not possible
if
(
notStatistical
)
{
daughterLight
=
new
CNucleus
(
evap
.
decay
[
notStatisticalMode
].
Z1
,
evap
.
decay
[
notStatisticalMode
].
A1
);
daughterHeavy
=
new
CNucleus
(
iZ
-
evap
.
decay
[
notStatisticalMode
].
Z1
,
iA
-
evap
.
decay
[
notStatisticalMode
].
A1
);
daughterLight
->
origin
=
origin
;
daughterHeavy
->
origin
=
origin
;
daughterLight
->
parent
=
this
;
daughterHeavy
->
parent
=
this
;
float
decayTime
=
ran
.
expDecayTime
(
evap
.
decay
[
notStatisticalMode
].
gamma
);
daughterLight
->
timeSinceStart
=
timeSinceStart
+
decayTime
;
daughterHeavy
->
timeSinceStart
=
timeSinceStart
+
decayTime
;
daughterLight
->
excite
(
0.
,
evap
.
decay
[
notStatisticalMode
].
S1
);
daughterHeavy
->
excite
(
0.
,
evap
.
decay
[
notStatisticalMode
].
S2
);
daughterLight
->
bStable
=
1
;
daughterLight
->
iWeight
=
0
;
daughterHeavy
->
iWeight
=
0
;
daughterLight
->
runningWeight
=
runningWeight
;
daughterHeavy
->
runningWeight
=
runningWeight
;
daughterLight
->
fact
=
fact
;
daughterHeavy
->
fact
=
fact
;
//make sure 8Be fragments decay
if
(
iZ
-
evap
.
decay
[
notStatisticalMode
].
Z1
==
4
&&
iA
-
evap
.
decay
[
notStatisticalMode
].
A1
==
8
)
{
daughterHeavy
->
notStatistical
=
1
;
daughterHeavy
->
notStatisticalMode
=
20
;
daughterHeavy
->
bStable
=
0
;
}
else
daughterHeavy
->
bStable
=
1
;
EvapLPlusS
=
evap
.
decay
[
notStatisticalMode
].
lPlusS1
;
EvapL
=
evap
.
decay
[
notStatisticalMode
].
L
;
EvapS1
=
evap
.
decay
[
notStatisticalMode
].
S1
;
EvapS2
=
evap
.
decay
[
notStatisticalMode
].
S2
;
EvapEk
=
evap
.
decay
[
notStatisticalMode
].
Ek
;
EvapA1
=
evap
.
decay
[
notStatisticalMode
].
A1
;
EvapA2
=
iA
-
EvapA1
;
angleEvap
();
// find the emission angles of the two fragments
allProducts
[
iProducts
]
=
daughterLight
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
allProducts
[
iProducts
]
=
daughterHeavy
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
return
;
}
//"statistical" decays into alpha plus ligher partner
if
(
fEx
>
0.
&&
(
iZ
==
3
||
(
iZ
==
2
&&
iA
==
5
)))
{
daughterLight
=
new
CNucleus
(
iZ
-
2
,
iA
-
4
);
daughterHeavy
=
new
CNucleus
(
2
,
4
);
double
Ek
=
fExpMass
+
fEx
-
daughterLight
->
fExpMass
-
daughterHeavy
->
fExpMass
;
if
(
Ek
<=
0.
)
{
delete
daughterLight
;
delete
daughterHeavy
;
daughterLight
=
NULL
;
daughterHeavy
=
new
CNucleus
(
iZ
,
iA
);
daughterHeavy
->
origin
=
origin
;
daughterHeavy
->
parent
=
this
;
daughterHeavy
->
timeSinceStart
=
timeSinceStart
;
daughterHeavy
->
excite
(
0.
,
0.
);
daughterHeavy
->
iWeight
=
iWeight
;
daughterHeavy
->
runningWeight
=
runningWeight
;
daughterHeavy
->
fact
=
fact
;
daughterHeavy
->
bStable
=
1
;
sumGammaEnergy
+=
fEx
;
allProducts
[
iProducts
]
=
daughterHeavy
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
return
;
}
else
{
daughterLight
->
origin
=
origin
;
daughterHeavy
->
origin
=
origin
;
daughterLight
->
parent
=
this
;
daughterHeavy
->
parent
=
this
;
daughterLight
->
timeSinceStart
=
timeSinceStart
;
daughterHeavy
->
timeSinceStart
=
timeSinceStart
;
daughterLight
->
excite
(
0.
,
0.
);
daughterHeavy
->
excite
(
0.
,
0.
);
daughterLight
->
bStable
=
1
;
daughterHeavy
->
bStable
=
1
;
daughterLight
->
iWeight
=
0
;
daughterHeavy
->
iWeight
=
0
;
daughterLight
->
runningWeight
=
runningWeight
;
daughterHeavy
->
runningWeight
=
runningWeight
;
daughterLight
->
fact
=
fact
;
daughterHeavy
->
fact
=
fact
;
//randomise angle
float
theta
=
acos
(
1.
-
2.
*
ran
.
Rndm
());
float
phi
=
2.
*
pi
*
ran
.
Rndm
();
float
vrel
=
sqrt
(
2.
*
Ek
*
(
float
)
iA
/
(((
float
)
iA
-
4.
)
*
4.
))
*
0.9794
;
float
v1
=
vrel
*
4.
/
(
float
)
iA
;
daughterLight
->
velocity
[
0
]
=
v1
*
sin
(
theta
)
*
cos
(
phi
);
daughterLight
->
velocity
[
1
]
=
v1
*
sin
(
theta
)
*
sin
(
phi
);
daughterLight
->
velocity
[
2
]
=
v1
*
cos
(
theta
);
float
v2
=
vrel
-
v1
;
theta
=
pi
-
theta
;
phi
+=
pi
;
daughterHeavy
->
velocity
[
0
]
=
v2
*
sin
(
theta
)
*
cos
(
phi
);
daughterHeavy
->
velocity
[
1
]
=
v2
*
sin
(
theta
)
*
sin
(
phi
);
daughterHeavy
->
velocity
[
2
]
=
v2
*
cos
(
theta
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
daughterLight
->
velocity
[
i
]
+=
velocity
[
i
];
daughterHeavy
->
velocity
[
i
]
+=
velocity
[
i
];
}
allProducts
[
iProducts
]
=
daughterLight
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
allProducts
[
iProducts
]
=
daughterHeavy
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
return
;
}
}
// start change
float
widthAsyFission
=
0.
;
needSymmetricFission
=
false
;
// don;t call asymmetric fission if all asymmetries are handled
// by the evaporation folmalism
if
(
iZ
/
2
>
evap
.
maxZ
)
{
if
(
noIMF
)
needSymmetricFission
=
true
;
else
widthAsyFission
=
asyFissionWidthZA
();
}
float
widthSymFission
=
0.
;
if
(
pow
((
float
)
iZ
,
2
)
/
(
float
)
iA
<
20.
)
needSymmetricFission
=
false
;
//end change
float
widthEvaporation
=
evaporationWidth
();
float
widthGamma
=
gammaWidth
();
float
width
=
widthAsyFission
+
widthEvaporation
+
widthGamma
;
float
decayTime
=
timeSinceStart
;
width
=
widthEvaporation
+
widthGamma
;
decayTime
+=
ran
.
expDecayTime
(
width
);
if
(
decayTime
<
timeTransient
)
{
widthAsyFission
=
0.
;
}
else
{
width
+=
widthAsyFission
;
decayTime
=
timeTransient
+
ran
.
expDecayTime
(
width
);
}
//transient delay for symmetry fission only
if
(
timeSinceStart
<
timeTransient
&&
needSymmetricFission
)
{
decayTime
+=
ran
.
expDecayTime
(
width
);
if
(
decayTime
<
timeTransient
)
{
needSymmetricFission
=
0
;
}
else
decayTime
=
timeTransient
;
}
if
(
needSymmetricFission
)
{
if
(
BohrWheeler
)
widthSymFission
=
BohrWheelerWidth
();
else
widthSymFission
=
LestoneFissionWidth
();
width
+=
widthSymFission
;
decayTime
+=
ran
.
expDecayTime
(
width
);
}
//end transient delay
if
(
isnan
(
width
))
{
cout
<<
" a non valid decay with width (nan) was obtained for "
<<
" Z= "
<<
iZ
<<
" A= "
<<
iA
<<
" Ex= "
<<
fEx
<<
" j= "
<<
fJ
<<
endl
;
cout
<<
"this event will be aborted "
<<
endl
;
cout
<<
"please report this to Bob Charity "
<<
endl
;
abortEvent
=
1
;
return
;
}
if
(
width
==
0
)
{
bStable
=
1
;
return
;
}
if
(
widthGamma
/
width
>
0.99
)
//terminate particle evaporation.
{
bStable
=
1
;
sumGammaEnergy
+=
fEx
;
return
;
}
float
xran
=
ran
.
Rndm
();
if
(
fEx
/
(
float
)
iA
>
6.
)
widthSymFission
=
0.
;
// I switch off fission at excitation
// energies above 6 MeV. Above
// this we get conceptable problems
// with most, or all, of the mass lost
// during the saddle-to-scission
// transition
int
iChan
=
chooseChannel
(
widthEvaporation
,
widthAsyFission
,
widthSymFission
,
widthGamma
,
xran
);
if
(
iChan
==
0
)
//light particle evaporation
{
// choose light [particle channelchannel
float
xran
=
ran
.
Rndm
();
int
i
=
0
;
for
(;;)
{
float
prob
=
evap
.
prob
[
i
]
/
widthEvaporation
;
if
(
prob
>
xran
)
break
;
if
(
i
==
evap
.
nLight
-
1
)
break
;
i
++
;
}
lightP
=
evap
.
lightP
[
i
];
EvapZ1
=
lightP
->
iZ
;
EvapA1
=
lightP
->
iA
;
EvapZ2
=
iZ
-
EvapZ1
;
EvapA2
=
iA
-
EvapA1
;
EvapMode
=
i
;
EvapEx1
=
lightP
->
fEx
;
EvapS1
=
lightP
->
fJ
;
getSpin
((
bool
)
0
);
// find the sum of L + S1
float
lPlusSMin1
=
fabs
((
float
)
EvapL
-
EvapS1
);
float
lPlusSMin2
=
fabs
(
fJ
-
EvapS2
);
float
lPlusSMin
=
max
(
lPlusSMin1
,
lPlusSMin2
);
float
lPlusSMax1
=
(
float
)
EvapL
+
EvapS1
;
float
lPlusSMax2
=
fJ
+
EvapS2
;
float
lPlusSMax
=
min
(
lPlusSMax1
,
lPlusSMax2
);
//the following two lines makes sure random!=1.000
float
random
=
1.5
;
while
(
floor
(
random
)
>
0.5
)
random
=
ran
.
Rndm
();
EvapLPlusS
=
lPlusSMin
+
floor
(
random
*
(
lPlusSMax
-
lPlusSMin
+
1
));
daughterLight
=
new
CNucleus
(
EvapZ1
,
EvapA1
);
daughterHeavy
=
new
CNucleus
(
EvapZ2
,
EvapA2
);
daughterLight
->
origin
=
origin
;
daughterHeavy
->
origin
=
origin
;
daughterLight
->
iWeight
=
0
;
daughterHeavy
->
iWeight
=
iWeight
;
daughterLight
->
runningWeight
=
runningWeight
;
daughterHeavy
->
runningWeight
=
runningWeight
;
daughterLight
->
fact
=
fact
;
daughterHeavy
->
fact
=
fact
;
daughterLight
->
parent
=
this
;
daughterHeavy
->
parent
=
this
;
daughterLight
->
timeSinceStart
=
timeSinceStart
+
decayTime
;
daughterHeavy
->
timeSinceStart
=
daughterLight
->
timeSinceStart
;
daughterLight
->
excite
(
EvapEx1
,
EvapS1
);
daughterHeavy
->
excite
(
EvapEx2
,
EvapS2
);
if
(
evap
.
decay
[
EvapMode
].
Ek
>
0
)
{
daughterLight
->
notStatistical
=
1
;
daughterLight
->
notStatisticalMode
=
EvapMode
;
daughterLight
->
bStable
=
0
;
}
else
daughterLight
->
bStable
=
1
;
angleEvap
();
// find the emission angles of the two fragments
allProducts
[
iProducts
]
=
daughterLight
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
allProducts
[
iProducts
]
=
daughterHeavy
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
}
else
if
(
iChan
==
1
)
//complex fragment or asymmetric fission decay
{
getCompoundNucleus
()
->
bResidue
=
false
;
getCompoundNucleus
()
->
bAsymmetricFission
=
true
;
daughterLight
=
new
CNucleus
(
fissionZ
,
fissionA
);
daughterHeavy
=
new
CNucleus
(
iZ
-
fissionZ
,
iA
-
fissionA
);
daughterLight
->
origin
=
2
;
//origin;
daughterHeavy
->
origin
=
3
;
//origin;
daughterLight
->
iWeight
=
0
;
daughterHeavy
->
iWeight
=
0
;
daughterLight
->
runningWeight
=
runningWeight
;
daughterHeavy
->
runningWeight
=
runningWeight
;
daughterLight
->
fact
=
fact
;
daughterHeavy
->
fact
=
fact
;
daughterLight
->
parent
=
this
;
daughterHeavy
->
parent
=
this
;
daughterLight
->
timeSinceStart
=
timeSinceStart
+
decayTime
;
daughterHeavy
->
timeSinceStart
=
daughterLight
->
timeSinceStart
;
// Coulomb part of kinetic energy
scission
.
init
(
iZ
,
iA
,
fJ
,
iChan
);
scission
.
getFissionKineticEnergy
(
fissionZ
,
fissionA
);
float
Ek
=
scission
.
ekTot
;
levelDensity
.
getLogLevelDensitySpherical
(
iA
,
fissionU
,(
float
)
0.
,(
float
)
0.
,
fJ
,
fMInertia
,
2
);
//add in fluctuations to Coulomb barrier
float
sigma
=
Ek
*
sqrt
(
levelDensity
.
getTemp
())
*
.1
;
//float sigma = 0.;
// fluctuations are in Coulomb energy are gaussian, but make sure the
//Coulomb energy is always positive
// and thermal excitation energy is positive
float
Qvalue
=
fExpMass
-
daughterLight
->
fExpMass
-
daughterHeavy
->
fExpMass
-
scission
.
Erotate1
-
scission
.
Erotate2
;
//Qvalue apart from EK
for
(;;)
{
Ek
=
ran
.
Gaus
(
scission
.
ekTot
,
sigma
);
fissionU
=
fEx
+
Qvalue
-
Ek
;
if
(
Ek
>
0.
&&
fissionU
>
0.
)
break
;
}
//Qvalue -= Ek;
// add the thermal part of kinetic energy
int
const
nE
=
200
;
float
sumE
[
nE
];
int
ie
=
0
;
float
probStart
=
levelDensity
.
getLogLevelDensitySpherical
(
iA
,
fissionU
,(
float
)
0.
,(
float
)
0.
,(
float
)
0.
,
fMInertia
);
for
(;;)
{
float
de
=
(
float
)
ie
*
0.5
+
0.25
;
if
(
de
>=
fissionU
)
break
;
float
prob
=
exp
(
levelDensity
.
getLogLevelDensitySpherical
(
iA
,
fissionU
-
de
,
0.
,
0.
,
0.
,
fMInertia
)
-
probStart
);
sumE
[
ie
]
=
prob
;
if
(
ie
>
0
)
sumE
[
ie
]
+=
sumE
[
ie
-
1
];
ie
++
;
if
(
prob
<
.01
)
break
;
if
(
ie
>=
nE
)
break
;
}
float
de
=
0.
;
if
(
ie
>
0
)
{
xran
=
ran
.
Rndm
();
int
iie
=
0
;
for
(;;)
{
if
(
xran
<
sumE
[
iie
]
/
sumE
[
ie
-
1
])
break
;
iie
++
;
}
de
=
(
float
)
iie
*
0.5
+
0.25
;
Ek
+=
de
;
fissionU
-=
de
;
}
scission
.
ekTot
=
Ek
;
asyFissionDivide
();
// find spin and excitation energy of two fragments
allProducts
[
iProducts
]
=
daughterLight
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
allProducts
[
iProducts
]
=
daughterHeavy
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
}
else
if
(
iChan
==
2
)
//fission decay
{
getCompoundNucleus
()
->
bResidue
=
false
;
getCompoundNucleus
()
->
bSymmetricFission
=
true
;
// start saddle to scission transition
float
Esaddle
=
yrast
.
getSymmetricSaddleEnergy
(
iZ
,
iA
,
fJ
);
Esaddle
-=
fPairing
+
fShell
;
scission
.
init
(
iZ
,
iA
,
fJ
,
2
);
float
Escission
=
scission
.
getScissionEnergy
()
-
fExpMass
;
daughterHeavy
=
new
CNucleus
(
iZ
,
iA
);
//if mass division is determined from energy at saddle point
if
(
fissionMassScission
==
0
)
{
//asyFissionWidthBW(); //try this instead of massAsymmetry()
//if you want
//mass distribution from Sierk's
//asymmetric barriers
massAsymmetry
(
Isaddle
);
bool
const
notSym
=
0
;
daughterHeavy
->
fissionZ
=
fissionZ
;
daughterHeavy
->
fissionA
=
fissionA
;
daughterHeavy
->
fissioningA
=
iA
;
daughterHeavy
->
fissioningZ
=
iZ
;
daughterHeavy
->
sigma2
=
sigma2
;
daughterHeavy
->
iWeight
=
iWeight
;
daughterHeavy
->
runningWeight
=
runningWeight
;
daughterHeavy
->
fact
=
fact
;
daughterHeavy
->
exciteScission
(
fEx
,
fJ
,
notSym
);
if
(
Escission
>=
Esaddle
)
timeScission
=
0.
;
else
timeScission
=
(
Esaddle
-
Escission
)
*
viscosity_saddle
;
}
//else the mass division is determined at scission
else
{
daughterHeavy
->
exciteScission
(
fEx
,
fJ
);
if
(
Escission
>=
Esaddle
)
timeScission
=
0.
;
else
timeScission
=
(
Esaddle
-
Escission
)
*
viscosity_scission
;
}
daughterHeavy
->
timeSinceSaddle
=
0.
;
daughterHeavy
->
timeSinceStart
=
timeSinceStart
+
decayTime
;
daughterHeavy
->
origin
=
1
;
daughterHeavy
->
parent
=
this
;
daughterHeavy
->
setVelocityCartesian
(
velocity
[
0
],
velocity
[
1
],
velocity
[
2
]);
daughterHeavy
->
setSpinAxis
(
spin
);
daughterHeavy
->
timeScission
=
timeScission
;
daughterLight
=
NULL
;
allProducts
[
iProducts
]
=
daughterHeavy
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
}
else
//gamma decay
{
sumGammaEnergy
+=
fEx
-
GammaEx
;
daughterLight
=
NULL
;
daughterHeavy
=
new
CNucleus
(
iZ
,
iA
);
daughterHeavy
->
origin
=
origin
;
daughterHeavy
->
parent
=
this
;
daughterHeavy
->
timeSinceStart
=
timeSinceStart
+
decayTime
;
daughterHeavy
->
excite
(
GammaEx
,
GammaJ
);
daughterHeavy
->
iWeight
=
iWeight
;
daughterHeavy
->
runningWeight
=
runningWeight
;
daughterHeavy
->
fact
=
fact
;
angleGamma
();
allProducts
[
iProducts
]
=
daughterHeavy
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
}
}
//************************************************************
/**
* fission mass division - uses the Rusanov systemtics to
* determine the fission-fragment mass distribution.
* \param saddleOrScission is true then the third Rusanov systematics
* are used, i.e., variance is determined from the temperature at the
* scission point
* if false, the second Rusanov systematics is used, i.e, the
* variance is determined from the temperature at the saddle point
*/
void
CNucleus
::
massAsymmetry
(
bool
saddleOrScission
)
{
// variance from systemacs
if
(
saddleOrScission
==
1
)
//asymmetry determined at scission point
sigma2
=
scission
.
sigmaFissionSystematicsScission
(
iZ
,
iA
,
fJ
,
fU0
);
else
//asymmetry determined at saddle point
{
sigma2
=
scission
.
sigmaFissionSystematicsSaddle
(
iZ
,
iA
,
fJ
,
fEx
-
symSaddlePoint
);
fU0
=
fEx
-
symSaddlePoint
;
}
//at this point fU0 is the thermal excitation energy above the
//configuration for symmetric division.
int
const
nStore
=
1000
;
SStore
store
[
nStore
];
int
iStore
=
0
;
int
iZ1
,
iZ2
,
iA1
,
iA2
;
iA1
=
iA
/
2
;
float
Amax
=
0.
;
//float gammaAOld = 1e32;
double
gammaTot
=
0.
;
for
(;;)
{
iA2
=
iA
-
iA1
;
int
iZ1Start
=
(
int
)((
float
)
iA1
/
(
float
)
iA
*
(
float
)
iZ
);
iZ1
=
max
(
3
,
iZ1Start
-
8
);
float
Zmax
=
0.
;
float
gammaA
=
0.
;
for
(;;)
{
iZ2
=
iZ
-
iZ1
;
if
(
iZ2
<=
(
float
)
iZ
/
17.
)
break
;
if
(
iA1
==
iA2
&&
iZ1
>
iZ2
)
break
;
//no double counting
//see if fragments are listed in mass table
if
(
mass
->
chart
.
getIndex
(
iZ1
,
iA1
)
<
0
||
mass
->
chart
.
getIndex
(
iZ2
,
iA2
)
<
0
)
{
iZ1
++
;
continue
;
}
float
scissionE
=
scission
.
getScissionEnergy
(
iZ1
,
iA1
);
// fU0 has the asymmetric saddle or scission energy removed
float
U
=
fU0
-
scissionE
+
scission
.
Esymmetric
;
if
(
U
<=
0.
)
{
if
(
iZ1
>
iZ1Start
)
break
;
iZ1
++
;
continue
;
}
float
logLevelDensitySciss
=
levelDensity
.
getLogLevelDensityScission
(
iA
,
U
,
10.
);
if
(
logLevelDensitySciss
==
0
)
{
if
(
iZ
>
iZ1Start
)
break
;
iZ1
++
;
continue
;
}
float
gamma
=
exp
(
logLevelDensitySciss
-
logLevelDensity
);
if
(
iA1
==
iA2
&&
iZ1
==
iZ2
)
gamma
/=
2.
;
gammaA
+=
gamma
;
store
[
iStore
].
gamma
=
(
double
)
gamma
;
store
[
iStore
].
iZ
=
iZ1
;
store
[
iStore
].
iA
=
iA1
;
iStore
++
;
if
(
iStore
>=
nStore
)
{
cout
<<
" increase nStore in saddleToScission "
<<
endl
;
abort
();
}
Zmax
=
max
(
gamma
,
Zmax
);
if
(
gamma
<
Zmax
*
.01
)
break
;
iZ1
++
;
}
// rescale widths so the sum for each A has a gausiian distribution
//with the widths from systematics
if
(
gammaA
>
0.
)
{
float
prob
=
exp
(
-
pow
((
float
)(
iA1
-
iA2
)
/
2.
,
2
)
/
2.
/
sigma2
);
if
(
iA1
==
iA2
)
prob
/=
2.
;
double
scale
=
prob
/
gammaA
;
int
jj
=
iStore
-
1
;
for
(;;)
{
if
(
jj
<
0
)
break
;
if
(
store
[
jj
].
iA
!=
iA1
)
break
;
store
[
jj
].
gamma
*=
scale
;
jj
--
;
}
gammaTot
+=
prob
;
Amax
=
max
(
Amax
,
prob
);
if
(
prob
<
Amax
*
0.001
)
break
;
}
else
break
;
iA1
--
;
if
(
iA1
<
(
float
)
iA
/
17.
)
break
;
}
if
(
iStore
==
0
)
{
//this shouldn't be possible, but this statement is here just in
//case or else the program would get stuck in the following loop
fissionZ
=
iZ
/
2
;
fissionA
=
iA
/
2
;
cout
<<
"iStore == 0 in saddle to scission"
<<
endl
;
cout
<<
" A = "
<<
iA
<<
" Z = "
<<
iZ
<<
" J= "
<<
fJ
<<
" Ex= "
<<
fEx
<<
" U= "
<<
fU0
<<
endl
;
}
else
{
for
(
int
i
=
1
;
i
<
iStore
;
i
++
)
store
[
i
].
gamma
+=
store
[
i
-
1
].
gamma
;
double
xran
=
ran
.
Rndm
();
int
i
=
0
;
for
(;;)
{
double
prob
=
store
[
i
].
gamma
/
store
[
iStore
-
1
].
gamma
;
if
(
prob
>
xran
)
break
;
if
(
i
==
iStore
-
1
)
break
;
i
++
;
}
fissionZ
=
store
[
i
].
iZ
;
fissionA
=
store
[
i
].
iA
;
}
iZ1
=
fissionZ
;
iZ2
=
iZ
-
iZ1
;
iA1
=
fissionA
;
iA2
=
iA
-
iA1
;
}
//************************************************************
/**
* Treats the saddle to scission evaporations
*/
void
CNucleus
::
saddleToScission
()
{
EvapEx2
=
0.
;
float
widthEvaporation
=
evaporationWidthSS
();
float
timeDecay
=
ran
.
expDecayTime
(
widthEvaporation
);
float
newTime
;
if
(
widthEvaporation
==
0
)
newTime
=
100000.
;
else
newTime
=
timeSinceSaddle
+
timeDecay
;
if
(
newTime
<
timeScission
&&
EvapEx2
>
15.
)
{
daughterLight
=
new
CNucleus
(
EvapZ1
,
EvapA1
);
daughterLight
->
origin
=
1
;
daughterLight
->
iWeight
=
0
;
daughterLight
->
runningWeight
=
runningWeight
;
daughterLight
->
fact
=
fact
;
daughterLight
->
timeSinceStart
=
timeSinceStart
+
timeDecay
;
daughterLight
->
timeSinceSaddle
=
newTime
;
daughterHeavy
=
new
CNucleus
(
EvapZ2
,
EvapA2
);
daughterHeavy
->
timeSinceSaddle
=
newTime
;
daughterHeavy
->
origin
=
1
;
daughterHeavy
->
iWeight
=
0
;
daughterHeavy
->
runningWeight
=
runningWeight
;
daughterHeavy
->
fact
=
fact
;
daughterHeavy
->
timeSinceStart
=
daughterLight
->
timeSinceStart
;
daughterHeavy
->
timeScission
=
timeScission
;
daughterLight
->
excite
(
EvapEx1
);
daughterHeavy
->
sigma2
=
sigma2
;
daughterHeavy
->
fissionZ
=
fissionZ
;
daughterHeavy
->
fissionA
=
fissionA
;
daughterHeavy
->
fissioningZ
=
fissioningZ
;
daughterHeavy
->
fissioningA
=
fissioningA
;
daughterHeavy
->
exciteScission
(
EvapEx2
,
fJ
,
fissionMassScission
);
daughterLight
->
parent
=
this
;
daughterHeavy
->
parent
=
this
;
if
(
evap
.
decay
[
EvapMode
].
Ek
>
0
)
{
daughterLight
->
notStatistical
=
1
;
daughterLight
->
notStatisticalMode
=
EvapMode
;
daughterLight
->
bStable
=
0
;
}
angleIsotropic
();
// find the emission angles of the two fragments
CAngle
angle
(
0.
,
0.
);
daughterLight
->
setSpinAxis
(
angle
);
daughterHeavy
->
setSpinAxis
(
spin
);
allProducts
[
iProducts
]
=
daughterLight
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
allProducts
[
iProducts
]
=
daughterHeavy
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
}
else
{
if
(
fissionMassScission
)
massAsymmetry
(
Iscission
);
else
{
float
Z
=
(
float
)
fissionZ
/
(
float
)
fissioningZ
*
(
float
)
iZ
;
float
A
=
(
float
)
fissionA
/
(
float
)
fissioningA
*
(
float
)
iA
;
fissionZ
=
(
int
)
Z
;
fissionA
=
(
int
)
A
;
if
(
ran
.
Rndm
()
<
Z
-
(
float
)
fissionZ
)
fissionZ
++
;
if
(
ran
.
Rndm
()
<
A
-
(
float
)
fissionA
)
fissionA
++
;
}
// go back to the separation that gives us the correct
// fission kinetic energy
scission
.
sep
=
scission
.
sep0
;
float
scissionE
=
scission
.
getScissionEnergy
(
fissionZ
,
fissionA
);
// for later us calculate fission kinetic energy and rotational
// energy of each fragment
scission
.
getFissionKineticEnergy
(
fissionZ
,
fissionA
);
scissionE
-=
fExpMass
;
fissionU
=
fEx
-
scissionE
;
fissionU
=
max
((
float
)
0.
,
fissionU
);
daughterLight
=
new
CNucleus
(
fissionZ
,
fissionA
);
daughterLight
->
origin
=
2
;
daughterLight
->
parent
=
this
;
daughterLight
->
iWeight
=
0
;
daughterLight
->
runningWeight
=
runningWeight
;
daughterLight
->
fact
=
fact
;
daughterLight
->
timeSinceStart
=
timeSinceStart
-
timeSinceSaddle
+
timeScission
;
daughterHeavy
=
new
CNucleus
(
iZ
-
fissionZ
,
iA
-
fissionA
);
daughterHeavy
->
origin
=
3
;
daughterHeavy
->
parent
=
this
;
daughterHeavy
->
iWeight
=
0
;
daughterHeavy
->
runningWeight
=
runningWeight
;
daughterHeavy
->
fact
=
fact
;
daughterHeavy
->
timeSinceStart
=
daughterLight
->
timeSinceStart
;
asyFissionDivide
();
allProducts
[
iProducts
]
=
daughterLight
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
allProducts
[
iProducts
]
=
daughterHeavy
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
}
}
//************************************************************
/**
* forces decay of 8Be
*/
void
CNucleus
::
force8Be
()
{
daughterLight
=
new
CNucleus
(
2
,
4
);
daughterHeavy
=
new
CNucleus
(
2
,
4
);
daughterLight
->
origin
=
origin
;
daughterHeavy
->
origin
=
origin
;
daughterLight
->
parent
=
this
;
daughterHeavy
->
parent
=
this
;
daughterHeavy
->
notStatistical
=
false
;
daughterLight
->
notStatistical
=
false
;
daughterLight
->
excite
(
0.
,
0.
);
daughterHeavy
->
excite
(
0.
,
0.
);
daughterLight
->
bStable
=
1
;
daughterHeavy
->
bStable
=
1
;
float
width
;
if
(
fEx
<
1.
)
width
=
5e-6
;
// use ground state experimental width
else
width
=
1.53
;
//use first excited state experimental width
float
decayTime
=
timeSinceStart
+
ran
.
expDecayTime
(
width
);
daughterLight
->
timeSinceStart
=
decayTime
;
daughterHeavy
->
timeSinceStart
=
decayTime
;
EvapLPlusS
=
fJ
;
EvapL
=
(
int
)
fJ
;
EvapS1
=
0.
;
EvapS2
=
0.
;
EvapEk
=
fEx
+
0.0918
;
EvapA1
=
4
;
EvapA2
=
4
;
angleEvap
();
// find the emission angles of the two fragments
allProducts
[
iProducts
]
=
daughterLight
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
allProducts
[
iProducts
]
=
daughterHeavy
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
return
;
}
//************************************************************
/**
* forces decay of 5Li
*/
void
CNucleus
::
force5Li
()
{
daughterLight
=
new
CNucleus
(
1
,
1
);
daughterHeavy
=
new
CNucleus
(
2
,
4
);
daughterLight
->
origin
=
origin
;
daughterHeavy
->
origin
=
origin
;
daughterLight
->
parent
=
this
;
daughterHeavy
->
parent
=
this
;
daughterHeavy
->
notStatistical
=
false
;
daughterLight
->
notStatistical
=
false
;
daughterLight
->
excite
(
0.
,
0.5
);
daughterHeavy
->
excite
(
0.
,
0.
);
daughterLight
->
bStable
=
1
;
daughterHeavy
->
bStable
=
1
;
float
const
width
=
1.23
;
float
decayTime
=
timeSinceStart
+
ran
.
expDecayTime
(
width
);
daughterLight
->
timeSinceStart
=
decayTime
;
daughterHeavy
->
timeSinceStart
=
decayTime
;
EvapLPlusS
=
fJ
;
EvapL
=
(
int
)(
fJ
-
0.5
);
EvapS1
=
0.
;
EvapS2
=
0.
;
EvapEk
=
fEx
+
1.69
;
EvapA1
=
1
;
EvapA2
=
4
;
angleEvap
();
// find the emission angles of the two fragments
allProducts
[
iProducts
]
=
daughterLight
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
allProducts
[
iProducts
]
=
daughterHeavy
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
return
;
}
//************************************************************
/**
* forces decay of 5He
*/
void
CNucleus
::
force5He
()
{
daughterLight
=
new
CNucleus
(
0
,
1
);
daughterHeavy
=
new
CNucleus
(
2
,
4
);
daughterLight
->
origin
=
origin
;
daughterHeavy
->
origin
=
origin
;
daughterLight
->
parent
=
this
;
daughterHeavy
->
parent
=
this
;
daughterHeavy
->
notStatistical
=
false
;
daughterLight
->
notStatistical
=
false
;
daughterLight
->
excite
(
0.
,
0.5
);
daughterHeavy
->
excite
(
0.
,
0.
);
daughterLight
->
bStable
=
1
;
daughterHeavy
->
bStable
=
1
;
float
const
width
=
.648
;
float
decayTime
=
timeSinceStart
+
ran
.
expDecayTime
(
width
);
daughterLight
->
timeSinceStart
=
decayTime
;
daughterHeavy
->
timeSinceStart
=
decayTime
;
EvapLPlusS
=
fJ
;
EvapL
=
(
int
)(
fJ
-
0.5
);
EvapS1
=
0.
;
EvapS2
=
0.
;
EvapEk
=
fEx
+
0.798
;
EvapA1
=
1
;
EvapA2
=
4
;
angleEvap
();
// find the emission angles of the two fragments
allProducts
[
iProducts
]
=
daughterLight
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
allProducts
[
iProducts
]
=
daughterHeavy
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
return
;
}
//************************************************************
/**
* forces decay of 9B
*/
void
CNucleus
::
force9B
()
{
daughterLight
=
new
CNucleus
(
1
,
1
);
daughterHeavy
=
new
CNucleus
(
4
,
8
);
daughterLight
->
origin
=
origin
;
daughterHeavy
->
origin
=
origin
;
daughterLight
->
excite
(
0.
,
0.5
);
daughterHeavy
->
excite
(
0.
,
0.
);
daughterLight
->
bStable
=
1
;
daughterHeavy
->
bStable
=
1
;
daughterLight
->
parent
=
this
;
daughterHeavy
->
parent
=
this
;
daughterHeavy
->
notStatistical
=
false
;
daughterLight
->
notStatistical
=
false
;
float
const
width
=
.54E-3
;
float
decayTime
=
timeSinceStart
+
ran
.
expDecayTime
(
width
);
daughterLight
->
timeSinceStart
=
decayTime
;
daughterHeavy
->
timeSinceStart
=
decayTime
;
EvapLPlusS
=
fJ
;
EvapL
=
(
int
)(
fJ
-
0.5
);
EvapS1
=
0.
;
EvapS2
=
0.
;
EvapEk
=
fEx
+
0.1851
;
EvapA1
=
1
;
EvapA2
=
8
;
angleEvap
();
// find the emission angles of the two fragments
allProducts
[
iProducts
]
=
daughterLight
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
allProducts
[
iProducts
]
=
daughterHeavy
;
iProducts
++
;
if
(
iProducts
==
Nproducts
)
{
cout
<<
"increase Nproducts"
<<
endl
;
abort
();
}
return
;
}
//**********************************************************
/**
* recursive function does multiple binary decays until excitation energy
* is exhausted.
*
* After executation, the pointer array allProducts- points to each of the
*intermediate and final products produced. The array stableProducts points
* to just the final stable products. This array can be accessed to get
* these fragments
*/
void
CNucleus
::
recursiveDecay
()
{
if
(
!
bStable
)
{
if
(
saddleToSciss
)
saddleToScission
();
else
binaryDecay
();
if
(
abortEvent
)
return
;
}
if
(
bStable
)
{
//first force the decay of fragments that are unstable in their ground state
if
(
iZ
==
4
&&
iA
==
8
)
force8Be
();
else
if
(
iZ
==
5
&&
iA
==
9
)
force9B
();
else
if
(
iZ
==
3
&&
iA
==
5
)
force5Li
();
else
if
(
iZ
==
2
&&
iA
==
5
)
force5He
();
else
{
stableProducts
[
iStable
]
=
this
;
iStable
++
;
if
(
iStable
==
Nstable
)
{
cout
<<
"increase Nstable"
<<
endl
;
abort
();
}
return
;
}
}
//daughterLight->print();
if
(
daughterLight
!=
NULL
)
{
daughterLight
->
recursiveDecay
();
if
(
daughterLight
->
abortEvent
)
{
abortEvent
=
1
;
return
;
}
}
//daughterHeavy->print();
//cout << daughterHeavy->iZ << " " << daughterHeavy->iA << " " << daughterHeavy->spin.theta << endl;
//if (daughterHeavy->iA > 180) cout << daughterHeavy->spin.theta << endl;
daughterHeavy
->
recursiveDecay
();
if
(
daughterHeavy
->
abortEvent
)
{
abortEvent
=
1
;
return
;
}
}
//**********************************************************
/**
* set the pointers to the static arrays of products to NULL.
*
*/
void
CNucleus
::
resetGlobal
()
{
for
(
int
i
=
iProducts
-
1
;
i
>=
0
;
i
--
)
{
allProducts
[
i
]
->
daughterLight
=
NULL
;
allProducts
[
i
]
->
daughterHeavy
=
NULL
;
delete
allProducts
[
i
];
allProducts
[
i
]
=
NULL
;
}
for
(
int
i
=
0
;
i
<
iStable
;
i
++
)
stableProducts
[
i
]
=
NULL
;
iProducts
=
0
;
iStable
=
0
;
iPoint
=
-
1
;
}
//*********************************************************
/**
* This reset function should be used before starting another statistical
* decay.
*/
void
CNucleus
::
reset
()
{
//local reset
resetGlobal
();
daughterLight
=
NULL
;
daughterHeavy
=
NULL
;
bStable
=
0
;
}
//***************************************************
/**
* Prints out the information on all the stable decay products
* produced in the statistical decay
*/
void
CNucleus
::
printStableProducts
()
{
for
(
int
i
=
0
;
i
<
iStable
;
i
++
)
{
stableProducts
[
i
]
->
print
();
}
}
//*******************************************************************
/**
* Prints out information on all products (stable and intermediates)
* formed in the statistical decay
*/
void
CNucleus
::
printAllProducts
()
{
// prints out the information on qll of the decay products
for
(
int
i
=
0
;
i
<
iProducts
;
i
++
)
{
allProducts
[
i
]
->
print
();
}
}
//****************************************************************
/**
* sets the excitation energy and spin of the compound nucleus.
\param fEx0 is the excitation energy in MeV
\param dJ0 is the spin in units of hbar
*/
void
CNucleus
::
excite
(
float
fEx0
,
double
dJ0
)
{
excite
(
fEx0
,(
float
)
dJ0
);
}
//****************************************************************
/**
* sets the excitation energy and spin of the compound nucleus.
\param dEx0 is the excitation energy in MeV
\param dJ0 is the spin in units of hbar
*/
void
CNucleus
::
excite
(
double
dEx0
,
double
dJ0
)
{
excite
((
float
)
dEx0
,(
float
)
dJ0
);
}
//****************************************************************
/**
* sets the excitation energy and spin of the compound nucleus.
\param dEx0 is the excitation energy in MeV
\param fJ0 is the spin in units of hbar
*/
void
CNucleus
::
excite
(
double
dEx0
,
float
fJ0
)
{
excite
((
float
)
dEx0
,
fJ0
);
}
//*****************************************************************
/**
* sets the excitation energy and spin of the compound nucleus.
\param fEx0 is the excitation energy in MeV
\param fJ0 is the spin in units of hbar
*/
void
CNucleus
::
excite
(
float
fEx0
,
float
fJ0
)
{
//initialized the excitation of the nucleus
//calculates the level density
notStatistical
=
0
;
fEx
=
fEx0
;
//make sure we have either interg spin for even mass or half interger
// spin for odd mass
fJ
=
floor
(
fJ0
);
if
(
iA
%
2
==
1
)
fJ
+=
0.5
;
if
(
fEx
==
0.
)
{
bStable
=
1
;
return
;
}
EdefScission
=
0.
;
fPairing
=
mass
->
getPairing
(
iZ
,
iA
);
fShell
=
mass
->
getShellCorrection
(
iZ
,
iA
);
//fShell = fExpMass - mass.getLiquidDropMass(iZ,iA) - fPairing;
if
(
iZ
<=
Zshell
)
{
fPairing
=
0.
;
fShell
=
0.
;
}
//note1
//old code with standard SM treatment of yrast line
Erot
=
yrast
.
getYrast
(
iZ
,
iA
,
fJ
);
//new code
//spheroid.init(iZ,iA);
//deformation = spheroid.getDeformationProlate(fJ);
//Erot = spheroid.getRotatePlusDefEnergy(fJ);
//end change
fMInertia
=
0.4
*
pow
(
r0
,
2
)
*
pow
((
float
)
iA
,(
float
)(
5.
/
3.
));
fU0
=
fEx
-
Erot
;
if
(
fU0
<
0.
)
{
bStable
=
1
;
return
;
}
//decide if to use Hauser-Feshback calculation
HF
=
0
;
if
(
(
Erot
>
fU0
/
4.
&&
fJ
>
10
)
||
iHF
==
1
)
HF
=
1
;
logLevelDensity
=
levelDensity
.
getLogLevelDensitySpherical
(
iA
,
fU0
,
fPairing
,
fShell
,
fJ
,
fMInertia
);
/* // mod TU
if (fU0 < 0. || fU0 > 2000.)
{
cout << "Ex= " << fEx << "Erot= " << Erot << " iZ = " << iZ
<< " iA= " << iA << " excite" << endl;
}
*/
// mod TU
temp
=
levelDensity
.
getTemp
();
if
(
logLevelDensity
==
0.
)
{
bStable
=
1
;
return
;
}
}
//*****************************************************************
/**
* sets the excitation energy and of the compound nucleus
* for a Weisskopf calculation (Spin not considered).
\param fEx0 is the excitation energy in MeV
*/
void
CNucleus
::
excite
(
float
fEx0
)
{
//initialized the excitation of the nucleus
//calculates the level density
HF
=
0
;
notStatistical
=
0
;
fEx
=
fEx0
;
fJ
=
0.
;
fU0
=
fEx
;
if
(
fU0
<
0.
)
{
bStable
=
1
;
return
;
}
EdefScission
=
0.
;
fPairing
=
mass
->
getPairing
(
iZ
,
iA
);
fShell
=
mass
->
getShellCorrection
(
iZ
,
iA
);
//fShell = fExpMass - mass.getLiquidDropMass(iZ,iA) - fPairing;
if
(
iZ
<=
Zshell
)
{
fPairing
=
0.
;
fShell
=
0.
;
}
Erot
=
0.
;
logLevelDensity
=
levelDensity
.
getLogLevelDensitySpherical
(
iA
,
fU0
,
fPairing
,
fShell
);
if
(
fU0
<
0.
||
fU0
>
2000.
)
{
cout
<<
"Ex= "
<<
fEx
<<
"Erot= "
<<
Erot
<<
" iZ = "
<<
iZ
<<
" iA= "
<<
iA
<<
" excite "
<<
endl
;
}
temp
=
levelDensity
.
getTemp
();
if
(
logLevelDensity
==
0.
)
{
bStable
=
1
;
return
;
}
}
//**********************************************************************
/**
* Initializes the excitation of the nucleus at its scission point
* and calculates the level density
*/
void
CNucleus
::
exciteScission
(
float
fEx0
,
float
fJ0
,
bool
sym
/*=1*/
)
{
saddleToSciss
=
1
;
notStatistical
=
0
;
HF
=
0
;
fEx
=
fEx0
;
//make sure we have either interg spin for even mass or half interger
// spin for odd mass
fJ
=
floor
(
fJ0
);
if
(
iA
%
2
==
1
)
fJ
+=
0.5
;
if
(
sym
)
{
scission
.
init
(
iZ
,
iA
,
fJ
,
2
);
EdefScission
=
scission
.
getScissionEnergy
();
}
else
{
float
Z1
=
(
float
)
fissionZ
/
(
float
)
fissioningZ
*
(
float
)
iZ
;
float
A1
=
(
float
)
fissionA
/
(
float
)
fissioningA
*
(
float
)
iA
;
scission
.
init
(
iZ
,
iA
,
fJ
,
2
,
Z1
,
A1
);
EdefScission
=
scission
.
getScissionEnergy
();
}
EdefScission
-=
fExpMass
;
fPairing
=
0.
;
fShell
=
0.
;
Erot
=
0.
;
if
(
fEx
-
EdefScission
<=
0.
)
{
bStable
=
1
;
return
;
}
//thermal excitation energy above the scission-point configuration
fU0
=
fEx
-
Erot
-
EdefScission
;
if
(
fU0
<
0.
)
{
bStable
=
1
;
return
;
}
logLevelDensity
=
levelDensity
.
getLogLevelDensityScission
(
iA
,
fU0
);
if
(
fU0
<
0
||
fU0
>
2000
)
{
cout
<<
"fU0 = "
<<
fU0
<<
" fEx= "
<<
fEx
<<
" Erot= "
<<
Erot
<<
"EdefScission= "
<<
EdefScission
<<
" iZ = "
<<
iZ
<<
"iA= "
<<
iA
<<
" fJ= "
<<
fJ
<<
" exciteScission "
<<
endl
;
}
temp
=
levelDensity
.
getTemp
();
if
(
logLevelDensity
==
0.
)
{
bStable
=
1
;
return
;
}
}
//**********************************************************************
/**
* Returns the transition-state decay width.
\param saddlePoint is the saddle-point energy in MeV
\param iAfAn indicates that the saddle-point ld parameter is increased by afan
*/
/*
float CNucleus::getWidthZA(float saddlePoint,short iAfAn)
{
if (saddlePoint > fEx) return 0.;
float U = fEx - saddlePoint;
float saddleLD = levelDensity.
getLogLevelDensitySpherical(iA,U,(float)0.,(float)0.,
fJ,fMInertia,iAfAn);
if (saddleLD == 0.) return 0.;
if (saddleLD - logLevelDensity < -65.) return 0.;
float gamma = exp(saddleLD-logLevelDensity)
*levelDensity.getTemp()/2./pi;
return gamma;
}
*/
float
CNucleus
::
getWidthZA
(
float
saddlePoint
,
short
iAfAn
)
{
if
(
saddlePoint
>
fEx
)
return
0.
;
float
U
=
fEx
-
saddlePoint
;
float
const
deltaEk
=
0.2
;
float
gamma
=
0.
;
float
gammaMax
=
0.
;
for
(;;)
{
float
saddleLD
=
levelDensity
.
getLogLevelDensitySpherical
(
iA
,
U
,(
float
)
0.
,(
float
)
0.
,
fJ
,
fMInertia
,
iAfAn
);
if
(
saddleLD
==
0.
)
break
;
if
(
saddleLD
-
logLevelDensity
<
-
65.
)
break
;
float
gamma0
=
exp
(
saddleLD
-
logLevelDensity
)
/
2.
/
pi
;
gammaMax
=
max
(
gammaMax
,
gamma0
);
gamma
+=
gamma0
*
deltaEk
;
if
(
gamma0
<
gammaMax
/
200.
)
break
;
U
-=
deltaEk
;
if
(
U
<=
0.
)
break
;
}
return
gamma
;
}
//*************************************************************************
/**
* Calculates the asymmetric decay width in MeV from the gammaZ formalism.
*
* if noSymmetry = 1 then it only includes channels outside of the fission peak
*/
float
CNucleus
::
asyFissionWidth
()
{
short
iAfAn
=
2
;
int
const
nStore
=
1000
;
SStore
store
[
1000
];
needSymmetricFission
=
0
;
int
iStore
=
0
;
float
gammaTot
=
0
;
float
saddlePointOld
=
-
10000.
;
yrast
.
prepareAsyBarrier
(
iZ
,
iA
,
fJ
);
//float Wigner0 = yrast.WignerEnergy(iZ,iA);
scission
.
init
(
iZ
,
iA
,
fJ
,
1
);
for
(
int
iZ1
=
evap
.
maxZ
+
1
;
iZ1
<=
iZ
/
2
;
iZ1
++
)
{
int
iZ2
=
iZ
-
iZ1
;
float
A1
=
(
float
)
iZ1
/
(
float
)
iZ
*
float
(
iA
);
float
saddlePoint
=
yrast
.
getSaddlePointEnergy
(
A1
);
saddlePoint
=
(
saddlePoint
-
Erot
)
*
scaleImf
+
Erot
;
//add on a Wigner energy
//saddlePoint += WignerScaled*Wigner0 + WignerAdd;
saddlePoint
+=
WignerAdd
;
if
(
iZ
>
Zshell
)
saddlePoint
-=
fPairing
+
fShell
;
if
(
noSymmetry
&&
saddlePoint
<
saddlePointOld
&&
iZ1
>
8
)
{
if
(
iZ
/
2
-
iZ1
>
5
&&
iA
>
120
)
{
needSymmetricFission
=
1
;
break
;
}
}
else
saddlePointOld
=
saddlePoint
;
float
gammaZ0
=
getWidthZA
(
saddlePoint
,
iAfAn
);
if
(
iZ1
==
iZ
-
iZ1
)
gammaZ0
/=
2.
;
if
(
gammaZ0
<=
0.
)
continue
;
int
iaMin1
=
mass
->
chart
.
getAmin
(
iZ1
);
int
iaMin2
=
iA
-
mass
->
chart
.
getAmax
(
iZ
-
iZ1
);
int
iaMin
=
max
(
iaMin1
,
iaMin2
);
int
iaMax1
=
mass
->
chart
.
getAmax
(
iZ1
);
int
iaMax2
=
iA
-
mass
->
chart
.
getAmin
(
iZ
-
iZ1
);
int
iaMax
=
min
(
iaMax1
,
iaMax2
);
if
(
iZ1
==
iZ
-
iZ1
)
iaMax
=
min
(
iA
/
2
,
iaMax
);
float
gammaZ
=
0
;
int
iStart
=
iStore
;
for
(
int
iA1
=
iaMin
;
iA1
<=
iaMax
;
iA1
++
)
{
int
iA2
=
iA
-
iA1
;
//make sure I can conserve energy latter
float
mass1
=
mass
->
getCalMass
(
iZ1
,
iA1
);
float
mass2
=
mass
->
getCalMass
(
iZ2
,
iA2
);
scission
.
getFissionKineticEnergy
(
iZ1
,
iA1
);
float
Qvalue
=
fExpMass
-
mass1
-
mass2
-
scission
.
ekTot
-
scission
.
Erotate1
-
scission
.
Erotate2
;
if
(
fEx
+
Qvalue
<=
0.
)
continue
;
float
saddlePoint
=
yrast
.
getSaddlePointEnergy
(
iZ1
,
iA1
);
saddlePoint
=
(
saddlePoint
-
Erot
)
*
scaleImf
+
Erot
;
//add on a congruence energy
//float Wigner1 = yrast.WignerEnergy(iZ1,iA1);
//float Wigner2 = yrast.WignerEnergy(iZ2,iA2);
//saddlePoint += WignerScaled*(Wigner1+Wigner2-Wigner0) + WignerAdd;
saddlePoint
+=
WignerAdd
;
if
(
iZ
>
Zshell
)
saddlePoint
-=
fPairing
+
fShell
;
float
gamma
=
getWidthZA
(
saddlePoint
,
iAfAn
);
if
(
iZ1
==
iZ
-
iZ1
&&
iA1
==
iA
-
iA1
)
gamma
/=
2.
;
if
(
gamma
<=
0.
)
continue
;
store
[
iStore
].
gamma
=
gamma
;
store
[
iStore
].
iZ
=
iZ1
;
store
[
iStore
].
iA
=
iA1
;
iStore
++
;
if
(
iStore
==
nStore
)
{
cout
<<
"increase nStore in asyFissionWidth"
<<
endl
;
abort
();
}
gammaZ
+=
gamma
;
}
// normalize gamma
if
(
gammaZ
==
0.
)
iStore
=
iStart
;
else
{
for
(
int
j
=
iStart
;
j
<
iStore
;
j
++
)
store
[
j
].
gamma
*=
gammaZ0
/
gammaZ
;
gammaTot
+=
gammaZ0
;
}
}
if
(
iStore
==
0
)
return
0.
;
for
(
int
j
=
0
;
j
<
iStore
;
j
++
)
{
store
[
j
].
gamma
/=
gammaTot
;
if
(
j
>
0
)
store
[
j
].
gamma
+=
store
[
j
-
1
].
gamma
;
}
//call random nummber
float
x
=
ran
.
Rndm
();
int
j
=
0
;
for
(;;)
{
if
(
x
<
store
[
j
].
gamma
)
break
;
if
(
j
==
iStore
-
1
)
break
;
j
++
;
}
fissionZ
=
store
[
j
].
iZ
;
fissionA
=
store
[
j
].
iA
;
float
saddlePoint
=
yrast
.
getSaddlePointEnergy
(
fissionZ
,
fissionA
);
saddlePoint
=
(
saddlePoint
-
Erot
)
*
scaleImf
+
Erot
;
/*
//add on a congruence energy
int iA2 = iA - fissionA;
int iZ2 = iZ - fissionZ;
float Wigner1 = yrast.WignerEnergy(fissionZ,fissionA);
float Wigner2 = yrast.WignerEnergy(iZ2,iA2);
saddlePoint += WignerScaled*(Wigner1+Wigner2-Wigner0) + WignerAdd;
*/
saddlePoint
+=
WignerAdd
;
if
(
iZ
>
Zshell
)
saddlePoint
-=
fPairing
+
fShell
;
fissionU
=
fEx
-
saddlePoint
;
return
gammaTot
;
}
//********************************************************************
/**
* Calculates the complex fragments decay widths in MeV where the total fission
* width all channels is normalised to the Bohr-Wheeler result.
*/
float
CNucleus
::
asyFissionWidthBW
()
{
short
iAfAn
=
1
;
int
const
nnstore
=
4000
;
SStore
store
[
nnstore
];
needSymmetricFission
=
0
;
int
iStore
=
0
;
int
iFission
=
-
1
;
float
gammaTot
=
0
;
float
saddlePointOld
=
-
10000.
;
yrast
.
prepareAsyBarrier
(
iZ
,
iA
,
fJ
);
float
A1
=
(
float
)
iA
/
2.
;
//the following is the differece between the symmetric saddle points
//Sierk symmetric calculation and my interpolated and extrapolated
//asymmetric barriers using Sierk asymmetry calculations as input
// at J=0, they are garenteed to be identical
// I fill just shift down the asymmetric barrirs by delta now
float
delta
=
yrast
.
getSaddlePointEnergy
(
A1
)
-
symSaddlePoint
;
for
(
int
iZ1
=
evap
.
maxZ
+
1
;
iZ1
<=
iZ
/
2
;
iZ1
++
)
{
float
A1
=
(
float
)
iZ1
/
(
float
)
iZ
*
float
(
iA
);
float
saddlePoint
=
yrast
.
getSaddlePointEnergy
(
A1
)
-
delta
;
if
(
iZ
>
Zshell
)
saddlePoint
-=
fPairing
+
fShell
;
float
A2
=
(
float
)(
iZ1
-
1
)
/
(
float
)(
iZ
)
*
float
(
iA
);
float
A3
=
(
float
)(
iZ1
+
1
)
/
(
float
)(
iZ
)
*
float
(
iA
);
float
A4
=
(
float
)(
iZ1
-
2
)
/
(
float
)(
iZ
)
*
float
(
iA
);
float
A5
=
(
float
)(
iZ1
+
2
)
/
(
float
)(
iZ
)
*
float
(
iA
);
float
saddlePoint2
=
yrast
.
getSaddlePointEnergy
(
A2
)
-
delta
;
float
saddlePoint3
=
yrast
.
getSaddlePointEnergy
(
A3
)
-
delta
;
float
saddlePoint4
=
yrast
.
getSaddlePointEnergy
(
A4
)
-
delta
;
float
saddlePoint5
=
yrast
.
getSaddlePointEnergy
(
A5
)
-
delta
;
saddlePoint
=
(
saddlePoint
+
saddlePoint2
+
saddlePoint3
+
saddlePoint4
+
saddlePoint5
)
/
5.
;
if
(
saddlePoint
<
saddlePointOld
&&
iZ1
>
8
&&
iFission
==
-
1
)
{
if
(
iZ
/
2
-
iZ1
>
5
)
{
iFission
=
iStore
;
}
}
else
saddlePointOld
=
saddlePoint
;
float
gammaZ0
=
getWidthZA
(
saddlePoint
,
iAfAn
);
if
(
iZ1
==
iZ
-
iZ1
)
gammaZ0
/=
2.
;
if
(
gammaZ0
<=
0.
)
continue
;
int
iaMin1
=
mass
->
chart
.
getAmin
(
iZ1
);
int
iaMin2
=
iA
-
mass
->
chart
.
getAmax
(
iZ
-
iZ1
);
int
iaMin
=
max
(
iaMin1
,
iaMin2
);
int
iaMax1
=
mass
->
chart
.
getAmax
(
iZ1
);
int
iaMax2
=
iA
-
mass
->
chart
.
getAmin
(
iZ
-
iZ1
);
int
iaMax
=
min
(
iaMax1
,
iaMax2
);
if
(
iZ1
==
iZ
-
iZ1
)
iaMax
=
min
(
iA
/
2
,
iaMax
);
float
gammaZ
=
0
;
int
iStart
=
iStore
;
for
(
int
iA1
=
iaMin
;
iA1
<=
iaMax
;
iA1
++
)
{
float
saddlePoint
=
yrast
.
getSaddlePointEnergy
(
iZ1
,
iA1
);
if
(
iZ
>
Zshell
)
saddlePoint
-=
fPairing
+
fShell
;
float
gamma
=
getWidthZA
(
saddlePoint
,
iAfAn
);
if
(
iZ1
==
iZ
-
iZ1
&&
iA1
==
iA
-
iA1
)
gamma
/=
2.
;
if
(
gamma
<=
0.
)
continue
;
store
[
iStore
].
gamma
=
gamma
;
store
[
iStore
].
iZ
=
iZ1
;
store
[
iStore
].
iA
=
iA1
;
iStore
++
;
if
(
iStore
==
nnstore
)
abort
();
gammaZ
+=
gamma
;
}
// normalize gamma
if
(
gammaZ
==
0.
)
iStore
=
iStart
;
else
{
for
(
int
j
=
iStart
;
j
<
iStore
;
j
++
)
store
[
j
].
gamma
*=
gammaZ0
/
gammaZ
;
gammaTot
+=
gammaZ0
;
}
}
if
(
iStore
==
0
)
{
fissionZ
=
iZ
/
2
;
fissionA
=
iA
/
2
;
fissionU
=
0.
;
return
0.
;
}
// to normalise fission peak to Bohr-wheeler width
if
(
iFission
>
0
)
{
float
gammaFission
=
0.
;
for
(
int
i
=
iFission
;
i
<
iStore
;
i
++
)
{
gammaFission
+=
store
[
i
].
gamma
;
}
float
gammaBW
=
BohrWheelerWidth
();
float
ratio
=
gammaBW
/
gammaFission
;
gammaTot
=
gammaBW
;
for
(
int
i
=
iFission
;
i
<
iStore
;
i
++
)
{
store
[
i
].
gamma
*=
ratio
;
}
//set other imf's to zero
for
(
int
i
=
0
;
i
<
iFission
;
i
++
)
{
store
[
i
].
gamma
=
0.
;
}
}
for
(
int
j
=
0
;
j
<
iStore
;
j
++
)
{
store
[
j
].
gamma
/=
gammaTot
;
if
(
j
>
0
)
store
[
j
].
gamma
+=
store
[
j
-
1
].
gamma
;
}
//call random nummber
float
x
=
ran
.
Rndm
();
int
j
=
0
;
for
(;;)
{
if
(
x
<
store
[
j
].
gamma
)
break
;
if
(
j
==
iStore
-
1
)
break
;
j
++
;
}
fissionZ
=
store
[
j
].
iZ
;
fissionA
=
store
[
j
].
iA
;
float
saddlePoint
=
yrast
.
getSaddlePointEnergy
(
fissionZ
,
fissionA
);
if
(
iZ
>
Zshell
)
saddlePoint
-=
fPairing
+
fShell
;
fissionU
=
fEx
-
saddlePoint
;
return
gammaTot
;
}
//*************************************************************************
/**
* Uses the GammaZA formalism to get complex fragment decay widths as in the
* original GEMINI.
*
* The asymmetric fission width are in MeV.
*/
float
CNucleus
::
asyFissionWidthZA
()
{
short
iAfAn
=
2
;
SStore
store
[
nStore
];
needSymmetricFission
=
0
;
int
iStore
=
0
;
float
gammaTot
=
0
;
float
saddlePointOld
=
-
10000.
;
yrast
.
prepareAsyBarrier
(
iZ
,
iA
,
fJ
);
//yrast.printAsyBarrier();
//float Wigner0 = yrast.WignerEnergy(iZ,iA);
scission
.
init
(
iZ
,
iA
,
fJ
,
1
);
for
(
int
iZ1
=
evap
.
maxZ
+
1
;
iZ1
<=
iZ
/
2
;
iZ1
++
)
{
int
iZ2
=
iZ
-
iZ1
;
float
A1
=
(
float
)
iZ1
/
(
float
)
iZ
*
float
(
iA
);
float
saddlePoint
=
yrast
.
getSaddlePointEnergy
(
A1
);
saddlePoint
=
(
saddlePoint
-
Erot
)
*
scaleImf
+
Erot
;
//add on a congruence energy
//saddlePoint += WignerScaled*Wigner0+WignerAdd;
saddlePoint
+=
WignerAdd
;
if
(
iZ
>
Zshell
)
saddlePoint
-=
fPairing
+
fShell
;
if
(
noSymmetry
&&
saddlePoint
<
saddlePointOld
&&
iZ1
>
8
&&
iZ
/
2
-
iZ1
>
5
)
{
needSymmetricFission
=
1.
;
break
;
}
else
saddlePointOld
=
saddlePoint
;
int
iaMin1
=
mass
->
chart
.
getAmin
(
iZ1
);
int
iaMin2
=
iA
-
mass
->
chart
.
getAmax
(
iZ
-
iZ1
);
int
iaMin
=
max
(
iaMin1
,
iaMin2
);
int
iaMax1
=
mass
->
chart
.
getAmax
(
iZ1
);
int
iaMax2
=
iA
-
mass
->
chart
.
getAmin
(
iZ
-
iZ1
);
int
iaMax
=
min
(
iaMax1
,
iaMax2
);
if
(
iZ1
==
iZ
-
iZ1
)
iaMax
=
min
(
iA
/
2
,
iaMax
);
for
(
int
iA1
=
iaMin
;
iA1
<=
iaMax
;
iA1
++
)
{
int
iA2
=
iA
-
iA1
;
//make sure I can conserve energy latter
float
mass1
=
mass
->
getCalMass
(
iZ1
,
iA1
);
float
mass2
=
mass
->
getCalMass
(
iZ2
,
iA2
);
scission
.
getFissionKineticEnergy
(
iZ1
,
iA1
);
float
Qvalue
=
fExpMass
-
mass1
-
mass2
-
scission
.
ekTot
-
scission
.
Erotate1
-
scission
.
Erotate2
;
if
(
fEx
+
Qvalue
<=
0.
)
continue
;
float
saddlePoint
=
yrast
.
getSaddlePointEnergy
(
iZ1
,
iA1
);
saddlePoint
=
(
saddlePoint
-
Erot
)
*
scaleImf
+
Erot
;
//add on a congruence energy
/*
float Wigner1 = yrast.WignerEnergy(iZ1,iA1);
float Wigner2 = yrast.WignerEnergy(iZ2,iA2);
saddlePoint += WignerScaled*(Wigner1+Wigner2-Wigner0)+WignerAdd;
*/
saddlePoint
+=
WignerAdd
;
if
(
iZ
>
Zshell
)
saddlePoint
-=
fPairing
+
fShell
;
float
gamma
=
getWidthZA
(
saddlePoint
,
iAfAn
);
if
(
iZ1
==
iZ
-
iZ1
&&
iA1
==
iA
-
iA1
)
gamma
/=
2.
;
if
(
gamma
<=
0.
)
continue
;
/*
// the following paragraph of code corrects the Moretto
//decay width such that a Lestone like logic is used.
//This was tried at
//some point, but for symmetric fission we obtained better agreement
//for fusion and splattion reactions with the standard
//Bohr-Wheeler value. It therefore was inconsistent to used
//the Lestone logical for asymmetric fission
//
// start Lestone correction
//float R1 = pow((float)iA1,(float)(1./3.))*r0;
//float R2 = pow((float)(iA-iA1),(float)(1./3.))*r0;
//float momInertia1 = 0.4*(float)iA*pow(R1,2);
//float momInertia2 = 0.4*(float)(iA-iA1)*pow(R2,2);
//float Areduced = (float)(iA1*(iA-iA1))/float(iA);
//float momInertiaPerp = momInertia1 + momInertia2 +
// Areduced*(R1+R2+sep);
//float momInertiaPara = momInertia1 + momInertia2;
//float momInertiaEff = 1./(1./momInertiaPara - 1./momInertiaPerp);
//float corr = LestoneCorrection(fEx-saddlePoint,momInertiaEff,iAfAn);
//gamma *= corr;
//end lestone correction
*/
gammaTot
+=
gamma
;
store
[
iStore
].
gamma
=
gamma
;
store
[
iStore
].
iZ
=
iZ1
;
store
[
iStore
].
iA
=
iA1
;
iStore
++
;
if
(
iStore
==
nStore
)
{
cout
<<
"increase nStore in asyFissionWidthZA"
<<
endl
;
abort
();
}
}
}
if
(
iStore
==
0
)
return
0.
;
for
(
int
j
=
0
;
j
<
iStore
;
j
++
)
{
store
[
j
].
gamma
/=
gammaTot
;
if
(
j
>
0
)
store
[
j
].
gamma
+=
store
[
j
-
1
].
gamma
;
}
//call random nummber
float
x
=
ran
.
Rndm
();
int
j
=
0
;
for
(;;)
{
if
(
x
<
store
[
j
].
gamma
)
break
;
if
(
j
==
iStore
-
1
)
break
;
j
++
;
}
fissionZ
=
store
[
j
].
iZ
;
fissionA
=
store
[
j
].
iA
;
float
saddlePoint
=
yrast
.
getSaddlePointEnergy
(
fissionZ
,
fissionA
);
saddlePoint
=
(
saddlePoint
-
Erot
)
*
scaleImf
+
Erot
;
//add on a congruence energy
/*
int iA2 = iA - fissionA;
int iZ2 = iZ - fissionZ;
float Wigner1 = yrast.WignerEnergy(fissionZ,fissionA);
float Wigner2 = yrast.WignerEnergy(iZ2,iA2);
saddlePoint += WignerScaled*(Wigner1+Wigner2-Wigner0) + WignerAdd;
*/
saddlePoint
+=
WignerAdd
;
if
(
iZ
>
Zshell
)
saddlePoint
-=
fPairing
+
fShell
;
fissionU
=
fEx
-
saddlePoint
;
return
gammaTot
;
}
//********************************************************************
float
CNucleus
::
LestoneFissionWidth
()
/**
* Gives the fission decay width from Lestone in units of MeV.
* Lestone gives an extention of the BohrWheeler width with the inclusion
* of one of the angular momentum degrees of freedom (tilting mode).
* See PRC 59 (1999) 1540.
*/
{
float
gamma
=
BohrWheelerWidth
();
if
(
gamma
<=
0.
)
return
gamma
;
short
iAfAn
=
1
;
float
momInertiaPerp
=
yrast
.
getMomentOfInertiaSierk
(
fJ
);
float
momInertiaPara
=
yrast
.
momInertiaMin
;
float
momInertiaEff
=
1.0
/
(
1.0
/
momInertiaPara
-
1.0
/
momInertiaPerp
);
float
U
=
fEx
-
symSaddlePoint
;
float
corr
=
LestoneCorrection
(
U
,
momInertiaEff
,
iAfAn
);
return
gamma
*
corr
;
}
//*************************************************************************
float
CNucleus
::
BohrWheelerWidth
()
/**
* Gives the Bohr-Wheeler decay width for fission in units of MeV
*/
{
symSaddlePoint
=
yrast
.
getSymmetricSaddleEnergy
(
iZ
,
iA
,
fJ
)
+
barAdd
;
if
(
iZ
>
Zshell
)
symSaddlePoint
-=
fPairing
+
fShell
;
/*float fJJ = fJ;
if (fJ > yrast.Jmax) fJJ = yrast.Jmax;*/
short
iAfAn
=
1
;
float
gamma
=
getWidthZA
(
symSaddlePoint
,
iAfAn
)
*
fissionScaleFactor
;
return
gamma
;
}
//************************************************
/**
* Responsible for subdividing spin and excitation energy for
* asymmetry fission.
*
* its uses a two-sphere approximation to get collective modes
*/
void
CNucleus
::
asyFissionDivide
()
{
//first a statement to handle a bad case
if
(
fissionU
<=
0.
)
{
daughterLight
->
excite
(
0.
,
0.
);
daughterHeavy
->
excite
(
0.
,
0.
);
float
phi
=
2.
*
pi
*
ran
.
Rndm
();
float
theta
=
acos
(
1.0
-
2.0
*
ran
.
Rndm
());
CAngle
symmetryCM
(
theta
,
phi
);
split
(
symmetryCM
);
return
;
}
float
A1
=
(
float
)
fissionA
;
float
A2
=
(
float
)(
iA
-
fissionA
);
float
Ared
=
A1
*
A2
/
(
A1
+
A2
);
float
U1
=
fissionU
*
A1
/
(
A1
+
A2
);
float
U2
=
fissionU
-
U1
;
float
r1
=
scission
.
r0
*
pow
(
A1
,(
float
)(
1.
/
3.
));
float
r2
=
scission
.
r0
*
pow
(
A2
,(
float
)(
1.
/
3.
));
float
MInertia1
=
0.4
*
A1
*
pow
(
r1
,
2
);
float
MInertia2
=
0.4
*
A2
*
pow
(
r2
,
2
);
float
MInertiaOrbit
=
Ared
*
pow
(
r1
+
r2
+
scission
.
sep
,
2
);
float
MInertia12
=
MInertia1
+
MInertia2
;
float
MInertiaSaddle
=
MInertia12
+
MInertiaOrbit
;
float
aden1
=
levelDensity
.
getLittleA
(
fissionA
,
U1
);
//float entropy1 = levelDensity.getEntropy();
float
aden2
=
levelDensity
.
getLittleA
(
iA
-
fissionA
,
U2
);
//float entropy2 = levelDensity.getEntropy();
float
aden
=
aden1
+
aden2
;
//float entropy0 = entropy1 + entropy2;
float
temp
=
sqrt
(
fissionU
/
aden
);
float
entropy0
=
2.
*
sqrt
(
aden
*
fissionU
);
float
fact10
=
MInertiaOrbit
*
(
MInertia2
-
MInertia1
)
/
(
2.0
*
MInertia1
*
MInertia2
);
float
fact1
=
sqrt
(
pow
(
fact10
,
2
)
+
1
);
float
theta
=
atan
(
fact10
+
fact1
);
float
fact3
=
MInertia12
/
(
MInertia1
*
MInertia2
);
float
c
=
cos
(
theta
);
float
s
=
sin
(
theta
);
float
cc
=
pow
(
c
,
2
);
float
ss
=
pow
(
s
,
2
);
float
fact4
=
2.0
*
s
*
c
/
MInertiaOrbit
;
float
aBending
=
(
cc
/
MInertia1
+
ss
/
MInertia2
+
1.0
/
MInertiaOrbit
-
fact4
)
*
kRotate
;
float
aWriggling
=
(
ss
/
MInertia1
+
cc
/
MInertia2
+
1.0
/
MInertiaOrbit
+
fact4
)
*
kRotate
;
float
aTilting
=
MInertiaOrbit
/
MInertia12
/
MInertiaSaddle
*
kRotate
;
float
aTwisting
=
fact3
*
kRotate
;
float
K
,
JTwisting
,
JBendingX
,
JBendingZ
,
JWrigglingX
,
JWrigglingZ
;
float
deltaE
;
int
tries
=
0
;
for
(;;)
{
//choose K tilting
K
=
selectJ
(
aTilting
,
aden
,
entropy0
,
fJ
);
//choose twisting
float
sig
=
5.
*
sqrt
(
temp
/
aTwisting
);
JTwisting
=
selectJ
(
aTwisting
,
aden
,
entropy0
,
sig
);
//choose bending for X direction
sig
=
5.0
*
sqrt
(
temp
/
aBending
);
JBendingX
=
selectJ
(
aBending
,
aden
,
entropy0
,
sig
);
//choose Jbending for Z direction
JBendingZ
=
selectJ
(
aBending
,
aden
,
entropy0
,
sig
);
//choose Jwriggling for x direction
sig
=
5.0
*
sqrt
(
temp
/
aWriggling
);
JWrigglingX
=
selectJ
(
aWriggling
,
aden
,
entropy0
,
sig
);
//choose Jwriggling for Z direction
JWrigglingZ
=
selectJ
(
aWriggling
,
aden
,
entropy0
,
sig
);
deltaE
=
0.5
*
(
aTilting
*
pow
(
K
,
2
)
+
aTwisting
*
pow
(
JTwisting
,
2
)
+
aBending
*
(
pow
(
JBendingX
,
2
)
+
pow
(
JBendingZ
,
2
))
+
aWriggling
*
(
pow
(
JWrigglingX
,
2
)
+
pow
(
JWrigglingZ
,
2
)));
if
(
deltaE
<=
fissionU
)
break
;
tries
++
;
if
(
tries
==
15
)
{
// not able to find a solution for some reason.
//so just turn off the depolarization modes.
//cout << "tries too big in asyFissionDivide" << endl;
//abort();
K
=
0.
;
JTwisting
=
0.
;
JBendingX
=
0.
;
JBendingZ
=
0.
;
JWrigglingX
=
0.
;
JWrigglingZ
=
0.
;
deltaE
=
0.
;
break
;
}
}
//calculate components of r1, depolarizing mode of fragment 1
float
R1x
=
JBendingX
*
c
+
JWrigglingX
*
s
;
float
R1y
=
JTwisting
;
float
R1z
=
JBendingZ
*
c
+
JWrigglingZ
*
s
;
// calculate components of r2
float
R2x
=
JWrigglingX
*
c
-
JBendingX
*
s
;
float
R2y
=
-
JTwisting
;
float
R2z
=
JWrigglingZ
*
c
-
JBendingZ
*
s
;
float
omega_t
=
ran
.
Rndm
()
*
2.
*
pi
;
float
J0xz
=
sqrt
(
pow
(
fJ
,
2
)
-
pow
(
K
,
2
));
float
J0x
=
J0xz
*
sin
(
omega_t
);
float
J0z
=
J0xz
*
cos
(
omega_t
);
//calculate components of s1
float
ratio1
=
MInertia1
/
MInertiaSaddle
;
float
S1x
=
J0x
*
ratio1
+
R1x
;
float
S1y
=
MInertia1
/
MInertia12
*
K
+
R1y
;
float
S1z
=
J0z
*
ratio1
+
R1z
;
float
S1
=
sqrt
(
pow
(
S1x
,
2
)
+
pow
(
S1y
,
2
)
+
pow
(
S1z
,
2
));
//calculate components of s2
float
ratio2
=
MInertia2
/
MInertiaSaddle
;
float
S2x
=
J0x
*
ratio2
+
R2x
;
float
S2y
=
MInertia2
/
MInertia12
*
K
+
R2y
;
float
S2z
=
J0z
*
ratio2
+
R2z
;
float
S2
=
sqrt
(
pow
(
S2x
,
2
)
+
pow
(
S2y
,
2
)
+
pow
(
S2z
,
2
));
//note that fissionU was calculated as the thermal energy above
//a rigidly rotation configuration. The rotational energy of the
//individual frgament's in that configuration has already been
//subtracted. As we now about to assign new rotational energies
//to these fragment, this component must be corrected for
//old rotational energies
float
Erotate10
=
scission
.
Erotate1
;
float
Erotate20
=
scission
.
Erotate2
;
float
Erotate1
=
pow
(
S1
,
2
)
*
kRotate
/
2.
/
MInertia1
;
float
Erotate2
=
pow
(
S2
,
2
)
*
kRotate
/
2.
/
MInertia2
;
fissionU
+=
Erotate10
+
Erotate20
-
Erotate1
-
Erotate2
;
if
(
fissionU
<
0.
)
fissionU
=
0.
;
temp
=
sqrt
(
fissionU
/
aden
);
float
sig
=
sqrt
(
2.0
*
pow
(
temp
,
3
)
*
aden1
*
aden2
/
aden
);
U1
=
fissionU
*
A1
/
(
A1
+
A2
);
U2
=
fissionU
-
U1
;
entropy0
=
2.0
*
sqrt
(
aden
*
fissionU
);
float
demax
=
min
((
float
)
5.0
*
sig
,
U1
);
float
demin
=
min
((
float
)
5.0
*
sig
,
U2
);
tries
=
0
;
for
(;;)
{
deltaE
=
(
demin
+
demax
)
*
ran
.
Rndm
()
-
demax
;
float
y
=
exp
(
2.0
*
sqrt
(
aden1
*
(
U1
+
deltaE
))
+
2.0
*
sqrt
(
aden2
*
(
U2
-
deltaE
))
-
entropy0
);
float
yy
=
ran
.
Rndm
();
// cout << deltaE << " " << y << " " << yy << endl;
if
(
yy
<=
y
)
break
;
tries
++
;
if
(
tries
==
10
)
{
//cout << "2nd tries too big in asyFissionDivide" << endl;
deltaE
=
0.
;
break
;
}
}
float
Ex1
=
U1
+
deltaE
+
Erotate1
;
float
Ex2
=
U2
-
deltaE
+
Erotate2
;
// the following should be zero if energy is conserved
//cout << fEx + fExpMass - daughterLight->fExpMass - daughterHeavy->fExpMass
//- scission.ekTot -Ex1 - Ex2 << endl;
float
fJ1
,
fJ2
;
if
(
fissionA
%
2
==
0
)
{
fJ1
=
round
(
S1
);
}
else
{
fJ1
=
round
(
S1
+
.5
)
-
.5
;
}
daughterLight
->
excite
(
Ex1
,
fJ1
);
if
((
iA
-
fissionA
)
%
2
==
0
)
{
fJ2
=
round
(
S2
);
}
else
{
fJ2
=
round
(
S2
+
.5
)
-
.5
;
}
daughterHeavy
->
excite
(
Ex2
,
fJ2
);
// this part of the subroutines calculates the final
// centre-of-mass velocity vectors of the complex fragments and
// their spin vectors. vectors are specified as:
// x_y_z
// x is polar angular coordinate for vector (theta or phi)
// y identifies the vector
// options : V1 - velocity of fragment 1
// S1 - spin of fragment 1
// V2 - velocity of fragment 2
// S2 - spin of fragment 2
// symmetry - specifies the symmetry axis of
// saddle-scission point configuration
// J0 - spin vector of fragment 0 (decaying system)
// V0 - velocity vector of fragment 0
// Z is frame in which polar coordinates are specified
// r - rotation frame of saddle point configuration
// see Schmitt and Pacheco Nucl Phys. A379 (1982) 313
// J0 - frame with Vector J0 as Z axis
// cm - centre of mass frame of reaction.
// in the frame of the di-nuclear complex the total angular
// momentum vector processes. The theta and phi angles at
// scission are. see schmitt and pacheco for coordinate system.
CAngle
J0r
;
if
(
fJ
==
0.0
)
{
J0r
.
phi
=
2.
*
pi
*
ran
.
Rndm
();
J0r
.
theta
=
-
acos
(
1.0
-
2.0
*
ran
.
Rndm
());
}
else
{
J0r
.
theta
=
-
acos
(
J0z
/
fJ
);
J0r
.
phi
=
atan2
(
K
,
J0x
);
}
// the symmetry axis occurs at x=0,z=0 in the above coordinate
// system i.e. theta_symmetry_r=90., phi_symmetry_r =90. degrees, find
// angles of the symmetry axis relative to the j0 vector
// (.i.e. rotate everything so that J0 is parallel to z axis)
CAngle
symmetryJ0
;
CAngle
perp
(
pi
/
2.
,
pi
/
2.
);
//rjc
symmetryJ0
=
CAngle
::
transform
(
perp
,
J0r
);
// randomize the phi coordinate.
float
dphi
=
2.
*
pi
*
ran
.
Rndm
();
symmetryJ0
.
phi
+=
dphi
;
if
(
symmetryJ0
.
phi
>
2.
*
pi
)
symmetryJ0
.
phi
-=
2.
*
pi
;
// find symmetry axis in lab frame
CAngle
symmetryCM
;
symmetryCM
=
CAngle
::
transform
(
symmetryJ0
,
spin
);
// in the rotating frame of dinuclear system, the spin vector of
// fragment 1 is s1X,s1Y,s1Z, relative to di nuclear coordinate system
// mentioned above
CAngle
S1r
;
if
(
S1
==
0.
)
{
S1r
.
theta
=
acos
(
1.0
-
2.0
*
ran
.
Rndm
());
S1r
.
phi
=
2.
*
pi
*
ran
.
Rndm
();
}
else
{
S1r
.
theta
=
acos
(
S1z
/
S1
);
S1r
.
phi
=
atan2
(
S1y
,
S1x
);
}
// rotate to frame of J0 vector (.i.e. z axis parallel to J0)
CAngle
S1J0
;
S1J0
=
CAngle
::
transform
(
S1r
,
J0r
);
S1J0
.
phi
+=
dphi
;
if
(
S1J0
.
phi
>
2.
*
pi
)
S1J0
.
phi
-=
2.
*
pi
;
// rotate to lab frame
daughterLight
->
spin
=
CAngle
::
transform
(
S1J0
,
spin
);
// do the same for fragment 2
CAngle
S2r
;
if
(
S2
==
0.0
)
{
S2r
.
theta
=
acos
(
1.0
-
2.0
*
ran
.
Rndm
());
S2r
.
phi
=
2.
*
pi
*
ran
.
Rndm
();
}
else
{
S2r
.
theta
=
acos
(
S2z
/
S2
);
S2r
.
phi
=
atan2
(
S2y
,
S2x
);
}
// rotate to frame of J0 vector (.i.e. z axis parallel to J0)
CAngle
S2J0
;
S2J0
=
CAngle
::
transform
(
S2r
,
J0r
);
S2J0
.
phi
+=
dphi
;
if
(
S2J0
.
phi
>
2.
*
pi
)
S2J0
.
phi
-=
2.
*
pi
;
// rotate to lab frame
daughterHeavy
->
spin
=
CAngle
::
transform
(
S2J0
,
spin
);
// calculate velocities in frame of emitting system
// first find the kinetic energy of separation
//Ek = 1.44*(float)fissionZ*(float)(iZ-fissionZ)/(r1+r2+sep)
//generlization of Viola see Hinde Nucl Phys A472, 318 (1987).
//float Ek = yrast.viola((float)fissionZ,A1,(float)(iZ-fissionZ),A2);
//float Ek = 0.755*(float)fissionZ*(float)(iZ-fissionZ)/
// (pow(A1,(float)(1./3.))+pow(A2,(float)(1./3.)))
// + 7.3;
// find orbital angular momentum
//float ratio_l = MInertiaOrbit/MInertiaSaddle;
//float lx = J0x*ratio_l - R1x - R2x;
//float lz = J0z*ratio_l - R1z - R2z;
//float l = sqrt(pow(lx,2) + pow(lz,2));
//ek = ek + 20.8993*l**2.0/M_inertia_orbit
split
(
symmetryCM
);
}
//************************************************
/**
* Randomly selects the spin associated with a fission normal modes such as
* wriggling, twisting, etc.
*/
float
CNucleus
::
selectJ
(
float
ac
,
float
aden
,
float
entropy0
,
float
Jmax
)
{
float
Jmax1
=
sqrt
(
2.0
*
fissionU
/
ac
);
float
Jmax2
=
min
(
Jmax
,
Jmax1
);
float
J
;
int
tries
=
0
;
for
(;;)
{
J
=
Jmax2
*
(
1.0
-
2.0
*
ran
.
Rndm
());
float
diff
=
max
(
fissionU
-
0.5
*
ac
*
J
*
J
,
0.0
);
float
y1
=
exp
(
2.0
*
sqrt
(
aden
*
diff
)
-
entropy0
);
float
y2
=
ran
.
Rndm
();
if
(
y2
<
y1
)
break
;
tries
++
;
if
(
tries
==
15
)
{
//after 15 tries, return zero
//cout << "tries too big in selectJ" << endl;
//abort();
return
0.
;
}
}
return
J
;
}
//****************************************
/**
* Sets the angle of the compound nucleus spin axis.
*
\param spin0 is the (theta,phi) angles in radians
*/
void
CNucleus
::
setSpinAxis
(
CAngle
spin0
)
{
spin
=
spin0
;
}
//****************************************
/**
* Sets the angle of the compound nucleus spin axis.
*
\param spin0 is the (theta,phi) angles in degrees
*/
void
CNucleus
::
setSpinAxisDegrees
(
CAngle
spin0
)
{
spin
=
spin0
;
spin
.
theta
*=
CAngle
::
pi
/
180.
;
spin
.
phi
*=
CAngle
::
pi
/
180.
;
}
//***************************************
/**
* Sets the velocity of the fragment in polar coordinates
*
/param vel is velocity in units of cm/ns
/param theta is theta angle in radians
/param phi is phi angle in radians
*/
void
CNucleus
::
setVelocityPolar
(
float
vel
/*=0.*/
,
float
theta
/*=0.*/
,
float
phi
/*=0.*/
)
{
//default values are zero
velocity
[
0
]
=
vel
*
sin
(
theta
)
*
cos
(
phi
);
velocity
[
1
]
=
vel
*
sin
(
theta
)
*
sin
(
phi
);
velocity
[
2
]
=
vel
*
cos
(
theta
);
}
//***************************************
/**
* Sets the velocity of the fragment in cartesian coordinates.
*
* with no input parameter, all components are set to zero.
\param vx is x component of velocity in cm/ns
\param vy is y component of velocity in cm/ns
\param vz is z component of velocity in cm/ns
*/
void
CNucleus
::
setVelocityCartesian
(
float
vx
/*=0.*/
,
float
vy
/*=0.*/
,
float
vz
/*=0.*/
)
{
//default values are zero
velocity
[
0
]
=
vx
;
velocity
[
1
]
=
vy
;
velocity
[
2
]
=
vz
;
}
//*****************************************
/**
* Calculates the total decay widths in MeV for light particle evaporation.
* using the Hauser-Feshbach formulism
*/
float
CNucleus
::
evaporationWidth
()
{
float
width
=
0.
;
EcostMin
=
1000.
;
for
(
int
i
=
0
;
i
<
evap
.
nLight
;
i
++
)
{
lightP
=
evap
.
lightP
[
i
];
if
(
HF
)
evap
.
prob
[
i
]
=
hauserFeshbach
(
i
);
else
evap
.
prob
[
i
]
=
weiskopf
((
bool
)
0
);
evap
.
prob
[
i
]
*=
lightP
->
suppress
;
//user-given suppression factor
width
+=
evap
.
prob
[
i
];
if
(
i
>
0
)
evap
.
prob
[
i
]
+=
evap
.
prob
[
i
-
1
];
}
if
(
width
<=
0.
)
{
return
0.
;
}
return
width
;
}
//*****************************************
/**
* Calculated the Hauser-Feshbach decay width in MeV for a given channel
\param iChannel is the channel of the evaporated particle
*/
float
CNucleus
::
hauserFeshbach
(
int
iChannel
)
{
//returns the Hauser-Feshbach evaporation width for a given channel
//width is in units of MeV
if
(
exp
(
-
lightP
->
fEx
/
temp
)
<
0.01
&&
iChannel
>
1
)
return
0.
;
lightP
->
residue
.
iZ
=
iZ
-
lightP
->
iZ
;
if
(
lightP
->
iZ
>=
lightP
->
residue
.
iZ
)
return
0.
;
lightP
->
residue
.
iA
=
iA
-
lightP
->
iA
;
if
(
lightP
->
iA
>=
lightP
->
residue
.
iA
)
return
0.
;
if
(
lightP
->
residue
.
iZ
>=
lightP
->
residue
.
iA
)
return
0.
;
//products must lie on the chart of nuclides used by gemini
if
(
lightP
->
residue
.
iA
<
mass
->
chart
.
getAmin
(
lightP
->
residue
.
iZ
))
return
0.
;
if
(
lightP
->
residue
.
iA
>
mass
->
chart
.
getAmax
(
lightP
->
residue
.
iZ
))
return
0.
;
//note1, new treament of yrast line
//spheroid.init(lightP->residue.iZ,lightP->residue.iA);
//spheroid.setDeformationProlate(deformation);
//odd A nuclei have 1/2 integer spin
lightP
->
odd
=
0
;
if
(
lightP
->
residue
.
iA
%
2
==
1
)
lightP
->
odd
=
1
;
if
(
lightP
->
residue
.
iZ
>
Zshell
)
lightP
->
fPair
=
mass
->
getPairing
(
lightP
->
residue
.
iZ
,
lightP
->
residue
.
iA
);
else
lightP
->
fPair
=
0.
;
lightP
->
residue
.
fExpMass
=
mass
->
getCalMass
(
lightP
->
residue
.
iZ
,
lightP
->
residue
.
iA
);
lightP
->
fShell
=
0.
;
if
(
lightP
->
residue
.
iZ
>
Zshell
)
lightP
->
fShell
=
mass
->
getShellCorrection
(
lightP
->
residue
.
iZ
,
lightP
->
residue
.
iA
);
lightP
->
separationEnergy
=
lightP
->
residue
.
fExpMass
+
lightP
->
fExpMass
-
fExpMass
;
rResidue
=
r0
*
pow
((
float
)
lightP
->
residue
.
iA
,(
float
)(
1.
/
3.
));
lightP
->
fMInertia
=
0.4
*
(
float
)
lightP
->
residue
.
iA
*
pow
(
rResidue
,
2
);
lightP
->
fMInertiaOrbit
=
(
float
)(
lightP
->
residue
.
iA
*
lightP
->
iA
)
/
(
float
)(
lightP
->
residue
.
iA
+
lightP
->
iA
)
*
pow
(
rResidue
+
lightP
->
rLight
+
2.
,
2
);
// decide if decay mode is too costly` (very rare) if so abort calculation
Ecoul
=
1.44
*
(
float
)(
lightP
->
iZ
*
lightP
->
residue
.
iZ
)
/
(
rResidue
+
lightP
->
rLight
+
2.
);
float
Ecost
=
lightP
->
separationEnergy
+
Ecoul
;
if
(
Ecost
<
EcostMin
)
EcostMin
=
Ecost
;
if
(
exp
(
-
(
Ecost
-
EcostMin
)
/
temp
)
<
threshold
&&
lightP
->
iA
>
1
)
return
0.
;
S2Start
=
roundf
(
lightP
->
fMInertia
/
(
lightP
->
fMInertia
+
lightP
->
fMInertiaOrbit
)
*
fJ
);
if
(
lightP
->
odd
)
S2Start
+=
0.5
;
//prepare transmission coeff
lightP
->
tlArray
->
prepare
(
lightP
->
residue
.
iZ
);
lightP
->
width
=
S2Loop
(
-
1.
);
return
lightP
->
width
;
}
//***************************************************************
/**
* Calculates \f$\sum_{\ell=\ell_{min}}^{\ell_{max}} T_{\ell}(\varepsilon)\f$
\param ek is \f$\varepsilon\f$, the kinetic energy in MeV
\param temp is the temperature on the residue in MeV
*/
float
CNucleus
::
getSumTl
(
float
ek
,
float
temp
)
{
//function used by hauserFeshbach
float
sumTl
=
0.
;
float
tlWeightMax
=
0.
;
storeSub
=
new
SStoreSub
[
nSubTl
];
int
iSub
=
0
;
int
iL
=
lMin
;
float
scale
=
1.
;
if
(
lightP
->
iA
==
1
&&
lightP
->
iZ
==
1
)
{
//mass at the attractor line
float
Aeal
=
2.045
*
(
float
)
lightP
->
residue
.
iZ
+
3.57e-3
*
pow
((
float
)
lightP
->
residue
.
iZ
,
2
);
float
r_eal
=
1.2
*
pow
(
Aeal
,
float
(
1.
/
3.
))
+
1.167
;
float
r
=
1.2
*
pow
((
float
)
lightP
->
residue
.
iA
,(
float
)(
1.
/
3.
))
+
1.167
;
scale
=
r
/
r_eal
;
//rjc
}
else
if
(
lightP
->
iA
==
4
)
{
//mass at the attractor line
float
Aeal
=
2.045
*
(
float
)
lightP
->
residue
.
iZ
+
3.57e-3
*
pow
((
float
)
lightP
->
residue
.
iZ
,
2
);
float
deltaA
=
(
float
)
lightP
->
residue
.
iA
-
Aeal
;
scale
=
1.
+
deltaA
*
(
-
5.412976E-04
-
9.176213E-02
/
(
float
)
lightP
->
residue
.
iZ
+
3.916151E-06
*
(
float
)
lightP
->
residue
.
iZ
);
scale
=
1.
/
scale
;
}
for
(;;)
{
float
tl
=
lightP
->
tlArray
->
getTl
(
iL
,
ek
*
scale
,
temp
);
//cout << iL << " " << ek << " " << lightP->residue.iZ << " " << tl << endl;
float
maxLplusS
=
min
(
iL
+
lightP
->
fJ
,
lPlusSMax
);
float
minLplusS
=
max
(
fabs
(
iL
-
lightP
->
fJ
),
lPlusSMin
);
float
tlWeight
=
tl
*
(
maxLplusS
-
minLplusS
+
1.
);
storeSub
[
iSub
].
weight
=
tlWeight
;
if
(
iSub
>
0
)
storeSub
[
iSub
].
weight
+=
storeSub
[
iSub
-
1
].
weight
;
storeSub
[
iSub
].
L
=
iL
;
iSub
++
;
if
(
iSub
>
nSubTl
)
{
cout
<<
" increase nSubTl"
<<
endl
;
abort
();
}
sumTl
+=
tlWeight
;
tlWeightMax
=
max
(
tlWeight
,
tlWeightMax
);
if
(
tlWeight
<
0.01
*
tlWeightMax
)
break
;
iL
++
;
if
(
iL
>
lMax
)
break
;
}
float
xran
=
ran
.
Rndm
();
int
i
=
0
;
for
(;;)
{
float
prob
=
storeSub
[
i
].
weight
/
sumTl
;
if
(
prob
>
xran
)
break
;
if
(
i
==
iSub
-
1
)
break
;
i
++
;
}
EvapL
=
storeSub
[
i
].
L
;
delete
[]
storeSub
;
return
sumTl
;
}
//**************************************************************************
/**
* Selects the angle and velocity of an evaporated product
*/
void
CNucleus
::
angleEvap
()
{
//chooses the angles of evaporated particles
// find orientation of residue spin vector with respect to s0
// vector (i.e. z axis parallel to s0)
CAngle
residueCM
;
if
(
EvapLPlusS
>
0.0
&&
fJ
>
0.0
)
residueCM
.
theta
=
acos
((
pow
(
fJ
,
2
)
+
pow
(
EvapLPlusS
,
2
)
-
pow
(
EvapS2
,
2
))
/
(
2.0
*
EvapLPlusS
*
fJ
));
else
if
(
EvapLPlusS
==
0
)
residueCM
.
theta
=
0
;
else
residueCM
.
theta
=
acos
(
1.
-
2.
*
ran
.
Rndm
());
residueCM
.
phi
=
2.
*
pi
*
ran
.
Rndm
();
// rotate to lab frame
daughterHeavy
->
spin
=
CAngle
::
transform
(
residueCM
,
spin
);
// find direction of emitted fragment
// first the orientation of the vector l_plus_s with respect to s0
// (i.e. z axis parallel to s0)
CAngle
lPlusSCM
;
if
(
EvapS2
>
0.0
&&
fJ
>
0.0
)
lPlusSCM
.
theta
=
acos
((
pow
(
fJ
,
2
)
+
pow
(
EvapS2
,
2
)
-
pow
(
EvapLPlusS
,
2
))
/
(
2.0
*
EvapS2
*
fJ
));
if
(
EvapS2
==
0
)
lPlusSCM
.
theta
=
0.
;
else
lPlusSCM
.
theta
=
acos
(
1.0
-
2.0
*
ran
.
Rndm
());
lPlusSCM
.
phi
=
pi
+
residueCM
.
phi
;
if
(
lPlusSCM
.
phi
>
2.
*
pi
)
lPlusSCM
.
phi
-=
2.
*
pi
;
//rotate to lab frame
CAngle
lPlusSLab
=
CAngle
::
transform
(
lPlusSCM
,
spin
);
//angle of L vector - orbital angular momentum
CAngle
LLLab
;
if
(
EvapS1
>
0.0
)
{
// find orientation of L vector with respect to l_plus_s vector
// (i.e. z axis parallel to l_plus_s)
CAngle
LL
;
if
(
EvapLPlusS
>
0.0
)
LL
.
theta
=
acos
((
pow
(
EvapLPlusS
,
2
)
+
pow
((
float
)
EvapL
,
2
)
-
pow
(
EvapS1
,
2
))
/
(
2.0
*
EvapLPlusS
*
(
float
)
EvapL
));
else
LL
.
theta
=
acos
(
1.
-
2.
*
ran
.
Rndm
());
LL
.
phi
=
2.
*
pi
*
ran
.
Rndm
();
// rotate to lab frame
LLLab
=
CAngle
::
transform
(
LL
,
lPlusSLab
);
// orientation of s1 vector with respect to l_plus_s
// (i.e. z axis parallel to l_plus_s)
CAngle
SS
;
if
(
EvapLPlusS
>
0.0
&&
EvapL
>
0
)
SS
.
theta
=
acos
((
pow
(
EvapLPlusS
,
2
)
+
pow
((
float
)
EvapL
,
2
)
-
pow
((
float
)
EvapS1
,
2
))
/
(
2.0
*
EvapLPlusS
*
(
float
)
EvapL
));
else
if
(
EvapL
==
0
)
SS
.
theta
=
0.
;
else
SS
.
theta
=
acos
(
1.
-
2.
*
ran
.
Rndm
());
SS
.
phi
=
LL
.
phi
+
pi
;
if
(
SS
.
phi
>
2.
*
pi
)
SS
.
phi
-=
2.
*
pi
;
// rotate to lab frame
daughterLight
->
spin
=
CAngle
::
transform
(
SS
,
lPlusSLab
);
}
else
// spin zero particle
{
LLLab
.
theta
=
lPlusSLab
.
theta
;
LLLab
.
phi
=
lPlusSLab
.
phi
;
CAngle
S1Lab
(
0.
,
0.
);
daughterLight
->
spin
=
S1Lab
;
}
// emission vector is perpendicular to l vector for classical mechanics
// a good approximation can be obtained if theta
// is chosen from the legendre distribution sqaured for m=l
CAngle
emitL
;
emitL
.
theta
=
angleDist
.
getTheta
(
EvapL
);
emitL
.
phi
=
2.
*
pi
*
ran
.
Rndm
();
// rotate into the lab frame
CAngle
emitLab
=
CAngle
::
transform
(
emitL
,
spin
);
if
(
EvapEk
<
0.0
)
{
cout
<<
"EvapEk < 0"
<<
" "
<<
EvapEk
<<
" "
<<
iZ
<<
" "
<<
iA
<<
" "
<<
fEx
<<
" "
<<
fJ
<<
" "
<<
daughterLight
->
iZ
<<
" "
<<
daughterLight
->
iA
<<
" "
<<
daughterLight
->
fEx
<<
" "
<<
daughterLight
->
fJ
<<
" "
<<
daughterHeavy
->
iZ
<<
" "
<<
daughterHeavy
->
iA
<<
" "
<<
daughterHeavy
->
fEx
<<
" "
<<
daughterHeavy
->
fJ
<<
endl
;
CNucleus
*
parent
;
parent
=
getParent
();
cout
<<
parent
->
iZ
<<
" "
<<
parent
->
iA
<<
" "
<<
parent
->
fEx
<<
" "
<<
parent
->
fJ
<<
endl
;
parent
=
parent
->
getParent
();
cout
<<
parent
->
iZ
<<
" "
<<
parent
->
iA
<<
" "
<<
parent
->
fEx
<<
" "
<<
parent
->
fJ
<<
endl
;
abort
();
}
// get velocities
float
vrel
=
sqrt
(
2.0
*
EvapEk
*
(
float
)(
EvapA1
+
EvapA2
)
/
(
float
)(
EvapA1
*
EvapA2
))
*
0.9794
;
float
v1
=
(
float
)
EvapA2
/
(
float
)(
EvapA2
+
EvapA1
)
*
vrel
;
daughterLight
->
velocity
[
0
]
=
v1
*
sin
(
emitLab
.
theta
)
*
cos
(
emitLab
.
phi
);
daughterLight
->
velocity
[
1
]
=
v1
*
sin
(
emitLab
.
theta
)
*
sin
(
emitLab
.
phi
);
daughterLight
->
velocity
[
2
]
=
v1
*
cos
(
emitLab
.
theta
);
float
v2
=
vrel
-
v1
;
emitLab
.
theta
=
pi
-
emitLab
.
theta
;
emitLab
.
phi
+=
pi
;
if
(
emitLab
.
phi
>
2.
*
pi
)
emitLab
.
phi
-=
2.
*
pi
;
daughterHeavy
->
velocity
[
0
]
=
v2
*
sin
(
emitLab
.
theta
)
*
cos
(
emitLab
.
phi
);
daughterHeavy
->
velocity
[
1
]
=
v2
*
sin
(
emitLab
.
theta
)
*
sin
(
emitLab
.
phi
);
daughterHeavy
->
velocity
[
2
]
=
v2
*
cos
(
emitLab
.
theta
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
daughterLight
->
velocity
[
i
]
+=
velocity
[
i
];
daughterHeavy
->
velocity
[
i
]
+=
velocity
[
i
];
}
}
//*********************************************************
/**
* selects the velocity of evaporated particles, the emission angles
* is assumed isotropic
*/
void
CNucleus
::
angleIsotropic
()
{
//chooses angles and velocities of evaporated particles from isotropic
//distribution - used with Weiskopf formalism
float
theta
=
acos
(
1.
-
2.
*
ran
.
Rndm
());
float
phi
=
2.
*
pi
*
ran
.
Rndm
();
float
vrel
=
sqrt
(
2.0
*
EvapEk
*
(
float
)(
EvapA1
+
EvapA2
)
/
(
float
)(
EvapA1
*
EvapA2
))
*
0.9794
;
float
v1
=
(
float
)
EvapA2
/
(
float
)(
EvapA2
+
EvapA1
)
*
vrel
;
daughterLight
->
velocity
[
0
]
=
v1
*
sin
(
theta
)
*
cos
(
phi
);
daughterLight
->
velocity
[
1
]
=
v1
*
sin
(
theta
)
*
sin
(
phi
);
daughterLight
->
velocity
[
2
]
=
v1
*
cos
(
theta
);
float
v2
=
vrel
-
v1
;
theta
=
pi
-
theta
;
phi
+=
pi
;
if
(
phi
>
2.
*
pi
)
phi
-=
2.
*
pi
;
daughterHeavy
->
velocity
[
0
]
=
v2
*
sin
(
theta
)
*
cos
(
phi
);
daughterHeavy
->
velocity
[
1
]
=
v2
*
sin
(
theta
)
*
sin
(
phi
);
daughterHeavy
->
velocity
[
2
]
=
v2
*
cos
(
theta
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
daughterLight
->
velocity
[
i
]
+=
velocity
[
i
];
daughterHeavy
->
velocity
[
i
]
+=
velocity
[
i
];
}
}
//*********************************************************
/**
* used to check momentum conservation
*
* prints out the center-of-mass velocity of all decay products
*/
void
CNucleus
::
vCMofAllProducts
()
{
float
momTot
[
3
]
=
{
0.
,
0.
,
0.
};
for
(
int
i
=
0
;
i
<
iStable
;
i
++
)
{
for
(
int
j
=
0
;
j
<
3
;
j
++
)
momTot
[
j
]
+=
stableProducts
[
i
]
->
velocity
[
j
]
*
(
float
)
stableProducts
[
i
]
->
iA
;
}
float
vcm
[
3
];
for
(
int
j
=
0
;
j
<
3
;
j
++
)
vcm
[
j
]
=
momTot
[
j
]
/
(
float
)
iA
;
cout
<<
"Vcm= "
<<
vcm
[
0
]
<<
" "
<<
vcm
[
1
]
<<
" "
<<
vcm
[
2
]
<<
endl
;
}
//************************************************************************
/**
* Returns the total gamma-ray decay width in MeV
*
* Contributions from E1's and E2's only
*/
float
CNucleus
::
gammaWidth
()
{
float
widthTot
=
0
;
float
width
[
3
];
float
Ex
[
3
];
float
S0
[
3
];
for
(
int
iMode
=
1
;
iMode
<=
2
;
iMode
++
)
{
//if (iMode == 1) width[iMode]=gammaWidthE1GDR();
//else width[iMode] = gammaWidthMultipole(iMode);
width
[
iMode
]
=
gammaWidthMultipole
(
iMode
);
Ex
[
iMode
]
=
GammaEx
;
S0
[
iMode
]
=
GammaJ
;
widthTot
+=
width
[
iMode
];
}
if
(
widthTot
<=
0.
)
return
0.
;
int
iMode
;
if
(
ran
.
Rndm
()
<
width
[
1
]
/
widthTot
)
iMode
=
1
;
else
iMode
=
2
;
GammaEx
=
Ex
[
iMode
];
GammaJ
=
S0
[
iMode
];
GammaL
=
iMode
;
return
widthTot
;
}
//**************************************************************
/**
* Returns the gamma-ray decay width in MeV for a specified multipole.
* The width is from Blatt and Weisskopf, "Theoretical Nuclear Physics"
* (Wiley, New York, 1958) Page=649 scaled by the factors gammaInhibition[]
* Values of the latter are taken from Phys. Rev. C39, 516 (1989).
\param iMode 1 is E1, 2=E2
*/
float
CNucleus
::
gammaWidthMultipole
(
int
iMode
)
{
//iMode =1 is E1 and Imode=2 is E2
//width given in units of MeV
storeEvap
=
new
SStoreEvap
[
nGamma
];
float
deltaE
=
1
;
if
(
fEx
-
Erot
<=
15.0
)
deltaE
=
0.2
;
float
exponent
=
(
float
)(
2.
*
iMode
)
/
3.
;
float
constant
=
pow
((
float
)(
iA
),
exponent
)
*
wue
[
iMode
]
*
pi
*
2.0
;
constant
*=
gammaInhibition
[
iMode
];
float
S0
=
fJ
;
float
S0Min
=
fabs
(
S0
-
(
float
)
iMode
);
float
S0Max
=
S0
+
(
float
)
iMode
;
S0
=
S0Min
;
float
sumGammaMax
=
0.0
;
float
width
=
0.
;
int
jj
=
0
;
for
(;;)
//loop over S0 nucleus spin
{
float
Erotation
=
yrast
.
getYrast
(
iZ
,
iA
,
S0
);
float
U2Max
=
fEx
-
Erotation
;
if
(
U2Max
<
0.01
)
break
;
float
e
=
0.1
;
float
sumGamma
=
0.0
;
float
gammaMax
=
0.0
;
for
(;;)
//loop over excitation energy
{
float
U2
=
U2Max
-
e
;
if
(
U2
<
0.01
)
break
;
float
logLevelDensityDaughter
=
levelDensity
.
getLogLevelDensitySpherical
(
iA
,
U2
,
fPairing
,
fShell
,
S0
,
fMInertia
);
if
(
logLevelDensityDaughter
==
0
)
break
;
float
gamma
=
pow
(
e
,
2
*
iMode
+
1
)
*
constant
*
deltaE
*
exp
(
logLevelDensityDaughter
-
logLevelDensity
)
/
2.
/
pi
;
storeEvap
[
jj
].
gamma
=
gamma
;
storeEvap
[
jj
].
spin
=
(
int
)
S0
;
storeEvap
[
jj
].
energy
=
e
;
gammaMax
=
max
(
gamma
,
gammaMax
);
sumGamma
+=
gamma
;
if
(
jj
>
0
)
storeEvap
[
jj
].
gamma
+=
storeEvap
[
jj
-
1
].
gamma
;
jj
++
;
if
(
jj
>
nGamma
)
{
cout
<<
" increase nGamma"
<<
endl
;
abort
();
}
if
(
gamma
<
0.01
*
gammaMax
)
break
;
e
+=
deltaE
;
}
sumGammaMax
=
max
(
sumGamma
,
sumGammaMax
);
if
(
sumGamma
<
0.01
*
sumGammaMax
)
break
;
width
+=
sumGamma
;
S0
++
;
if
(
S0
>
S0Max
)
break
;
}
if
(
jj
==
0
||
width
<=
0.
)
{
delete
[]
storeEvap
;
return
0.
;
}
int
i
=
0
;
float
xran
=
ran
.
Rndm
();
for
(;;)
{
float
prob
=
storeEvap
[
i
].
gamma
/
width
;
if
(
xran
<
prob
)
break
;
i
++
;
if
(
i
==
jj
)
break
;
}
//choose gamma energy and excitation energy of residual
float
e
;
// gamma ray energy
GammaEx
=
-
1.
;
int
iTry
=
0
;
for
(;;)
{
e
=
storeEvap
[
i
].
energy
+
deltaE
*
(
0.5
*
ran
.
Rndm
());
GammaEx
=
fEx
-
e
;
if
(
e
>
0.
&&
GammaEx
>
0.
)
break
;
iTry
++
;
if
(
iTry
>
10
)
{
e
=
storeEvap
[
i
].
energy
;
GammaEx
=
fEx
-
e
;
break
;
}
}
GammaJ
=
storeEvap
[
i
].
spin
;
if
(
iA
%
2
==
1
)
GammaJ
+=
0.5
;
delete
[]
storeEvap
;
return
width
;
}
//*****************************************************************
/**
* Returns the gamma-ray decay width in MeV for statistical E1
* taking into acount GDR strength function
* see see D.R. Chakrabarty et al. Phys Rev. C36 (1987) 1886
*/
float
CNucleus
::
gammaWidthE1GDR
()
{
//gives the statistical E1 gamma width in units of MeV
storeEvap
=
new
SStoreEvap
[
nGamma
];
float
deltaE
=
1
;
if
(
fEx
-
Erot
<=
15.0
)
deltaE
=
0.2
;
//giant dipole strength function
//see D.R. Chakrabarty et al. Phys Rev. C36 (1987) 1886
//for details
float
EGDR
=
77.0
/
pow
((
float
)
iA
,(
float
)(
1.
/
3.
));
float
gammaGDR
=
4.8
+
0.0026
*
pow
(
fEx
-
Erot
,(
float
)
1.6
);
float
Fe1
=
2.09e-5
*
(
float
)
iZ
*
(
float
)(
iA
-
iZ
)
/
(
float
)(
iA
)
*
gammaGDR
;
float
S0
=
fJ
;
float
S0Min
=
fabs
(
S0
-
1.
);
float
S0Max
=
S0
+
1.
;
S0
=
S0Min
;
float
sumGammaMax
=
0.0
;
float
width
=
0.
;
int
jj
=
0
;
for
(;;)
//loop over S0 nucleus spin
{
float
Erotation
=
yrast
.
getYrast
(
iZ
,
iA
,
S0
);
float
U2Max
=
fEx
-
Erotation
;
if
(
U2Max
<
0.01
)
break
;
float
e
=
0.1
;
float
sumGamma
=
0.0
;
float
gammaMax
=
0.0
;
for
(;;)
//loop over excitation energy
{
float
U2
=
U2Max
-
e
;
if
(
U2
<
0.01
)
break
;
float
logLevelDensityDaughter
=
levelDensity
.
getLogLevelDensitySpherical
(
iA
,
U2
,
fPairing
,
fShell
,
S0
,
fMInertia
);
if
(
logLevelDensityDaughter
==
0
)
break
;
float
gamma
=
Fe1
*
pow
(
e
,
4
)
/
(
pow
(
pow
(
e
,
2
)
-
pow
(
EGDR
,
2
),
2
)
+
pow
(
gammaGDR
*
e
,
2
))
*
deltaE
*
exp
(
logLevelDensityDaughter
-
logLevelDensity
)
/
2.
/
pi
;
storeEvap
[
jj
].
gamma
=
gamma
;
storeEvap
[
jj
].
spin
=
(
int
)
S0
;
storeEvap
[
jj
].
energy
=
e
;
gammaMax
=
max
(
gamma
,
gammaMax
);
sumGamma
+=
gamma
;
if
(
jj
>
0
)
storeEvap
[
jj
].
gamma
+=
storeEvap
[
jj
-
1
].
gamma
;
jj
++
;
if
(
jj
>
nGamma
)
{
cout
<<
" increase nGamma"
<<
endl
;
abort
();
}
if
(
gamma
<
0.01
*
gammaMax
)
break
;
e
+=
deltaE
;
}
sumGammaMax
=
max
(
sumGamma
,
sumGammaMax
);
if
(
sumGamma
<
0.01
*
sumGammaMax
)
break
;
width
+=
sumGamma
;
S0
++
;
if
(
S0
>
S0Max
)
break
;
}
if
(
jj
==
0
||
width
<=
0.
)
{
delete
[]
storeEvap
;
return
0.
;
}
int
i
=
0
;
float
xran
=
ran
.
Rndm
();
for
(;;)
{
float
prob
=
storeEvap
[
i
].
gamma
/
width
;
if
(
xran
<
prob
)
break
;
i
++
;
if
(
i
==
jj
)
break
;
}
float
e
=
storeEvap
[
i
].
energy
;
e
+=
deltaE
*
(
0.5
*
ran
.
Rndm
());
if
(
e
<
0.
)
e
=
0.
;
GammaEx
=
fEx
-
e
;
GammaJ
=
storeEvap
[
i
].
spin
;
if
(
iA
%
2
==
1
)
GammaJ
+=
0.5
;
delete
[]
storeEvap
;
return
width
;
}
//*****************************************************************
/**
* Selects the angle and sin axis of a daughter product after gamma
* emission
*/
void
CNucleus
::
angleGamma
()
{
for
(
int
i
=
0
;
i
<
3
;
i
++
)
daughterHeavy
->
velocity
[
i
]
=
velocity
[
i
];
// find orientation of residue spin vector with respect to s0
// vector (i.e. z axis parallel to s0)
CAngle
residueCM
;
if
(
GammaL
>
0
&&
fJ
>
0.0
)
residueCM
.
theta
=
acos
((
pow
(
fJ
,
2
)
+
pow
((
float
)
GammaL
,
2
)
-
pow
(
GammaJ
,
2
))
/
(
2.0
*
(
float
)
GammaL
*
fJ
));
else
if
(
GammaL
==
0
)
residueCM
.
theta
=
0
;
else
residueCM
.
theta
=
acos
(
1.
-
2.
*
ran
.
Rndm
());
residueCM
.
phi
=
2.
*
pi
*
ran
.
Rndm
();
// rotate to lab frame
daughterHeavy
->
spin
=
CAngle
::
transform
(
residueCM
,
spin
);
}
//*******************************************************************
/**
* Return the theta angle of the fragments in radians
*/
float
CNucleus
::
getTheta
()
{
float
V
=
0.
;
for
(
int
i
=
0
;
i
<
3
;
i
++
)
V
+=
pow
(
velocity
[
i
],
2
);
return
acos
(
velocity
[
2
]
/
sqrt
(
V
));
}
//*******************************************************************
/**
* Returns the theta and phi angle of the fragments in radians
*/
CAngle
CNucleus
::
getAngle
()
{
float
V
=
0.
;
for
(
int
i
=
0
;
i
<
3
;
i
++
)
V
+=
pow
(
velocity
[
i
],
2
);
float
theta
;
float
phi
;
if
(
V
>
0.
)
{
theta
=
acos
(
velocity
[
2
]
/
sqrt
(
V
));
phi
=
atan2
(
velocity
[
1
],
velocity
[
0
]);
}
else
{
theta
=
0.0
;
phi
=
0.0
;
}
return
CAngle
(
theta
,
phi
);
}
//*******************************************************************
/**
* Return the theta angle of the fragments in degrees
*/
float
CNucleus
::
getThetaDegrees
()
{
//get the theta angle of a fragments in degrees
return
getTheta
()
*
180.
/
pi
;
}
//************************************************
/**
* returns the theta and phi angles in degrees
*/
CAngle
CNucleus
::
getAngleDegrees
()
{
CAngle
angle
=
getAngle
();
angle
.
theta
*=
180.
/
pi
;
angle
.
phi
*=
180.
/
pi
;
return
angle
;
}
//*****************************************
/**
* Calculated the evaporation decay width of a channel in MeV using
* the Weisskopf formulism
\param saddle bool true=saddleToScission decay false=normal evaporation
*/
float
CNucleus
::
weiskopf
(
bool
saddle
)
{
//calculates the evaporation decay width with the Weiskopf formalism
lightP
->
width
=
0.
;
lightP
->
iStore
=
0
;
if
(
exp
(
-
lightP
->
fEx
/
temp
)
<
0.01
)
return
0.
;
lightP
->
residue
.
iZ
=
iZ
-
lightP
->
iZ
;
if
(
lightP
->
iZ
>=
lightP
->
residue
.
iZ
)
return
0.
;
lightP
->
residue
.
iA
=
iA
-
lightP
->
iA
;
if
(
lightP
->
iA
>=
lightP
->
residue
.
iA
)
return
0.
;
if
(
lightP
->
residue
.
iZ
>=
lightP
->
residue
.
iA
)
return
0.
;
//products must lie on the chart of nuclides used by gemini
if
(
lightP
->
residue
.
iA
<
mass
->
chart
.
getAmin
(
lightP
->
residue
.
iZ
))
return
0.
;
if
(
lightP
->
residue
.
iA
>
mass
->
chart
.
getAmax
(
lightP
->
residue
.
iZ
))
return
0.
;
rResidue
=
r0
*
pow
((
float
)
lightP
->
residue
.
iA
,(
float
)(
1.
/
3.
));
lightP
->
fMInertia
=
0.4
*
(
float
)
lightP
->
residue
.
iA
*
pow
(
rResidue
,
2
);
lightP
->
fMInertiaOrbit
=
(
float
)(
lightP
->
residue
.
iA
*
lightP
->
iA
)
/
(
float
)(
lightP
->
residue
.
iA
+
lightP
->
iA
)
*
pow
(
rResidue
+
lightP
->
rLight
+
2.
,
2
);
if
(
saddle
)
{
if
(
fissionMassScission
)
scission
.
init
(
lightP
->
residue
.
iZ
,
lightP
->
residue
.
iA
,
fJ
,
2
);
else
{
float
Z1
=
(
float
)
fissionZ
/
(
float
)
fissioningZ
*
(
float
)
lightP
->
residue
.
iZ
;
float
A1
=
(
float
)
fissionA
/
(
float
)
fissioningA
*
(
float
)
lightP
->
residue
.
iA
;
scission
.
init
(
lightP
->
residue
.
iZ
,
lightP
->
residue
.
iA
,
fJ
,
2
,
Z1
,
A1
);
}
}
//odd A nuclei have 1/2 integer spin
lightP
->
odd
=
0
;
if
(
lightP
->
residue
.
iA
%
2
==
1
)
lightP
->
odd
=
1
;
if
(
lightP
->
residue
.
iZ
>
Zshell
)
lightP
->
fPair
=
mass
->
getPairing
(
lightP
->
residue
.
iZ
,
lightP
->
residue
.
iA
);
else
lightP
->
fPair
=
0.
;
lightP
->
residue
.
fExpMass
=
mass
->
getCalMass
(
lightP
->
residue
.
iZ
,
lightP
->
residue
.
iA
);
lightP
->
fShell
=
0.
;
if
(
lightP
->
residue
.
iZ
>
Zshell
)
lightP
->
fShell
=
mass
->
getShellCorrection
(
lightP
->
residue
.
iZ
,
lightP
->
residue
.
iA
);
lightP
->
separationEnergy
=
lightP
->
residue
.
fExpMass
+
lightP
->
fExpMass
-
fExpMass
;
float
Edef
=
0.
;
if
(
saddle
)
{
Edef
=
scission
.
getScissionEnergy
();
Edef
-=
lightP
->
residue
.
fExpMass
;
}
else
Edef
=
yrast
.
getYrast
(
iZ
,
iA
,
fJ
);
float
maxGamma
=
0.
;
float
constant
=
(
2.
*
lightP
->
fJ
+
1.
)
*
de
/
(
2.
*
pi
);
if
(
!
saddle
)
constant
*=
(
2
*
fJ
+
1.
);
//prepare transmission coeff
float
Ecoul
;
if
(
Isig
)
{
lightP
->
sigBarDist
->
prepare
((
float
)
lightP
->
residue
.
iZ
,(
float
)
lightP
->
residue
.
iA
);
Ecoul
=
lightP
->
sigBarDist
->
getBarrier
();
}
else
{
lightP
->
sigBarDist
->
prepare
((
float
)
lightP
->
residue
.
iZ
,(
float
)
lightP
->
residue
.
iA
);
Ecoul
=
lightP
->
sigBarDist
->
getBarrier
();
lightP
->
tlArray
->
prepare
(
lightP
->
residue
.
iZ
);
}
float
fEk
=
Ecoul
;
bool
up
=
1
;
for
(;;)
{
float
U
=
fEx
-
lightP
->
separationEnergy
-
fEk
-
Edef
;
if
(
U
<=
0.
)
break
;
float
logLevelDensity2
=
0.
;
if
(
saddle
)
logLevelDensity2
=
levelDensity
.
getLogLevelDensityScission
(
iA
,
U
);
else
logLevelDensity2
=
levelDensity
.
getLogLevelDensitySpherical
(
lightP
->
residue
.
iA
,
U
,
lightP
->
fPair
,
lightP
->
fShell
,
-
fJ
,
lightP
->
fMInertia
);
if
(
logLevelDensity2
==
0.
)
break
;
float
temp
=
levelDensity
.
getTemp
();
float
sigmaInverse
;
if
(
Isig
)
sigmaInverse
=
lightP
->
sigBarDist
->
getInverseXsec
(
fEk
,
temp
);
else
sigmaInverse
=
lightP
->
tlArray
->
getInverseXsec
(
fEk
,
temp
);
float
gamma
=
sigmaInverse
*
exp
(
logLevelDensity2
-
logLevelDensity
)
*
constant
;
lightP
->
width
+=
gamma
;
lightP
->
storeEvap
[
lightP
->
iStore
].
gamma
=
gamma
;
if
(
lightP
->
iStore
>
0
)
lightP
->
storeEvap
[
lightP
->
iStore
].
gamma
+=
lightP
->
storeEvap
[
lightP
->
iStore
-
1
].
gamma
;
lightP
->
storeEvap
[
lightP
->
iStore
].
energy
=
fEk
;
lightP
->
iStore
++
;
if
(
lightP
->
iStore
==
lightP
->
nStore
)
{
cout
<<
"increase nStore in nucleus.h "
<<
endl
;
abort
();
}
maxGamma
=
max
(
maxGamma
,
gamma
);
if
(
gamma
<
maxGamma
*
.01
)
{
if
(
up
)
{
up
=
0
;
fEk
=
Ecoul
-
de
;
if
(
fEk
<=
0.
)
break
;
else
continue
;
}
else
break
;
}
if
(
up
)
fEk
+=
de
;
else
{
fEk
-=
de
;
if
(
fEk
<-
0.
)
break
;
}
}
// float del = 0.;
//if (lightP->residue.iA%2 == 1)del = 0.5;
return
lightP
->
width
;
}
//*****************************************
/**
* Calculates the decay width for evaporation at the scission point using
* the Weiskopf formalism
*
* The width is given in units of MeV
*/
float
CNucleus
::
evaporationWidthSS
()
{
float
width
=
0.
;
EcostMin
=
1000.
;
bool
isaddle
=
1
;
for
(
int
i
=
0
;
i
<
evap
.
nLight
;
i
++
)
{
lightP
=
evap
.
lightP
[
i
];
evap
.
prob
[
i
]
=
weiskopf
(
isaddle
);
width
+=
evap
.
prob
[
i
];
if
(
i
>
0
)
evap
.
prob
[
i
]
+=
evap
.
prob
[
i
-
1
];
}
if
(
width
<=
0.
)
return
0.
;
//if decay possible choose channel
float
xran
=
ran
.
Rndm
();
int
i
=
0
;
for
(;;)
{
float
prob
=
evap
.
prob
[
i
]
/
width
;
if
(
prob
>
xran
)
break
;
if
(
i
==
evap
.
nLight
-
1
)
break
;
i
++
;
}
lightP
=
evap
.
lightP
[
i
];
EvapZ1
=
lightP
->
iZ
;
EvapA1
=
lightP
->
iA
;
EvapZ2
=
iZ
-
EvapZ1
;
EvapA2
=
iA
-
EvapA1
;
EvapMode
=
i
;
EvapEx1
=
lightP
->
fEx
;
EvapS1
=
lightP
->
fJ
;
getSpin
(
bool
(
1
));
return
width
;
}
//*****************************************
/**
* Initializes the compound nucleus excitation and spin.
\param fEx0 is the compound nucleus excitation energy in MeV
\param fJ0 is the compound nucleus spin in hbar
*/
void
CNucleus
::
setCompoundNucleus
(
float
fEx0
,
float
fJ0
)
{
//initialize as a compound nucleus ready for decay
excite
(
fEx0
,
fJ0
);
origin
=
0
;
timeSinceStart
=
0.
;
sumGammaEnergy
=
0.
;
iPoint
=
-
1
;
runningWeight
=
1.
;
iWeight
=
0
;
bResidue
=
true
;
bSymmetricFission
=
false
;
bAsymmetricFission
=
false
;
}
//*****************************************
/**
* Initializes the compound nucleus excitation and spin.
\param dEx0 is the compound nucleus excitation energy in MeV
\param fJ0 is the compound nucleus spin in hbar
*/
void
CNucleus
::
setCompoundNucleus
(
double
dEx0
,
float
fJ0
)
{
setCompoundNucleus
((
float
)
dEx0
,
fJ0
);
}
//********************************************
/**
* Initializes the compound nucleus excitation and spin.
\param fEx0 is the compound nucleus excitation energy in MeV
\param dJ0 is the compound nucleus spin in hbar
*/
void
CNucleus
::
setCompoundNucleus
(
float
fEx0
,
double
dJ0
)
{
setCompoundNucleus
(
fEx0
,(
float
)
dJ0
);
}
//**********************************************
/**
* Initializes the compound nucleus excitation and spin.
\param dEx0 is the compound nucleus excitation energy in MeV
\param dJ0 is the compound nucleus spin in hbar
*/
void
CNucleus
::
setCompoundNucleus
(
double
dEx0
,
double
dJ0
)
{
setCompoundNucleus
((
float
)
dEx0
,(
float
)
dJ0
);
}
//*************************************************
/**
* Returns a pointer to a stable decay product.
*
* if no input given, the first or next product is pointed to.
/param i is the index of the product (0-getNumberOfProducts-1)
*/
CNucleus
*
CNucleus
::
getProducts
(
int
i
/*=-1*/
)
{
//returns pointer to array of stable products
if
(
i
>=
0
)
iPoint
=
i
;
else
iPoint
++
;
return
stableProducts
[
iPoint
];
}
//*************************************************
/**
* Returns a pointer to the parent nucleus,
* i.e. the nucleus which emitted this product.
* This is useful to see if there was secondary decay.
* If the NULL pointer is returned, then the
* initial compound nucleus did not decay presumably
* because there was not enough excitation energy.
* Obveriously in this case the final product is the same
* as the initial nucleus and there is no parent.
*
*/
CNucleus
*
CNucleus
::
getParent
()
{
return
parent
;
}
//*****************************************
/**
*Returns a pointer to the heavy daughter nucleus
*If NULL is returned, then this fragment was stable
*/
CNucleus
*
CNucleus
::
getHeavyDaughter
()
{
return
daughterHeavy
;
}
//*****************************************
/**
* Returns a pointer to the light daughter nucleus
* if NULL is returned, then this fragment was stable
* or a fission event stated, in which case the
* heavy daughter pointer will not be NULL
*/
CNucleus
*
CNucleus
::
getLightDaughter
()
{
return
daughterLight
;
}
//**************************************************
/**
* Returns the number of stable decay products produced in the
*the statistical decay
*/
int
CNucleus
::
getNumberOfProducts
()
{
return
iStable
;
}
//**************************************************************
/**
* Causes the nucleus to undergo statistical decay
*/
void
CNucleus
::
decay
()
{
int
iProductsOld
=
iProducts
;
int
iStableOld
=
iStable
;
int
tries
=
0
;
for
(;;)
{
recursiveDecay
();
if
(
abortEvent
==
0
)
break
;
//cout << "aborted event, try again" << endl;
// valid event could not be generated
// set arrays points back to NULL and try again
abortEvent
=
0
;
if
(
iProducts
>
iProductsOld
)
{
for
(
int
i
=
iProducts
-
1
;
i
>=
iProductsOld
;
i
--
)
{
allProducts
[
i
]
->
daughterLight
=
NULL
;
allProducts
[
i
]
->
daughterHeavy
=
NULL
;
delete
allProducts
[
i
];
allProducts
[
i
]
=
NULL
;
}
}
if
(
iStable
>
iStableOld
)
{
for
(
int
i
=
iStable
-
1
;
i
>=
iStableOld
;
i
--
)
{
stableProducts
[
i
]
=
NULL
;
}
}
iProducts
=
iProductsOld
;
iStable
=
iStableOld
;
daughterLight
=
NULL
;
daughterHeavy
=
NULL
;
tries
++
;
if
(
tries
>
3
)
{
cout
<<
"given up trying to decay this nucleus"
<<
endl
;
cout
<<
" Z = "
<<
iZ
<<
" A= "
<<
iA
<<
" Ex = "
<<
fEx
<<
" J= "
<<
fJ
<<
endl
;
abortEvent
=
1
;
return
;
}
}
multPostLight
=
0
;
multPostHeavy
=
0
;
multSaddleToScission
=
0
;
multPreSaddle
=
0
;
for
(
int
i
=
0
;
i
<
iStable
;
i
++
)
{
if
(
stableProducts
[
i
]
->
iZ
==
0
&&
stableProducts
[
i
]
->
iA
==
1
)
{
if
(
stableProducts
[
i
]
->
origin
==
2
)
multPostLight
++
;
if
(
stableProducts
[
i
]
->
origin
==
3
)
multPostHeavy
++
;
if
(
stableProducts
[
i
]
->
origin
==
1
)
multSaddleToScission
++
;
if
(
stableProducts
[
i
]
->
origin
==
0
)
multPreSaddle
++
;
}
}
}
//************************************************************
bool
CNucleus
::
isSymmetricFission
()
/**
* Returns a true value if a symmetric fission occurred
* Only use this function for the compound nucleus object, otherwise
* the output is garbage.
*/
{
return
bSymmetricFission
;
}
//**********************************************
bool
CNucleus
::
isAsymmetricFission
()
/**
* Returns a true value if an asymmetyric fission occurred
* Only use this function for the compound nucleus object, otherwise
* the output is garbage.
*/
{
return
bAsymmetricFission
;
}
//**************************************************************
/**
* Returns a true value if the event doesn't fission and has an
* evaporation residue.
* Only use this function for the compound nucleus object, otherwise
* the output is garbage.
*/
bool
CNucleus
::
isResidue
()
{
return
bResidue
;
}
//*****************************************************************
/**
* returns a true value if the fragment does not undergo
* statistical decay, for example a particular excited state of
* a nucleus. These nuclei are produced in evaporation processes.
*/
bool
CNucleus
::
isNotStatistical
()
{
return
notStatistical
;
}
//****************************************************************
/**
* returns true if the nucleus is undergoing a saddle to scission
* transition. All symmetric fission events, pass thought this
* stage and some emit light particles during this stage.
*/
bool
CNucleus
::
isSaddleToScission
()
{
return
saddleToSciss
;
}
//****************************************************************
int
CNucleus
::
getMultPost
()
/**
* Returns the number of neutrons emitted from both fission fragments
*/
{
return
multPostLight
+
multPostHeavy
;
}
//****************************************************************
int
CNucleus
::
getMultPre
()
/**
* Returns the number of neutrons emitted before the scission point
*/
{
return
multPreSaddle
+
multSaddleToScission
;
}
//***************************************************************
int
CNucleus
::
getMultPostLight
()
/**
* returns the multiplicity of neutrons emitted from the lighter
* fission fragment.
*/
{
return
multPostLight
;
}
//*****************************************************************
int
CNucleus
::
getMultPostHeavy
()
/**
* returns the multiplicity of neutrons emitted from the heavier
* fission fragment.
*/
{
return
multPostHeavy
;
}
//****************************************************************
/**
* Returns the multiplicity of neutrons emitted before the saddle-point
*/
int
CNucleus
::
getMultPreSaddle
()
{
return
multPreSaddle
;
}
//************************************************************
/**
* Returns the multiplicity of neutrons emitted between saddle
* and scission
*/
int
CNucleus
::
getMultSaddleToScission
()
{
return
multSaddleToScission
;
}
//************************************************************
/**
* used to check for conservation of energy.
*
* this is a debugging tool. prints out the various contributions
* to teh final energy and the energy difference between inital and final
* states. The latter shoukd be zero is energy is conserved.
*/
void
CNucleus
::
energyConservation
()
{
float
sumKE
=
0.
;
float
sumMass
=
0.
;
float
sumEx
=
0.
;
for
(
int
i
=
0
;
i
<
iStable
;
i
++
)
{
sumKE
+=
stableProducts
[
i
]
->
getKE
();
sumMass
+=
stableProducts
[
i
]
->
getExcessMass
();
sumEx
+=
stableProducts
[
i
]
->
fEx
;
}
float
Qvalue
=
fExpMass
-
sumMass
;
cout
<<
sumKE
<<
" "
<<
Qvalue
<<
" "
<<
sumEx
<<
" "
<<
sumKE
-
Qvalue
+
sumEx
+
sumGammaEnergy
<<
" "
<<
fEx
-
sumKE
+
Qvalue
-
sumEx
-
sumGammaEnergy
<<
endl
;
}
//**********************************************************
float
CNucleus
::
getKE
()
/**
* Returns the fragments kinetic energy in MeV.
*/
{
float
KE
=
0.
;
for
(
int
i
=
0
;
i
<
3
;
i
++
)
KE
+=
pow
(
velocity
[
i
]
/
.9784
,
2
);
KE
*=
0.5
*
(
float
)
iA
;
return
KE
;
}
//**********************************************************
/**
* Returns the magnitude of the fragment's velocity in cm/ns
*/
float
CNucleus
::
getVelocity
()
{
float
vel
=
0.
;
for
(
int
i
=
0
;
i
<
3
;
i
++
)
vel
+=
pow
(
velocity
[
i
],
2
);
vel
=
sqrt
(
vel
);
return
vel
;
}
//**********************************************************
/**
* Returns the magnitude of the fragment's momentum in MeV/c
*/
float
CNucleus
::
getMomentum
()
{
return
getVelocity
()
*
(
float
)
iA
/
30.
*
931.5016
;
}
//********************************************************
/**
* Determines the angles and velocities of the daughter fragments
* when the decay was determined by the transition-state formulism
*/
void
CNucleus
::
split
(
CAngle
symmetryCM
)
{
//angles and velocity of fragments after binary decay (not evaporation)
float
A1
=
(
float
)
fissionA
;
float
A2
=
(
float
)(
iA
-
fissionA
);
float
Ared
=
A1
*
A2
/
(
A1
+
A2
);
//float Ek = yrast.viola((float)fissionZ,A1,
// (float)(iZ-fissionZ),A2);
float
Ek
=
scission
.
ekTot
;
float
Vrel
=
sqrt
(
2.0
*
Ek
/
Ared
)
*
0.9794
;
float
V1CM
=
A2
/
(
A1
+
A2
)
*
Vrel
;
float
V2CM
=
Vrel
-
V1CM
;
// in the c-o-m frame the velocity vectors are
daughterLight
->
velocity
[
0
]
=
V1CM
*
sin
(
symmetryCM
.
theta
)
*
cos
(
symmetryCM
.
phi
);
daughterLight
->
velocity
[
1
]
=
V1CM
*
sin
(
symmetryCM
.
theta
)
*
sin
(
symmetryCM
.
phi
);
daughterLight
->
velocity
[
2
]
=
V1CM
*
cos
(
symmetryCM
.
theta
);
// fragment 2 get emitted 180 degrees away.
symmetryCM
.
theta
=
pi
-
symmetryCM
.
theta
;
symmetryCM
.
phi
+=
pi
;
if
(
symmetryCM
.
phi
>
2.
*
pi
)
symmetryCM
.
phi
-=
2.
*
pi
;
daughterHeavy
->
velocity
[
0
]
=
V2CM
*
sin
(
symmetryCM
.
theta
)
*
cos
(
symmetryCM
.
phi
);
daughterHeavy
->
velocity
[
1
]
=
V2CM
*
sin
(
symmetryCM
.
theta
)
*
sin
(
symmetryCM
.
phi
);
daughterHeavy
->
velocity
[
2
]
=
V2CM
*
cos
(
symmetryCM
.
theta
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
daughterLight
->
velocity
[
i
]
+=
velocity
[
i
];
daughterHeavy
->
velocity
[
i
]
+=
velocity
[
i
];
}
return
;
}
//**********************************************************
/**
* can be used to initialize another compound nucleus
\param iZ0 is the proton number
\param iA0 is the mass number
\param fEx0 is the excitation energy in MeV
\param fJ0 is the spin in hbar
*/
void
CNucleus
::
setNewIsotope
(
int
iZ0
,
int
iA0
,
float
fEx0
,
float
fJ0
)
{
init
(
iZ0
,
iA0
);
setCompoundNucleus
(
fEx0
,
fJ0
);
}
//*******************************************************
/**
* sets the transient time (fission delay) in zs different from the default
* value. This is a static function.
*/
void
CNucleus
::
setTimeTransient
(
float
time
)
{
timeTransient
=
time
;
}
//*******************************************************
/**
* returns the transient time (fission delay) in zs different from the default
* value. This is a static function.
*/
float
CNucleus
::
getTimeTransient
()
{
return
timeTransient
;
}
//**************************************************************
/**
* returns a pointer to the array containing the velocity vector.
* units are in cm/ns
*/
float
*
CNucleus
::
getVelocityVector
()
{
return
velocity
;
}
//**************************************************************
/**
* returns a pointer to the arrays containing the momentum vector.
* units are in MeV/c
*/
float
*
CNucleus
::
getMomentumVector
()
{
for
(
int
i
=
0
;
i
<
3
;
i
++
)
momentum
[
i
]
=
velocity
[
i
]
*
(
float
)
iA
/
30.
*
931.5016
;
return
momentum
;
}
//****************************************************
/**
* sets the fission scale factor
\param factor is the scale factor
*/
void
CNucleus
::
setFissionScaleFactor
(
float
factor
)
{
fissionScaleFactor
=
factor
;
}
//***********************************************
/**
* returns the fission scale factor
*/
float
CNucleus
::
getFissionScaleFactor
()
{
return
fissionScaleFactor
;
}
//**************************************************
/**
* set the parameter controlling the width of the barrier distribution
\param width - width is \f$ \sqrt(T)* width \f$
*/
void
CNucleus
::
setBarWidth
(
float
width
)
{
CTlBarDist
::
setBarWidth
(
width
);
CSigBarDist
::
setBarWidth
(
width
);
}
//***************************************************
/**
* returns the paramter controlling the width of the barrier dist
*/
float
CNucleus
::
getBarWidth
()
{
return
CTlBarDist
::
getBarWidth
();
}
//****************************************************
/**
* set the width of the energy bins for integating the Hauser-Feshbach
*formulism
\param de0 with of the energy bin
*/
void
CNucleus
::
setDeltaE
(
float
de0
)
{
de
=
de0
;
}
//*******************************************************
/**
* returns the energy bin width used for integrating the Hauser-Feshbach
* formulism
*/
float
CNucleus
::
getDeltaE
()
{
return
de
;
}
//********************************************************
/**
* sets the threshold used to cut out low probability evaporation
* channels. All channels will be included if set to zero.
\param threshold0 is the threshold
*/
void
CNucleus
::
setThreshold
(
float
threshold0
)
{
threshold
=
threshold0
;
}
//*******************************************************
/**
* returns the threshold used to cut out low probability evaporation
* channels
*/
float
CNucleus
::
getThreshold
()
{
return
threshold
;
}
//***********************************************************
/**
* the symmetric fission barrier is modified by adding this quantity
\param barAdd0 barrier adjestment in MeV
*/
void
CNucleus
::
setAddToFisBarrier
(
float
barAdd0
)
{
barAdd
=
barAdd0
;
}
//***********************************************************
/**
* returns the quantity by which the symmerty fission is added to.
*/
float
CNucleus
::
getAddToFisBarrier
()
{
return
barAdd
;
}
//************************************************************
/**
* prints out the values of the statistical model parameters
*/
void
CNucleus
::
printParameters
()
{
CLevelDensity
::
printParameters
();
CTlBarDist
::
printParameters
();
CYrast
::
printParameters
();
cout
<<
"barAdd = "
<<
barAdd
<<
endl
;
cout
<<
"fissionScaleFactor = "
<<
fissionScaleFactor
<<
endl
;
if
(
fissionMassScission
)
cout
<<
" viscosity= "
<<
viscosity_scission
<<
endl
;
else
cout
<<
" viscosity= "
<<
viscosity_saddle
<<
endl
;
cout
<<
" fission delay = "
<<
timeTransient
<<
" e-21 s"
<<
endl
;
if
(
noIMF
)
cout
<<
" IMF emissions turned off"
<<
endl
;
else
cout
<<
" IMF turned on"
<<
endl
;
if
(
fissionMassScission
)
cout
<<
" fission mass dist determined at scission"
<<
endl
;
else
cout
<<
" fission mass dist determined at saddle"
<<
endl
;
if
(
BohrWheeler
)
cout
<<
" Bohr-Wheeler decay width"
<<
endl
;
else
cout
<<
" Lestone Decay width"
<<
endl
;
if
(
barAdd
!=
0.
)
cout
<<
barAdd
<<
" added to barriers"
<<
endl
;
// cout << "WignerAdd= " << WignerAdd << " WignerScaler= " << WignerScaled << endl;
cout
<<
"WignerAdd= "
<<
WignerAdd
<<
endl
;
if
(
iHF
==
1
)
cout
<<
"Hauser Feshback for evaporation"
<<
endl
;
else
if
(
iHF
==
0
)
{
cout
<<
"Weisskopf for evaporation with"
<<
endl
;
if
(
Isig
)
cout
<<
" parameterized inverse xsections"
<<
endl
;
else
cout
<<
" inverse xsection from sum of parameterized transmission coef"
<<
endl
;
}
else
if
(
iHF
==
2
)
{
cout
<<
"switches from HF to Weisskopf with"
<<
endl
;
if
(
Isig
)
cout
<<
" parameterized inverse xsections"
<<
endl
;
else
cout
<<
" inverse xsection from sum of parameterized transmission coef"
<<
endl
;
}
}
//************************************************************
/**
* Gives a correction to either the Bohr-Wheeler or Morreto formalism
* when the tilting angular momentum bearing mode is considered.
* See J. Lestone PRC 59 (1999) 1540
* the saddle-point shape is assumed constant as a function of K,
* the projection of the spin on the symmetry axis.
\param Usaddle is saddle point excitation energy in Mev
\param momInertiaEff is the effective moment of inertia for tilting
\param iAfAn switch to allow af/an value.
*/
float
CNucleus
::
LestoneCorrection
(
float
Usaddle
,
float
momInertiaEff
,
short
iAfAn
)
{
float
saddleLD
=
levelDensity
.
getLogLevelDensitySpherical
(
iA
,
Usaddle
,(
float
)
0.
,(
float
)
0.
,
fJ
,
fMInertia
,
iAfAn
);
float
saddleTemp
=
levelDensity
.
getTemp
();
float
K
=
fJ
-
roundf
(
fJ
);
float
tot
=
0.
;
for
(;;)
{
if
(
K
>
fJ
)
break
;
if
(
K
<
0.1
)
tot
=
1.
;
else
{
float
ErotK
=
kRotate
/
2.
*
pow
(
K
,
2
)
/
momInertiaEff
;
float
U
=
Usaddle
-
ErotK
;
if
(
U
<=
0.
)
break
;
float
LD
=
levelDensity
.
getLogLevelDensitySpherical
(
iA
,
U
,(
float
)
0.
,(
float
)
0.
,
fJ
,
fMInertia
,
iAfAn
);
float
yield
=
exp
(
LD
-
saddleLD
)
*
2.
*
levelDensity
.
getTemp
()
/
saddleTemp
;
if
(
yield
<
1.e-3
)
break
;
tot
+=
yield
;
}
K
++
;
}
return
tot
/
(
2.
*
fJ
+
1.
);
}
//************************************************************************
/**
* returns a pointer to the Compound nucleus
*/
CNucleus
*
CNucleus
::
getCompoundNucleus
()
{
CNucleus
*
parent
=
this
;
for
(;;)
{
CNucleus
*
parentNew
=
parent
->
getParent
();
if
(
parentNew
==
NULL
)
break
;
parent
=
parentNew
;
}
return
parent
;
}
//***********************************************************
/**
* Hauser-Feshbach routine to sum of the spin of the residual nucleus
\param Ekvalue if < 0, then loop over Ek, other for the specificed Ekvalue
*/
float
CNucleus
::
S2Loop
(
float
Ekvalue
)
{
lightP
->
iStore
=
0
;
S2
=
S2Start
;
float
width0
=
S2Width
(
Ekvalue
);
S2
+=
1.
;
float
width1
=
S2Width
(
Ekvalue
);
float
width
=
width0
+
width1
;
if
(
width
<=
0.
)
return
0.
;
float
sign
=
1.
;
if
(
width1
<
width0
)
sign
=
-
1.
;
float
gammaMax
=
max
(
width0
,
width1
);
//increase or decrease S2
if
(
sign
>
0.
)
S2
++
;
else
S2
=
S2Start
-
1
;
for
(;;)
{
if
(
S2
<
0.
)
break
;
float
gamma
=
S2Width
(
Ekvalue
);
gammaMax
=
max
(
gammaMax
,
gamma
);
width
+=
gamma
;
if
(
gamma
<
0.01
*
gammaMax
)
break
;
S2
+=
sign
;
}
//now go the other direction
if
(
sign
<
0.
)
S2
=
S2Start
+
2
;
else
S2
=
S2Start
-
1
;
sign
*=
-
1.
;
for
(;;)
{
if
(
S2
<
0.
)
break
;
float
gamma
=
S2Width
(
Ekvalue
);
gammaMax
=
max
(
gammaMax
,
gamma
);
width
+=
gamma
;
if
(
gamma
<
0.01
*
gammaMax
)
break
;
S2
+=
sign
;
}
return
width
;
}
//********************************************************************
/**
* calculates the Hauser-Feshbach decay width for a single S2 values,
* but integrated over l and ek
\param Ekvalue if < 0, then loop over Ek, other for the specificed Ekvalue
*/
float
CNucleus
::
S2Width
(
float
Ekvalue
)
{
// consider particle"s spin in determining
// the l (orbital angular momentum limits)
lPlusSMin
=
fabs
(
fJ
-
S2
);
//minimum value of (l+s) vector
lPlusSMax
=
fJ
+
S2
;
//maximum value of (l+s) vector
lMax
=
(
int
)
round
(
lPlusSMax
+
lightP
->
fJ
);
//maximum value of l vector
if
(
lMax
>
lMaxQuantum
)
lMax
=
lMaxQuantum
;
lMin
=
(
int
)
round
(
lPlusSMin
-
lightP
->
fJ
);
// minimum value of l
if
(
lMin
<
0
)
lMin
=
(
int
)
round
(
lightP
->
fJ
-
lPlusSMax
);
if
(
lMin
<
0
)
lMin
=
0
;
EYrast2
=
yrast
.
getYrast
(
lightP
->
residue
.
iZ
,
lightP
->
residue
.
iA
,
S2
);
UMin
=
fEx
-
lightP
->
separationEnergy
-
EYrast2
;
if
(
UMin
<
0
)
return
0
;
if
(
Ekvalue
<
0
)
return
EkLoop
();
else
return
EkWidth
(
Ekvalue
);
}
//********************************************************************
/**
* Calculates the Hauser-Feshbach decay width for a single S2 and ek,
* but integrated over l
*/
float
CNucleus
::
EkWidth
(
float
ek
)
{
float
U2
=
UMin
-
ek
;
float
daughterLD
=
levelDensity
.
getLogLevelDensitySpherical
(
lightP
->
residue
.
iA
,
U2
,
lightP
->
fPair
,
lightP
->
fShell
,
S2
,
lightP
->
fMInertia
);
if
(
daughterLD
==
0
)
return
0.
;
float
temp
=
levelDensity
.
getTemp
();
float
sumTl
=
getSumTl
(
ek
,
temp
);
if
(
sumTl
==
0
)
return
0.
;
float
gamma
=
de
*
sumTl
*
exp
(
daughterLD
-
logLevelDensity
)
/
2.
/
pi
;
if
(
gamma
<=
0.
)
return
0.
;
lightP
->
storeEvap
[
lightP
->
iStore
].
gamma
=
gamma
;
lightP
->
storeEvap
[
lightP
->
iStore
].
spin
=
(
int
)
S2
;
lightP
->
storeEvap
[
lightP
->
iStore
].
energy
=
ek
;
lightP
->
storeEvap
[
lightP
->
iStore
].
L
=
EvapL
;
if
(
lightP
->
iStore
>
0
)
lightP
->
storeEvap
[
lightP
->
iStore
].
gamma
+=
lightP
->
storeEvap
[
lightP
->
iStore
-
1
].
gamma
;
lightP
->
iStore
++
;
if
(
lightP
->
iStore
>
lightP
->
nStore
)
{
cout
<<
" increase nStore in Ek loop"
<<
endl
;
abort
();
}
/*
if (lightP->iA == 1 && lightP->iZ == 1)
{
cout << fEx - lightP->separationEnergy - ek << " " << S2 << " " << gamma <<
" " << daughterLD << " " << sumTl << " " << ek << endl;
}
*/
return
gamma
;
}
//******************************************
/**
*Hauser-Feshbach function to sum over kinetic energy for a given S2
*/
float
CNucleus
::
EkLoop
()
{
//find energy at which tl=0.5 approximately
float
ekMin
=
(
float
)((
lMin
+
1
)
*
lMin
)
*
20.454
/
lightP
->
fMInertiaOrbit
+
Ecoul
;
if
(
ekMin
>
UMin
)
ekMin
=
UMin
;
//start just below the barrier
ekMin
*=
0.8
;
ekMin
=
round
(
ekMin
+
de
/
2.0
)
-
de
/
2.0
;
if
(
ekMin
<
de
/
2.
)
ekMin
=
de
/
2.
;
float
ek
=
ekMin
;
float
width0
=
EkWidth
(
ek
);
ek
+=
de
;
float
width1
=
EkWidth
(
ek
);
float
width
=
width0
+
width1
;
if
(
width
<=
0.
)
return
0.
;
float
sign
=
1.
;
if
(
width1
<
width0
)
sign
=
-
1.
;
float
gammaMax
=
max
(
width0
,
width1
);
//increase or decrease S2
if
(
sign
>
0.
)
ek
+=
de
;
else
ek
=
ekMin
-
de
;
for
(;;)
{
if
(
ek
<
0.
)
break
;
float
gamma
=
EkWidth
(
ek
);
gammaMax
=
max
(
gammaMax
,
gamma
);
width
+=
gamma
;
if
(
gamma
<
0.01
*
gammaMax
)
break
;
ek
+=
sign
*
de
;
}
//now go the other direction
if
(
sign
<
0.
)
ek
=
ekMin
+
2.
*
de
;
else
ek
=
ekMin
-
de
;
sign
*=
-
1.
;
for
(;;)
{
if
(
ek
<
0.
)
break
;
float
gamma
=
EkWidth
(
ek
);
gammaMax
=
max
(
gammaMax
,
gamma
);
width
+=
gamma
;
if
(
gamma
<
0.01
*
gammaMax
)
break
;
ek
+=
sign
*
de
;
}
return
width
;
}
//****************************************************
/**
* Turns off imf emissions. The default option is
* IMF emsiion on.
*/
void
CNucleus
::
setNoIMF
()
{
noIMF
=
1
;
}
//****************************************************
/**
* Turns on imf emissions. This is the default option.
*/
void
CNucleus
::
setYesIMF
()
{
noIMF
=
0
;
}
//****************************************************
/**
* Calculations use Lestone fission width.
* the default is the BohrWheeler decay width
*/
void
CNucleus
::
setLestone
()
{
BohrWheeler
=
0
;
}
//****************************************************
/**
* Calculations use BohrWheeler fission width
* This is the default. Alternative is setLestone()
*/
void
CNucleus
::
setBohrWheeler
()
{
BohrWheeler
=
1
;
}
//********************************************
/**
* Set one of the parameter sets
\param isol solution number
*/
void
CNucleus
::
setSolution
(
int
isol
)
{
if
(
isol
==
0
)
{
setBohrWheeler
();
setTimeTransient
(
0.
);
CLevelDensity
::
setAfAn
(
1.036
);
CLevelDensity
::
setLittleA
(
7.3
,
.00517
,
.0345
,
12.
);
CTlBarDist
::
setBarWidth
(
1.
);
}
else
if
(
isol
==
1
)
{
setLestone
();
setTimeTransient
(
1.
);
CLevelDensity
::
setAfAn
(
1.057
);
CLevelDensity
::
setLittleA
(
7.3
,
.00517
,
.0345
,
12.
);
CTlBarDist
::
setBarWidth
(
1.
);
}
else
{
cout
<<
"this solution not defined"
<<
endl
;
}
}
//***********************************************
/**
* returns the total energy removed by gamma rays in MeV
*/
float
CNucleus
::
getSumGammaEnergy
()
{
return
sumGammaEnergy
;
}
//*************************************************
/**
* returns the time in zs at which the particle was created after
* the formation of the CN
*/
float
CNucleus
::
getTime
()
{
return
timeSinceStart
;
}
//*****************************************************************
/**
* determined the spin of the residue (for Weisskopf)
\param saddle bool true=saddleToScission decay false=normal evaporation
*/
void
CNucleus
::
getSpin
(
bool
saddle
)
{
if
(
HF
&&
!
saddle
)
{
//choose the residue spin and evaporated particles energy;
float
xran
=
1.5
;
while
(
floor
(
xran
)
>
0.5
)
xran
=
ran
.
Rndm
();
int
i
=
0
;
for
(;;)
{
float
prob
=
lightP
->
storeEvap
[
i
].
gamma
/
lightP
->
width
;
if
(
prob
>
xran
)
break
;
if
(
i
==
lightP
->
iStore
-
1
)
break
;
i
++
;
}
float
Ek
,
Ex
;
int
iTry
=
0
;
for
(;;)
{
Ek
=
lightP
->
storeEvap
[
i
].
energy
+
(
1.
-
2.
*
ran
.
Rndm
())
*
de
/
2.
;
Ex
=
fEx
-
lightP
->
separationEnergy
-
Ek
;
if
(
Ek
>=
0.
&&
Ex
>=
0.
)
break
;
if
(
iTry
==
4
)
{
Ek
=
lightP
->
storeEvap
[
i
].
energy
;
Ex
=
fEx
-
lightP
->
separationEnergy
-
Ek
;
break
;
}
iTry
++
;
}
EvapEx2
=
Ex
;
EvapS2
=
lightP
->
storeEvap
[
i
].
spin
;
if
(
lightP
->
odd
)
EvapS2
+=
0.5
;
EvapEk
=
Ek
;
EvapL
=
lightP
->
storeEvap
[
i
].
L
;
return
;
}
//now for HF == 0
//choose the residue spin and evaporated particles energy;
float
xran
=
ran
.
Rndm
();
int
i
=
0
;
for
(;;)
{
float
prob
=
lightP
->
storeEvap
[
i
].
gamma
/
lightP
->
width
;
if
(
prob
>
xran
)
break
;
if
(
i
==
lightP
->
iStore
-
1
)
break
;
i
++
;
}
float
Ek
,
Ex
;
int
iTry
=
0
;
for
(;;)
{
Ek
=
lightP
->
storeEvap
[
i
].
energy
+
(
1.
-
2.
*
ran
.
Rndm
())
*
de
/
2.
;
Ex
=
fEx
-
lightP
->
separationEnergy
-
Ek
;
if
(
Ek
>=
0.
&&
Ex
>=
0.
)
break
;
if
(
iTry
==
4
)
{
Ek
=
lightP
->
storeEvap
[
i
].
energy
;
Ex
=
fEx
-
lightP
->
separationEnergy
-
Ek
;
break
;
}
iTry
++
;
}
EvapEx2
=
Ex
;
EvapEk
=
Ek
;
if
(
saddle
)
{
EvapS2
=
fJ
-
lightP
->
fJ
;
EvapL
=
0
;
}
else
{
lightP
->
iStore
=
0
;
S2Start
=
roundf
(
lightP
->
fMInertia
/
(
lightP
->
fMInertia
+
lightP
->
fMInertiaOrbit
)
*
fJ
);
if
(
lightP
->
odd
)
S2Start
+=
0.5
;
//prepare transmission coeff
lightP
->
tlArray
->
prepare
(
lightP
->
residue
.
iZ
);
float
width
=
S2Loop
(
Ek
);
//choose the residue spin and evaporated particles energy;
float
xran
=
1.5
;
while
(
floor
(
xran
)
>
0.5
)
xran
=
ran
.
Rndm
();
int
i
=
0
;
for
(;;)
{
float
prob
=
lightP
->
storeEvap
[
i
].
gamma
/
width
;
if
(
prob
>
xran
)
break
;
if
(
i
==
lightP
->
iStore
-
1
)
break
;
i
++
;
}
EvapS2
=
lightP
->
storeEvap
[
i
].
spin
;
if
(
lightP
->
odd
)
EvapS2
+=
0.5
;
EvapL
=
lightP
->
storeEvap
[
i
].
L
;
/*
float sigmaInverse;
if (Isig) sigmaInverse = lightP->sigBarDist->getInverseXsec(Ek,0.);
else sigmaInverse =
lightP->tlArray->getInverseXsec(Ek,0.);
float lmax = sqrt(sigmaInverse);
int lc = (int)((lmax+.5)*sqrt(ran.Rndm()));
float jmin = fabs(fJ - (float)lc);
jmin = jmin - lightP->fJ;
for (;;)
{
if (jmin > 0.) break;
jmin++;
}
float jmax = fJ + (float)lc + lightP->fJ;
for (;;)
{
if (jmax < 90.) break;
jmax--;
}
int NN = (int) (jmax - jmin) + 1;
float prob[NN];
float U = Ex - Edef;
int ii = 0;
for (float jj=jmin;jj<jmax+1.;jj+=1.)
{
prob[ii] = levelDensity.getLogLevelDensitySpherical
(lightP->residue.iA,U,fPairing,fShell,jj,fMInertia2)/(2.*jj+1);
if (ii > 0) prob[ii] += prob[ii-1];
ii++;
}
if (ii > NN)
{
cout << "increase NN" << endl;
abort();
}
float x = ran.Rndm();
int i = 0;
for (;;)
{
if (prob[i]/prob[ii-1] > x) break;
i++;
}
storeChan[iChannel].S2 = jmin + (float) i;
storeChan[iChannel].Ek = Ek;
storeChan[iChannel].L = 0;
*/
/*
//find mean and sigma of angular momentum distribution of residue
float Mreduced = (float)(lightP->iA*lightP->residue.iA)/
(float)(lightP->iA+lightP->residue.iA);
float dist = 1.4*pow((float)lightP->residue.iA,(float)(1./3.)) + 2.;
float fMInertiaOrbit = Mreduced*pow(dist,2);
//float fS2 = (fJ - lightP->fJ)*fMInertia2/(fMInertia2+fMInertiaOrbit);
float fS2 = fJ*fMInertia2/(fMInertia2+fMInertiaOrbit);
float U = Ex - Edef;
levelDensity.getLogLevelDensitySpherical
(lightP->residue.iA,U,fPair2,fShell2,0.,fMInertia2);
float temp = levelDensity.getTemp();
float sigma = 0.1546*sqrt(temp*fMInertiaOrbit*fMInertia2/(
fMInertiaOrbit+fMInertia2));
//now pick the final angular momentum
float value;
for(;;)
{
value = ran.Gaus(fS2,sigma);
if (value >= 0.) break;
}
if (del == 0)storeChan[iChannel].S2 = floor(value+.5);
else storeChan[iChannel].S2 = floor(value)+.5;
if (storeChan[iChannel].S2 < 0.) storeChan[iChannel].S2 = del;
storeChan[iChannel].Ek = Ek;
storeChan[iChannel].L = 0;
*/
}
}
//********************************************
/**
* Sets the mode use for evaporation
* 1 = Hauser-Feshach formalism as in the original GEMINI
* 0 = widths calculated from Weisskopf, then kinetic energy
* of particle also from Weisskopf, but spin and orbital
* angular momentum from Hauser-Feshbach
* 2 = Switches bewteen options 0 and 1 dependeing of the ratio of
* rotational to thermal energy. (default)
*
\param iHF0 =0,1,2
*/
void
CNucleus
::
setEvapMode
(
int
iHF0
/*=2*/
)
{
iHF
=
iHF0
;
}
//
// mod-TU 3/14/2011 Added for convinience
//
TLorentzVector
CNucleus
::
getLorentzVector
()
// in GeV
{
float
*
m
=
getMomentumVector
();
// in MeV
TVector3
p
(
m
[
0
]
/
1000.
,
m
[
1
]
/
1000
,
m
[
2
]
/
1000.
);
// in GeV
double
mass
=
iA
*
0.9315016
;
if
(
iA
==
1
&&
iZ
==
0
)
mass
=
0.93956533
;
// neutron
if
(
iA
==
1
&&
iZ
==
1
)
mass
=
0.93827200
;
// proton
TLorentzVector
vec
(
p
,
sqrt
(
mass
*
mass
+
p
.
Mag2
()));
return
vec
;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sat, Dec 21, 3:27 PM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4000003
Default Alt Text
CNucleus.cpp (124 KB)
Attached To
rSARTRESVN sartresvn
Event Timeline
Log In to Comment