10#ifndef MCGIDI_headerSource_hpp_included
11#define MCGIDI_headerSource_hpp_included 1
16#ifdef MCGIDI_USE_DOUBLES
17 #define crossSectionSumError 1e-8
19 #define crossSectionSumError 1e-6
32template <
typename RNG>
41 URR_protare_info.
m_inURR = protareSingle->
inURR( a_energy );
57template <
typename RNG>
76 double a1, b1, t1, s1, r1, mu, energyOut;
78 a1 = 1.0 / a_energyIn;
79 b1 = 1.0 / ( 1.0 + 2.0 * a_energyIn );
81 if( a_energyIn < 3.0 ) {
84 t1 = 1.0 / ( 1.0 + 8.0 * b1 );
86 if( a_rng( ) <= t1 ) {
88 s1 = 1.0 / ( 1.0 + a_energyIn * r1 );
90 reject = a_rng( ) > 4.0 * s1 * ( 1.0 - s1 ); }
92 s1 = ( 1.0 + 2.0 * a_energyIn * a_rng( ) ) * b1;
93 mu = 1.0 + a1 * ( 1.0 - 1.0 / s1 );
94 reject = a_rng( ) > 0.5 * ( mu * mu + s1 );
97 energyOut = a_energyIn / ( 1 + a_energyIn * ( 1 - mu ) ); }
99 t1 = a_rng( ) * ( 4.0 * a1 + 0.5 * ( 1.0 - b1 * b1 ) - ( 1.0 - 2.0 * ( 1.0 + a_energyIn ) * ( a1 * a1 ) ) * log( b1 ) );
100 if( t1 > 2.0 * a1 ) {
101 if( t1 > 4.0 * a1 ) {
102 if( t1 > 4.0 * a1 + 0.5 * ( 1.0 - b1 * b1 ) ) {
103 energyOut = a_energyIn * pow( b1, a_rng( ) );
104 mu = 1.0 + a1 - 1.0 / energyOut; }
106 energyOut = a_energyIn * sqrt( 1.0 - a_rng( ) * ( 1.0 - b1 * b1 ) );
107 mu = 1.0 + a1 - 1.0 / energyOut;
110 energyOut = a_energyIn * ( 1.0 + a_rng( ) * ( b1 - 1.0 ) );
111 mu = 1.0 + a1 - 1.0 / energyOut; } }
115 energyOut = 1.0 / ( a1 + r1 );
120 *a_energyOut = energyOut;
134template <
typename RNG>
201template <
typename RNG>
203 RNG && a_rng,
double &a_energy_out )
const {
205 double probability = 0.0;
213 a_rng, a_energy_out );
217 a_rng, a_energy_out );
221 a_rng, a_energy_out );
225 a_rng, a_energy_out );
229 a_rng, a_energy_out );
233 a_rng, a_energy_out );
237 a_rng, a_energy_out );
241 a_rng, a_energy_out );
245 a_rng, a_energy_out );
249 a_rng, a_energy_out );
253 a_rng, a_energy_out );
257 a_rng, a_energy_out );
261 a_rng, a_energy_out );
265 a_rng, a_energy_out );
269 return( probability );
297 double x, v_p, p, pp3, pp4, px3, py3, pz3, pz4, pz, p_perp2, E3, E4, gamma, m3cc2 = a_m3cc * a_m3cc, m4cc2 = a_m4cc * a_m4cc;
299 p = sqrt( a_kinetic_com * ( a_kinetic_com + 2. * a_m3cc ) * ( a_kinetic_com + 2. * a_m4cc ) *
300 ( a_kinetic_com + 2. * ( a_m3cc + a_m4cc ) ) ) / ( 2. * ( a_kinetic_com + a_m3cc + a_m4cc ) );
302 py3 = p * sqrt( 1 - a_input.
m_mu * a_input.
m_mu );
303 px3 = py3 * cos( a_input.
m_phi );
304 py3 *= sin( a_input.
m_phi );
305 pz = p * a_input.
m_mu;
308 E3 = sqrt( p * p + m3cc2 );
309 E4 = sqrt( p * p + m4cc2 );
310 gamma = sqrt( 1. / ( 1. - a_beta * a_beta ) );
311 pz3 = gamma * ( pz + a_beta * E3 );
312 pz4 = gamma * ( -pz + a_beta * E4 ); }
319 p_perp2 = px3 * px3 + py3 * py3;
324 pp3 = p_perp2 + pz3 * pz3;
325 x = ( a_m3cc > 0 ) ? pp3 / ( 2 * m3cc2 ) : 1.;
327 a_input.
m_energyOut1 = a_m3cc * x * ( 1 - 0.5 * x * ( 1 - x ) ); }
334 pp4 = p_perp2 + pz4 * pz4;
335 x = ( a_m4cc > 0 ) ? pp4 / ( 2 * m4cc2 ) : 1.;
337 a_input.
m_energyOut2 = a_m4cc * x * ( 1 - 0.5 * x * ( 1 - x ) ); }
365template <
typename RNG>
369 double beta = sqrt( a_X * ( a_X + 2. *
projectileMass( ) ) ) / ( a_X + initialMass );
370 double _x =
targetMass( ) * ( a_X - m_twoBodyThreshold ) / ( finalMass * finalMass );
378 if( upscatterModelB( a_X, a_input, a_rng ) )
return;
383 Kp = finalMass * _x * ( 1 - 0.5 * _x * ( 1 - _x ) ); }
385 Kp = sqrt( finalMass * finalMass + 2 *
targetMass( ) * ( a_X - m_twoBodyThreshold ) ) - finalMass;
387 if( Kp < 0 ) Kp = 0.;
389 a_input.
m_mu = m_angular->sample( a_X, a_rng( ), a_rng );
409template <
typename RNG>
411 double a_energy_in,
double a_mu_lab, RNG && a_rng,
double &a_energy_out )
const {
416 double _x =
targetMass( ) * ( a_energy_in - m_twoBodyThreshold ) / ( finalMass * finalMass );
420 Kp = finalMass * _x * ( 1 - 0.5 * _x * ( 1 - _x ) ); }
422 Kp = sqrt( finalMass * finalMass + 2.0 *
targetMass( ) * ( a_energy_in - m_twoBodyThreshold ) ) - finalMass;
424 if( Kp < 0 ) Kp = 0.;
426 double energy_product_com = 0.5 * Kp * ( Kp + 2.0 * m_residualMass ) / ( Kp +
productMass( ) + m_residualMass );
429 double boostBeta = sqrt( a_energy_in * ( a_energy_in + 2. *
projectileMass( ) ) ) / ( a_energy_in + initialMass );
430 double one_mu_beta = 1.0 - a_mu_lab * boostBeta;
431 double mu_com = ( a_mu_lab - boostBeta ) / one_mu_beta;
432 double Jacobian = ( 1.0 - boostBeta * boostBeta ) / ( one_mu_beta * one_mu_beta );
434 a_energy_out = sqrt( 1.0 - boostBeta * boostBeta ) * energy_product_com * ( 1.0 + mu_com * boostBeta );
436 return( Jacobian * m_angular->evaluate( a_energy_in, mu_com ) );
440 double boostBeta = sqrt( a_energy_in * ( a_energy_in + 2. *
projectileMass( ) ) ) / ( a_energy_in + initialMass );
441 double muPlus = 0.0, JacobianPlus = 0.0, muMinus = 0.0, JacobianMinus = 0.0;
443 int numberOfMus =
muCOM_From_muLab( a_mu_lab, boostBeta, productBeta, muPlus, JacobianPlus, muMinus, JacobianMinus );
445 if( numberOfMus == 0 )
return( 0.0 );
447 double probability = JacobianPlus * m_angular->evaluate( a_energy_in, muPlus );
449 if( numberOfMus == 2 ) {
450 double probabilityMinus = JacobianMinus * m_angular->evaluate( a_energy_in, muMinus );
451 probability += probabilityMinus;
452 if( probabilityMinus > a_rng( ) * probability ) {
457 double productBeta2 = productBeta * productBeta;
458 double productBetaLab2 = productBeta2 + boostBeta * boostBeta * ( 1.0 - productBeta2 * ( 1.0 - muPlus * muPlus ) ) + 2.0 * muPlus * productBeta * boostBeta;
459 productBetaLab2 /= 1.0 - muPlus * productBeta * boostBeta;
462 return( probability );
474template <
typename RNG>
477 const double Two_sqrtPi = 1.1283791670955125739;
478 const double C0 = 1.0410423479,
C1 = 3.9626339162e-4, C2 =-1.8654539193e-3,
C3 = 1.0264818153e-4;
479 double neutronMass = projectileMass( );
480 double _targetMass = targetMass( );
482 double kineticLabMax = 1e4 * temperature;
485 double kineticLabMax200 = 200.0 * temperature;
487 kineticLabMax = 1e3 * temperature * neutronMass / _targetMass;
488 if( kineticLabMax < kineticLabMax200 ) kineticLabMax = kineticLabMax200;
489 if( a_kineticLab >= 0.1 ) kineticLabMax = 0.9 * a_kineticLab; }
491 if( kineticLabMax > 1e-2 ) {
492 kineticLabMax = 1e-2;
493 if( kineticLabMax < 100.0 * temperature ) {
494 kineticLabMax = 100.0 * temperature;
495 if( kineticLabMax > 10.0 ) kineticLabMax = 10.0;
500 if( a_kineticLab > kineticLabMax )
return(
false );
504 double muProjectileTarget, relativeBeta, targetBeta;
509 bool continueLoop =
false;
510 double crossSectionMax = 0.0;
512 double targetThermalSpeed = m_modelDBRC_data->targetThermalSpeed( temperature );
513 crossSectionMax = m_modelDBRC_data->crossSectionMax( a_kineticLab, targetThermalSpeed );
516 continueLoop =
false;
519 int MethodP1orP2 = 0;
520 if( a_rng( ) * ( neutronBeta + Two_sqrtPi * targetThermalBeta ) < neutronBeta ) MethodP1orP2 = 1;
521 muProjectileTarget = 1.0 - 2.0 * a_rng( );
522 if( MethodP1orP2 == 0 ) {
523 targetBeta = targetThermalBeta * sqrt( -log( ( 1.0 - a_rng( ) ) * ( 1.0 - a_rng( ) ) ) ); }
528 x1 = sqrt( -log( ( 1.0 - a_rng( ) ) * ( 1.0 - x1 * x1 ) ) );
529 x1 = x1 / ( ( (
C3 * x1 + C2 ) * x1 +
C1 ) * x1 + C0 );
531 targetBeta = targetThermalBeta * x1;
533 relativeBeta = sqrt( targetBeta * targetBeta + neutronBeta * neutronBeta - 2 * muProjectileTarget * targetBeta * neutronBeta );
534 }
while( relativeBeta < ( targetBeta + neutronBeta ) * a_rng( ) );
536 double relativeNeutronEnergy = 0.5 * productMass( ) * relativeBeta * relativeBeta;
537 if( m_modelDBRC_data->evaluate( relativeNeutronEnergy ) < a_rng( ) * crossSectionMax ) continueLoop =
true;
539 }
while( continueLoop );
541 double m1_12 = neutronMass / ( neutronMass + _targetMass );
542 double m2_12 = _targetMass / ( neutronMass + _targetMass );
544 double cosRelative = 0.0;
545 if( relativeBeta != 0.0 ) cosRelative = ( neutronBeta - muProjectileTarget * targetBeta ) / relativeBeta;
546 if( cosRelative > 1.0 ) {
548 else if( cosRelative < -1.0 ) {
551 double sinRelative = sqrt( 1.0 - cosRelative * cosRelative );
553 a_input.
m_muLab = muProjectileTarget;
557 double betaNeutronOut = m2_12 * relativeBeta;
559 double muCOM = m_angular->sample( kineticEnergyRelative, a_rng( ), a_rng );
560 double phiCOM = 2.0 *
M_PI * a_rng( );
561 double SCcom = sqrt( 1.0 - muCOM * muCOM );
562 double SScom = SCcom * sin( phiCOM );
563 SCcom *= cos( phiCOM );
565 a_input.
m_pz_vz1 = betaNeutronOut * ( muCOM * cosRelative - SCcom * sinRelative );
566 a_input.
m_px_vx1 = betaNeutronOut * ( muCOM * sinRelative + SCcom * cosRelative );
567 a_input.
m_py_vy1 = betaNeutronOut * SScom;
569 double massRatio = -neutronMass / _targetMass;
574 double vCOMz = m1_12 * neutronBeta + m2_12 * muProjectileTarget * targetBeta;
575 double vCOMx = m2_12 * sqrt( 1.0 - muProjectileTarget * muProjectileTarget ) * targetBeta;
584 if( v2 != 0.0 ) a_input.
m_mu = a_input.
m_pz_vz1 / sqrt( v2 );
608 double phi = 2.0 *
M_PI * a_rng( );
609 double sine = sin( phi );
610 double cosine = cos( phi );
629template <
typename RNG>
633 a_input.
m_mu = m_angular->sample( a_X, a_rng( ), a_rng );
634 a_input.
m_energyOut1 = m_energy->sample( a_X, a_rng( ), a_rng );
653template <
typename RNG>
655 double a_energy_in,
double a_mu_lab, RNG && a_rng,
double &a_energy_out )
const {
661 double boostBeta = sqrt( a_energy_in * ( a_energy_in + 2. *
projectileMass( ) ) ) / ( a_energy_in + initialMass );
662 double energy_out_com = m_energy->sample( a_energy_in, a_rng( ), a_rng );
665 double one_mu_beta = 1.0 - a_mu_lab * boostBeta;
666 double mu_com = ( a_mu_lab - boostBeta ) / one_mu_beta;
667 double Jacobian = ( 1.0 - boostBeta * boostBeta ) / ( one_mu_beta * one_mu_beta );
669 a_energy_out = sqrt( 1.0 - boostBeta * boostBeta ) * energy_out_com * ( 1.0 + mu_com * boostBeta );
671 return( Jacobian * m_angular->evaluate( a_energy_in, mu_com ) );
675 double muPlus = 0.0, JacobianPlus = 0.0, muMinus = 0.0, JacobianMinus = 0.0;
676 int numberOfMus =
muCOM_From_muLab( a_mu_lab, boostBeta, productBeta, muPlus, JacobianPlus, muMinus, JacobianMinus );
678 if( numberOfMus == 0 )
return( 0.0 );
680 double probability = JacobianPlus * m_angular->evaluate( a_energy_in, muPlus );
682 if( numberOfMus == 2 ) {
683 double probabilityMinus = JacobianMinus * m_angular->evaluate( a_energy_in, muMinus );
685 probability += probabilityMinus;
686 if( probabilityMinus > a_rng( ) * probability ) muPlus = muMinus;
689 double productBeta2 = productBeta * productBeta;
690 double productBetaLab2 = productBeta2 + boostBeta * boostBeta * ( 1.0 - productBeta2 * ( 1.0 - muPlus * muPlus ) ) + 2.0 * muPlus * productBeta * boostBeta;
691 productBetaLab2 /= 1.0 - muPlus * productBeta * boostBeta;
694 return( probability );
697 a_energy_out = m_energy->sample( a_energy_in, a_rng( ), a_rng );
698 return( m_angular->evaluate( a_energy_in, a_mu_lab ) );
709template <
typename RNG>
728template <
typename RNG>
732 double probability = 0.0;
734 return( probability );
746template <
typename RNG>
749 double energyOut_1, energyOut_2;
752 a_input.
m_energyOut1 = m_energy->sample2dOf3d( a_X, a_rng( ), a_rng, &energyOut_1, &energyOut_2 );
753 a_input.
m_mu = m_angularGivenEnergy->sample( a_X, energyOut_1, energyOut_2, a_rng( ), a_rng );
772template <
typename RNG>
774 double a_energy_in,
double a_mu_lab, RNG && a_rng,
double &a_energy_out )
const {
776 double probability = 0.0;
779 a_energy_out = m_energy->sample( a_energy_in, a_rng( ), a_rng );
782 double boostBeta = sqrt( a_energy_in * ( a_energy_in + 2. *
projectileMass( ) ) ) / ( a_energy_in + initialMass );
783 double energy_out_com = m_energy->sample( a_energy_in, a_rng( ), a_rng );
786 double one_mu_beta = 1.0 - a_mu_lab * boostBeta;
787 double mu_com = ( a_mu_lab - boostBeta ) / one_mu_beta;
788 double Jacobian = ( 1.0 - boostBeta * boostBeta ) / ( one_mu_beta * one_mu_beta );
790 a_energy_out = sqrt( 1.0 - boostBeta * boostBeta ) * energy_out_com * ( 1.0 + mu_com * boostBeta );
792 return( Jacobian * m_angularGivenEnergy->evaluate( a_energy_in, energy_out_com, mu_com ) );
796 double muPlus = 0.0, JacobianPlus = 0.0, muMinus = 0.0, JacobianMinus = 0.0;
797 int numberOfMus =
muCOM_From_muLab( a_mu_lab, boostBeta, productBeta, muPlus, JacobianPlus, muMinus, JacobianMinus );
799 if( numberOfMus == 0 )
return( 0.0 );
801 probability = JacobianPlus * m_angularGivenEnergy->evaluate( a_energy_in, energy_out_com, muPlus );
803 if( numberOfMus == 2 ) {
804 double probabilityMinus = JacobianMinus * m_angularGivenEnergy->evaluate( a_energy_in, energy_out_com, muMinus );
806 probability += probabilityMinus;
807 if( probabilityMinus > a_rng( ) * probability ) muPlus = muMinus;
810 double productBeta2 = productBeta * productBeta;
811 double productBetaLab2 = productBeta2 + boostBeta * boostBeta * ( 1.0 - productBeta2 * ( 1.0 - muPlus * muPlus ) ) + 2.0 * muPlus * productBeta * boostBeta;
812 productBetaLab2 /= 1.0 - muPlus * productBeta * boostBeta;
815 a_energy_out = m_energy->sample( a_energy_in, a_rng( ), a_rng );
816 probability = m_angularGivenEnergy->evaluate( a_energy_in, a_energy_out, a_mu_lab );
819 return( probability );
831template <
typename RNG>
837 a_input.
m_mu = m_angular->sample2dOf3d( a_X, a_rng( ), a_rng, &mu_1, &mu_2 );
838 a_input.
m_energyOut1 = m_energyGivenAngular->sample( a_X, mu_1, mu_2, a_rng( ), a_rng );
857template <
typename RNG>
859 double a_energy_in,
double a_mu_lab, RNG && a_rng,
double &a_energy_out )
const {
863 a_energy_out = m_energyGivenAngular->sample( a_energy_in, a_mu_lab, a_mu_lab, a_rng( ), a_rng );
864 return( m_angular->evaluate( a_energy_in, a_mu_lab ) );
876template <
typename RNG>
880 a_input.
m_energyOut1 = m_f->sample( a_X, a_rng( ), a_rng );
881 double rValue = m_r->evaluate( a_X, a_input.
m_energyOut1 );
882 double aValue = m_a->evaluate( a_X, a_input.
m_energyOut1 );
885 if( a_rng( ) >= rValue ) {
886 double T = ( 2. * a_rng( ) - 1. ) * sinh( aValue );
888 a_input.
m_mu = log( T + sqrt( T * T + 1. ) ) / aValue; }
890 double rng1 = a_rng( ), exp_a = exp( aValue );
892 a_input.
m_mu = log( rng1 * exp_a + ( 1. - rng1 ) / exp_a ) / aValue;
894 if( a_input.
m_mu < -1 ) a_input.
m_mu = -1;
895 if( a_input.
m_mu > 1 ) a_input.
m_mu = 1;
915template <
typename RNG>
917 double a_energy_in,
double a_mu_lab, RNG && a_rng,
double &a_energy_out )
const {
922 double energy_out_com = m_f->sample( a_energy_in, a_rng( ), a_rng );
924 double boostBeta = sqrt( a_energy_in * ( a_energy_in + 2. *
projectileMass( ) ) ) / ( a_energy_in + initialMass );
926 double muPlus = 0.0, JacobianPlus = 0.0, muMinus = 0.0, JacobianMinus = 0.0;
928 int numberOfMus =
muCOM_From_muLab( a_mu_lab, boostBeta, productBeta, muPlus, JacobianPlus, muMinus, JacobianMinus );
930 if( numberOfMus == 0 )
return( 0.0 );
932 double rAtEnergyEnergyPrime = m_r->evaluate( a_energy_in, energy_out_com );
933 double aAtEnergyEnergyPrime = m_a->evaluate( a_energy_in, energy_out_com );
934 double aMu = aAtEnergyEnergyPrime * muPlus;
936 double probability = 0.5 * JacobianPlus;
938 probability *= 1.0 - rAtEnergyEnergyPrime + rAtEnergyEnergyPrime * aAtEnergyEnergyPrime * exp( aMu ) / sinh( aAtEnergyEnergyPrime ); }
940 probability *= aAtEnergyEnergyPrime * ( cosh( aMu ) + rAtEnergyEnergyPrime * cosh( aMu ) ) / sinh( aAtEnergyEnergyPrime );
943 if( numberOfMus == 2 ) {
944 aMu = aAtEnergyEnergyPrime * muMinus;
946 double probabilityMinus = 0.5 * JacobianMinus;
948 probabilityMinus *= 1.0 - rAtEnergyEnergyPrime + rAtEnergyEnergyPrime * aAtEnergyEnergyPrime * exp( aMu ) / sinh( aAtEnergyEnergyPrime ); }
950 probabilityMinus *= aAtEnergyEnergyPrime * ( cosh( aMu ) + rAtEnergyEnergyPrime * cosh( aMu ) ) / sinh( aAtEnergyEnergyPrime );
952 probability += probabilityMinus;
954 if( probabilityMinus > a_rng( ) * probability ) muPlus = muMinus;
957 double productBeta2 = productBeta * productBeta;
958 double productBetaLab2 = productBeta2 + boostBeta * boostBeta * ( 1.0 - productBeta2 * ( 1.0 - muPlus * muPlus ) ) + 2.0 * muPlus * productBeta * boostBeta;
959 productBetaLab2 /= 1.0 - muPlus * productBeta * boostBeta;
962 return( probability );
974template <
typename RNG>
981 if( intLowerIndex < 1 ) {
983 a_input.
m_mu = 1.0 - 2.0 * a_rng( );
984 }
while( ( 1.0 + a_input.
m_mu * a_input.
m_mu ) < 2.0 * a_rng( ) ); }
986 std::size_t lowerIndex =
static_cast<std::size_t
>( intLowerIndex );
987 double _a = m_a[lowerIndex];
988 double X_i = m_energies[lowerIndex];
989 double formFactor_i = m_formFactor[lowerIndex];
990 double formFactor_X_i = formFactor_i * X_i;
991 double Z = a_X / X_i;
992 double realAnomalousFactor = 0.0;
993 double imaginaryAnomalousFactor = 0.0;
995 if( m_anomalousDataPresent ) {
996 realAnomalousFactor = m_realAnomalousFactor->evaluate( a_X );
997 imaginaryAnomalousFactor = m_imaginaryAnomalousFactor->evaluate( a_X );
1000 double anomalousFactorSquared = realAnomalousFactor * realAnomalousFactor + imaginaryAnomalousFactor * imaginaryAnomalousFactor;
1001 double normalization = m_integratedFormFactorSquared[lowerIndex] + formFactor_X_i * formFactor_X_i * Z_a( Z, 2.0 * _a + 2.0 );
1003 anomalousFactorSquared = 0.0;
1004 if( anomalousFactorSquared != 0.0 ) {
1005 double integratedFormFactor_i = m_integratedFormFactor[lowerIndex] + formFactor_X_i * Z_a( Z, _a + 2.0 );
1007 normalization += 2.0 * integratedFormFactor_i * realAnomalousFactor + 0.5 * anomalousFactorSquared * a_X * a_X;
1011 double partialIntegral = a_rng( ) * normalization;
1013 if( anomalousFactorSquared == 0.0 ) {
1014 intLowerIndex =
binarySearchVector( partialIntegral, m_integratedFormFactorSquared );
1015 lowerIndex =
static_cast<std::size_t
>( intLowerIndex );
1017 if( lowerIndex == 0 ) {
1018 X = sqrt( 2.0 * partialIntegral ) / m_formFactor[0]; }
1020 double remainer = partialIntegral - m_integratedFormFactorSquared[lowerIndex];
1021 double epsilon = 2.0 * m_a[lowerIndex] + 2.0;
1023 X_i = m_energies[lowerIndex];
1024 formFactor_i = m_formFactor[lowerIndex];
1025 formFactor_X_i = formFactor_i * X_i;
1027 remainer /= formFactor_X_i * formFactor_X_i;
1028 if( fabs(
epsilon ) < 1e-6 ) {
1029 X = X_i * exp( remainer ); }
1037 double X_E = X / a_X;
1038 a_input.
m_mu = 1.0 - 2.0 * X_E * X_E;
1039 }
while( ( 1.0 + a_input.
m_mu * a_input.
m_mu ) < 2.0 * a_rng( ) );
1060template <
typename RNG>
1062 double a_energy_in,
double a_mu_lab,
LUPI_maybeUnused RNG && a_rng,
double &a_energy_out )
const {
1064 a_energy_out = a_energy_in;
1069 double imaginaryAnomalousFactor = 0.0;
1071 if( m_anomalousDataPresent ) {
1072 formFactor += m_realAnomalousFactor->evaluate( a_energy_in );
1073 imaginaryAnomalousFactor = m_imaginaryAnomalousFactor->evaluate( a_energy_in );
1077 * ( formFactor * formFactor + imaginaryAnomalousFactor * imaginaryAnomalousFactor ) / sigma;
1079 return( probability );
1091template <
typename RNG>
1095 double energyOut, mu, scatteringFactor;
1097 if( a_X >= m_energies.back( ) ) {
1104 }
while( scatteringFactor < a_rng( ) * scatteringFactorMax );
1123template <
typename RNG>
1126 double energyOut, mu, occupationNumber;
1129 double alpha_ratio, occupation_pz, occupationNumberMax;
1130 double quad_a = 0, quad_b = 0, quad_c = 0, pz = 0;
1132 bool energetically_possible =
false;
1134 while( energetically_possible ==
false && ep_it < 1000 ){
1143 }
while( occupationNumber < occupationNumberMax * a_rng( ) );
1147 occupation_pz = occupationNumberMax*a_rng();
1149 if( intLowerIndex == -1 ){
1153 std::size_t lowerIndex =
static_cast<std::size_t
>( intLowerIndex );
1154 pz = m_pz[lowerIndex] + (occupation_pz-m_occupationNumber[lowerIndex])*(m_pz[lowerIndex+1]-m_pz[lowerIndex])/(m_occupationNumber[lowerIndex+1]-m_occupationNumber[lowerIndex]);
1159 quad_a = pz*pz - (1/alpha_ratio)*(1/alpha_ratio);
1160 quad_b = -2*alpha_in*( pz*pz * mu - (1/alpha_ratio));
1161 quad_c = alpha_in*alpha_in*( pz*pz - 1 );
1163 if(quad_b*quad_b - 4*quad_a*quad_c > 0){
1164 energetically_possible =
true;
1169 const double quad_1 = -quad_b/(2*quad_a) + sqrt( quad_b*quad_b - 4*quad_a*quad_c )/( 2*quad_a );
1170 const double quad_2 = -quad_b/(2*quad_a) - sqrt( quad_b*quad_b - 4*quad_a*quad_c )/( 2*quad_a );
1174 if(quad_1 >= quad_2){
1182 if(quad_1 >= quad_2){
1211template <
typename RNG>
1213 double a_energy_in,
double a_mu_lab,
LUPI_maybeUnused RNG && a_rng,
double &a_energy_out )
const {
1220 double one_minus_mu = 1.0 - a_mu_lab;
1222 a_energy_out = a_energy_in / ( 1.0 + k_in * one_minus_mu );
1225 double k_ratio = k_out / k_in;
1227 probability *= k_ratio * k_ratio * ( 1.0 + a_mu_lab * a_mu_lab + k_in * k_out * one_minus_mu * one_minus_mu ) * norm;
1229 return( probability );
1247template <
typename RNG>
1249 double a_energy_in,
double a_mu_lab, RNG && a_rng,
double &a_energy_out )
const {
1256 double one_minus_mu = 1.0 - a_mu_lab;
1259 double quad_a, quad_b, quad_c, alpha_ratio, pz, occupation_pz, occupationNumberMax;
1261 bool energetically_possible =
false;
1263 while( energetically_possible ==
false && ep_it < 1000 ){
1267 occupation_pz = occupationNumberMax*a_rng();
1270 if( intLowerIndex == -1 ){
1274 std::size_t lowerIndex =
static_cast<std::size_t
>( intLowerIndex );
1275 pz = m_pz[lowerIndex] + (occupation_pz-m_occupationNumber[lowerIndex])*(m_pz[lowerIndex+1]-m_pz[lowerIndex])/(m_occupationNumber[lowerIndex+1]-m_occupationNumber[lowerIndex]);
1280 quad_a = pz*pz - (1/alpha_ratio)*(1/alpha_ratio);
1281 quad_b = -2*alpha_in*( pz*pz * a_mu_lab - (1/alpha_ratio));
1282 quad_c = alpha_in*alpha_in*( pz*pz - 1 );
1283 if(quad_b*quad_b - 4*quad_a*quad_c > 0){
1284 energetically_possible =
true;
1289 const double quad_1 = -quad_b/(2*quad_a) + sqrt( quad_b*quad_b - 4*quad_a*quad_c )/( 2*quad_a );
1290 const double quad_2 = -quad_b/(2*quad_a) - sqrt( quad_b*quad_b - 4*quad_a*quad_c )/( 2*quad_a );
1293 double alpha_out = 0;
1295 if(quad_1 >= quad_2){
1303 if(quad_1 >= quad_2){
1310 alpha_ratio = alpha_out / alpha_in;
1313 probability *= alpha_ratio * alpha_ratio * ( 1.0 + a_mu_lab * a_mu_lab + alpha_in * alpha_out * one_minus_mu * one_minus_mu ) * norm;
1315 return( probability );
1327template <
typename RNG>
1330 double halfTheta = 0.5 * acos( a_input.
m_mu );
1332 double psi = atan( 1.0 / cot_psi );
1334 double deltaE_photon = a_energy - a_input.
m_energyOut1;
1338 a_input.
m_mu = cos( psi );
1358template <
typename RNG>
1377template <
typename RNG>
1380 if( m_firstSampled ) {
1381 a_input.
m_mu = 1.0 - 2.0 * a_rng( );
1384 a_input.
m_mu *= -1.0;
1406template <
typename RNG>
1422template <
typename RNG>
1424 RNG && a_rng )
const {
1426 if( a_energy <= m_energies[0] ) {
1427 a_input.
m_mu = 1.0; }
1430 if( temperature < m_temperatures[0] ) temperature = m_temperatures[0];
1431 if( temperature > m_temperatures.back( ) ) temperature = m_temperatures.back( );
1433 double const *pointer1 = &m_S_table[temperatureIndex * m_energies.size( )];
1435 double const *pointer2 = pointer1;
1436 double fractionFirstTemperature = 1.0;
1437 if( temperatureIndex != ( m_temperatures.size( ) - 1 ) ) {
1438 fractionFirstTemperature = ( m_temperatures[temperatureIndex+1] - temperature ) / ( m_temperatures[temperatureIndex+1] - m_temperatures[temperatureIndex] );
1439 pointer2 += m_energies.size( );
1441 double fractionSecondTemperature = 1.0 - fractionFirstTemperature;
1444 std::size_t energyIndexMax =
static_cast<std::size_t
>( intEnergyIndexMax );
1445 if( a_energy == m_energies[energyIndexMax] ) --energyIndexMax;
1447 double randomTotal = a_rng( ) * ( fractionFirstTemperature * pointer1[energyIndexMax] + fractionSecondTemperature * pointer2[energyIndexMax] );
1448 std::size_t energyIndex = 0;
1449 for( ; energyIndex < energyIndexMax; ++energyIndex ) {
1450 if( randomTotal <= fractionFirstTemperature * pointer1[energyIndex] + fractionSecondTemperature * pointer2[energyIndex] )
break;
1452 a_input.
m_mu = 1.0 - 2.0 * m_energies[energyIndex] / a_energy;
1474template <
typename RNG>
1478 double probability = 0.0;
1480 a_energy_out = a_energy_in;
1482 return( probability );
1493template <
typename RNG>
1495 RNG && a_rng )
const {
1497 double temperature = a_input.
temperature( ) / m_temperatureToMeV_K;
1498 double W_prime = m_DebyeWallerIntegral->evaluate( temperature );
1499 double twoEW = 2 * a_energy * W_prime;
1500 double expOfTwice_twoEW = exp( -2 * twoEW );
1501 double sampled_cdf = a_rng( );
1503 if( sampled_cdf > ( 1 - 1e-5 ) ) {
1504 double Variable = ( 1.0 - sampled_cdf ) * ( 1.0 - expOfTwice_twoEW );
1505 a_input.
m_mu = 1.0 - Variable * ( 1.0 + 0.5 * Variable ) / twoEW; }
1506 else if( sampled_cdf < expOfTwice_twoEW ) {
1507 a_input.
m_mu = -1.0 + log( sampled_cdf / expOfTwice_twoEW * ( 1.0 - expOfTwice_twoEW ) + 1.0 ) / twoEW; }
1509 a_input.
m_mu = 1.0 + log( expOfTwice_twoEW + sampled_cdf * ( 1.0 - expOfTwice_twoEW ) ) / twoEW;
1531template <
typename RNG>
1533 double a_energy_in,
double a_mu_lab,
LUPI_maybeUnused RNG && a_rng,
double &a_energy_out )
const {
1535 double temperature = a_temperature / m_temperatureToMeV_K;
1536 double W_prime = m_DebyeWallerIntegral->evaluate( temperature );
1537 double twoEW = 2 * a_energy_in * W_prime;
1538 double probability = exp( -twoEW * ( 1.0 - a_mu_lab ) ) * twoEW / ( 1.0 - exp( -2 * twoEW ) );
1540 a_energy_out = a_energy_in;
1542 return( probability );
1553template <
typename RNG>
1578template <
typename RNG>
1592template <
typename RNG >
1599 int iValue = (int) d_value;
1600 if( iValue == d_value )
return( iValue );
1601 if( d_value - iValue > a_rng( ) ) ++iValue;
1616template <
typename RNG>
1619 const double Terrell_BSHIFT = -0.43287;
1620 double width = M_SQRT2 * m_width;
1621 double temp1 = m_multiplicity->evaluate( a_energy ) + 0.5;
1622 double temp2 = temp1 / width;
1623 double expo = exp( -temp2 * temp2 );
1624 double cshift = temp1 + Terrell_BSHIFT * m_width * expo / ( 1.0 - expo );
1626 double multiplicity = 1.0;
1628 double rw = sqrt( -log( a_rng( ) ) );
1629 double theta = ( 2.0 *
M_PI ) * a_rng();
1631 multiplicity = width * rw * cos( theta ) + cshift;
1632 }
while ( multiplicity < 0.0 );
1634 return(
static_cast<int>( floor( multiplicity ) ) );
1646template <
typename RNG>
1652template <
typename RNG>
1656 double domainValue = 0;
1658 if( intLower < 0 ) {
1659 LUPI_THROW(
"Xs_pdf_cdf1d::sample: intLower < 0." );
1662 std::size_t lower =
static_cast<std::size_t
>( intLower );
1665 double fraction = ( m_cdf[lower+1] - a_rngValue ) / ( m_cdf[lower+1] - m_cdf[lower] );
1666 domainValue = fraction *
m_Xs[lower] + ( 1 - fraction ) *
m_Xs[lower+1]; }
1668 double slope = m_pdf[lower+1] - m_pdf[lower];
1670 if( slope == 0.0 ) {
1671 if( m_pdf[lower] == 0.0 ) {
1672 domainValue =
m_Xs[lower];
1673 if( lower == 0 ) domainValue =
m_Xs[1]; }
1675 double fraction = ( m_cdf[lower+1] - a_rngValue ) / ( m_cdf[lower+1] - m_cdf[lower] );
1676 domainValue = fraction *
m_Xs[lower] + ( 1 - fraction ) *
m_Xs[lower+1];
1681 slope = slope / (
m_Xs[lower+1] -
m_Xs[lower] );
1682 d1 = a_rngValue - m_cdf[lower];
1683 d2 = m_cdf[lower+1] - a_rngValue;
1685 domainValue =
m_Xs[lower] + ( sqrt( m_pdf[lower] * m_pdf[lower] + 2. * slope * d1 ) - m_pdf[lower] ) / slope; }
1687 domainValue =
m_Xs[lower+1] - ( m_pdf[lower+1] - sqrt( m_pdf[lower+1] * m_pdf[lower+1] - 2. * slope * d2 ) ) / slope;
1691 return( domainValue );
1702template <
typename RNG>
1731template <
typename RNG>
1750 value =
static_cast<Regions2d const *
>( this )->
sample( a_x2, a_rngValue, a_rng );
1754 LUPI_THROW(
"ProbabilityBase2d_d1::sample: This should never happen." );
1770template <
typename RNG>
1772 double *a_x1_1,
double *a_x1_2 )
const {
1778 value =
static_cast<XYs2d const *
>( this )->
sample2dOf3d( a_x2, a_rngValue, a_rng, a_x1_1, a_x1_2 );
1781 LUPI_THROW(
"ProbabilityBase2d_d1::sample2dOf3d: not implemented." );
1797template <
typename RNG>
1804 value =
static_cast<XYs2d const *
>( this )->
sample( a_x2, a_rngValue, a_rng );
1807 value =
static_cast<Isotropic2d const *
>( this )->
sample( a_x2, a_rngValue, a_rng );
1816 value =
static_cast<Recoil2d const *
>( this )->
sample( a_x2, a_rngValue, a_rng );
1831 value =
static_cast<Watt2d const *
>( this )->
sample( a_x2, a_rngValue, a_rng );
1836 LUPI_THROW(
"ProbabilityBase2d_d2::sample: This should never happen." );
1852template <
typename RNG>
1854 double *a_x1_1,
double *a_x1_2 )
const {
1860 value =
static_cast<XYs2d const *
>( this )->
sample2dOf3d( a_x2, a_rngValue, a_rng, a_x1_1, a_x1_2 );
1863 LUPI_THROW(
"ProbabilityBase2d_d2::sample2dOf3d: not implemented." );
1869template <
typename RNG>
1876 double sampledValue = 0;
1879 if( intLower == -2 ) {
1880 sampledValue = m_probabilities[0]->sample( a_rngValue, a_rng ); }
1881 else if( intLower == -1 ) {
1882 sampledValue = m_probabilities.back( )->sample( a_rngValue, a_rng ); }
1884 auto lower =
static_cast<std::size_t
>( intLower );
1885 double sampled1 = m_probabilities[lower]->sample( a_rngValue, a_rng );
1888 sampledValue = sampled1; }
1890 double sampled2 = m_probabilities[lower+1]->sample( a_rngValue, a_rng );
1893 double fraction = (
m_Xs[lower+1] - a_x2 ) / (
m_Xs[lower+1] -
m_Xs[lower] );
1894 sampledValue = fraction * sampled1 + ( 1 - fraction ) * sampled2; }
1896 double fraction = (
m_Xs[lower+1] - a_x2 ) / (
m_Xs[lower+1] -
m_Xs[lower] );
1897 sampledValue = sampled2 * pow( sampled2 / sampled1, fraction ); }
1899 double fraction = log(
m_Xs[lower+1] / a_x2 ) / log(
m_Xs[lower+1] /
m_Xs[lower] );
1900 sampledValue = fraction * sampled1 + ( 1 - fraction ) * sampled2; }
1902 double fraction = log(
m_Xs[lower+1] / a_x2 ) / log(
m_Xs[lower+1] /
m_Xs[lower] );
1903 sampledValue = sampled2 * pow( sampled2 / sampled1, fraction ); }
1905 LUPI_THROW(
"XYs2d::sample: unsupported interpolation." );
1909 return( sampledValue );
1922template <
typename RNG>
1924 double *a_x1_1,
double *a_x1_2 )
const {
1929 double sampledValue = 0;
1932 if( intLower == -2 ) {
1933 sampledValue = m_probabilities[0]->sample( a_rngValue, a_rng );
1934 *a_x1_2 = *a_x1_1 = sampledValue; }
1935 else if( intLower == -1 ) {
1936 sampledValue = m_probabilities.back( )->sample( a_rngValue, a_rng );
1937 *a_x1_2 = *a_x1_1 = sampledValue; }
1939 std::size_t lower =
static_cast<std::size_t
>( intLower );
1940 *a_x1_1 = m_probabilities[lower]->sample( a_rngValue, a_rng );
1943 sampledValue = *a_x1_2 = *a_x1_1; }
1945 *a_x1_2 = m_probabilities[lower+1]->sample( a_rngValue, a_rng );
1948 double fraction = (
m_Xs[lower+1] - a_x2 ) / (
m_Xs[lower+1] -
m_Xs[lower] );
1949 sampledValue = fraction * *a_x1_1 + ( 1 - fraction ) * *a_x1_2; }
1951 double fraction = (
m_Xs[lower+1] - a_x2 ) / (
m_Xs[lower+1] -
m_Xs[lower] );
1952 sampledValue = *a_x1_2 * pow( *a_x1_2 / *a_x1_1, fraction ); }
1954 double fraction = log(
m_Xs[lower+1] / a_x2 ) / log(
m_Xs[lower+1] /
m_Xs[lower] );
1955 sampledValue = fraction * *a_x1_1 + ( 1 - fraction ) * *a_x1_2; }
1957 double fraction = log(
m_Xs[lower+1] / a_x2 ) / log(
m_Xs[lower+1] /
m_Xs[lower] );
1958 sampledValue = *a_x1_2 * pow( *a_x1_2 / *a_x1_1 , fraction ); }
1960 LUPI_THROW(
"XYs2d::sample: unsupported interpolation." );
1964 return( sampledValue );
1967template <
typename RNG>
1972 if( intLower < 0 ) {
1973 if( intLower == -1 ) {
1974 return( m_probabilities.back( )->sample( a_x2, a_rngValue, a_rng ) );
1979 std::size_t lower =
static_cast<std::size_t
>( intLower );
1981 return( m_probabilities[lower]->
sample( a_x2, a_rngValue, a_rng ) );
1984template <
typename RNG>
1987#if !defined(__NVCC__) && !defined(__HIP__)
1988 LUPI_THROW(
"Recoil2d::sample: not implemented." );
2002template <
typename RNG>
2005 double energyMax = m_energy_in_COMFactor * a_x2 + m_Q;
2007 if( energyMax < 0.0 )
return( 0.0 );
2009 return( energyMax * m_massFactor * m_dist->sample( a_rngValue, a_rng ) );
2012inline LUPI_HOST_DEVICE static double MCGIDI_sampleEvaporation(
double a_xMax,
double a_rngValue ) {
2014 double b1, c1, xMid, norm, xMin = 0.;
2016 norm = 1 - ( 1 + a_xMax ) * exp( -a_xMax );
2017 b1 = 1. - norm * a_rngValue;
2018 for(
int i1 = 0; i1 < 16; i1++ ) {
2019 xMid = 0.5 * ( xMin + a_xMax );
2020 c1 = ( 1 + xMid ) * exp( -xMid );
2031template <
typename RNG>
2034 double theta = m_theta->evaluate( a_x2 );
2036 return( theta * MCGIDI_sampleEvaporation( ( a_x2 - m_U ) / theta, a_rngValue ) );
2039template <
typename RNG>
2042 return( m_theta->evaluate( a_x2 ) * m_g->sample( a_rngValue, a_rng ) );
2045inline LUPI_HOST_DEVICE static double MCGIDI_sampleSimpleMaxwellianFission(
double a_xMax,
double a_rngValue ) {
2047 double b1, c1, xMid, norm, xMin = 0., sqrt_xMid, sqrt_pi_2 = 0.5 * sqrt(
M_PI );
2049 sqrt_xMid = sqrt( a_xMax );
2050 norm = sqrt_pi_2 * erf( sqrt_xMid ) - sqrt_xMid * exp( -a_xMax );
2051 b1 = norm * a_rngValue;
2052 for(
int i1 = 0; i1 < 16; i1++ ) {
2053 xMid = 0.5 * ( xMin + a_xMax );
2054 sqrt_xMid = sqrt( xMid );
2055 c1 = sqrt_pi_2 * erf( sqrt_xMid ) - sqrt_xMid * exp( -xMid );
2065template <
typename RNG>
2068 double theta = m_theta->evaluate( a_x2 );
2070 return( theta * MCGIDI_sampleSimpleMaxwellianFission( ( a_x2 - m_U ) / theta, a_rngValue ) );
2073template <
typename RNG>
2078 double WattMin = 0., WattMax = a_x2 - m_U, x, y, z, energyOut, rand1, rand2;
2079 double Watt_a = 1./m_a->evaluate( a_x2 );
2080 double Watt_b = m_b->evaluate( a_x2 );
2082 x = 1. + ( Watt_b / ( 8. * Watt_a ) );
2083 y = ( x + sqrt( x * x - 1. ) ) / Watt_a;
2084 z = Watt_a * y - 1.;
2086 rand1 = -log( a_rng( ) );
2087 rand2 = -log( a_rng( ) );
2088 energyOut = y * rand1;
2089 }
while( ( ( rand2 - z * ( rand1 + 1. ) ) * ( rand2 - z * ( rand1 + 1. ) ) > Watt_b * y * rand1 ) ||
2090 ( energyOut < WattMin ) || ( energyOut > WattMax ) );
2091 return( energyOut );
2095template <
typename RNG>
2101 std::size_t n1 = m_weight.size( ) - 1;
2102 double randomWeight = a_rng( ), cumulativeWeight = 0.;
2104 for( i1 = 0; i1 < n1; ++i1 ) {
2105 cumulativeWeight += m_weight[i1]->evaluate( a_x2 );
2106 if( cumulativeWeight >= randomWeight )
break;
2108 return( m_energy[i1]->
sample( a_x2, a_rngValue, a_rng) );
2121template <
typename RNG>
2124 return(
static_cast<XYs3d const *
>(
this )->
sample( a_x3, a_x2_1, a_x2_2, a_rngValue, a_rng ) );
2127template <
typename RNG>
2134 double sampledValue = 0;
2137 if( intLower == -2 ) {
2138 sampledValue = m_probabilities[0]->sample( a_x2_1, a_rngValue, a_rng ); }
2139 else if( intLower == -1 ) {
2140 sampledValue = m_probabilities.back( )->sample( a_x2_1, a_rngValue, a_rng ); }
2142 std::size_t lower =
static_cast<std::size_t
>( intLower );
2143 double sampled1 = m_probabilities[lower]->sample( a_x2_1, a_rngValue, a_rng );
2146 sampledValue = sampled1; }
2148 double sampled2 = m_probabilities[lower+1]->sample( a_x2_2, a_rngValue, a_rng );
2151 double fraction = (
m_Xs[lower+1] - a_x3 ) / (
m_Xs[lower+1] -
m_Xs[lower] );
2152 sampledValue = fraction * sampled1 + ( 1 - fraction ) * sampled2; }
2154 double fraction = (
m_Xs[lower+1] - a_x3 ) / (
m_Xs[lower+1] -
m_Xs[lower] );
2155 sampledValue = sampled2 * pow( sampled2 / sampled1, fraction ); }
2157 double fraction = log(
m_Xs[lower+1] / a_x3 ) / log(
m_Xs[lower+1] /
m_Xs[lower] );
2158 sampledValue = fraction * sampled1 + ( 1 - fraction ) * sampled2; }
2160 double fraction = log(
m_Xs[lower+1] / a_x3 ) / log(
m_Xs[lower+1] /
m_Xs[lower] );
2161 sampledValue = sampled2 * pow( sampled2 / sampled1, fraction ); }
2163 LUPI_THROW(
"XYs3d::sample: unsupported interpolation." );
2168 return( sampledValue );
2186template <
typename RNG>
2188 int a_URR_index, std::size_t a_hashIndex,
double a_temperature,
double a_energy,
double a_crossSection, RNG && a_rng )
const {
2190 std::size_t sampled_reaction_index, temperatureIndex1, temperatureIndex2, number_of_temperatures = m_temperatures.size( );
2191 double sampleCrossSection = a_crossSection * a_rng( );
2193 if( a_temperature <= m_temperatures[0] ) {
2194 temperatureIndex1 = 0;
2195 temperatureIndex2 = temperatureIndex1; }
2196 else if( a_temperature >= m_temperatures.back( ) ) {
2197 temperatureIndex1 = m_temperatures.size( ) - 1;
2198 temperatureIndex2 = temperatureIndex1; }
2201 for( ; i1 < number_of_temperatures; ++i1 )
if( a_temperature < m_temperatures[i1] )
break;
2202 temperatureIndex1 = i1 - 1;
2203 temperatureIndex2 = i1;
2206 std::size_t numberOfReactions = m_heatedCrossSections[0]->numberOfReactions( );
2207 double energyFraction1, energyFraction2, crossSectionSum = 0.0;
2210 std::size_t energyIndex1 = heatedCrossSection1.
evaluationInfo( a_hashIndex, a_energy, &energyFraction1 );
2212 if( temperatureIndex1 == temperatureIndex2 ) {
2213 for( sampled_reaction_index = 0; sampled_reaction_index < numberOfReactions; ++sampled_reaction_index ) {
2214 crossSectionSum += heatedCrossSection1.
reactionCrossSection2( sampled_reaction_index, a_URR_protareInfos, a_URR_index, a_energy,
2215 energyIndex1, energyFraction1 );
2216 if( crossSectionSum >= sampleCrossSection )
break;
2219 double temperatureFraction2 = ( a_temperature - m_temperatures[temperatureIndex1] )
2220 / ( m_temperatures[temperatureIndex2] - m_temperatures[temperatureIndex1] );
2221 double temperatureFraction1 = 1.0 - temperatureFraction2;
2223 std::size_t energyIndex2 = heatedCrossSection2.
evaluationInfo( a_hashIndex, a_energy, &energyFraction2 );
2225 for( sampled_reaction_index = 0; sampled_reaction_index < numberOfReactions; ++sampled_reaction_index ) {
2226 if( m_thresholds[sampled_reaction_index] >= a_energy )
continue;
2227 crossSectionSum += temperatureFraction1 * heatedCrossSection1.
reactionCrossSection2( sampled_reaction_index, a_URR_protareInfos,
2228 a_URR_index, a_energy, energyIndex1, energyFraction1 );
2229 crossSectionSum += temperatureFraction2 * heatedCrossSection2.
reactionCrossSection2( sampled_reaction_index, a_URR_protareInfos,
2230 a_URR_index, a_energy, energyIndex2, energyFraction2 );
2231 if( crossSectionSum >= sampleCrossSection )
break;
2235 if( sampled_reaction_index == numberOfReactions ) {
2238 MCGIDI_PRINTF(
"HeatedCrossSectionsContinuousEnergy::sampleReaction: crossSectionSum %.17e less than a_crossSection = %.17e.",
2239 crossSectionSum, a_crossSection );
2241 std::string errorString =
"HeatedCrossSectionsContinuousEnergy::sampleReaction: crossSectionSum "
2247 for( sampled_reaction_index = 0; sampled_reaction_index < numberOfReactions; ++sampled_reaction_index ) {
2248 if( heatedCrossSection1.
reactionCrossSection2( sampled_reaction_index, a_URR_protareInfos, a_URR_index, a_energy, energyIndex1,
2249 energyFraction1,
true ) > 0 )
break;
2253 return( sampled_reaction_index );
2266template <
typename RNG>
2268 RNG && a_rng )
const {
2270 std::size_t i1, sampled_reaction_index, temperatureIndex1, temperatureIndex2, numberOfTemperatures = m_temperatures.size( );
2271 double sampleCrossSection = a_crossSection * a_rng( );
2273 if( a_temperature <= m_temperatures[0] ) {
2274 temperatureIndex1 = 0;
2275 temperatureIndex2 = temperatureIndex1; }
2276 else if( a_temperature >= m_temperatures.back( ) ) {
2277 temperatureIndex1 = m_temperatures.size( ) - 1;
2278 temperatureIndex2 = temperatureIndex1; }
2280 for( i1 = 0; i1 < numberOfTemperatures; ++i1 )
if( a_temperature < m_temperatures[i1] )
break;
2281 temperatureIndex1 = i1 - 1;
2282 temperatureIndex2 = i1;
2285 std::size_t numberOfReactions = m_heatedCrossSections[0]->numberOfReactions( );
2286 double crossSectionSum = 0;
2289 if( temperatureIndex1 == temperatureIndex2 ) {
2290 for( sampled_reaction_index = 0; sampled_reaction_index < numberOfReactions; ++sampled_reaction_index ) {
2291 crossSectionSum += heatedCrossSection1.
reactionCrossSection( sampled_reaction_index, a_hashIndex,
true );
2292 if( crossSectionSum >= sampleCrossSection )
break;
2295 double temperatureFraction2 = ( a_temperature - m_temperatures[temperatureIndex1] ) / ( m_temperatures[temperatureIndex2] - m_temperatures[temperatureIndex1] );
2296 double temperatureFraction1 = 1.0 - temperatureFraction2;
2299 for( sampled_reaction_index = 0; sampled_reaction_index < numberOfReactions; ++sampled_reaction_index ) {
2300 if( m_thresholds[sampled_reaction_index] >= a_energy )
continue;
2301 crossSectionSum += temperatureFraction1 * heatedCrossSection1.
reactionCrossSection( sampled_reaction_index, a_hashIndex,
true );
2302 crossSectionSum += temperatureFraction2 * heatedCrossSection2.
reactionCrossSection( sampled_reaction_index, a_hashIndex,
true );
2303 if( crossSectionSum >= sampleCrossSection )
break;
2309 if( m_multiGroupThresholdIndex[sampled_reaction_index] ==
static_cast<int>( a_hashIndex ) ) {
2310 double energyAboveThreshold = a_energy - m_thresholds[sampled_reaction_index];
2312 if( energyAboveThreshold <= ( a_rng( ) * ( m_projectileMultiGroupBoundariesCollapsed[a_hashIndex+1] - m_thresholds[sampled_reaction_index] ) ) )
2316 return( sampled_reaction_index );
2332template <
typename RNG>
2335 double _g = 2.0 / ( 1.37 * 0.5 * 1.772453850905516 );
2340 beta = sqrt( -2.0 * log( r1 ) );
2341 }
while( _g * r1 * beta < a_rng( ) );
2357template <
typename RNG>
2363 if( C_rel > 1.0 ) C_rel = 1.0;
2364 if( C_rel < -1.0 ) C_rel = -1.0;
2366 double S_rel = sqrt( 1.0 - C_rel * C_rel );
2368 double pz_vz = a_product.
m_pz_vz;
2376 double phi = 2.0 *
M_PI * a_rng( );
2377 double sine = sin( phi );
2378 double cosine = cos( phi );
2379 double px_vx = a_product.
m_px_vx;
2405template <
typename RNG,
typename PUSHBACK>
2409 if( m_hasFinalStatePhotons ) {
2410 double random = a_rng( );
2411 double cumulative = 0.0;
2412 bool sampled =
false;
2413 for(
auto productIter = m_products.begin( ); productIter != m_products.end( ); ++productIter ) {
2414 cumulative += (*productIter)->multiplicity( )->evaluate( a_projectileEnergy );
2415 if( cumulative >= random ) {
2416 (*productIter)->sampleFinalState( a_protare, a_projectileEnergy, a_input, a_rng, a_push_back, a_products );
2425 (*iter)->sampleProducts( a_protare, a_projectileEnergy, a_input, a_rng, a_push_back, a_products );
2428 if( m_totalDelayedNeutronMultiplicity !=
nullptr ) {
2429 double totalDelayedNeutronMultiplicity = m_totalDelayedNeutronMultiplicity->evaluate( a_projectileEnergy );
2431 if( a_rng( ) < totalDelayedNeutronMultiplicity ) {
2434 totalDelayedNeutronMultiplicity *= a_rng( );
2435 for( std::size_t i1 = 0; i1 < (std::size_t) m_delayedNeutrons.size( ); ++i1 ) {
2439 sum += product.multiplicity( )->evaluate( a_projectileEnergy );
2440 if( sum >= totalDelayedNeutronMultiplicity ) {
2441 product.distribution( )->sample( a_projectileEnergy, a_input, a_rng );
2444 a_products.
add( a_projectileEnergy, product.intid( ), product.index( ), product.userParticleIndex( ), product.mass( ),
2445 a_input, a_rng, a_push_back,
false );
2468template <
typename RNG>
2470 double &a_weight,
double &a_energy_out, RNG && a_rng,
double &a_cumulative_weight )
const {
2473 (*iter)->angleBiasing( a_reaction, a_index, a_temperature, a_energy_in, a_mu_lab, a_weight, a_energy_out, a_rng, a_cumulative_weight );
2475 if( ( m_totalDelayedNeutronMultiplicity !=
nullptr ) && ( a_index == m_neutronIndex ) ) {
2476 for( std::size_t i1 = 0; i1 < (std::size_t) m_delayedNeutrons.size( ); ++i1 ) {
2480 product.angleBiasing( a_reaction, a_index, a_temperature, a_energy_in, a_mu_lab, a_weight, a_energy_out, a_rng, a_cumulative_weight );
2500template <
typename RNG>
2502 double &a_weight,
double &a_energy_out, RNG && a_rng,
double &a_cumulative_weight )
const {
2505 (*iter)->angleBiasingViaIntid( a_reaction, a_intid, a_temperature, a_energy_in, a_mu_lab, a_weight, a_energy_out, a_rng, a_cumulative_weight );
2508 for( std::size_t i1 = 0; i1 < (std::size_t) m_delayedNeutrons.size( ); ++i1 ) {
2512 product.angleBiasingViaIntid( a_reaction, a_intid, a_temperature, a_energy_in, a_mu_lab, a_weight, a_energy_out, a_rng, a_cumulative_weight );
2530template <
typename RNG,
typename PUSHBACK>
2534#ifdef MCGIDI_USE_OUTPUT_CHANNEL
2535 if( m_outputChannel !=
nullptr ) {
2536 m_outputChannel->sampleProducts( a_protare, a_projectileEnergy, a_input, a_rng, a_push_back, a_products ); }
2542 int _multiplicity = m_multiplicity->sampleBoundingInteger( a_projectileEnergy, a_rng );
2543 int __multiplicity = _multiplicity;
2545 for( ; _multiplicity > 0; --_multiplicity ) {
2546 m_distribution->sample( a_projectileEnergy, a_input, a_rng );
2551 if( m_initialStateIndex >= 0 ) {
2552 if( __multiplicity == 0 ) {
2553 a_protare->
sampleBranchingGammas( a_input, a_projectileEnergy, m_initialStateIndex, a_rng, a_push_back, a_products );
2557#ifdef MCGIDI_USE_OUTPUT_CHANNEL
2573template <
typename RNG,
typename PUSHBACK>
2577 m_distribution->sample( a_projectileEnergy, a_input, a_rng );
2580 a_products.
add( a_projectileEnergy, m_intid, m_index, m_userParticleIndex,
mass( ), a_input, a_rng, a_push_back, m_intid ==
PoPI::Intids::photon );
2582 if( m_initialStateIndex >= 0 ) {
2583 a_protare->
sampleBranchingGammas( a_input, a_projectileEnergy, m_initialStateIndex, a_rng, a_push_back, a_products );
2601template <
typename RNG>
2603 double &a_weight,
double &a_energy_out, RNG && a_rng,
double &a_cumulative_weight )
const {
2605#ifdef MCGIDI_USE_OUTPUT_CHANNEL
2606 if( m_outputChannel !=
nullptr ) {
2607 m_outputChannel->angleBiasing( a_reaction, a_index, a_temperature, a_energy_in, a_mu_lab, a_weight, a_energy_out, a_rng, a_cumulative_weight ); }
2610 if( m_index != a_index )
return;
2612 double probability = 0.0;
2613 double energy_out = 0.0;
2615 if( a_cumulative_weight == 0.0 ) a_energy_out = 0.0;
2620 probability = m_distribution->angleBiasing( a_reaction, a_temperature, a_energy_in, a_mu_lab, a_rng, energy_out );
2623 double weight = m_multiplicity->evaluate( a_energy_in ) * probability;
2624 a_cumulative_weight += weight;
2625 if( weight > a_rng( ) * a_cumulative_weight ) {
2627 a_energy_out = energy_out;
2629#ifdef MCGIDI_USE_OUTPUT_CHANNEL
2649template <
typename RNG>
2651 double &a_weight,
double &a_energy_out, RNG && a_rng ,
double &a_cumulative_weight )
const {
2653#ifdef MCGIDI_USE_OUTPUT_CHANNEL
2654 if( m_outputChannel !=
nullptr ) {
2655 m_outputChannel->angleBiasingViaIntid( a_reaction, a_intid, a_temperature, a_energy_in, a_mu_lab, a_weight, a_energy_out, a_rng, a_cumulative_weight ); }
2658 if( m_intid != a_intid )
return;
2660 angleBiasing( a_reaction, m_index, a_temperature, a_energy_in, a_mu_lab, a_weight, a_energy_out, a_rng, a_cumulative_weight );
2662#ifdef MCGIDI_USE_OUTPUT_CHANNEL
2684template <
typename RNG>
2686 std::size_t a_hashIndex,
double a_crossSection, RNG && a_rng )
const {
2693 a_crossSection, a_rng );
2697 a_crossSection, a_rng );
2701 a_crossSection, a_rng );
2705 return( reactionIndex );
2717template <
typename RNG,
typename PUSHBACK>
2721 int initialStateIndex = a_initialStateIndex;
2722 double energyLevelSampleWidthUpper = 0.0;
2725 if( initialStateIndex >= 0 ) nuclideGammaBranchStateInfo = m_nuclideGammaBranchStateInfos[
static_cast<std::size_t
>(initialStateIndex)];
2726 while( initialStateIndex >= 0 ) {
2727 auto const &branchIndices = nuclideGammaBranchStateInfo->
branchIndices( );
2729 double random = a_rng( );
2731 initialStateIndex = -1;
2732 for( std::size_t i1 = 0; i1 < branchIndices.size( ); ++i1 ) {
2736 if( sum >= random ) {
2737 double energyLevelSampleWidthLower = 0.0;
2739 if( initialStateIndex >= 0 ) {
2740 nuclideGammaBranchStateInfo = m_nuclideGammaBranchStateInfos[
static_cast<std::size_t
>(initialStateIndex)];
2745 a_input.m_dataInTargetFrame =
false;
2748 a_input.
m_energyOut1 = nuclideGammaBranchInfo->
gammaEnergy( ) + energyLevelSampleWidthUpper - energyLevelSampleWidthLower;
2749 a_input.
m_mu = 1.0 - 2.0 * a_rng( );
2754 energyLevelSampleWidthUpper = energyLevelSampleWidthLower;
2771template <
typename RNG>
2782 if( targetThermalBeta < 1e-4 * projectileBeta )
return(
false );
2784 a_input.m_modelTemperature = 0.0;
2786 double relativeBetaMin = projectileBeta - 2.0 * targetThermalBeta;
2787 double relativeBetaMax = projectileBeta + 2.0 * targetThermalBeta;
2789 std::size_t maxIndex = m_upscatterModelAGroupVelocities.size( ) - 2;
2790 int intRelativeBetaMinIndex =
binarySearchVector( relativeBetaMin, m_upscatterModelAGroupVelocities,
true );
2791 std::size_t relativeBetaMinIndex =
static_cast<std::size_t
>( intRelativeBetaMinIndex );
2792 int intRelativeBetaMaxIndex =
binarySearchVector( relativeBetaMax, m_upscatterModelAGroupVelocities,
true );
2793 std::size_t relativeBetaMaxIndex =
static_cast<std::size_t
>( intRelativeBetaMaxIndex );
2794 double targetBeta, relativeBeta, mu;
2796 if( relativeBetaMinIndex >= maxIndex ) relativeBetaMinIndex = maxIndex;
2797 if( relativeBetaMaxIndex >= maxIndex ) relativeBetaMaxIndex = maxIndex;
2799 if( relativeBetaMinIndex == relativeBetaMaxIndex ) {
2801 mu = 1.0 - 2.0 * a_rng( );
2802 relativeBeta = sqrt( targetBeta * targetBeta + projectileBeta * projectileBeta - 2.0 * mu * targetBeta * projectileBeta ); }
2805 double reactionRate;
2806 double reactionRateMax = 0;
2807 for( std::size_t i1 = relativeBetaMinIndex; i1 <= relativeBetaMaxIndex; ++i1 ) {
2808 reactionRate = m_upscatterModelACrossSection[i1] * m_upscatterModelAGroupVelocities[i1+1];
2809 if( reactionRate > reactionRateMax ) reactionRateMax = reactionRate;
2814 mu = 1.0 - 2.0 * a_rng( );
2815 relativeBeta = sqrt( targetBeta * targetBeta + projectileBeta * projectileBeta - 2.0 * mu * targetBeta * projectileBeta );
2817 std::size_t index =
static_cast<std::size_t
>(
binarySearchVector( relativeBeta, m_upscatterModelAGroupVelocities,
true ) );
2818 if( index > maxIndex ) index = maxIndex;
2819 reactionRate = m_upscatterModelACrossSection[index] * relativeBeta;
2820 }
while( reactionRate < a_rng( ) * reactionRateMax );
2842template <
typename RNG>
2844 std::size_t a_hashIndex,
double a_crossSection, RNG && a_rng )
const {
2846 std::size_t hashIndex = a_hashIndex;
2847 double crossSection1 = a_crossSection;
2849 a_input.m_dataInTargetFrame =
false;
2850 a_input.m_modelTemperature = a_input.m_temperature;
2851 a_input.m_modelEnergy = a_input.m_energy;
2855 if( a_input.m_dataInTargetFrame ) {
2856 if( m_continuousEnergy ) {
2857 hashIndex = m_domainHash.index( a_input.m_modelEnergy ); }
2859 hashIndex = m_multiGroupHash.index( a_input.m_modelEnergy );
2861 crossSection1 =
crossSection( a_URR_protareInfos, hashIndex, a_input.m_modelTemperature, a_input.m_modelEnergy,
true );
2865 if( m_continuousEnergy )
return( m_heatedCrossSections.sampleReaction( a_URR_protareInfos, m_URR_index, hashIndex,
2866 a_input.m_modelTemperature, a_input.m_modelEnergy, crossSection1, a_rng ) );
2868 return( m_heatedMultigroupCrossSections.sampleReaction( hashIndex, a_input.m_modelTemperature, a_input.m_modelEnergy,
2869 crossSection1, a_rng ) );
2887template <
typename RNG>
2889 std::size_t a_hashIndex,
double a_crossSection, RNG && a_rng )
const {
2891 std::size_t length =
static_cast<std::size_t
>( m_protares.size( ) );
2892 std::size_t reaction_index = 0;
2893 double cross_section_sum = 0.0;
2894 double cross_section_rng = a_rng( ) * a_crossSection;
2896 for( std::size_t i1 = 0; i1 < length; ++i1 ) {
2897 double cross_section = m_protares[i1]->crossSection( a_URR_protareInfos, a_hashIndex, a_input.
temperature( ), a_input.
energy( ),
true );
2899 cross_section_sum += cross_section;
2900 if( cross_section_sum > cross_section_rng ) {
2901 std::size_t reaction_index2 = m_protares[i1]->sampleReaction( a_input, a_URR_protareInfos, a_hashIndex, cross_section, a_rng );
2903 reaction_index += reaction_index2;
2907 reaction_index += m_protares[i1]->numberOfReactions( );
2910 return( reaction_index );
2928template <
typename RNG>
2930 std::size_t a_hashIndex,
double a_crossSection, RNG && a_rng )
const {
2932 std::size_t reactionIndex = 0;
2934 if( ( a_input.
energy( ) < m_TNSL_maximumEnergy ) && ( a_input.
temperature( ) <= m_TNSL_maximumTemperature ) ) {
2935 double TNSL_crossSection = m_TNSL->crossSection( a_URR_protareInfos, a_hashIndex, a_input.
temperature( ), a_input.
energy( ),
true );
2937 if( TNSL_crossSection > a_rng( ) * a_crossSection ) {
2938 reactionIndex = m_TNSL->sampleReaction( a_input, a_URR_protareInfos, a_hashIndex, TNSL_crossSection, a_rng ); }
2940 reactionIndex = m_protareWithoutElastic->sampleReaction( a_input, a_URR_protareInfos, a_hashIndex,
2941 a_crossSection - TNSL_crossSection, a_rng );
2945 reactionIndex = m_protareWithElastic->sampleReaction( a_input, a_URR_protareInfos, a_hashIndex, a_crossSection, a_rng );
2949 return( reactionIndex );
2965template <
typename RNG,
typename PUSHBACK>
2977 if( m_GRIN_specialSampleProducts ) {
2978 if( m_GRIN_capture !=
nullptr ) {
2979 if( projectileEnergy < m_GRIN_maximumCaptureIncidentEnergy ) {
2980 if( m_GRIN_capture->sampleProducts( (
ProtareSingle const *) a_protare, projectileEnergy, a_input, a_rng, a_push_back, a_products ) ) {
2984 else if( m_GRIN_inelastic !=
nullptr ) {
2985 if( m_GRIN_inelastic->sampleProducts( (
ProtareSingle const *) a_protare, projectileEnergy, a_input, a_rng, a_push_back, a_products ) ) {
2991#ifdef MCGIDI_USE_OUTPUT_CHANNEL
2992 m_outputChannel->sampleProducts( m_protareSingle, projectileEnergy, a_input, a_rng, a_push_back, a_products );
2994 if( m_hasFinalStatePhotons ) {
2995 double random = a_rng( );
2996 double cumulative = 0.0;
2997 bool sampled =
false;
2998 for(
auto productIter = m_products.begin( ); productIter != m_products.end( ); ++productIter ) {
2999 cumulative += (*productIter)->multiplicity( )->evaluate( projectileEnergy );
3000 if( cumulative >= random ) {
3001 (*productIter)->sampleFinalState( m_protareSingle, projectileEnergy, a_input, a_rng, a_push_back, a_products );
3009 for(
auto productIter = m_products.begin( ); productIter != m_products.end( ); ++productIter ) {
3010 (*productIter)->sampleProducts( m_protareSingle, projectileEnergy, a_input, a_rng, a_push_back, a_products );
3014 if( m_totalDelayedNeutronMultiplicity !=
nullptr ) {
3015 double totalDelayedNeutronMultiplicity = m_totalDelayedNeutronMultiplicity->evaluate( projectileEnergy );
3017 if( a_rng( ) < totalDelayedNeutronMultiplicity ) {
3020 totalDelayedNeutronMultiplicity *= a_rng( );
3021 for( std::size_t i1 = 0; i1 < (std::size_t) m_delayedNeutrons.size( ); ++i1 ) {
3025 sum +=
product.multiplicity( )->evaluate( projectileEnergy );
3026 if( sum >= totalDelayedNeutronMultiplicity ) {
3027 product.distribution( )->sample( projectileEnergy, a_input, a_rng );
3037 if( m_fissionResiduaIntid != -1 ) {
3042 a_input.
m_phi = 0.0;
3045 a_products.
add( 0.0, m_fissionResiduaIntid, m_fissionResiduaIndex, m_fissionResiduaUserIndex, m_fissionResidualMass, a_input, a_rng, a_push_back,
false );
3046 a_products.
add( 0.0, m_fissionResiduaIntid, m_fissionResiduaIndex, m_fissionResiduaUserIndex, m_fissionResidualMass, a_input, a_rng, a_push_back,
false );
3051 if( a_checkOrphanProducts ) {
3052 for(
auto productIter = m_associatedOrphanProducts.begin( ); productIter != m_associatedOrphanProducts.end( ); ++productIter ) {
3053 (*productIter)->sampleProducts( m_protareSingle, projectileEnergy, a_input, a_rng, a_push_back, a_products );
3068template <
typename RNG,
typename PUSHBACK>
3072 std::size_t index = 0;
3073 double random = a_rng( );
3074 for( ; index < m_summedProbabilities.size( ) - 1; ++index ) {
3075 if( random < m_summedProbabilities[index] )
break;
3079 double availableEnergy = m_captureNeutronSeparationEnergy + a_projectileEnergy;
3080 int primaryCaptureLevelIndex = GRIN_captureLevelProbability1->
sampleCaptureLevel( a_protare, availableEnergy, a_rng );
3086 a_input.m_dataInTargetFrame =
false;
3090 a_input.
m_mu = 2 * a_rng( ) - 1.0;
3094 0.0, a_input, a_rng, a_push_back,
true );
3096 a_protare->
sampleBranchingGammas( a_input, a_projectileEnergy, primaryCaptureLevelIndex, a_rng, a_push_back, a_products );
3098 if( m_residualIntid != -1 ) {
3101 a_input.
m_phi = 0.0;
3102 a_products.
add( a_projectileEnergy, m_residualIntid, m_residualIndex, m_residualUserIndex, m_residualMass, a_input, a_rng, a_push_back,
false );
3118template <
typename RNG,
typename PUSHBACK>
3122 std::size_t index = 1;
3123 for( ; index < m_energies.size( ); ++index ) {
3124 if( m_energies[index] > a_projectileEnergy )
break;
3129 int levelIndex = inelasticForEnergy->
sampleLevelIndex( a_projectileEnergy, a_rng( ) );
3130 if( levelIndex < 0 )
return(
false );
3136 double residualMass = m_targetMass + nuclideGammaBranchStateInfo->
nuclearLevelEnergy( );
3137 double initialMass = m_neutronMass + m_targetMass;
3138 double finalMass = m_neutronMass + residualMass;
3139 double twoBodyThreshold = 0.5 * ( finalMass * finalMass - initialMass * initialMass ) / m_targetMass;
3140 double betaBoast = sqrt( a_projectileEnergy * ( a_projectileEnergy + 2. * m_neutronMass ) )
3141 / ( a_projectileEnergy + m_neutronMass + m_targetMass );
3142 double _x = m_targetMass * ( a_projectileEnergy - twoBodyThreshold ) / ( finalMass * finalMass );
3143 if( _x < 0 ) _x = 0.;
3146 Kp = finalMass * _x * ( 1 - 0.5 * _x * ( 1 - _x ) ); }
3148 Kp = sqrt( finalMass * finalMass + 2 * m_targetMass * ( a_projectileEnergy - twoBodyThreshold ) ) - finalMass;
3150 if( Kp < 0 ) Kp = 0.;
3153 a_input.
m_mu = 1.0 - 2.0 * a_rng( );
3159 a_products.
add( a_projectileEnergy,
PoPI::Intids::neutron, m_neutronIndex, m_neutronUserParticleIndex, m_neutronMass, a_input, a_rng,
3160 a_push_back,
false );
3161 a_products.
add( a_projectileEnergy, m_targetIntid, m_targetIndex, m_targetUserParticleIndex,
3162 m_targetMass, a_input, a_rng, a_push_back,
false );
3164 a_protare->
sampleBranchingGammas( a_input, a_projectileEnergy, levelIndex, a_rng, a_push_back, a_products );
3179template <
typename RNG>
3181 RNG && a_rng,
bool a_checkEnergy )
const {
3183 if( a_checkEnergy ) {
3188 double random = a_rng( );
3189 std::size_t
index = 0;
3190 for( ;
index < m_continuumIndices.m_levels.size( ) - 1; ++
index ) {
3191 if( m_continuumIndices.m_summedProbabilities[
index] >= random )
break;
3193 return( m_continuumIndices.m_levels[
index] );
3207template <
typename RNG>
3210 double random = a_rng( );
3211 for( std::size_t index = 0; index < m_knownLevelsAndProbabilities.m_levels.size( ); ++index ) {
3212 if( m_knownLevelsAndProbabilities.m_summedProbabilities[index] >= random ) {
3213 return( m_knownLevelsAndProbabilities.m_levels[index] );
3217 for( std::size_t i1 = 0; i1 < m_captureToCompounds.size( ) - 1; ++i1 ) {
3220 int index = GRIN_captureToCompound1->
sampleCaptureLevel( a_protare, a_energy, a_rng,
true );
3221 if( index > -1 )
return( index );
3224 return( m_captureToCompounds.back( )->sampleCaptureLevel( a_protare, a_energy, a_rng,
false ) );
3239template <
typename RNG,
typename PUSHBACK>
3245 a_input.m_dataInTargetFrame =
false;
3252 a_input.
m_phi = 0.0;
3273template <
typename RNG>
3275 RNG && a_rng,
double *a_cumulative_weight,
bool a_checkOrphanProducts )
const {
3277 double cumulative_weight1 = 0.0;
3278 if( a_cumulative_weight ==
nullptr ) a_cumulative_weight = &cumulative_weight1;
3279 double weight1 = 0.0;
3281#ifdef MCGIDI_USE_OUTPUT_CHANNEL
3282 m_outputChannel->angleBiasing(
this, a_index, a_temperature, a_energy_in, a_mu_lab, weight1, a_energy_out, a_rng, *a_cumulative_weight );
3285 for(
auto productIter = m_products.begin( ); productIter != m_products.end( ); ++productIter ) {
3286 (*productIter)->angleBiasing(
this, a_index, a_temperature, a_energy_in, a_mu_lab, weight1, a_energy_out, a_rng, *a_cumulative_weight );
3289 if( ( m_totalDelayedNeutronMultiplicity !=
nullptr ) && ( a_index == m_neutronIndex ) ) {
3290 for( std::size_t i1 = 0; i1 < (std::size_t) m_delayedNeutrons.size( ); ++i1 ) {
3294 product.angleBiasing(
this, a_index, a_temperature, a_energy_in, a_mu_lab, weight1, a_energy_out, a_rng, *a_cumulative_weight );
3299 if( a_checkOrphanProducts ) {
3300 for(
auto productIter = m_associatedOrphanProducts.begin( ); productIter != m_associatedOrphanProducts.end( ); ++productIter ) {
3301 (*productIter)->angleBiasing(
this, a_index, a_temperature, a_energy_in, a_mu_lab, weight1, a_energy_out, a_rng,
3302 *a_cumulative_weight );
3325template <
typename RNG>
3327 RNG && a_rng,
double *a_cumulative_weight,
bool a_checkOrphanProducts )
const {
3329 double cumulative_weight1 = 0.0;
3330 if( a_cumulative_weight ==
nullptr ) a_cumulative_weight = &cumulative_weight1;
3331 double weight1 = 0.0;
3333#ifdef MCGIDI_USE_OUTPUT_CHANNEL
3334 m_outputChannel->angleBiasingViaIntid(
this, a_intid, a_temperature, a_energy_in, a_mu_lab, weight1, a_energy_out, a_rng, *a_cumulative_weight );
3337 for(
auto productIter = m_products.begin( ); productIter != m_products.end( ); ++productIter ) {
3338 (*productIter)->angleBiasingViaIntid(
this, a_intid, a_temperature, a_energy_in, a_mu_lab, weight1, a_energy_out, a_rng, *a_cumulative_weight );
3342 for( std::size_t i1 = 0; i1 < (std::size_t) m_delayedNeutrons.size( ); ++i1 ) {
3346 product.angleBiasingViaIntid(
this, a_intid, a_temperature, a_energy_in, a_mu_lab, weight1, a_energy_out, a_rng, *a_cumulative_weight );
3351 if( a_checkOrphanProducts ) {
3352 for(
auto productIter = m_associatedOrphanProducts.begin( ); productIter != m_associatedOrphanProducts.end( ); ++productIter ) {
3353 (*productIter)->angleBiasingViaIntid(
this, a_intid, a_temperature, a_energy_in, a_mu_lab, weight1, a_energy_out, a_rng,
3354 *a_cumulative_weight );
3363template <
typename RNG,
typename PUSHBACK>
3365 double a_productMass,
Input &a_input, RNG && a_rng, PUSHBACK && a_push_back,
bool a_isPhoton ) {
3371 product.m_sampledType = a_input.m_sampledType;
3373 product.m_productIntid = a_productIntid;
3374 product.m_productIndex = a_productIndex;
3375 product.m_userProductIndex = a_userProductIndex;
3377 product.m_productMass = a_productMass;
3381 product.m_birthTimeSec = 0.;
3382 if( product.m_delayedNeutronDecayRate > 0. ) {
3383 product.m_birthTimeSec = -log( a_rng( ) ) / product.m_delayedNeutronDecayRate;
3387 product.m_kineticEnergy = 0.0;
3388 product.m_px_vx = 0.0;
3389 product.m_py_vy = 0.0;
3390 product.m_pz_vz = 0.0; }
3396 massRatio = a_input.
m_projectileMass * a_productMass / ( massRatio * massRatio );
3397 double modifiedProjectileEnergy = massRatio * a_projectileEnergy;
3399 double sqrtModifiedProjectileEnergy = sqrt( modifiedProjectileEnergy );
3402 a_input.
m_energyOut1 += modifiedProjectileEnergy + 2. * sqrtModifiedProjectileEnergy * sqrtEnergyOut_com;
3411 product.m_pz_vz = p_v * a_input.
m_mu;
3412 p_v *= sqrt( 1. - a_input.
m_mu * a_input.
m_mu );
3413 product.m_px_vx = p_v * sin( a_input.
m_phi );
3414 product.m_py_vy = p_v * cos( a_input.
m_phi ); }
3417 product.m_px_vx = a_input.
m_px_vx1;
3418 product.m_py_vy = a_input.
m_py_vy1;
3419 product.m_pz_vz = a_input.
m_pz_vz1;
3423 product.m_px_vx = a_input.
m_px_vx2;
3424 product.m_py_vy = a_input.
m_py_vy2;
3425 product.m_pz_vz = a_input.
m_pz_vz2; }
3431 product.m_pz_vz = a_input.
m_mu * pz_vz_factor;
3433 double v_perp = sqrt( 1.0 - a_input.
m_mu * a_input.
m_mu ) * pz_vz_factor;
3434 product.m_px_vx = cos( a_input.
m_phi ) * v_perp;
3435 product.m_py_vy = sin( a_input.
m_phi ) * v_perp; }
3438 product.m_px_vx = a_input.
m_px_vx2;
3439 product.m_py_vy = a_input.
m_py_vy2;
3440 product.m_pz_vz = a_input.
m_pz_vz2;
3445 a_push_back( product );
G4double epsilon(G4double density, G4double temperature)
#define MCGIDI_speedOfLight_cm_sec
#define MCGIDI_particleBeta(a_mass_unitOfEnergy, a_kineticEnergy)
#define MCGIDI_classicalElectronRadius
#define MCGIDI_nullReaction
#define PoPI_electronMass_MeV_c2
LUPI_HOST_DEVICE double rate() const
LUPI_HOST_DEVICE int delayedNeutronIndex() const
LUPI_HOST_DEVICE Product const & product() const
LUPI_HOST_DEVICE double angleBiasing(Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab, RNG &&a_rng, double &a_energy_out) const
LUPI_HOST_DEVICE void sample(double a_X, Sampling::Input &a_input, RNG &&a_rng) const
LUPI_HOST_DEVICE void sample(double a_X, Sampling::Input &a_input, RNG &&a_rng) const
LUPI_HOST_DEVICE double angleBiasing(Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab, RNG &&a_rng, double &a_energy_out) const
LUPI_HOST_DEVICE void sample(double a_X, Sampling::Input &a_input, RNG &&a_rng) const
LUPI_HOST_DEVICE double angleBiasing(Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab, RNG &&a_rng, double &a_energy_out) const
LUPI_HOST_DEVICE double angleBiasing(Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab, RNG &&a_rng, double &a_energy_out) const
LUPI_HOST_DEVICE void sample(double a_energy, Sampling::Input &a_input, RNG &&a_rng) const
LUPI_HOST_DEVICE void sample(double a_X, Sampling::Input &a_input, RNG &&a_rng) const
LUPI_HOST_DEVICE double angleBiasing(Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab, RNG &&a_rng, double &a_energy_out) const
LUPI_HOST_DEVICE double evaluateFormFactor(double a_energyIn, double a_mu) const
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION double angleBiasing(Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab, RNG &&a_rng, double &a_energy_out) const MCGIDI_TRUE_VIRTUAL
LUPI_HOST_DEVICE double targetMass() const
LUPI_HOST_DEVICE Type type() const
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION void sample(double a_X, Sampling::Input &a_input, RNG &&a_rng) const MCGIDI_TRUE_VIRTUAL
LUPI_HOST_DEVICE GIDI::Frame productFrame() const
LUPI_HOST_DEVICE double productMass() const
LUPI_HOST_DEVICE double projectileMass() const
LUPI_HOST_DEVICE void sample(double a_X, Sampling::Input &a_input, RNG &&a_rng) const
LUPI_HOST_DEVICE double angleBiasing(Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab, RNG &&a_rng, double &a_energy_out) const
LUPI_HOST_DEVICE void sample(double a_X, Sampling::Input &a_input, RNG &&a_rng) const
LUPI_HOST_DEVICE double energyRatio(double a_energyIn, double a_mu) const
LUPI_HOST_DEVICE double angleBiasing(Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab, RNG &&a_rng, double &a_energy_out) const
LUPI_HOST_DEVICE double evaluateOccupationNumber(double a_X, double a_mu) const
LUPI_HOST_DEVICE double angleBiasing(Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab, RNG &&a_rng, double &a_energy_out) const
LUPI_HOST_DEVICE void sample(double a_energy, Sampling::Input &a_input, RNG &&a_rng) const
LUPI_HOST_DEVICE double angleBiasing(Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab, RNG &&a_rng, double &a_energy_out) const
LUPI_HOST_DEVICE void sample(double a_energy, Sampling::Input &a_input, RNG &&a_rng) const
LUPI_HOST_DEVICE void sample(double a_X, Sampling::Input &a_input, RNG &&a_rng) const
LUPI_HOST_DEVICE double angleBiasing(Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab, RNG &&a_rng, double &a_energy_out) const
LUPI_HOST_DEVICE double evaluateScatteringFactor(double a_X) const
LUPI_HOST_DEVICE double angleBiasing(Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab, RNG &&a_rng, double &a_energy_out) const
LUPI_HOST_DEVICE void sample(double a_X, Sampling::Input &a_input, RNG &&a_rng) const
LUPI_HOST_DEVICE double angleBiasing(Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab, RNG &&a_rng, double &a_energy_out) const
LUPI_HOST_DEVICE void sample(double a_X, Sampling::Input &a_input, RNG &&a_rng) const
LUPI_HOST_DEVICE double angleBiasing(Reaction const *a_reaction, double a_temperature, double a_energy_in, double a_mu_lab, RNG &&a_rng, double &a_energy_out) const
LUPI_HOST_DEVICE void sample(double a_X, Sampling::Input &a_input, RNG &&a_rng) const
LUPI_HOST_DEVICE Function1dType type() const
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION int sampleBoundingInteger(double a_x1, RNG &&a_rng) const
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION double evaluate(double a_x1) const MCGIDI_TRUE_VIRTUAL
LUPI_HOST_DEVICE Interpolation interpolation() const
LUPI_HOST_DEVICE int sampleBoundingInteger(double a_energy, RNG &&a_rng) const
LUPI_HOST_DEVICE int sampleCaptureLevel(ProtareSingle const *a_protare, double a_energy, RNG &&a_rng)
LUPI_HOST_DEVICE std::size_t index() const
LUPI_HOST_DEVICE int sampleCaptureLevel(ProtareSingle const *a_protare, double a_energy, RNG &&a_rng, bool a_checkEnergy) const
LUPI_HOST_DEVICE bool sampleProducts(ProtareSingle const *a_protare, double a_projectileEnergy, Sampling::Input &a_input, RNG &&a_rng, PUSHBACK &&a_push_back, Sampling::ProductHandler &a_products) const
LUPI_HOST_DEVICE int sampleLevelIndex(double a_projectileEnergy, double a_random) const
LUPI_HOST_DEVICE bool sampleProducts(ProtareSingle const *a_protare, double a_projectileEnergy, Sampling::Input &a_input, RNG &&a_rng, PUSHBACK &&a_push_back, Sampling::ProductHandler &a_products) const
LUPI_HOST_DEVICE double reactionCrossSection2(std::size_t a_reactionIndex, URR_protareInfos const &a_URR_protareInfos, int a_URR_index, double a_energy, std::size_t a_energyIndex, double a_energyFraction, bool a_sampling=false) const
LUPI_HOST_DEVICE std::size_t evaluationInfo(std::size_t a_hashIndex, double a_energy, double *a_energyFraction) const
LUPI_HOST_DEVICE double reactionCrossSection(std::size_t a_reactionIndex, std::size_t a_hashIndex, bool a_sampling=false) const
LUPI_HOST_DEVICE std::size_t sampleReaction(URR_protareInfos const &a_URR_protareInfos, int a_URR_index, std::size_t a_hashIndex, double a_temperature, double a_energy, double a_crossSection, RNG &&a_rng) const
LUPI_HOST_DEVICE std::size_t sampleReaction(std::size_t a_hashIndex, double a_temperature, double a_energy_in, double a_crossSection, RNG &&rng) const
LUPI_HOST_DEVICE double probability() const
LUPI_HOST_DEVICE int residualStateIndex() const
LUPI_HOST_DEVICE double gammaEnergy() const
LUPI_HOST_DEVICE double photonEmissionProbability() const
LUPI_HOST_DEVICE Vector< std::size_t > const & branchIndices() const
LUPI_HOST_DEVICE double nuclearLevelEnergy() const
LUPI_HOST_DEVICE int intid() const
LUPI_HOST_DEVICE double nuclearLevelEnergyWidth() const
LUPI_HOST_DEVICE void angleBiasing(Reaction const *a_reaction, int a_pid, double a_temperature, double a_energy_in, double a_mu_lab, double &a_probability, double &a_energy_out, RNG &&a_rng, double &a_cumulative_weight) const
LUPI_HOST_DEVICE void angleBiasingViaIntid(Reaction const *a_reaction, int a_intid, double a_temperature, double a_energy_in, double a_mu_lab, double &a_probability, double &a_energy_out, RNG &&a_rng, double &a_cumulative_weight) const
LUPI_HOST_DEVICE void sampleProducts(ProtareSingle const *a_protare, double a_projectileEnergy, Sampling::Input &a_input, RNG &&a_rng, PUSHBACK &&a_push_back, Sampling::ProductHandler &a_products) const
LUPI_HOST_DEVICE DelayedNeutron const * delayedNeutron(std::size_t a_index) const
LUPI_HOST_DEVICE double sample(double a_x2, double a_rngValue, RNG &&a_rng) const
LUPI_HOST_DEVICE double sample(double a_x2, double a_rngValue, RNG &&a_rng) const
LUPI_HOST_DEVICE double sample(double a_x2, double a_rngValue, RNG &&a_rng) const
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION double sample(double a_rngValue, RNG &&a_rng) const MCGIDI_TRUE_VIRTUAL
LUPI_HOST_DEVICE double sample(double a_x2, double a_rngValue, RNG &&a_rng) const
LUPI_HOST_DEVICE double sample2dOf3d(double a_x2, double a_rngValue, RNG &&a_rng, double *a_x1_1, double *a_x1_2) const
LUPI_HOST_DEVICE double sample2dOf3d(double a_x2, double a_rngValue, RNG &&a_rng, double *a_x1_1, double *a_x1_2) const
LUPI_HOST_DEVICE double sample(double a_x2, double a_rngValue, RNG &&a_rng) const
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION double sample(double a_x2, double a_rngValue, RNG &&a_rng) const MCGIDI_TRUE_VIRTUAL
LUPI_HOST_DEVICE ProbabilityBase2dType type() const
LUPI_HOST_DEVICE MCGIDI_VIRTUAL_FUNCTION double sample(double a_x3, double a_x2_1, double a_x2_2, double a_rngValue, RNG &&a_rng) const MCGIDI_TRUE_VIRTUAL
LUPI_HOST_DEVICE double sample(double a_x2, double a_rngValue, RNG &&a_rng) const
LUPI_HOST_DEVICE double sample(double a_x2, double a_rngValue, RNG &&a_rng) const
LUPI_HOST_DEVICE double sample(double a_x2, double a_rngValue, RNG &&a_rng) const
LUPI_HOST_DEVICE double sample(double a_x2, double a_rngValue, RNG &&a_rng) const
LUPI_HOST_DEVICE double sample(double a_x2, double a_rngValue, RNG &&a_rng) const
LUPI_HOST_DEVICE double sample2dOf3d(double a_x2, double a_rngValue, RNG &&a_rng, double *a_x1_1, double *a_x1_2) const
LUPI_HOST_DEVICE double sample(double a_x2, double a_rngValue, RNG &&a_rng) const
LUPI_HOST_DEVICE double sample(double a_x3, double a_x2_1, double a_x2_2, double a_rngValue, RNG &&a_rng) const
LUPI_HOST_DEVICE double sample(double a_rngValue, RNG &&a_rng) const
LUPI_HOST_DEVICE int userParticleIndex() const
LUPI_HOST_DEVICE void sampleProducts(ProtareSingle const *a_protare, double a_projectileEnergy, Sampling::Input &a_input, RNG &&a_rng, PUSHBACK &&a_push_back, Sampling::ProductHandler &a_products) const
LUPI_HOST_DEVICE int index() const
LUPI_HOST_DEVICE void angleBiasing(Reaction const *a_reaction, int a_pid, double a_temperature, double a_energy_in, double a_mu_lab, double &a_probability, double &a_energy_out, RNG &&a_rng, double &a_cumulative_weight) const
LUPI_HOST_DEVICE void sampleFinalState(ProtareSingle const *a_protare, double a_projectileEnergy, Sampling::Input &a_input, RNG &&a_rng, PUSHBACK &&a_push_back, Sampling::ProductHandler &a_products) const
LUPI_HOST_DEVICE int intid() const
LUPI_HOST_DEVICE double mass() const
LUPI_HOST_DEVICE void angleBiasingViaIntid(Reaction const *a_reaction, int a_intid, double a_temperature, double a_energy_in, double a_mu_lab, double &a_probability, double &a_energy_out, RNG &&a_rng, double &a_cumulative_weight) const
LUPI_HOST_DEVICE std::size_t sampleReaction(Sampling::Input &a_input, URR_protareInfos const &a_URR_protareInfos, std::size_t a_hashIndex, double a_crossSection, RNG &&a_rng) const
LUPI_HOST_DEVICE std::size_t sampleReaction(Sampling::Input &a_input, URR_protareInfos const &a_URR_protareInfos, std::size_t a_hashIndex, double a_crossSection, RNG &&a_rng) const
LUPI_HOST_DEVICE void sampleBranchingGammas(Sampling::Input &a_input, double a_projectileEnergy, int a_initialStateIndex, RNG &&a_rng, PUSHBACK &&push_back, Sampling::ProductHandler &a_products) const
LUPI_HOST_DEVICE bool inURR(double a_energy) const
LUPI_HOST_DEVICE double crossSection(URR_protareInfos const &a_URR_protareInfos, std::size_t a_hashIndex, double a_temperature, double a_energy, bool a_sampling=false) const
LUPI_HOST_DEVICE double reactionCrossSection(std::size_t a_reactionIndex, URR_protareInfos const &a_URR_protareInfos, std::size_t a_hashIndex, double a_temperature, double a_energy, bool a_sampling=false) const
LUPI_HOST_DEVICE bool sampleTargetBetaForUpscatterModelA(Sampling::Input &a_input, RNG &&a_rng) const
LUPI_HOST_DEVICE const Vector< NuclideGammaBranchStateInfo * > & nuclideGammaBranchStateInfos() const
LUPI_HOST_DEVICE int URR_index() const
LUPI_HOST_DEVICE bool upscatterModelASupported() const
LUPI_HOST_DEVICE std::size_t sampleReaction(Sampling::Input &a_input, URR_protareInfos const &a_URR_protareInfos, std::size_t a_hashIndex, double a_crossSection, RNG &&a_rng) const
LUPI_HOST_DEVICE int projectileIntid() const
LUPI_HOST_DEVICE ProtareType protareType() const
LUPI_HOST_DEVICE int projectileIndex() const
LUPI_HOST_DEVICE int userPhotonIndex() const
LUPI_HOST_DEVICE int projectileUserIndex() const
LUPI_HOST_DEVICE int photonIndex() const
MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE std::size_t numberOfProtares() const MCGIDI_TRUE_VIRTUAL
MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE std::size_t sampleReaction(Sampling::Input &a_input, URR_protareInfos const &a_URR_protareInfos, std::size_t a_hashIndex, double a_crossSection, RNG &&a_rng) const MCGIDI_TRUE_VIRTUAL
LUPI_HOST_DEVICE double projectileMass() const
MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE ProtareSingle const * protare(std::size_t a_index) const MCGIDI_TRUE_VIRTUAL
static LUPI_HOST_DEVICE void sampleNullProducts(Protare const &a_protare, double a_projectileEnergy, Sampling::Input &a_input, RNG &&a_rng, PUSHBACK &&a_push_back, Sampling::ProductHandler &a_products)
LUPI_HOST_DEVICE double angleBiasing(int a_pid, double a_temperature, double a_energy_in, double a_mu_lab, double &a_energy_out, RNG &&a_rng, double *a_cumulative_weight=nullptr, bool a_checkOrphanProducts=true) const
LUPI_HOST_DEVICE std::size_t reactionIndex() const
LUPI_HOST_DEVICE Product const * product(std::size_t a_index) const
LUPI_HOST_DEVICE ProtareSingle const * protareSingle() const
LUPI_HOST_DEVICE void sampleProducts(Protare const *a_protare, Sampling::Input &a_input, RNG &&a_rng, PUSHBACK &&a_push_back, Sampling::ProductHandler &a_products, bool a_checkOrphanProducts=true) const
LUPI_HOST_DEVICE double angleBiasingViaIntid(int a_intid, double a_temperature, double a_energy_in, double a_mu_lab, double &a_energy_out, RNG &&a_rng, double *a_cumulative_weight=nullptr, bool a_checkOrphanProducts=true) const
LUPI_HOST_DEVICE void add(double a_projectileEnergy, int a_productIntid, int a_productIndex, int a_userProductIndex, double a_productMass, Input &a_input, RNG &&a_rng, PUSHBACK &&push_back, bool isPhoton)
LUPI_HOST_DEVICE bool inURR() const
LUPI_HOST_DEVICE void updateProtare(MCGIDI::Protare const *a_protare, double a_energy, RNG &&a_rng)
std::string doubleToString3(char const *a_format, double a_value, bool a_reduceBits=false)
@ coherentPhotoAtomicScattering
@ incoherentPhotoAtomicScattering
@ incoherentPhotoAtomicScatteringElectron
@ incoherentBoundToFreePhotoAtomicScattering
LUPI_HOST_DEVICE void upScatterModelABoostParticle(Sampling::Input &a_input, RNG &&a_rng, Sampling::Product &a_product)
LUPI_HOST_DEVICE double particleKineticEnergy(double a_mass_unitOfEnergy, double a_particleBeta)
LUPI_HOST_DEVICE int binarySearchVector(double a_x, Vector< double > const &a_Xs, bool a_boundIndex=false)
LUPI_HOST_DEVICE double particleKineticEnergyFromBeta2(double a_mass_unitOfEnergy, double a_particleBeta2)
@ simpleMaxwellianFission
LUPI_HOST_DEVICE int muCOM_From_muLab(double a_muLab, double a_boostBeta, double a_productBeta, double &a_muPlus, double &a_JacobianPlus, double &a_muMinus, double &a_JacobianMinus)
@ TerrellFissionNeutronMultiplicityModel
static int constexpr photon
static int constexpr neutron