Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions
G4Clebsch Class Reference

#include <G4Clebsch.hh>

Public Member Functions

 G4Clebsch ()
 
virtual ~G4Clebsch ()
 
G4bool operator== (const G4Clebsch &right) const
 
G4bool operator!= (const G4Clebsch &right) const
 
G4double ClebschGordan (G4int isoIn1, G4int iso3In1, G4int isoIn2, G4int iso3In2, G4int jOut) const
 
std::vector< G4doubleGenerateIso3 (G4int isoIn1, G4int iso3In1, G4int isoIn2, G4int iso3In2, G4int isoOut1, G4int isoOut2) const
 
G4double Weight (G4int isoIn1, G4int iso3In1, G4int isoIn2, G4int iso3In2, G4int isoOut1, G4int isoOut2) const
 
G4double Wigner3J (G4double j1, G4double j2, G4double j3, G4double m1, G4double m2, G4double m3) const
 
const std::vector< G4double > & GetLogs () const
 
G4double NormalizedClebschGordan (G4int J, G4int m, G4int J1, G4int J2, G4int m1, G4int m2) const
 

Detailed Description

Definition at line 49 of file G4Clebsch.hh.

Constructor & Destructor Documentation

G4Clebsch::G4Clebsch ( )

Definition at line 36 of file G4Clebsch.cc.

37 {
38  G4int nLogs = 101;
39  logs.push_back(0.);
40  G4int i;
41  for (i=1; i<nLogs; i++)
42  {
43  G4double previousLog = logs.back();
44  G4double value = previousLog + std::log((G4double)i);
45  logs.push_back(value);
46  }
47 }
int G4int
Definition: G4Types.hh:78
const XML_Char int const XML_Char * value
double G4double
Definition: G4Types.hh:76
G4Clebsch::~G4Clebsch ( )
virtual

Definition at line 50 of file G4Clebsch.cc.

51 { }

Member Function Documentation

G4double G4Clebsch::ClebschGordan ( G4int  isoIn1,
G4int  iso3In1,
G4int  isoIn2,
G4int  iso3In2,
G4int  jOut 
) const

Definition at line 100 of file G4Clebsch.cc.

References G4lrint(), n, and Wigner3J().

Referenced by GenerateIso3(), NormalizedClebschGordan(), and Weight().

103 {
104  // Calculates Clebsch-Gordan coefficient
105 
106  G4double j1 = isoIn1 / 2.0;
107  G4double j2 = isoIn2 / 2.0;
108  G4double j3 = jOut / 2.0;
109 
110  G4double m_1 = iso3In1 / 2.0;
111  G4double m_2 = iso3In2 / 2.0;
112  G4double m_3 = - (m_1 + m_2);
113 
114  G4int n = G4lrint(m_3+j1+j2+.1);
115  G4double argument = 2. * j3 + 1.;
116  if (argument < 0.)
117  throw G4HadronicException(__FILE__, __LINE__, "G4Clebsch::ClebschGordan - sqrt of negative argument");
118  G4double coeff = std::sqrt(argument) / (std::pow(-1.,n));
119  G4double clebsch = coeff * Wigner3J(j1,j2,j3, m_1,m_2,m_3);
120  G4double value = clebsch * clebsch;
121 
122 // G4cout << "ClebschGordan("
123 // << isoIn1 << "," << iso3In1 << ","
124 // << isoIn2 << "," << iso3In2 << "," << jOut
125 // << ") = " << value << G4endl;
126 
127  return value;
128 }
int G4int
Definition: G4Types.hh:78
const G4int n
G4double Wigner3J(G4double j1, G4double j2, G4double j3, G4double m1, G4double m2, G4double m3) const
Definition: G4Clebsch.cc:131
int G4lrint(double ad)
Definition: templates.hh:163
const XML_Char int const XML_Char * value
double G4double
Definition: G4Types.hh:76
std::vector< G4double > G4Clebsch::GenerateIso3 ( G4int  isoIn1,
G4int  iso3In1,
G4int  isoIn2,
G4int  iso3In2,
G4int  isoOut1,
G4int  isoOut2 
) const

Definition at line 292 of file G4Clebsch.cc.

References ClebschGordan(), G4cout, G4endl, G4UniformRand, G4INCL::Math::max(), and G4INCL::Math::min().

Referenced by G4VXResonance::IsospinCorrection().

