51 : fTwoJ1(0), fTwoJ2(0), fLbar(1), fL(0), fDelta(0),
52 kPolyPDF(0, nullptr, -1, 1)
62 if(fCoeff == 0)
return 0;
64 if(fCoeff == 0)
return 0;
65 if(((twoJ1+twoJ2)/2 - 1) %2) fCoeff = -fCoeff;
66 return fCoeff*sqrt((2*K+1)*(twoJ1+1)*(2*LL+1)*(2*Lprime+1));
74 if(fCoeff == 0)
return 0;
77 if(fCoeff == 0)
return 0;
78 if((Lprime+K2+K1+1) % 2) fCoeff = -fCoeff;
79 return fCoeff*sqrt((twoJ1+1)*(twoJ2+1)*(2*LL+1)*(2*Lprime+1)*(2*K+1)*(2*K1+1)*(2*K2+1));
96 if(
fDelta == 0)
return transFCoeff;
106 if(
fDelta == 0)
return transF3Coeff;
114 size_t length = pol.size();
120 vector<G4double> polyPDFCoeffs(length, 0.0);
121 for(
size_t k = 0; k < length; k += 2) {
122 if(std::abs(((pol)[k])[0].imag()) >
kEps) {
123 G4cout <<
"Warning: fPolarization[" << k <<
"][0] has imag component: = "
124 << ((pol)[k])[0].real() <<
" + "
125 << ((pol)[k])[0].imag() <<
"*i" <<
G4endl;
139 size_t length = pol.size();
141 G4bool phiIsIsotropic =
true;
142 for(
size_t i=0; i<length; ++i) {
143 if(((pol)[i]).size() > 1) {
144 phiIsIsotropic =
false;
152 vector<G4double> amp(length, 0.0);
153 vector<G4double> phase(length, 0.0);
154 for(
size_t kappa = 0; kappa < length; ++kappa) {
156 for(
size_t k = kappa + (kappa % 2); k < length; k += 2) {
157 if(kappa >= length || std::abs(((pol)[k])[kappa]) <
kEps) {
continue; }
159 if(tmpAmp == 0) {
continue; }
162 cAmpSum += ((pol)[k])[kappa]*tmpAmp;
164 if(kappa == 0 && std::abs(cAmpSum.imag()) >
kEps) {
165 G4cout <<
"G4PolarizationTransition::GenerateGammaPhi: WARNING "
166 <<
" got complex amp for kappa = 0! A = " << cAmpSum.real()
167 <<
" + " << cAmpSum.imag() <<
"*i" <<
G4endl;
169 amp[kappa] = std::abs(cAmpSum);
171 G4cout <<
"G4PolarizationTransition::GenerateGammaPhi: WARNING "
172 <<
"got negative abs for kappa = " << kappa <<
G4endl;
174 phase[kappa] = arg(cAmpSum);
180 for(
size_t kappa = 0; kappa < amp.size(); ++kappa) { pdfMax += amp[kappa]; }
182 G4cout <<
"G4PolarizationTransition::GenerateGammaPhi: WARNING "
183 <<
"got pdfMax = 0 for ";
185 G4cout <<
"I suspect a non-allowed transition! Returning isotropic phi..."
191 for(
size_t i=0; i<1000; ++i) {
195 for(
size_t kappa = 1; kappa < amp.size(); ++kappa) {
196 pdfSum += amp[kappa]*cos(phi*kappa + phase[kappa]);
198 if(prob < pdfSum)
return phi;
199 if(pdfSum > pdfMax) {
200 G4cout <<
"G4PolarizationTransition::GenerateGammaPhi: WARNING "
201 <<
"got pdfSum (" << pdfSum <<
") > pdfMax ("
202 << pdfMax <<
") at phi = " << phi <<
G4endl;
206 G4cout <<
"G4PolarizationTransition::GenerateGammaPhi: WARNING "
207 <<
"no phi generated in 1000 throws! Returning isotropic phi..." <<
G4endl;
223 size_t length = pol.size();
225 size_t newlength =
fTwoJ2+1;
227 newPol.resize(newlength);
229 for(
size_t k2=0; k2<newlength; ++k2) {
230 (newPol[k2]).assign(k2+1, 0);
231 for(
size_t k1=0; k1<length; ++k1) {
232 for(
size_t k=0; k<=k1+k2; k+=2) {
238 for(
size_t kappa2=0; kappa2<=k2; ++kappa2) {
239 G4int ll = (pol[k1]).size();
240 for(
G4int kappa1 = 1 - ll; kappa1<ll; ++kappa1) {
241 if(k+k2<k1 || k+k1<k2)
continue;
243 conj((pol[k1])[-kappa1])*(kappa1 % 2 ? -1.: 1.) : (pol[k1])[kappa1];
244 if(std::abs(tmpAmp) <
kEps)
continue;
247 if(std::abs(tmpAmp) <
kEps)
continue;
252 if(std::abs(tF3) <
kEps)
break;
254 if(std::abs(tmpAmp) <
kEps)
continue;
255 tmpAmp *= ((kappa1+(
G4int)k1)%2 ? -1. : 1.)
256 * sqrt((2.*k+1.)*(2.*k1+1.)/(2.*k2+1.));
261 tmpAmp *= polar(1., phi*kappa);
263 (newPol[k2])[kappa2] += tmpAmp;
265 if(!recalcTF3 && std::abs(tF3) <
kEps)
break;
272 if(0.0 == newPol[0][0]) {
276 if(std::abs((newPol[0])[0].imag()) >
kEps) {
277 G4cout <<
"G4PolarizationTransition::UpdatePolarizationToFinalState WWARNING:"
278 <<
" P[0][0] has a non-zero imaginary part! Unpolarizing..." <<
G4endl;
284 size_t lastNonEmptyK2 = 0;
285 for(
size_t k2=0; k2<newlength; ++k2) {
286 G4int lastNonZero = -1;
287 for(
size_t kappa2=0; kappa2<(newPol[k2]).size(); ++kappa2) {
288 if(k2 == 0 && kappa2 == 0) {
292 if(std::abs((newPol[k2])[kappa2]) > 0.0) {
293 lastNonZero = kappa2;
294 (newPol[k2])[kappa2] /= (newPol[0])[0];
297 while((newPol[k2]).size() != size_t (lastNonZero+1)) (newPol[k2]).pop_back();
298 if((newPol[k2]).size() > 0) lastNonEmptyK2 = k2;
300 while(newPol.size() != lastNonEmptyK2+1) { newPol.pop_back(); }
301 (newPol[0])[0] = 1.0;
314 G4cout <<
"G4PolarizationTransition transition: ";
321 for(
size_t k=0; k<pol.size(); ++k) {
322 if(k>0)
G4cout <<
" }, { ";
323 for(
size_t kappa=0; kappa<(pol[k]).size(); ++kappa) {
324 if(kappa > 0)
G4cout <<
", ";
325 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 &)
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)
static const double twopi
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]
static const G4double kEps
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)