Example #1
0
def stark_interaction_Wigner_6j(state_1, state_2, **kwargs):
    """ Stark interaction between two states.

        <n' l' S' J' MJ'| H_S |n l S J MJ>.
    """
    field_angle = kwargs.get('field angle', 0.0)
    if not np.mod(field_angle, 180.0) == 90.0:  # parallel fields
        q_arr = [0]
        tau_arr = [1.]
    elif not np.mod(field_angle, 180.0) == 0.0:  # perpendicular fields
        q_arr = [1, -1]
        tau_arr = [(1. / 2)**0.5, -(1. / 2)**0.5]
    else:
        raise Exception('Arbitrary angles not yet supported!')

    delta_L = state_1.L - state_2.L
    delta_S = state_1.S - state_2.S
    delta_MJ = state_1.M - state_2.M
    if abs(delta_L) == 1 and delta_S == 0:
        S = state_1.S
        sum_q = []
        for q, tau in zip(q_arr, tau_arr):
            sum_q.append( (-1.)**(int(state_1.J - state_1.M)) * \
                        wigner_3j(state_1.J, 1, state_2.J, -state_1.M, -q, state_2.M) * \
                        (-1.)**(int(state_1.L + S + state_2.J + 1.)) * \
                        np.sqrt((2.*state_1.J+1.) * (2.*state_2.J+1.)) * \
                        wigner_6j(state_1.J, 1., state_2.J, state_2.L, S, state_1.L) * \
                        (-1.)**state_1.L * np.sqrt((2.*state_1.L+1.) * (2.*state_2.L+1.)) * \
                        wigner_3j(state_1.L, 1, state_2.L, 0, 0, 0) * tau)

        return np.sum(sum_q) * radial_overlap(state_1.n_eff, state_1.L,
                                              state_2.n_eff, state_2.L)
    return 0.0
def SetMatrix(I,J,AF,BF,B,gj): #Set values of interaction Hamiltonian matrix
    NMAX = int((2*J+1)*(2*I+1)) #size of matrix
    h_bar = scc.hbar #Plank constant/2pi
    mb = scc.physical_constants['Bohr magneton'][0] #Bohr magneton
    Hint=np.empty([NMAX,NMAX])
    AF = AF * h_bar * 2 * np.pi # magnetic dipole constant
    BF = BF * h_bar * 2 * np.pi # electric quadrupole constant
    sj = wigner_6j(1, J, J, J, 1, 2) * wigner_6j(1, I, I, I, 1, 2)
    m = 0
    n = 0
    for mj1 in np.arange(-J,J+1):
        if n > NMAX or m > NMAX: break #stop if n or m exceed NMAX
        for mi1 in np.arange(-I,I+1):
            if n > NMAX or m > NMAX: break
            n = 0
            for mj2 in np.arange(-J,J+1):
                if n > NMAX or m > NMAX: break
                for mi2 in np.arange(-I,I+1):
                    if n > NMAX or m > NMAX: break
                    Hint[m][n] = Delta(mi1, mi2) * Delta(mj1, mj2) * B * mb * gj * mj1 # first term of Hint

                    if I>0 and J>0 : #contribution if there is a magnetic dipole moment
                       Hint[m][n] = Hint[m][n] + AF * Minus(mj2 + mi1 + J + I)\
                       *np.sqrt(J*(J+1)*(2*J+1)*I*(I+1)*(2*I+1))\
                       *wigner_3j(J, 1, J, mj2, mj1 - mj2, -mj1)\
                       *wigner_3j(I, 1, I, mi2, mj2 - mj1, -mi1)

                    if I>0.5 and J>0.5: #contribution if there is a electric quadrupole moment
                        Hint[m][n] = Hint[m][n] + BF * Minus(mj2 + mi1 - J - I) * 15 / 2\
                        *((2 * J + 1) * (J + 1) * (2 * I + 1) * (I + 1)) / ((2 * J - 1) * (2 * I - 1))\
                        *wigner_3j(J, 2, J, mj2, mj1 - mj2, -mj1)\
                        *wigner_3j(I, 2, I, mi2, mj2 - mj1, -mi1) * sj
                    n += 1
            m += 1
    return(Hint)
Example #3
0
def calculate_microwave_ED_matrix_element(ground_state, excited_state,reduced = True, pol_vec = np.array((0,0,1))):
    #Find quantum numbers for ground state
    J = float(ground_state.J)
    F1 = float(ground_state.F1)
    F = float(ground_state.F)
    mF = float(ground_state.mF)
    I1 = float(ground_state.I1)
    I2 = float(ground_state.I2)
    
    #Find quantum numbers of excited state
    Jprime = float(excited_state.J)
    F1prime = float(excited_state.F1)
    Fprime = float(excited_state.F)
    mFprime = float(excited_state.mF)
    
    #Calculate reduced matrix element
    M_r = (np.sqrt(float((2*F1+1) * (2*F1prime+1) * (2*F+1)* (2*Fprime+1))) * float(wigner_6j(Jprime, F1prime,1/2,F1,J,1))
               * float(wigner_6j(F1prime, Fprime,1/2,F,F1,1)) * np.sqrt(float((2*J+1) * (2*Jprime+1))) 
               *(-1)**(F1prime+J+Fprime+F1+1)
               * float(wigner_3j(J,1,Jprime,0,0,0) * (-1)**J))
    
    if reduced:
        return float(M_r)
    else:
        p_vec = {}
        p_vec[-1] = -1/np.sqrt(2) * (pol_vec[0] + 1j *pol_vec[1])
        p_vec[0] = pol_vec[2]
        p_vec[1] = +1/np.sqrt(2) * (pol_vec[0] - 1j *pol_vec[1])
        
        prefactor = 0
        for p in range(-1,2):
            prefactor +=  (-1)**(p+F-mF) * p_vec[p] *  float(wigner_3j(F,1,Fprime,-mF,-p,mFprime))
        
        
        return prefactor*float(M_r)