295 {
296  std::vector<G4double> temp;
297 
298  // ---- Special cases first ----
299 
300  // Special case, both Jin are zero
301  if (isoIn1 == 0 && isoIn2 == 0)
302  {
303  G4cout << "WARNING: G4Clebsch::GenerateIso3 - both isoIn are zero" << G4endl;
304  temp.push_back(0.);
305  temp.push_back(0.);
306  return temp;
307  }
308 
309  G4int iso3 = iso3In1 + iso3In2;
310 
311  // Special case, either Jout is zero
312  if (isoA == 0)
313  {
314  temp.push_back(0.);
315  temp.push_back(iso3);
316  return temp;
317  }
318  if (isoB == 0)
319  {
320  temp.push_back(iso3);
321  temp.push_back(0.);
322  return temp;
323  }
324 
325  // Number of possible states, in
326  G4int jMinIn = std::max(std::abs(isoIn1 - isoIn2), std::abs(iso3));
327  G4int jMaxIn = isoIn1 + isoIn2;
328 
329  // Number of possible states, out
330 
331  G4int jMinOut = 9999;
332  G4int jTmp, i, j;
333 
334  for(i=-1; i<=1; i+=2)
335  {
336  for(j=-1; j<=1; j+=2)
337  {
338  jTmp= std::abs(i*isoA + j*isoB);
339  if(jTmp < jMinOut) jMinOut = jTmp;
340  }
341  }
342  jMinOut = std::max(jMinOut, std::abs(iso3));
343  G4int jMaxOut = isoA + isoB;
344 
345  // Possible in and out common states
346  G4int jMin = std::max(jMinIn, jMinOut);
347  G4int jMax = std::min(jMaxIn, jMaxOut);
348  if (jMin > jMax)
349  {
350  throw G4HadronicException(__FILE__, __LINE__, "G4Clebsch::GenerateIso3 - jMin > JMax");
351  }
352 
353  // Number of possible isospins
354  G4int nJ = (jMax - jMin) / 2 + 1;
355 
356  // A few consistency checks
357 
358  if ( (isoIn1 == 0 || isoIn2 == 0) && jMin != jMax )
359  throw G4HadronicException(__FILE__, __LINE__, "G4Clebsch::GenerateIso3 - J1 or J2 = 0, but jMin != JMax");
360 
361  // MGP ---- Shall it be a warning or an exception?
362  if (nJ == 0)
363  throw G4HadronicException(__FILE__, __LINE__, "G4Clebsch::GenerateIso3 - nJ is zero, no overlap between in and out");
364 
365  // Loop over all possible combinations of isoIn1, isoIn2, iso3In11, iso3In2, jTot
366  // to get the probability of each of the in-channel couplings
367 
368  std::vector<G4double> clebsch;
369 
370  for(j=jMin; j<=jMax; j+=2)
371  {
372  G4double cg = ClebschGordan(isoIn1, iso3In1, isoIn2, iso3In2, j);
373  clebsch.push_back(cg);
374  }
375 
376  // Consistency check
377  if (static_cast<G4int>(clebsch.size()) != nJ)
378  throw G4HadronicException(__FILE__, __LINE__, "G4Clebsch::GenerateIso3 - nJ inconsistency");
379 
380  G4double sum = clebsch[0];
381 
382  for (j=1; j<nJ; j++)
383  {
384  sum += clebsch[j];
385  }
386  // Consistency check
387  if (sum <= 0.)
388  throw G4HadronicException(__FILE__, __LINE__, "G4Clebsch::GenerateIso3 - Sum of Clebsch-Gordan probabilities <=0");
389 
390  // Generate a normalized pdf
391 
392  std::vector<G4double> clebschPdf;
393  G4double previous = clebsch[0];
394  clebschPdf.push_back(previous/sum);
395  for (j=1; j<nJ; j++)
396  {
397  previous += clebsch[j];
398  G4double prob = previous / sum;
399  clebschPdf.push_back(prob);
400  }
401 
402  // Generate a random jTot according to the Clebsch-Gordan pdf
403  G4double rand = G4UniformRand();
404  G4int jTot = 0;
405  for (j=0; j<nJ; j++)
406  {
407  G4bool found = false;
408  if (rand < clebschPdf[j])
409  {
410  found = true;
411  jTot = jMin + 2*j;
412  }
413  if (found) break;
414  }
415 
416  // Generate iso3Out
417 
418  std::vector<G4double> mMin;
419  mMin.push_back(-isoA);
420  mMin.push_back(-isoB);
421 
422  std::vector<G4double> mMax;
423  mMax.push_back(isoA);
424  mMax.push_back(isoB);
425 
426  // Calculate the possible |J_i M_i> combinations and their probability
427 
428  std::vector<G4double> m1Out;
429  std::vector<G4double> m2Out;
430 
431  const G4int size = 20;
432  G4double prbout[size][size];
433 
434  G4int m1pos(0), m2pos(0);
435  G4int j12;
436  G4int m1pr(0), m2pr(0);
437 
438  sum = 0.;
439  for(j12 = std::abs(isoA-isoB); j12<=(isoA+isoB); j12+=2)
440  {
441  m1pos = -1;
442  for (m1pr = static_cast<G4int>(mMin[0]+.00001); m1pr <= mMax[0]; m1pr+=2)
443  {
444  m1pos++;
445  if (m1pos >= size)
446  throw G4HadronicException(__FILE__, __LINE__, "G4Clebsch::GenerateIso3 - m1pos > size");
447  m1Out.push_back(m1pr);
448  m2pos = -1;
449  for (m2pr = static_cast<G4int>(mMin[1]+.00001); m2pr <= mMax[1]; m2pr+=2)
450  {
451  m2pos++;
452  if (m2pos >= size)
453  {
454  throw G4HadronicException(__FILE__, __LINE__, "G4Clebsch::GenerateIso3 - m2pos > size");
455  }
456  m2Out.push_back(m2pr);
457 
458  if(m1pr + m2pr == iso3)
459  {
460  G4int m12 = m1pr + m2pr;
461  G4double c12 = ClebschGordan(isoA, m1pr, isoB,m2pr, j12);
462  G4double c34 = ClebschGordan(0,0,0,0,0);
463  G4double ctot = ClebschGordan(j12, m12, 0, 0, jTot);
464  G4double cleb = c12*c34*ctot;
465  prbout[m1pos][m2pos] = cleb;
466  sum += cleb;
467  }
468  else
469  {
470  prbout[m1pos][m2pos] = 0.;
471  }
472  }
473  }
474  }
475 
476  if (sum <= 0.)
477  throw G4HadronicException(__FILE__, __LINE__, "G4Clebsch::GenerateIso3 - sum (out) <=0");
478 
479  for (i=0; i<size; i++)
480  {
481  for (j=0; j<size; j++)
482  {
483  prbout[i][j] /= sum;
484  }
485  }
486 
487  rand = G4UniformRand();
488 
489  G4int m1p, m2p;
490 
491  for (m1p=0; m1p<m1pos; m1p++)
492  {
493  for (m2p=0; m2p<m2pos; m2p++)
494  {
495  if (rand < prbout[m1p][m2p])
496  {
497  temp.push_back(m1Out[m1p]);
498  temp.push_back(m2Out[m2p]);
499  return temp;
500  }
501  else
502  {
503  rand -= prbout[m1p][m2p];
504  }
505  }
506  }
507 
508  throw G4HadronicException(__FILE__, __LINE__, "Should never get here ");
509  return temp;
510 }
int G4int
Definition: G4Types.hh:78
#define G4UniformRand()
Definition: Randomize.hh:87
G4GLOB_DLL std::ostream G4cout
bool G4bool
Definition: G4Types.hh:79
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
G4double ClebschGordan(G4int isoIn1, G4int iso3In1, G4int isoIn2, G4int iso3In2, G4int jOut) const
Definition: G4Clebsch.cc:100
const std::vector< G4double > & G4Clebsch::GetLogs ( ) const

