Esempio n. 1
0
    def term1(self, expr, s, t, **kwargs):

        const, expr = factor_const(expr, s)

        if isinstance(expr, AppliedUndef):
            # Handle V(s), 3 * V(s) etc.  If causal is True it is assumed
            # that the unknown functions are causal.
            result = self.func(expr, s, t)
            return result * const, Zero

        if expr.has(AppliedUndef):
            return const * self.product(expr, s, t, **kwargs), Zero

        try:
            # This is the common case.
            cresult, uresult = self.ratfun(expr, s, t, **kwargs)
            return const * cresult, const * uresult
        except:
            pass

        if expr.is_Pow and expr.args[1] == -1 and expr.args[0].is_Function:
            arg = expr.args[0].args[0]

            m = self.dummy_var(expr, 'm', level=0, real=True)
            if expr.args[0].func == sym.cosh:
                scale, shift = scale_shift(arg, s)
                if shift == 0:
                    return const * 2 * sym.Sum(
                        (-1)**m * sym.DiracDelta(t - scale * (2 * m + 1)),
                        (m, 0, sym.oo)), Zero
            elif expr.args[0].func == sym.sinh:
                scale, shift = scale_shift(arg, s)
                if shift == 0:
                    return const * 2 * sym.Sum(
                        sym.DiracDelta(t - scale * (2 * m + 1)),
                        (m, 0, sym.oo)), Zero
            elif expr.args[0].func == sym.tanh:
                scale, shift = scale_shift(arg, s)
                if shift == 0:
                    return const * 2 * sym.Sum(
                        (-1)**m * sym.DiracDelta(t - scale * (2 * m + 1)),
                        (m, 1, sym.oo)) + const * sym.DiracDelta(t), Zero

        if expr.has(sym.cosh) and expr.has(sym.sinh):
            try:
                return const * self.tline_end(expr, s, t), Zero
            except:
                pass
            try:
                return const * self.tline_start(expr, s, t), Zero
            except:
                pass

        if expr.is_Pow and expr.args[0] == s:
            return Zero, const * self.power(expr, s, t)

        self.error('Cannot determine inverse Laplace transform')
Esempio n. 2
0
def generate_cross_section(N, arg, atom_list):
    """Generates the Cross-Section Formula for the one magnon case"""
    S = sp.Symbol('S', commutative=True)
    gam = sp.Symbol('gamma', commutative=True)
    r = sp.Symbol('r0', commutative=True)
    h = sp.Symbol('hbar', commutative=True)
    k = sp.Symbol('k', commutative=True)
    kp = sp.Symbol('kp', commutative=True)
    g = sp.Symbol('g', commutative=True)
    F = sp.Function('F')
    kap = sp.Symbol('kappa', commutative=True)
    kapx = sp.Symbol('kappax', commutative=True)
    kapy = sp.Symbol('kappay', commutative=True)
    w = sp.Symbol('w', commutative=True)
    W = sp.Symbol('W', commutative=False)
    t = sp.Symbol('t', commutative=True)
    dif = sp.Symbol('diff', commutative=False)

    A = sp.Wild('A', exclude=[0])
    B = sp.Wild('B', exclude=[0])
    C = sp.Wild('C', exclude=[0])
    D = sp.Wild('D', exclude=[0])

    front_constant = (gam * r)**2 / (2 * pi * h) * (kp / k) * N
    front_func = (1. / 2.) * g * F(kap) * exp(-2 * W)

    temp2 = []
    temp3 = []
    temp4 = []

    # This is were the heart of the calculation comes in.
    # First the exponentials are turned into delta functions:
    #   exp(I(wq*t - w*t)) ---> delta(wq-w)
    #   exp(I(wq*t - w*t)+I*(q-qp)*l) ---> delta(wq*t-w*t+q*l-qp*l) ---> delta(wq-w)*delta(q*l-qp*l)        # NEEDS REVIEW
    for i in range(len(arg)):  # _
        for j in range(N):  # ^
            arg[i][j] = (arg[i][j] * exp(-I * w * t)).expand()  # |
            arg[i][j] = sub_in(arg[i][j], exp(A * I * t + B * I * t),
                               sp.DiracDelta(A + B))  # |
            arg[i][j] = sub_in(arg[i][j],
                               exp(I * t * A + I * t * B + I * C + I * D),
                               sp.DiracDelta(A * t + B * t + C + D))  # |
            arg[i][j] = sub_in(arg[i][j], sp.DiracDelta(A * t + B * t + C + D),
                               sp.DiracDelta(A + B) *
                               sp.DiracDelta(C + D))  # |
            temp2.append(exp(I * kap * atom_list[j]) * arg[i][j])  # |
        temp3.append(sum(temp2))  # |
    print "Converted to Delta Functions!"  # |
    for i in range(len(temp3)):  # |
        temp4.append((1 - kapx**2) * temp3[i])  # V
    dif = front_constant * front_func**2 * (sum(temp4))  # _

    print "Cross-section calculated!"
    return dif
Esempio n. 3
0
 def __build_energy_distribution_function(energy_distribution_function,
                                          energy_spread):
     conduction_band_energy, energy, trap_central_energy_level = sym.symbols(
         'Ecb E Et')
     if energy_distribution_function in energy_distribution_functions[
             'Single Level']:
         energy_distribution = sym.DiracDelta(energy -
                                              conduction_band_energy +
                                              trap_central_energy_level)
     elif energy_distribution_function in energy_distribution_functions[
             'Gaussian Level']:
         energy_distribution = sym.exp(
             -((energy - conduction_band_energy + trap_central_energy_level)
               **2) / (2 * energy_spread**2))
         energy_distribution /= (sym.sqrt(sym.pi) * energy_spread)
         energy_distribution *= sym.sqrt(2) / 2
     elif energy_distribution_function in energy_distribution_functions[
             'Rectangular Level']:
         energy_offset = conduction_band_energy - trap_central_energy_level
         energy_distribution = (
             sym.sign(energy - energy_offset + energy_spread / 2) + 1) / 2
         energy_distribution *= (
             sym.sign(energy_offset + energy_spread / 2 - energy) + 1) / 2
         energy_distribution /= energy_spread
     else:
         raise Exception(
             'The distribution function supplied is not supported!')
     return energy_distribution
Esempio n. 4
0
    def lambd_eq_maker(self, t, x_state, U_input):  # for_ode_int
        My_helicopter = Helicopter()
        symp_eq = My_helicopter.Helicopter_model(t, x_state, U_input)
        jacobian = ((sp.Matrix(symp_eq)).jacobian(x_state)).replace(
            sp.DiracDelta(sp.sqrt(x_state[0] ** 2 + x_state[1] ** 2)), 0
        )

        J_symb_math = sp.lambdify((x_state, t) + U_input, jacobian, modules=["numpy"])
        symb_math = sp.lambdify((x_state, t) + U_input, symp_eq, modules=["numpy"])
        return symb_math, J_symb_math
Esempio n. 5
0
def normalize_dirac_delta_term(term, target):
    """Given a term of the form "f(n) δ(g(n))", shift n such
    that g(n) is `target`"""
    n = sympy.symbols('n', integer=True)
    coeff, delta = split_dirac_delta(term)
    delta_arg = delta.args[0]
    if delta_arg == target:
        return term
    else:
        for shift in [1, -1]:
            mapping = {n: n + shift}
            delta_arg_new = delta_arg.subs(mapping).simplify()
            if delta_arg_new == target:
                return coeff.subs(mapping) * sympy.DiracDelta(delta_arg_new)
        raise ValueError("Cannot bring %s to δ(%s)" % (term, target))
Esempio n. 6
0
def inverse_laplace_damped_sin(expr, s, t, **assumptions):

    ncoeffs, dcoeffs = expr.coeffs()
    K = ncoeffs[0] / dcoeffs[0]

    ncoeffs = [(c / ncoeffs[0]) for c in ncoeffs]
    dcoeffs = [(c / dcoeffs[0]) for c in dcoeffs]

    if len(ncoeffs) > 3 or len(dcoeffs) > 3:
        raise ValueError('Not a second-order response')

    omega0 = sym.sqrt(dcoeffs[2])
    zeta = dcoeffs[1] / (2 * omega0)

    if zeta.is_constant() and zeta > 1:
        print('Warning: expression is overdamped')

    sigma1 = (zeta * omega0).simplify()
    omega1 = (omega0 * sym.sqrt(1 - zeta**2)).simplify()
    K = (K / omega1).simplify()

    E = sym.exp(-sigma1 * t)
    S = sym.sin(omega1 * t)

    h = K * E * S

    # If overdamped
    #h = K * sym.exp(-sigma1 * t) * sym.sinh(omega0 * mu * t)

    if len(ncoeffs) == 1:
        return sym.S.Zero, h

    C = sym.cos(omega1 * t)
    kCd = omega1
    kSd = -sigma1
    hd = K * E * (kCd * C + kSd * S)

    if len(ncoeffs) == 2:
        return sym.S.Zero, K * E * (kCd * C + (ncoeffs[1] + kSd) * S)

    kCdd = -2 * omega1 * sigma1
    kSdd = sigma1**2 - omega1**2

    G = K * E * ((kCdd + ncoeffs[1] * kCd) * C +
                 (kSdd + ncoeffs[1] * kSd + ncoeffs[2]) * S)

    return K * kCd * sym.DiracDelta(t), G
