53G4int G4SandiaTable::fCumulInterval[101] = {0};
54G4double G4SandiaTable::fSandiaCofPerAtom[4] = {0.0};
55G4double const G4SandiaTable::funitc[5] = {keV,
59 cm2*keV*keV*keV*keV/g};
67 fMatSandiaMatrixPAI = 0;
68 fPhotoAbsorptionCof = 0;
70 fMatNbOfIntervals = 0;
78 fCumulInterval[0] = 1;
80 for (
G4int Z=1; Z<101; ++Z) {
81 fCumulInterval[Z] = fCumulInterval[Z-1] + fNbOfIntervals[Z];
85 fnulcof[0] = fnulcof[1] = fnulcof[2] = fnulcof[3] = 0.;
90 ComputeMatSandiaMatrix();
101 : fMaterial(0),fMatSandiaMatrix(0),fMatSandiaMatrixPAI(0),fPhotoAbsorptionCof(0)
103 fnulcof[0] = fnulcof[1] = fnulcof[2] = fnulcof[3] = 0.;
105 fMatNbOfIntervals = 0;
113 if(fMatSandiaMatrix) {
115 delete fMatSandiaMatrix;
117 if(fMatSandiaMatrixPAI) {
119 delete fMatSandiaMatrixPAI;
121 if(fPhotoAbsorptionCof)
123 delete [] fPhotoAbsorptionCof;
132 G4double Emin = fSandiaTable[fCumulInterval[Z-1]][0]*keV;
133 G4double Iopot = fIonizationPotentials[Z]*eV;
134 if (Iopot > Emin) Emin = Iopot;
136 G4int interval = fNbOfIntervals[Z] - 1;
137 G4int row = fCumulInterval[Z-1] + interval;
138 while ((interval>0) && (energy<fSandiaTable[row][0]*keV)) {
140 row = fCumulInterval[Z-1] + interval;
144 G4double AoverAvo = Z*amu/fZtoAratio[Z];
146 fSandiaCofPerAtom[0]=AoverAvo*funitc[1]*fSandiaTable[row][1];
147 fSandiaCofPerAtom[1]=AoverAvo*funitc[2]*fSandiaTable[row][2];
148 fSandiaCofPerAtom[2]=AoverAvo*funitc[3]*fSandiaTable[row][3];
149 fSandiaCofPerAtom[3]=AoverAvo*funitc[4]*fSandiaTable[row][4];
153 fSandiaCofPerAtom[0] = fSandiaCofPerAtom[1] = fSandiaCofPerAtom[2] =
154 fSandiaCofPerAtom[3] = 0.;
156 return fSandiaCofPerAtom;
163 assert (Z>0 && Z<101);
164 return fZtoAratio[Z];
169void G4SandiaTable::ComputeMatSandiaMatrix()
179 G4int MaxIntervals = 0;
182 for ( elm = 0; elm < NbElm; elm++ )
184 Z[elm] = (
G4int)(*ElementVector)[elm]->GetZ();
185 MaxIntervals += fNbOfIntervals[Z[elm]];
195 for ( elm = 0; elm < NbElm; elm++ )
197 IonizationPot = GetIonizationPot(Z[elm]);
199 for (
G4int row = fCumulInterval[ Z[elm]-1 ]; row < fCumulInterval[Z[elm]]; row++ )
201 tmp1[interval1++] = std::max(fSandiaTable[row][0]*keV,IonizationPot);
216 for (
G4int i1 = 0; i1 < MaxIntervals; i1++ )
218 if (tmp1[i1] < Emin) Emin = tmp1[i1];
220 if (Emin <
DBL_MAX) tmp2[interval2++] = Emin;
222 for (
G4int j1 = 0; j1 < MaxIntervals; j1++ )
224 if (tmp1[j1] <= Emin) tmp1[j1] =
DBL_MAX;
233 for (interval = 0; interval < interval2; interval++ )
243 G4double coef, oldsum(0.), newsum(0.);
244 fMatNbOfIntervals = 0;
246 for ( interval = 0; interval < interval2; interval++ )
248 Emin = (*(*fMatSandiaMatrix)[fMatNbOfIntervals])[0] = tmp2[interval];
250 for (
G4int k = 1; k < 5; k++ ) {
251 (*(*fMatSandiaMatrix)[fMatNbOfIntervals])[k] = 0.;
255 for ( elm = 0; elm < NbElm; elm++ )
259 for (
G4int j = 1; j < 5; j++ )
261 coef = NbOfAtomsPerVolume[elm]*fSandiaCofPerAtom[j-1];
262 (*(*fMatSandiaMatrix)[fMatNbOfIntervals])[j] += coef;
263 newsum += std::fabs(coef);
268 if (newsum != oldsum) { oldsum = newsum; fMatNbOfIntervals++;}
274 if ( fVerbose > 0 && fMaterial->
GetName() ==
"G4_Ar" )
276 G4cout<<
"mma, G4SandiaTable::ComputeMatSandiaMatrix(), mat = "
279 for(
G4int i = 0; i < fMatNbOfIntervals; i++)
292void G4SandiaTable::ComputeMatSandiaMatrixPAI()
294 G4int MaxIntervals = 0;
295 G4int elm, c, i, j, jj, k, k1, k2, c1, n1;
301 for ( elm = 0; elm < noElm; elm++ )
303 Z[elm] = (
G4int)(*ElementVector)[elm]->GetZ();
304 MaxIntervals += fNbOfIntervals[Z[elm]];
306 fMaxInterval = MaxIntervals + 2;
308 if ( fVerbose > 0 && fMaterial->
GetName() ==
"G4_Ar" )
318 for( c = 0; c < fMaxInterval; c++ )
320 fPhotoAbsorptionCof0[c] = 0.;
321 fPhotoAbsorptionCof1[c] = 0.;
322 fPhotoAbsorptionCof2[c] = 0.;
323 fPhotoAbsorptionCof3[c] = 0.;
324 fPhotoAbsorptionCof4[c] = 0.;
328 for(i = 0; i < noElm; i++)
330 G4double I1 = fIonizationPotentials[Z[i]]*keV;
333 for( j = 1; j < Z[i]; j++ ) n1 += fNbOfIntervals[j];
335 G4int n2 = n1 + fNbOfIntervals[Z[i]];
337 for( k1 = n1; k1 < n2; k1++ )
339 if( I1 > fSandiaTable[k1][0] )
347 for( c1 = 1; c1 < c; c1++ )
349 if( fPhotoAbsorptionCof0[c1] == I1 )
357 fPhotoAbsorptionCof0[c] = I1;
360 for( k2 = k1; k2 < n2; k2++ )
364 for( c1 = 1; c1 < c; c1++ )
366 if( fPhotoAbsorptionCof0[c1] == fSandiaTable[k2][0] )
374 fPhotoAbsorptionCof0[c] = fSandiaTable[k2][0];
381 for( i = 1; i < c; i++ )
383 for( j = i + 1; j < c; j++ )
385 if( fPhotoAbsorptionCof0[i] > fPhotoAbsorptionCof0[j] )
387 G4double tmp = fPhotoAbsorptionCof0[i];
388 fPhotoAbsorptionCof0[i] = fPhotoAbsorptionCof0[j];
389 fPhotoAbsorptionCof0[j] = tmp;
392 if ( fVerbose > 0 && fMaterial->
GetName() ==
"G4_Ar" )
394 G4cout<<i<<
"\t energy = "<<fPhotoAbsorptionCof0[i]<<
G4endl;
401 if ( fVerbose > 0 && fMaterial->
GetName() ==
"G4_Ar" )
403 for( i = 0; i < noElm; i++ )
G4cout<<i<<
" = elN, fraction = "<<fractionW[i]<<
G4endl;
406 for( i = 0; i < noElm; i++ )
409 G4double I1 = fIonizationPotentials[Z[i]]*keV;
411 for( j = 1; j < Z[i]; j++ ) n1 += fNbOfIntervals[j];
413 G4int n2 = n1 + fNbOfIntervals[Z[i]] - 1;
415 for(k = n1; k < n2; k++)
420 for(
G4int q = 1; q < fMaxInterval-1; q++)
422 G4double E1 = fPhotoAbsorptionCof0[q];
423 G4double E2 = fPhotoAbsorptionCof0[q+1];
425 if ( fVerbose > 0 && fMaterial->
GetName() ==
"G4_Ar" )
427 G4cout<<
"k = "<<k<<
", q = "<<q<<
", B1 = "<<B1<<
", B2 = "<<B2<<
", E1 = "<<E1<<
", E2 = "<<E2<<
G4endl;
429 if( B1 > E1 || B2 < E2 || E1 < I1 )
431 if ( fVerbose > 0 && fMaterial->
GetName() ==
"G4_Ar" )
433 G4cout<<
"continue for: B1 = "<<B1<<
", B2 = "<<B2<<
", E1 = "<<E1<<
", E2 = "<<E2<<
G4endl;
437 fPhotoAbsorptionCof1[q] += fSandiaTable[k][1]*fractionW[i];
438 fPhotoAbsorptionCof2[q] += fSandiaTable[k][2]*fractionW[i];
439 fPhotoAbsorptionCof3[q] += fSandiaTable[k][3]*fractionW[i];
440 fPhotoAbsorptionCof4[q] += fSandiaTable[k][4]*fractionW[i];
445 fPhotoAbsorptionCof1[fMaxInterval-1] += fSandiaTable[k][1]*fractionW[i];
446 fPhotoAbsorptionCof2[fMaxInterval-1] += fSandiaTable[k][2]*fractionW[i];
447 fPhotoAbsorptionCof3[fMaxInterval-1] += fSandiaTable[k][3]*fractionW[i];
448 fPhotoAbsorptionCof4[fMaxInterval-1] += fSandiaTable[k][4]*fractionW[i];
456 if( fPhotoAbsorptionCof1[c] != 0.0 ||
457 fPhotoAbsorptionCof2[c] != 0.0 ||
458 fPhotoAbsorptionCof3[c] != 0.0 ||
459 fPhotoAbsorptionCof4[c] != 0.0 )
continue;
461 if ( fVerbose > 0 && fMaterial->
GetName() ==
"G4_Ar" )
465 for( jj = 2; jj < fMaxInterval; jj++ )
467 fPhotoAbsorptionCof0[jj-1] = fPhotoAbsorptionCof0[jj];
468 fPhotoAbsorptionCof1[jj-1] = fPhotoAbsorptionCof1[jj];
469 fPhotoAbsorptionCof2[jj-1] = fPhotoAbsorptionCof2[jj];
470 fPhotoAbsorptionCof3[jj-1] = fPhotoAbsorptionCof3[jj];
471 fPhotoAbsorptionCof4[jj-1] = fPhotoAbsorptionCof4[jj];
476 while( c < fMaxInterval - 1 );
483 for (i = 0; i < fMaxInterval; i++) fMatSandiaMatrixPAI->push_back(
new G4DataVector(5,0.));
485 for (i = 0; i < fMaxInterval; i++)
487 (*(*fMatSandiaMatrixPAI)[i])[0] = fPhotoAbsorptionCof0[i+1];
488 (*(*fMatSandiaMatrixPAI)[i])[1] = fPhotoAbsorptionCof1[i+1]*density;
489 (*(*fMatSandiaMatrixPAI)[i])[2] = fPhotoAbsorptionCof2[i+1]*density;
490 (*(*fMatSandiaMatrixPAI)[i])[3] = fPhotoAbsorptionCof3[i+1]*density;
491 (*(*fMatSandiaMatrixPAI)[i])[4] = fPhotoAbsorptionCof4[i+1]*density;
493 if ( fVerbose > 0 && fMaterial->
GetName() ==
"G4_Ar" )
495 G4cout<<
"mma, G4SandiaTable::ComputeMatSandiaMatrixPAI(), mat = "<<fMaterial->
GetName()<<
G4endl;
497 for( i = 0; i < fMaxInterval; i++)
506 delete [] fPhotoAbsorptionCof0;
507 delete [] fPhotoAbsorptionCof1;
508 delete [] fPhotoAbsorptionCof2;
509 delete [] fPhotoAbsorptionCof3;
510 delete [] fPhotoAbsorptionCof4;
526 fMatNbOfIntervals = 0;
527 fMatSandiaMatrix = 0;
528 fMatSandiaMatrixPAI = 0;
529 fPhotoAbsorptionCof = 0;
536 fnulcof[0] = fnulcof[1] = fnulcof[2] = fnulcof[3] = 0.;
541 if ( matIndex >= 0 && matIndex < numberOfMat)
543 fMaterial = (*theMaterialTable)[matIndex];
548 G4Exception(
"G4SandiaTable::G4SandiaTable(G4int matIndex)",
"mat401",
562 for(
G4int i = 1;i < sz; i++ )
564 for(
G4int j = i + 1;j < sz; j++ )
580 G4int c, i, flag = 0, n1 = 1;
585 for( i = 0; i < el; i++ ) fMaxInterval += fNbOfIntervals[ Z[i] ];
589 if( fVerbose > 0 )
G4cout<<
"begin sanInt, fMaxInterval = "<<fMaxInterval<<
G4endl;
591 fPhotoAbsorptionCof =
new G4double* [fMaxInterval];
593 for( i = 0; i < fMaxInterval; i++ ) fPhotoAbsorptionCof[i] =
new G4double[5];
597 for( c = 0; c < fMaxInterval; c++ ) fPhotoAbsorptionCof[c][0] = 0.;
601 for( i = 0; i < el; i++ )
603 I1 = fIonizationPotentials[ Z[i] ]*keV;
606 for( j = 1; j < Z[i]; j++ ) n1 += fNbOfIntervals[j];
608 G4int n2 = n1 + fNbOfIntervals[Z[i]];
610 for( k1 = n1; k1 < n2; k1++ )
612 if( I1 > fSandiaTable[k1][0] )
620 for( c1 = 1; c1 < c; c1++ )
622 if( fPhotoAbsorptionCof[c1][0] == I1 )
630 fPhotoAbsorptionCof[c][0] = I1;
633 for( k2 = k1; k2 < n2; k2++ )
637 for( c1 = 1; c1 < c; c1++ )
639 if( fPhotoAbsorptionCof[c1][0] == fSandiaTable[k2][0] )
647 fPhotoAbsorptionCof[c][0] = fSandiaTable[k2][0];
648 if( fVerbose > 0 )
G4cout<<
"sanInt, c = "<<c<<
", E_c = "<<fPhotoAbsorptionCof[c][0]<<
G4endl;
656 if( fVerbose > 0 )
G4cout<<
"end SanInt, fMaxInterval = "<<fMaxInterval<<
G4endl;
671 G4int i, j, n1, k, c=1, jj, kk;
674 for( i = 0; i < mi; i++ )
676 for( j = 1; j < 5; j++ ) fPhotoAbsorptionCof[i][j] = 0.;
678 for( i = 0; i < el; i++ )
681 I1 = fIonizationPotentials[Z[i]]*keV;
683 for( j = 1; j < Z[i]; j++ ) n1 += fNbOfIntervals[j];
685 G4int n2 = n1 + fNbOfIntervals[Z[i]] - 1;
687 for( k = n1; k < n2; k++ )
689 B1 = fSandiaTable[k][0];
690 B2 = fSandiaTable[k+1][0];
692 for( c = 1; c < mi-1; c++ )
694 E1 = fPhotoAbsorptionCof[c][0];
695 E2 = fPhotoAbsorptionCof[c+1][0];
697 if( B1 > E1 || B2 < E2 || E1 < I1 )
continue;
699 for( j = 1; j < 5; j++ )
701 fPhotoAbsorptionCof[c][j] += fSandiaTable[k][j]*fractionW[i];
704 G4cout<<
"c="<<c<<
"; j="<<j<<
"; fST="<<fSandiaTable[k][j]<<
"; frW="<<fractionW[i]<<
G4endl;
709 for( j = 1; j < 5; j++ )
711 fPhotoAbsorptionCof[mi-1][j] += fSandiaTable[k][j]*fractionW[i];
714 G4cout<<
"mi-1="<<mi-1<<
"; j="<<j<<
"; fST="<<fSandiaTable[k][j]<<
"; frW="<<fractionW[i]<<
G4endl;
724 if( fPhotoAbsorptionCof[c][1] != 0.0 ||
725 fPhotoAbsorptionCof[c][2] != 0.0 ||
726 fPhotoAbsorptionCof[c][3] != 0.0 ||
727 fPhotoAbsorptionCof[c][4] != 0.0 )
continue;
729 for( jj = 2; jj < mi; jj++ )
731 for( kk = 0; kk < 5; kk++ ) fPhotoAbsorptionCof[jj-1][kk] = fPhotoAbsorptionCof[jj][kk];
738 if( fVerbose > 0 )
G4cout<<
"end SanMix, mi = "<<mi<<
G4endl;
747 return fMatNbOfIntervals;
754 assert (Z>0 && Z<101);
755 return fNbOfIntervals[Z];
763 assert (Z>0 && Z<101 && interval>=0 && interval<fNbOfIntervals[Z]
766 G4int row = fCumulInterval[Z-1] + interval;
767 G4double x = fSandiaTable[row][0]*CLHEP::keV;
769 x = Z*CLHEP::amu/fZtoAratio[Z]*fSandiaTable[row][j]*funitc[j];
779 assert (interval>=0 && interval<fMatNbOfIntervals && j>=0 && j<5);
780 return ((*(*fMatSandiaMatrix)[interval])[j]);
789 if (energy >= (*(*fMatSandiaMatrix)[0])[0]) {
791 G4int interval = fMatNbOfIntervals - 1;
792 while ((interval>0)&&(energy<(*(*fMatSandiaMatrix)[interval])[0]))
794 x = &((*(*fMatSandiaMatrix)[interval])[1]);
804 assert (interval >= 0 && interval < fMaxInterval && j >= 0 && j < 5 );
805 return ((*(*fMatSandiaMatrix)[interval])[j])*funitc[j];
813 assert (interval>=0 && interval<fMatNbOfIntervals && j>=0 && j<5);
814 if(!fMatSandiaMatrixPAI) ComputeMatSandiaMatrixPAI();
815 return ((*(*fMatSandiaMatrixPAI)[interval])[j]);
823 if(!fMatSandiaMatrixPAI) ComputeMatSandiaMatrixPAI();
825 if (energy >= (*(*fMatSandiaMatrixPAI)[0])[0]) {
827 G4int interval = fMatNbOfIntervals - 1;
828 while ((interval>0)&&(energy<(*(*fMatSandiaMatrixPAI)[interval])[0]))
830 x = &((*(*fMatSandiaMatrixPAI)[interval])[1]);
840 assert (interval >= 0 && interval < fMaxInterval && j >= 0 && j < 5 );
841 if(!fMatSandiaMatrixPAI) { ComputeMatSandiaMatrixPAI(); }
842 return ((*(*fMatSandiaMatrixPAI)[interval])[j])*funitc[j];
848G4SandiaTable::GetIonizationPot(
G4int Z)
850 assert (Z>0 && Z<101);
851 return fIonizationPotentials[Z]*CLHEP::eV;
859 if(!fMatSandiaMatrixPAI) { ComputeMatSandiaMatrixPAI(); }
860 return fMatSandiaMatrixPAI;
868void G4SandiaTable::ComputeMatTable()
870 G4int MaxIntervals = 0;
871 G4int elm, c, i, j, jj, k, kk, k1, k2, c1, n1;
877 for (elm = 0; elm<noElm; elm++)
879 Z[elm] = (
G4int)(*ElementVector)[elm]->GetZ();
880 MaxIntervals += fNbOfIntervals[Z[elm]];
884 for(i = 0; i < noElm; i++) fMaxInterval += fNbOfIntervals[Z[i]];
890 fPhotoAbsorptionCof =
new G4double* [fMaxInterval];
892 for(i = 0; i < fMaxInterval; i++)
894 fPhotoAbsorptionCof[i] =
new G4double[5];
899 for(c = 0; c < fMaxInterval; c++)
901 fPhotoAbsorptionCof[c][0] = 0.;
905 for(i = 0; i < noElm; i++)
907 G4double I1 = fIonizationPotentials[Z[i]]*keV;
910 for(j = 1; j < Z[i]; j++)
912 n1 += fNbOfIntervals[j];
914 G4int n2 = n1 + fNbOfIntervals[Z[i]];
916 for(k1 = n1; k1 < n2; k1++)
918 if(I1 > fSandiaTable[k1][0])
926 for(c1 = 1; c1 < c; c1++)
928 if(fPhotoAbsorptionCof[c1][0] == I1)
936 fPhotoAbsorptionCof[c][0] = I1;
939 for(k2 = k1; k2 < n2; k2++)
943 for(c1 = 1; c1 < c; c1++)
945 if(fPhotoAbsorptionCof[c1][0] == fSandiaTable[k2][0])
953 fPhotoAbsorptionCof[c][0] = fSandiaTable[k2][0];
964 for(i = 0; i < fMaxInterval; i++)
966 for(j = 1; j < 5; j++) fPhotoAbsorptionCof[i][j] = 0.;
968 for(i = 0; i < noElm; i++)
971 G4double I1 = fIonizationPotentials[Z[i]]*keV;
973 for(j = 1; j < Z[i]; j++)
975 n1 += fNbOfIntervals[j];
977 G4int n2 = n1 + fNbOfIntervals[Z[i]] - 1;
979 for(k = n1; k < n2; k++)
983 for(
G4int q = 1; q < fMaxInterval-1; q++)
985 G4double E1 = fPhotoAbsorptionCof[q][0];
986 G4double E2 = fPhotoAbsorptionCof[q+1][0];
987 if(B1 > E1 || B2 < E2 || E1 < I1)
991 for(j = 1; j < 5; j++)
993 fPhotoAbsorptionCof[q][j] += fSandiaTable[k][j]*fractionW[i];
997 for(j = 1; j < 5; j++)
999 fPhotoAbsorptionCof[fMaxInterval-1][j] += fSandiaTable[k][j]*fractionW[i];
1009 if( fPhotoAbsorptionCof[c][1] != 0.0 ||
1010 fPhotoAbsorptionCof[c][2] != 0.0 ||
1011 fPhotoAbsorptionCof[c][3] != 0.0 ||
1012 fPhotoAbsorptionCof[c][4] != 0.0 )
continue;
1014 for(jj = 2; jj < fMaxInterval; jj++)
1016 for(kk = 0; kk < 5; kk++)
1018 fPhotoAbsorptionCof[jj-1][kk]= fPhotoAbsorptionCof[jj][kk];
1024 while(c < fMaxInterval - 1);
1032 for (i = 0; i < fMaxInterval; i++)
1036 for ( i = 0; i < fMaxInterval; i++ )
1038 for( j = 0; j < 5; j++ )
1040 (*(*fMatSandiaMatrix)[i])[j] = fPhotoAbsorptionCof[i+1][j];
1043 fMatNbOfIntervals = fMaxInterval;
1049 for ( i = 0; i < fMaxInterval; i++ )
std::vector< G4Element * > G4ElementVector
std::vector< G4Material * > G4MaterialTable
G4DLLIMPORT std::ostream G4cout
G4double GetDensity() const
static const G4MaterialTable * GetMaterialTable()
const G4ElementVector * GetElementVector() const
static size_t GetNumberOfMaterials()
const G4double * GetFractionVector() const
size_t GetNumberOfElements() const
const G4double * GetVecNbOfAtomsPerVolume() const
const G4String & GetName() const
G4double GetSandiaMatTablePAI(G4int, G4int)
void SandiaSwap(G4double **da, G4int i, G4int j)
static G4double GetZtoA(G4int Z)
G4double GetSandiaCofForMaterialPAI(G4int, G4int)
G4SandiaTable(G4Material *)
static G4double * GetSandiaCofPerAtom(G4int Z, G4double energy)
G4int GetMatNbOfIntervals()
G4int SandiaMixing(G4int Z[], const G4double *fractionW, G4int el, G4int mi)
G4double GetSandiaMatTable(G4int, G4int)
G4double GetSandiaCofForMaterial(G4int, G4int)
void SandiaSort(G4double **da, G4int sz)
G4OrderedTable * GetSandiaMatrixPAI()
G4int SandiaIntervals(G4int Z[], G4int el)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)