Definition at line 66 of file G4Clebsch.cc.

Referenced by Wigner3J().

67 {
68  return logs;
69 }
G4double G4Clebsch::NormalizedClebschGordan ( G4int  J,
G4int  m,
G4int  J1,
G4int  J2,
G4int  m1,
G4int  m2 
) const

Definition at line 513 of file G4Clebsch.cc.

References ClebschGordan().

516 {
517  // Calculate the normalized Clebsch-Gordan coefficient, that is the prob
518  // of isospin decomposition of (J,m) into J1, J2, m1, m2
519 
520  G4double cleb = 0.;
521 
522  if(J1 == 0 || J2 == 0) return cleb;
523 
524  G4double sum = 0.0;
525 
526  // Loop over all J1,J2,Jtot,m1,m2 combinations
527 
528  for(G4int m1Current=-J1; m1Current<=J1; m1Current+=2)
529  {
530  G4int m2Current = M - m1Current;
531 
532  G4double prob = ClebschGordan(J1, m1Current, J2, m2Current, J);
533  sum += prob;
534  if (m2Current == m_2 && m1Current == m_1) cleb += prob;
535  }
536 
537  // Normalize probs to 1
538  if (sum > 0.) cleb /= sum;
539 
540  return cleb;
541 }
int G4int
Definition: G4Types.hh:78
double G4double
Definition: G4Types.hh:76
G4double ClebschGordan(G4int isoIn1, G4int iso3In1, G4int isoIn2, G4int iso3In2, G4int jOut) const
Definition: G4Clebsch.cc:100
G4bool G4Clebsch::operator!= ( const G4Clebsch right) const