Example #4
0
def H_hfs(A, B):
    """
    Hamiltonian hyperfine structure for the ground state.
    Through the wigner 3-J calculations.

    The two c_hfs terms come about due to the non-spherical, but present
    cylindrical symmetry of the diatomic representation of YbOh.
    If we choose to ignore them, then the energy levels will behave well
    as if it were atomic energy levels.

    Note, objects A != B.

    @type A: MolecularState Object
    @type B: MolecularState Object
    @rtype: float (Energy Value)
    """
    # hfs J.I
    H_hfs = 0
    for q in (-1, 0, 1):
        H_hfs += b_hfs * delta(A.N, B.N) * delta(A.mN, B.mN) * delta(A.mF(), B.mF()) \
        * (-1)**q * (-1)**(A.S - A.mS) * wigner_3j(A.S, 1, B.S, -A.mS, q, B.mS) \
        * (-1)**(A.I - A.mI) * wigner_3j(A.I, 1, B.I, -A.mI, -q,B.mI) \
        * np.sqrt(A.S*(A.S+1)*(2*A.S+1)) * np.sqrt(A.I * (A.I+1) * (2 * A.I + 1)) \

        H_hfs += c_hfs * ((delta(A.N,B.N) * delta(A.mN,B.mN) * delta(A.mS,B.mS) \
        * delta(A.mI,B.mI) * (A.mS*A.mI)))

        H_hfs += -c_hfs * ((1/3) * delta(A.N,B.N) * delta(A.mN,B.mN) \
        * delta(A.mF(),B.mF()) * (-1)**q * (-1)**(A.S-A.mS) \
        * wigner_3j(A.S,1,B.S,-A.mS,q,B.mS) * (-1)**(A.I-A.mI) \
        * wigner_3j(A.I,1,B.I,-A.mI,-q,B.mI) * np.sqrt(A.S*(A.S+1) * (2*A.S+1)) \
        * np.sqrt(A.I * (A.I+1) * (2*A.I+1)))
    return H_hfs
Example #5
0
def hunds_case_b_to_hunds_case_a(k,
                                 Q,
                                 J1,
                                 S1,
                                 N1,
                                 lam1,
                                 sig1,
                                 J,
                                 S,
                                 N,
                                 lam,
                                 sig,
                                 n=True):
    """
    describes the transformation between the Hunds case (a)
    basis set and the Hunds case (b) basis set. Here, we must 
    implicitly sum over all allowed values of sig and sig1
    
    see Brown and Carrington 6.149
    """

    output = ((-1)**(J + J1 - S - S1 + lam + lam1) * sqrt(
        (2 * N + 1) *
        (2 * N1 + 1)) * wigner_3j(J1, S1, N1, lam1 + sig1, -sig1, -lam1) *
              wigner_3j(J, S, N, lam + sig, -sig, -lam) *
              reduced_lab_to_mol(J, lam + sig, k, Q, J1, lam1 + sig1))

    return formated_output(output, n=n)
Example #6
0
 def WeightFunction(l1, l2, l12, l3, l4, m1, m2, m3, m4):
     """C_m^Lambda for 4th order isotropic basis function"""
     pref = pow(-1., l1 + l2 + l3 + l4) * np.sqrt(2. * l12 + 1.)
     wig1 = np.float64(wigner_3j(l1, l2, l12, m1, m2, -m1 - m2))
     if wig1 == 0: return 0.
     wig2 = np.float64(wigner_3j(l12, l3, l4, m1 + m2, m3, m4))
     if wig2 == 0: return 0.
     summ = wig1 * wig2 * pow(-1., l12 - m1 - m2)
     return summ * pref
Example #7
0
def QuadMoment(Nmax,I1,I2):
    ''' Calculate the nuclear electric quadrupole moments of nuclei 1 and 2.

    spherical tensor for the nuclear quadrupole moment of both nuclei. Depends
    on the nuclear spin states not the rotational states.
    Args:
        Nmax (int) - Maximum rotational state to include
        I1,I2 (float) - The nuclear spins of nucleus 1 and 2
    Returns:
        T (list of numpy.ndarray) - length-5 list of numpy.ndarrays

    '''
    shape1 = int(2*I1+1)
    shape1 = (shape1,shape1)

    T1 = [numpy.zeros(shape1),numpy.zeros(shape1),
        numpy.zeros(shape1),
        numpy.zeros(shape1),numpy.zeros(shape1)]

    shape2 = int(2*I2+1)
    shape2 = (shape2,shape2)

    T2 = [numpy.zeros(shape2),numpy.zeros(shape2),
        numpy.zeros(shape2),
        numpy.zeros(shape2),numpy.zeros(shape2)]

    ShapeN = int(sum([2*x+1 for x in range(0,Nmax+1)]))

    IdentityN = numpy.identity(ShapeN)
    Identity1 = numpy.identity(int(2*I1+1))
    Identity2 = numpy.identity(int(2*I2+1))

    x=-1
    for M1 in numpy.arange(I1,-(I1+1),-1):
        x+=1
        y=-1
        for M1p in numpy.arange(I1,-(I1+1),-1):
            y+=1
            for i,q in enumerate(range(-2,2+1)):
                T1[i][x,y]=(-1)**(I1-M1)*wigner_3j(I1,2,I1,-M1,q,M1p)/\
                wigner_3j(I1,2,I1,-I1,0,I1)
    x=-1
    for M2 in numpy.arange(I2,-(I2+1),-1):
        x+=1
        y=-1
        for M2p in numpy.arange(I2,-(I2+1),-1):
            y+=1
            for i,q in enumerate(range(-2,2+1)):
                T2[i][x,y]=(-1)**(I2-M2)*wigner_3j(I2,2,I2,-M2,q,M2p)/\
                wigner_3j(I2,2,I2,-I2,0,I2)

    for i,q in enumerate(range(-2,2+1)):
        T1[i] = numpy.kron(IdentityN,numpy.kron(T1[i],Identity2))
        T2[i] = numpy.kron(IdentityN,numpy.kron(Identity1,T2[i]))
    return T1,T2
Example #8
0
def calculate_microwave_ME(state1,
                           state2,
                           reduced=False,
                           pol_vec=np.array((0, 0, 1))):
    """
    Function that evaluates the microwave matrix element between two states, state1 and state2, for a given polarization
    of the microwaves
    
    inputs:
    state1 = an UncoupledBasisState object
    state2 = an UncoupledBasisState object
    reduced = boolean that determines if the function returns reduced or full matrix element
    pol_vec = np.array describing the orientation of the microwave polarization in cartesian coordinates
    
    returns:
    Microwave matrix element between state 1 and state2
    """

    #Find quantum numbers for ground state
    J = float(state1.J)
    mJ = float(state1.mJ)
    I1 = float(state1.I1)
    m1 = float(state1.m1)
    I2 = float(state1.I2)
    m2 = float(state1.m2)

    #Find quantum numbers of excited state
    Jprime = float(state2.J)
    mJprime = float(state2.mJ)
    I1prime = float(state2.I1)
    m1prime = float(state2.m1)
    I2prime = float(state2.I2)
    m2prime = float(state2.m2)

    #Calculate reduced matrix element
    M_r = (N(wigner_3j(J, 1, Jprime, 0, 0, 0)) * np.sqrt(
        (2 * J + 1) * (2 * Jprime + 1)) *
           float(I1 == I1prime and m1 == m1prime and I2 == I2prime
                 and m2 == m2prime))

    #If desired, return just the reduced matrix element
    if reduced:
        return float(M_r)
    else:
        p_vec = {}
        p_vec[-1] = -1 / np.sqrt(2) * (pol_vec[0] + 1j * pol_vec[1])
        p_vec[0] = pol_vec[2]
        p_vec[1] = +1 / np.sqrt(2) * (pol_vec[0] - 1j * pol_vec[1])

        prefactor = 0
        for p in range(-1, 2):
            prefactor += (-1)**(p - mJ) * p_vec[p] * float(
                wigner_3j(J, 1, Jprime, -mJ, -p, mJprime))

        return prefactor * float(M_r)
Example #9
0
def TwoBodyElement(Q1,Q2,m1p,m2p,m1,m2,l):
	result = 0.0
	for lp in range(0,int(2*l+1)):
		for mp in range(-lp,lp+1):
			tmp = (-1)**(-m2p-m1p-mp)
			try:
				tmp *= wigner_3j(l,lp,l,-Q1,0,Q1)*wigner_3j(l,lp,l,m2p,-mp,-m2)*wigner_3j(l,lp,l,m1p,mp,-m1)*wigner_3j(l,lp,l,-Q2,0,Q2)
			except:
				tmp *= 0.0
			result += tmp
	return ((2*l+1)**2)*((-1)**(Q1+Q2))*result
Example #10
0
def w1_coeffs(l, p, n, m, q, s):
    w1 = 0.0
    if (l >= abs(m)) and (p >= abs(q)) and (n >= abs(s)):
        if (l + p + n) % 2 == 0:
            fac = np.sqrt((sp.factorial(l + m) / sp.factorial(l - m)) *
                          (sp.factorial(p + q) / sp.factorial(p - q)) *
                          (sp.factorial(n - s) / sp.factorial(n + s)))
            w1 = ((-1)**s) * float(
                wigner_3j(l, p, n, 0, 0, 0) *
                wigner_3j(l, p, n, m, q, -s)) * fac
    return (2 * n + 1) * w1.real
Example #11
0
 def WeightFunction(l1, l2, l12, l3, l123, l4, l5, m1, m2, m3, m4, m5):
     """calE(Lambda)*C_M^Lambda for 5th order isotropic basis function"""
     pref = np.sqrt(2. * l12 + 1.) * np.sqrt(2. * l123 + 1.)
     # noting m12 = m1+m2, m123 = m1+m2+m3
     wig1 = wigner_3j(l1, l2, l12, m1, m2, -m1 - m2)
     if wig1 == 0: return 0.
     wig2 = wigner_3j(l12, l3, l123, m1 + m2, m3, -m1 - m2 - m3)
     if wig2 == 0: return 0.
     wig3 = wigner_3j(l123, l4, l5, m1 + m2 + m3, m4, m5)
     if wig3 == 0: return 0.
     summ = wig1 * wig2 * wig3 * pow(-1.,
                                     l12 - m1 - m2 + l123 - m1 - m2 - m3)
     return summ * pref
    def compute_matrix_coeff(i):
        # output submatrix
        tmp_out = np.zeros((len(ell_1), len(ell_1)))

        # i is first matrix index
        L_1, L_2, L_3 = ell_1[i], ell_2[i], ell_3[i]
        pref_1 = np.sqrt((2. * L_1 + 1.) * (2. * L_2 + 1.) * (2. * L_3 + 1.))

        for j in range(len(ell_1)):
            # j is second matrix index
            Lpp_1, Lpp_2, Lpp_3 = ell_1[j], ell_2[j], ell_3[j]
            pref_2 = pref_1 * np.sqrt(
                (2. * Lpp_1 + 1.) * (2. * Lpp_2 + 1.) * (2. * Lpp_3 + 1.))
            # add phase
            pref_2 *= (-1.)**(Lpp_1 + Lpp_2 + Lpp_3)

            for k in range(len(ell_1)):
                # k indexes inner Lambda' term
                Lp_1, Lp_2, Lp_3 = ell_1[k], ell_2[k], ell_3[k]

                # Compute prefactor
                pref = pref_2 * np.sqrt(
                    (2. * Lp_1 + 1.) * (2. * Lp_2 + 1.) *
                    (2. * Lp_3 + 1.)) / (4. * np.pi)**(3. / 2.)

                # Compute 3j couplings
                three_j_piece = np.float64(wigner_3j(L_1, Lp_1, Lpp_1, 0, 0,
                                                     0))
                if three_j_piece == 0: continue
                three_j_piece *= np.float64(
                    wigner_3j(L_2, Lp_2, Lpp_2, 0, 0, 0))
                if three_j_piece == 0: continue
                three_j_piece *= np.float(wigner_3j(L_3, Lp_3, Lpp_3, 0, 0, 0))
                if three_j_piece == 0: continue

                # Compute the 9j component
                nine_j_piece = np.float64(
                    wigner_9j(L_1,
                              Lp_1,
                              Lpp_1,
                              L_2,
                              Lp_2,
                              Lpp_2,
                              L_3,
                              Lp_3,
                              Lpp_3,
                              prec=8))
                if nine_j_piece == 0: continue

                tmp_out[j, k] = pref * three_j_piece * nine_j_piece
        return tmp_out
Example #13
0
def xdipole_wigner3j_recurrence(l, wig_1llp1_000, wig_1llm1_000,
                                wig_1llp1_1m10, wig_1llm1_1m10):
    #routine for computing successive Wigner3j symbols for x-polarized dipole based on recurrence
    #wig_1llp1_000 stores wigner symbols of the form (1 l l+1 ; 0 0 0)
    #wig_1llm1_000 stores wigner symbols of the form (1 l l-1 ; 0 0 0)
    mp.dps = mp.dps * 2
    if len(wig_1llp1_000) < 2:
        #the m1=m2=m3=0 wigner3j symbols
        wig_1llp1_000.clear()
        wig_1llm1_000.clear()

        wig_1llp1_000.extend([
            mp.mpf(wigner_3j(1, 1, 2, 0, 0, 0).evalf(mp.dps)),
            mp.mpf(wigner_3j(1, 2, 3, 0, 0, 0).evalf(mp.dps))
        ])
        wig_1llm1_000.extend([
            mp.mpf(wigner_3j(1, 1, 0, 0, 0, 0).evalf(mp.dps)),
            mp.mpf(wigner_3j(1, 2, 1, 0, 0, 0).evalf(mp.dps))
        ])

        #the m1=1, m2=-1, m3=0 wigner3j symbols
        wig_1llp1_1m10.clear()
        wig_1llm1_1m10.clear()

        wig_1llp1_1m10.extend([
            mp.mpf(wigner_3j(1, 1, 2, 1, -1, 0).evalf(mp.dps)),
            mp.mpf(wigner_3j(1, 2, 3, 1, -1, 0).evalf(mp.dps))
        ])

        wig_1llm1_1m10.extend([
            mp.mpf(wigner_3j(1, 1, 0, 1, -1, 0).evalf(mp.dps)),
            mp.mpf(wigner_3j(1, 2, 1, 1, -1, 0).evalf(mp.dps))
        ])

    i = len(wig_1llp1_000)
    while i < l:
        i = i + 1
        mp_i = mp.mpf(i)

        wig_1llm1_000.append(-mp.sqrt(mp_i * (2 * mp_i - 3) /
                                      ((mp_i - 1) * (2 * mp_i + 1))) *
                             wig_1llp1_000[i - 3])
        wig_1llp1_000.append(-mp.sqrt(
            (2 * mp_i - 1) * (mp_i + 1) / (mp_i * (2 * mp_i + 3))) *
                             wig_1llm1_000[i - 1])

        wig_1llm1_1m10.append(
            (wig3j_j2rec_j2m1_factor(1, i, i - 1, 1, -1, 0) *
             wig3j_j2rec_j2m1_factor(1, i - 1, i - 1, 1, -1, 0) +
             wig3j_j2rec_j2m2_factor(1, i, i - 1, 1, -1, 0)) *
            wig_1llp1_1m10[i - 1 - 2])

        wig_1llp1_1m10.append(
            (wig3j_j3rec_j3m1_factor(1, i, i + 1, 1, -1, 0) *
             wig3j_j3rec_j3m1_factor(1, i, i, 1, -1, 0) +
             wig3j_j3rec_j3m2_factor(1, i, i + 1, 1, -1, 0)) *
            wig_1llm1_1m10[i - 1])

    mp.dps = mp.dps // 2