Esempio n. 7
0
def inverse_laplace_power(expr, s, t, **assumptions):

    # Handle expressions with a power of s.
    if not (expr.is_Pow and expr.args[0] == s):
        raise ValueError('Expression %s is not a power of s' % expr)
    exponent = expr.args[1]

    # Have many possible forms; the common ones are:
    # s**a, s**-a, s**(1+a), s**(1-a), s**-(1+a), s**(a-1)
    # Cannot tell if 1-a is positive.

    if exponent.is_positive:
        # Unfortunately, SymPy does not seem to support fractional
        # derivatives...
        return sym.Derivative(sym.DiracDelta(t), t, exponent, evaluate=False)

    if exponent.is_negative:
        return sym.Pow(t, -exponent - 1) / sym.Gamma(-exponent)

    raise ValueError('Cannot determine sign of exponent for %s' % expr)
Esempio n. 8
0
import sympy as sp
from sympy.abc import x

sp.init_printing()

# %% Se definen las cargas distribuidas de acuerdo con la Tabla
# Caso 2: carga puntual
qpunt = lambda p, a: p * sp.DiracDelta(x - a)

# Caso 5: carga distribuida variable
qdist = lambda f, a, b: sp.Piecewise((f, (a < x) & (x < b)), (0, True))

# Funcion rectangular: si x>a y x<b retorne 1 sino retorne 0
rect = lambda a, b: sp.Piecewise((1, (a < x) & (x < b)), (0, True))

# Se especifica el vector de cargas q(x)
q = qdist(-12, 10, 16) + qpunt(-30, 5)

# Se define una función que hace el código más corto y legible
integre = lambda f, x: sp.integrate(f, x, meijerg=False)

# %%  Se define la geometría de la viga y las propiedades del material
b = 0.1  # Ancho de la viga, m
h = 0.3  # Altura de la viga, m
E = 210e6  # Modulo de elasticidad de la viga, kPa
I = (b * h * h * h) / 12  # Momento de inercia en z, m^4

# %% Se resuelve la ecuacion diferencial tramo por tramo
# Tramo 1
C1_1, C1_2, C1_3, C1_4 = sp.symbols('C1_1 C1_2 C1_3 C1_4')
q1 = q * rect(0, 10)  # restriccion de q al tramo 1
# symbols
t = Symbol('t', positive=True)
zeta = Symbol('\zeta', positive=True)
omegan = Symbol('\omega_n', positive=True)
omegad = Symbol('\omega_d', positive=True)
epsilon = Symbol(r'\varepsilon', positive=True)
tn = Symbol('t_n', positive=True)
P0 = Symbol('P0')
m = Symbol('m', positive=True)
u0 = 0
v0 = 0

# unknown function
u = Function('u')(t)

# solving ODE (mass-normalized EOM)
f = P0*sympy.DiracDelta(t-tn)
ics = {u.subs(t, 0): u0,
       u.diff(t).subs(t, 0): v0,
       }
sol = dsolve(u.diff(t, t) + 2*zeta*omegan*u.diff(t) + omegan**2*u - f/m, ics=ics)
display(sympy.simplify(sol.rhs))

from sympy.plotting import plot
plot(sol.rhs.subs({omegan: 10, zeta: 0.1, tn: 3, P0: 1, m: 3}), (t, 0, 10),
     adaptive=False,
     nb_of_points=1000,
     ylabel='$u(t)$')

Esempio n. 10
0
def eval_cross_section(interactionfile,
                       spinfile,
                       lattice,
                       arg,
                       tau_list,
                       h_list,
                       k_list,
                       l_list,
                       w_vect_list,
                       direction,
                       temperature,
                       kmin,
                       kmax,
                       steps,
                       eief,
                       efixed=14.7):
    """
    Calculates the cross_section given the following parameters:
    interactionfile, spinfile - files to get atom data
    lattice     - Lattice object from tripleaxisproject
    arg         - reduced list of operator combinations
    tau_list    - list of tau position
    w_list      - list of w's probed
    direction   - direction of scan
    temp        - temperature
    kmin        - minimum value of k to scan
    kmax        - maximum value of k to scan
    steps       - number of steps between kmin, kmax
    eief        - True if the energy scheme is Ei - Ef, False if it is Ef - Ei
    efixed      - value of the fixed energy, either Ei or Ef
    """

    # Read files, get atom_list and such
    atom_list, jnums, jmats, N_atoms_uc = readFiles(interactionfile, spinfile)
    N_atoms = len(atom_list)
    N = N_atoms

    # TEMPORARY TO OVERRIDE ATOM_LIST ABOVE
    #    atom1 = atom(pos = [0.00,0,0], neighbors = [1],   interactions = [0], int_cell = [0],
    #                 atomicNum = 26, valence = 3, spinRmatrix=spm.Matrix([[1, 0, 0],[0, 1, 0],[0, 0, 1]]))
    #    atom2 = atom(pos = [0.25,0,0], neighbors = [0,2], interactions = [0], int_cell = [0],
    #                 atomicNum = 26, valence = 3, spinRmatrix=spm.Matrix([[1, 0, 0],[0, 1, 0],[0, 0, 1]]))
    #    atom3 = atom(pos = [0.50,0,0], neighbors = [1,3], interactions = [0], int_cell = [0],
    #                 atomicNum = 26, valence = 3, spinRmatrix=spm.Matrix([[1, 0, 0],[0, 1, 0],[0, 0, 1]]))
    #    atom4 = atom(pos = [0.75,0,0], neighbors = [2],   interactions = [0], int_cell = [0],
    #                 atomicNum = 26, valence = 3, spinRmatrix=spm.Matrix([[1, 0, 0],[0, 1, 0],[0, 0, 1]]))
    #    atom_list,N_atoms_uc = ([atom1, atom2, atom3, atom4],1)
    N_atoms = len(atom_list)

    # Get Hsave to calculate its eigenvalues
    (Hsave, charpoly, eigs) = calculate_dispersion(atom_list,
                                                   N_atoms_uc,
                                                   N_atoms,
                                                   jmats,
                                                   showEigs=True)
    print "Calculated: Dispersion Relation"

    # Generate kappa's from (h,k,l)
    kaprange = []
    kapvect = []
    if len(h_list) == len(k_list) == len(l_list):
        for i in range(len(h_list)):
            kappa = lattice.modvec(h_list[i], k_list[i], l_list[i],
                                   'latticestar')
            kaprange.append(kappa[0])
            kapvect.append(np.array([h_list[i], k_list[i], l_list[i]]))
#            kapvect.append(np.array([h_list[i]/kappa,k_list[i]/kappa,l_list[i]/kappa]))
    else:
        raise Exception('h,k,l not same lengths')
    # Generate q's from kappa and tau
    pqrange = []
    mqrange = []
    for tau in tau_list:
        ptemp = []
        mtemp = []
        for kap in kapvect:
            #tau = lattice.modvec(tau[0],tau[1],tau[2], 'latticestar')
            ptemp.append(kap - tau)
            mtemp.append(tau - kap)
        pqrange.append(ptemp)
        mqrange.append(mtemp)
    # Calculate w_q's using q
    qrange = []
    #    krange = []
    wrange = []
    if 1:  # Change this later
        for set in pqrange:
            temp = []
            temp1 = []
            for q in set:
                eigs = calc_eigs(Hsave, q[0] * direction['kx'],
                                 q[1] * direction['ky'],
                                 q[2] * direction['kz'])
                # Take only one set of eigs. Should probably have a flag here.
                temp.append(eigs[0])
                #                krange.append(np.array([q*direction['kx'], q*direction['ky'], q*direction['kz']]))
                temp1.append(q)
            wrange.append(temp)
            qrange.append(temp1)
    print "Calculated: Eigenvalues"

    wrange = np.array(np.real(wrange))
    qrange = np.array(np.real(qrange))
    kaprange = np.array(np.real(kaprange))

    print qrange.shape
    print wrange.shape
    print kaprange.shape

    # Calculate w (not _q) as well as kp/k
    w_calc = []
    kpk = []
    if eief == True:
        for tau in tau_list:
            temp = []
            temp1 = []
            for om in w_vect_list:
                temp.append(om - efixed)
                temp1.append(np.sqrt(om / efixed))
            w_calc.append(temp)
            kpk.append(temp1)
    else:
        for tau in tau_list:
            temp = []
            temp1 = []
            for om in w_vect_list:
                temp.append(-(om - efixed))
                temp1.append(np.sqrt(efixed / om))
            w_calc.append(temp)
            kpk.append(temp1)

    w_calc = np.array(np.real(w_calc))

    # Grab Form Factors
    ff_list = []
    s = sp.Symbol('s')
    for i in range(N_atoms):
        el = elements[atom_list[i].atomicNum]
        val = atom_list[i].valence
        if val != None:
            Mq = el.magnetic_ff[val].M_Q(kaprange)
        else:
            Mq = el.magnetic_ff[0].M_Q(kaprange)
        ff_list.append(Mq)
    print "Calculated: Form Factors"

    # Other Constants
    gamr0 = 2 * 0.2695 * 10**(-12)  #sp.Symbol('gamma', commutative = True)
    hbar = 1.0  # 1.05457148*10**(-34) #sp.Symbol('hbar', commutative = True)
    g = 2.  #sp.Symbol('g', commutative = True)
    # Kappa vector
    kap = sp.Symbol(
        'kappa', real=True
    )  #spm.Matrix([sp.Symbol('kapx',real = True),sp.Symbol('kapy',real = True),sp.Symbol('kapz',real = True)])
    t = sp.Symbol('t', real=True)
    w = sp.Symbol('w', real=True)
    W = sp.Symbol('W', real=True)
    tau = sp.Symbol('tau', real=True)
    q = sp.Symbol('q', real=True)
    L = sp.Symbol('L', real=True)
    boltz = 1.  #1.3806503*10**(-23)

    # Wilds for sub_in method
    A = sp.Wild('A', exclude=[0, t])
    B = sp.Wild('B', exclude=[0, t])
    C = sp.Wild('C')
    D = sp.Wild('D')
    K = sp.Wild('K')

    # First the exponentials are turned into delta functions:
    for i in range(len(arg)):
        for j in range(N):
            print '1', arg[i][j]
            arg[i][j] = sp.powsimp(
                arg[i]
                [j])  #sp.powsimp(arg[i][j], deep = True, combine = 'all')
            arg[i][j] = (
                arg[i][j] * exp(-I * w * t) * exp(I * kap * L)).expand(
                )  # * exp(I*inner_prod(spm.Matrix(atom_list[j].pos).T,kap))
            arg[i][j] = sp.powsimp(
                arg[i]
                [j])  #sp.powsimp(arg[i][j], deep = True, combine = 'all')
            #            print '2', arg[i][j]
            arg[i][j] = sub_in(
                arg[i][j], exp(I * t * A + I * t * B + I * C + I * D + I * K),
                sp.DiracDelta(A * t + B * t + C + D + K))  #*sp.DiracDelta(C))
            #            print '3', arg[i][j]
            arg[i][j] = sub_in(
                arg[i][j],
                sp.DiracDelta(A * t + B * t + C * L + D * L + K * L),
                sp.DiracDelta(A * hbar + B * hbar) *
                sp.simplify(sp.DiracDelta(C + D + K + tau)))
            #            print '4', arg[i][j]
            arg[i][j] = sub_in(arg[i][j],
                               sp.DiracDelta(-A - B) * sp.DiracDelta(C),
                               sp.DiracDelta(A + B) * sp.DiracDelta(C))
            print '5', arg[i][j]
    print "Applied: Delta Function Conversion"

    # Grabs the unit vectors from the back of the lists.
    unit_vect = []
    kapxhat = sp.Symbol('kapxhat', commutative=False)
    kapyhat = sp.Symbol('kapyhat', commutative=False)
    kapzhat = sp.Symbol('kapzhat', commutative=False)
    for i in range(len(arg)):
        unit_vect.append(arg[i].pop())

    # Subs the actual values for kx,ky,kz, omega_q and n_q into the operator combos
    # The result is basically a nested list:
    #
    #    csdata     = [ op combos ]
    #    op combos  = [ one combo per atom ]
    #    1 per atom = [ evaluated exp ]
    #

    csdata = []
    for i in range(len(arg)):
        temp1 = []
        for j in range(len(arg[i])):
            temp2 = []
            for k in range(len(tau_list)):
                temp3 = []
                print i, j, k
                for g in range(len(qrange[k])):
                    pvalue = tau_list[k] + kapvect[g] + qrange[k][g]
                    mvalue = tau_list[k] + kapvect[g] - qrange[k][g]
                    if pvalue[0] == 0 and pvalue[1] == 0 and pvalue[2] == 0:
                        arg[i][j] = arg[i][j].subs(
                            sp.DiracDelta(kap + tau + q), sp.DiracDelta(0))
                    else:
                        arg[i][j] = arg[i][j].subs(
                            sp.DiracDelta(kap + tau + q), 0)
                    if mvalue[0] == 0 and mvalue[1] == 0 and mvalue[2] == 0:
                        arg[i][j] = arg[i][j].subs(
                            sp.DiracDelta(kap + tau - q), sp.DiracDelta(0))
                    else:
                        arg[i][j] = arg[i][j].subs(
                            sp.DiracDelta(kap + tau - q), 0)
                    wq = sp.Symbol('wq', real=True)
                    nq = sp.Symbol('n%i' % (k, ), commutative=False)
                    arg[i][j] = arg[i][j].subs(wq, wrange[k][g])
                    arg[i][j] = arg[i][j].subs(w, w_calc[k][g])
                    n = sp.Pow(
                        sp.exp(hbar * wrange[k][g] / boltz * temperature) - 1,
                        -1)
                    arg[i][j] = arg[i][j].subs(nq, n)
                    temp3.append(arg[i][j])
                temp2.append(temp3)
            temp1.append(temp2)
        csdata.append(temp1)
##            print arg[i][j]
#            for g in range(len(kaprange)):
#                arg[i][j] = arg[i][j].subs(kap, kaprange[g])
#            for g in range(len(krange)):
##                print 'calculating'
#                temp3 = []
#                wg = sp.Symbol('w%i'%(g,), real = True)
#                ng = sp.Symbol('n%i'%(g,), commutative = False)
##                kx = sp.Symbol('kx', real = True, commutative = True)
##                ky = sp.Symbol('ky', real = True, commutative = True)
##                kz = sp.Symbol('kz', real = True, commutative = True)
##                arg[i][j] = arg[i][j].subs(kx,krange[g][0])
##                arg[i][j] = arg[i][j].subs(ky,krange[g][1])
##                arg[i][j] = arg[i][j].subs(kz,krange[g][2])
#                arg[i][j] = arg[i][j].subs(wg,wrange[g])
#                arg[i][j] = arg[i][j].subs(w,w_calc[g])
#                nq = sp.Pow( sp.exp(hbar*wrange[g]/boltz*temp) - 1 ,-1)
#                arg[i][j] = arg[i][j].subs(ng,nq)
##                arg[i][j] = arg[i][j].subs(tau,tau_list[0])
#
#                temp3.append(arg[i][j])
##                print arg[i][j]
#            temp2.append(temp3)
##            print arg[i][j]
#        csdata.append(temp2)

    print csdata

    # Front constants and stuff for the cross-section
    front_constant = 1.0  # (gamr0)**2/(2*pi*hbar)
    front_func = (1. / 2.) * g  #*F(k)
    vanderwaals = 1.  #exp(-2*W)

    csrange = []
    if 1:
        temp1 = []
        temp2 = []
        for q in range(len(qrange)):
            print 'calculating'
            for ii in range(len(csdata)):
                for jj in range(len(csdata[ii])):
                    temp1.append(csdata[ii][jj])
            # Put on gamr0, 2pi hbar, form factor, kp/k, vanderwaals first
            dif = front_func**2 * front_constant  # * kpk[q][0] * vanderwaals * ff_list[0][q]
            #            for vect in unit_vect:
            #                vect.subs(kapxhat,kapvect[q][0][0])
            #                vect.subs(kapyhat,kapvect[q][1][0])
            #                vect.subs(kapzhat,kapvect[q][2][0])
            print 'diff', dif
            print 'temp1', temp1
            print sum(temp1)
            dif = (dif * sum(temp1))  # * sum(unit_vect))#.expand()
            csrange.append(dif)
    print "Calculated: Cross-section"
    csrange = np.real(csrange)
    csrange = np.array(csrange)

    xi = qrange
    yi = wrange
    zi = csrange
    Z = np.zeros((xi.shape[0], yi.shape[0]))
    Z[range(len(xi)), range(len(yi))] = zi

    pylab.contourf(xi, yi, Z)
    pylab.colorbar()
    pylab.show()
Esempio n. 11
0
    def blahblah(x, y, z):
        if y > z:
            check = lambda x, y: x + y
        else:
            check = lambda x, y: x**y
        return check(x, y)

    print blahblah(1, 2, 3)
    print blahblah(3, 2, 1)
    x = sp.Symbol('x')
    f = lambda x: sp.sin(x + 2)
    print f(x)

if 0:
    d, e = sp.symbols('de')
    print(sp.DiracDelta(0) * d + e).evalf()
    a = 1.00001
    b = 1.00001
    print sp.DiracDelta(a - b)
    c = 1.00000

    print sp.DiracDelta(a - c) * d

if 0:
    x = sp.Symbol('x', commutative=False)
    y = sp.Symbol('y', commutative=False)
    print(x * y * x * y).subs(x * y, 2)
    a, b = sp.symbols('ab')
    print(x * y).subs(x * y, y * x + 1)
    print(y * x).subs(x * y, y * x + 1)
    e = a * b
Esempio n. 12
0
def fourier_term(expr, t, f, inverse=False):

    if expr.has(sym.function.AppliedUndef) and expr.args[0] == t:
        # TODO, handle things like 3 * v(t), a * v(t), 3 * t * v(t), v(t-T),
        # v(4 * a * t), etc.
        if not isinstance(expr, sym.function.AppliedUndef):
            raise ValueError('Could not compute Fourier transform for ' +
                             str(expr))

        # Convert v(t) to V(f), etc.
        name = expr.func.__name__
        if inverse:
            name = name[0].lower() + name[1:] + '(%s)' % -f
        else:
            name = name[0].upper() + name[1:] + '(%s)' % f
        return sym.sympify(name)

    # Check for constant.
    if not expr.has(t):
        return expr * sym.DiracDelta(f)

    one = sym.sympify(1)
    const = one
    other = one
    exps = one
    factors = expr.as_ordered_factors()
    for factor in factors:
        if not factor.has(t):
            const *= factor
        else:
            if factor.is_Function and factor.func == sym.exp:
                exps *= factor
            else:
                other *= factor

    if other != 1 and exps == 1:
        if other == t:
            return const * sym.I * 2 * sym.pi * sym.DiracDelta(f, 1)
        if other == t**2:
            return const * (sym.I * 2 * sym.pi)**2 * sym.DiracDelta(f, 2)

        # Sympy incorrectly gives exp(-a * t) instead of exp(-a * t) *
        # Heaviside(t)
        if other.is_Pow and other.args[1] == -1:
            foo = other.args[0]
            if foo.is_Add and foo.args[1].has(t):
                bar = foo.args[1] / t
                if not bar.has(t) and bar.has(sym.I):
                    a = -(foo.args[0] * 2 * sym.pi * sym.I) / bar
                    return const * sym.exp(-a * f) * sym.Heaviside(
                        f * sym.sign(a))

        # Punt and use SymPy.  Should check for t**n, t**n * exp(-a * t), etc.
        return fourier_sympy(expr, t, f)

    args = exps.args[0]
    foo = args / t
    if foo.has(t):
        # Have exp(a * t**n), SymPy might be able to handle this
        return fourier_sympy(expr, t, f)

    if exps != 1 and foo.has(sym.I):
        return const * sym.DiracDelta(f - foo / (sym.I * 2 * sym.pi))

    return fourier_sympy(expr, t, f)
Esempio n. 13
0
def generate_cross_section(atom_list, arg, q, real_list, recip_list):
    """Generates the Cross-Section Formula for the one magnon case"""
    N = len(atom_list)
    gam = 1.913  #sp.Symbol('gamma', commutative = True)
    r = sp.Symbol('r0', commutative=True)
    h = 1.  # 1.05457148*10**(-34) #sp.Symbol('hbar', commutative = True)
    k = sp.Symbol('k', commutative=True)
    kp = sp.Symbol('kp', commutative=True)
    g = sp.Symbol('g', commutative=True)
    F = sp.Function('F')

    def FF(arg):
        F = sp.Function('F')
        if arg.shape == (3, 1) or arg.shape == (1, 3):
            return sp.Symbol("%r" % (F(arg.tolist()), ), commutative=False)

    kap = spm.Matrix([
        sp.Symbol('kapx', commutative=False),
        sp.Symbol('kapy', commutative=False),
        sp.Symbol('kapz', commutative=False)
    ])
    t = sp.Symbol('t', commutative=True)
    w = sp.Symbol('w', commutative=True)
    W = sp.Symbol('W', commutative=False)
    kappa = sp.Symbol('kappa', commutative=False)
    tau = sp.Symbol('tau', commutative=False)

    # Wilds for sub_in method
    A = sp.Wild('A', exclude=[0])
    B = sp.Wild('B', exclude=[0])
    C = sp.Wild('C')
    D = sp.Wild('D')

    front_constant = (gam * r)**2 / (2 * pi * h) * (kp / k) * N
    front_func = (1. / 2.) * g  #*F(k)
    vanderwaals = exp(-2 * W)

    temp2 = []
    temp3 = []
    temp4 = []

    # Grabs the unit vectors from the back of the lists.
    unit_vect = []
    kapx = sp.Symbol('kapxhat', )
    kapy = sp.Symbol('kapyhat', commutative=False)
    kapz = sp.Symbol('kapzhat', commutative=False)
    for i in range(len(arg)):
        unit_vect.append(arg[i].pop())
#    for ele in unit_vect:
#        ele = ele.subs(kapx,spm.Matrix([1,0,0]))
#        ele = ele.subs(kapy,spm.Matrix([0,1,0]))
#        ele = ele.subs(kapz,spm.Matrix([0,0,1]))
# This is were the heart of the calculation comes in.
# First the exponentials are turned into delta functions:
    for i in range(len(arg)):
        for j in range(N):
            arg[i][j] = sp.powsimp(arg[i][j], deep=True, combine='all')
            arg[i][j] = arg[i][j] * exp(-I * w * t) * exp(
                I * inner_prod(spm.Matrix(atom_list[j].pos).T, kap))
            arg[i][j] = sp.powsimp(arg[i][j], deep=True, combine='all')
            arg[i][j] = sub_in(arg[i][j], exp(I * t * A + I * t * B + C),
                               sp.DiracDelta(A * t + B * t +
                                             C / I))  #*sp.DiracDelta(C))
            arg[i][j] = sub_in(
                arg[i][j], sp.DiracDelta(A * t + B * t + C),
                sp.DiracDelta(A * h + B * h) * sp.DiracDelta(C + tau))
            arg[i][j] = sub_in(arg[i][j], sp.DiracDelta(-A - B),
                               sp.DiracDelta(A + B))
            print arg[i][j]
    print "Applied: Delta Function Conversion"

    #    for ele in arg:
    #        for subele in ele:
    #            temp2.append(subele)
    #        temp3.append(sum(temp2))
    #
    #    for i in range(len(temp3)):
    #        temp4.append(unit_vect[i] * temp3[i])

    for k in range(len(arg)):
        temp4.append(arg[k][q])
    dif = (front_func**2 * front_constant * vanderwaals * sum(temp4)
           )  #.expand()#sp.simplify(sum(temp4))).expand()

    print "Complete: Cross-section Calculation"
    return dif
Esempio n. 14
0
import sympy as sp
from sympy.abc import x

sp.init_printing()

# %% Se definen las cargas distribuidas de acuerdo con la Tabla   
# Caso 2: carga puntual 
qpunt = lambda p,a : p*sp.DiracDelta(x-a)

# Caso 5: carga distribuida variable 
qdist = lambda f,a,b : sp.Piecewise((f, (a < x) & (x < b)), (0, True))

# Funcion rectangular: si x>a y x<b retorne 1 sino retorne 0   
rect = lambda a,b : sp.Piecewise((1, (a < x) & (x < b)), (0, True))

# Se define una función que hace el código más corto y legible
integre = lambda f, x : sp.integrate(f, x, meijerg=False)

# %%  Se define la geometría de la viga y las propiedades del material
b = 0.1           # Ancho de la viga, m                       
h = 0.3           # Altura de la viga, m                      
E = 210e6         # Módulo de elasticidad de la viga, kPa     
I = (b*h*h*h)/12  # Momento de inercia en z, m^4              

# %% FORMA 1:
# Momento flector
mflec = lambda m,a : -m*sp.DiracDelta(x-a, 1)
    
# Se especifica el vector de cargas q(x)     
q = qpunt(-5,1) + qdist(-3*x/2,2,4) + mflec(-8,3.5) + mflec(3,5)
Esempio n. 15
0
import sympy as sp
from IPython.display import display
sp.init_printing()  # pretty printing

# Define impulse and unit step as functions of t
t = sp.symbols('t')
imp = sp.DiracDelta(t)
ustep = sp.Heaviside(t)
#ustep = sp.Piecewise( (0, t<1), (1, True));  # diff() doesn't give delta function?!

# Setup differential equation
x = sp.Function('x')
y = sp.Function('y')
RC = sp.symbols('RC')
#, real=True);
lp1de = sp.Eq(y(t) + RC * sp.diff(y(t), t), x(t))
#print(lp1de);  display(lp1de);

# Generic solution
y_sl0e = sp.dsolve(lp1de, y(t))
y_sl0r = y_sl0e.rhs  # take only right hand side
#print(y_sl0e);  display(y_sl0e);

# Initial condition
a0 = sp.symbols('a0')
cnd1 = sp.Eq(y_sl0r.subs(t, -1), a0)
# y(-1) = a0
#cnd2 = sp.Eq(y_sl0r.diff(t).subs(t, -1), b0)  # y'(-1) = b0
#print(cnd1);  display(cnd1);

# Solve for C1:  magic brackets in solve() returns result as dictionary
Esempio n. 16
0
def eval_cross_section(N_atoms_uc, csection, kaprange, qlist, tau_list,
                       eig_list, kapvect, wtlist):
    print "begin part 2"

    gamr0 = 2 * 0.2695e-12  #sp.Symbol('gamma', commutative = True)
    hbar = sp.S(
        1.0)  # 1.05457148*10**(-34) #sp.Symbol('hbar', commutative = True)
    g = 2.  #sp.Symbol('g', commutative = True)
    # Kappa vector
    kap = sp.Symbol(
        'kappa', real=True
    )  #spm.Matrix([sp.Symbol('kapx',real = True),sp.Symbol('kapy',real = True),sp.Symbol('kapz',real = True)])
    t = sp.Symbol('t', real=True)
    w = sp.Symbol('w', real=True)
    W = sp.Symbol('W', real=True)
    tau = sp.Symbol('tau', real=True)
    Q = sp.Symbol('q', real=True)
    L = sp.Symbol('L', real=True)
    lifetime = sp.Symbol('V', real=True)
    boltz = 8.617343e-2
    kapxhat = sp.Symbol('kapxhat', real=True)
    kapyhat = sp.Symbol('kapyhat', real=True)
    kapzhat = sp.Symbol('kapzhat', real=True)

    kapunit = kapvect.copy()
    kapunit[:, 0] = kapvect[:, 0] / kaprange
    kapunit[:, 1] = kapvect[:, 1] / kaprange
    kapunit[:, 2] = kapvect[:, 2] / kaprange

    nkpts = len(kaprange)
    nqpts = 2 * nkpts

    csdata = []
    wq = sp.Symbol('wq', real=True)

    for k in range(len(tau_list)):
        temp1 = []
        for g in range(nqpts):
            temp2 = []
            for i in range(len(eig_list[k][g])):
                #temp = eval_it(k,g,i,nkpts,csection)
                temp = csection

                for num in range(N_atoms_uc):
                    nq = sp.Symbol('n%i' % (num, ), real=True)
                    #n = sp.Pow( sp.exp(-np.abs(eig_list[k][g][i])/boltz/temperature) - 1 ,-1)
                    n = sp.S(0.0)
                    temp = temp.subs(nq, n)

                #if g==0:
                if g < nkpts:
                    value = kapvect[g] - tau_list[k] - qlist[k][g]
                    if eq(value[0], 0) == 0 and eq(value[1], 0) == 0 and eq(
                            value[2], 0) == 0:
                        temp = temp.subs(sp.DiracDelta(kap - tau - Q), sp.S(1))
                        temp = temp.subs(sp.DiracDelta(-kap + tau + Q), sp.S(
                            1))  # recall that the delta function is symmetric
                    else:
                        temp = temp.subs(sp.DiracDelta(kap - tau - Q), sp.S(0))
                        temp = temp.subs(sp.DiracDelta(-kap + tau + Q),
                                         sp.S(0))
                    temp = temp.subs(kapxhat, kapunit[g, 0])
                    temp = temp.subs(kapyhat, kapunit[g, 1])
                    temp = temp.subs(kapzhat, kapunit[g, 2])
                #value =kapvect[g//2]- tau_list[k] + qlist[k][g]
                #if g%2!=0:
                elif g >= nkpts:
                    value = kapvect[g - nkpts] - tau_list[k] - qlist[k][g]
                    if eq(value[0], 0) == 0 and eq(value[1], 0) == 0 and eq(
                            value[2], 0) == 0:
                        temp = temp.subs(sp.DiracDelta(kap - tau + Q), sp.S(1))
                        temp = temp.subs(sp.DiracDelta(-kap + tau - Q),
                                         sp.S(1))
                    else:
                        temp = temp.subs(sp.DiracDelta(kap - tau + Q), sp.S(0))
                        temp = temp.subs(sp.DiracDelta(-kap + tau - Q),
                                         sp.S(0))
                    temp = temp.subs(kapxhat, kapunit[g - nkpts, 0])
                    temp = temp.subs(kapyhat, kapunit[g - nkpts, 1])
                    temp = temp.subs(kapzhat, kapunit[g - nkpts, 2])
                value = tau_list[k]
                if eq(value[0], 0) == 0 and eq(value[1], 0) == 0 and eq(
                        value[2], 0) == 0:
                    temp = temp.subs(sp.DiracDelta(kap - tau - Q), sp.S(1))
                    temp = temp.subs(sp.DiracDelta(-kap + tau + Q), sp.S(1))  #
                    temp = temp.subs(sp.DiracDelta(kap - tau + Q), sp.S(1))
                    temp = temp.subs(sp.DiracDelta(-kap + tau - Q), sp.S(1))

                #temp = temp.subs(kapxhat,kapunit[g//2,0])
                #temp = temp.subs(kapyhat,kapunit[g//2,1])
                #temp = temp.subs(kapzhat,kapunit[g//2,2])

                value = eig_list[k][g][i] - wtlist[g]
                #print '1',temp
                temp = temp.subs(wq, eig_list[k][g][i])

                temp = temp.subs(w, wtlist[g])
                if 0:
                    if eq(value, 0) == 0:
                        temp = temp.subs(sp.DiracDelta(wq - w), sp.S(1))
                    else:
                        temp = temp.subs(sp.DiracDelta(wq - w), sp.S(0))
                if 0:
                    if eq(eig_list[k][g][i], wtlist[g]) == 0:
                        G = sp.Wild('G', exclude=[Q, kap, tau, w])
                        temp = sub_in(temp, sp.DiracDelta(G - A * w), sp.S(1))
                    elif eq(eig_list[k][g][i], -wtlist[g]) == 0:
                        G = sp.Wild('G', exclude=[Q, kap, tau, w])
                        temp = sub_in(temp, sp.DiracDelta(G - A * w), sp.S(1))
                    else:
                        temp = temp.subs(w, wtlist[g])

#                print '4',temp
                temp2.append(temp)
            temp1.append(temp2)
        csdata.append(temp1)

    #print csdata

    # Front constants and stuff for the cross-section
    front_constant = 1.0  #(gamr0)**2#/(2*pi*hbar)
    front_func = (1. / 2.) * g  #*F(k)
    debye_waller = 1.  #exp(-2*W)

    cstemp = []
    for g in range(nqpts):
        for k in range(len(tau_list)):
            cstemp.append(csdata[k][g][0].subs(lifetime, sp.S(.1)))

    print cstemp
    sys.exit()

    qtlist = np.array(qlist, 'Float64').reshape((nqpts * len(tau_list), 3))[:,
                                                                            0]
    xi = qtlist
    yi = wtlist
    zi = np.array(cstemp, 'Float64')
    Z = matplotlib.mlab.griddata(xi, yi, zi, xi, yi)
    zmin, zmax = np.min(Z), np.max(Z)
    locator = ticker.MaxNLocator(10)  # if you want no more than 10 contours
    locator.create_dummy_axis()
    locator.set_bounds(zmin, zmax)
    levs = locator()
    levs[0] = 1.0
    print zmin, zmax
    #zm=ma.masked_where(Z<=0,Z)
    zm = Z
    print zm
    print levs
    plt.contourf(
        xi, yi, Z,
        levs)  #, norm=matplotlib.colors.LogNorm(levs[0],levs[len(levs)-1]))
    l_f = ticker.LogFormatter(10, labelOnlyBase=False)
    cbar = plt.colorbar(ticks=levs, format=l_f)
    plt.show()
Esempio n. 17
0
def inverse_laplace_ratfun(expr, s, t, **assumptions):

    sexpr = Ratfun(expr, s)

    damping = assumptions.get('damping', None)

    if assumptions.get('damped_sin', False):
        if sexpr.degree == 2:
            return inverse_laplace_damped_sin(sexpr, s, t, **assumptions)
        #if False and sexpr.degree == 3 and Ratfun(expr * s).degree == 2:
        #    return inverse_laplace_damped_sin3(sexpr, s, t, **assumptions)

    Q, M, D, delay, undef = sexpr.as_QMD()

    cresult = sym.S.Zero

    if Q:
        Qpoly = sym.Poly(Q, s)
        C = Qpoly.all_coeffs()
        for n, c in enumerate(C):
            cresult += c * sym.diff(sym.DiracDelta(t), t, len(C) - n - 1)

    expr = M / D
    for factor in expr.as_ordered_factors():
        if factor == sym.oo:
            return factor

    sexpr = Ratfun(expr, s)
    poles = sexpr.poles(damping=damping)
    polesdict = {}
    for pole in poles:
        polesdict[pole.expr] = pole.n

    uresult = sym.S.Zero

    for pole in poles:

        p = pole.expr

        # Number of occurrences of the pole.
        o = polesdict[p]

        if o == 0:
            continue

        if o == 1:
            pc = pole.conjugate
            r = sexpr.residue(p, poles)

            if pc != p and pc in polesdict:
                # Remove conjugate from poles and process pole with its
                # conjugate.  Unfortunately, for symbolic expressions
                # we cannot tell if a quadratic has two real poles,
                # a repeated real pole, or a complex conjugate pair of poles.

                polesdict[pc] -= 1

                p_re = sym.re(p)
                p_im = sym.im(p)
                r_re = sym.re(r)
                r_im = sym.im(r)
                et = sym.exp(p_re * t)
                uresult += 2 * r_re * et * sym.cos(p_im * t)
                uresult -= 2 * r_im * et * sym.sin(p_im * t)
            else:
                uresult += r * sym.exp(p * t)
            continue

        # Handle repeated poles.
        expr2 = expr * (s - p)**o
        expr2 = expr2.simplify()
        for n in range(1, o + 1):
            m = o - n
            r = sym.limit(sym.diff(expr2, s, m), s, p) / sym.factorial(m)
            uresult += r * sym.exp(p * t) * t**(n - 1)

    # cresult is a sum of Dirac deltas and its derivatives so is known
    # to be causal.

    return cresult, uresult
Esempio n. 18
0
def generate_cross_section(interactionfile,
                           spinfile,
                           lattice,
                           arg,
                           tau_list,
                           h_list,
                           k_list,
                           l_list,
                           w_list,
                           temperature,
                           steps,
                           eief,
                           efixed=14.7):
    """
    Calculates the cross_section given the following parameters:
    interactionfile, spinfile - files to get atom data
    lattice     - Lattice object from tripleaxisproject
    arg         - reduced list of operator combinations
    tau_list    - list of tau position
    w_list      - list of w's probed
    temp        - temperature
    kmin        - minimum value of k to scan
    kmax        - maximum value of k to scan
    steps       - number of steps between kmin, kmax
    eief        - True if fixed Ef
    efixed      - value of the fixed energy, either Ei or Ef
    """

    # Read files, get atom_list and such
    atom_list, jnums, jmats, N_atoms_uc = readFiles(interactionfile, spinfile)

    # Get Hsave to calculate its eigenvalues
    N_atoms = len(atom_list)
    Hsave = calculate_dispersion(atom_list,
                                 N_atoms_uc,
                                 N_atoms,
                                 jmats,
                                 showEigs=False)
    atom_list = atom_list[:N_atoms_uc]
    N_atoms = len(atom_list)
    N = N_atoms

    print "Calculated: Dispersion Relation"

    # Generate kappa's from (h,k,l)
    kaprange = []
    kapvect = []
    #if len(h_list) == len(k_list) == len(l_list):
    #for i in range(len(h_list)):
    #kappa = lattice.modvec(h_list[i],k_list[i],l_list[i], 'latticestar')
    #kaprange.append(kappa[0])
    #kapvect.append(np.array([h_list[i],k_list[i],l_list[i]]))
    ##            kapvect.append(np.array([h_list[i]/kappa,k_list[i]/kappa,l_list[i]/kappa]))
    #else:
    #raise Exception('h,k,l not same lengths')
    # Generate q's from kappa and tau
    kaprange = lattice.modvec(h_list, k_list, l_list, 'latticestar')
    nkpts = len(kaprange)
    kapvect = np.empty((nkpts, 3), 'Float64')
    kapvect[:, 0] = h_list
    kapvect[:, 1] = k_list
    kapvect[:, 2] = l_list
    #    print kapvect.shape
    #    print kaprange.shape
    kapunit = kapvect.copy()
    kapunit[:, 0] = kapvect[:, 0] / kaprange
    kapunit[:, 1] = kapvect[:, 1] / kaprange
    kapunit[:, 2] = kapvect[:, 2] / kaprange
    #plusq=kappa-tau
    plusq = []
    minusq = []
    qlist = []
    ones_list = np.ones((1, nkpts), 'Float64')
    #wtlist=np.ones((1,nkpts*2),'Float64').flatten()
    wtlist = np.hstack([w_list, w_list])
    #weven=np.array(range(0,nkpts*2,2))
    #wodd=np.array(range(1,nkpts*2,2))
    #wtlist[wodd]=w_list
    #wtlist[weven]=w_list
    qtlist = []

    for tau in tau_list:
        taui = np.ones((nkpts, 3), 'Float64')
        taui[:, 0] = ones_list * tau[0]
        taui[:, 1] = ones_list * tau[1]
        taui[:, 2] = ones_list * tau[2]
        kappa_minus_tau = kapvect - taui
        tau_minus_kappa = taui - kapvect

        qlist.append(np.vstack([kappa_minus_tau, tau_minus_kappa]))
    #calculate kfki
    nqpts = nkpts * 2
    kfki = calc_kfki(w_list, eief, efixed)

    eig_list = []
    #    print qlist
    for q in qlist:
        #eigs = calc_eigs_direct(Hsave,q[:,0],q[:,1],q[:,2])
        eigs = Hsave.eigenvals().keys()
        eig_list.append(eigs)
    print "Calculated: Eigenvalues"

    #   print len(qlist)
    #   print len(eig_list[0])
    #    sys.exit()
    # Grab Form Factors
    #----Commented out 9/14/09 by Tom becuase of magnetic_ff error--------------
    #ff_list = []
    #s = sp.Symbol('s')
    #for i in range(N_atoms):
    #el = elements[atom_list[i].atomicNum]
    #val = atom_list[i].valence
    #if val != None:
    #Mq = el.magnetic_ff[val].M_Q(kaprange)
    #else:
    #Mq = el.magnetic_ff[0].M_Q(kaprange)
    #ff_list.append(Mq)
    #print "Calculated: Form Factors"
    #--------------------------------------------------------------------------

    # Other Constants
    gamr0 = 2 * 0.2695e-12  #sp.Symbol('gamma', commutative = True)
    hbar = sp.S(
        1.0)  # 1.05457148*10**(-34) #sp.Symbol('hbar', commutative = True)
    g = 2.  #sp.Symbol('g', commutative = True)
    # Kappa vector
    kap = sp.Symbol(
        'kappa', real=True
    )  #spm.Matrix([sp.Symbol('kapx',real = True),sp.Symbol('kapy',real = True),sp.Symbol('kapz',real = True)])
    t = sp.Symbol('t', real=True)
    w = sp.Symbol('w', real=True)
    W = sp.Symbol('W', real=True)
    tau = sp.Symbol('tau', real=True)
    Q = sp.Symbol('q', real=True)
    L = sp.Symbol('L', real=True)
    lifetime = sp.Symbol('V', real=True)
    boltz = 8.617343e-2

    # Wilds for sub_in method
    A = sp.Wild('A', exclude=[0, t])
    B = sp.Wild('B', exclude=[0, t])
    C = sp.Wild('C')
    D = sp.Wild('D')
    K = sp.Wild('K')

    # Grabs the unit vectors from the back of the lists.
    unit_vect = []
    kapxhat = sp.Symbol('kapxhat', real=True)
    kapyhat = sp.Symbol('kapyhat', real=True)
    kapzhat = sp.Symbol('kapzhat', real=True)
    for i in range(len(arg)):
        unit_vect.append(arg[i].pop())
    #print unit_vect
    unit_vect = sum(unit_vect)
    print unit_vect

    csection = 0
    for i in range(len(arg)):
        for j in range(len(arg[i])):
            csection = csection + arg[i][j] * unit_vect

    print csection

    csection = sp.powsimp(csection)
    csection = (csection * exp(-I * w * t) *
                exp(I * kap * L)).expand(deep=False)
    print 'intermediate'
    #print csection
    csection = sp.powsimp(csection)
    csection = sub_in(csection,
                      exp(I * t * A + I * t * B + I * C + I * D + I * K),
                      sp.DiracDelta(A * t + B * t + C + D + K))
    csection = sub_in(
        csection, sp.DiracDelta(A * t + B * t + C * L + D * L),
        sp.DiracDelta(A * hbar + B * hbar) *
        sp.simplify(sp.DiracDelta(C + D - tau)))  #This is correct
    #csection = sub_in(csection,sp.DiracDelta(A*t + B*t + C*L + D*L ),sp.simplify(lifetime*sp.DiracDelta(C + D  - tau)*
    #sp.Pow((A-B)**2+lifetime**2,-1)))
    print "Applied: Delta Function Conversion"
    # print csection
    print 'done'

    ## First the exponentials are turned into delta functions:
    #for i in range(len(arg)):
    #for j in range(N):
    ##            print '1', arg[i][j]
    #arg[i][j] = sp.powsimp(arg[i][j])#sp.powsimp(arg[i][j], deep = True, combine = 'all')
    #arg[i][j] = (arg[i][j] * exp(-I*w*t) * exp(I*kap*L)).expand()# * exp(I*inner_prod(spm.Matrix(atom_list[j].pos).T,kap))
    #arg[i][j] = sp.powsimp(arg[i][j])#sp.powsimp(arg[i][j], deep = True, combine = 'all')
    ##            print '2', arg[i][j]
    #arg[i][j] = sub_in(arg[i][j],exp(I*t*A + I*t*B + I*C + I*D + I*K),sp.DiracDelta(A*t + B*t + C + D + K))#*sp.DiracDelta(C))
    ##            print '3', arg[i][j]
    #arg[i][j] = sub_in(arg[i][j],sp.DiracDelta(A*t + B*t + C*L + D*L + K*L),sp.DiracDelta(A*hbar + B*hbar)*sp.simplify(sp.DiracDelta(C + D + K + tau)))
    ##            print '4', arg[i][j]
    #arg[i][j] = sub_in(arg[i][j],sp.DiracDelta(-A - B)*sp.DiracDelta(C),sp.DiracDelta(A + B)*sp.DiracDelta(C))
    ##            arg[i][j] = arg[i][j].subs(-w - wq, w + wq)
    ##            print '5', arg[i][j]

    print "Applied: Delta Function Conversion"

    # Subs the actual values for kx,ky,kz, omega_q and n_q into the operator combos
    # The result is basically a nested list:
    #
    #    csdata     = [ op combos ]
    #    op combos  = [ one combo per atom ]
    #    1 per atom = [ evaluated exp ]
    #
    csection = sub_in(csection,
                      sp.DiracDelta(-A - B) * sp.DiracDelta(C),
                      sp.DiracDelta(A + B) * sp.DiracDelta(C))

    print "end part 1"
    #print csection
    return (N_atoms_uc, csection, kaprange, qlist, tau_list, eig_list, kapvect,
            wtlist)
Esempio n. 19
0
def find_dirac_delta_terms(expr):
    """Return all sub-expressions of the form "x * δ(y)" in `expr`"""
    _w = sympy.Wild('w')
    _w2 = sympy.Wild('w2')
    return list(term for term in expr.find(_w * sympy.DiracDelta(_w2))
                if isinstance(term, sympy.Mul))
Esempio n. 20
0
    def product(self, expr, s, t, **kwargs):

        # Handle expressions with a function of s, e.g., V(s) * Y(s), V(s)
        # / s etc.
        if kwargs.get('causal', False):
            # Assume that all functions are causal in the expression.
            t1 = Zero
            t2 = t
        else:
            t1 = -sym.oo
            t2 = sym.oo

        const, expr = factor_const(expr, s)

        factors = expr.as_ordered_factors()
        if len(factors) < 2:
            cresult, uresult = self.term1(expr, s, t, **kwargs)
            return const * (cresult + uresult)

        if (len(factors) > 2 and not
            # Help s * 1 / (s + R * C) * I(s)
            isinstance(factors[1], AppliedUndef) and
                isinstance(factors[2], AppliedUndef)):
            factors = [factors[0], factors[2], factors[1]] + factors[3:]

        if isinstance(factors[1], AppliedUndef):
            # Try to expose more simple cases, e.g. (R + s * L) * V(s)
            terms = factors[0].expand().as_ordered_terms()
            if len(terms) >= 2:
                result = Zero
                for term in terms:
                    result += self.product(factors[1] * term, s, t, **kwargs)
                return result * const

        cresult, uresult = self.term1(factors[0], s, t, **kwargs)
        result = cresult + uresult

        intnum = 0
        for m in range(len(factors) - 1):
            if m == 0 and isinstance(factors[1], AppliedUndef):
                # Note, as_ordered_factors puts powers of s before the functions.
                if factors[0] == s:
                    # Handle differentiation
                    # Convert s * V(s) to d v(t) / dt
                    result = self.func(factors[1], s, t)
                    result = sym.Derivative(result, t)
                    if not kwargs.get('zero_initial_conditions', True):
                        fname = factors[1].func.__name__
                        func = sym.Function(fname[0].lower() + fname[1:])
                        result += func(0) * sym.DiracDelta(t)
                    continue
                elif factors[0].is_Pow and factors[0].args[
                        0] == s and factors[0].args[1] > 0:
                    # Handle higher order differentiation
                    # Convert s ** 2 * V(s) to d^2 v(t) / dt^2
                    result = self.func(factors[1], s, t)
                    result = sym.Derivative(result, t, factors[0].args[1])
                    if not kwargs.get('zero_initial_conditions', True):
                        fname = factors[1].func.__name__
                        func = sym.Function(fname[0].lower() + fname[1:])
                        v = func(t)
                        order = factors[0].args[1]
                        for m in range(order - 1):
                            result += sym.Derivative(v, t, m).subs(t, 0) * \
                                sym.DiracDelta(t, order - m - 1)
                        result += sym.Derivative(v, t, order - 1).subs(t, 0) * \
                            sym.DiracDelta(t)

                    continue
                elif factors[0].is_Pow and factors[0].args[0] == s and factors[
                        0].args[1] == -1:
                    # Handle integration  1 / s * V(s)
                    tau = self.dummy_var(expr, 'tau', level=intnum, real=True)
                    intnum += 1
                    result = self.func(factors[1], s, tau)
                    result = sym.Integral(result, (tau, t1, t))
                    continue
            # Convert product to convolution
            tau = self.dummy_var(expr, 'tau', level=intnum, real=True)
            intnum += 1
            cresult, uresult = self.term1(factors[m + 1], s, t, **kwargs)
            expr2 = cresult + uresult
            result = sym.Integral(
                result.subs(t, t - tau) * expr2.subs(t, tau), (tau, t1, t2))

        return result * const
Esempio n. 21
0
    def ratfun(self, expr, s, t, **kwargs):

        if kwargs.pop('pdb', False):
            import pdb
            pdb.set_trace()

        sexpr = Ratfun(expr, s)

        if kwargs.get('damped_sin', False):
            if sexpr.degree == 2:
                return self.do_damped_sin(sexpr, s, t)
            # if False and sexpr.degree == 3 and Ratfun(expr * s).degree == 2:
            #    return self.do_damped_sin3(sexpr, s, t)

        self.debug('Finding QRPO representation')

        damping = kwargs.get('damping', None)
        Q, R, P, O, delay, undef = sexpr.as_QRPO(damping)

        if delay != 0:
            # This will be caught and trigger expansion of the expression.
            self.error('Unhandled delay %s' % delay)

        cresult = Zero

        if Q:
            Qpoly = sym.Poly(Q, s)
            C = Qpoly.all_coeffs()
            for n, c in enumerate(C):
                cresult += c * sym.diff(sym.DiracDelta(t), t, len(C) - n - 1)

        if R == []:
            return cresult, 0

        uresult = 0
        for m, (p, n, A) in enumerate(zip(P, O, R)):

            # This is zero for the conjugate pole.
            if R[m] == 0:
                continue

            # Search and remove conjugate pair.
            has_conjpair = False
            if p.is_complex and kwargs.get('pairs', True):
                pc = p.conjugate()
                Ac = A.conjugate()
                for m2, p2 in enumerate(P[m + 1:]):
                    m2 += m + 1
                    if n == O[m2] and p2 == pc and R[m2] == Ac:
                        R[m2] = 0
                        has_conjpair = True
                        break

            if has_conjpair:
                # Combine conjugate pairs.
                p = p.expand(complex=True)
                A = A.expand(complex=True)
                p_re = sym.re(p)
                p_im = sym.im(p)
                A_re = sym.re(A)
                A_im = sym.im(A)
                et = sym.exp(p_re * t)
                result = 2 * A_re * et * sym.cos(p_im * t)
                result -= 2 * A_im * et * sym.sin(p_im * t)
            else:
                result = A * sym.exp(p * t)

            if n > 1:
                result *= t**(n - 1) / sym.factorial(n - 1)
            uresult += result

        # cresult is a sum of Dirac deltas and its derivatives so is known
        # to be causal.

        return cresult, uresult
Esempio n. 22
0
def fourier_term(expr, t, f, inverse=False):

    const, expr = factor_const(expr, t)

    if isinstance(expr, sym.function.AppliedUndef):
        return fourier_func(expr, t, f, inverse) * const

    # TODO add u(t) <-->  delta(f) / 2 - j / (2 * pi * f)

    if expr.has(sym.function.AppliedUndef):
        # Handle v(t), v(t) * y(t),  3 * v(t) / t etc.
        return fourier_function(expr, t, f, inverse) * const

    # Check for constant.
    if not expr.has(t):
        return expr * sym.DiracDelta(f) * const

    one = sym.S.One
    const1 = const
    other = one
    exps = one
    factors = expr.as_ordered_factors()
    for factor in factors:
        if not factor.has(t):
            const1 *= factor
        else:
            if factor.is_Function and factor.func == sym.exp:
                exps *= factor
            else:
                other *= factor

    sf = -f if inverse else f

    if other != 1 and exps == 1:
        if other == t:
            return const1 * sym.I * 2 * sym.pi * sym.DiracDelta(f, 1)
        if other == t**2:
            return const1 * (sym.I * 2 * sym.pi)**2 * sym.DiracDelta(f, 2)

        # Sympy incorrectly gives exp(-a * t) instead of exp(-a * t) *
        # Heaviside(t)
        if other.is_Pow and other.args[1] == -1:
            foo = other.args[0]
            if foo.is_Add and foo.args[1].has(t):
                bar = foo.args[1] / t
                if not bar.has(t) and bar.has(sym.I):
                    a = -(foo.args[0] * 2 * sym.pi * sym.I) / bar
                    return const1 * sym.exp(-a * sf) * sym.Heaviside(
                        sf * sym.sign(a))

        # Punt and use SymPy.  Should check for t**n, t**n * exp(-a * t), etc.
        return const * fourier_sympy(expr, t, sf)

    args = exps.args[0]
    foo = args / t
    if foo.has(t):
        # Have exp(a * t**n), SymPy might be able to handle this
        return const * fourier_sympy(expr, t, sf)

    if exps != 1 and foo.has(sym.I):
        return const1 * sym.DiracDelta(sf - foo / (sym.I * 2 * sym.pi))

    return const * fourier_sympy(expr, t, sf)
Esempio n. 23
0
def inverse_laplace_ratfun(expr, s, t):

    N, D, delay = Ratfun(expr, s).as_ratfun_delay()
    # The delay should be zero

    Q, M = N.div(D)

    result1 = sym.sympify(0)

    if Q:
        C = Q.all_coeffs()
        for n, c in enumerate(C):
            result1 += c * sym.diff(sym.DiracDelta(t), t, len(C) - n - 1)

    expr = M / D
    for factor in expr.as_ordered_factors():
        if factor == sym.oo:
            return factor

    sexpr = Ratfun(expr, s)
    P = sexpr.poles()
    result2 = sym.sympify(0)

    P2 = P.copy()

    for p in P2:

        # Number of occurrences of the pole.
        N = P2[p]

        if N == 0:
            continue

        f = s - p

        if N == 1:
            r = sexpr.residue(p, P)

            pc = p.conjugate()
            if pc != p and pc in P:
                # Remove conjugate from poles and process pole with its
                # conjugate.  Unfortunately, for symbolic expressions
                # we cannot tell if a quadratic has two real poles,
                # a repeat real pole, or a complex conjugate pair of poles.
                P2[pc] = 0

                p_re = sym.re(p)
                p_im = sym.im(p)
                r_re = sym.re(r)
                r_im = sym.im(r)
                et = sym.exp(p_re * t)
                result2 += 2 * r_re * et * sym.cos(p_im * t)
                result2 -= 2 * r_im * et * sym.sin(p_im * t)
            else:
                result2 += r * sym.exp(p * t)
            continue

        # Handle repeated poles.
        expr2 = expr * f**N
        for n in range(1, N + 1):
            m = N - n
            r = sym.limit(sym.diff(expr2, s, m), s, p) / sym.factorial(m)
            result2 += r * sym.exp(p * t) * t**(n - 1)

    # result1 is a sum of Dirac deltas and its derivatives so is known
    # to be causal.

    return result1, result2
Esempio n. 24
0
def fourier_term(expr, t, f, inverse=False):

    const, expr = factor_const(expr, t)

    if expr.has(sym.Integral):
        return fourier_integral(expr, t, f, inverse) * const
    
    if isinstance(expr, AppliedUndef):
        return fourier_func(expr, t, f, inverse) * const
    
    # TODO add u(t) <-->  delta(f) / 2 - j / (2 * pi * f)
    
    if expr.has(AppliedUndef):
        # Handle v(t), v(t) * y(t),  3 * v(t) / t etc.
        return fourier_function(expr, t, f, inverse) * const

    # Check for constant.
    if not expr.has(t):
        return expr * sym.DiracDelta(f) * const

    one = sym.S.One
    const1 = const
    other = one
    exps = one
    factors = expr.expand().as_ordered_factors()    
    for factor in factors:
        if not factor.has(t):
            const1 *= factor
        else:
            if factor.is_Function and factor.func == sym.exp:
                exps *= factor
            else:
                other *= factor

    sf = -f if inverse else f
    
    if other != 1 and exps == 1:
        if other == t:
            return const1 * sym.I / (2 * sym.pi) * sym.DiracDelta(sf, 1)
        elif other == t**2:
            return -const1 / (2 * sym.pi)**2 * sym.DiracDelta(sf, 2)
        # TODO check for other powers of t...
        elif other == sym.sign(t):
            return const1 / (sym.I * sym.pi * sf)
        elif other == sym.sign(t) * t:
            return -const1 * 2 / (2 * sym.pi * f)**2
        elif other == sym.Heaviside(t):
            return const1 / (sym.I * 2 * sym.pi * f) + const1 * sym.DiracDelta(sf) / 2
        elif other == 1 / t:
            return -const1 * sym.I * sym.pi * sym.sign(sf)
        elif other == 1 / t**2:
            return -const1 * 2 * sym.pi**2 * sf * sym.sign(sf)        
        elif other.is_Function and other.func == sym.Heaviside and other.args[0].has(t):
            # TODO, generalise use of similarity and shift theorems for other functions and expressions
            scale, shift = scale_shift(other.args[0], t)
            return (const1 / (sym.I * 2 * sym.pi * sf / scale) / abs(scale) + const1 * sym.DiracDelta(sf) / 2) * sym.exp(sym.I * 2 * sym.pi * sf /scale * shift)
        elif other == sym.Heaviside(t) * t:
            return -const1 / (2 * sym.pi * f)**2 + const1 * sym.I * sym.DiracDelta(sf, 1) / (4 * pi)
        elif other.is_Function and other.func == sinc and other.args[0].has(t):
            scale, shift = scale_shift(other.args[0], t)            
            return const1 * rect(sf / scale) * sym.exp(sym.I * 2 * sym.pi * sf /scale * shift) / abs(scale)
        elif other.is_Function and other.func == rect and other.args[0].has(t):        
            return const1 * sinc(sf / scale) * sym.exp(sym.I * 2 * sym.pi * sf /scale * shift) / abs(scale)

        # Sympy incorrectly gives exp(-a * t) instead of exp(-a * t) *
        # Heaviside(t)
        if other.is_Pow and other.args[1] == -1:
            foo = other.args[0]
            if foo.is_Add and foo.args[1].has(t):
                bar = foo.args[1] / t
                if not bar.has(t) and bar.has(sym.I):
                    a = -(foo.args[0] * 2 * sym.pi * sym.I) / bar
                    return const1 * sym.exp(-a * sf) * sym.Heaviside(sf * sym.sign(a))

        if expr == t * sym.DiracDelta(t, 1):
            return const * sf / (-sym.I * 2 * sym.pi)
                
        # Punt and use SymPy.  Should check for t**n, t**n * exp(-a * t), etc.
        return const * fourier_sympy(expr, t, sf)

    args = exps.args[0]
    foo = args / t
    if foo.has(t):
        # Have exp(a * t**n), SymPy might be able to handle this
        return const * fourier_sympy(expr, t, sf)

    if exps != 1 and foo.has(sym.I):
        return const1 * sym.DiracDelta(sf - foo / (sym.I * 2 * sym.pi))
        
    return const * fourier_sympy(expr, t, sf)