Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Python] Уравнение Шрёдиннгера в потенциальная яма, Возможная потеря точности 
:(
    Опции темы
Kemix
Дата 13.12.2015, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 21.4.2012

Репутация: нет
Всего: нет



Здравствуйте, дорогое сообщество Vingrad.
Я уже неделю пытаюсь решить одну лабораторную по теме "Одномерное стационарное уравнение Шрёдиннгера в прямоугольной потенциальной яме с бесконечными стенками".

Алгоритм
Имеем U(x)=V0*v(x) и начальное приближение E=U_min + б, где б>0, U_min - наименьшее значение потенциальной ф-ции U(x).
Необходимо найти основное, первое и второе возбуждённые состояния электрона.
Делаем это вычислением f через Метод Нумерова (интегрированием вперёд psi(x) и интергрированием назад phi(x) ) и сдвигом E с небольшим шагом. 
Продолжаем это до тех пор, пока не найдём место. где функция f меняет знак (f1*f2<=0).
После этого, при помощи метода бисекций уточняем найденное f2 и строим графики U(x) [жёлтый], phi(x) [синий] , psi(x) [красный], x [зелёный] и указываем узел сшивки(задают произвольно).
Суть в том, что программа расчитывает неверно, а где ошибка - понять не могу.
Изначальный код выдал преподаватель для встраивания метода бисекции и поиска "перегиба".
Дополнительную справку прикладываю в методичке.

Код

# import time
import math
import numpy as np
# from numpy import *
# from scipy.integrate import odeint
import matplotlib.pyplot as plt

# потенциальная ф-я
def U(x):
    return float(V0*(0.5*x*x-1) if abs(x)<L else W)
    #return float((-1 + (x*x+L*L)/(2*L*L)) if abs(x) < L else W)
    #return float(U0 if abs(x) < L else W)

# ф-я (13)
def q(e, x):
    return 2.0*(e-U(x))

# ф-я для вычисления производной по ф-ле (19)
def deriv(Y, h, m):
    return (Y[m-2]-Y[m+2]+8.0*(Y[m+1]-Y[m-1]))/(12.0*h)

# метод Нумерова
def num(e, r, n):
    # print("r =", r)
    F = np.array([c*q(e, X[i]) for i in np.arange(n)])
    # print("F =", F)
    Psi[0] = 0.0
    Fi[n-1] = 0.0
    Psi[1] = d1
    Fi[n-2] = d2
    # интегрирование "вперед" по ф-ле (16)
    for i in np.arange(1, n-1, 1):
        p1 = 2.0*(1.0 - 5.0*F[i])*Psi[i]
        p2 = (1.0 + F[i-1])*Psi[i-1]
        Psi[i+1] = (p1 - p2)/(1.0 + F[i+1])
    # интегрирование "назад" по ф-ле (17)
    for i in np.arange(n-2, 0, -1):
        # print("Fi[i+1]=", Fi[i+1], "  Fi[i]=", Fi[i])
        f1 = 2.0*(1.0 - 5.0*F[i])*Fi[i]
        f2 = (1.0 + F[i+1])*Fi[i+1]
        Fi[i-1] = (f1 - f2)/(1.0 + F[i-1])
    # поиск максимального по модулю эл-та списка Psi
    p1 = np.abs(Psi).max()
    p2 = np.abs(Psi).min()
    big = p1 if p1 > p2 else p2
    # масштабирование эл-ов списка Psi
    for i in np.arange(0, n-1, 1):
        Psi[i] = Psi[i]/big
    # масштабирование эл-ов списка Fi так, чтобы F[r]=Psi[r]
    coef = Psi[r]/Fi[r]
    for i in np.arange(0, n-1, 1):
        Fi[i] = coef*Fi[i]
    # вычисление f по ф-ле (18) в узле сшивки r
    f = deriv(Psi, h, r) - deriv(Fi, h, r)
    return f

# границы ямы с а.е.
L = 2.0/0.5292
A = -L
B = +L

# кол-во узлов сетки - нечетное число
n = 5001

# шаг сетки
h = (B-A)/(n-1)

# константа для метода Нумерова
c = h**2/12.0


V0=10
# минимальное значение потенциала а а.е.
U0 = V0*-1.0/27.212

# максимальное значение потенциала на графике
W = V0*2.0/27.212

# описание и инициализация списков
Psi = np.zeros(n)
Fi = np.zeros(n)
F = np.zeros(n)
Psi2 = np.zeros(n)
X = np.linspace(A, B, n)

# задание узла сшивки
r = (n-1)/2+15

d1 = 1.e-9
d2 = d1

# ввод пристрелочного значения энергии с клавиатуры
e = float(input("Начальное приближение E = U_min + "))
e=e+U0
print("e =", e)
f = num(e, r, n)
print("f =", f)

# ввод шага ΔЕ
dE = float(input("ΔE = "))
maxsost = int(input("До какого состояния считать? (0 - основное): "))
maxsost=maxsost+1

f1 = num(e, r, n)
e = e+dE
f2 = num(e, r, n)

step = 0
cursost=0

# метод бисекции
while cursost<maxsost:
    while f1*f2>0:
        f1 = f2
        e = e+dE
        f2 = num(e, r, n)
        step = step+1
    cursost=cursost+1
    if cursost<maxsost:
        e = e+dE
        f2 = num(e, r, n)

exactness = 0.0001
f3 = f2
e1 = e - dE
e2 = e
it=0
e3=e
maxit=50
while abs(f3) > exactness and it<maxit:
    e3 = (e2 + e1)/2
    f3 = num(e3, r, n)
    step = step + 1
    if f1*f3<0:
        e2 = e3
        f2 = f3
    else:
        e1 = e3
        f1 = f3
    it += 1

f = f3
print("Расчетное значение e =", e3)
print("f(e) =", f)

i=0
FPl = np.zeros(n)
while i<n:
    FPl[i] = Psi[i]*Psi[i]
    i = i+1

#print (FPl)
i = 1
h = (B-A)/n
sum = 0
while i<n:
    sum = sum + (FPl[i]+FPl[i-1])/2*h
    i = i+1
print ("интеграл: ", sum)

i=0
#kor = (math.sqrt(sum))
#print ("kor = ", kor)
while i<n:
    FPl[i] = FPl[i] / sum
    i = i+1

#print (FPl)
i = 1
sum1 = 0
while i<n:
    sum1 = sum1 + (FPl[i]+FPl[i-1])/2*h
    i = i+1

print ("после нормировки: ", sum1)

plt.style.use('dark_background')
plt.figure(1, figsize=(12, 8))
plt.rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']})
plt.rc('text', usetex=True)
plt.rc('font', size=16)
Upot = np.array([U(X[i]) for i in np.arange(n)])
plt.plot(X[1:n-1], Psi[1:n-1], 'r-', linewidth=4.0, label=r"$\psi(x)$")
plt.plot(X[1:n-1], Fi[1:n-1], 'b-', linewidth=2.0, label=r"$\phi(x)$")
plt.plot(X[1:n-1], FPl[1:n-1], 'g-', linewidth=2.0, label=r"$\fpl(x)$")
plt.plot(X, Upot, 'y-', linewidth=6.0,  label=r"$U(x)$")
# plt.plot(X, Upot, 'k-', linewidth=6.0,  label=r"$U(x)$")
plt.xlabel(r"$x$", fontsize=26, color="w")

plt.ylabel(r"${\psi(x), \phi(x), U(x)}$", fontsize=26, color="w")
plt.grid(True)
plt.legend(fontsize=16, shadow=True, fancybox=True)

plt.plot([X[r]], [Psi[r]], color='green', marker='o', markersize=10)

string1 = "E    = " + str(e3)
string2 = "f(E) = " + str(f)
plt.text(-1.5, 2.6, string1, fontsize=18, color='yellow')
plt.text(-1.5, 2.3, string2, fontsize=18, color="yellow")

# we can make labels and lines bigger/thicker by
# making the plot smaller!
F = plt.gcf() # get current figure
size = F.get_size_inches()
# print('size =', size)
fac = 0.9
F.set_size_inches(size[0]*fac, size[1]*fac)
plt.savefig('schrodinger-1.pdf', dpi=300)  # save to file

plt.show()



Присоединённый файл ( Кол-во скачиваний: 12 )
Присоединённый файл  MolDiz1a.pdf 442,61 Kb
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0612 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.