def _recouplingSphHarm(self, l1, m1, l3, m3): """ _recoupling Spherical Harmonics: [Y_{l_i', m_i'}Y_{l_j, l_j}]* [Y_{l_k', m_k'}Y_{l_l, m_l}] where l_i' come from the gradient formula, we rename this value to 1 and 3 """ l2, m2 = self.wf_j.l, self.wf_j.m_l l4, m4 = self.wf_l.l, self.wf_l.m_l M_L = m1 + m2 if ((l1 + l2) + (l3 + l4))%2 == 1: # it cannot be valid L'=l3+l4 if the elements if they don't share parity return 0 if (m3 + m4) != M_L: return 0 aux = 0 for L in range(abs(l1 - l2), l1 + l2 +1, 2): # parity clebsh-gordan imply same parity for L and l1+l2 #L' = L if not angular_condition(l3, l4, L): continue elif abs(M_L) > L: continue aux += ( safe_clebsch_gordan(l1, l2, L, 0, 0, 0) * safe_clebsch_gordan(l1, l2, L, m1, m2, M_L) * safe_clebsch_gordan(l3, l4, L, 0, 0, 0) * safe_clebsch_gordan(l3, l4, L, m3, m4, M_L) ) return aux * np.sqrt((2*l1 + 1)*(2*l2 + 1)*(2*l3 + 1)*(2*l4 + 1)) /(4*np.pi)
def _check_InverseCompletnessConditionForBMB(self, rho): """ Inverse For all n, l, N, L compatible with a certain rho, evaluate same/different COM quantum numbers for two states and verify orthogonality """ max_lambda = 6 fails = [] _fail_msg_template = "[!= {}] (lambda={}) nlNL{} nlNL_prima{}, got: [{}]" for lambda_ in range(max_lambda): for n1l1n2l2 in self._allPossibleQNforARho(rho, lambda_): for n1l1n2l2_prima in self._allPossibleQNforARho(rho, lambda_): orthogonality = [] for nlNL in self._allPossibleQNforARho(rho, lambda_): aux = BM_Bracket(*nlNL, *n1l1n2l2, lambda_) \ * BM_Bracket(*nlNL, *n1l1n2l2_prima, lambda_) self._numberBMBs += 2 orthogonality.append(aux) _angular_cond_1 = angular_condition(n1l1n2l2[1], n1l1n2l2[3], lambda_) _angular_cond_2 = angular_condition(n1l1n2l2_prima[1], n1l1n2l2_prima[3], lambda_) _same_qns = n1l1n2l2 == n1l1n2l2_prima _result = sum(orthogonality) if _angular_cond_1 and _angular_cond_2: if _same_qns: if abs(_result - 1) > self.TOLERANCE: fails.append(_fail_msg_template.format( 1, lambda_, n1l1n2l2, n1l1n2l2_prima, _result)) else: if abs(_result) > self.TOLERANCE: fails.append(_fail_msg_template.format( 0, lambda_, n1l1n2l2, n1l1n2l2_prima, _result)) else: if abs(_result) != 0: fails.append(_fail_msg_template.format( 0, lambda_, n1l1n2l2, n1l1n2l2_prima, _result)) self.assertTrue(len(fails) == 0, "\n"+"\n".join(fails))
def _allPossibleQNforARho(self, rho, lambda_): for n1 in range(rho//2 +1): for n2 in range(rho//2 - n1 +1): for l1 in range(rho - 2*(n1 + n2) +1): l2 = rho - 2*(n1 + n2) - l1 if not angular_condition(l1, l2, lambda_) or (l2 < 0): continue yield (n1, l1, n2, l2)
def _validCOM_Bra_qqnn(self): rho = self.rho_bra lambda_ = self.L_bra ## Notation: big_Lambda = L + l, big_N = N + n rho_lambda_dont_pair = (rho - lambda_) % 2 valid_qqnn = [] big_Lambda_min = lambda_ if rho_lambda_dont_pair: if (lambda_ == 0): #lambda_ = 0 case for parity return valid_qqnn else: big_Lambda_min += 1 # the order is fixed to be similar to BMosh. book benchmark for n in range((rho // 2) + 1): for N in range((rho // 2) - n, -1, -1): big_N = N + n big_Lambda = rho - (2 * big_N) if big_Lambda < lambda_: # ensure angular condition on L+l >= lambda_ continue l_min = lambda_ + ((big_Lambda - big_Lambda_min) // 2) for l in range(big_Lambda - l_min, l_min + 1, +1): L = rho - l - (2 * big_N) if not angular_condition(l, L, lambda_): _ = 0 continue elif self.parity_bra + (L + l) % 2 == 1: _ = 1 continue valid_qqnn.append((n, l, N, L)) # TODO: Comment when not debugging # valid_qqnn = sorted(valid_qqnn, # key=lambda x: 1000*x[0]+100*x[1]+10*x[2]+x[3]) return valid_qqnn