142 auto Z =
static_cast<G4int>(massCode / 1000);
143 auto A =
static_cast<G4int>(massCode - 1000 * Z);
160 if (Z == 2) result->SetDefinition(
G4He3::He3());
166 "G4ParticleHPContAngularPar: Unknown ion case 1");
181 if (angularRep == 1) {
182 if (nDiscreteEnergies != 0) {
185 if (fCache.
Get().fresh) {
188 fCache.
Get().remaining_energy =
189 std::max(theAngular[0].GetLabel(), theAngular[nEnergies - 1].GetLabel());
190 fCache.
Get().fresh =
false;
195 if (nDiscreteEnergies == nEnergies) {
196 fCache.
Get().remaining_energy =
197 std::max(fCache.
Get().remaining_energy,
198 theAngular[nDiscreteEnergies - 1].
GetLabel());
202 for (
G4int j = nDiscreteEnergies; j < nEnergies; ++j) {
203 cont_min = theAngular[j].
GetLabel();
204 if (theAngular[j].GetValue(0) != 0.0)
break;
206 fCache.
Get().remaining_energy = std::max(
207 fCache.
Get().remaining_energy, std::min(theAngular[nDiscreteEnergies - 1].
GetLabel(),
212 auto running =
new G4double[nEnergies + 1];
216 for (
G4int j = 0; j < nDiscreteEnergies; ++j) {
218 if (theAngular[j].GetLabel() <= fCache.
Get().remaining_energy)
220 running[j + 1] = running[j] + delta;
223 G4double tot_prob_DIS = std::max(running[nDiscreteEnergies], 0.0);
226 for (
G4int j = nDiscreteEnergies; j < nEnergies; ++j) {
230 if (theAngular[j].GetLabel() <= fCache.
Get().remaining_energy)
238 if (theAngular[j].GetLabel() != 0) {
239 if (j == nDiscreteEnergies) {
244 e_low = theAngular[j - 1].
GetLabel() / eV;
246 e_high = theAngular[j].
GetLabel() / eV;
251 if (theAngular[j].GetLabel() == 0.0) {
252 e_low = theAngular[j].
GetLabel() / eV;
253 if (j != nEnergies - 1) {
254 e_high = theAngular[j + 1].
GetLabel() / eV;
257 e_high = theAngular[j].
GetLabel() / eV;
261 running[j + 1] = running[j] + ((e_high - e_low) * delta1);
263 G4double tot_prob_CON = std::max(running[nEnergies] - running[nDiscreteEnergies], 0.0);
266 if (tot_prob_DIS == 0.0 && tot_prob_CON == 0.0) {
271 random *= (tot_prob_DIS + tot_prob_CON);
275 if (random <= (tot_prob_DIS / (tot_prob_DIS + tot_prob_CON))
276 || nDiscreteEnergies == nEnergies)
279 for (
G4int j = 0; j < nDiscreteEnergies; ++j) {
281 if (random < running[j + 1]) {
286 fsEnergy = theAngular[it].
GetLabel();
289 theStore.
Init(0, fsEnergy, nAngularParameters);
290 for (
G4int j = 0; j < nAngularParameters; ++j) {
291 theStore.
SetCoeff(0, j, theAngular[it].GetValue(j));
299 for (
G4int j = nDiscreteEnergies; j < nEnergies; ++j) {
301 if (random < running[j]) {
313 if (it != nDiscreteEnergies) y1 = theAngular[it - 1].
GetLabel();
319 theStore.
Init(0, y1, nAngularParameters);
320 theStore.
Init(1, y2, nAngularParameters);
323 for (
G4int j = 0; j < nAngularParameters; ++j) {
325 if (it == nDiscreteEnergies) itt = it + 1;
328 theStore.
SetCoeff(0, j, theAngular[itt - 1].GetValue(j));
329 theStore.
SetCoeff(1, j, theAngular[itt].GetValue(j));
340 fCache.
Get().remaining_energy -= fsEnergy;
347 if (fCache.
Get().fresh) {
348 fCache.
Get().remaining_energy = theAngular[nEnergies - 1].
GetLabel();
349 fCache.
Get().fresh =
false;
353 auto running =
new G4double[nEnergies];
356 for (i = 1; i < nEnergies; i++) {
357 running[i] = running[i - 1];
358 if (fCache.
Get().remaining_energy >= theAngular[i].
GetLabel()) {
369 if (nEnergies == 1 || running[nEnergies - 1] == 0) {
370 fCache.
Get().currentMeanEnergy = 0.0;
373 fCache.
Get().currentMeanEnergy = weighted / running[nEnergies - 1];
376 if (nEnergies == 1) it = 0;
377 if (running[nEnergies - 1] != 0) {
378 for (i = 1; i < nEnergies; i++) {
380 if (random < running[i] / running[nEnergies - 1])
break;
384 if (running[nEnergies - 1] == 0) it = 0;
385 if (it < nDiscreteEnergies || it == 0) {
387 fsEnergy = theAngular[it].
GetLabel();
389 theStore.
Init(0, fsEnergy, nAngularParameters);
390 for (i = 0; i < nAngularParameters; i++) {
391 theStore.
SetCoeff(0, i, theAngular[it].GetValue(i));
401 running[it - 1] / running[nEnergies - 1],
402 running[it] / running[nEnergies - 1], e1, e2);
405 theStore.
Init(0, e1, nAngularParameters);
406 theStore.
Init(1, e2, nAngularParameters);
407 for (i = 0; i < nAngularParameters; i++) {
408 theStore.
SetCoeff(0, i, theAngular[it - 1].GetValue(i));
409 theStore.
SetCoeff(1, i, theAngular[it].GetValue(i));
417 G4double x1 = running[it - 1] / running[nEnergies - 1];
418 G4double x2 = running[it] / running[nEnergies - 1];
423 theStore.
Init(0, y1, nAngularParameters);
424 theStore.
Init(1, y2, nAngularParameters);
426 for (i = 0; i < nAngularParameters; i++) {
427 theStore.
SetCoeff(0, i, theAngular[it - 1].GetValue(i));
428 theStore.
SetCoeff(1, i, theAngular[it].GetValue(i));
439 fCache.
Get().remaining_energy -= fsEnergy;
444 else if (angularRep == 2) {
447 auto running =
new G4double[nEnergies];
450 for (j = 1; j < nEnergies; ++j) {
451 if (j != 0) running[j] = running[j - 1];
462 fCache.
Get().currentMeanEnergy = 0.0;
464 fCache.
Get().currentMeanEnergy = weighted / running[nEnergies - 1];
468 for (j = 1; j < nEnergies; ++j) {
470 if (randkal*running[nEnergies - 1] < running[j])
break;
475 if (itt == 0) itt = 1;
476 x = randkal * running[nEnergies - 1];
477 x1 = running[itt - 1];
481 y1 = theAngular[itt - 1].
GetLabel();
488 compoundFraction = theInt.
Interpolate(theManager.
GetScheme(itt), fsEnergy, y1, y2, cLow, cHigh);
490 if (compoundFraction > 1.0)
491 compoundFraction = 1.0;
499 G4double productMass = result->GetMass();
500 auto targetZ =
G4int(fCache.
Get().theTargetCode / 1000);
501 auto targetA =
G4int(fCache.
Get().theTargetCode - 1000 * targetZ);
504 if (targetA == 0) targetA =
G4int(fCache.
Get().theTarget->GetMass() / amu_c2 + 0.5);
505 G4double targetMass = fCache.
Get().theTarget->GetMass();
506 auto incidentA =
G4int(incidentMass / amu_c2 + 0.5);
508 G4int residualA = targetA + incidentA -
A;
509 G4int residualZ = targetZ + incidentZ - Z;
513 compoundFraction, incidentEnergy, incidentMass, productEnergy, productMass, residualMass,
514 residualA, residualZ, targetMass, targetA, targetZ, incidentA, incidentZ,
A, Z);
515 cosTh = theKallbach.
Sample(anEnergy);
518 else if (angularRep > 10 && angularRep < 16) {
520 auto running =
new G4double[nEnergies];
523 for (i = 1; i < nEnergies; ++i) {
524 if (i != 0) running[i] = running[i - 1];
535 fCache.
Get().currentMeanEnergy = 0.0;
537 fCache.
Get().currentMeanEnergy = weighted / running[nEnergies - 1];
539 if (nEnergies == 1) it = 0;
540 for (i = 1; i < nEnergies; i++) {
542 if (random < running[i] / running[nEnergies - 1])
break;
545 if (it < nDiscreteEnergies || it == 0) {
547 fsEnergy = theAngular[0].
GetLabel();
550 for (
G4int j = 1; j < nAngularParameters; j += 2) {
551 theStore.
SetX(aCounter, theAngular[0].GetValue(j));
552 theStore.
SetY(aCounter, theAngular[0].GetValue(j + 1));
556 aMan.
Init(angularRep - 10, nAngularParameters - 1);
558 cosTh = theStore.
Sample();
561 fsEnergy = theAngular[it].
GetLabel();
564 aMan.
Init(angularRep - 10, nAngularParameters - 1);
568 for (
G4int j = 1; j < nAngularParameters; j += 2) {
569 theStore.
SetX(aCounter, theAngular[it].GetValue(j));
571 running[it - 1] / running[nEnergies - 1],
572 running[it] / running[nEnergies - 1],
577 cosTh = theStore.
Sample();
581 G4double x1 = running[it - 1] / running[nEnergies - 1];
582 G4double x2 = running[it] / running[nEnergies - 1];
589 aMan.
Init(angularRep - 10, nAngularParameters - 1);
592 for (i = 0, j = 1; i < nAngularParameters; i++, j += 2) {
593 theBuff1.
SetX(i, theAngular[it - 1].GetValue(j));
594 theBuff1.
SetY(i, theAngular[it - 1].GetValue(j + 1));
595 theBuff2.
SetX(i, theAngular[it].GetValue(j));
596 theBuff2.
SetY(i, theAngular[it].GetValue(j + 1));
605 x = theBuff1.
GetX(i);
606 y1 = theBuff1.
GetY(i);
607 y2 = theBuff2.
GetY(i);
613 cosTh = theStore.
Sample();
619 "G4ParticleHPContAngularPar::Sample: Unknown angular representation");
622 result->SetKineticEnergy(fsEnergy);
625 if(cosTh > 1.0) { cosTh = 1.0; }
626 else if (cosTh < -1.0) { cosTh = -1.0; }
627 G4double sinth = std::sqrt((1.0 - cosTh)*(1.0 + cosTh));
628 G4double mtot = result->GetTotalMomentum();
629 G4ThreeVector tempVector(mtot * sinth * std::cos(phi), mtot * sinth * std::sin(phi), mtot * cosTh);
630 result->SetMomentum(tempVector);
660 G4int ie, ie1, ie2, ie1Prev, ie2Prev;
664 if (!fCache.
Get().fresh)
return;
672 nAngularParameters = copyAngpar1.nAngularParameters;
673 theManager = copyAngpar1.theManager;
674 theEnergy = anEnergy;
684 const std::map<G4double, G4int> discEnerOwn1 = copyAngpar1.GetDiscreteEnergiesOwn();
686 std::map<G4double, G4int>::const_iterator itedeo1;
687 std::map<G4double, G4int>::const_iterator itedeo2;
688 std::vector<G4ParticleHPList*> vAngular(discEnerOwn1.size());
690 for (itedeo1 = discEnerOwn1.cbegin(); itedeo1 != discEnerOwn1.cend(); ++itedeo1) {
691 discEner1 = itedeo1->first;
692 if (discEner1 < theMinEner) {
693 theMinEner = discEner1;
695 if (discEner1 > theMaxEner) {
696 theMaxEner = discEner1;
698 ie1 = itedeo1->second;
699 itedeo2 = discEnerOwn2.find(discEner1);
700 if (itedeo2 == discEnerOwn2.cend()) {
704 ie2 = itedeo2->second;
707 vAngular[ie1]->SetLabel(copyAngpar1.theAngular[ie1].GetLabel());
709 for (
G4int ip = 0; ip < nAngularParameters; ++ip) {
710 val1 = copyAngpar1.theAngular[ie1].GetValue(ip);
712 val2 = copyAngpar2.theAngular[ie2].
GetValue(ip);
718 copyAngpar2.theEnergy, val1, val2);
719 vAngular[ie1]->SetValue(ip, value);
724 std::vector<G4ParticleHPList*>::const_iterator itv;
726 for (itedeo2 = discEnerOwn2.cbegin(); itedeo2 != discEnerOwn2.cend(); ++itedeo2) {
727 discEner2 = itedeo2->first;
728 ie2 = itedeo2->second;
730 itedeo1 = discEnerOwn1.find(discEner2);
731 if (itedeo1 != discEnerOwn1.cend()) {
736 if (discEner2 < theMinEner) {
737 theMinEner = discEner2;
739 if (discEner2 > theMaxEner) {
740 theMaxEner = discEner2;
743 G4bool isInserted =
false;
745 for (itv = vAngular.cbegin(); itv != vAngular.cend(); ++itv, ++ie) {
746 if (discEner2 > (*itv)->GetLabel()) {
748 (*itv)->SetLabel(copyAngpar2.theAngular[ie2].
GetLabel());
754 ie = (
G4int)vAngular.size();
756 vAngular[ie]->SetLabel(copyAngpar2.theAngular[ie2].
GetLabel());
761 for (
G4int ip = 0; ip < nAngularParameters; ++ip) {
763 val2 = copyAngpar2.theAngular[ie2].
GetValue(ip);
765 copyAngpar2.theEnergy, val1, val2);
766 vAngular[ie]->SetValue(ip, value);
772 nDiscreteEnergies = (
G4int)vAngular.size();
774 theAngular =
nullptr;
775 if (nDiscreteEnergies > 0) {
778 theDiscreteEnergiesOwn.clear();
779 theDiscreteEnergies.clear();
780 for (ie = 0; ie < nDiscreteEnergies; ++ie) {
781 theAngular[ie].
SetLabel(vAngular[ie]->GetLabel());
782 for (
G4int ip = 0; ip < nAngularParameters; ++ip) {
783 theAngular[ie].
SetValue(ip, vAngular[ie]->GetValue(ip));
785 theDiscreteEnergiesOwn[theAngular[ie].
GetLabel()] = ie;
786 theDiscreteEnergies.insert(theAngular[ie].GetLabel());
797 G4double interMinEner = copyAngpar1.GetMinEner()
798 + (theEnergy - copyAngpar1.GetEnergy())
799 * (copyAngpar2.
GetMinEner() - copyAngpar1.GetMinEner())
800 / (copyAngpar2.
GetEnergy() - copyAngpar1.GetEnergy());
801 G4double interMaxEner = copyAngpar1.GetMaxEner()
802 + (theEnergy - copyAngpar1.GetEnergy())
803 * (copyAngpar2.
GetMaxEner() - copyAngpar1.GetMaxEner())
804 / (copyAngpar2.
GetEnergy() - copyAngpar1.GetEnergy());
807 theEnergiesTransformed.clear();
809 G4int nEnergies1 = copyAngpar1.GetNEnergies();
810 G4int nDiscreteEnergies1 = copyAngpar1.GetNDiscreteEnergies();
811 G4double minEner1 = copyAngpar1.GetMinEner();
812 G4double maxEner1 = copyAngpar1.GetMaxEner();
825 for (ie1 = nDiscreteEnergies1; ie1 < nEnergies1; ++ie1) {
826 e1 = copyAngpar1.theAngular[ie1].GetLabel();
827 eTNorm1 = (e1 - minEner1);
828 if (maxEner1 != minEner1) eTNorm1 /= (maxEner1 - minEner1);
829 if (eTNorm1 >= 0 && eTNorm1 <= 1) theEnergiesTransformed.insert(eTNorm1);
834 for (ie2 = nDiscreteEnergies2; ie2 < nEnergies2; ++ie2) {
835 e2 = copyAngpar2.theAngular[ie2].
GetLabel();
836 eTNorm2 = (e2 - minEner2);
837 if (maxEner2 != minEner2) eTNorm2 /= (maxEner2 - minEner2);
838 if (eTNorm2 >= 0 && eTNorm2 <= 1) theEnergiesTransformed.insert(eTNorm2);
842 nEnergies = nDiscreteEnergies + (
G4int)theEnergiesTransformed.size();
845 const std::size_t esize = nEnergies > 0 ? nEnergies : 1;
850 if (theAngular !=
nullptr) {
851 for (ie = 0; ie < nDiscreteEnergies; ++ie) {
852 theNewAngular[ie].SetLabel(theAngular[ie].GetLabel());
853 for (
G4int ip = 0; ip < nAngularParameters; ++ip) {
854 theNewAngular[ie].SetValue(ip, theAngular[ie].GetValue(ip));
859 theAngular = theNewAngular;
862 auto iteet = theEnergiesTransformed.begin();
866 for (ie = nDiscreteEnergies; ie < nEnergies; ++ie, ++iteet) {
870 e1Interp = (maxEner1 - minEner1) * eT + minEner1;
872 for (ie1 = nDiscreteEnergies1; ie1 < nEnergies1; ++ie1) {
873 if ((copyAngpar1.theAngular[ie1].GetLabel() - e1Interp) > 1.E-10 * e1Interp)
break;
876 if (ie1 == 0) ++ie1Prev;
877 if (ie1 == nEnergies1) {
883 e2Interp = (maxEner2 - minEner2) * eT + minEner2;
885 for (ie2 = nDiscreteEnergies2; ie2 < nEnergies2; ++ie2) {
886 if ((copyAngpar2.theAngular[ie2].
GetLabel() - e2Interp) > 1.E-10 * e2Interp)
break;
889 if (ie2 == 0) ++ie2Prev;
890 if (ie2 == nEnergies2) {
896 G4double eN = (interMaxEner - interMinEner) * eT + interMinEner;
899 if (eN < theMinEner) {
902 if (eN > theMaxEner) {
909 for (
G4int ip = 0; ip < nAngularParameters; ++ip) {
911 theManager.
GetScheme(ie), e1Interp, copyAngpar1.theAngular[ie1Prev].GetLabel(),
912 copyAngpar1.theAngular[ie1].GetLabel(), copyAngpar1.theAngular[ie1Prev].GetValue(ip),
913 copyAngpar1.theAngular[ie1].GetValue(ip))
914 * (maxEner1 - minEner1);
917 copyAngpar2.theAngular[ie2].
GetLabel(), copyAngpar2.theAngular[ie2Prev].
GetValue(ip),
918 copyAngpar2.theAngular[ie2].
GetValue(ip))
919 * (maxEner2 - minEner2);
921 value = theInt.
Interpolate(aScheme, anEnergy, copyAngpar1.theEnergy, copyAngpar2.theEnergy,
923 if (interMaxEner != interMinEner) {
924 value /= (interMaxEner - interMinEner);
926 else if (value != 0) {
928 "G4ParticleHPContAngularPar::PrepareTableInterpolation "
929 "interMaxEner == interMinEner and value != 0.");
935 for (itv = vAngular.cbegin(); itv != vAngular.cend(); ++itv)