Definition at line 60 of file G4Clebsch.cc.

61 {
62  return (this != (G4Clebsch *) &right);
63 }
G4bool G4Clebsch::operator== ( const G4Clebsch right) const

Definition at line 54 of file G4Clebsch.cc.

55 {
56  return (this == (G4Clebsch *) &right);
57 }
G4double G4Clebsch::Weight ( G4int  isoIn1,
G4int  iso3In1,
G4int  isoIn2,
G4int  iso3In2,
G4int  isoOut1,
G4int  isoOut2 
) const

Definition at line 73 of file G4Clebsch.cc.

References ClebschGordan(), G4INCL::Math::max(), and G4INCL::Math::min().

Referenced by G4VXResonance::DetailedBalance(), and G4VXResonance::IsospinCorrection().

76 {
77  G4double value = 0.;
78 
79  G4int an_m = iso3In1 + iso3In2;
80 
81  G4int jMinIn = std::max(std::abs(isoIn1 - isoIn2), std::abs(an_m));
82  G4int jMaxIn = isoIn1 + isoIn2;
83 
84  G4int jMinOut = std::max(std::abs(isoOut1 - isoOut2), std::abs(an_m));
85  G4int jMaxOut = isoOut1 + isoOut2;
86 
87  G4int jMin = std::max(jMinIn,jMinOut);
88  G4int jMax = std::min(jMaxIn,jMaxOut);
89 
90  G4int j;
91  for (j=jMin; j<=jMax; j+=2)
92  {
93  value += ClebschGordan(isoIn1,iso3In1, isoIn2,iso3In2, j);
94  }
95 
96  return value;
97 }
int G4int
Definition: G4Types.hh:78
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
const XML_Char int const XML_Char * value
double G4double
Definition: G4Types.hh:76
G4double ClebschGordan(G4int isoIn1, G4int iso3In1, G4int isoIn2, G4int iso3In2, G4int jOut) const
Definition: G4Clebsch.cc:100
G4double G4Clebsch::Wigner3J ( G4double  j1,
G4double  j2,
G4double  j3,
G4double  m1,
G4double  m2,
G4double  m3 
) const

Definition at line 131 of file G4Clebsch.cc.

References G4lrint(), GetLogs(), n, and G4INCL::Math::sign().

Referenced by ClebschGordan().

