如何在python中建模量子谐波振荡器

时间:2019-12-18 09:42:04

标签: python physics ode

我只需要帮助弄清楚为什么b)的基态图看起来不对,这是一个完整的问题:(我认为将其完整发布会为我要使用的方法提供上下文)

(a)考虑两个无限高的壁之间的potential(?)= 0的方势阱,其距离the等于Bohr半径,即间隔[0,?]中的所有x。

  • 编写一个使用参数energy的函数solve(energy, func)和一个Python函数????。对于上述情况,此函数应求解SchrödingerODE并仅在边界?处返回?(?)的最终值。

  • 使用函数solve(energy, func)编写脚本,以eV为单位(即将结果除以基本电荷值)来计算该势阱中电子的基态能量。对于初始条件,请参见下面的技术提示。对于要求解?(?)的值的数量,建议使用值1000。

计算结果应为134 eV至135 eV之间的数字。其中一项测试将评估您的solve(energy,func)函数对变形的势阱的影响。

(b)考虑谐波电位 ?(?)=? 0 ? 2 /? 2 ,其中? 0 和?= 10 −11 m是常数。将变量?的无限范围限制为区间[−10?,10?],且? 0 = 50 eV。

  • 已知谐波振荡器具有等距的能量本征值。通过计算基态和前两个激发态,检查计算结果是否正确。 (提示:基态的能量在100到200 eV之间。)

  • 为了测试您的结果,编写一个函数result(),该函数必须以eV为单位返回计算出的能量本征值之差。请注意,具有预期数字的测试将被隐藏,并且将以±1 eV的精度测试您的结果。

  • 提供图标题和适当的轴标签,使用颜色编码的线将所有三个wave函数绘制在一张画布上,并在x和y中提供适当的轴限制以使所有曲线清晰可见。

技术提示:这不是SchrödingerODE的初始值问题,而是边界值问题!这需要额外的努力,这与以前的ODE练习不同,因此是一个“看不见的”问题。

  • 对两个问题分别采用> 0 = 0或? 0 = −10?的简单初始条件::(? 0 < / sub>)= 0和??(? 0 )/??= 1。以此作为求解ODE的起点,并改变能量?直至解收敛。任务是评估能量变量的变化,直到满足第二个边界条件(例如,在练习(a)的L处),因为由于初始条件的选择,第一个边界条件已经满足。

    < / li>
  • 这需要对可能存在解的能量间隔进行初步猜测,并需要一种用于求根的计算方法。搜索scipy寻找根查找方法,然后选择一种不需要导数知识的方法。在这里找到根是合适的,因为要满足的边界条件是?(?)= 0。

量子物理学的背景,两个练习的边界条件是在每个潜在边界处?(?)= 0。这些只能在特定的离散能量值?上实现,称为能量特征值,其中最小的一个称为基态能量。

m_el   = 9.1094e-31      # mass of electron in [kg]
hbar   = 1.0546e-34      # Planck's constant over 2 pi [Js]
e_el   = 1.6022e-19      # electron charge in [C]
L_bohr = 5.2918e-11      # Bohr radius [m]
V0 = 50*e_el
a = 10**(-11)

import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
from matplotlib.pyplot import figure
from scipy.integrate import odeint
from scipy import optimize

def eqn(y, x, energy):                       #part a)
    y0 = y[1]
    y1 = -2*m_el*energy*y[0]/hbar**2

    return np.array([y0,y1])

x = np.linspace(0,L_bohr,1000)
def solve(energy, func):
    p0 = 0
    dp0 = 1
    init = np.array([p0,dp0])
    ysolve = odeint(func, init, x, args=(energy,))
    return ysolve[-1,0]

def eigen(energy):

    return solve(energy, eqn)

root_ = optimize.toms748(eigen,134*e_el,135*e_el)
root = root_/e_el

print('Ground state infinite square well',root,'eV')

intervalb = np.linspace(-10*a,10*a,1000)                    #part b)

def heqn(y, x2, energy):
    f0 = y[1]
    f1 = (2.0 * m_el / hbar**2) * (V0 * (x2**2/a**2) - energy) * y[0]

    return np.array([f0,f1])

def solveh(energy, func):
    ph0 = 0
    dph = 1
    init = np.array([ph0,dph])
    ysolve = odeint(func, init, intervalb, args=(energy,))
    return ysolve

def boundary(energy):        #finding the boundary V=E to apply the b.c
    f = a*np.sqrt(energy/V0)
    index = np.argmin(np.abs(intervalb-f))

    return index

def eigen2(energy):

    return solveh(energy,heqn)[boundary(energy),0]

groundh_ = optimize.toms748(eigen2,100*e_el,200*e_el)
groundh = groundh_/e_el


