|
Lines 59-64
Link Here
|
| 59 |
#include "G4IonTable.hh" |
59 |
#include "G4IonTable.hh" |
| 60 |
#include "G4ParticleHPManager.hh" |
60 |
#include "G4ParticleHPManager.hh" |
| 61 |
#include <set> |
61 |
#include <set> |
|
|
62 |
#include <vector> |
| 62 |
|
63 |
|
| 63 |
G4ParticleHPContAngularPar::G4ParticleHPContAngularPar( G4ParticleDefinition* projectile ) |
64 |
G4ParticleHPContAngularPar::G4ParticleHPContAngularPar( G4ParticleDefinition* projectile ) |
| 64 |
{ |
65 |
{ |
|
Lines 168-173
Link Here
|
| 168 |
//Continues Emssions, low to high LAST |
169 |
//Continues Emssions, low to high LAST |
| 169 |
fCache.Get()->remaining_energy = std::max ( theAngular[0].GetLabel() , theAngular[nEnergies-1].GetLabel() ); |
170 |
fCache.Get()->remaining_energy = std::max ( theAngular[0].GetLabel() , theAngular[nEnergies-1].GetLabel() ); |
| 170 |
fCache.Get()->fresh = false; |
171 |
fCache.Get()->fresh = false; |
|
|
172 |
if( std::getenv("G4PHPTEST") ) G4cout << " G4ParticleHPContAngularPar::Sample fresh remaining_energy " << fCache.Get()->remaining_energy << G4endl; |
| 173 |
|
| 171 |
} |
174 |
} |
| 172 |
|
175 |
|
| 173 |
//Cheating for small remaining_energy |
176 |
//Cheating for small remaining_energy |
|
Lines 175-180
Link Here
|
| 175 |
if ( nDiscreteEnergies == nEnergies ) |
178 |
if ( nDiscreteEnergies == nEnergies ) |
| 176 |
{ |
179 |
{ |
| 177 |
fCache.Get()->remaining_energy = std::max ( fCache.Get()->remaining_energy , theAngular[nDiscreteEnergies-1].GetLabel() ); //Minimum Line |
180 |
fCache.Get()->remaining_energy = std::max ( fCache.Get()->remaining_energy , theAngular[nDiscreteEnergies-1].GetLabel() ); //Minimum Line |
|
|
181 |
if( std::getenv("G4PHPTEST") ) G4cout << " G4ParticleHPContAngularPar::Sample cheat case for small remaining_energy " << fCache.Get()->remaining_energy << G4endl; |
| 178 |
} |
182 |
} |
| 179 |
else |
183 |
else |
| 180 |
{ |
184 |
{ |
|
Lines 187-192
Link Here
|
| 187 |
if ( theAngular[j].GetValue(0) != 0.0 ) break; |
191 |
if ( theAngular[j].GetValue(0) != 0.0 ) break; |
| 188 |
} |
192 |
} |
| 189 |
fCache.Get()->remaining_energy = std::max ( fCache.Get()->remaining_energy , std::min ( theAngular[nDiscreteEnergies-1].GetLabel() , cont_min ) ); //Minimum Line or grid |
193 |
fCache.Get()->remaining_energy = std::max ( fCache.Get()->remaining_energy , std::min ( theAngular[nDiscreteEnergies-1].GetLabel() , cont_min ) ); //Minimum Line or grid |
|
|
194 |
if( std::getenv("G4PHPTEST") ) G4cout << " G4ParticleHPContAngularPar::Sample max line or grid remaining_energy " << fCache.Get()->remaining_energy << G4endl; |
| 190 |
} |
195 |
} |
| 191 |
// |
196 |
// |
| 192 |
G4double random = G4UniformRand(); |
197 |
G4double random = G4UniformRand(); |
|
Lines 197-203
Link Here
|
| 197 |
for ( G4int j = 0 ; j < nDiscreteEnergies ; j++ ) |
202 |
for ( G4int j = 0 ; j < nDiscreteEnergies ; j++ ) |
| 198 |
{ |
203 |
{ |
| 199 |
G4double delta = 0.0; |
204 |
G4double delta = 0.0; |
| 200 |
if ( theAngular[j].GetLabel() <= fCache.Get()->remaining_energy ) delta = theAngular[i].GetValue(0); |
205 |
if ( theAngular[j].GetLabel() <= fCache.Get()->remaining_energy ) delta = theAngular[j].GetValue(0); |
| 201 |
running[j+1] = running[j] + delta; |
206 |
running[j+1] = running[j] + delta; |
| 202 |
} |
207 |
} |
| 203 |
G4double tot_prob_DIS = running[ nDiscreteEnergies ]; |
208 |
G4double tot_prob_DIS = running[ nDiscreteEnergies ]; |
|
Lines 327-333
Link Here
|
| 327 |
} |
332 |
} |
| 328 |
|
333 |
|
| 329 |
//TK080711 |
334 |
//TK080711 |
| 330 |
if( adjustResult ) fCache.Get()->remaining_energy -= fsEnergy; |
335 |
// SM 30 March 2022 |
|
|
336 |
// the remaining energy needs to be lowered by the photon |
| 337 |
// energy in *any* case. Otherwise additional photons with |
| 338 |
// too high energy will be produced - therefore the |
| 339 |
// adjustResult condition has been removed |
| 340 |
// |
| 341 |
//if( adjustResult ) fCache.Get()->remaining_energy -= fsEnergy; |
| 342 |
if( std::getenv("G4PHPTEST") ) G4cout << " G4ParticleHPContAngularPar::Sample remaining_energy - fsEnergy " << fCache.Get()->remaining_energy << " - " << fsEnergy << G4endl; |
| 343 |
fCache.Get()->remaining_energy -= fsEnergy; |
| 331 |
//TK080711 |
344 |
//TK080711 |
| 332 |
|
345 |
|
| 333 |
//080801b |
346 |
//080801b |
|
Lines 343-348
Link Here
|
| 343 |
{ |
356 |
{ |
| 344 |
fCache.Get()->remaining_energy = theAngular[ nEnergies-1 ].GetLabel(); |
357 |
fCache.Get()->remaining_energy = theAngular[ nEnergies-1 ].GetLabel(); |
| 345 |
fCache.Get()->fresh = false; |
358 |
fCache.Get()->fresh = false; |
|
|
359 |
if( std::getenv("G4PHPTEST") ) G4cout << " G4ParticleHPContAngularPar::Sample 2nd fresh remaining_energy " << fCache.Get()->remaining_energy << G4endl; |
| 346 |
} |
360 |
} |
| 347 |
//080714 |
361 |
//080714 |
| 348 |
G4double random = G4UniformRand(); |
362 |
G4double random = G4UniformRand(); |
|
Lines 462-468
Link Here
|
| 462 |
delete [] running; |
476 |
delete [] running; |
| 463 |
|
477 |
|
| 464 |
//080714 |
478 |
//080714 |
| 465 |
if( adjustResult ) fCache.Get()->remaining_energy -= fsEnergy; |
479 |
// SM 30 March 2022 |
|
|
480 |
// the remaining energy needs to be lowered by the photon |
| 481 |
// energy in *any* case. Otherwise additional photons with |
| 482 |
// too high energy will be produced - therefore the |
| 483 |
// adjustResult condition has been removed |
| 484 |
// |
| 485 |
//if( adjustResult ) fCache.Get()->remaining_energy -= fsEnergy; |
| 486 |
if( std::getenv("G4PHPTEST") ) G4cout << " G4ParticleHPContAngularPar::Sample 2nd remaining_energy - fsEnergy " << fCache.Get()->remaining_energy << " - " << fsEnergy << G4endl; |
| 487 |
fCache.Get()->remaining_energy -= fsEnergy; |
| 466 |
//080714 |
488 |
//080714 |
| 467 |
} |
489 |
} |
| 468 |
} |
490 |
} |
|
Lines 697-710
Link Here
|
| 697 |
|
719 |
|
| 698 |
#define MERGE_NEW |
720 |
#define MERGE_NEW |
| 699 |
|
721 |
|
| 700 |
void G4ParticleHPContAngularPar::PrepareTableInterpolation(const G4ParticleHPContAngularPar* angParPrev) |
722 |
void G4ParticleHPContAngularPar::PrepareTableInterpolation() // SM 26 Apr 2022 const G4ParticleHPContAngularPar* angParPrev) |
| 701 |
{ |
723 |
{ |
| 702 |
|
724 |
|
| 703 |
//----- Discrete energies: store own energies in a map for faster searching |
725 |
//----- Discrete energies: store own energies in a map for faster searching |
|
|
726 |
/* |
| 727 |
* SM 27 Apr 2022 |
| 728 |
* |
| 729 |
* the data files sometimes have identical discrete energies (likely typos) |
| 730 |
* which would lead to overwriting the already existing index and hence |
| 731 |
* creating a hole in the lookup table. |
| 732 |
* No attempt is made here to correct for the energies - rather an epsilon |
| 733 |
* is subtracted from the energy in order to uniquely identify the line |
| 734 |
*/ |
| 704 |
G4int ie; |
735 |
G4int ie; |
| 705 |
for(ie=0; ie<nDiscreteEnergies; ie++) { |
736 |
for(ie=0; ie<nDiscreteEnergies; ie++) { |
| 706 |
theDiscreteEnergiesOwn[theAngular[ie].GetLabel()] = ie; |
737 |
// check if energy is already present and subtract epsilon if that's the case |
|
|
738 |
double myE = theAngular[ie].GetLabel(); |
| 739 |
while ( theDiscreteEnergiesOwn.find(myE) != theDiscreteEnergiesOwn.end() ) { |
| 740 |
myE -= 1e-6; |
| 741 |
} |
| 742 |
theDiscreteEnergiesOwn[myE] = ie; |
| 707 |
} |
743 |
} |
|
|
744 |
/* |
| 745 |
* SM 26 Apr 2022 |
| 746 |
* |
| 747 |
* the approach here makes no sense. It would work only for two sets that |
| 748 |
* have identical min and max energy. If the 2 sets differ in min, max or |
| 749 |
* both, the energy inserted would be normalized to its original set but |
| 750 |
* interpreted with the new - which is not correct. |
| 751 |
* |
| 752 |
* Disable the code for now and simply return ... |
| 753 |
*/ |
| 754 |
|
| 755 |
return; |
| 756 |
|
| 757 |
/* SM 26 Apr 2022 |
| 758 |
* |
| 759 |
|
| 708 |
if( !angParPrev ) return; |
760 |
if( !angParPrev ) return; |
| 709 |
|
761 |
|
| 710 |
//----- Discrete energies: use energies that appear in one or another |
762 |
//----- Discrete energies: use energies that appear in one or another |
|
Lines 721-727
Link Here
|
| 721 |
G4double ener = theAngular[ie].GetLabel(); |
773 |
G4double ener = theAngular[ie].GetLabel(); |
| 722 |
G4double enerT = (ener-theMinEner)/(theMaxEner-theMinEner); |
774 |
G4double enerT = (ener-theMinEner)/(theMaxEner-theMinEner); |
| 723 |
theEnergiesTransformed.insert(enerT); |
775 |
theEnergiesTransformed.insert(enerT); |
| 724 |
//- if( getenv("G4PHPTEST2") ) G4cout <<this << " G4ParticleHPContAngularPar::PrepareTableInterpolation theEnergiesTransformed1 " << enerT << G4endl; //GDEB |
776 |
if( getenv("G4PHPTEST2") ) G4cout <<this << " G4ParticleHPContAngularPar::PrepareTableInterpolation theEnergiesTransformed1 " << enerT << G4endl; //GDEB |
| 725 |
} |
777 |
} |
| 726 |
G4int nEnergiesPrev = angParPrev->GetNEnergies(); |
778 |
G4int nEnergiesPrev = angParPrev->GetNEnergies(); |
| 727 |
G4double minEnerPrev = angParPrev->GetMinEner(); |
779 |
G4double minEnerPrev = angParPrev->GetMinEner(); |
|
Lines 730-740
Link Here
|
| 730 |
G4double ener = angParPrev->theAngular[ie].GetLabel(); |
782 |
G4double ener = angParPrev->theAngular[ie].GetLabel(); |
| 731 |
G4double enerT = (ener-minEnerPrev)/(maxEnerPrev-minEnerPrev); |
783 |
G4double enerT = (ener-minEnerPrev)/(maxEnerPrev-minEnerPrev); |
| 732 |
theEnergiesTransformed.insert(enerT); |
784 |
theEnergiesTransformed.insert(enerT); |
| 733 |
//- if( getenv("G4PHPTEST2") ) G4cout << this << " G4ParticleHPContAngularPar::PrepareTableInterpolation theEnergiesTransformed2 " << enerT << G4endl; //GDEB |
785 |
if( getenv("G4PHPTEST2") ) G4cout << this << " G4ParticleHPContAngularPar::PrepareTableInterpolation theEnergiesTransformed2 " << enerT << G4endl; //GDEB |
| 734 |
} |
786 |
} |
| 735 |
// add the maximum energy |
787 |
// add the maximum energy |
| 736 |
theEnergiesTransformed.insert(1.); |
788 |
//theEnergiesTransformed.insert(1.); |
| 737 |
|
789 |
|
|
|
790 |
* |
| 791 |
*/ // SM 26 Apr 2022 |
| 738 |
} |
792 |
} |
| 739 |
|
793 |
|
| 740 |
void G4ParticleHPContAngularPar::BuildByInterpolation(G4double anEnergy, G4InterpolationScheme aScheme, |
794 |
void G4ParticleHPContAngularPar::BuildByInterpolation(G4double anEnergy, G4InterpolationScheme aScheme, |
|
Lines 742-825
Link Here
|
| 742 |
G4ParticleHPContAngularPar & angpar2) |
796 |
G4ParticleHPContAngularPar & angpar2) |
| 743 |
{ |
797 |
{ |
| 744 |
G4int ie,ie1,ie2, ie1Prev, ie2Prev; |
798 |
G4int ie,ie1,ie2, ie1Prev, ie2Prev; |
| 745 |
nAngularParameters = angpar1.nAngularParameters; |
799 |
// SM 12.Feb 2022 |
| 746 |
theManager = angpar1.theManager; |
800 |
// |
|
|
801 |
// only re-build the interpolation table if we have a new interaction. For several subsequent |
| 802 |
// samplings of final state particles in the same interaction we should use the existing table. |
| 803 |
if ( fCache.Get()->fresh != true ) return; |
| 804 |
|
| 805 |
// SM 10. Apr 2022 |
| 806 |
// |
| 807 |
// make copies of angpar1 and angpar2. Since these are given by reference it can not |
| 808 |
// be excluded that one of them is this. Hence this code uses potentially the old this |
| 809 |
// for creating the new this - which leads to memory corruption if the old is not stored |
| 810 |
// as separarte object for lookup |
| 811 |
const G4ParticleHPContAngularPar copyAngpar1(angpar1),copyAngpar2(angpar2); |
| 812 |
|
| 813 |
nAngularParameters = copyAngpar1.nAngularParameters; |
| 814 |
theManager = copyAngpar1.theManager; |
| 747 |
theEnergy = anEnergy; |
815 |
theEnergy = anEnergy; |
| 748 |
|
816 |
theMinEner = DBL_MAX; // SM 27 Apr 2022 min and max will be re-calculated after interpolation |
| 749 |
nDiscreteEnergies = theDiscreteEnergies.size(); |
817 |
theMaxEner = -DBL_MAX; |
| 750 |
std::set<G4double>::const_iterator itede; |
818 |
// SM 11. Feb 2022 |
| 751 |
std::map<G4double,G4int> discEnerOwn1 = angpar1.GetDiscreteEnergiesOwn(); |
819 |
// |
| 752 |
std::map<G4double,G4int> discEnerOwn2 = angpar2.GetDiscreteEnergiesOwn(); |
820 |
// re-wrote most of this. The two discrete sets have to be merged. A vector holds the temporary |
| 753 |
std::map<G4double,G4int>::const_iterator itedeo; |
821 |
// data to be copied to the array in the end. Since the G4ParticleHPList class contains pointers |
| 754 |
ie = 0; |
822 |
// one can not simply assign elements of this type. Each member needs to call the explicit Set() |
| 755 |
for( itede = theDiscreteEnergies.begin(); itede != theDiscreteEnergies.end(); itede++, ie++ ) { |
823 |
// method instead. |
| 756 |
G4double discEner = *itede; |
824 |
// |
| 757 |
itedeo = discEnerOwn1.find(discEner); |
825 |
// First average probabilities for those lines that are in both sets |
| 758 |
if( itedeo == discEnerOwn1.end() ) { |
826 |
const std::map<G4double,G4int> discEnerOwn1 = copyAngpar1.GetDiscreteEnergiesOwn(); |
| 759 |
ie1 = 0; |
827 |
const std::map<G4double,G4int> discEnerOwn2 = copyAngpar2.GetDiscreteEnergiesOwn(); |
| 760 |
} else { |
828 |
std::map<G4double,G4int>::const_iterator itedeo1; |
| 761 |
ie1 = -1; |
829 |
std::map<G4double,G4int>::const_iterator itedeo2; |
|
|
830 |
std::vector<G4ParticleHPList *> vAngular(discEnerOwn1.size()); |
| 831 |
for( itedeo1 = discEnerOwn1.begin(); itedeo1 != discEnerOwn1.end(); ++itedeo1) { |
| 832 |
G4double discEner = itedeo1->first; |
| 833 |
if ( discEner < theMinEner ) { |
| 834 |
theMinEner = discEner; |
| 762 |
} |
835 |
} |
| 763 |
itedeo = discEnerOwn2.find(discEner); |
836 |
if ( discEner > theMaxEner ) { |
| 764 |
if( itedeo == discEnerOwn2.end() ) { |
837 |
theMaxEner = discEner; |
| 765 |
ie2 = 0; |
838 |
} |
| 766 |
} else { |
839 |
ie1 = itedeo1->second; |
|
|
840 |
itedeo2 = discEnerOwn2.find(discEner); |
| 841 |
if( itedeo2 == discEnerOwn2.end() ) { |
| 767 |
ie2 = -1; |
842 |
ie2 = -1; |
|
|
843 |
} else { |
| 844 |
ie2 = itedeo2->second; |
| 768 |
} |
845 |
} |
| 769 |
|
846 |
vAngular[ie1] = new G4ParticleHPList(); |
| 770 |
theAngular[ie].SetLabel(discEner); |
847 |
vAngular[ie1]->SetLabel(copyAngpar1.theAngular[ie1].GetLabel()); |
| 771 |
G4double val1, val2; |
848 |
G4double val1, val2; |
| 772 |
for(G4int ip=0; ip<nAngularParameters; ip++) { |
849 |
for(G4int ip=0; ip<nAngularParameters; ++ip) { |
| 773 |
if( ie1 != -1 ) { |
850 |
val1 = copyAngpar1.theAngular[ie1].GetValue(ip); |
| 774 |
val1 = angpar1.theAngular[ie1].GetValue(ip); |
|
|
| 775 |
} else { |
| 776 |
val1 = 0.; |
| 777 |
} |
| 778 |
if( ie2 != -1 ) { |
851 |
if( ie2 != -1 ) { |
| 779 |
val2 = angpar2.theAngular[ie2].GetValue(ip); |
852 |
val2 = copyAngpar2.theAngular[ie2].GetValue(ip); |
| 780 |
} else { |
853 |
} else { |
| 781 |
val2 = 0.; |
854 |
val2 = 0.; |
| 782 |
} |
855 |
} |
|
|
856 |
G4double value = theInt.Interpolate(aScheme, anEnergy, |
| 857 |
copyAngpar1.theEnergy, copyAngpar2.theEnergy, |
| 858 |
val1, |
| 859 |
val2); |
| 860 |
if( std::getenv("G4PHPTEST2") ) G4cout << ie1 << " " << ip << " G4ParticleHPContAngularPar::Merge DiscreteEnergies val1 " << val1 << " val2 " << val2 << " value " << value << G4endl; //GDEB |
| 783 |
|
861 |
|
|
|
862 |
vAngular[ie1]->SetValue(ip, value); |
| 863 |
} |
| 864 |
} |
| 865 |
// add the ones in set2 but not in set1 |
| 866 |
std::vector<G4ParticleHPList *>::iterator itv; |
| 867 |
for( itedeo2 = discEnerOwn2.begin(); itedeo2 != discEnerOwn2.end(); ++itedeo2) { |
| 868 |
G4double discEner = itedeo2->first; |
| 869 |
ie2=itedeo2->second; |
| 870 |
bool notFound = true; |
| 871 |
int iiv=0; |
| 872 |
for(itv = vAngular.begin(); itv != vAngular.end(); ++itv,++iiv) { |
| 873 |
if ( discEner == (*itv)->GetLabel() ) { |
| 874 |
notFound = false; |
| 875 |
break; |
| 876 |
} |
| 877 |
} |
| 878 |
if( notFound ) { |
| 879 |
// not yet in list |
| 880 |
if ( discEner < theMinEner ) { |
| 881 |
theMinEner = discEner; |
| 882 |
} |
| 883 |
if ( discEner > theMaxEner ) { |
| 884 |
theMaxEner = discEner; |
| 885 |
} |
| 886 |
// find position to insert |
| 887 |
bool isInserted=false; |
| 888 |
ie=0; |
| 889 |
for(itv=vAngular.begin();itv!=vAngular.end();++itv,++ie) { |
| 890 |
if ( discEner > (*itv)->GetLabel() ) { |
| 891 |
itv=vAngular.insert(itv,new G4ParticleHPList); |
| 892 |
(*itv)->SetLabel(copyAngpar2.theAngular[ie2].GetLabel()); |
| 893 |
isInserted=true; |
| 894 |
break; |
| 895 |
} |
| 896 |
} |
| 897 |
if (!isInserted) { |
| 898 |
ie=vAngular.size(); |
| 899 |
vAngular.push_back(new G4ParticleHPList); |
| 900 |
vAngular[ie]->SetLabel(copyAngpar2.theAngular[ie2].GetLabel()); |
| 901 |
isInserted=true; |
| 902 |
} |
| 903 |
G4double val1, val2; |
| 904 |
for(G4int ip=0; ip<nAngularParameters; ++ip) { |
| 905 |
val1 = 0; |
| 906 |
val2 = copyAngpar2.theAngular[ie2].GetValue(ip); |
| 784 |
G4double value = theInt.Interpolate(aScheme, anEnergy, |
907 |
G4double value = theInt.Interpolate(aScheme, anEnergy, |
| 785 |
angpar1.theEnergy, angpar2.theEnergy, |
908 |
copyAngpar1.theEnergy, copyAngpar2.theEnergy, |
| 786 |
val1, |
909 |
val1, |
| 787 |
val2); |
910 |
val2); |
| 788 |
if( std::getenv("G4PHPTEST2") ) G4cout << ie << " " << ip << " G4ParticleHPContAngularPar::Merge DiscreteEnergies val1 " << val1 << " val2 " << val2 << " value " << value << G4endl; //GDEB |
911 |
if( std::getenv("G4PHPTEST2") ) G4cout << ie << " " << ip << " G4ParticleHPContAngularPar::Merge DiscreteEnergies val1 " << val1 << " val2 " << val2 << " value " << value << G4endl; //GDEB |
| 789 |
|
912 |
|
| 790 |
theAngular[ie].SetValue(ip, value); |
913 |
vAngular[ie]->SetValue(ip, value); |
|
|
914 |
} |
| 791 |
} |
915 |
} |
| 792 |
} |
916 |
} |
| 793 |
|
917 |
|
|
|
918 |
// store new discrete list |
| 919 |
nDiscreteEnergies = vAngular.size(); |
| 794 |
if(theAngular != 0) delete [] theAngular; |
920 |
if(theAngular != 0) delete [] theAngular; |
| 795 |
nEnergies = nDiscreteEnergies + angpar2.GetNEnergiesTransformed(); |
921 |
theAngular = 0; |
| 796 |
theAngular = new G4ParticleHPList [nEnergies]; |
922 |
if ( nDiscreteEnergies > 0 ) { |
|
|
923 |
theAngular = new G4ParticleHPList [nDiscreteEnergies]; |
| 924 |
} |
| 925 |
theDiscreteEnergiesOwn.clear(); |
| 926 |
theDiscreteEnergies.clear(); |
| 927 |
for(ie=0; ie<nDiscreteEnergies; ++ie) { |
| 928 |
theAngular[ie].SetLabel(vAngular[ie]->GetLabel()); |
| 929 |
for(int ip=0; ip<nAngularParameters; ++ip) { |
| 930 |
theAngular[ie].SetValue(ip,vAngular[ie]->GetValue(ip)); |
| 931 |
} |
| 932 |
theDiscreteEnergiesOwn[theAngular[ie].GetLabel()] = ie; |
| 933 |
theDiscreteEnergies.insert(theAngular[ie].GetLabel()); |
| 934 |
} |
| 935 |
|
| 936 |
/* |
| 937 |
* SM 26 Apr 2022 |
| 938 |
* |
| 939 |
* the continuous energies need to be made from scratch like the discrete |
| 940 |
* ones. Therefore the re-assignemnt of theAngular needs to be done |
| 941 |
* after the continuous energy set is also finalized. Only then the |
| 942 |
* total number of nEnergies is known and the array can be allocated. |
| 943 |
* |
| 944 |
* Hence the code here is commented out. |
| 945 |
|
| 946 |
nEnergies = nDiscreteEnergies + copyAngpar2.GetNEnergiesTransformed(); |
| 947 |
if ( nEnergies > nDiscreteEnergies ) { |
| 948 |
G4ParticleHPList * theNewAngular = new G4ParticleHPList [nEnergies]; |
| 949 |
if (theAngular !=0 ) { |
| 950 |
for(ie=0; ie<nDiscreteEnergies; ++ie) { |
| 951 |
theNewAngular[ie].SetLabel(theAngular[ie].GetLabel()); |
| 952 |
for(int ip=0; ip<nAngularParameters; ++ip) { |
| 953 |
theNewAngular[ie].SetValue(ip,theAngular[ie].GetValue(ip)); |
| 954 |
} |
| 955 |
} |
| 956 |
delete [] theAngular; |
| 957 |
} |
| 958 |
theAngular = theNewAngular; |
| 959 |
} |
| 960 |
|
| 961 |
* |
| 962 |
*/ // SM 26 Apr 2022 |
| 797 |
|
963 |
|
| 798 |
//---- Get minimum and maximum energy interpolating |
964 |
//---- Get minimum and maximum energy interpolating |
| 799 |
theMinEner = angpar1.GetMinEner() + (theEnergy-angpar1.GetEnergy()) * (angpar2.GetMinEner()-angpar1.GetMinEner())/(angpar2.GetEnergy()-angpar1.GetEnergy()); |
965 |
// SM 27 Apr 2022 don't use theMinEner or theMaxEner here, since the transformed |
| 800 |
theMaxEner = angpar1.GetMaxEner() + (theEnergy-angpar1.GetEnergy()) * (angpar2.GetMaxEner()-angpar1.GetMaxEner())/(angpar2.GetEnergy()-angpar1.GetEnergy()); |
966 |
// energies need the interpolated range from the original Angpar |
|
|
967 |
G4double interMinEner = copyAngpar1.GetMinEner() + (theEnergy-copyAngpar1.GetEnergy()) * (copyAngpar2.GetMinEner()-copyAngpar1.GetMinEner())/(copyAngpar2.GetEnergy()-copyAngpar1.GetEnergy()); |
| 968 |
G4double interMaxEner = copyAngpar1.GetMaxEner() + (theEnergy-copyAngpar1.GetEnergy()) * (copyAngpar2.GetMaxEner()-copyAngpar1.GetMaxEner())/(copyAngpar2.GetEnergy()-copyAngpar1.GetEnergy()); |
| 801 |
|
969 |
|
| 802 |
if( std::getenv("G4PHPTEST2") ) G4cout << " G4ParticleHPContAngularPar::Merge E " << anEnergy << " minmax " << theMinEner << " " << theMaxEner << G4endl; //GDEB |
970 |
if( std::getenv("G4PHPTEST2") ) G4cout << " G4ParticleHPContAngularPar::Merge E " << anEnergy << " minmax " << interMinEner << " " << interMaxEner << G4endl; //GDEB |
| 803 |
|
971 |
|
| 804 |
//--- Loop to energies of new set |
972 |
//--- Loop to energies of new set |
| 805 |
std::set<G4double> energiesTransformed = angpar2.GetEnergiesTransformed(); |
973 |
//SM 26 Apr 2022 std::set<G4double> energiesTransformed = copyAngpar2.GetEnergiesTransformed(); |
| 806 |
std::set<G4double>::const_iterator iteet = energiesTransformed.begin(); |
974 |
//SM 26 Apr 2022 std::set<G4double>::const_iterator iteet = energiesTransformed.begin(); |
| 807 |
G4int nEnergies1 = angpar1.GetNEnergies(); |
975 |
theEnergiesTransformed.clear(); |
| 808 |
G4int nDiscreteEnergies1 = angpar1.GetNDiscreteEnergies(); |
976 |
|
| 809 |
G4double minEner1 = angpar1.GetMinEner(); |
977 |
G4int nEnergies1 = copyAngpar1.GetNEnergies(); |
| 810 |
G4double maxEner1 = angpar1.GetMaxEner(); |
978 |
G4int nDiscreteEnergies1 = copyAngpar1.GetNDiscreteEnergies(); |
| 811 |
G4int nEnergies2 = angpar2.GetNEnergies(); |
979 |
G4double minEner1 = copyAngpar1.GetMinEner(); |
| 812 |
G4int nDiscreteEnergies2 = angpar2.GetNDiscreteEnergies(); |
980 |
G4double maxEner1 = copyAngpar1.GetMaxEner(); |
| 813 |
G4double minEner2 = angpar2.GetMinEner(); |
981 |
G4int nEnergies2 = copyAngpar2.GetNEnergies(); |
| 814 |
G4double maxEner2 = angpar2.GetMaxEner(); |
982 |
G4int nDiscreteEnergies2 = copyAngpar2.GetNDiscreteEnergies(); |
| 815 |
for(ie=nDiscreteEnergies; ie<nEnergies; ie++,iteet++) { |
983 |
G4double minEner2 = copyAngpar2.GetMinEner(); |
|
|
984 |
G4double maxEner2 = copyAngpar2.GetMaxEner(); |
| 985 |
|
| 986 |
// SM 26 Apr 2022: first build the list of transformed energies normalized |
| 987 |
// to the new min max by assuming that the min-max range of |
| 988 |
// each set would be scalable to the new, interpolated min |
| 989 |
// max range |
| 990 |
|
| 991 |
for(ie1=nDiscreteEnergies1; ie1<nEnergies1; ++ie1) { |
| 992 |
G4double e1 = copyAngpar1.theAngular[ie1].GetLabel(); |
| 993 |
G4double eT = (e1-minEner1); |
| 994 |
if ( maxEner1 != minEner1) { |
| 995 |
eT /= (maxEner1-minEner1); |
| 996 |
} |
| 997 |
if ( eT >= 0 && eT <= 1 ) { |
| 998 |
theEnergiesTransformed.insert(eT); |
| 999 |
} |
| 1000 |
} |
| 1001 |
for(ie2=nDiscreteEnergies2; ie2<nEnergies2; ++ie2) { |
| 1002 |
G4double e2 = copyAngpar2.theAngular[ie2].GetLabel(); |
| 1003 |
G4double eT = (e2-minEner2); |
| 1004 |
if ( maxEner2 != minEner2) { |
| 1005 |
eT /= (maxEner2-minEner2); |
| 1006 |
} |
| 1007 |
if ( eT >= 0 && eT <= 1 ) { |
| 1008 |
theEnergiesTransformed.insert(eT); |
| 1009 |
} |
| 1010 |
} |
| 1011 |
|
| 1012 |
// now the list of energies is complete |
| 1013 |
|
| 1014 |
nEnergies = nDiscreteEnergies+theEnergiesTransformed.size(); |
| 1015 |
|
| 1016 |
// create final array of angular parameters |
| 1017 |
|
| 1018 |
G4ParticleHPList * theNewAngular = new G4ParticleHPList [nEnergies]; |
| 1019 |
|
| 1020 |
// copy the discrete energies and interpolated parameters to new array |
| 1021 |
|
| 1022 |
if (theAngular !=0 ) { |
| 1023 |
for(ie=0; ie<nDiscreteEnergies; ++ie) { |
| 1024 |
theNewAngular[ie].SetLabel(theAngular[ie].GetLabel()); |
| 1025 |
for(int ip=0; ip<nAngularParameters; ++ip) { |
| 1026 |
theNewAngular[ie].SetValue(ip,theAngular[ie].GetValue(ip)); |
| 1027 |
} |
| 1028 |
} |
| 1029 |
delete [] theAngular; |
| 1030 |
} |
| 1031 |
theAngular = theNewAngular; |
| 1032 |
|
| 1033 |
// interpolate the continuous energies for new array |
| 1034 |
std::set<G4double>::const_iterator iteet = theEnergiesTransformed.begin(); |
| 1035 |
|
| 1036 |
for(ie=nDiscreteEnergies; ie<nEnergies; ++ie,++iteet) { |
| 816 |
G4double eT = (*iteet); |
1037 |
G4double eT = (*iteet); |
| 817 |
|
1038 |
|
| 818 |
//--- Use eT1 = eT: Get energy and parameters of angpar1 for this eT |
1039 |
//--- Use eT1 = eT: Get energy and parameters of copyAngpar1 for this eT |
| 819 |
G4double e1 = (maxEner1-minEner1) * eT + minEner1; |
1040 |
G4double e1 = (maxEner1-minEner1) * eT + minEner1; |
| 820 |
//----- Get parameter value corresponding to this e1 |
1041 |
//----- Get parameter value corresponding to this e1 |
| 821 |
for(ie1=nDiscreteEnergies1; ie1<nEnergies1; ie1++) { |
1042 |
for(ie1=nDiscreteEnergies1; ie1<nEnergies1; ++ie1) { |
| 822 |
if( (angpar1.theAngular[ie1].GetLabel() - e1) > 1.E-10*e1 ) break; |
1043 |
if( (copyAngpar1.theAngular[ie1].GetLabel() - e1) > 1.E-10*e1 ) break; |
| 823 |
} |
1044 |
} |
| 824 |
ie1Prev = ie1 - 1; |
1045 |
ie1Prev = ie1 - 1; |
| 825 |
if( ie1 == 0 ) ie1Prev++; |
1046 |
if( ie1 == 0 ) ie1Prev++; |
|
Lines 827-838
Link Here
|
| 827 |
ie1--; |
1048 |
ie1--; |
| 828 |
ie1Prev = ie1; |
1049 |
ie1Prev = ie1; |
| 829 |
} |
1050 |
} |
| 830 |
//--- Use eT2 = eT: Get energy and parameters of angpar2 for this eT |
1051 |
//--- Use eT2 = eT: Get energy and parameters of copyAngpar2 for this eT |
| 831 |
G4double e2 = (maxEner2-minEner2) * eT + minEner2; |
1052 |
G4double e2 = (maxEner2-minEner2) * eT + minEner2; |
| 832 |
//----- Get parameter value corresponding to this e2 |
1053 |
//----- Get parameter value corresponding to this e2 |
| 833 |
for(ie2=nDiscreteEnergies2; ie2<nEnergies2; ie2++) { |
1054 |
for(ie2=nDiscreteEnergies2; ie2<nEnergies2; ++ie2) { |
| 834 |
// G4cout << " GET IE2 " << ie2 << " - " << angpar2.theAngular[ie2].GetLabel() - e2 << " " << angpar2.theAngular[ie2].GetLabel() << " " << e2 <<G4endl; |
1055 |
// G4cout << " GET IE2 " << ie2 << " - " << copyAngpar2.theAngular[ie2].GetLabel() - e2 << " " << copyAngpar2.theAngular[ie2].GetLabel() << " " << e2 <<G4endl; |
| 835 |
if( (angpar2.theAngular[ie2].GetLabel() - e2) > 1.E-10*e2 ) break; |
1056 |
if( (copyAngpar2.theAngular[ie2].GetLabel() - e2) > 1.E-10*e2 ) break; |
| 836 |
} |
1057 |
} |
| 837 |
ie2Prev = ie2 - 1; |
1058 |
ie2Prev = ie2 - 1; |
| 838 |
if( ie2 == 0 ) ie2Prev++; |
1059 |
if( ie2 == 0 ) ie2Prev++; |
|
Lines 842-896
Link Here
|
| 842 |
} |
1063 |
} |
| 843 |
|
1064 |
|
| 844 |
//---- Energy corresponding to energy transformed |
1065 |
//---- Energy corresponding to energy transformed |
| 845 |
G4double eN = (theMaxEner-theMinEner) * eT + theMinEner; |
1066 |
G4double eN = (interMaxEner-interMinEner) * eT + interMinEner; |
| 846 |
if( std::getenv("G4PHPTEST2") ) G4cout << ie << " " << ie1 << " " << ie2 << " G4ParticleHPContAngularPar::loop eT " << eT << " -> eN " << eN << " e1 " << e1 << " e2 " << e2 << G4endl; //GDEB |
1067 |
if( std::getenv("G4PHPTEST2") ) G4cout << ie << " " << ie1 << " " << ie2 << " G4ParticleHPContAngularPar::loop eT " << eT << " -> eN " << eN << " e1 " << e1 << " e2 " << e2 << G4endl; //GDEB |
| 847 |
|
1068 |
|
| 848 |
theAngular[ie].SetLabel(eN); |
1069 |
theAngular[ie].SetLabel(eN); |
|
|
1070 |
if ( eN < theMinEner ) { |
| 1071 |
theMinEner = eN; |
| 1072 |
} |
| 1073 |
if ( eN > theMaxEner ) { |
| 1074 |
theMaxEner = eN; |
| 1075 |
} |
| 849 |
|
1076 |
|
| 850 |
for(G4int ip=0; ip<nAngularParameters; ip++) { |
1077 |
for(G4int ip=0; ip<nAngularParameters; ++ip) { |
| 851 |
G4double val1 = theInt.Interpolate2(theManager.GetScheme(ie), |
1078 |
G4double val1 = theInt.Interpolate2(theManager.GetScheme(ie), |
| 852 |
e1, |
1079 |
e1, |
| 853 |
angpar1.theAngular[ie1Prev].GetLabel(), |
1080 |
copyAngpar1.theAngular[ie1Prev].GetLabel(), |
| 854 |
angpar1.theAngular[ie1].GetLabel(), |
1081 |
copyAngpar1.theAngular[ie1].GetLabel(), |
| 855 |
angpar1.theAngular[ie1Prev].GetValue(ip), |
1082 |
copyAngpar1.theAngular[ie1Prev].GetValue(ip), |
| 856 |
angpar1.theAngular[ie1].GetValue(ip)) * (maxEner1-minEner1); |
1083 |
copyAngpar1.theAngular[ie1].GetValue(ip)) * (maxEner1-minEner1); |
| 857 |
G4double val2 = theInt.Interpolate2(theManager.GetScheme(ie), |
1084 |
G4double val2 = theInt.Interpolate2(theManager.GetScheme(ie), |
| 858 |
e2, |
1085 |
e2, |
| 859 |
angpar2.theAngular[ie2Prev].GetLabel(), |
1086 |
copyAngpar2.theAngular[ie2Prev].GetLabel(), |
| 860 |
angpar2.theAngular[ie2].GetLabel(), |
1087 |
copyAngpar2.theAngular[ie2].GetLabel(), |
| 861 |
angpar2.theAngular[ie2Prev].GetValue(ip), |
1088 |
copyAngpar2.theAngular[ie2Prev].GetValue(ip), |
| 862 |
angpar2.theAngular[ie2].GetValue(ip)) * (maxEner2-minEner2); |
1089 |
copyAngpar2.theAngular[ie2].GetValue(ip)) * (maxEner2-minEner2); |
| 863 |
|
1090 |
|
| 864 |
G4double value = theInt.Interpolate(aScheme, anEnergy, |
1091 |
G4double value = theInt.Interpolate(aScheme, anEnergy, |
| 865 |
angpar1.theEnergy, angpar2.theEnergy, |
1092 |
copyAngpar1.theEnergy, copyAngpar2.theEnergy, |
| 866 |
val1, |
1093 |
val1, |
| 867 |
val2); |
1094 |
val2); |
| 868 |
//value /= (theMaxEner-theMinEner); |
1095 |
//value /= (interMaxEner-interMinEner); |
| 869 |
if ( theMaxEner != theMinEner ) { |
1096 |
if ( interMaxEner != interMinEner ) { |
| 870 |
value /= (theMaxEner-theMinEner); |
1097 |
value /= (interMaxEner-interMinEner); |
| 871 |
} else if ( value != 0 ) { |
1098 |
} else if ( value != 0 ) { |
| 872 |
throw G4HadronicException(__FILE__, __LINE__, "G4ParticleHPContAngularPar::PrepareTableInterpolation theMaxEner == theMinEner and value != 0."); |
1099 |
throw G4HadronicException(__FILE__, __LINE__, "G4ParticleHPContAngularPar::PrepareTableInterpolation interMaxEner == interMinEner and value != 0."); |
| 873 |
} |
1100 |
} |
| 874 |
if( std::getenv("G4PHPTEST2") ) G4cout << ie << " " << ip << " G4ParticleHPContAngularPar::Merge val1 " << val1 << " val2 " << val2 << " value " << value << G4endl; //GDEB |
1101 |
if( std::getenv("G4PHPTEST2") ) G4cout << ie << " " << ip << " G4ParticleHPContAngularPar::Merge val1 " << val1 << " val2 " << val2 << " value " << value << G4endl; //GDEB |
| 875 |
//- val1 = angpar1.theAngular[ie1-1].GetValue(ip) * (maxEner1-minEner1); |
1102 |
//- val1 = copyAngpar1.theAngular[ie1-1].GetValue(ip) * (maxEner1-minEner1); |
| 876 |
//- val2 = angpar2.theAngular[ie2-1].GetValue(ip) * (maxEner2-minEner2); |
1103 |
//- val2 = copyAngpar2.theAngular[ie2-1].GetValue(ip) * (maxEner2-minEner2); |
| 877 |
//- if( getenv("G4PHPTEST2") ) G4cout << ie << " " << ip << " G4ParticleHPContAngularPar::MergeOLD val1 " << val1 << " val2 " << val2 << " value " << value << G4endl; //GDEB |
1104 |
//- if( getenv("G4PHPTEST2") ) G4cout << ie << " " << ip << " G4ParticleHPContAngularPar::MergeOLD val1 " << val1 << " val2 " << val2 << " value " << value << G4endl; //GDEB |
| 878 |
|
1105 |
|
| 879 |
theAngular[ie].SetValue(ip, value); |
1106 |
theAngular[ie].SetValue(ip, value); |
| 880 |
} |
1107 |
} |
| 881 |
} |
1108 |
} |
| 882 |
|
1109 |
|
|
|
1110 |
for(itv = vAngular.begin(); itv != vAngular.end(); ++itv) { |
| 1111 |
delete (*itv); |
| 1112 |
} |
| 1113 |
|
| 883 |
if( std::getenv("G4PHPTEST2") ) { |
1114 |
if( std::getenv("G4PHPTEST2") ) { |
| 884 |
G4cout << " G4ParticleHPContAngularPar::Merge ANGPAR1 " << G4endl; //GDEB |
1115 |
G4cout << " G4ParticleHPContAngularPar::Merge ANGPAR1 " << G4endl; //GDEB |
| 885 |
angpar1.Dump(); |
1116 |
copyAngpar1.Dump(); |
| 886 |
G4cout << " G4ParticleHPContAngularPar::Merge ANGPAR2 " << G4endl; |
1117 |
G4cout << " G4ParticleHPContAngularPar::Merge ANGPAR2 " << G4endl; |
| 887 |
angpar2.Dump(); |
1118 |
copyAngpar2.Dump(); |
| 888 |
G4cout << " G4ParticleHPContAngularPar::Merge ANGPARNEW " << G4endl; |
1119 |
G4cout << " G4ParticleHPContAngularPar::Merge ANGPARNEW " << G4endl; |
| 889 |
Dump(); |
1120 |
Dump(); |
| 890 |
} |
1121 |
} |
| 891 |
} |
1122 |
} |
| 892 |
|
1123 |
|
| 893 |
void G4ParticleHPContAngularPar::Dump() |
1124 |
void G4ParticleHPContAngularPar::Dump() const |
| 894 |
{ |
1125 |
{ |
| 895 |
G4cout << theEnergy << " " << nEnergies << " " << nDiscreteEnergies << " " << nAngularParameters << G4endl; |
1126 |
G4cout << theEnergy << " " << nEnergies << " " << nDiscreteEnergies << " " << nAngularParameters << G4endl; |
| 896 |
|
1127 |
|