def _radial_integral(n1, l1, n2, l2, numerov=False, numerov_step=0.005, numerov_rmin=0.65): """Calculate the radial integral (cached). Parameters ---------- n1 : int principal quantum number, state 1 l1 : int orbital angular momentum, state 1 n2 : int principal quantum number, state 2 l2 : int orbital angular momentum, state 2 numerov=False : bool numerov_step=0.005 : float numerov_rmin=0.65 : float Returns ------- float Examples -------- >>> # sympy >>> radial_integral(10, 4, 11, 5) 63.4960193562957 >>> # numerov >>> radial_integral(10, 4, 11, 5, numerov=True) 63.496017658724504 Nb. If numerov fails, automatically reverts to sympy """ if numerov: ri = float( radial_numerov(n1, l1, n2, l2, step=numerov_step, rmin=numerov_rmin)) if not np.isnan(ri): return ri else: # TODO fix numerov.radial_integral() warnings.warn( f"numerov.radial_integral returned nan for n1={n1}, l1={l1}, n2={n2}, l2={l2}.\\Fallback to scipy" ) var("r") return float( integrate(R_nl(n1, l1, r) * r**3 * R_nl(n2, l2, r), (r, 0, oo)).evalf())
def getOrbitals(self): orbitals = [] self.nShells = int(ceil(pow(self.nOrbitals,1.0/3.0)) + 1) o = 0 for n in range(1,self.nShells+1): for l in range(n): for m in range(-l,l+1): self.nlm[o] = [n,l,m] o += 1 o = 0 for i in range(len(self.nlm)): n,l,m = self.nlm[i] func = self.getSphericalFunc(l, m) func = R_nl(n,l,r3d,Z=k) * func func = func.simplify().collect(x).collect(y).collect(z) orbitals.append(self.removeConstants(func).collect(k)) if o >= self.nOrbitals: break o += 1 return orbitals
def test_radial_integral(n1=12, l1=5, n2=15, l2=4): """ compare radial integral with sympy """ var("r") integral_sympy = integrate( R_nl(n1, l1, r) * r**3 * R_nl(n2, l2, r), (r, 0, oo)).evalf() integral_numerov = radial_integral(n1, l1, n2, l2, step=STEP) frac_diff = abs(integral_numerov - integral_sympy) / integral_sympy assert frac_diff < FRAC_DIFF
def x_ex(n, l, m): x_ex = 0.0 for l0 in range(2 * l + 1): # zenghui's note for more general cases: cg(l0,lj,0)*cg(l0,lj,mj) * cg(l0,li,0)*cg(l0,li,mi) x_ex += (cg(l0,l,0)*cg(l0,l,m))**2 * \ ( integrate( R_nl(n, l, r1)**2 * \ (r1**(1-l0) * integrate( r2**(l0+2) * R_nl(n, l, r2)**2, (r2, 0, r1)) \ + r1**(l0+2) * integrate( R_nl(n,l,r2)**2 * r2**(1-l0), (r2, r1, oo))), (r1, 0, oo)) ) return -x_ex / 2
def do_plot(n, l, color="k"): x = arange(0, 100, 0.1) var("z") f = R_nl(n, l, 1, z) y = [f.subs(z, _x) for _x in x] plot(x, y, color + "-", lw=2, label="$R_{%d%d}$" % (n, l)) xlabel("$\\rho$") ylabel("$R_{nl}(\\rho)$") title("Eigenvectors (l=%d, Z=1)" % l) legend()
def do_plot(n, l, color="k"): x = arange(0, 100, 0.1) var("z") f = R_nl(n, l, 1, z) y = [f.subs(z, _x) for _x in x] plot(x, y, color + "-", lw=2, label="$R_{%d%d}$" % (n, l)) xlabel("$\\rho$") ylabel("$R_{nl}(\\rho)$") title("Eigenvectors (l=%d, Z=1)" % l) legend()
def main(): print("Hydrogen radial wavefunctions:") a, r = symbols("a r") print("R_{21}:") pprint(R_nl(2, 1, a, r)) print("R_{60}:") pprint(R_nl(6, 0, a, r)) print("Normalization:") i = Integral(R_nl(1, 0, 1, r)**2 * r**2, (r, 0, oo)) pprint(Eq(i, i.doit())) i = Integral(R_nl(2, 0, 1, r)**2 * r**2, (r, 0, oo)) pprint(Eq(i, i.doit())) i = Integral(R_nl(2, 1, 1, r)**2 * r**2, (r, 0, oo)) pprint(Eq(i, i.doit()))
def test_wavefunction(): a = 1 / Z R = { (1, 0): 2 * sqrt(1 / a**3) * exp(-r / a), (2, 0): sqrt(1 / (2 * a**3)) * exp(-r / (2 * a)) * (1 - r / (2 * a)), (2, 1): S(1) / 2 * sqrt(1 / (6 * a**3)) * exp(-r / (2 * a)) * r / a, (3, 0): S(2) / 3 * sqrt(1 / (3 * a**3)) * exp(-r / (3 * a)) * (1 - 2 * r / (3 * a) + S(2) / 27 * (r / a)**2), (3, 1): S(4) / 27 * sqrt(2 / (3 * a**3)) * exp(-r / (3 * a)) * (1 - r / (6 * a)) * r / a, (3, 2): S(2) / 81 * sqrt(2 / (15 * a**3)) * exp(-r / (3 * a)) * (r / a)**2, (4, 0): S(1) / 4 * sqrt(1 / a**3) * exp(-r / (4 * a)) * (1 - 3 * r / (4 * a) + S(1) / 8 * (r / a)**2 - S(1) / 192 * (r / a)**3), (4, 1): S(1) / 16 * sqrt(5 / (3 * a**3)) * exp(-r / (4 * a)) * (1 - r / (4 * a) + S(1) / 80 * (r / a)**2) * (r / a), (4, 2): S(1) / 64 * sqrt(1 / (5 * a**3)) * exp(-r / (4 * a)) * (1 - r / (12 * a)) * (r / a)**2, (4, 3): S(1) / 768 * sqrt(1 / (35 * a**3)) * exp(-r / (4 * a)) * (r / a)**3, } for n, l in R: assert simplify(R_nl(n, l, r, Z) - R[(n, l)]) == 0
def radial_func(Z, n, l): """ This function provides the formal definition of the radial part of the hydrogen wavefunction which are Laguerre polynomials. --- Parameters: r, array: An array of the r values. n, int: The principle quantum number of the hydrogen system. l, int: The angular momentum quantum number of the hydrogen system. --- Returns: prob_amps, array: An array of the radial components of the hydrogen wavefunction. """ ## Importing sympy modules that are only used in this function. from sympy import Symbol from sympy.physics.hydrogen import R_nl from sympy.utilities.lambdify import lambdify # Making r into a variable. r = Symbol('r', real=True, positive=True) ## Generating the r array. stop = 10 r_vals = np.linspace(0, stop, num=stop**4) ## Creating the radial arrays. prob_amps = [] for i in l: rad_func = lambdify([r], R_nl(n, i, r, Z)) values = [] for j in r_vals: values.append(rad_func(j)) prob_amps.append(values) return r_vals, prob_amps
def test_sympy(n=10, l=5): """ test that sympy wf and numerov are approximately equal """ r_cy, y_cy = radial_wf_cy(n, l, step=STEP) y_sympy = np.array([R_nl(n, l, r).evalf() for r in r_cy]) max_diff = np.max(np.abs(y_cy - y_sympy)) assert max_diff < MAX_DIFF
def test_wavefunction(): a = 1 / Z R = { (1, 0): 2 * sqrt(1 / a**3) * exp(-r / a), (2, 0): sqrt(1 / (2 * a**3)) * exp(-r / (2 * a)) * (1 - r / (2 * a)), (2, 1): S.Half * sqrt(1 / (6 * a**3)) * exp(-r / (2 * a)) * r / a, (3, 0): Rational(2, 3) * sqrt(1 / (3 * a**3)) * exp(-r / (3 * a)) * (1 - 2 * r / (3 * a) + Rational(2, 27) * (r / a)**2), (3, 1): Rational(4, 27) * sqrt(2 / (3 * a**3)) * exp(-r / (3 * a)) * (1 - r / (6 * a)) * r / a, (3, 2): Rational(2, 81) * sqrt(2 / (15 * a**3)) * exp(-r / (3 * a)) * (r / a)**2, (4, 0): Rational(1, 4) * sqrt(1 / a**3) * exp(-r / (4 * a)) * (1 - 3 * r / (4 * a) + Rational(1, 8) * (r / a)**2 - Rational(1, 192) * (r / a)**3), (4, 1): Rational(1, 16) * sqrt(5 / (3 * a**3)) * exp(-r / (4 * a)) * (1 - r / (4 * a) + Rational(1, 80) * (r / a)**2) * (r / a), (4, 2): Rational(1, 64) * sqrt(1 / (5 * a**3)) * exp(-r / (4 * a)) * (1 - r / (12 * a)) * (r / a)**2, (4, 3): Rational(1, 768) * sqrt(1 / (35 * a**3)) * exp(-r / (4 * a)) * (r / a)**3, } for n, l in R: assert simplify(R_nl(n, l, r, Z) - R[(n, l)]) == 0
def HFunc(r, theta, phi, n, l, m): #Full wavefunction (radial and spherical harmonics functions) # between an electron and nucleus of atomic number Z. The function was #taken from http://www.pitt.edu/~djb145/python/utilities/2016/03/07/Plot-Density/ sphHarm = spe.sph_harm(m, l, phi, theta) # Note the different convention from doc return R_nl(n, l, r, Z) * sphHarm
def test_norm(): # Maximum "n" which is tested: n_max = 2 # you can test any n and it works, but it's slow, so it's commented out: #n_max = 4 for n in range(n_max + 1): for l in range(n): assert integrate(R_nl(n, l, r)**2 * r**2, (r, 0, oo)) == 1
def main(): print "Hydrogen radial wavefunctions:" var("r a") print "R_{21}:" pprint(R_nl(2, 1, a, r)) print "R_{60}:" pprint(R_nl(6, 0, a, r)) print "Normalization:" i = Integral(R_nl(1, 0, 1, r)**2 * r**2, (r, 0, oo)) pprint(Eq(i, i.doit())) i = Integral(R_nl(2, 0, 1, r)**2 * r**2, (r, 0, oo)) pprint(Eq(i, i.doit())) i = Integral(R_nl(2, 1, 1, r)**2 * r**2, (r, 0, oo)) pprint(Eq(i, i.doit()))
def test_norm(): # Maximum "n" which is tested: n_max = 2 # it works, but is slow, for n_max > 2 for n in range(n_max + 1): for l in range(n): assert integrate(R_nl(n, l, r)**2 * r**2, (r, 0, oo)) == 1
from sympy.printing.theanocode import * from sympy.physics.hydrogen import R_nl import theano from sympy import Derivative, simplify, Symbol, pprint, latex, count_ops n, l, Z = 6, 2, 6 x = Symbol('x') expr = R_nl(n, l, x, Z) for e in (expr, expr.diff(x), simplify(expr.diff(x))): print latex(e) print "Operations: ", count_ops(e) print print latex(Derivative(expr, x)) print '\n\n\n' # Theano simplification functions def fgraph_of(*exprs): """ Transform SymPy expressions into Theano Computation """ outs = map(theano_code, exprs) ins = theano.gof.graph.inputs(outs) ins, outs = theano.gof.graph.clone(ins, outs) return theano.gof.FunctionGraph(ins, outs) def theano_simplify(fgraph): """ Simplify a Theano Computation """
from sympy.physics.hydrogen import Psi_nlm, R_nl from sympy.physics import hydrogen from sympy import Symbol, symbols, Matrix from sympy import integrate, conjugate, pi, sin r_axis = Matrix(r_axis) phi, theta = symbols('phi theta', real=True) r = Symbol('r', real=True, positive=True) Z, n, l, m = symbols('Z n l m', positive=True, integer=True, real=True) n = 3 l = 1 m = 0 wf = R_nl(n, l, r, Z) #Psi_nlm(n, l, m, r, phi, theta) abs_sqrd = wf * conjugate(wf)
def getRadialFunc(self, n, l): return R_nl(n, l, r3d, Z=k)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Fri Oct 19 13:35:48 2018 @author: gustavo """ from sympy.utilities.lambdify import implemented_function from sympy.physics.hydrogen import R_nl a, r = symbols('a r') psi_nl = implemented_function('psi_nl', Lambda([a, r], R_nl(1, 0, a, r))) psi_nl(a, r)
def Rnl(n, l, x): return lambdify(r, R_nl(n, l, r), modules=['numpy'])(x)
""" This example shows how to work with the Hydrogen radial wavefunctions. """ from sympy import var, pprint, Integral, oo, Eq from sympy.physics.hydrogen import R_nl print "Hydrogen radial wavefunctions:" var("r a") print "R_{21}:" pprint(R_nl(2, 1, a, r)) print "R_{60}:" pprint(R_nl(6, 0, a, r)) print "Normalization:" i = Integral(R_nl(1, 0, 1, r)**2 * r**2, (r, 0, oo)) pprint(Eq(i, i.doit())) i = Integral(R_nl(2, 0, 1, r)**2 * r**2, (r, 0, oo)) pprint(Eq(i, i.doit())) i = Integral(R_nl(2, 1, 1, r)**2 * r**2, (r, 0, oo)) pprint(Eq(i, i.doit()))
if 'left' in spines: ax.yaxis.set_ticks_position('left') else: # no yaxis ticks ax.yaxis.set_ticks([]) if 'bottom' in spines: ax.xaxis.set_ticks_position('bottom') else: # no xaxis ticks ax.xaxis.set_ticks([]) #n=1,l=0 r = linspace(0, 10, 100) lam_R_nl = lambdify(x, R_nl(1, 0, x)) ax = fig.add_subplot(6, 1, 1) ax.plot(r, r**2 * abs(lam_R_nl(r))**2, 'k', clip_on=False, label=r'$a_0^2|R_{nl}(r)|^2$') ax.fill(r, r**2 * abs(lam_R_nl(r))**2, color=[.7, .7, .7]) ax.plot(r, lam_R_nl(r), 'k:', clip_on=False, label=r'$R_{nl}(r)$') ax.plot([1, 1], [min(r**2 * abs(lam_R_nl(r))**2), max(r**2 * abs(lam_R_nl(r))**2)], 'k--') ax.set_ylim([0, 1.]) P.legend(frameon=False, fontsize=14, loc='best', ncol=2) adjust_spines(ax, ['left'])
from sympy.physics.hydrogen import E_nl, E_nl_dirac, R_nl from sympy import var var("n Z") var("r Z") var("n l") E_nl(n, Z) E_nl(1) E_nl(2, 4) E_nl(n, l) E_nl_dirac(5, 2) # l should be less than n E_nl_dirac(2, 1) E_nl_dirac(3, 2, False) R_nl(5, 0, r) # z = 1 by default R_nl(5, 0, r, 1)
def dRnl(n, l, x): return lambdify(r, diff(R_nl(n, l, r), r), modules=['numpy'])(x)
if Problem=='Hydrogen atom (Helium correction)': if atomic_number.value=='1 (Show Hydrogen energies)': z=1 if atomic_number.value=='2 (Correct Helium first energy)': z=2 large=0 omega=0 # Energías del átomo hidrogenoide En=z*E_nl(n,z) # Funciones de onda del átomo de hidrógeno # Número cuántico l=0 q=0 # La variable l ya esta siendo utilizada para el largo de la caja por ello se sustituyo por q Psin=(R_nl(n,q,r1,z)*R_nl(n,q,r2,z)) # Límites del átomo de hidrógeno de 0 a oo para sympy li_sympy=0 ls_sympy=oo # Límites del átomo de hidrógeno de 0 a oo para scipy li_scipy=0 ls_scipy=inf # Para sistemas no degenerados, la corrección a la energía a primer orden se calcula como # # $$ E_{n}^{(1)} = \int\psi_{n}^{(0)*} H' \psi_{n}^{(0)}d\tau$$ # ** Tarea 1 : Programar esta ecuación si conoces $H^{0}$ y sus soluciones. **