41 if(twoJ1 < 0 || twoJ2 < 0 || twoJ < 0 ||
42 ((twoJ1-twoM1) % 2) || ((twoJ2-twoM2) % 2)) {
return 0; }
44 G4int twoM = twoM1 + twoM2;
45 if(twoM1 > twoJ1 || twoM1 < -twoJ1 ||
46 twoM2 > twoJ2 || twoM2 < -twoJ2 ||
47 twoM > twoJ || twoM < -twoJ) {
return 0; }
50 G4double triangle = TriangleCoeff(twoJ1, twoJ2, twoJ);
51 if(triangle == 0) {
return 0; }
63 G4int sum1 = (twoJ1 - twoM1)/2;
65 G4int sum2 = (twoJ - twoJ2 + twoM1)/2;
66 if(-sum2 > kMin) kMin = -sum2;
67 G4int sum3 = (twoJ2 + twoM2)/2;
68 if(sum3 < kMax) kMax = sum3;
69 G4int sum4 = (twoJ - twoJ1 - twoM2)/2;
70 if(-sum4 > kMin) kMin = -sum4;
71 G4int sum5 = (twoJ1 + twoJ2 - twoJ)/2;
72 if(sum5 < kMax) kMax = sum5;
76 G4Exception(
"G4Clebsch::ClebschGordanCoeff()",
"Clebsch001",
81 G4Exception(
"G4Clebsch::ClebschGordanCoeff()",
"Clebsch002",
86 G4Exception(
"G4Clebsch::ClebschGordanCoeff()",
"Clebsch003",
103 return triangle*sqrt(twoJ+1)*kSum;
111 G4double clebsch = ClebschGordanCoeff(twoJ1, twoM1, twoJ2, twoM2, twoJ);
112 return clebsch*clebsch;
115 std::vector<G4double>
120 std::vector<G4double> temp;
125 if (twoJ1 == 0 && twoJ2 == 0) {
126 G4Exception(
"G4Clebsch::GenerateIso3()",
"Clebsch010",
133 G4int twoM3 = twoM1 + twoM2;
138 temp.push_back(twoM3);
142 temp.push_back(twoM3);
149 G4int twoJMaxIn = twoJ1 + twoJ2;
152 G4int twoJMinOut = 9999;
153 for(
G4int i=-1; i<=1; i+=2) {
154 for(
G4int j=-1; j<=1; j+=2) {
156 if(twoJTmp < twoJMinOut) twoJMinOut = twoJTmp;
160 G4int twoJMaxOut = twoJOut1 + twoJOut2;
165 if (twoJMin > twoJMax) {
166 G4Exception(
"G4Clebsch::GenerateIso3()",
"Clebsch020",
172 G4int nJ = (twoJMax - twoJMin) / 2 + 1;
176 if ( (twoJ1 == 0 || twoJ2 == 0) && twoJMin != twoJMax ) {
177 G4Exception(
"G4Clebsch::GenerateIso3()",
"Clebsch021",
178 JustWarning,
"twoJ1 or twoJ2 = 0, but twoJMin != JMax");
184 G4Exception(
"G4Clebsch::GenerateIso3()",
"Clebsch022",
185 JustWarning,
"nJ is zero, no overlap between in and out");
192 std::vector<G4double> clebsch;
194 for(
G4int twoJ=twoJMin; twoJ<=twoJMax; twoJ+=2) {
195 sum += ClebschGordan(twoJ1, twoM1, twoJ2, twoM2, twoJ);
196 clebsch.push_back(sum);
200 if (static_cast<G4int>(clebsch.size()) != nJ) {
201 G4Exception(
"G4Clebsch::GenerateIso3()",
"Clebsch023",
208 G4Exception(
"G4Clebsch::GenerateIso3()",
"Clebsch024",
209 JustWarning,
"Sum of Clebsch-Gordan probabilities <=0");
215 G4int twoJTot = twoJMin;
216 for (
G4int i=0; i<nJ; ++i) {
217 if (sum < clebsch[i]) {
225 std::vector<G4double> mMin;
226 mMin.push_back(-twoJOut1);
227 mMin.push_back(-twoJOut2);
229 std::vector<G4double> mMax;
230 mMax.push_back(twoJOut1);
231 mMax.push_back(twoJOut2);
235 std::vector<G4double> m1Out;
236 std::vector<G4double> m2Out;
238 const G4int size = 20;
241 G4int m1pos(0), m2pos(0);
243 G4int m1pr(0), m2pr(0);
246 for(j12 =
std::abs(twoJOut1-twoJOut2); j12<=(twoJOut1+twoJOut2); j12+=2)
249 for (m1pr = static_cast<G4int>(mMin[0]+.00001); m1pr <= mMax[0]; m1pr+=2)
253 G4Exception(
"G4Clebsch::GenerateIso3()",
"Clebsch025",
257 m1Out.push_back(m1pr);
259 for (m2pr = static_cast<G4int>(mMin[1]+.00001); m2pr <= mMax[1]; m2pr+=2)
264 G4Exception(
"G4Clebsch::GenerateIso3()",
"Clebsch026",
268 m2Out.push_back(m2pr);
270 if(m1pr + m2pr == twoM3)
272 G4int m12 = m1pr + m2pr;
273 G4double c12 = ClebschGordan(twoJOut1, m1pr, twoJOut2,m2pr, j12);
274 G4double c34 = ClebschGordan(0,0,0,0,0);
275 G4double ctot = ClebschGordan(j12, m12, 0, 0, twoJTot);
277 prbout[m1pos][m2pos] = cleb;
282 prbout[m1pos][m2pos] = 0.;
289 G4Exception(
"G4Clebsch::GenerateIso3()",
"Clebsch027",
294 for (
G4int i=0; i<size; i++) {
295 for (
G4int j=0; j<size; j++) {
304 for (m1p=0; m1p<m1pos; m1p++) {
305 for (m2p=0; m2p<m2pos; m2p++) {
306 if (rand < prbout[m1p][m2p]) {
307 temp.push_back(m1Out[m1p]);
308 temp.push_back(m2Out[m2p]);
311 else rand -= prbout[m1p][m2p];
315 G4Exception(
"G4Clebsch::GenerateIso3()",
"Clebsch028",
326 G4int twoM = twoM1 + twoM2;
329 G4int twoJMaxIn = twoJ1 + twoJ2;
332 G4int twoJMaxOut = twoJOut1 + twoJOut2;
337 for (
G4int twoJ=twoJMin; twoJ<=twoJMax; twoJ+=2) {
339 value += ClebschGordan(twoJ1, twoM1, twoJ2, twoM2, twoJ);
356 return Wigner3J(twoJ1, twoM1, twoJ2, twoM2, twoJ3, twoM3);
363 G4double clebsch = ClebschGordanCoeff(twoJ1, twoM1, twoJ2, twoM2, twoJ3);
364 if(clebsch == 0)
return clebsch;
365 if( (twoJ1-twoJ2+twoM1+twoM2)/2 % 2) clebsch = -clebsch;
366 return clebsch / sqrt(twoJ3+1);
373 if(twoM1 + twoM2 != -twoM3)
return 0;
374 G4double clebsch = ClebschGordanCoeff(twoJ1, twoM1, twoJ2, twoM2, twoJ3);
375 if(clebsch == 0)
return clebsch;
376 if( (twoJ1-twoJ2-twoM3)/2 % 2) clebsch = -clebsch;
377 return clebsch / sqrt(twoJ3+1);
388 if(twoJ1 == 0 || twoJ2 == 0)
return cleb;
392 for(
G4int twoM1Current=-twoJ1; twoM1Current<=twoJ1; twoM1Current+=2) {
393 G4int twoM2Current = twoM - twoM1Current;
395 G4double prob = ClebschGordan(twoJ1, twoM1Current, twoJ2,
398 if (twoM2Current == twoM2 && twoM1Current == twoM1) cleb += prob;
402 if (sum > 0.) cleb /=
sum;
414 G4int i = twoA+twoB-twoC;
416 if(i<0 || (i%2))
return 0;
427 i = twoA+twoB+twoC+2;
435 if(twoJ1 < 0 || twoJ2 < 0 || twoJ3 < 0 ||
436 twoJ4 < 0 || twoJ5 < 0 || twoJ6 < 0)
return 0;
441 if(twoJ1 != twoJ5)
return 0;
442 if(twoJ2 != twoJ4)
return 0;
443 if(twoJ1+twoJ2 < twoJ3)
return 0;
444 if((twoJ1 > twoJ2) && (twoJ3 < (twoJ1-twoJ2)))
return 0;
445 if((twoJ2 > twoJ1) && (twoJ3 < (twoJ2-twoJ1)))
return 0;
446 if((twoJ1+twoJ2+twoJ3) % 2)
return 0;
447 return (((twoJ1+twoJ2+twoJ3)/2) % 2 ? -1. : 1.) /sqrt((twoJ1+1)*(twoJ2+1));
449 if(twoJ1 == 0)
return Wigner6J(twoJ6, twoJ2, twoJ4, twoJ3, twoJ5, 0);
450 if(twoJ2 == 0)
return Wigner6J(twoJ1, twoJ6, twoJ5, twoJ4, twoJ3, 0);
451 if(twoJ3 == 0)
return Wigner6J(twoJ4, twoJ2, twoJ6, twoJ1, twoJ5, 0);
452 if(twoJ4 == 0)
return Wigner6J(twoJ3, twoJ2, twoJ1, twoJ6, twoJ5, 0);
453 if(twoJ5 == 0)
return Wigner6J(twoJ1, twoJ3, twoJ2, twoJ4, twoJ6, 0);
458 double triangles = 0;
460 i = twoJ1+twoJ2-twoJ3;
if(i<0 || i%2)
return 0;
else triangles += g4pow->
logfactorial(i/2);
461 i = twoJ1-twoJ2+twoJ3;
if(i<0 || i%2)
return 0;
else triangles += g4pow->
logfactorial(i/2);
462 i = -twoJ1+twoJ2+twoJ3;
if(i<0 || i%2)
return 0;
else triangles += g4pow->
logfactorial(i/2);
463 i = twoJ1+twoJ2+twoJ3+2;
if(i<0 || i%2)
return 0;
else triangles -= g4pow->
logfactorial(i/2);
464 i = twoJ1+twoJ5-twoJ6;
if(i<0 || i%2)
return 0;
else triangles += g4pow->
logfactorial(i/2);
465 i = twoJ1-twoJ5+twoJ6;
if(i<0 || i%2)
return 0;
else triangles += g4pow->
logfactorial(i/2);
466 i = -twoJ1+twoJ5+twoJ6;
if(i<0 || i%2)
return 0;
else triangles += g4pow->
logfactorial(i/2);
467 i = twoJ1+twoJ5+twoJ6+2;
if(i<0 || i%2)
return 0;
else triangles -= g4pow->
logfactorial(i/2);
468 i = twoJ4+twoJ2-twoJ6;
if(i<0 || i%2)
return 0;
else triangles += g4pow->
logfactorial(i/2);
469 i = twoJ4-twoJ2+twoJ6;
if(i<0 || i%2)
return 0;
else triangles += g4pow->
logfactorial(i/2);
470 i = -twoJ4+twoJ2+twoJ6;
if(i<0 || i%2)
return 0;
else triangles += g4pow->
logfactorial(i/2);
471 i = twoJ4+twoJ2+twoJ6+2;
if(i<0 || i%2)
return 0;
else triangles -= g4pow->
logfactorial(i/2);
472 i = twoJ4+twoJ5-twoJ3;
if(i<0 || i%2)
return 0;
else triangles += g4pow->
logfactorial(i/2);
473 i = twoJ4-twoJ5+twoJ3;
if(i<0 || i%2)
return 0;
else triangles += g4pow->
logfactorial(i/2);
474 i = -twoJ4+twoJ5+twoJ3;
if(i<0 || i%2)
return 0;
else triangles += g4pow->
logfactorial(i/2);
475 i = twoJ4+twoJ5+twoJ3+2;
if(i<0 || i%2)
return 0;
else triangles -= g4pow->
logfactorial(i/2);
476 triangles =
G4Exp(0.5*triangles);
482 G4int sum1 = (twoJ1 + twoJ2 + twoJ3)/2;
484 G4int sum2 = (twoJ1 + twoJ5 + twoJ6)/2;
485 if(sum2 > kMin) kMin = sum2;
486 G4int sum3 = (twoJ4 + twoJ2 + twoJ6)/2;
487 if(sum3 > kMin) kMin = sum3;
488 G4int sum4 = (twoJ4 + twoJ5 + twoJ3)/2;
489 if(sum4 > kMin) kMin = sum4;
492 G4int sum5 = (twoJ1 + twoJ2 + twoJ4 + twoJ5)/2;
494 G4int sum6 = (twoJ2 + twoJ3 + twoJ5 + twoJ6)/2;
495 if(sum6 < kMax) kMax = sum6;
496 G4int sum7 = (twoJ1 + twoJ3 + twoJ4 + twoJ6)/2;
497 if(sum7 < kMax) kMax = sum7;
530 return triangles*kSum;
537 if(twoJ1 < 0 || twoJ2 < 0 || twoJ3 < 0 ||
538 twoJ4 < 0 || twoJ5 < 0 || twoJ6 < 0 ||
539 twoJ7 < 0 || twoJ8 < 0 || twoJ9 < 0)
return 0;
542 if(twoJ3 != twoJ6)
return 0;
543 if(twoJ7 != twoJ8)
return 0;
544 G4double sixJ = Wigner6J(twoJ1, twoJ2, twoJ3, twoJ5, twoJ4, twoJ7);
545 if(sixJ == 0)
return 0;
546 if((twoJ2+twoJ3+twoJ4+twoJ7)/2 % 2) sixJ = -sixJ;
547 return sixJ/sqrt((twoJ3+1)*(twoJ7+1));
549 if(twoJ1 == 0)
return Wigner9J(twoJ9, twoJ6, twoJ3, twoJ8, twoJ5, twoJ2, twoJ7, twoJ4, twoJ1);
550 if(twoJ2 == 0)
return Wigner9J(twoJ7, twoJ9, twoJ8, twoJ4, twoJ6, twoJ5, twoJ1, twoJ3, twoJ2);
551 if(twoJ4 == 0)
return Wigner9J(twoJ3, twoJ2, twoJ1, twoJ9, twoJ8, twoJ7, twoJ6, twoJ5, twoJ4);
552 if(twoJ5 == 0)
return Wigner9J(twoJ1, twoJ3, twoJ2, twoJ7, twoJ9, twoJ8, twoJ4, twoJ6, twoJ5);
553 G4int twoS = twoJ1+twoJ2+twoJ3+twoJ4+twoJ5+twoJ6+twoJ7+twoJ8+twoJ9;
554 if(twoS % 2)
return 0;
556 if(twoJ3 == 0)
return sign*Wigner9J(twoJ7, twoJ8, twoJ9, twoJ4, twoJ5, twoJ6, twoJ1, twoJ2, twoJ3);
557 if(twoJ6 == 0)
return sign*Wigner9J(twoJ1, twoJ2, twoJ3, twoJ7, twoJ8, twoJ9, twoJ4, twoJ5, twoJ6);
558 if(twoJ7 == 0)
return sign*Wigner9J(twoJ3, twoJ2, twoJ1, twoJ6, twoJ5, twoJ4, twoJ9, twoJ8, twoJ7);
559 if(twoJ8 == 0)
return sign*Wigner9J(twoJ1, twoJ3, twoJ2, twoJ4, twoJ6, twoJ5, twoJ7, twoJ9, twoJ8);
563 i = twoJ1+twoJ2-twoJ3;
if(i<0 || i%2)
return 0;
564 i = twoJ1-twoJ2+twoJ3;
if(i<0 || i%2)
return 0;
565 i = -twoJ1+twoJ2+twoJ3;
if(i<0 || i%2)
return 0;
566 i = twoJ4+twoJ5-twoJ6;
if(i<0 || i%2)
return 0;
567 i = twoJ4-twoJ5+twoJ6;
if(i<0 || i%2)
return 0;
568 i = -twoJ4+twoJ5+twoJ6;
if(i<0 || i%2)
return 0;
569 i = twoJ7+twoJ8-twoJ9;
if(i<0 || i%2)
return 0;
570 i = twoJ7-twoJ8+twoJ9;
if(i<0 || i%2)
return 0;
571 i = -twoJ7+twoJ8+twoJ9;
if(i<0 || i%2)
return 0;
572 i = twoJ1+twoJ4-twoJ7;
if(i<0 || i%2)
return 0;
573 i = twoJ1-twoJ4+twoJ7;
if(i<0 || i%2)
return 0;
574 i = -twoJ1+twoJ4+twoJ7;
if(i<0 || i%2)
return 0;
575 i = twoJ2+twoJ5-twoJ8;
if(i<0 || i%2)
return 0;
576 i = twoJ2-twoJ5+twoJ8;
if(i<0 || i%2)
return 0;
577 i = -twoJ2+twoJ5+twoJ8;
if(i<0 || i%2)
return 0;
578 i = twoJ3+twoJ6-twoJ9;
if(i<0 || i%2)
return 0;
579 i = twoJ3-twoJ6+twoJ9;
if(i<0 || i%2)
return 0;
580 i = -twoJ3+twoJ6+twoJ9;
if(i<0 || i%2)
return 0;
584 G4int twoKMax = twoJ1+twoJ9;
585 if(twoJ4+twoJ8 < twoKMax) twoKMax = twoJ4+twoJ8;
586 if(twoJ2+twoJ6 < twoKMax) twoKMax = twoJ2+twoJ6;
587 G4int twoKMin = twoJ1-twoJ9;
588 if(twoJ9-twoJ1 > twoKMin) twoKMin = twoJ9-twoJ1;
589 if(twoJ4-twoJ8 > twoKMin) twoKMin = twoJ4-twoJ8;
590 if(twoJ8-twoJ4 > twoKMin) twoKMin = twoJ8-twoJ4;
591 if(twoJ2-twoJ6 > twoKMin) twoKMin = twoJ2-twoJ6;
592 if(twoJ6-twoJ2 > twoKMin) twoKMin = twoJ6-twoJ2;
593 if(twoKMin > twoKMax)
return 0;
596 for(
G4int twoK = twoKMin; twoK <= twoKMax; twoK += 2) {
597 G4double value = Wigner6J(twoJ1, twoJ4, twoJ7, twoJ8, twoJ9, twoK);
598 if(value == 0)
continue;
599 value *= Wigner6J(twoJ2, twoJ5, twoJ8, twoJ4, twoK, twoJ6);
600 if(value == 0)
continue;
601 value *= Wigner6J(twoJ3, twoJ6, twoJ9, twoK, twoJ1, twoJ2);
602 if(value == 0)
continue;
603 if(twoK % 2) value = -
value;
612 if(twoM < -twoJ || twoM > twoJ || twoN < -twoJ || twoN > twoJ
613 || ((twoM % 2) != (twoJ % 2)) || ((twoN % 2) != (twoJ % 2)))
616 if(cosTheta == 1.0) {
return G4double(twoM == twoN); }
619 if(twoM > twoN) kMin = (twoM-twoN)/2;
621 if((twoJ-twoN)/2 <
kMax) kMax = (twoJ-twoN)/2;
637 logSum += (twoJ+(twoM-twoN)/2 - 2*
k)*lnCosHalfTheta +
638 (2*
k + (twoN-twoM)/2)*lnSinHalfTheta;
640 d += sign *
G4Exp(logSum);