Skip to content

Commit

Permalink
'hf done'
Browse files Browse the repository at this point in the history
  • Loading branch information
DPotoyan authored Dec 11, 2024
1 parent 20ab295 commit c89cae8
Show file tree
Hide file tree
Showing 5 changed files with 234 additions and 0 deletions.
1 change: 1 addition & 0 deletions _toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ parts:
- file: ch07/note01
- file: ch07/note02
- file: ch07/note03
- file: ch07/note04
- file: ch08/index
sections:
- file: ch08/note01
Expand Down
Binary file added ch07/images/HF1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ch07/images/HF2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ch07/images/cat5.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
233 changes: 233 additions & 0 deletions ch07/note04.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Hartree-Fock"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **1. Introduction**\n",
"\n",
"- **Objective**: Approximate the electronic structure of atoms and molecules by treating electrons as independent particles in an average field created by all other electrons.\n",
"- **Motivation**: The Schrödinger equation for multi-electron systems is too complex to solve exactly.\n",
"\n",
"## **2. Key Concepts**\n",
"\n",
"### **Wavefunction**\n",
"- The total wavefunction $\\Psi(1, 2, \\cdots, N)$ is approximated as a single Slater determinant to satisfy the Pauli exclusion principle.\n",
" $$ \\Psi(1, 2, \\cdots, N) = \\frac{1}{\\sqrt{N!}} \\begin{vmatrix} \\psi_1(1) & \\psi_2(1) & \\cdots & \\psi_N(1) \\\\ \\psi_1(2) & \\psi_2(2) & \\cdots & \\psi_N(2) \\\\ \\vdots & \\vdots & \\ddots & \\vdots \\\\ \\psi_1(N) & \\psi_2(N) & \\cdots & \\psi_N(N) \\end{vmatrix} $$\n",
"\n",
"### **Hartree-Fock Equations**\n",
"- Each molecular orbital (MO) $\\psi_i$ satisfies the self-consistent field (SCF) equation:\n",
" $$ \\hat{F} \\psi_i = \\varepsilon_i \\psi_i $$\n",
" where $\\hat{F}$ is the **Fock operator** and $\\varepsilon_i$ are the orbital energies.\n",
"\n",
"### **Fock Operator**\n",
"- The Fock operator $\\hat{F}$ is a sum of the one-electron Hamiltonian and a mean-field potential:\n",
" $$ \\hat{F} = \\hat{h} + \\sum_{j} \\left( \\hat{J}_j - \\hat{K}_j \\right) $$\n",
" - $\\hat{h}$: Kinetic energy and nuclear attraction operators.\n",
" - $\\hat{J}_j$: Coulomb operator (electron-electron repulsion).\n",
" - $\\hat{K}_j$: Exchange operator (arises from antisymmetry requirement of the wavefunction).\n",
"\n",
"### **Self-Consistent Field (SCF) Method**\n",
"1. **Guess** initial molecular orbitals $\\psi_i$.\n",
"2. **Construct** the Fock operator $\\hat{F}$ using the current $\\psi_i$.\n",
"3. **Solve** the Hartree-Fock equation $\\hat{F} \\psi_i = \\varepsilon_i \\psi_i$ to obtain new orbitals $\\psi_i$.\n",
"4. **Repeat** steps 2-3 until convergence (orbitals do not change significantly).\n",
"\n",
"\n",
"\n",
"\n",
"## **3. Total Energy of the System**\n",
"- Total electronic energy $E_{HF}$ in the Hartree-Fock approximation:\n",
" $$ E_{HF} = \\sum_{i} \\langle \\psi_i | \\hat{h} | \\psi_i \\rangle + \\frac{1}{2} \\sum_{i,j} \\left( J_{ij} - K_{ij} \\right) $$\n",
" - $J_{ij}$: Coulomb integral.\n",
" - $K_{ij}$: Exchange integral.\n",
"\n",
"\n",
"\n",
"\n",
"## **4. Strengths and Limitations**\n",
"\n",
"### **Strengths**\n",
"- **Efficient**: Reduces the complexity of the multi-electron Schrödinger equation.\n",
"- **Exchange interactions**: Includes effects of exchange through the Slater determinant.\n",
"\n",
"### **Limitations**\n",
"- **No dynamic correlation**: Electron-electron correlation is only partially captured.\n",
"- **Post-Hartree-Fock methods**: Needed for more accurate energy calculations (e.g., MP2, CCSD).\n",
"\n",
"\n",
"\n",
"\n",
"## **5. Summary**\n",
"- Hartree-Fock approximates the multi-electron wavefunction as a Slater determinant.\n",
"- The Fock operator accounts for one-electron and mean-field electron-electron interactions.\n",
"- The SCF procedure ensures convergence to a consistent set of orbitals.\n",
"- While efficient, it lacks dynamic correlation, motivating the development of post-Hartree-Fock methods.\n",
"\n",
"**Important Equations**\n",
"1. **Slater Determinant**:\n",
"\n",
" $$ \\Psi(1, 2, \\cdots, N) = \\frac{1}{\\sqrt{N!}} \\begin{vmatrix} \\psi_1(1) & \\psi_2(1) & \\cdots & \\psi_N(1) \\\\ \\psi_1(2) & \\psi_2(2) & \\cdots & \\psi_N(2) \\\\ \\vdots & \\vdots & \\ddots & \\vdots \\\\ \\psi_1(N) & \\psi_2(N) & \\cdots & \\psi_N(N) \\end{vmatrix} $$\n",
"\n",
"2. **Hartree-Fock Equations**:\n",
"\n",
" $$ \\hat{F} \\psi_i = \\varepsilon_i \\psi_i $$\n",
"\n",
"3. **Fock Operator**:\n",
"\n",
" $$ \\hat{F} = \\hat{h} + \\sum_{j} \\left( \\hat{J}_j - \\hat{K}_j \\right) $$\n",
"\n",
"4. **Electronic Energy**:\n",
"\n",
" $$ E_{HF} = \\sum_{i} \\langle \\psi_i | \\hat{h} | \\psi_i \\rangle + \\frac{1}{2} \\sum_{i,j} \\left( J_{ij} - K_{ij} \\right) $$\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![](./images/HF1.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Practical use of HF "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* We need to install a few things before we get started\n",
" * [PySCF](https://pyscf.org/) (for the quantum chemistry)\n",
" * [py3DMol](https://3dmol.csb.pitt.edu/) for visualizing the molecule\n",
" * [plotly](https://plotly.com/python/) and kaleido for plotting"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%pip install -q pyscf py3DMol plotly kaleido"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#@title PYSCF code to calcualte energies of Alkali Metals\n",
"\n",
"from pyscf import gto, scf\n",
"\n",
"# Function to calculate orbitals and energies for a given atom\n",
"def calculate_orbitals_energies(atom_symbol):\n",
" \"\"\"\n",
" Calculate the orbitals and energies for a given atom using PySCF.\n",
" \n",
" Parameters:\n",
" atom_symbol (str): Symbol of the atom (e.g., 'He', 'Li').\n",
" \n",
" Returns:\n",
" dict: A dictionary containing the total energy, MO coefficients, and MO energies.\n",
" \"\"\"\n",
" # Define the atom and basis set\n",
" mol = gto.Mole()\n",
" mol.atom = [(atom_symbol, (0, 0, 0))] # Specify the atom and its position\n",
" mol.basis = 'sto-3g' # Basis set\n",
" \n",
" \n",
" mol.spin = 1 # 2S = 1, since Li, Na, K has 1 unpaired electron\n",
" \n",
" mol.build()\n",
" \n",
" # Perform Hartree-Fock calculation\n",
" mf = scf.RHF(mol) # Restricted Hartree-Fock\n",
" total_energy = mf.kernel() # Calculate the total electronic energy\n",
" \n",
" # Extract molecular orbital coefficients and energies\n",
" mo_coefficients = mf.mo_coeff # MO coefficients\n",
" mo_energies = mf.mo_energy # MO energies\n",
"\n",
" # Determine the HOMO (highest occupied molecular orbital) energy\n",
" num_electrons = mol.nelectron # Total number of electrons in the system\n",
" homo_index = num_electrons // 2 - 1 # HOMO index for closed-shell systems (0-indexed)\n",
" homo_energy = mo_energies[homo_index] if homo_index >= 0 else None\n",
"\n",
" # Generate the cube file for the HOMO\n",
" if homo_index >= 0:\n",
" cube_filename = f\"{atom_symbol}_HOMO.cube\"\n",
" cubegen.orbital(mol, cube_filename, mf.mo_coeff[:, homo_index])\n",
" print(f\"HOMO cube file saved as: {cube_filename}\")\n",
" \n",
" # Visualize the cube file using py3Dmol\n",
" cube_view = py3Dmol.view(width=400, height=400)\n",
" with open(cube_filename, 'r') as file:\n",
" cube_data = file.read()\n",
" cube_view.addVolumetricData(cube_data, \"cube\", {'isoval': -0.03, 'color': \"red\", 'opacity': 0.85})\n",
" cube_view.addVolumetricData(cube_data, \"cube\", {'isoval': 0.03, 'color': \"blue\", 'opacity': 0.85})\n",
" cube_view.addModel(mol.tostring(format=\"xyz\"), 'xyz')\n",
" cube_view.setStyle({'stick': {}, \"sphere\": {\"radius\": 0.4}})\n",
" cube_view.setBackgroundColor('0xeeeeee')\n",
" cube_view.show()\n",
" \n",
" results = {\n",
" 'atom': atom_symbol,\n",
" 'total_energy': total_energy,\n",
" 'mo_coefficients': mo_coefficients,\n",
" 'mo_energies': mo_energies,\n",
" 'homo_energy': homo_energy\n",
" }\n",
" \n",
" return results"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# List of atoms to calculate\n",
"atoms = ['Li', 'Na']\n",
"\n",
"# Store the results for each atom\n",
"results_dict = {}\n",
"\n",
"# Loop over each atom and calculate orbitals and energies\n",
"for atom in atoms:\n",
" results = calculate_orbitals_energies(atom)\n",
" results_dict[atom] = results\n",
" \n",
" print(f\"Results for {atom} atom:\")\n",
" print(\"Total Energy (Hartree):\", results['total_energy'])\n",
" print(\"Molecular Orbital Energies (Hartree):\", results['mo_energies'])\n",
" print(\"HOMO energy (Hartree):\", results['homo_energy'])\n",
" #print(\"Molecular Orbital Coefficients:\")\n",
" #print(results['mo_coefficients'])\n",
" #print(\"\\n\" + \"-\"*50 + \"\\n\")\n",
" print(\"\\n\")"
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit c89cae8

Please sign in to comment.