Photoelectric effect gif

Here are provided two simple gif images in order to illustrate the photoelectric effect.

Below the threshold energy, nothing append, whatever the light intensity.

No photoelectric effect
No photoelectric effect

Above the threshold energy, each photon bear enough energy in order to extract electrons from the material.

Photoelectric effect
Photoelectric effect

All pictures can be downloaded here : graphene.zip

Bands diagram using VASP and pymatgen

This article presents a python source code in order to plot the bands diagram of graphene calculated using VASP. The plot is done using pymatgen library and RGB coloring adapted from this example. Here is the output obtained with the script :

Graphene bands diagram
Graphene bands diagram

On the band diagram, the contribution of s, (px,py) and pz atomic orbital is map on a RGB scale. Red is associated to a s contribution, green to (px, py) contribution and blue to pz contribution. The same function or procedure can be used to map atomic contributions on the band diagram.

At the end of the article you can find a tarball containing all VASP input/ouput files and the python source code. This calculation is not accurate and is used only for band diagram plotting illustration. For example, you can see a short gap on the DOS which does not exist.

Edit 2016, March 15, update : source code is now python3 and pymatgen version 3.3.5 compatible. You can find the below scripts in an up to date version on github : bandstructureplots

#!/usr/bin/env python
# -*- coding=utf-8 -*-
 
import sys
 
import numpy as np
from numpy import array as npa
 
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from matplotlib.gridspec import GridSpec
 
import pymatgen as mg
from pymatgen.io.vasp.outputs import Vasprun, Procar
from pymatgen.symmetry.bandstructure import HighSymmKpath
from pymatgen.electronic_structure.core import Spin, Orbital
 
 
def rgbline(ax, k, e, red, green, blue, alpha=1.):
    # creation of segments based on
    # http://nbviewer.ipython.org/urls/raw.github.com/dpsanders/matplotlib-examples/master/colorline.ipynb
    pts = np.array([k, e]).T.reshape(-1, 1, 2)
    seg = np.concatenate([pts[:-1], pts[1:]], axis=1)
 
    nseg = len(k) - 1
    r = [0.5 * (red[i] + red[i + 1]) for i in range(nseg)]
    g = [0.5 * (green[i] + green[i + 1]) for i in range(nseg)]
    b = [0.5 * (blue[i] + blue[i + 1]) for i in range(nseg)]
    a = np.ones(nseg, np.float) * alpha
    lc = LineCollection(seg, colors=list(zip(r, g, b, a)), linewidth=2)
    ax.add_collection(lc)
 
if __name__ == "__main__":
    # read data
    # ---------
 
    # kpoints labels
    path = HighSymmKpath(mg.Structure.from_file("./opt/CONTCAR")).kpath["path"]
    labels = [r"$%s$" % lab for lab in path[0][0:4]]
 
    # bands
    bands = Vasprun("./bands/vasprun.xml").get_band_structure("./bands/KPOINTS", line_mode=True)
 
    # projected bands
    data = Procar("./bands/PROCAR").data
 
    # density of state
    dosrun = Vasprun("./dos/vasprun.xml")
 
    # set up matplotlib plot
    # ----------------------
 
    # general options for plot
    font = {'family': 'serif', 'size': 24}
    plt.rc('font', **font)
 
    # set up 2 graph with aspec ration 2/1
    # plot 1: bands diagram
    # plot 2: Density of State
    gs = GridSpec(1, 2, width_ratios=[2, 1])
    fig = plt.figure(figsize=(11.69, 8.27))
    fig.suptitle("Bands diagram of graphene")
    ax1 = plt.subplot(gs[0])
    ax2 = plt.subplot(gs[1])  # , sharey=ax1)
 
    # set ylim for the plot
    # ---------------------
    emin = 1e100
    emax = -1e100
    for spin in bands.bands.keys():
        for b in range(bands.nb_bands):
            emin = min(emin, min(bands.bands[spin][b]))
            emax = max(emax, max(bands.bands[spin][b]))
 
    emin -= bands.efermi + 1
    emax -= bands.efermi - 1
    ax1.set_ylim(emin, emax)
    ax2.set_ylim(emin, emax)
 
    # Band Diagram
    # ------------
 
    # sum up contribution over carbon atoms
    data = data[Spin.up].sum(axis=2)
 
    # sum up px and py contributions and normalize contributions
    contrib = np.zeros((bands.nb_bands, len(bands.kpoints), 3))
    for b in range(bands.nb_bands):
        for k in range(len(bands.kpoints)):
            sc = data[k][b][Orbital.s.value]**2
            pxpyc = data[k][b][Orbital.px.value]**2 + \
                data[k][b][Orbital.py.value]**2
            pzc = data[k][b][Orbital.pz.value]**2
            tot = sc + pxpyc + pzc
            if tot != 0.0:
                contrib[b, k, 0] = sc / tot
                contrib[b, k, 1] = pxpyc / tot
                contrib[b, k, 2] = pzc / tot
 
    # plot bands using rgb mapping
    for b in range(bands.nb_bands):
        rgbline(ax1,
                range(len(bands.kpoints)),
                [e - bands.efermi for e in bands.bands[Spin.up][b]],
                contrib[b, :, 0],
                contrib[b, :, 1],
                contrib[b, :, 2])
 
    # style
    ax1.set_xlabel("k-points")
    ax1.set_ylabel(r"$E - E_f$   /   eV")
    ax1.grid()
 
    # fermi level at 0
    ax1.hlines(y=0, xmin=0, xmax=len(bands.kpoints), color="k", lw=2)
 
    # labels
    nlabs = len(labels)
    step = len(bands.kpoints) / (nlabs - 1)
    for i, lab in enumerate(labels):
        ax1.vlines(i * step, emin, emax, "k")
    ax1.set_xticks([i * step for i in range(nlabs)])
    ax1.set_xticklabels(labels)
 
    ax1.set_xlim(0, len(bands.kpoints))
 
    # Density of state
    # ----------------
 
    ax2.set_yticklabels([])
    ax2.grid()
    ax2.set_xticks(np.arange(0, 1.5, 0.4))
    ax2.set_xticklabels(np.arange(0, 1.5, 0.4))
    ax2.set_xlim(1e-6, 1.5)
    ax2.hlines(y=0, xmin=0, xmax=1.5, color="k", lw=2)
    ax2.set_xlabel("Density of State")
 
    # s contribution
    ax2.plot(npa(dosrun.pdos[0][Orbital.s][Spin.up]) +
             npa(dosrun.pdos[1][Orbital.s][Spin.up]),
             dosrun.tdos.energies - dosrun.efermi,
             "r-", label="s", linewidth=2)
 
    # px py contribution
    ax2.plot(npa(dosrun.pdos[0][Orbital.px][Spin.up]) +
             npa(dosrun.pdos[1][Orbital.px][Spin.up]) +
             npa(dosrun.pdos[0][Orbital.py][Spin.up]) +
             npa(dosrun.pdos[1][Orbital.py][Spin.up]),
             dosrun.tdos.energies - dosrun.efermi,
             "g-",
             label="(px, py)",
             linewidth=2)
 
    # pz contribution
    ax2.plot(npa(dosrun.pdos[0][Orbital.pz][Spin.up]) +
             npa(dosrun.pdos[1][Orbital.pz][Spin.up]),
             dosrun.tdos.energies - dosrun.efermi,
             "b-", label="pz", linewidth=2)
 
    # total dos
    ax2.fill_between(dosrun.tdos.densities[Spin.up],
                     0,
                     dosrun.tdos.energies - dosrun.efermi,
                     color=(0.7, 0.7, 0.7),
                     facecolor=(0.7, 0.7, 0.7))
 
    ax2.plot(dosrun.tdos.densities[Spin.up],
             dosrun.tdos.energies - dosrun.efermi,
             color=(0.6, 0.6, 0.6),
             label="total DOS")
 
    # plot format style
    # -----------------
 
    ax2.legend(fancybox=True, shadow=True, prop={'size': 18})
    plt.subplots_adjust(wspace=0)
 
    # plt.show()
    plt.savefig(sys.argv[0].strip(".py") + ".pdf", format="pdf")

graphene.zip

Hereafter there are two more examples for Cu and Si. The script may be simpler as all data can be extracted using pymatgen methods.

Si_bands.zip

Cu_bands.zip

Bands diagram of copper

Bands diagram of silicon

Outils pour la symétrie moléculaire : théorie des groupes

En chimie et en physique, on utilise les propriétés de symétrie du système pour simplifier la résolution. L’outils mathématiques à la base de l’utilisation de la symétrie en chimie est la théorie des groupes. Le livre « chimie et théorie des groupes » de Paul H. Walton (édition De Boeck) est un ouvrages bien adapté aux chimistes ou physico-chimistes qui désirent découvrir cette approche.

Lorsqu’on utilise la théorie des groupes, une étape primordiale et très mécanique est la décomposition de la représentation d’un groupe en représentation irréductibles de ce groupe (analogue à déterminer les coordonnées d’un vecteur dans une base orthonormée). Le module python ci-dessous permet d’obtenir automatiquement la décomposition. Voici un exemple :

>>> from groupes import c4v
>>> rep = [4, 0, 0, 2, 0]
>>> print(c4v)
 C4v  |     1E      2C4      1C2    2sigma_v 2sigma_d
------------------------------------------------------------
  A1  |     1        1        1        1        1    
  A2  |     1        1        1        -1       -1   
  B1  |     1        -1       1        1        -1   
  B2  |     1        -1       1        -1       1    
  E   |     2        0        -2       0        0
>>> c4v.ordre
8
>>> c4v.reduce(rep)
1 A1 + 1 B1 + 1 E

Je n’ai pas entré tous les groupes ponctuels de symétrie mais uniquement ceux dont j’ai eu besoin pour le moment. Les groupes disponnibles sont :

  • C2v
  • C3v
  • C4v
  • D3h
  • D4h

groupes.py

vasptools : a package for vasp post treatments

Since may 2014, I did not continue the development of vasptools. I strongly recommend you tu use pymatgen instead.

vasptools is a package wrote in python in order to do pre or post treatments of a VASP calculations. This package contains :

  • python modules : vasptools, crystal, myxml, adsorption
  • several script using vasptools module

Scripts and functions read the data into the vasprun.xml file because it contains both input parameters and the results of a calculations. The main features are :

  • extract or plot density of state
  • extract or plot bands
  • get structural data
  • control convergence
  • a tools to put a molecule at a given position on a slab
  • some simple operation on CHGCAR file (split, sum)

You can find the whole documentation here : vasptools documentation.

vasptools.tar.gz (version 58 : 20/03/2013)

If you want to contribute, please contact me.

Guide pour tracer des graphiques en coordonnées polaires ou sphériques

Pour tracer un graphique en utilisant les coordonnées polaires le quadrillage habituel (feuille à carreaux, papier millimétré …) n’est pas adapté car il est fait pour des coordonnées cartésiennes. Les codes des figures que je donne ici permettent de tracer des guides qui facilitent le tracé de courbes en coordonnées polaire.

Guide pour tracer des courbes en coordonnées polaires

Lorsqu’on utilise les coordonnées sphériques, on peut choisir de tracer la fonction dans un plan de l’espace, par exemple le plan (xOz). En coordonnées sphériques, l’angle \theta n’est pas défini de la même manière qu’en coordonnées polaires. Il faut donc faire quelques modifications. Voici ci-dessous un exemple de tracé de la partie angulaire de l’orbitale atomique d_{z^2} dans le plan (xOz) en coordonnées sphériques.

orbitale atomique dz2 tracée avec tikz

Le fichier polar_graph.tex ci-dessous contient :

  • Le guide pour tracer des courbes en coordonnées polaires
  • Le guide pour tracer des courbes en coordonnées sphériques dans le plan (xOz)
  • L’exemple de dessin de la partie angulaire de l’orbitale atomique d_{z^2}

Fichier source : polar_graph.tex

Fichier pdf : polar_graph.pdf

Ci-dessous un script en python qui permet de faire un graphique en coordonnées polaires en utilisant la librairies matplotlib. Le défaut est que c’est un graphique en coordonnées polaires, donc du fait de la définition de l’angle \theta, l’axe z est horizontal.

orbitale atomique dz2 tracée avec python

script : dz2.py

Orbites de l’atome de Bohr

Niels Bohr (1885 – 1962) était un physicien danois. Il est l’un des premiers à avoir introduit la notion de quantification de l’énergie à l’échelle microscopique. Ces travaux furent un point de départ pour le développement de la mécanique quantique.

Modèle de Bohr de l'atome d'hydrogène

Le modèle de Bohr est un modèle planétaire de l’atome tel que celui de Rutherford. Bohr ajouta cependant plusieurs hypothèses :

  • L’électron ne peut se trouver que sur des orbites stables où il ne rayonne aucune énergie.
  • Ces orbites stables sont telles que m_e v R = n \hbar , où R est le rayon de l’orbite, v la vitesse de l’électron et n un nombre entier strictement positif. \hbar = h/2\pi, avec h la constante de Planck.
  • L’électron n’absorbe ni ne rayonne d’énergie que lors d’un changement d’orbite.

En introduisant ces hypothèses dans les équations du mouvement classiques de l’électron autour d’un proton, on obtient que le rayon des orbites de Bohr est donné par n^2 a_o, où a_o est appelé rayon de Bohr et vaut 0.529 \AA soit 0.529e-10 m.

Fichier source : atome_bohr.tex

Fichier pdf : atome_bohr.pdf

Le script ci-dessous, écrit en python, utilise la bibliothèque mathplotlib pour tracer les n premières orbites de Bohr et suivre l’évolution du rapport et de la différence entre deux rayons de Bohr consécutifs.

script : r.py

Transitions électroniques

Ce schéma présente les différentes transitions électroniques qui peuvent avoir lieu entre les niveaux d’énergie d’un atome sous l’effet d’un rayonnement incident :

  • Absorption : Correspond à un gain d’énergie (du point de vue de l’atome).
  • Émission : Correspond à une perte d’énergie (du point de vue de l’atome).
  • Ionisation : Correspond à un gain d’énergie supérieur au seuil d’ionisation ce qui a pour effet d’ioniser l’atome, c’est à dire, d’extraire un de ses électrons.

Transitions électroniques

Fichier source : transitions.tex

Fichier pdf : transitions.pdf

Expérience de Franck et Hertz

Cette expérience a été réalisée pour la première fois en 1914 par deux physiciens allemand : Gustav Hertz et James Franck, d’où son nom. Le but était de comprendre l’interaction entre un faisceau d’électrons et un gaz atomique (du mercure gazeux). Franck et Hertz ont pu déduire de leurs résultats que les échanges d’énergie au niveau microscopique sont quantifiés, c’est à dire que la quantité d’énergie échangée ne peut prendre que certaines valeurs particulières. Ils reçurent le prix nobel de physique en 1925 pour leur découverte des lois régissant la collision d’un électron sur un atome.

Schéma de l'expérience de Franck et Hertz

Fichier source : FranckHertz.tex

Fichier pdf : FranckHertz.pdf

Règle de Klechkowski

Pour un atome polyélectronique, dans le cadre du modèle à particules indépendantes, chaque électron est décrit par une orbitale atomique (fonction d’onde monoélectronique solution de l’équation de Schrodinger pour un électron). La fonction d’onde électronique totale, décrivant l’ensemble des électrons de l’atome, est donnée par le produit des fonctions d’onde monoélectroniques.

La règle de Klechkowski donne l’ordre d’attribution des orbitales atomique permettant d’obtenir la fonction d’onde de l’état fondamental de l’atome. Il s’agit d’une règle empirique qui donne l’ordre croissant des énergies des orbitales atomiques. Le schéma ci-dessous permet de retrouver l’ordre énergétique des orbitales atomique.

1s < 2s < 2p < 3s < 3p < 4s < 3s ... Schéma permettant de retrouver la règle de Klechkowski

Fichier source : Klechkowski.tex

Fichier pdf : Klechkowski.pdf

Séries de l’atome d’hydrogène

Les raies d’émission de l’atome d’hydrogène sont regroupées en séries. Cette figure représente les trois premières séries : celle de Lyman, de Balmer et de Pashen. Une série correspond à l’ensemble des raies d’émission qui ont en commun le niveau d’énergie final de l’atome d’hydrogène.

Séries du spectre d'émission de l'atome d'hydrogène

Fichier source : series_atome_H.tex

Fichier pdf : series_atome_H.pdf