Solución numérica de la ecuación de Schrödinger - valores propios

Esta es mi primera pregunta aquí. Estoy tratando de resolver numéricamente la ecuación de Schrödinger para el potencial de Woods-Saxon y encontrar los valores propios y las funciones propias de la energía, pero estoy confundido acerca de cómo se debe hacer exactamente esto.

Resolví algunos problemas de valor inicial en el pasado usando métodos iterativos como Runge-Kutta. He leído que el método de Numerov es la forma de resolver la ecuación de Schrödinger, pero Wikipedia también lo describe como un método iterativo para problemas de valor inicial.

¿Cómo lo uso para resolver un problema de valores propios?

Esto me confunde por las siguientes razones:

  • ¿Resolver iterativamente la ED no requeriría el conocimiento de los valores propios de la energía para usarlos como entrada para el cálculo? Todavía no sé los valores propios; son precisamente lo que estoy tratando de calcular.
  • Si hiciera eso, ¿no obtendría simplemente una solución única, en lugar de una familia de funciones propias y valores propios?

He visto alguna mención de "matrices tridiagonales" que se generan de alguna manera, pero no estoy seguro de cuáles serían los elementos de esa matriz o cómo se aplica eso al problema. Leandro M. mencionó que “la discretización define un problema de valores propios de dimensión finita (matricial)”. Este parece ser el camino correcto que debería seguir, pero no he podido encontrar nada que explique explícitamente este proceso o cómo se construye la matriz. Si este es el procedimiento correcto, ¿cómo se construye esa matriz?

¿Sería la ciencia computacional un mejor hogar para esta pregunta?
@DavidZ ¿La redacción de la pregunta es satisfactoria ahora?
Mucho mejor, si. (y noté que la pregunta ya ha acumulado varios votos de reapertura más desde que la editó, por lo que probablemente se reabriría incluso sin mí, ¡así es como se supone que funciona el sistema!) Por cierto, lo siento, no entendí para mirarlo antes; Acabé estando mucho más ocupado de lo que pensaba anoche.
Si puede resolver problemas de valor inicial, puede resolver el problema de valor límite utilizando el método de disparo .
No he podido encontrar nada que explique explícitamente este proceso o cómo se construye la matriz. Entonces no te has molestado en abrir un libro sobre PDE numéricas.
¿Por qué no usar el método variacional en su lugar?

Respuestas (2)

Me alegro de que finalmente pueda responder a esto.

El método de Numerov como se describe en Wikipedia no es cómo desea proceder aquí. Para darle una idea de cómo proceder, comencemos con una versión simplificada del método. Lo que voy a hacer es discretizar ingenuamente el operador diferencial, así:

d 2 d X 2 ψ ψ ( X d ) 2 ψ ( X ) + ψ ( X + d ) d 2 ψ norte 1 2 ψ norte + ψ norte + 1 d 2

La última ecuación es solo una definición: estoy tratando el espacio como si fuera una red con puntos d aparte y estoy llamando ψ norte el valor de la función de onda en el norte th point.. Ahora la ecuación de Schrödinger se lee en esta notación:

2 2 metro ψ norte 1 2 ψ norte + ψ norte + 1 d 2 + V norte ψ norte = mi ψ norte

¡ Pero esta es una ecuación matricial ! Permítanme ser más explícito:

2 2 metro d 2 ( 2 1 1 2 1 1 2 1 1 2 ) ( ψ 1 ψ 2 ψ norte 1 ψ norte ) + ( V 1 V 2 V norte 1 V norte ) ( ψ 1 ψ 2 ψ norte 1 ψ norte ) = mi ( ψ 1 ψ 2 ψ norte 1 ψ norte )

Por supuesto, tuve que elegir algún número entero. norte eso solo corresponde a colocar el sistema en una caja que es "lo suficientemente grande" para tener un sistema finito.

Ahora está claro que lo que tiene es un problema de valor propio de matriz de la forma

A ψ = mi ψ

y puede proceder a diagonalizarlo de la forma que elija. Tenga en cuenta que llamamos A una matriz tridiagonal, por razones obvias. Es posible que desee ocuparse primero de las condiciones de contorno; lo hace configurando ψ 1 = ψ norte = 0 antes de construir la matriz, lo que corresponde a establecer la primera y la última columna en cero. Esto le dará algunas funciones propias falsas con valor propio cero que simplemente puede descartar. Si tiene diferentes condiciones de contorno, no tiene suerte; no conozco una forma que lo haga funcionar en general.

Ahora solo tienes que rehacer lo anterior con el método completo de Numerov, que será un poco más complicado, y ya está todo listo.

Esta parece ser la forma que está buscando pero, por supuesto, no es la única forma de hacerlo. Griffiths describe uno llamado "movimiento del perro" que consiste en lo siguiente: adivinas un valor inicial para una energía y calculas la función de onda como quieras (RK, por ejemplo). Lo más probable es que no sea un valor propio, por lo que la función de onda explotará en el infinito. podría ir a + para grande X o podría ir a . Ahora va variando lentamente la energía hasta que el comportamiento en el infinito "cambie", es decir, hasta que la cola "se mueva". Eso le permitirá restringir el valor de un solo valor propio de energía y le dará la forma de la función de onda a un tamaño máximo que aumenta a medida que se elige. mi se aproxima al valor propio exacto.

Será mejor que te establezcas ψ 0 = ψ norte + 1 = 0 en lugar de ψ 1 = ψ norte = 0 (es decir, coloque el punto con r = 0 a norte = 0 ). De esta manera, excluye específicamente los puntos que no son de uso real y, de hecho, su matriz ya representa dicha elección. Entonces no habrá soluciones espurias y, como beneficio adicional, también podría resolver problemas potenciales de Coulomb (porque la singularidad está excluida de los puntos que resuelve). Tenga en cuenta también que dado que el problema es un problema en 3D y resuelve la parte radial de la función de onda, la solución que encuentre debe dividirse por r .

Puede buscar valores propios utilizando el método de bisección.

Priliminares: para obtener los valores propios del método de Numerov, necesitará conocer la función de onda en los límites. En general, esto significaría que debe establecer el potencial en infinito en los límites, por lo tanto, poner la función de onda en cero en esos puntos. Para su potencial, modifíquelo de la siguiente manera:

V = infinito si -50fm>r>50fm V = 0 si |r|>8.5fm V = potencial de Woods en caso contrario

El trato real: ahora escriba un programa para calcular la función de onda en el potencial anterior utilizando cualquier energía arbitraria en el dominio -50fm

Aquí hay un código de Python que encuentra un valor propio en el intervalo dado (E1, E2) si existe.


import numpy as np

rmin = 0 rmax = 0

def vradial(r): global rmin global rmax if r < rmin or r > rmax: #This is important. >= and <= won't work #as they interfere with the bc on psi return np.inf elif r > rmin and r < rmin + 2: return (r - rmin - 2)**2 elif r > rmax - 2 and r < rmax: return (r - rmax + 2)**2 else: return 0

def f(l,E,r): """Calculate the f(r) in the Schrodinger equation of the form D2(Psi(r)) = f(r)Psi(r)""" if r == 0: return np.inf return l*(l+1)/(r**2) + vradial(r) - E

def psitophi(psi, l, E, r, delta): if psi == 0: return 0 #To handle the 0*infinity case of boundary return psi*(1-(f(l, E, r)*delta**2)/12)

def phitopsi(phi, l, E, r, delta): #if phi == 0: return 0 return phi/(1-(f(l, E, r)*delta**2)/12)

def calcpsiradial(rmin, rmax, N, psibcmin, psibcmax, l, E):

psiarray = []
r = np.linspace(rmin, rmax, N)
delta = r[1]-r[0]

#Assume psi(rmin) = psibcmin and psi(rmin+delta) = 1 and then
#calculate phi0 and phi1
psiarray.append(psibcmin)
psiarray.append(1)
phi0 = psitophi(psiarray[0], l, E, r[0], delta) #r[0]=rmin
phi1 = psitophi(psiarray[1], l, E, r[1], delta)

#Now populate the psiarray for each value of r
for i in range(2, len(r)):
    phi2 = 2*phi1 - phi0 + (delta**2)*f(l, E, r[i-1])*psiarray[i-1]
    psi = phitopsi(phi2, l, E, r[i], delta)
    psiarray.append(psi)
    phi0 = phi1
    phi1 = phi2

return r, psiarray

def normalize(delta, psi): area = 0 for i in range(1,len(psi)-1): area = area + abs(psi[i])*delta

for i in range(len(psi)):
    psi[i] = psi[i]/area

return psi

def locateEvalueInBracket(rmin, rmax, N, psibcmin, psibcmax, l, e1, e2,\ tol): #Any value of Psi smaller than psi is while abs(e2-e1) > tol:
r, psi = calcpsiradial(rmin, rmax, N, psibcmin, psibcmax, l, e1) psi1 = psi.pop() r, psi = calcpsiradial(rmin, rmax, N, psibcmin, psibcmax, l, e2) psi2 = psi.pop()

    if psi1*psi2 < 0:
        emid = e1 + (e2 - e1) * 0.5
        r, psi = calcpsiradial(rmin, rmax, N, psibcmin, psibcmax, l, emid)
        psimid = psi.pop()

        if psimid*psi1 < 0:
            e2 = emid

        elif psimid*psi2 < 0:
            e1 = emid
    elif psi1*psi2 > 0:
        print "There are either no eigenvalues or too many of them in"+\
        " the given energy interval. For e1={} psi={} and e2={} psi=".format(e1, psi1, e2)+\
        "{}".format(psi2)
        return e1,e2
return e1,e2

def main(): import sys import matplotlib.pyplot as plt global rmin global rmax

e1 = float(sys.argv[1])
e2 = float(sys.argv[2])
l = int(sys.argv[3])
if l == 0:
    rmin = -1
else:
    rmin = 0
tol =1e-5
rmax = 1
psibcmin = 0
psibcmax = 0
N = 100

e1, e2 = locateEvalueInBracket(rmin, rmax, N, psibcmin, psibcmax,\
        l, e1, e2, tol)

fig = plt.figure()
ax = fig.add_subplot(111)
r, psi = calcpsiradial(rmin, rmax, N, psibcmin, psibcmax, l, e1)
ax.plot(r,psi, 'o')
r, psi = calcpsiradial(rmin, rmax, N, psibcmin, psibcmax, l ,e2)
ax.plot(r, psi, 'g')
ax.set_title("l = {} and E_blue = {}, E_green={}".format(l,e1,e2))
plt.show()

if name=="main": main()

Utilice sangrías sensibles al copiar y pegar el código anterior. No puedo encontrar la manera de hacer que se renderice bien aquí. Te enviaré una copia si me envías un correo electrónico.