Example #14
0
 def calc_hyperfine_transition_dipole(self, Fg, Fe, mFg, mFe, q):
     dFF = (self.dJJ * (-1)**(Fe + self.Jg + 1 + self.Inuc) * np.sqrt(
         (2 * Fe + 1) * (2 * self.Jg + 1)) *
            wigner_6j(self.Jg, self.Je, 1, Fe, Fg, self.Inuc))  #.evalf())
     d_hf = dFF * (-1)**(Fe - 1 + mFg) * np.sqrt(2 * Fg + 1) * wigner_3j(
         Fe, 1, Fg, mFe, q, -mFg)  #.evalf()
     return d_hf
Example #15
0
def _ang_integral(S, L1, J1, MJ1, L2, J2, MJ2):
    """Calculate the angular integral (cached).

    Parameters
    ----------
    S : int
        spin
    L1 : int
        orbital angular momentum, state 1
    J1 : int
        total angular momentum, state 1
    MJ1 : int
        projection of the total angular momentum, state 1
    L2 : int
        orbital angular momentum, state 2
    J2 : int
        total angular momentum, state 2
    MJ2 : int
        projection of the total angular momentum, state 2

    Returns
    -------
    float

    """
    return float(
        (-1.0)**(S + 1 + MJ2) *
        np.sqrt(max(L1, L2) * (2 * J2 + 1) * (2 * J1 + 1)) *
        wigner_3j(J2, 1, J1, -MJ2, 0, MJ1) * wigner_6j(S, L2, J2, 1, J1, L1))
def Yl_red(l1, l2, l):
    """
    < l1 || Y_l || l2 >
    Note: all inputs are not not doubled
    """
    return (-1)**l1 * np.sqrt((2 * l1 + 1) * (2 * l2 + 1) * (2 * l + 1) /
                              (4 * np.pi)) * N(wigner_3j(l1, l, l2, 0, 0, 0))
Example #17
0
 def F_func_2(self):
     """ define the F in eq(14) with the l2, L, l1 order """
     ell1 = self.ell1
     ell = self.ell
     ell2 = self.ell2
     spin = self.spin
     return self.H_func()*wigner_3j(ell2, ell, ell1, spin, 0, -spin)
Example #18
0
def mu(N_u,J_u,F_u,F_uz,N_l,J_l,F_l,F_lz,I,q):#compute the dipole moment. from eq. 4.33 pg 55 in Laser cooling and Trapping (Metcalf)
	rad_el = Rad(N_u,J_u,N_l,J_l)*a_0 #q is the photon polarization q = +-1 or 0
	exp = c_e*(-1.0)**(1+(J_u-0.5)+0.5+J_l+J_u+I-F_uz)
	sqrt = n.sqrt((2.0*J_u+1.0)*(2.0*J_l+1.0)*(2.0*F_u+1.0)*(2.0*F_l+1.0))
	wig6 = wigner_6j((J_u-0.5),J_u,0.5,J_l,(J_l-0.5),1)*wigner_6j(J_u,F_u,I,F_l,J_l,1)
	wig3 = wigner_3j(F_l,1,F_u,F_lz,q,-F_uz)
	mu = rad_el*exp*sqrt*wig6*wig3
	return mu
Example #19
0
def A_calc(J_u,F_u,F_uz,J_l,F_l,F_lz,I,q):#compute the dipole moment. from eq. 4.33 pg 55 in Laser cooling and Trapping (Metcalf)
	#q is the photon polarization q = +-1 or 0
	exp = c_e*(-1.0)**(1+(J_u-0.5)+0.5+J_l+J_u+I-F_uz)
	sqrt = n.sqrt((2.0*J_u+1.0)*(2.0*J_l+1.0)*(2.0*F_u+1.0)*(2.0*F_l+1.0))
	wig6 = wigner_6j((J_u-0.5),J_u,0.5,J_l,(J_l-0.5),1)*wigner_6j(J_u,F_u,I,F_l,J_l,1)
	wig3 = float(wigner_3j(F_l,1,F_u,F_lz,q,-F_uz))
	A_calc = exp*sqrt*wig6*wig3
	return [A_calc,exp,sqrt,wig6,wig3]
