-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
234 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |