49 : fTwoJ1(0), fTwoJ2(0), fLbar(1), fL(0), fDelta(0), kEps(1.e-15),
50 kPolyPDF(0, nullptr, -1, 1)
60 if(fCoeff == 0)
return 0;
62 if(fCoeff == 0)
return 0;
63 if(((twoJ1+twoJ2)/2 - 1) %2) fCoeff = -fCoeff;
64 return fCoeff*sqrt((2*K+1)*(twoJ1+1)*(2*LL+1)*(2*Lprime+1));
72 if(fCoeff == 0)
return 0;
75 if(fCoeff == 0)
return 0;
76 if((Lprime+K2+K1+1) % 2) fCoeff = -fCoeff;
77 return fCoeff*sqrt((twoJ1+1)*(twoJ2+1)*(2*LL+1)*(2*Lprime+1)*(2*K+1)*(2*K1+1)*(2*K2+1));
94 if(
fDelta == 0)
return transFCoeff;
104 if(
fDelta == 0)
return transF3Coeff;
112 size_t length = pol.size();
118 vector<G4double> polyPDFCoeffs(length, 0.0);
119 for(
size_t k = 0; k < length; k += 2) {
120 if(std::abs(((pol)[k])[0].imag()) >
kEps) {
121 G4cout <<
"Warning: fPolarization[" << k <<
"][0] has imag component: = "
122 << ((pol)[k])[0].real() <<
" + "
123 << ((pol)[k])[0].imag() <<
"*i" <<
G4endl;
137 size_t length = pol.size();
139 G4bool phiIsIsotropic =
true;
140 for(
size_t i=0; i<length; ++i) {
141 if(((pol)[i]).size() > 1) {
142 phiIsIsotropic =
false;
150 vector<G4double> amp(length, 0.0);
151 vector<G4double> phase(length, 0.0);
152 for(
size_t kappa = 0; kappa < length; ++kappa) {
154 for(
size_t k = kappa + (kappa % 2); k < length; k += 2) {
155 if(kappa >= length || std::abs(((pol)[k])[kappa]) <
kEps) {
continue; }
157 if(tmpAmp == 0) {
continue; }
160 cAmpSum += ((pol)[k])[kappa]*tmpAmp;
162 if(kappa == 0 && std::abs(cAmpSum.imag()) >
kEps) {
163 G4cout <<
"G4PolarizationTransition::GenerateGammaPhi: WARNING "
164 <<
" got complex amp for kappa = 0! A = " << cAmpSum.real()
165 <<
" + " << cAmpSum.imag() <<
"*i" <<
G4endl;
167 amp[kappa] = std::abs(cAmpSum);
169 G4cout <<
"G4PolarizationTransition::GenerateGammaPhi: WARNING "
170 <<
"got negative abs for kappa = " << kappa <<
G4endl;
172 phase[kappa] = arg(cAmpSum);
178 for(
size_t kappa = 0; kappa < amp.size(); ++kappa) { pdfMax += amp[kappa]; }
180 G4cout <<
"G4PolarizationTransition::GenerateGammaPhi: WARNING "
181 <<
"got pdfMax = 0 for ";
183 G4cout <<
"I suspect a non-allowed transition! Returning isotropic phi..."
189 for(
size_t i=0; i<1000; ++i) {
193 for(
size_t kappa = 1; kappa < amp.size(); ++kappa) {
194 pdfSum += amp[kappa]*cos(phi*kappa + phase[kappa]);
196 if(prob < pdfSum)
return phi;
197 if(pdfSum > pdfMax) {
198 G4cout <<
"G4PolarizationTransition::GenerateGammaPhi: WARNING "
199 <<
"got pdfSum (" << pdfSum <<
") > pdfMax ("
200 << pdfMax <<
") at phi = " << phi <<
G4endl;
204 G4cout <<
"G4PolarizationTransition::GenerateGammaPhi: WARNING "
205 <<
"no phi generated in 1000 throws! Returning isotropic phi..." <<
G4endl;
221 size_t length = pol.size();
223 size_t newlength =
fTwoJ2+1;
225 newPol.resize(newlength);
227 for(
size_t k2=0; k2<newlength; ++k2) {
228 (newPol[k2]).assign(k2+1, 0);
229 for(
size_t k1=0; k1<length; ++k1) {
230 for(
size_t k=0; k<=k1+k2; k+=2) {
236 for(
size_t kappa2=0; kappa2<=k2; ++kappa2) {
237 G4int ll = (pol[k1]).size();
238 for(
G4int kappa1 = 1 - ll; kappa1<ll; ++kappa1) {
239 if(k+k2<k1 || k+k1<k2)
continue;
241 conj((pol[k1])[-kappa1])*(kappa1 % 2 ? -1.: 1.) : (pol[k1])[kappa1];
242 if(std::abs(tmpAmp) <
kEps)
continue;
245 if(std::abs(tmpAmp) <
kEps)
continue;
250 if(std::abs(tF3) <
kEps)
break;
252 if(std::abs(tmpAmp) <
kEps)
continue;
253 tmpAmp *= ((kappa1+(
G4int)k1)%2 ? -1. : 1.)
254 * sqrt((2.*k+1.)*(2.*k1+1.)/(2.*k2+1.));
259 tmpAmp *= polar(1., phi*kappa);
261 (newPol[k2])[kappa2] += tmpAmp;
263 if(!recalcTF3 && std::abs(tF3) <
kEps)
break;
270 if(0.0 == newPol[0][0]) {
274 if(std::abs((newPol[0])[0].imag()) >
kEps) {
275 G4cout <<
"G4PolarizationTransition::UpdatePolarizationToFinalState WWARNING:"
276 <<
" P[0][0] has a non-zero imaginary part! Unpolarizing..." <<
G4endl;
282 size_t lastNonEmptyK2 = 0;
283 for(
size_t k2=0; k2<newlength; ++k2) {
284 G4int lastNonZero = -1;
285 for(
size_t kappa2=0; kappa2<(newPol[k2]).size(); ++kappa2) {
286 if(k2 == 0 && kappa2 == 0) {
290 if(std::abs((newPol[k2])[kappa2]) > 0.0) {
291 lastNonZero = kappa2;
292 (newPol[k2])[kappa2] /= (newPol[0])[0];
295 while((newPol[k2]).size() != size_t (lastNonZero+1)) (newPol[k2]).pop_back();
296 if((newPol[k2]).size() > 0) lastNonEmptyK2 = k2;
298 while(newPol.size() != lastNonEmptyK2+1) { newPol.pop_back(); }
299 (newPol[0])[0] = 1.0;
312 G4cout <<
"G4PolarizationTransition transition: ";
319 for(
size_t k=0; k<pol.size(); ++k) {
320 if(k>0)
G4cout <<
" }, { ";
321 for(
size_t kappa=0; kappa<(pol[k]).size(); ++kappa) {
322 if(kappa > 0)
G4cout <<
", ";
323 G4cout << (pol[k])[kappa].real() <<
" + " << (pol[k])[kappa].imag() <<
"*i";
G4double FCoefficient(G4int K, G4int L, G4int Lprime, G4int twoJ2, G4int twoJ1) const
void SetCoefficients(const std::vector< G4double > &v)
G4double GenerateGammaPhi(G4double cosTheta, const POLAR &)
G4double GammaTransF3Coefficient(G4int K, G4int K2, G4int K1) const
G4double LnFactorial(int k) const
static size_t GetNCoefficients(size_t order)
G4double GenerateGammaCosTheta(const POLAR &)
static constexpr double twopi
std::vector< std::vector< G4complex > > POLAR
G4LegendrePolynomial fgLegendrePolys
std::complex< G4double > G4complex
G4GLOB_DLL std::ostream G4cout
void SetNuclearPolarization(G4NuclearPolarization *)
std::vector< std::vector< G4complex > > & GetPolarization()
static G4double Wigner9J(G4int twoJ1, G4int twoJ2, G4int twoJ3, G4int twoJ4, G4int twoJ5, G4int twoJ6, G4int twoJ7, G4int twoJ8, G4int twoJ9)
G4double GammaTransFCoefficient(G4int K) const
void SetGammaTransitionData(G4int twoJ1, G4int twoJ2, G4int Lbar, G4double delta=0, G4int Lprime=1)
~G4PolarizationTransition()
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double F3Coefficient(G4int K, G4int K2, G4int K1, G4int L, G4int Lprime, G4int twoJ2, G4int twoJ1) const
static G4double Wigner3J(G4double j1, G4double j2, G4double j3, G4double m1, G4double m2, G4double m3)
G4double EvalAssocLegendrePoly(G4int l, G4int m, G4double x)
void UpdatePolarizationToFinalState(G4double cosTheta, G4double phi, G4Fragment *)
static const G4int LL[nN]
void DumpTransitionData(const POLAR &pol) const
static G4double Wigner6J(G4int twoJ1, G4int twoJ2, G4int twoJ3, G4int twoJ4, G4int twoJ5, G4int twoJ6)
G4PolarizationTransition()
G4NuclearPolarization * GetNuclearPolarization() const
G4double GetCoefficient(size_t i, size_t order)
void SetPolarization(std::vector< std::vector< G4complex > > &p)