Example #20
0
def AC_aniso(Nmax,a2,Beta,I1,I2):
    ''' Calculate anisotropic ac stark shift.

        Generates the effect of the anisotropic AC Stark shift for a rigid-rotor
        like molecule.

        This term is calculated differently to all of the others in this work
        and is based off Jesus Aldegunde's FORTRAN 77 code. It iterates over
        N,MN,N',MN' to build a matrix without hyperfine structure then uses
        kronecker products to expand it into all of the hyperfine states.

        Args:

            Nmax (int) - maximum rotational quantum number to calculate
            a2 (float) - anisotropic polarisability
            Beta (float) - polarisation angle of the laser in Radians
            I1,I2 (float) - Nuclear spin of nucleus 1,2

        Returns:
            H (numpy.ndarray): Hamiltonian in joules
     '''
    I1shape = int(2*I1+1)
    I2shape = int(2*I2+1)
    shape = numpy.sum(numpy.array([2*x+1 for x in range(0,Nmax+1)]))
    HAC = numpy.zeros((shape,shape),dtype= numpy.complex)
    i=0
    j=0
    for N1 in range(0,Nmax+1):
        for M1 in range(N1,-(N1+1),-1):
            for N2 in range(0,Nmax+1):
                for M2 in range(N2,-(N2+1),-1):
                    M = M2-M1
                    HAC[i,j]= -a2*(Wigner_D(2,M,0,Beta,0)*(-1)**M2*\
                                numpy.sqrt((2*N1+1)*(2*N2+1))*\
                                wigner_3j(N2,2,N1,0,0,0)*\
                                wigner_3j(N2,2,N1,-M2,M,M1))
                    j+=1
            j=0
            i+=1
    #final check for NaN errors, mostly this is due to division by zero or
    # multiplication by a small prefactor. it is safe to set these terms to 0
    HAC[numpy.isnan(HAC)] =0

    #return the matrix, in the full uncoupled basis.
    return (numpy.kron(HAC,numpy.kron(numpy.identity(I1shape),
            numpy.identity(I2shape))))
Example #21
0
def thj(j1, j2, j3, m1, m2, m3):
    """
    3-j symbol
    ( j1 j2 j3 )
    ( m1 m2 m3 )
    """
    #return wigner3j(j1,j2,j3,m1,m2,m3)
    return N(wigner_3j(j1, j2, j3, m1, m2, m3))
Example #22
0
def safe_3j_symbols(j1, j2, j3, m1, m2, m3):
    """
    :args     j_1, j_2, j_3, m_1, m_2, m_3
    
    Calculates the Clebsch-Gordan coefficient for the base 
    < j1 m1, j2 m2 | j3 m3 >.
    """
    return float(wigner_3j(j1, j2, j3, m1, m2, m3))
Example #23
0
def H_sr(A, B):
    """
    Hamiltonian Spin rotation

    @type A: MolecularState Object
    @type B: MolecularState Object
    @rtype: float (Energy Value)
    """
    # spin-rotation S.N
    H_sr = 0
    for q in (-1, 0, 1):
        H_sr += delta(A.mI, B.mI) * delta(A.N, B.N) * delta(A.mF(), B.mF()) * \
        (-1)**q * (-1) ** (A.S - A.mS) * wigner_3j(A.S, 1, B.S, -A.mS, q, B.mS) * \
        (-1)**(A.N - A.mN) * wigner_3j(A.N, 1, B.N, -A.mN, -q, B.mN)

    H_sr = gamma * H_sr * np.sqrt(A.S * (A.S+1) * (2 * A.S+1)) \
    * np.sqrt(A.N * (A.N+1) * (2 * A.N+1))
    return H_sr
Example #24
0
 def M1_moment(A, B, q=0):
     """M1 matrix element: <A|mu|B>
         Units are mu_B """
     if (A.P *
             B.P == +1):  # check to see if the two states have same parity
         return (-1)**(A.F - A.mF) * wigner_3j(A.F, 1, B.F, -A.mF, q,
                                               B.mF) * M1_reduced_F(A, B)
     else:
         return 0
Example #25
0
def switch_basis(theta_12, BDm0, BDm1):
    '''
	Switch the bispectrum basis from Scocimarro to tripolar
	spherical harmonics by integrating over theta_12 (k1 and k2 are fixed)
	'''
    ell1 = 1
    ell2 = 0
    L = 1
    #{'k1': [0.002, 0.005, 0.01, 0.02], 'k2': [0.002, 0.005, 0.01, 0.02], 'b1': 1.08, 'b2': 0.0, 'be': 0.0,
    #'B101': [48662961.978645*sqrt(3), 78399057.5970337*sqrt(3), 76977056.1599017*sqrt(3), 37667729.8442636*sqrt(3)]}

    # B101_dict =  {'k1': [0.002, 0.005, 0.01, 0.02], 'k2': [0.002, 0.005, 0.01, 0.02], 'b1': 1.08, 'b2': 0.0, 'be': 0.0,
    #'B101': [145988885.935935*sqrt(3), 235197172.791101*sqrt(3), 230931168.479705*sqrt(3), 113003189.532791*sqrt(3)]}
    print("switch basis to (%d,%d,%d)" % (ell1, ell2, L))
    BDm0_interp = interp1d(theta_12, BDm0)
    BDm1_interp = interp1d(theta_12, BDm1)  # B_{11} = -B_{1-1}
    sp_factor = np.sqrt(4. * np.pi / (2. * ell2 + 1.))
    int1 = lambda costh_12: wigner_3j(
        ell1, ell2, L, 0, 0, 0) * sp_factor * sp.sph_harm(
            0, ell2, costh_12, 0.) * BDm0_interp(np.arccos(costh_12))  # M = 0
    int2 = lambda costh_12: wigner_3j(
        ell1, ell2, L, 0, -1, 1) * sp_factor * sp.sph_harm(
            -1, ell2, costh_12, 0.) * BDm1_interp(np.arccos(costh_12))  # M = 1
    int3 = lambda costh_12: wigner_3j(
        ell1, ell2, L, 0, 1, -1) * sp_factor * sp.sph_harm(
            1, ell2, costh_12, 0.) * BDm1_interp(np.arccos(costh_12))  # M = -1
    tmp = integrate.nquad(int1, [[-1 + ep, 1 - ep]], full_output=True)
    print("tmp = ", tmp)
    result = tmp[0]
    print("result = ", result)
    if ell2 > 0:
        ###### is there a symmetry which makes the M=1 and M=-1 contributions to cancel out?
        tmp = integrate.nquad(int2, [[-1 + ep, 1 - ep]], full_output=True)
        print("tmp = ", tmp)
        result += tmp[0]
        print("result = ", result)
        tmp = integrate.nquad(int3, [[-1 + ep, 1 - ep]], full_output=True)
        print("tmp = ", tmp)
        result += tmp[0]
        print("result = ", result)

    H = wigner_3j(ell1, ell2, L, 0, 0, 0)
    N = (2. * ell1 + 1.) * (2. * ell2 + 1) * (2. * L + 1.)
    return -0.5 * N * H * result / np.sqrt(4. * np.pi * (2. * L + 1.))
Example #26
0
def hunds_case_b_to_hunds_case_a(k, Q, 
                                 J1, S1, N1, lam1, sig1,
                                 J,  S,  N,  lam,  sig,
                                 n=True):
    """
    describes the transformation between the Hunds case (a)
    basis set and the Hunds case (b) basis set. Here, we must 
    implicitly sum over all allowed values of sig and sig1
    
    see Brown and Carrington 6.149
    """
    
    output = ((-1)**(J + J1 - S - S1 + lam + lam1) * 
              sqrt((2 * N + 1) * (2 * N1 + 1)) *
              wigner_3j(J1, S1, N1, lam1 + sig1, -sig1, -lam1) *
              wigner_3j(J,  S,  N,  lam  + sig,  -sig,  -lam)  *
              reduced_lab_to_mol(J, lam + sig, k, Q, J1, lam1 + sig1))
    
    return formated_output(output, n=n)
Example #27
0
def DC(Nmax,d0,I1,I2):
    '''
        Generates the effect of the dc Stark shift for a rigid-rotor like
        molecule.

        This term is calculated differently to all of the others in this work
        and is based off Jesus Aldegunde's FORTRAN 77 code. It iterates over
        N,MN,N',MN' to build a matrix without hyperfine structure then uses
        kronecker products to expand it into all of the hyperfine states.


        input arguments:

        Nmax: maximum rotational quantum number to calculate (int)
        d0: Permanent electric dipole momentum (float)
        I1,I2: Nuclear spin of nucleus 1,2 (float)


        returns:
        H: Hamiltonian, (2*Nmax+1)*(2*I1_mag+1)*(2*I2_mag+1)x
           (2*Nmax+1)*(2*I1_mag+1)*(2*I2_mag+1) array.
     '''

    shape = numpy.sum(numpy.array([2*x+1 for x in range(0,Nmax+1)]))
    HDC = numpy.zeros((shape,shape),dtype= numpy.complex)

    I1shape = int(2*I1+1)
    I2shape = int(2*I2+1)

    i =0
    j =0
    for N1 in range(0,Nmax+1):
        for M1 in range(N1,-(N1+1),-1):
            for N2 in range(0,Nmax+1):
                for M2 in range(N2,-(N2+1),-1):
                    HDC[i,j]=-d0*numpy.sqrt((2*N1+1)*(2*N2+1))*(-1)**(M1)*\
                    wigner_3j(N1,1,N2,-M1,0,M2)*wigner_3j(N1,1,N2,0,0,0)
                    j+=1
            j=0
            i+=1
    return (numpy.kron(HDC,numpy.kron(numpy.identity(I1shape),
            numpy.identity(I2shape))))
Example #28
0
def wigner_eckart(j, m, k, q, j1, m1, n=True):
    """
    the wigner-eckart theorem allows extraction of the 
    angular dependence of a matrix element leaving the reduced
    matrix element that is no longer dependent on spatial
    orientation (M quantum numbers).
    
    See Brown and Carrington 5.172
    """
    output = (-1)**(j - m) * wigner_3j(j, k, j1, -m, q, m1)
    return format_output(output, n=n)
