def turnDebugMode(cls, on=True): if on: cls.DEBUG_MODE = True else: cls.DEBUG_MODE = False XLog.resetLog() XLog('root')
def _LScoupled_MatrixElement(self): if not hasattr(self, "_kin_factor"): ## Real constant, but COM taurus multiplies by 2/(A*b^2) # self._kin_factor = (Constants.HBAR_C**2) / ( # 2 * Constants.M_MEAN # * (self.PARAMS_SHO[SHO_Parameters.b_length]**2) # * self.PARAMS_SHO[SHO_Parameters.A_Mass]) self._kin_factor = 0.5 * (Constants.HBAR_C**2) / Constants.M_MEAN #= 20.74 # self._kin_factor = 1 # self._kin_factor = 1 / (self.PARAMS_SHO[SHO_Parameters.A_Mass] # * (self.PARAMS_SHO[SHO_Parameters.b_length]**2) # * 2 * Constants.M_MEAN) fact = safe_wigner_6j(self.bra.l1, self.bra.l2, self.L_bra, self.ket.l2, self.ket.l1, 1) fact *= ((-1)**(self.ket.l1 + self.bra.l2 + self.L_bra)) nabla_1 = self._nablaReducedMatrixElement(1) nabla_2 = self._nablaReducedMatrixElement(2) if self.DEBUG_MODE: XLog.write("Lme", nabla1=nabla_1, nabla2=nabla_2, f=fact, kin_f= self._kin_factor) return fact * self._kin_factor * nabla_1 * nabla_2
def _getQRadialNumbers(self, exchanged): """ Auxiliary method to exchange the quantum numbers returns: bra_l1, bra_l2, ket_l1, ket_l2, <tuple>(bra1, bra2, ket1, ket2) """ if exchanged: l1, l2 = self.ket.l2, self.ket.l1 l1_q, l2_q = self.bra.l2, self.bra.l1 qn_cc1 = QN_1body_radial(self.bra.n2, self.bra.l2) # conjugated qn_cc2 = QN_1body_radial(self.bra.n1, self.bra.l1) # conjugated qn_3 = QN_1body_radial(self.ket.n2, self.ket.l2) qn_4 = QN_1body_radial(self.ket.n1, self.ket.l1) if self.DEBUG_MODE: XLog.write('Ltens', t="EXCH", wf=(qn_cc1, qn_cc2, qn_3, qn_4)) else: l1, l2 = self.ket.l1, self.ket.l2 l1_q, l2_q = self.bra.l1, self.bra.l2 qn_cc1 = QN_1body_radial(self.bra.n1, self.bra.l1) # conjugated qn_cc2 = QN_1body_radial(self.bra.n2, self.bra.l2) # conjugated qn_3 = QN_1body_radial(self.ket.n1, self.ket.l1) qn_4 = QN_1body_radial(self.ket.n2, self.ket.l2) if self.DEBUG_MODE: XLog.write('Ltens', t="DIR", wf=(qn_cc1, qn_cc2, qn_3, qn_4)) return l1_q, l2_q, l1, l2, (qn_cc1, qn_cc2, qn_3, qn_4)
def _LScoupled_MatrixElement(self): """ <(n1,l1)(n2,l2) (LS)| V |(n1,l1)'(n2,l2)'(L'S') (T)> """ aux_sum = 0.0 # Sum of gaussians and projection operators for i in range(self.numberGaussians): self._part = i # Radial Part for Gaussian Integral radial_energy = self.centerOfMassMatrixElementEvaluation() if self.DEBUG_MODE: XLog.write( 'BB', mu=self.PARAMS_FORCE[i][CentralMEParameters.mu_length]) prod_part = radial_energy * self.PARAMS_FORCE[i].get( CentralMEParameters.constant) aux_sum += prod_part if self.DEBUG_MODE: XLog.write('BB', radial=radial_energy, val=prod_part) return aux_sum
def __init__(self, bra, ket, run_it=True): self.__checkInputArguments(bra, ket) self.bra = bra self.ket = ket self.J = bra.J self.T = bra.T self.exchange_phase = None self.exch_2bme = None if (bra.J != ket.J) or (bra.T != ket.T): print("Bra JT [{}]doesn't match with ket's JT [{}]" .format(bra.J, bra.T, ket.J, ket.T)) self._value = 0.0 else: self._nullConditionForSameOrbit() if not self.isNullMatrixElement and run_it: # evaluate the normal and antisymmetrized me if self.DEBUG_MODE: XLog.write('nas', bra=bra.shellStatesNotation, ket=ket.shellStatesNotation, J=self.J, T=self.T) self._run()
def saveXLog(self, title=None): #raise MatrixElementException("define the string for the log xml file (cannot have ':/\\.' etc)") if title == None: title = 'me' XLog.getLog("{}_({}_{}_{}).xml" .format(title, self.bra.shellStatesNotation.replace('/2', '.2'), self.__class__.__name__, self.ket.shellStatesNotation.replace('/2', '.2')))
def saveXLog(self, title=None): if title == None: title = 'me' auxT_ = 'T{}'.format(self.T) if hasattr(self, 'T') else '' XLog.getLog("{}_({}_{}_{})J{}{}.xml" .format(title, self.bra.shellStatesNotation.replace('/2', '.2'), self.__class__.__name__, self.ket.shellStatesNotation.replace('/2', '.2'), self.J, auxT_))
def _L_tensor_MatrixElement(self, exchanged=False): b = self.PARAMS_SHO.get(SHO_Parameters.b_length) l1_q, l2_q, l1, l2, qqnn = self._getQRadialNumbers(exchanged) qn_cc1, qn_cc2, qn_3, qn_4 = qqnn if ((l1 + l2) + (l1_q + l2_q)) % 2 == 1: return 0 factor = np.sqrt( (2 * self.L_bra + 1) * (2 * self.L_ket + 1) * (2 * l1 + 1) * (2 * l2 + 1) * (2 * l1_q + 1) * (2 * l2_q + 1)) factor /= 4 * np.pi * (b**6) # Factor include the effect of oscillator length b!= 1 aux0 = ((-1)**self.L_ket) * np.sqrt( 2 * l2 * (l2 + 1)) * (safe_3j_symbols(l1_q, l2_q, self.L_bra, 0, 0, 0) * safe_3j_symbols(l2, l1, self.L_ket, 1, 0, -1) * safe_3j_symbols(1, self.L_bra, self.L_ket, 1, 0, -1)) aux1 = ((-1)**self.L_bra) * np.sqrt(2 * l1_q * (l1_q + 1)) * ( safe_3j_symbols(l1_q, l2_q, self.L_bra, 1, 0, -1) * safe_3j_symbols(l2, l1, self.L_ket, 0, 0, 0) * safe_3j_symbols(1, self.L_ket, self.L_bra, 1, 0, -1)) aux2 = ((-1)**(self.L_bra + self.L_ket + l1 + l2)) \ * np.sqrt(l1_q*(l1_q + 1) * l2*(l2 + 1)) * ( safe_3j_symbols(l1_q, l2_q, self.L_bra, 1,0,-1) * safe_3j_symbols(l2, l1, self.L_ket, 1,0,-1) * safe_3j_symbols(1, self.L_ket, self.L_bra, 0,1,-1)) if self.DEBUG_MODE: XLog.write('Ltens', fact=factor, aux0=aux0, aux1=aux1, aux2=aux2) _RadialIntegralsLS.DEBUG_MODE = True if not self.isNullValue(aux0): aux0 *= _RadialIntegralsLS.integral(1, qn_cc1, qn_cc2, qn_3, qn_4, b) if not self.isNullValue(aux1): aux1 *= _RadialIntegralsLS.integral(1, qn_4, qn_3, qn_cc2, qn_cc1, b) if not self.isNullValue(aux2): aux2 *= _RadialIntegralsLS.integral(2, qn_cc1, qn_cc2, qn_3, qn_4, b) if self.DEBUG_MODE: XLog.write('Ltens', value=factor * (aux0 + aux1 + aux2)) return factor * (aux0 + aux1 + aux2)
def _r_dependentIntegral(self, No2, A, Z, alpha): """ Radial integral for (factors omitted) exp(-(alpha + 2)r**2) * r^2*No2 * fermi_density :No2 stands for N over 2, being N = 2*(p+p') + sum{l} + 2 """ if self._DENSITY_APROX: cte = 2**(No2 + 1.5) else: ## TODO (MOVED): pon la constante del llenado aqui tras la prueba pass cte = 2 * ((alpha + 2)**(No2 + 0.5)) aux = GaussianQuadrature.laguerre(self._auxFunction_static, (100, 0.5), No2, A, Z, alpha) if self.DEBUG_MODE: XLog.write("Ip_q", Lag_int=aux) return aux / cte
def _angularRecouplingCoefficiens(self): """ :L for the Bra <int> :S for the Bra <int> :L for the Ket <int> :S for the Ket <int> Return :null_values <bool> To skip Moshinky transformation :recoupling_coeff <float> """ # j attribute is defined as 2*j w9j_bra = safe_wigner_9j( *self.bra.getAngularSPQuantumNumbers(1, j_over2=True), *self.bra.getAngularSPQuantumNumbers(2, j_over2=True), self.L_bra, self.S_bra, self.bra.J) if not self.isNullValue(w9j_bra): recoupling = np.sqrt((self.bra.j1 + 1)*(self.bra.j2 + 1)) * w9j_bra if self.DEBUG_MODE: re1 = ((self.bra.j1 + 1)*(self.bra.j2 + 1)*(2*self.S_bra + 1) *(2*self.L_bra + 1))**.5 * w9j_bra XLog.write('recoup', Lb=self.L_bra, Sb=self.S_bra, re_b=re1) w9j_ket = safe_wigner_9j( *self.ket.getAngularSPQuantumNumbers(1, j_over2=True), *self.ket.getAngularSPQuantumNumbers(2, j_over2=True), self.L_ket, self.S_ket, self.ket.J) if not self.isNullValue(w9j_ket): recoupling *= w9j_ket recoupling *= np.sqrt((self.ket.j1 + 1)*(self.ket.j2 + 1)) recoupling *= np.sqrt((2*self.S_bra + 1)*(2*self.L_bra + 1) *(2*self.S_ket + 1)*(2*self.L_ket + 1)) if self.DEBUG_MODE: re2 = ((self.ket.j1 + 1)*(self.ket.j2 + 1)*(2*self.S_ket + 1) *(2*self.L_ket + 1))**.5 * w9j_ket XLog.write('recoup', Lk=self.L_ket, Sk=self.S_ket, cts=re1*re2) return (False, recoupling) return (True, 0.0)
def _integral(self, wf1_bra, wf2_bra, wf1_ket, wf2_ket, b_length, A, Z, alpha): n1_q, l1_q = wf1_bra.n, wf1_bra.l n2_q, l2_q = wf2_bra.n, wf2_bra.l n1, l1 = wf1_ket.n, wf1_ket.l n2, l2 = wf2_ket.n, wf2_ket.l self.b_length = b_length ## keep for _DensityProfile if (l1 + l2 + l1_q + l2_q) % 2 == 1: raise IntegralException("(l1 + l2 + l1_q + l2_q) not even") sum_ = 0 if self.DEBUG_MODE: XLog.write("R_int", a=wf1_bra, b=wf2_bra, c=wf1_ket, d=wf2_ket) # for p1 in range(n1_q+n2_q +1): for p1 in range(n1_q+n1 +1): ket_coeff = self._B_coeff(n1_q, l1_q, n1, l1, p1) # ket_coeff = self._B_coeff(n1_q, l1_q, n2_q, l2_q, p1) if self.DEBUG_MODE: XLog.write("Ip", p1=p1, ket_C=ket_coeff) for p2 in range(n2_q+n2 +1): bra_coeff = self._B_coeff(n2_q, l2_q, n2, l2, p2) # for p2 in range(n1+n2 +1): # bra_coeff = self._B_coeff(n1, l1, n2, l2, p2) # l1 + l2 + l1_q + l2_q is even No2 = (p1 + p2) + ((l1 + l2 + l1_q + l2_q)//2) + 1 I_dd = self._r_dependentIntegral(No2, A, Z, alpha) if self.DEBUG_MODE: XLog.write("Ip_q", p2=p2, bra_C=bra_coeff, N=No2, Idd=I_dd) aux = ket_coeff * bra_coeff * I_dd sum_ += aux if self.DEBUG_MODE: XLog.write("Ip_q", val= aux) norm_fact = 1 / ((4*np.pi)**alpha * b_length**(3)) # b_length**(3*(1 - 2)) if not self._DENSITY_APROX: norm_fact /= b_length**(3*alpha) if self.DEBUG_MODE: XLog.write("R_int", sum=sum_, norm=norm_fact, value=norm_fact*sum_) return norm_fact * sum_
def _LScoupled_MatrixElement(self): """ <(n1,l1)(n2,l2) (LS)| V |(n1,l1)'(n2,l2)'(L'S') (T)> """ aux_sum = 0.0 # Sum of gaussians and projection operators for i in range(2): self._part = i # Radial Part for Gaussian Integral radial_energy = self.centerOfMassMatrixElementEvaluation() if self.DEBUG_MODE: XLog.write( 'BB', mu=self.PARAMS_FORCE[i][CentralMEParameters.mu_length]) # Exchange Part # W + P(S)* B - P(T)* H - P(T)*P(S)* M _S_aux = (-1)**(self.S_bra + 1) _T_aux = (-1)**(self.T) _L_aux = (-1)**(self.T + self.S_bra + 1) exchange_energy = (self.PARAMS_FORCE[i].get( bb_p.Wigner), self.PARAMS_FORCE[i].get(bb_p.Bartlett) * _S_aux, self.PARAMS_FORCE[i].get(bb_p.Heisenberg) * _T_aux, self.PARAMS_FORCE[i].get(bb_p.Majorana) * _L_aux) # Add up prod_part = radial_energy * sum(exchange_energy) aux_sum += prod_part if self.DEBUG_MODE: XLog.write('BB', radial=radial_energy, exch=exchange_energy, exch_sum=sum(exchange_energy), val=prod_part) return aux_sum
def _run(self): """ Calculates the NON antisymmetrized_ matrix element value. This overwriting allow to implement the antysimmetrization in the inner process to avoid the explicit calculation of the whole m.e. """ if self.isNullMatrixElement: return if self.DEBUG_MODE: XLog.write('nas_me', ket=self.ket.shellStatesNotation) # antisymmetrization_ taken in the inner evaluation self._value = self._LS_recoupling_ME() if self.DEBUG_MODE: XLog.write('nas_me', value=self._value, norms=self.bra.norm()*self.ket.norm()) # value is always M=0, M_T=0 self._value *= self.bra.norm() * self.ket.norm()
def _BrodyMoshinskyTransformation(self): """ ## WARNING: This method is final. Do not overwrite!! Sum over valid p-Talmi integrals range (Energy + Ang. momentum + parity conservation laws). Call implemented Talmi Coefficients for Brody-Moshinsky transformation """ sum_ = 0.0 if self.DEBUG_MODE: XLog.write('talmi') for p in range(max(self.rho_bra, self.rho_ket) + 1): if self.DEBUG_MODE: XLog.write('talmi', p=p) self._p = p # 2* from the antisymmetrization_ (_deltaConditionsForCOM_Iteration) series = 2 * self._interactionSeries() Ip = self.talmiIntegral() product = series * Ip sum_ += product # sum_ += self._interactionSeries() * self.talmiIntegral() if self.DEBUG_MODE: XLog.write('talmi', series=series, Ip=Ip, val=product) return self._globalInteractionCoefficient() * sum_
def _run(self): if self.isNullMatrixElement: return if self.DEBUG_MODE: XLog.write('nas_me', ket=self.ket.shellStatesNotation) # antisymmetrization_ taken in the inner evaluation self._value = self._RadialCoeff() self._value *= self._AngularCoeff() if self.DEBUG_MODE: XLog.write('nas_me', value=self._value, norms=self.bra.norm()*self.ket.norm()) self._value *= self.bra.norm() * self.ket.norm() if self._evaluateMSDI: ## V_MSDI = V_SDI + B * <tau(1) · tau(2)> + C (only off-diagonal) if self.T == 0: self._value += self._msdi_T0 elif self.T == 1: self._value += self._msdi_T1
def _LScoupled_MatrixElement(self): """ <(n1,l1)(n2,l2) (LS)| V |(n1,l1)'(n2,l2)'(L'S') (JT)> This matrix element don't call directly to centerOfMassMatrixElementEvaluation since this name is reserved for the center of mass transformation. Extracted from Dr. Tomas Gonzalez Llarena (1999) """ skip, spin_me = self._totalSpinTensorMatrixElement() if skip or self.T == 0: return 0 # factor = safe_racah(self.L_bra, self.L_ket, self.S_bra, self.S_ket, 1, self.J) factor = safe_wigner_6j(self.L_bra, 1, self.L_ket, self.S_bra, self.J, self.S_ket) factor *= (-1)**(self.L_ket + self.J) * spin_me if (self.isNullValue(factor) or not self.deltaConditionsForGlobalQN()): # same delta conditions act here, since tensor is rank 1 return 0 if self.DEBUG_MODE: XLog.write("LSme") dir_ = self._L_tensor_MatrixElement() exch = self._L_tensor_MatrixElement(exchanged=True) # Notice that the matrix element is not antisymmetrized_ (exchanged is # just a name), tbme_ are permutable, then the factor *2 to antisymmetr_ factor *= self.PARAMS_FORCE.get(CentralMEParameters.constant) aux = 2 * factor * (dir_ + ((-1)**(self.L_bra + self.L_ket)) * exch) # ^-- factor 2 for the antisymmetrization_ if self.DEBUG_MODE: XLog.write("LSme", factor=factor, dir=dir_, exch=exch, value=aux) return aux
def _interactionSeries(self): sum_ = 0.0 if self.DEBUG_MODE: XLog.write('intSer') for qqnn_bra in self._validCOM_Bra_qqnn(): self._n, self._l, self._N, self._L = qqnn_bra bmb_bra = BM_Bracket(self._n, self._l, self._N, self._L, self.bra.n1, self.bra.l1, self.bra.n2, self.bra.l2, self.L_bra) if self.isNullValue(bmb_bra): continue for l_q in self._validKet_relativeAngularMomentums(): self._l_q = l_q self._n_q = self._n self._n_q += (self.rho_ket - self.rho_bra + self._l - self._l_q) // 2 if self._n_q < 0 or not self._deltaConditionsForCOM_Iteration( ): continue bmb_ket = BM_Bracket(self._n_q, self._l_q, self._N, self._L, self.ket.n1, self.ket.l1, self.ket.n2, self.ket.l2, self.L_ket) if self.isNullValue(bmb_ket): continue _b_coeff = self._B_coefficient( self.PARAMS_SHO.get(SHO_Parameters.b_length)) _com_coeff = self._interactionConstantsForCOM_Iteration() aux = _com_coeff * bmb_bra * bmb_ket * _b_coeff sum_ += aux # TODO: comment when not debugging if self.DEBUG_MODE: XLog.write('intSer', bmbs=bmb_bra * bmb_ket, B=_b_coeff, comCoeff=_com_coeff, aux=aux) # self._debbugingTable(bmb_bra, bmb_ket, _com_coeff, _b_coeff) if self.DEBUG_MODE: XLog.write('intSer', value=sum_) return sum_
def _run(self): """ Calculate the explicit antisymmetric matrix element value. """ if self.isNullMatrixElement: return # construct the exchange ket phase, exchanged_ket = self.ket.exchange() self.exchange_phase = phase self.exch_2bme = self.__class__(self.bra, exchanged_ket, run_it=False) if self.DEBUG_MODE: XLog.write('na_me', p='DIRECT', ket=self.ket.shellStatesNotation) # value is always M=0, M_T=0 self._value = self._LS_recoupling_ME() self._value *= self.bra.norm() * self.ket.norm() if self.DEBUG_MODE: XLog.write('na_me', phs=phase) XLog.write('nas', norms=self.bra.norm()*self.ket.norm(), value=self._value)
def _run(self): """ Calculate the antisymmetric matrix element value. """ if self.isNullMatrixElement: return if self.T != 1: # Spin-orbit approximation antisymmetrization_ condition 1 - PxPsPt = # 1 + delta(tau1, tau2) => T=0 is null (factor 2 in the m.e. below) self._value = 0.0 self._isNullMatrixElement = True return if self.DEBUG_MODE: XLog.write('nas', ket=self.ket.shellStatesNotation) self._value = self._LS_recoupling_ME() self._value *= self.bra.norm() * self.ket.norm() if self.DEBUG_MODE: XLog.write('nas', value=self._value) XLog.write('nas', norms=self.bra.norm() * self.ket.norm())
def _integral(self, type_integral, wf1_bra, wf2_bra, wf1_ket, wf2_ket, b_length): assert type_integral in (1, 2), "type_integral can only be 1 or 2" n1_q, l1_q = wf1_bra.n, wf1_bra.l n2_q, l2_q = wf2_bra.n, wf2_bra.l n1, l1 = wf1_ket.n, wf1_ket.l n2, l2 = wf2_ket.n, wf2_ket.l sum_ = 0 if self.DEBUG_MODE: XLog.write("R_int", type=type_integral, wf1=wf1_bra, wf2=wf2_bra, wf3=wf1_ket, wf4=wf2_ket) for p in range(n1+n2 +1): ket_coeff = self._B_coeff(n1, l1, n2, l2, p) if self.DEBUG_MODE: XLog.write("Ip", p=p, ket_C=ket_coeff) for p_q in range(n1_q+n2_q +1): bra_b = self._B_coeff(n1_q, l1_q, n2_q, l2_q, p_q) No2 = (p + p_q) + ((l1 + l2 + l1_q + l2_q)//2) I_1 = self._r_dependentIntegral(No2) if self.DEBUG_MODE: XLog.write("Ip_q", pq=p_q, bra_B=bra_b, N=No2, I_1=I_1) if type_integral == 1: bra_d = self._D_coeff(n1_q, l1_q, n2_q, l2_q, p_q) I_2 = self._r_dependentIntegral(No2 + 1) aux = ket_coeff * ((bra_d*I_1) - (bra_b*I_2)) sum_ += aux if self.DEBUG_MODE: XLog.write("Ip_q", I_2=I_2, bra_D=bra_d, val= aux) else: aux = ket_coeff * bra_b * I_1 sum_ += aux if self.DEBUG_MODE: XLog.write("Ip_q", val= aux) # norm_fact = np.prod([self._norm_coeff(wf) for wf in # (wf1_bra, wf2_bra, wf1_ket, wf2_ket)]) norm_fact = b_length if self.DEBUG_MODE: XLog.write("R_int", sum=sum_, norm=norm_fact, value=norm_fact*sum_) return norm_fact * sum_