2021-01-03 18:45:58 +01:00
|
|
|
#+TITLE: Quantum Monte Carlo
|
|
|
|
#+AUTHOR: Anthony Scemama, Claudia Filippi
|
2021-01-26 10:02:38 +01:00
|
|
|
#+LANGUAGE: en
|
2021-01-28 15:04:57 +01:00
|
|
|
#+INFOJS_OPT: toc:t mouse:underline path:org-info.js
|
2021-01-03 18:45:58 +01:00
|
|
|
#+STARTUP: latexpreview
|
2021-01-21 12:49:12 +01:00
|
|
|
#+LATEX_CLASS: report
|
|
|
|
#+LATEX_HEADER_EXTRA: \usepackage{minted}
|
2021-01-11 20:54:40 +01:00
|
|
|
#+HTML_HEAD: <link rel="stylesheet" title="Standard" href="worg.css" type="text/css" />
|
2021-01-26 10:02:38 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
#+OPTIONS: H:4 num:t toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
|
2021-01-21 12:49:12 +01:00
|
|
|
#+OPTIONS: TeX:t LaTeX:t skip:nil d:nil todo:t pri:nil tags:not-in-toc
|
2021-01-29 13:23:00 +01:00
|
|
|
# EXCLUDE_TAGS: solution
|
2021-01-21 12:49:12 +01:00
|
|
|
|
|
|
|
#+BEGIN_SRC elisp :output none :exports none
|
|
|
|
(setq org-latex-listings 'minted
|
|
|
|
org-latex-packages-alist '(("" "minted"))
|
|
|
|
org-latex-pdf-process
|
|
|
|
'("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
|
|
|
|
"pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
|
|
|
|
"pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))
|
|
|
|
(setq org-latex-minted-options '(("breaklines" "true")
|
|
|
|
("breakanywhere" "true")))
|
|
|
|
(setq org-latex-minted-options
|
|
|
|
'(("frame" "lines")
|
|
|
|
("fontsize" "\\scriptsize")
|
|
|
|
("linenos" "")))
|
|
|
|
(org-beamer-export-to-pdf)
|
|
|
|
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
#+RESULTS:
|
|
|
|
: /home/scemama/TREX/qmc-lttc/QMC.pdf
|
2021-01-03 18:45:58 +01:00
|
|
|
|
|
|
|
* Introduction
|
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
This web site is the QMC tutorial of the LTTC winter school
|
|
|
|
[[https://www.irsamc.ups-tlse.fr/lttc/Luchon][Tutorials in Theoretical Chemistry]].
|
|
|
|
|
2021-01-07 11:07:18 +01:00
|
|
|
We propose different exercises to understand quantum Monte Carlo (QMC)
|
|
|
|
methods. In the first section, we propose to compute the energy of a
|
|
|
|
hydrogen atom using numerical integration. The goal of this section is
|
|
|
|
to introduce the /local energy/.
|
|
|
|
Then we introduce the variational Monte Carlo (VMC) method which
|
|
|
|
computes a statistical estimate of the expectation value of the energy
|
|
|
|
associated with a given wave function.
|
|
|
|
Finally, we introduce the diffusion Monte Carlo (DMC) method which
|
2021-01-28 15:04:57 +01:00
|
|
|
gives the exact energy of the hydrogen atom and of the H_2 molecule.
|
2021-01-07 11:07:18 +01:00
|
|
|
|
2021-01-25 23:52:53 +01:00
|
|
|
Code examples will be given in Python and Fortran. You can use
|
|
|
|
whatever language you prefer to write the program.
|
2021-01-11 18:41:36 +01:00
|
|
|
|
|
|
|
We consider the stationary solution of the Schrödinger equation, so
|
|
|
|
the wave functions considered here are real: for an $N$ electron
|
|
|
|
system where the electrons move in the 3-dimensional space,
|
|
|
|
$\Psi : \mathbb{R}^{3N} \rightarrow \mathbb{R}$. In addition, $\Psi$
|
|
|
|
is defined everywhere, continuous and infinitely differentiable.
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-25 23:52:53 +01:00
|
|
|
All the quantities are expressed in /atomic units/ (energies,
|
|
|
|
coordinates, etc).
|
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
* Numerical evaluation of the energy
|
|
|
|
|
2021-01-07 11:07:18 +01:00
|
|
|
In this section we consider the Hydrogen atom with the following
|
|
|
|
wave function:
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-07 11:07:18 +01:00
|
|
|
$$
|
|
|
|
\Psi(\mathbf{r}) = \exp(-a |\mathbf{r}|)
|
|
|
|
$$
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-21 23:24:21 +01:00
|
|
|
We will first verify that, for a given value of $a$, $\Psi$ is an
|
|
|
|
eigenfunction of the Hamiltonian
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-07 11:07:18 +01:00
|
|
|
$$
|
|
|
|
\hat{H} = \hat{T} + \hat{V} = - \frac{1}{2} \Delta - \frac{1}{|\mathbf{r}|}
|
|
|
|
$$
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-21 23:24:21 +01:00
|
|
|
To do that, we will check if the local energy, defined as
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-07 11:07:18 +01:00
|
|
|
$$
|
|
|
|
E_L(\mathbf{r}) = \frac{\hat{H} \Psi(\mathbf{r})}{\Psi(\mathbf{r})},
|
|
|
|
$$
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-21 23:24:21 +01:00
|
|
|
is constant.
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-11 18:41:36 +01:00
|
|
|
|
|
|
|
The probabilistic /expected value/ of an arbitrary function $f(x)$
|
|
|
|
with respect to a probability density function $p(x)$ is given by
|
|
|
|
|
2021-01-21 23:24:21 +01:00
|
|
|
$$ \langle f \rangle_p = \int_{-\infty}^\infty p(x)\, f(x)\,dx. $$
|
2021-01-11 18:41:36 +01:00
|
|
|
|
|
|
|
Recall that a probability density function $p(x)$ is non-negative
|
|
|
|
and integrates to one:
|
|
|
|
|
2021-01-21 23:24:21 +01:00
|
|
|
$$ \int_{-\infty}^\infty p(x)\,dx = 1. $$
|
2021-01-11 18:41:36 +01:00
|
|
|
|
|
|
|
|
|
|
|
The electronic energy of a system is the expectation value of the
|
2021-01-11 20:54:40 +01:00
|
|
|
local energy $E(\mathbf{r})$ with respect to the 3N-dimensional
|
2021-01-11 18:41:36 +01:00
|
|
|
electron density given by the square of the wave function:
|
|
|
|
|
2021-01-11 20:54:40 +01:00
|
|
|
\begin{eqnarray*}
|
|
|
|
E & = & \frac{\langle \Psi| \hat{H} | \Psi\rangle}{\langle \Psi |\Psi \rangle}
|
|
|
|
= \frac{\int \Psi(\mathbf{r})\, \hat{H} \Psi(\mathbf{r})\, d\mathbf{r}}{\int \left[\Psi(\mathbf{r}) \right]^2 d\mathbf{r}} \\
|
|
|
|
& = & \frac{\int \left[\Psi(\mathbf{r})\right]^2\, \frac{\hat{H} \Psi(\mathbf{r})}{\Psi(\mathbf{r})}\,d\mathbf{r}}{\int \left[\Psi(\mathbf{r}) \right]^2 d\mathbf{r}}
|
|
|
|
= \frac{\int \left[\Psi(\mathbf{r})\right]^2\, E_L(\mathbf{r})\,d\mathbf{r}}{\int \left[\Psi(\mathbf{r}) \right]^2 d\mathbf{r}}
|
2021-01-11 18:41:36 +01:00
|
|
|
= \langle E_L \rangle_{\Psi^2}
|
2021-01-11 20:54:40 +01:00
|
|
|
\end{eqnarray*}
|
2021-01-11 18:41:36 +01:00
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
** Local energy
|
2021-01-07 11:07:18 +01:00
|
|
|
:PROPERTIES:
|
|
|
|
:header-args:python: :tangle hydrogen.py
|
|
|
|
:header-args:f90: :tangle hydrogen.f90
|
|
|
|
:END:
|
2021-01-12 01:01:52 +01:00
|
|
|
|
2021-01-21 23:24:21 +01:00
|
|
|
Write all the functions of this section in a single file :
|
|
|
|
~hydrogen.py~ if you use Python, or ~hydrogen.f90~ is you use
|
|
|
|
Fortran.
|
|
|
|
|
2021-01-26 00:22:37 +01:00
|
|
|
#+begin_note
|
|
|
|
- When computing a square root in $\mathbb{R}$, *always* make sure
|
|
|
|
that the argument of the square root is non-negative.
|
|
|
|
- When you divide, *always* make sure that you will not divide by zero
|
|
|
|
|
|
|
|
If a /floating-point exception/ can occur, you should make a test
|
|
|
|
to catch the error.
|
|
|
|
#+end_note
|
|
|
|
|
2021-01-12 01:01:52 +01:00
|
|
|
*** Exercise 1
|
|
|
|
|
|
|
|
#+begin_exercise
|
|
|
|
Write a function which computes the potential at $\mathbf{r}$.
|
2021-01-07 11:07:18 +01:00
|
|
|
The function accepts a 3-dimensional vector =r= as input arguments
|
|
|
|
and returns the potential.
|
2021-01-12 01:01:52 +01:00
|
|
|
#+end_exercise
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-11 20:54:40 +01:00
|
|
|
$\mathbf{r}=\left( \begin{array}{c} x \\ y\\ z\end{array} \right)$, so
|
2021-01-07 11:07:18 +01:00
|
|
|
$$
|
2021-01-11 20:54:40 +01:00
|
|
|
V(\mathbf{r}) = -\frac{1}{\sqrt{x^2 + y^2 + z^2}}
|
2021-01-07 11:07:18 +01:00
|
|
|
$$
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Python*
|
2021-01-21 23:24:21 +01:00
|
|
|
#+BEGIN_SRC python :results none :tangle none
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
def potential(r):
|
|
|
|
# TODO
|
|
|
|
#+END_SRC
|
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Fortran*
|
|
|
|
#+BEGIN_SRC f90 :tangle none
|
|
|
|
double precision function potential(r)
|
|
|
|
implicit none
|
|
|
|
double precision, intent(in) :: r(3)
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
! TODO
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
end function potential
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
**** Solution :solution:
|
|
|
|
*Python*
|
2021-01-11 20:54:40 +01:00
|
|
|
#+BEGIN_SRC python :results none
|
2021-01-03 18:45:58 +01:00
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
def potential(r):
|
2021-01-26 00:22:37 +01:00
|
|
|
distance = np.sqrt(np.dot(r,r))
|
|
|
|
assert (distance > 0)
|
|
|
|
return -1. / distance
|
2021-01-11 20:54:40 +01:00
|
|
|
#+END_SRC
|
2021-01-07 10:01:55 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Fortran*
|
2021-01-11 20:54:40 +01:00
|
|
|
#+BEGIN_SRC f90
|
2021-01-03 18:45:58 +01:00
|
|
|
double precision function potential(r)
|
|
|
|
implicit none
|
|
|
|
double precision, intent(in) :: r(3)
|
2021-01-29 13:23:00 +01:00
|
|
|
|
|
|
|
double precision :: distance
|
|
|
|
|
2021-01-26 00:22:37 +01:00
|
|
|
distance = dsqrt( r(1)*r(1) + r(2)*r(2) + r(3)*r(3) )
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-26 00:22:37 +01:00
|
|
|
if (distance > 0.d0) then
|
2021-01-29 13:23:00 +01:00
|
|
|
potential = -1.d0 / distance
|
2021-01-26 00:22:37 +01:00
|
|
|
else
|
|
|
|
stop 'potential at r=0.d0 diverges'
|
|
|
|
end if
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
end function potential
|
2021-01-11 20:54:40 +01:00
|
|
|
#+END_SRC
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*** Exercise 2
|
2021-01-12 01:01:52 +01:00
|
|
|
#+begin_exercise
|
|
|
|
Write a function which computes the wave function at $\mathbf{r}$.
|
2021-01-07 11:07:18 +01:00
|
|
|
The function accepts a scalar =a= and a 3-dimensional vector =r= as
|
|
|
|
input arguments, and returns a scalar.
|
2021-01-12 01:01:52 +01:00
|
|
|
#+end_exercise
|
2021-01-11 20:54:40 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Python*
|
2021-01-25 23:52:53 +01:00
|
|
|
#+BEGIN_SRC python :results none :tangle none
|
2021-01-21 23:24:21 +01:00
|
|
|
def psi(a, r):
|
|
|
|
# TODO
|
|
|
|
#+END_SRC
|
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Fortran*
|
2021-01-25 23:52:53 +01:00
|
|
|
#+BEGIN_SRC f90 :tangle none
|
2021-01-21 23:24:21 +01:00
|
|
|
double precision function psi(a, r)
|
|
|
|
implicit none
|
|
|
|
double precision, intent(in) :: a, r(3)
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-21 23:24:21 +01:00
|
|
|
! TODO
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-21 23:24:21 +01:00
|
|
|
end function psi
|
|
|
|
#+END_SRC
|
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
**** Solution :solution:
|
|
|
|
*Python*
|
|
|
|
#+BEGIN_SRC python :results none
|
|
|
|
def psi(a, r):
|
|
|
|
return np.exp(-a*np.sqrt(np.dot(r,r)))
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
*Fortran*
|
2021-01-11 20:54:40 +01:00
|
|
|
#+BEGIN_SRC f90
|
2021-01-03 18:45:58 +01:00
|
|
|
double precision function psi(a, r)
|
|
|
|
implicit none
|
|
|
|
double precision, intent(in) :: a, r(3)
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
psi = dexp(-a * dsqrt( r(1)*r(1) + r(2)*r(2) + r(3)*r(3) ))
|
|
|
|
end function psi
|
2021-01-11 20:54:40 +01:00
|
|
|
#+END_SRC
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*** Exercise 3
|
2021-01-12 01:01:52 +01:00
|
|
|
#+begin_exercise
|
|
|
|
Write a function which computes the local kinetic energy at $\mathbf{r}$.
|
2021-01-07 11:07:18 +01:00
|
|
|
The function accepts =a= and =r= as input arguments and returns the
|
|
|
|
local kinetic energy.
|
2021-01-12 01:01:52 +01:00
|
|
|
#+end_exercise
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-11 20:54:40 +01:00
|
|
|
The local kinetic energy is defined as $$-\frac{1}{2}\frac{\Delta \Psi}{\Psi}.$$
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-07 11:07:18 +01:00
|
|
|
We differentiate $\Psi$ with respect to $x$:
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-11 20:54:40 +01:00
|
|
|
\[\Psi(\mathbf{r}) = \exp(-a\,|\mathbf{r}|) \]
|
|
|
|
\[\frac{\partial \Psi}{\partial x}
|
|
|
|
= \frac{\partial \Psi}{\partial |\mathbf{r}|} \frac{\partial |\mathbf{r}|}{\partial x}
|
|
|
|
= - \frac{a\,x}{|\mathbf{r}|} \Psi(\mathbf{r}) \]
|
2021-01-07 11:07:18 +01:00
|
|
|
|
|
|
|
and we differentiate a second time:
|
|
|
|
|
|
|
|
$$
|
|
|
|
\frac{\partial^2 \Psi}{\partial x^2} =
|
2021-01-11 20:54:40 +01:00
|
|
|
\left( \frac{a^2\,x^2}{|\mathbf{r}|^2} -
|
|
|
|
\frac{a(y^2+z^2)}{|\mathbf{r}|^{3}} \right) \Psi(\mathbf{r}).
|
2021-01-07 11:07:18 +01:00
|
|
|
$$
|
|
|
|
|
|
|
|
The Laplacian operator $\Delta = \frac{\partial^2}{\partial x^2} +
|
|
|
|
\frac{\partial^2}{\partial y^2} + \frac{\partial^2}{\partial z^2}$
|
|
|
|
applied to the wave function gives:
|
|
|
|
|
|
|
|
$$
|
2021-01-11 20:54:40 +01:00
|
|
|
\Delta \Psi (\mathbf{r}) = \left(a^2 - \frac{2a}{\mathbf{|r|}} \right) \Psi(\mathbf{r})
|
2021-01-07 11:07:18 +01:00
|
|
|
$$
|
|
|
|
|
|
|
|
So the local kinetic energy is
|
|
|
|
$$
|
2021-01-11 20:54:40 +01:00
|
|
|
-\frac{1}{2} \frac{\Delta \Psi}{\Psi} (\mathbf{r}) = -\frac{1}{2}\left(a^2 - \frac{2a}{\mathbf{|r|}} \right)
|
2021-01-07 11:07:18 +01:00
|
|
|
$$
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Python*
|
2021-01-25 23:52:53 +01:00
|
|
|
#+BEGIN_SRC python :results none :tangle none
|
2021-01-21 23:24:21 +01:00
|
|
|
def kinetic(a,r):
|
|
|
|
# TODO
|
|
|
|
#+END_SRC
|
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Fortran*
|
2021-01-25 23:52:53 +01:00
|
|
|
#+BEGIN_SRC f90 :tangle none
|
2021-01-21 23:24:21 +01:00
|
|
|
double precision function kinetic(a,r)
|
|
|
|
implicit none
|
|
|
|
double precision, intent(in) :: a, r(3)
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-21 23:24:21 +01:00
|
|
|
! TODO
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-21 23:24:21 +01:00
|
|
|
end function kinetic
|
|
|
|
#+END_SRC
|
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
**** Solution :solution:
|
|
|
|
*Python*
|
|
|
|
#+BEGIN_SRC python :results none
|
|
|
|
def kinetic(a,r):
|
|
|
|
distance = np.sqrt(np.dot(r,r))
|
|
|
|
assert (distance > 0.)
|
2021-01-29 13:23:00 +01:00
|
|
|
|
|
|
|
return a * (1./distance - 0.5 * a)
|
2021-01-27 13:04:32 +01:00
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
*Fortran*
|
2021-01-11 20:54:40 +01:00
|
|
|
#+BEGIN_SRC f90
|
2021-01-03 18:45:58 +01:00
|
|
|
double precision function kinetic(a,r)
|
|
|
|
implicit none
|
|
|
|
double precision, intent(in) :: a, r(3)
|
2021-01-29 13:23:00 +01:00
|
|
|
|
|
|
|
double precision :: distance
|
|
|
|
|
2021-01-26 00:22:37 +01:00
|
|
|
distance = dsqrt( r(1)*r(1) + r(2)*r(2) + r(3)*r(3) )
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-26 00:22:37 +01:00
|
|
|
if (distance > 0.d0) then
|
2021-01-29 13:23:00 +01:00
|
|
|
|
|
|
|
kinetic = a * (1.d0 / distance - 0.5d0 * a)
|
|
|
|
|
2021-01-26 00:22:37 +01:00
|
|
|
else
|
|
|
|
stop 'kinetic energy diverges at r=0'
|
|
|
|
end if
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
end function kinetic
|
2021-01-11 20:54:40 +01:00
|
|
|
#+END_SRC
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*** Exercise 4
|
2021-01-12 01:01:52 +01:00
|
|
|
#+begin_exercise
|
2021-01-21 23:24:21 +01:00
|
|
|
Write a function which computes the local energy at $\mathbf{r}$,
|
|
|
|
using the previously defined functions.
|
|
|
|
The function accepts =a= and =r= as input arguments and returns the
|
|
|
|
local kinetic energy.
|
2021-01-12 01:01:52 +01:00
|
|
|
#+end_exercise
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-07 11:07:18 +01:00
|
|
|
$$
|
2021-01-11 20:54:40 +01:00
|
|
|
E_L(\mathbf{r}) = -\frac{1}{2} \frac{\Delta \Psi}{\Psi} (\mathbf{r}) + V(\mathbf{r})
|
2021-01-07 11:07:18 +01:00
|
|
|
$$
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-11 20:54:40 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Python*
|
2021-01-25 23:52:53 +01:00
|
|
|
#+BEGIN_SRC python :results none :tangle none
|
2021-01-21 23:24:21 +01:00
|
|
|
def e_loc(a,r):
|
|
|
|
#TODO
|
|
|
|
#+END_SRC
|
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Fortran*
|
2021-01-25 23:52:53 +01:00
|
|
|
#+BEGIN_SRC f90 :tangle none
|
2021-01-21 23:24:21 +01:00
|
|
|
double precision function e_loc(a,r)
|
|
|
|
implicit none
|
|
|
|
double precision, intent(in) :: a, r(3)
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-21 23:24:21 +01:00
|
|
|
! TODO
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-21 23:24:21 +01:00
|
|
|
end function e_loc
|
|
|
|
#+END_SRC
|
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
**** Solution :solution:
|
|
|
|
*Python*
|
|
|
|
#+BEGIN_SRC python :results none
|
|
|
|
def e_loc(a,r):
|
|
|
|
return kinetic(a,r) + potential(r)
|
|
|
|
#+END_SRC
|
|
|
|
|
|
|
|
*Fortran*
|
2021-01-11 20:54:40 +01:00
|
|
|
#+BEGIN_SRC f90
|
2021-01-03 18:45:58 +01:00
|
|
|
double precision function e_loc(a,r)
|
|
|
|
implicit none
|
|
|
|
double precision, intent(in) :: a, r(3)
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
double precision, external :: kinetic, potential
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
e_loc = kinetic(a,r) + potential(r)
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
end function e_loc
|
2021-01-11 20:54:40 +01:00
|
|
|
#+END_SRC
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*** Exercise 5
|
|
|
|
|
|
|
|
#+begin_exercise
|
|
|
|
Find the theoretical value of $a$ for which $\Psi$ is an eigenfunction of $\hat{H}$.
|
|
|
|
#+end_exercise
|
|
|
|
|
|
|
|
**** Solution :solution:
|
|
|
|
|
|
|
|
\begin{eqnarray*}
|
|
|
|
E &=& \frac{\hat{H} \Psi}{\Psi} = - \frac{1}{2} \frac{\Delta \Psi}{\Psi} -
|
|
|
|
\frac{1}{|\mathbf{r}|} \\
|
|
|
|
&=& -\frac{1}{2}\left(a^2 - \frac{2a}{\mathbf{|r|}} \right) -
|
|
|
|
\frac{1}{|\mathbf{r}|} \\
|
|
|
|
&=&
|
|
|
|
-\frac{1}{2} a^2 + \frac{a-1}{\mathbf{|r|}}
|
|
|
|
\end{eqnarray*}
|
|
|
|
|
|
|
|
$a=1$ cancels the $1/|r|$ term, and makes the energy constant,
|
|
|
|
equal to -0.5 atomic units.
|
|
|
|
|
2021-01-11 18:41:36 +01:00
|
|
|
** Plot of the local energy along the $x$ axis
|
2021-01-07 11:07:18 +01:00
|
|
|
:PROPERTIES:
|
|
|
|
:header-args:python: :tangle plot_hydrogen.py
|
|
|
|
:header-args:f90: :tangle plot_hydrogen.f90
|
|
|
|
:END:
|
2021-01-12 01:01:52 +01:00
|
|
|
|
2021-01-26 00:22:37 +01:00
|
|
|
#+begin_note
|
|
|
|
The potential and the kinetic energy both diverge at $r=0$, so we
|
|
|
|
choose a grid which does not contain the origin.
|
|
|
|
#+end_note
|
|
|
|
|
2021-01-12 01:01:52 +01:00
|
|
|
*** Exercise
|
|
|
|
#+begin_exercise
|
|
|
|
For multiple values of $a$ (0.1, 0.2, 0.5, 1., 1.5, 2.), plot the
|
2021-01-21 23:24:21 +01:00
|
|
|
local energy along the $x$ axis. In Python, you can use matplotlib
|
|
|
|
for example. In Fortran, it is convenient to write in a text file
|
|
|
|
the values of $x$ and $E_L(\mathbf{r})$ for each point, and use
|
|
|
|
Gnuplot to plot the files.
|
2021-01-12 01:01:52 +01:00
|
|
|
#+end_exercise
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Python*
|
2021-01-25 23:52:53 +01:00
|
|
|
#+BEGIN_SRC python :results none :tangle none
|
2021-01-03 18:45:58 +01:00
|
|
|
import numpy as np
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
|
|
|
from hydrogen import e_loc
|
|
|
|
|
|
|
|
x=np.linspace(-5,5)
|
2021-01-21 23:24:21 +01:00
|
|
|
plt.figure(figsize=(10,5))
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-21 23:24:21 +01:00
|
|
|
# TODO
|
|
|
|
|
|
|
|
plt.tight_layout()
|
|
|
|
plt.legend()
|
|
|
|
plt.savefig("plot_py.png")
|
|
|
|
#+end_src
|
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Fortran*
|
2021-01-25 23:52:53 +01:00
|
|
|
#+begin_src f90 :tangle none
|
2021-01-21 23:24:21 +01:00
|
|
|
program plot
|
|
|
|
implicit none
|
|
|
|
double precision, external :: e_loc
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-21 23:24:21 +01:00
|
|
|
double precision :: x(50), dx
|
|
|
|
integer :: i, j
|
|
|
|
|
|
|
|
dx = 10.d0/(size(x)-1)
|
|
|
|
do i=1,size(x)
|
|
|
|
x(i) = -5.d0 + (i-1)*dx
|
|
|
|
end do
|
|
|
|
|
|
|
|
! TODO
|
|
|
|
|
|
|
|
end program plot
|
2021-01-25 23:52:53 +01:00
|
|
|
#+end_src
|
2021-01-21 23:24:21 +01:00
|
|
|
|
2021-01-25 23:52:53 +01:00
|
|
|
To compile and run:
|
2021-01-21 23:24:21 +01:00
|
|
|
|
2021-01-25 23:52:53 +01:00
|
|
|
#+begin_src sh :exports both
|
2021-01-21 23:24:21 +01:00
|
|
|
gfortran hydrogen.f90 plot_hydrogen.f90 -o plot_hydrogen
|
|
|
|
./plot_hydrogen > data
|
2021-01-25 23:52:53 +01:00
|
|
|
#+end_src
|
2021-01-21 23:24:21 +01:00
|
|
|
|
2021-01-25 23:52:53 +01:00
|
|
|
To plot the data using Gnuplot:
|
2021-01-21 23:24:21 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
#+begin_src gnuplot :file plot.png :exports code
|
2021-01-21 23:24:21 +01:00
|
|
|
set grid
|
|
|
|
set xrange [-5:5]
|
|
|
|
set yrange [-2:1]
|
|
|
|
plot './data' index 0 using 1:2 with lines title 'a=0.1', \
|
|
|
|
'./data' index 1 using 1:2 with lines title 'a=0.2', \
|
|
|
|
'./data' index 2 using 1:2 with lines title 'a=0.5', \
|
|
|
|
'./data' index 3 using 1:2 with lines title 'a=1.0', \
|
|
|
|
'./data' index 4 using 1:2 with lines title 'a=1.5', \
|
|
|
|
'./data' index 5 using 1:2 with lines title 'a=2.0'
|
2021-01-25 23:52:53 +01:00
|
|
|
#+end_src
|
2021-01-21 23:24:21 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
**** Solution :solution:
|
|
|
|
*Python*
|
|
|
|
#+BEGIN_SRC python :results none
|
|
|
|
import numpy as np
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
|
|
|
from hydrogen import e_loc
|
|
|
|
|
|
|
|
x=np.linspace(-5,5)
|
|
|
|
plt.figure(figsize=(10,5))
|
|
|
|
|
|
|
|
for a in [0.1, 0.2, 0.5, 1., 1.5, 2.]:
|
|
|
|
y=np.array([ e_loc(a, np.array([t,0.,0.]) ) for t in x])
|
|
|
|
plt.plot(x,y,label=f"a={a}")
|
|
|
|
|
|
|
|
plt.tight_layout()
|
|
|
|
plt.legend()
|
|
|
|
plt.savefig("plot_py.png")
|
|
|
|
#+end_src
|
|
|
|
|
|
|
|
#+RESULTS:
|
|
|
|
|
|
|
|
[[./plot_py.png]]
|
|
|
|
|
|
|
|
*Fortran*
|
2021-01-25 23:52:53 +01:00
|
|
|
#+begin_src f90
|
2021-01-03 18:45:58 +01:00
|
|
|
program plot
|
|
|
|
implicit none
|
|
|
|
double precision, external :: e_loc
|
|
|
|
|
|
|
|
double precision :: x(50), energy, dx, r(3), a(6)
|
|
|
|
integer :: i, j
|
|
|
|
|
|
|
|
a = (/ 0.1d0, 0.2d0, 0.5d0, 1.d0, 1.5d0, 2.d0 /)
|
|
|
|
|
|
|
|
dx = 10.d0/(size(x)-1)
|
|
|
|
do i=1,size(x)
|
|
|
|
x(i) = -5.d0 + (i-1)*dx
|
|
|
|
end do
|
|
|
|
|
|
|
|
r(:) = 0.d0
|
|
|
|
|
|
|
|
do j=1,size(a)
|
|
|
|
print *, '# a=', a(j)
|
|
|
|
do i=1,size(x)
|
|
|
|
r(1) = x(i)
|
|
|
|
energy = e_loc( a(j), r )
|
|
|
|
print *, x(i), energy
|
|
|
|
end do
|
|
|
|
print *, ''
|
|
|
|
print *, ''
|
|
|
|
end do
|
|
|
|
|
|
|
|
end program plot
|
2021-01-25 23:52:53 +01:00
|
|
|
#+end_src
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
#+begin_src sh :exports none
|
2021-01-03 18:45:58 +01:00
|
|
|
gfortran hydrogen.f90 plot_hydrogen.f90 -o plot_hydrogen
|
|
|
|
./plot_hydrogen > data
|
2021-01-25 23:52:53 +01:00
|
|
|
#+end_src
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
#+begin_src gnuplot :file plot.png :exports results
|
2021-01-03 18:45:58 +01:00
|
|
|
set grid
|
|
|
|
set xrange [-5:5]
|
|
|
|
set yrange [-2:1]
|
|
|
|
plot './data' index 0 using 1:2 with lines title 'a=0.1', \
|
|
|
|
'./data' index 1 using 1:2 with lines title 'a=0.2', \
|
|
|
|
'./data' index 2 using 1:2 with lines title 'a=0.5', \
|
|
|
|
'./data' index 3 using 1:2 with lines title 'a=1.0', \
|
|
|
|
'./data' index 4 using 1:2 with lines title 'a=1.5', \
|
|
|
|
'./data' index 5 using 1:2 with lines title 'a=2.0'
|
2021-01-25 23:52:53 +01:00
|
|
|
#+end_src
|
|
|
|
#+RESULTS:
|
|
|
|
[[file:plot.png]]
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-25 23:52:53 +01:00
|
|
|
** Numerical estimation of the energy
|
2021-01-07 11:07:18 +01:00
|
|
|
:PROPERTIES:
|
|
|
|
:header-args:python: :tangle energy_hydrogen.py
|
|
|
|
:header-args:f90: :tangle energy_hydrogen.f90
|
|
|
|
:END:
|
|
|
|
|
2021-01-11 20:54:40 +01:00
|
|
|
If the space is discretized in small volume elements $\mathbf{r}_i$
|
|
|
|
of size $\delta \mathbf{r}$, the expression of $\langle E_L \rangle_{\Psi^2}$
|
|
|
|
becomes a weighted average of the local energy, where the weights
|
|
|
|
are the values of the probability density at $\mathbf{r}_i$
|
|
|
|
multiplied by the volume element:
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-07 11:07:18 +01:00
|
|
|
$$
|
2021-01-11 18:41:36 +01:00
|
|
|
\langle E \rangle_{\Psi^2} \approx \frac{\sum_i w_i E_L(\mathbf{r}_i)}{\sum_i w_i}, \;\;
|
2021-01-07 11:07:18 +01:00
|
|
|
w_i = \left[\Psi(\mathbf{r}_i)\right]^2 \delta \mathbf{r}
|
|
|
|
$$
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-11 20:54:40 +01:00
|
|
|
#+begin_note
|
|
|
|
The energy is biased because:
|
2021-01-11 18:41:36 +01:00
|
|
|
- The volume elements are not infinitely small (discretization error)
|
|
|
|
- The energy is evaluated only inside the box (incompleteness of the space)
|
2021-01-11 20:54:40 +01:00
|
|
|
#+end_note
|
2021-01-07 10:01:55 +01:00
|
|
|
|
2021-01-12 01:01:52 +01:00
|
|
|
|
|
|
|
*** Exercise
|
|
|
|
#+begin_exercise
|
|
|
|
Compute a numerical estimate of the energy in a grid of
|
|
|
|
$50\times50\times50$ points in the range $(-5,-5,-5) \le
|
|
|
|
\mathbf{r} \le (5,5,5)$.
|
|
|
|
#+end_exercise
|
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Python*
|
2021-01-25 23:52:53 +01:00
|
|
|
#+BEGIN_SRC python :results none :tangle none
|
|
|
|
import numpy as np
|
|
|
|
from hydrogen import e_loc, psi
|
|
|
|
|
|
|
|
interval = np.linspace(-5,5,num=50)
|
|
|
|
delta = (interval[1]-interval[0])**3
|
|
|
|
|
|
|
|
r = np.array([0.,0.,0.])
|
|
|
|
|
|
|
|
for a in [0.1, 0.2, 0.5, 0.9, 1., 1.5, 2.]:
|
|
|
|
# TODO
|
|
|
|
print(f"a = {a} \t E = {E}")
|
|
|
|
|
|
|
|
#+end_src
|
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Fortran*
|
|
|
|
#+begin_src f90
|
|
|
|
program energy_hydrogen
|
|
|
|
implicit none
|
|
|
|
double precision, external :: e_loc, psi
|
|
|
|
double precision :: x(50), w, delta, energy, dx, r(3), a(6), norm
|
|
|
|
integer :: i, k, l, j
|
|
|
|
|
|
|
|
a = (/ 0.1d0, 0.2d0, 0.5d0, 1.d0, 1.5d0, 2.d0 /)
|
|
|
|
|
|
|
|
dx = 10.d0/(size(x)-1)
|
|
|
|
do i=1,size(x)
|
|
|
|
x(i) = -5.d0 + (i-1)*dx
|
|
|
|
end do
|
|
|
|
|
|
|
|
do j=1,size(a)
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
! TODO
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
print *, 'a = ', a(j), ' E = ', energy
|
|
|
|
end do
|
|
|
|
|
|
|
|
end program energy_hydrogen
|
|
|
|
#+end_src
|
|
|
|
|
|
|
|
To compile the Fortran and run it:
|
|
|
|
|
|
|
|
#+begin_src sh :results output :exports code
|
|
|
|
gfortran hydrogen.f90 energy_hydrogen.f90 -o energy_hydrogen
|
|
|
|
./energy_hydrogen
|
|
|
|
#+end_src
|
|
|
|
|
|
|
|
**** Solution :solution:
|
|
|
|
*Python*
|
|
|
|
#+BEGIN_SRC python :results none :exports both
|
2021-01-03 18:45:58 +01:00
|
|
|
import numpy as np
|
|
|
|
from hydrogen import e_loc, psi
|
|
|
|
|
2021-01-11 18:41:36 +01:00
|
|
|
interval = np.linspace(-5,5,num=50)
|
|
|
|
delta = (interval[1]-interval[0])**3
|
2021-01-07 11:07:18 +01:00
|
|
|
|
2021-01-11 18:41:36 +01:00
|
|
|
r = np.array([0.,0.,0.])
|
2021-01-07 11:07:18 +01:00
|
|
|
|
2021-01-11 18:41:36 +01:00
|
|
|
for a in [0.1, 0.2, 0.5, 0.9, 1., 1.5, 2.]:
|
2021-01-29 13:23:00 +01:00
|
|
|
E = 0.
|
2021-01-11 18:41:36 +01:00
|
|
|
norm = 0.
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-25 23:52:53 +01:00
|
|
|
for x in interval:
|
|
|
|
r[0] = x
|
|
|
|
for y in interval:
|
|
|
|
r[1] = y
|
|
|
|
for z in interval:
|
|
|
|
r[2] = z
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-25 23:52:53 +01:00
|
|
|
w = psi(a,r)
|
|
|
|
w = w * w * delta
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-25 23:52:53 +01:00
|
|
|
E += w * e_loc(a,r)
|
|
|
|
norm += w
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-11 18:41:36 +01:00
|
|
|
E = E / norm
|
|
|
|
print(f"a = {a} \t E = {E}")
|
|
|
|
|
2021-01-25 23:52:53 +01:00
|
|
|
#+end_src
|
2021-01-07 11:07:18 +01:00
|
|
|
|
2021-01-25 23:52:53 +01:00
|
|
|
#+RESULTS:
|
|
|
|
: a = 0.1 E = -0.24518438948809218
|
|
|
|
: a = 0.2 E = -0.26966057967803525
|
|
|
|
: a = 0.5 E = -0.3856357612517407
|
|
|
|
: a = 0.9 E = -0.49435709786716214
|
|
|
|
: a = 1.0 E = -0.5
|
|
|
|
: a = 1.5 E = -0.39242967082602226
|
|
|
|
: a = 2.0 E = -0.08086980667844901
|
2021-01-07 11:07:18 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Fortran*
|
2021-01-25 23:52:53 +01:00
|
|
|
#+begin_src f90
|
2021-01-03 18:45:58 +01:00
|
|
|
program energy_hydrogen
|
|
|
|
implicit none
|
|
|
|
double precision, external :: e_loc, psi
|
|
|
|
double precision :: x(50), w, delta, energy, dx, r(3), a(6), norm
|
2021-01-29 13:23:00 +01:00
|
|
|
integer :: i, k, l, j
|
2021-01-03 18:45:58 +01:00
|
|
|
|
|
|
|
a = (/ 0.1d0, 0.2d0, 0.5d0, 1.d0, 1.5d0, 2.d0 /)
|
|
|
|
|
|
|
|
dx = 10.d0/(size(x)-1)
|
|
|
|
do i=1,size(x)
|
|
|
|
x(i) = -5.d0 + (i-1)*dx
|
|
|
|
end do
|
|
|
|
|
|
|
|
delta = dx**3
|
|
|
|
|
|
|
|
r(:) = 0.d0
|
|
|
|
|
|
|
|
do j=1,size(a)
|
|
|
|
energy = 0.d0
|
2021-01-29 13:23:00 +01:00
|
|
|
norm = 0.d0
|
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
do i=1,size(x)
|
|
|
|
r(1) = x(i)
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
do k=1,size(x)
|
|
|
|
r(2) = x(k)
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
do l=1,size(x)
|
|
|
|
r(3) = x(l)
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
w = psi(a(j),r)
|
|
|
|
w = w * w * delta
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
energy = energy + w * e_loc(a(j), r)
|
|
|
|
norm = norm + w
|
|
|
|
end do
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
end do
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
end do
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-03 18:45:58 +01:00
|
|
|
energy = energy / norm
|
|
|
|
print *, 'a = ', a(j), ' E = ', energy
|
|
|
|
end do
|
|
|
|
|
|
|
|
end program energy_hydrogen
|
2021-01-25 23:52:53 +01:00
|
|
|
#+end_src
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
#+begin_src sh :results output :exports results
|
2021-01-03 18:45:58 +01:00
|
|
|
gfortran hydrogen.f90 energy_hydrogen.f90 -o energy_hydrogen
|
|
|
|
./energy_hydrogen
|
2021-01-25 23:52:53 +01:00
|
|
|
#+end_src
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-25 23:52:53 +01:00
|
|
|
#+RESULTS:
|
|
|
|
: a = 0.10000000000000001 E = -0.24518438948809140
|
|
|
|
: a = 0.20000000000000001 E = -0.26966057967803236
|
|
|
|
: a = 0.50000000000000000 E = -0.38563576125173815
|
|
|
|
: a = 1.0000000000000000 E = -0.50000000000000000
|
|
|
|
: a = 1.5000000000000000 E = -0.39242967082602065
|
|
|
|
: a = 2.0000000000000000 E = -8.0869806678448772E-002
|
|
|
|
|
|
|
|
** Variance of the local energy
|
2021-01-07 11:07:18 +01:00
|
|
|
:PROPERTIES:
|
|
|
|
:header-args:python: :tangle variance_hydrogen.py
|
|
|
|
:header-args:f90: :tangle variance_hydrogen.f90
|
|
|
|
:END:
|
|
|
|
|
2021-01-11 18:41:36 +01:00
|
|
|
The variance of the local energy is a functional of $\Psi$
|
|
|
|
which measures the magnitude of the fluctuations of the local
|
2021-01-25 23:52:53 +01:00
|
|
|
energy associated with $\Psi$ around its average:
|
2021-01-07 11:07:18 +01:00
|
|
|
|
|
|
|
$$
|
|
|
|
\sigma^2(E_L) = \frac{\int \left[\Psi(\mathbf{r})\right]^2\, \left[
|
|
|
|
E_L(\mathbf{r}) - E \right]^2 \, d\mathbf{r}}{\int \left[\Psi(\mathbf{r}) \right]^2 d\mathbf{r}}
|
|
|
|
$$
|
2021-01-19 10:45:36 +01:00
|
|
|
which can be simplified as
|
|
|
|
|
2021-01-25 23:52:53 +01:00
|
|
|
$$ \sigma^2(E_L) = \langle E_L^2 \rangle_{\Psi^2} - \langle E_L \rangle_{\Psi^2}^2.$$
|
2021-01-07 11:07:18 +01:00
|
|
|
|
2021-01-11 18:41:36 +01:00
|
|
|
If the local energy is constant (i.e. $\Psi$ is an eigenfunction of
|
|
|
|
$\hat{H}$) the variance is zero, so the variance of the local
|
|
|
|
energy can be used as a measure of the quality of a wave function.
|
|
|
|
|
2021-01-19 10:45:36 +01:00
|
|
|
*** Exercise (optional)
|
|
|
|
#+begin_exercise
|
|
|
|
Prove that :
|
2021-01-25 23:52:53 +01:00
|
|
|
$$\left( \langle E - \langle E \rangle_{\Psi^2} \rangle_{\Psi^2} \right)^2 = \langle E^2 \rangle_{\Psi^2} - \langle E \rangle_{\Psi^2}^2 $$
|
2021-01-19 10:45:36 +01:00
|
|
|
#+end_exercise
|
|
|
|
|
2021-01-27 15:21:44 +01:00
|
|
|
**** Solution :solution:
|
|
|
|
|
|
|
|
$\bar{E} = \langle E \rangle$ is a constant, so $\langle \bar{E}
|
|
|
|
\rangle = \bar{E}$ .
|
|
|
|
|
|
|
|
\begin{eqnarray*}
|
|
|
|
\langle E - \bar{E} \rangle^2 & = &
|
|
|
|
\langle E^2 - 2 E \bar{E} + \bar{E}^2 \rangle \\
|
|
|
|
&=& \langle E^2 \rangle - 2 \langle E \bar{E} \rangle + \langle \bar{E}^2 \rangle \\
|
|
|
|
&=& \langle E^2 \rangle - 2 \langle E \rangle \bar{E} + \bar{E}^2 \\
|
|
|
|
&=& \langle E^2 \rangle - 2 \bar{E}^2 + \bar{E}^2 \\
|
|
|
|
&=& \langle E^2 \rangle - \bar{E}^2 \\
|
|
|
|
&=& \langle E^2 \rangle - \langle E \rangle^2 \\
|
|
|
|
\end{eqnarray*}
|
2021-01-12 01:01:52 +01:00
|
|
|
*** Exercise
|
|
|
|
#+begin_exercise
|
2021-01-27 15:21:44 +01:00
|
|
|
Add the calculation of the variance to the previous code, and
|
|
|
|
compute a numerical estimate of the variance of the local energy in
|
|
|
|
a grid of $50\times50\times50$ points in the range $(-5,-5,-5) \le
|
|
|
|
\mathbf{r} \le (5,5,5)$ for different values of $a$.
|
2021-01-12 01:01:52 +01:00
|
|
|
#+end_exercise
|
2021-01-03 18:45:58 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Python*
|
2021-01-25 23:52:53 +01:00
|
|
|
#+begin_src python :results none :tangle none
|
2021-01-27 15:21:44 +01:00
|
|
|
import numpy as np from hydrogen import e_loc, psi
|
2021-01-25 23:52:53 +01:00
|
|
|
|
2021-01-29 13:23:00 +01:00
|
|
|
interval = np.linspace(-5,5,num=50)
|
|
|
|
|
|
|
|
delta = (interval[1]-interval[0])**3
|
2021-01-25 23:52:53 +01:00
|
|
|
|
|
|
|
r = np.array([0.,0.,0.])
|
|
|
|
|
|
|
|
for a in [0.1, 0.2, 0.5, 0.9, 1., 1.5, 2.]:
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-25 23:52:53 +01:00
|
|
|
# TODO
|
2021-01-29 13:23:00 +01:00
|
|
|
|
2021-01-27 15:21:44 +01:00
|
|
|
print(f"a = {a} \t E = {E:10.8f} \t \sigma^2 = {s2:10.8f}")
|
|
|
|
#+end_src
|
2021-01-25 23:52:53 +01:00
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
*Fortran*
|
|
|
|
#+begin_src f90 :tangle none
|
2021-01-29 13:23:00 +01:00
|
|
|
program variance_hydrogen
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
double precision :: x(50), w, delta, energy, energy2
|
|
|
|
double precision :: dx, r(3), a(6), norm, e_tmp, s2
|
|
|
|
integer :: i, k, l, j
|
|
|
|
|
|
|
|
double precision, external :: e_loc, psi
|
2021-01-27 13:04:32 +01:00
|
|
|
|
|
|
|
a = (/ 0.1d0, 0.2d0, 0.5d0, 1.d0, 1.5d0, 2.d0 /)
|
|
|
|
|
2021-01-29 13:23:00 +01:00
|
|
|
dx = 10.d0/(size(x)-1)
|
|
|
|
do i=1,size(x)
|
|
|
|
x(i) = -5.d0 + (i-1)*dx
|
|
|
|
end do
|
|
|
|
|
|
|
|
do j=1,size(a)
|
|
|
|
|
|
|
|
! TODO
|
|
|
|
|
|
|
|
print *, 'a = ', a(j), ' E = ', energy
|
|
|
|
end do
|
|
|
|
|
|
|
|
end program variance_hydrogen
|
|
|
|
#+end_src
|
2021-01-27 13:04:32 +01:00
|
|
|
|
|
|
|
To compile and run:
|
|
|
|
|
|
|
|
#+begin_src sh :results output :exports both
|
|
|
|
gfortran hydrogen.f90 variance_hydrogen.f90 -o variance_hydrogen
|
2021-01-29 13:23:00 +01:00
|
|
|
./variance_hydrogen
|
|
|
|
#+end_src
|
|
|
|
|
2021-01-27 13:04:32 +01:00
|
|
|
**** Solution :solution:
|
|
|
|
*Python*
|
|