Example #29
0
def angular_overlap_wigner(L_1, L_2, M_1, M_2, **kwargs):
    field_angle = kwargs.get('field_angle', 0.0)
    if not np.mod(field_angle, 180.0) == 90.0:  # parallel fields
        q_arr = [0]
        tau_arr = [1.]
    elif not np.mod(field_angle, 180.0) == 0.0:  # perpendicular fields
        q_arr = [1, -1]
        tau_arr = [(1. / 2)**0.5, (1. / 2)**0.5]
    else:
        raise Exception('Arbitrary angles not yet supported!')

    # For accumulating each element in the angular component, q sum
    sum_q = []
    for q, tau in zip(q_arr, tau_arr):
        sum_q.append(tau * float(wigner_3j(L_2, 1, L_1, -M_2, q, M_1)))
    # Calculate the angular overlap term using Wigner-3J symbols
    _angular_overlap = ((2*L_2+1)*(2*L_1+1))**0.5 * \
                          np.sum(sum_q) * \
                          wigner_3j(L_2, 1, L_1, 0, 0, 0)
    return _angular_overlap
def Wignerindex(l):
    """ Define Wigner 3-j symbol """
    selected = []
    for m1 in range(-l, l + 1):
        for m2 in range(-l, l + 1):
            for m3 in range(-l, l + 1):
                if m1 + m2 + m3 == 0:
                    windex = wigner_3j(l, l, l, m1, m2, m3).evalf()
                    selected.append(np.array([m1, m2, m3, windex]))

    return np.ravel(np.array(selected)).reshape(-1, 4)
Example #31
0
def w_term(lmax, x, F):
    res = np.zeros((len(x), lmax + 1, lmax + 1), dtype=float)
    for lx in range(lmax + 1):
        for ly in range(lmax + 1):
            if lx == ly:
                res[:, lx, ly] = pot_cent(x, lx) + pot_int(x)
            else:
                res[:, lx, ly] = -dipole(x) * F * np.sqrt(
                    (2 * lx + 1) *
                    (2 * ly + 1)) * wigner_3j(lx, ly, 1, 0, 0, 0)**2
    return res
Example #32
0
def wigner_eckart(j, m, k, q, j1, m1, n=True):
    """
    the wigner-eckart theorem allows extraction of the 
    angular dependence of a matrix element leaving the reduced
    matrix element that is no longer dependent on spatial
    orientation (M quantum numbers).
    
    See Brown and Carrington 5.172
    """
    output = (-1)**(j - m) * wigner_3j(j, k, j1, -m, q, m1)
    return format_output(output, n=n)
Example #33
0
def reduced_lab_to_mol(j, w, k, Q, j1, w1, n=True):
    """
    This function describes the transformation from the
    laboratory frame to the molecular-axis-fixed frame.
    This assumes that the angular dependence has already
    been extracted using the wigner eckart theorem.
    
    see Brown and Carrington 5.186
    """
    output = ((-1)**(j - w) * wigner_3j(j, k, j1, -w, Q, w1) *
              sqrt((2 * j + 1) * (2 * j1 + 1)))
    return format_output(output, n=n)
Example #34
0
 def test_thrj(self):
   """  """
   from sympy.physics.wigner import wigner_3j
   for l1 in range(0,3):
     for l2 in range(0,3):
       for l3 in range(0,3):
         for m1 in range(-4,4+1):
           for m2 in range(-4,4+1):
             for m3 in range(-4,4+1):
               w3j1 = thrj(l1, l2, l3, m1, m2, m3)
               w3j2 = thrj_nobuf(l1, l2, l3, m1, m2, m3)
               w3j3 = float(wigner_3j(l1, l2, l3, m1, m2, m3))
               #print(w3j1, w3j2, w3j3, l1, l2, l3)
               self.assertAlmostEqual(w3j1, w3j2)
               self.assertAlmostEqual(w3j2, w3j3)
Example #35
0
 def dipole(self, Me, Mg, q):
     """
     Find the q-spherical component of the dipole matrix element between Me and Mg
     :param M1:
     :param M2:
     :param q:
     :return:
     """
     key = "%d%d%d" % (Me, Mg, q)
     if key not in self._cache:
         self._cache[key] = (
             (-1)**(self.Ig + self.Je - Me) * self.reduced_dipole_element *
             sqrt((2*self.Fg+1)*(2*self.Fe+1)) *
             float(wigner_6j(self.Je, self.Fe, self.Ig, self.Fg, self.Jg, 1)) *
             float(wigner_3j(self.Fg, 1, self.Fe, Mg, q, -Me))
         )
     return self._cache[key]
Example #36
0
def N3j(*args):
    """ gives numerical value of 3-j symbol
    """
    return float(wigner.wigner_3j(*args))
Example #37
0
File: cg.py Project: lazovich/sympy
 def doit(self, **hints):
     if self.is_symbolic:
         raise ValueError("Coefficients must be numerical")
     return wigner_3j(self.j1, self.j2, self.j3, self.m1, self.m2, self.m3)
Example #38
0
 def gaunt_ref(l1, l2, l3, m1, m2, m3):
     return (
         sqrt((2 * l1 + 1) * (2 * l2 + 1) * (2 * l3 + 1) / (4 * pi)) *
         wigner_3j(l1, l2, l3, 0, 0, 0) *
         wigner_3j(l1, l2, l3, m1, m2, m3)
     )