コード例 #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
コード例 #2
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)
コード例 #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)
コード例 #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
コード例 #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)
コード例 #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
コード例 #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
コード例 #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)
コード例 #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
コード例 #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
コード例 #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
コード例 #12
0
    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
コード例 #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
コード例 #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
コード例 #15
0
ファイル: stark.py プロジェクト: ad3ller/pypositronium
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))
コード例 #16
0
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))
コード例 #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)
コード例 #18
0
ファイル: OP_new.py プロジェクト: EigenJT/MSC
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
コード例 #19
0
ファイル: OP_new.py プロジェクト: EigenJT/MSC
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]
コード例 #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))))
コード例 #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))
コード例 #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))
コード例 #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
コード例 #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
コード例 #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.))
コード例 #26
0
ファイル: matrix_elements.py プロジェクト: b-r-oleary/acme
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)
コード例 #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))))
コード例 #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)
コード例 #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
コード例 #30
0
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)
コード例 #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
コード例 #32
0
ファイル: matrix_elements.py プロジェクト: b-r-oleary/acme
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)
コード例 #33
0
ファイル: matrix_elements.py プロジェクト: b-r-oleary/acme
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)
コード例 #34
0
ファイル: test_0009_thrj.py プロジェクト: chrinide/pyscf
 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)
コード例 #35
0
ファイル: atoms.py プロジェクト: troelsim/pyfibers
 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]
コード例 #36
0
ファイル: angmoment.py プロジェクト: ReiMatsuzaki/rescol
def N3j(*args):
    """ gives numerical value of 3-j symbol
    """
    return float(wigner.wigner_3j(*args))
コード例 #37
0
ファイル: cg.py プロジェクト: 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)
コード例 #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)
     )