133 {
134  // Calculates Wigner 3-j symbols
135 
136  G4double value = 0.;
137 
138  G4double sigma = j1 + j2 + j3;
139  std::vector<G4double> n;
140  n.push_back(-j1 + j2 + j3); // n0
141  n.push_back(j1 - m_1); // n1
142  n.push_back(j1 + m_1); // n2
143  n.push_back(j1 - j2 + j3); // n3
144  n.push_back(j2 - m_2); // n4
145  n.push_back(j2 + m_2); // n5
146  n.push_back(j1 + j2 - j3); // n6
147  n.push_back(j3 - m_3); // n7
148  n.push_back(j3 + m_3); // n8
149 
150  // Some preliminary checks
151 
152  G4bool ok = true;
153  size_t i;
154  for(i=1; i<=3; i++)
155  {
156  G4double sum1 = n[i-1] + n[i+2] + n[i+5];
157  G4double sum2 = n[3*i-1] + n[3*i-2] + n[3*i-3];
158  if (sum1 != sigma || sum2 != sigma) ok = false;
159  G4int j;
160  for(j=1; j<=3; j++)
161  {
162  if (n[i+3*j-4] < 0.) ok = false;
163  }
164  }
165 
166  if (ok)
167  {
168  G4int iMin = 1;
169  G4int jMin = 1;
170  G4double smallest = n[0];
171 
172  // Find the smallest n
173  for (i=1; i<=3; i++)
174  {
175  G4int j;
176  for (j=1; j<=3; j++)
177  {
178  if (n[i+3*j-4] < smallest)
179  {
180  smallest = n[i+3*j-4];
181  iMin = i;
182  jMin = j;
183  }
184  }
185  }
186 
187  G4int sign = 1;
188 
189  if(iMin > 1)
190  {
191  for(G4int j=1; j<=3; ++j)
192  {
193  G4double tmp = n[j*3-3];
194  n[j*3-3] = n[iMin+j*3-4];
195  n[iMin+j*3-4] = tmp;
196  }
197  sign = (G4int) std::pow(-1.,sigma);
198  }
199 
200  if (jMin > 1)
201  {
202  for(i=1; i<=3; i++)
203  {
204  G4double tmp = n[i-1];
205  n[i-1] = n[i+jMin*3-4];
206  n[i+jMin*3-4] = tmp;
207  }
208  sign *= (G4int) std::pow(-1.,sigma);
209  }
210 
211  const std::vector<G4double> logVector = GetLogs();
212  size_t n1 = G4lrint(n[0]);
213 
214  // Some boundary checks
215  G4int logEntries = logVector.size() - 1;
216  for (i=0; i<n.size(); i++)
217  {
218  if (n[i] < 0. || n[i] > logEntries)
219  throw G4HadronicException(__FILE__, __LINE__, "G4Clebsch::Wigner3J - Outside logVector boundaries, n");
220  }
221 
222  G4double r1 = n[0];
223  G4double r2 = n[3];
224  G4double r3 = n[6];
225  G4double r4 = n[1];
226  G4double r5 = n[4];
227  G4double r6 = n[7];
228  G4double r7 = n[2];
229  G4double r8 = n[5];
230  G4double r9 = n[8];
231 
232  G4double l1 = logVector[(G4int)r1];
233  G4double l2 = logVector[(G4int)r2];
234  G4double l3 = logVector[(G4int)r3];
235  G4double l4 = logVector[(G4int)r4];
236  G4double l5 = logVector[(G4int)r5];
237  G4double l6 = logVector[(G4int)r6];
238  G4double l7 = logVector[(G4int)r7];
239  G4double l8 = logVector[(G4int)r8];
240  G4double l9 = logVector[(G4int)r9];
241 
242  G4double sigma1 = sigma + 1.;
243  if (sigma1 < 0. || sigma1 > logEntries)
244  throw G4HadronicException(__FILE__, __LINE__, "G4Clebsch::Wigner3J - Outside logVector boundaries, sigma");
245 
246  G4double ls = logVector[static_cast<G4int>(sigma1+.00001)];
247  G4double hlp1 = (l2 + l3 + l4 +l7 -ls -l1 -l5 -l9 -l6 -l8) / 2.;
248  G4int expon = static_cast<G4int>(r6 + r8+.00001);
249  G4double sgn = std::pow(-1., expon);
250  G4double coeff = std::exp(hlp1) * sgn;
251 
252  G4int n61 = static_cast<G4int>(r6 - r1+.00001);
253  if (n61 < 0. || n61 > logEntries)
254  throw G4HadronicException(__FILE__, __LINE__, "G4Clebsch::Wigner3J - Outside logVector boundaries, n61");
255  G4int n81 = static_cast<G4int>(r8 - r1+.00001);
256  if (n81 < 0. || n81 > logEntries)
257  throw G4HadronicException(__FILE__, __LINE__, "G4Clebsch::Wigner3J - Outside logVector boundaries, n81");
258 
259  G4double hlp2 = l6 - logVector[n61] + l8 - logVector[n81];
260  G4double sum = std::exp(hlp2);
261  std::vector<G4double> S;
262  S.push_back(sum);
263  n1 = (size_t)r1;
264  for (i=1; i<=n1; i++)
265  {
266  G4double last = S.back();
267  G4double den = i * (r6 - r1 + i) * (r8 - r1 + i);
268  if (den == 0)
269  throw G4HadronicException(__FILE__, __LINE__, "G4Clebsch::Wigner3J - divide by zero");
270  G4double data = -last * (r1 + 1.0 - i) * (r5 + 1.0 - i) * (r9 + 1. - i) / den;
271  S.push_back(data);
272  sum += data;
273  }
274  value = coeff * sum * sign;
275  } // endif ok
276  else
277  {
278  }
279 
280 
281 // G4cout << "Wigner3j("
282 // << j1 << "," << j2 << "," << j3 << ","
283 // << m1 << "," << m2 << "," << m3 << ") = "
284 // << value
285 // << G4endl;
286 
287  return value;
288 }
const std::vector< G4double > & GetLogs() const
Definition: G4Clebsch.cc:66
int G4int
Definition: G4Types.hh:78
bool G4bool
Definition: G4Types.hh:79
const G4int n
int G4lrint(double ad)
Definition: templates.hh:163
const XML_Char int const XML_Char * value
double G4double
Definition: G4Types.hh:76
G4int sign(const T t)
const XML_Char const XML_Char * data

The documentation for this class was generated from the following files: