55 const G4double G4SandiaTable::funitc[5] =
64 G4int G4SandiaTable::fCumulInterval[] = {0};
71 fMatSandiaMatrix =
nullptr;
72 fMatSandiaMatrixPAI =
nullptr;
73 fPhotoAbsorptionCof =
nullptr;
75 fMatNbOfIntervals = 0;
81 if(0 == fCumulInterval[0]) {
82 fCumulInterval[0] = 1;
90 fSandiaCofPerAtom.resize(4,0.0);
93 ComputeMatSandiaMatrix();
102 : fMaterial(nullptr),fMatSandiaMatrix(nullptr),
103 fMatSandiaMatrixPAI(nullptr),fPhotoAbsorptionCof(nullptr)
106 fMatNbOfIntervals = 0;
109 fSandiaCofPerAtom.resize(4,0.0);
119 delete fMatSandiaMatrix;
121 if(fMatSandiaMatrixPAI)
124 delete fMatSandiaMatrixPAI;
126 if(fPhotoAbsorptionCof)
128 delete [] fPhotoAbsorptionCof;
136 std::vector<G4double>& coeff)
const
139 if(Z < 1 || Z > 100) {
140 Z = PrintErrorZ(Z,
"GetSandiaCofPerAtom");
142 if(4 > coeff.size()) {
143 PrintErrorV(
"GetSandiaCofPerAtom(): input vector is resized");
152 if (energy <= Emin) {
157 row = fCumulInterval[Z-1] + interval;
159 while ((interval>0) && (energy<fSandiaTable[row][0]*CLHEP::keV)) {
161 row = fCumulInterval[Z-1] + interval;
167 coeff[0]=AoverAvo*funitc[1]*fSandiaTable[row][1];
168 coeff[1]=AoverAvo*funitc[2]*fSandiaTable[row][2];
169 coeff[2]=AoverAvo*funitc[3]*fSandiaTable[row][3];
170 coeff[3]=AoverAvo*funitc[4]*fSandiaTable[row][4];
177 std::vector<G4double>& coeff)
const
180 if(4 > coeff.size()) {
181 PrintErrorV(
"GetSandiaCofWater: input vector is resized");
187 i = fH2OlowerInt - 1;
189 if(energy >=
fH2OlowerI1[i][0]*CLHEP::keV) {
break; }
193 coeff[1]=funitc[2]*fH2OlowerI1[i][2];
194 coeff[2]=funitc[3]*fH2OlowerI1[i][3];
195 coeff[3]=funitc[4]*fH2OlowerI1[i][4];
217 if(Z < 1 || Z > 100) {
218 Z = PrintErrorZ(Z,
"GetSandiaCofPerAtom");
232 ed <<
"Atomic number out of range Z= " << Z <<
"; closest value is used";
234 return (Z > 100) ? 100 : 1;
239 void G4SandiaTable::PrintErrorV(
const G4String& ss)
241 G4String sss =
"G4SandiaTable::"+ss;
249 void G4SandiaTable::ComputeMatSandiaMatrix()
258 G4int MaxIntervals = 0;
263 for (elm = 0; elm < NbElm; ++elm)
265 z =
G4lrint((*ElementVector)[elm]->GetZ());
267 else if(z > 100) { z = 100; }
278 for (elm = 0; elm < NbElm; ++elm)
282 for(
G4int row = fCumulInterval[z-1]; row<fCumulInterval[z]; ++row)
300 for (
G4int i1 = 0; i1 < MaxIntervals; ++i1)
305 tmp2[interval2] =
Emin;
309 for (
G4int j1 = 0; j1 < MaxIntervals; ++j1)
311 if (tmp1[j1] <= Emin) { tmp1[j1] =
DBL_MAX; }
321 for (interval = 0; interval < interval2; ++interval)
331 G4double coef, oldsum(0.), newsum(0.);
332 fMatNbOfIntervals = 0;
334 for ( interval = 0; interval < interval2; ++interval)
336 Emin = (*(*fMatSandiaMatrix)[fMatNbOfIntervals])[0] = tmp2[interval];
338 for (
G4int k = 1; k < 5; ++k ) {
339 (*(*fMatSandiaMatrix)[fMatNbOfIntervals])[k] = 0.;
343 for ( elm = 0; elm < NbElm; elm++ )
347 for (
G4int j = 1; j < 5; ++j )
349 coef = NbOfAtomsPerVolume[elm]*fSandiaCofPerAtom[j-1];
350 (*(*fMatSandiaMatrix)[fMatNbOfIntervals])[j] += coef;
351 newsum += std::abs(coef);
356 if (newsum != oldsum) { oldsum = newsum; ++fMatNbOfIntervals;}
364 G4cout<<
"G4SandiaTable::ComputeMatSandiaMatrix(), mat = "
367 for(
G4int i = 0; i < fMatNbOfIntervals; ++i)
382 void G4SandiaTable::ComputeMatSandiaMatrixPAI()
384 G4int MaxIntervals = 0;
385 G4int elm, c, i, j, jj, k, k1, k2, c1, n1, z;
390 std::vector<G4int>
Z(noElm);
392 for ( elm = 0; elm < noElm; elm++ )
394 z =
G4lrint((*ElementVector)[elm]->GetZ());
396 else if(z > 100) { z = 100; }
400 fMaxInterval = MaxIntervals + 2;
404 G4cout<<
"G4SandiaTable::ComputeMatSandiaMatrixPAI: fMaxInterval = "
414 for( c = 0; c < fMaxInterval; ++c )
416 fPhotoAbsorptionCof0[c] = 0.;
417 fPhotoAbsorptionCof1[c] = 0.;
418 fPhotoAbsorptionCof2[c] = 0.;
419 fPhotoAbsorptionCof3[c] = 0.;
420 fPhotoAbsorptionCof4[c] = 0.;
424 for(i = 0; i < noElm; ++i)
433 for( k1 = n1; k1 < n2; k1++ )
435 if( I1 > fSandiaTable[k1][0] )
443 for( c1 = 1; c1 < c; c1++ )
445 if( fPhotoAbsorptionCof0[c1] == I1 )
453 fPhotoAbsorptionCof0[c] = I1;
456 for( k2 = k1; k2 < n2; k2++ )
460 for( c1 = 1; c1 < c; c1++ )
462 if( fPhotoAbsorptionCof0[c1] == fSandiaTable[k2][0] )
470 fPhotoAbsorptionCof0[c] = fSandiaTable[k2][0];
477 for( i = 1; i < c; ++i )
479 for( j = i + 1; j < c; ++j )
481 if( fPhotoAbsorptionCof0[i] > fPhotoAbsorptionCof0[j] )
483 G4double tmp = fPhotoAbsorptionCof0[i];
484 fPhotoAbsorptionCof0[i] = fPhotoAbsorptionCof0[j];
485 fPhotoAbsorptionCof0[j] = tmp;
490 G4cout<<i<<
"\t energy = "<<fPhotoAbsorptionCof0[i]<<
G4endl;
499 for( i = 0; i < noElm; ++i )
503 for( i = 0; i < noElm; ++i )
512 for(k = n1; k < n2; ++k)
517 for(
G4int q = 1; q < fMaxInterval-1; q++)
519 G4double E1 = fPhotoAbsorptionCof0[q];
520 G4double E2 = fPhotoAbsorptionCof0[q+1];
524 G4cout<<
"k = "<<k<<
", q = "<<q<<
", B1 = "<<B1<<
", B2 = "<<B2
525 <<
", E1 = "<<E1<<
", E2 = "<<E2<<
G4endl;
527 if( B1 > E1 || B2 < E2 || E1 < I1 )
531 G4cout<<
"continue for: B1 = "<<B1<<
", B2 = "<<B2<<
", E1 = "
532 <<E1<<
", E2 = "<<E2<<
G4endl;
536 fPhotoAbsorptionCof1[q] += fSandiaTable[k][1]*fractionW[i];
537 fPhotoAbsorptionCof2[q] += fSandiaTable[k][2]*fractionW[i];
538 fPhotoAbsorptionCof3[q] += fSandiaTable[k][3]*fractionW[i];
539 fPhotoAbsorptionCof4[q] += fSandiaTable[k][4]*fractionW[i];
544 fPhotoAbsorptionCof1[fMaxInterval-1] += fSandiaTable[k][1]*fractionW[i];
545 fPhotoAbsorptionCof2[fMaxInterval-1] += fSandiaTable[k][2]*fractionW[i];
546 fPhotoAbsorptionCof3[fMaxInterval-1] += fSandiaTable[k][3]*fractionW[i];
547 fPhotoAbsorptionCof4[fMaxInterval-1] += fSandiaTable[k][4]*fractionW[i];
555 if( fPhotoAbsorptionCof1[c] != 0.0 ||
556 fPhotoAbsorptionCof2[c] != 0.0 ||
557 fPhotoAbsorptionCof3[c] != 0.0 ||
558 fPhotoAbsorptionCof4[c] != 0.0 )
continue;
564 for( jj = 2; jj < fMaxInterval; ++jj )
566 fPhotoAbsorptionCof0[jj-1] = fPhotoAbsorptionCof0[jj];
567 fPhotoAbsorptionCof1[jj-1] = fPhotoAbsorptionCof1[jj];
568 fPhotoAbsorptionCof2[jj-1] = fPhotoAbsorptionCof2[jj];
569 fPhotoAbsorptionCof3[jj-1] = fPhotoAbsorptionCof3[jj];
570 fPhotoAbsorptionCof4[jj-1] = fPhotoAbsorptionCof4[jj];
576 while( c < fMaxInterval - 1 );
578 if( fPhotoAbsorptionCof0[fMaxInterval-1] == 0.0 ) fMaxInterval--;
586 for (i = 0; i < fMaxInterval; ++i)
588 fPhotoAbsorptionCof0[i+1] *= funitc[0];
589 fPhotoAbsorptionCof1[i+1] *= funitc[1]*density;
590 fPhotoAbsorptionCof2[i+1] *= funitc[2]*density;
591 fPhotoAbsorptionCof3[i+1] *= funitc[3]*density;
592 fPhotoAbsorptionCof4[i+1] *= funitc[4]*density;
596 if( fMaterial->
GetName() ==
"G4_WATER")
598 fMaxInterval += fH2OlowerInt;
600 for (i = 0; i < fMaxInterval; ++i)
602 fMatSandiaMatrixPAI->push_back(
new G4DataVector(5,0.) );
604 for (i = 0; i < fH2OlowerInt; ++i)
606 (*(*fMatSandiaMatrixPAI)[i])[0] =
fH2OlowerI1[i][0];
607 (*(*fMatSandiaMatrixPAI)[i])[1] =
fH2OlowerI1[i][1];
608 (*(*fMatSandiaMatrixPAI)[i])[2] =
fH2OlowerI1[i][2];
609 (*(*fMatSandiaMatrixPAI)[i])[3] =
fH2OlowerI1[i][3];
610 (*(*fMatSandiaMatrixPAI)[i])[4] =
fH2OlowerI1[i][4];
612 for (i = fH2OlowerInt; i < fMaxInterval; ++i)
614 (*(*fMatSandiaMatrixPAI)[i])[0] = fPhotoAbsorptionCof0[i+1-fH2OlowerInt];
615 (*(*fMatSandiaMatrixPAI)[i])[1] = fPhotoAbsorptionCof1[i+1-fH2OlowerInt];
616 (*(*fMatSandiaMatrixPAI)[i])[2] = fPhotoAbsorptionCof2[i+1-fH2OlowerInt];
617 (*(*fMatSandiaMatrixPAI)[i])[3] = fPhotoAbsorptionCof3[i+1-fH2OlowerInt];
618 (*(*fMatSandiaMatrixPAI)[i])[4] = fPhotoAbsorptionCof4[i+1-fH2OlowerInt];
624 for (i = 0; i < fMaxInterval; ++i)
626 fMatSandiaMatrixPAI->push_back(
new G4DataVector(5,0.) );
628 for (i = 0; i < fMaxInterval; ++i)
630 (*(*fMatSandiaMatrixPAI)[i])[0] = fPhotoAbsorptionCof0[i+1];
631 (*(*fMatSandiaMatrixPAI)[i])[1] = fPhotoAbsorptionCof1[i+1];
632 (*(*fMatSandiaMatrixPAI)[i])[2] = fPhotoAbsorptionCof2[i+1];
633 (*(*fMatSandiaMatrixPAI)[i])[3] = fPhotoAbsorptionCof3[i+1];
634 (*(*fMatSandiaMatrixPAI)[i])[4] = fPhotoAbsorptionCof4[i+1];
642 G4cout<<
"G4SandiaTable::ComputeMatSandiaMatrixPAI(), mat = "
645 for( i = 0; i < fMaxInterval; ++i)
664 fMatNbOfIntervals = 0;
665 fMatSandiaMatrix = 0;
666 fMatSandiaMatrixPAI = 0;
667 fPhotoAbsorptionCof = 0;
673 fSandiaCofPerAtom.resize(4,0.0);
678 if ( matIndex >= 0 && matIndex < numberOfMat)
680 fMaterial = (*theMaterialTable)[matIndex];
684 G4Exception(
"G4SandiaTable::G4SandiaTable(G4int matIndex)",
"mat401",
694 fMatNbOfIntervals = 0;
695 fMatSandiaMatrix = 0;
696 fMatSandiaMatrixPAI = 0;
697 fPhotoAbsorptionCof = 0;
703 fSandiaCofPerAtom.resize(4,0.0);
711 ComputeMatSandiaMatrixPAI();
723 G4double** G4SandiaTable::GetPointerToCof()
725 if(!fPhotoAbsorptionCof) { ComputeMatTable(); }
726 return fPhotoAbsorptionCof;
731 void G4SandiaTable::SandiaSwap(
G4double** da ,
736 da[i][0] = da[j][0] ;
744 return fPhotoAbsorptionCof[i][j]*funitc[j];
755 for(
G4int i = 1;i < sz; ++i )
757 for(
G4int j = i + 1;j < sz; ++j )
759 if(da[i][0] > da[j][0]) SandiaSwap(da,i,j);
771 G4int c, i, flag = 0, n1 = 1;
781 G4cout<<
"begin sanInt, fMaxInterval = "<<fMaxInterval<<
G4endl;
784 fPhotoAbsorptionCof =
new G4double* [fMaxInterval];
786 for( i = 0; i < fMaxInterval; ++i ) {
787 fPhotoAbsorptionCof[i] =
new G4double[5];
791 for( c = 0; c < fMaxInterval; ++c ) { fPhotoAbsorptionCof[c][0] = 0.; }
795 for( i = 0; i < el; ++i )
804 for( k1 = n1; k1 < n2; k1++ )
806 if( I1 > fSandiaTable[k1][0] )
814 for( c1 = 1; c1 < c; c1++ )
816 if( fPhotoAbsorptionCof[c1][0] == I1 )
824 fPhotoAbsorptionCof[c][0] = I1;
827 for( k2 = k1; k2 < n2; k2++ )
831 for( c1 = 1; c1 < c; c1++ )
833 if( fPhotoAbsorptionCof[c1][0] == fSandiaTable[k2][0] )
841 fPhotoAbsorptionCof[c][0] = fSandiaTable[k2][0];
843 G4cout<<
"sanInt, c = "<<c<<
", E_c = "<<fPhotoAbsorptionCof[c][0]
851 SandiaSort(fPhotoAbsorptionCof,c);
854 G4cout<<
"end SanInt, fMaxInterval = "<<fMaxInterval<<
G4endl;
870 G4int i, j, n1, k, c=1, jj, kk;
873 for( i = 0; i < mi; ++i )
875 for( j = 1; j < 5; ++j ) fPhotoAbsorptionCof[i][j] = 0.;
877 for( i = 0; i < el; ++i )
886 for( k = n1; k < n2; ++k )
888 B1 = fSandiaTable[k][0];
889 B2 = fSandiaTable[k+1][0];
891 for( c = 1; c < mi-1; ++c )
893 E1 = fPhotoAbsorptionCof[c][0];
894 E2 = fPhotoAbsorptionCof[c+1][0];
896 if( B1 > E1 || B2 < E2 || E1 < I1 )
continue;
898 for( j = 1; j < 5; ++j )
900 fPhotoAbsorptionCof[c][j] += fSandiaTable[k][j]*fractionW[i];
903 G4cout<<
"c="<<c<<
"; j="<<j<<
"; fST="<<fSandiaTable[k][j]
904 <<
"; frW="<<fractionW[i]<<
G4endl;
909 for( j = 1; j < 5; ++j )
911 fPhotoAbsorptionCof[mi-1][j] += fSandiaTable[k][j]*fractionW[i];
914 G4cout<<
"mi-1="<<mi-1<<
"; j="<<j<<
"; fST="<<fSandiaTable[k][j]
915 <<
"; frW="<<fractionW[i]<<
G4endl;
925 if( fPhotoAbsorptionCof[c][1] != 0.0 ||
926 fPhotoAbsorptionCof[c][2] != 0.0 ||
927 fPhotoAbsorptionCof[c][3] != 0.0 ||
928 fPhotoAbsorptionCof[c][4] != 0.0 )
continue;
930 for( jj = 2; jj < mi; ++jj )
932 for( kk = 0; kk < 5; ++kk ) {
933 fPhotoAbsorptionCof[jj-1][kk] = fPhotoAbsorptionCof[jj][kk];
942 if( fVerbose > 0 )
G4cout<<
"end SanMix, mi = "<<mi<<
G4endl;
951 return fMatNbOfIntervals;
957 G4SandiaTable::GetSandiaPerAtom(
G4int Z,
G4int interval,
G4int j)
const
960 if(Z < 1 || Z > 100) {
961 Z = PrintErrorZ(Z,
"GetSandiaPerAtom");
964 PrintErrorV(
"GetSandiaPerAtom");
968 PrintErrorV(
"GetSandiaPerAtom");
972 G4int row = fCumulInterval[Z-1] + interval;
986 if(interval<0 || interval>=fMatNbOfIntervals) {
987 PrintErrorV(
"GetSandiaCofForMaterial");
988 interval = (interval<0) ? 0 : fMatNbOfIntervals-1;
991 PrintErrorV(
"GetSandiaCofForMaterial");
995 return ((*(*fMatSandiaMatrix)[interval])[j]);
1004 if (energy > (*(*fMatSandiaMatrix)[0])[0]) {
1005 interval = fMatNbOfIntervals - 1;
1007 while ((interval>0)&&(energy<(*(*fMatSandiaMatrix)[interval])[0]))
1010 return &((*(*fMatSandiaMatrix)[interval])[1]);
1019 if(interval<0 || interval>=fMatNbOfIntervals) {
1020 PrintErrorV(
"GetSandiaCofForMaterial");
1021 interval = (interval<0) ? 0 : fMatNbOfIntervals-1;
1024 PrintErrorV(
"GetSandiaCofForMaterial");
1028 return ((*(*fMatSandiaMatrix)[interval])[j])*funitc[j];
1037 if(interval<0 || interval>=fMaxInterval) {
1038 PrintErrorV(
"GetSandiaCofForMaterialPAI");
1039 interval = (interval<0) ? 0 : fMaxInterval-1;
1042 PrintErrorV(
"GetSandiaCofForMaterialPAI");
1046 return ((*(*fMatSandiaMatrixPAI)[interval])[j]);
1054 void G4SandiaTable::ComputeMatTable()
1056 G4int MaxIntervals = 0;
1057 G4int elm, c, i, j, jj, k, kk, k1, k2, c1, n1;
1063 for (elm = 0; elm<noElm; ++elm)
1065 Z[elm] = (
G4int)(*ElementVector)[elm]->GetZ();
1076 fPhotoAbsorptionCof =
new G4double* [fMaxInterval];
1078 for(i = 0; i < fMaxInterval; ++i)
1080 fPhotoAbsorptionCof[i] =
new G4double[5];
1085 for(c = 0; c < fMaxInterval; ++c)
1087 fPhotoAbsorptionCof[c][0] = 0.;
1091 for(i = 0; i < noElm; ++i)
1096 for(j = 1; j < Z[i]; ++j)
1102 for(k1 = n1; k1 < n2; ++k1)
1104 if(I1 > fSandiaTable[k1][0])
1112 for(c1 = 1; c1 < c; ++c1)
1114 if(fPhotoAbsorptionCof[c1][0] == I1)
1122 fPhotoAbsorptionCof[c][0] = I1;
1125 for(k2 = k1; k2 < n2; ++k2)
1129 for(c1 = 1; c1 < c; ++c1)
1131 if(fPhotoAbsorptionCof[c1][0] == fSandiaTable[k2][0])
1139 fPhotoAbsorptionCof[c][0] = fSandiaTable[k2][0];
1145 SandiaSort(fPhotoAbsorptionCof,c);
1150 for(i = 0; i < fMaxInterval; ++i)
1152 for(j = 1; j < 5; ++j) fPhotoAbsorptionCof[i][j] = 0.;
1154 for(i = 0; i < noElm; ++i)
1159 for(j = 1; j < Z[i]; ++j)
1165 for(k = n1; k < n2; ++k)
1168 G4double B2 = fSandiaTable[k+1][0];
1169 for(
G4int q = 1; q < fMaxInterval-1; q++)
1171 G4double E1 = fPhotoAbsorptionCof[q][0];
1172 G4double E2 = fPhotoAbsorptionCof[q+1][0];
1173 if(B1 > E1 || B2 < E2 || E1 < I1)
1177 for(j = 1; j < 5; ++j)
1179 fPhotoAbsorptionCof[q][j] += fSandiaTable[k][j]*fractionW[i];
1183 for(j = 1; j < 5; ++j)
1185 fPhotoAbsorptionCof[fMaxInterval-1][j] +=
1186 fSandiaTable[k][j]*fractionW[i];
1196 if( fPhotoAbsorptionCof[c][1] != 0.0 ||
1197 fPhotoAbsorptionCof[c][2] != 0.0 ||
1198 fPhotoAbsorptionCof[c][3] != 0.0 ||
1199 fPhotoAbsorptionCof[c][4] != 0.0 )
continue;
1201 for(jj = 2; jj < fMaxInterval; ++jj)
1203 for(kk = 0; kk < 5; ++kk)
1205 fPhotoAbsorptionCof[jj-1][kk]= fPhotoAbsorptionCof[jj][kk];
1212 while( c < fMaxInterval - 1 );
1220 for (i = 0; i < fMaxInterval; ++i)
1224 for ( i = 0; i < fMaxInterval; ++i )
1226 for( j = 0; j < 5; ++j )
1228 (*(*fMatSandiaMatrix)[i])[j] = fPhotoAbsorptionCof[i+1][j];
1231 fMatNbOfIntervals = fMaxInterval;
1235 G4cout<<
"vmg, G4SandiaTable::ComputeMatTable(), mat = "
1238 for ( i = 0; i < fMaxInterval; ++i )
static const G4double fH2OlowerI1[23][5]
std::vector< G4Element * > G4ElementVector
std::ostringstream G4ExceptionDescription
static constexpr double cm2
static constexpr double keV
G4double GetSandiaCofForMaterial(G4int, G4int) const
const G4String & GetName() const
static G4MaterialTable * GetMaterialTable()
std::vector< G4Material * > G4MaterialTable
G4double GetDensity() const
G4int GetMaxInterval() const
G4double GetSandiaMatTablePAI(G4int, G4int) const
const G4ElementVector * GetElementVector() const
static const G4double fIonizationPotentials[101]
static constexpr double g
G4int SandiaMixing(G4int Z[], const G4double *fractionW, G4int el, G4int mi)
static const G4double fZtoAratio[101]
const G4double * GetVecNbOfAtomsPerVolume() const
G4GLOB_DLL std::ostream G4cout
G4double GetWaterCofForMaterial(G4int, G4int) const
static constexpr double amu
static size_t GetNumberOfMaterials()
G4int GetMatNbOfIntervals() const
G4int SandiaIntervals(G4int Z[], G4int el)
static constexpr double eV
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
static const char sss[MAX_N_PAR+2]
T max(const T t1, const T t2)
brief Return the largest of the two arguments
G4double energy(const ThreeVector &p, const G4double m)
static G4double GetZtoA(G4int Z)
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4double GetPhotoAbsorpCof(G4int i, G4int j) const
static const G4double Emin
G4double GetSandiaMatTable(G4int, G4int) const
size_t GetNumberOfElements() const
void GetSandiaCofWater(G4double energy, std::vector< G4double > &coeff) const
const G4double * GetFractionVector() const
static constexpr double keV
void GetSandiaCofPerAtom(G4int Z, G4double energy, std::vector< G4double > &coeff) const
G4double GetWaterEnergyLimit() const
static const G4int fNbOfIntervals[101]
void Initialize(G4Material *)