print('Ground state of Harmonic Potential:', groundh, 'eV')
plt.suptitle('Harmonic Potential Well')
plt.xlabel('x (a [pm])')
plt.ylabel('Psi(x)')

groundsol = solveh(groundh_,heqn)[:,0]
plt.plot(intervalb/a, groundsol)

enter image description here

对于100 eV至200 eV之间的所有能量值,图形形状看起来像这样。我不明白我要去哪里错了。我尝试过尽可能多地测试我的代码。任何帮助将不胜感激,(可能有赏金)

1 个答案:

答案 0 :(得分:3)

函数const fs = require('fs') const jwt = require('jsonwebtoken') const mqtt = require('mqtt') const exec = require('child_process').exec const projectId = 'my-project' const cloudRegion = 'us-central1' const registryId = 'my-registry' const mqttHost = 'mqtt.googleapis.com' const mqttPort = 8883 const privateKeyFile = './certs/rsa_private.pem' const algorithm = 'RS256' var messageType = 'events'// or event function createJwt (projectId, privateKeyFile, algorithm) { var token = { iat: parseInt(Date.now() / 1000), exp: parseInt(Date.now() / 1000) + 86400 * 60, // 1 day aud: projectId } const privateKey = fs.readFileSync(privateKeyFile) return jwt.sign(token, privateKey, { algorithm: algorithm }) } function fetchData () {} async function configureDevice () { // Get the device's serial number await exec('cat /proc/cpuinfo | grep Serial', (error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`) return } // Concat serial number w/ project name to meet device id naming requirement starting w/ a letter const deviceId = `my-project${stdout.split(' ')[1].split('\n')[0]}` var mqttClientId = 'projects/' + projectId + '/locations/' + cloudRegion + '/registries/' + registryId + '/devices/' + deviceId var mqttTopic = '/devices/' + deviceId + '/' + messageType var connectionArgs = { // protocolId: 'MQIsdp' if I add this property I see "connecting..." get logged in the console // followed by "close" repeatedly being logged. If I don't add it I get // "Error: Connection refused: Not authorized" host: mqttHost, port: mqttPort, clientId: mqttClientId, username: 'unused', password: createJwt(projectId, privateKeyFile, algorithm), protocol: 'mqtts', secureProtocol: 'TLSv1_2_method' } console.log('connecting...') var client = mqtt.connect(connectionArgs) // Subscribe to the /devices/{device-id}/config topic to receive config updates. client.subscribe('/devices/' + deviceId + '/config') client.on('connect', function (success) { if (success) { console.log('Client connected...') sendData() } else { console.log('Client not connected...') } }) client.on('close', function () { debugger console.log('close') }) client.on('error', function (err) { debugger console.log('error', err) }) client.on('message', function (topic, message, packet) { console.log(topic, 'message received: ', Buffer.from(message, 'base64').toString('ascii')) }) function sendData () { var payload = fetchData() payload = JSON.stringify(payload) console.log(mqttTopic, ': Publishing message:', payload) client.publish(mqttTopic, payload, { qos: 1 }) console.log('Transmitting in 30 seconds') setTimeout(sendData, 30000) } }) } configureDevice() 的代码或任务文本中没有任何原因。如a)中那样,在边界条件的正确间隔末尾取值,理想情况下应该是无穷大的值。

您的代码中还有另外两个问题,但这并不是您的错:

  • 由于某些原因,最新版本的BillingsRunningTotal = CALCULATE ( SUM ( Datatable[Allowable] ), FILTER ( ALLSELECTED ( DimDate ), DimDate[Date] <= MAX ( DimDate[Date] ) ) ) 中可能没有这些,并且我无法在可用的源代码中找到根查找程序boundary的调用,使用,似乎缓存该功能,而不是将其替换为较新的功能。这意味着在b)部分中,根查找器调用仍找到根,但它是a)部分中scipy的根。只需检查功能值即可确认。我建议在初始括号间隔中使用更通用的界面,默认情况下使用Brent方法的版本。

  • 第二个问题是能量规模过大,因此超出了寻根方法的设计参数范围。一种解决方案是操纵绝对和相对公差以适合您的问题域和范围比例。另一种解决方案是将问题转换为具有更合理缩放范围的域,以使错误控制方法/试探法在其设计范围和默认容差范围内起作用。

toms748

工作完美(可能使用布伦特方法作为包围方法的标准),在138.023972 eV处找到基态能量并生成波形图

wave form

继续搜索,首先在eigensol = optimize.root_scalar(lambda s: eigen2(s*e_el), bracket=(100,200)) groundh = sol.root groundh_ = sol.root*e_el 的间隔中搜索符号更改,然后搜索根,​​

enter image description here