{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Calculate magnetic parameters" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "grogupy is specifically written in a modular way, to fully take advantage of python classes. In this simple example we show how to use grogupy to simulate the magnetic interaction between two atoms from a density functional theory (DFT) calculation and create an output file for [magnopy](https://docs.magnopy.org/en/latest/user-guide/start/about.html). In this example we will use a non-collinear Siesta calculation of the CrI3 system with spin-orbit coupling." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First import grogupy, which will import the most important classes, functions and variables in its namespace." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/danielpozsar/Documents/Documents_MacBook Air/studies/elte/phd/grogu/.venv/lib/python3.13/site-packages/grogupy/_tqdm.py:41: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from tqdm.autonotebook import tqdm\n" ] } ], "source": [ "import grogupy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we start to create the basic classes based on the desired parameters. First create the ``Kspace`` class which contains the parameters fot the Brillouin zone integration. Because in this case we only take a single layer of CrI3 and there is a large vacuum in the perpendicular direction it is sufficient to only integrate in the plane of the material. Furthermore for a fast initial calculation a 10x10 grid of k-points should be enough, but this is not fully converged." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "CrI3_kspace = grogupy.Kspace(kset=[10, 10, 1])\n", "CrI3_kspace" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we would like to set the parameters for the complex integral for the Green's function calculation. This can be done through the ``Contour`` class. Because CrI3 is an insulator 50 sample points should be enough. The energy minimum should be set below the smallest eigenvalue from the Siesta Hamiltonian.\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "CrI3_contour = grogupy.Contour(emin=-30, eset=50, esetp=100)\n", "CrI3_contour" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we can create the ``Hamiltonian`` class, which extracts and stores the Hamiltonian and geometrical data from the Siesta files using the ``sisl`` library. Furthermore we must provide the exchange field orientation in the DFT calculation, which is usually the perpendicular direction from the 2D material.\n" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Setting up Hamiltonian: 100%|██████████| 147/147 [00:00<00:00, 618.10it/s]\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "CrI3_hamiltonian = grogupy.Hamiltonian(\n", " infile=\"./../../../benchmarks/CrI3/CrI3.fdf\",\n", " scf_xcf_orientation=[0, 0, 1],\n", ")\n", "CrI3_hamiltonian" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After these initial steps we can create the ``Builder`` class and initialize with the above information. We have to provide the directions of the rotated exchange field and the two perpendicular directions are calculated automatically.\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "orientations = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]\n", "\n", "CrI3 = grogupy.Builder(ref_xcf_orientations=orientations)\n", "CrI3.add_kspace(CrI3_kspace)\n", "CrI3.add_contour(CrI3_contour)\n", "CrI3.add_hamiltonian(CrI3_hamiltonian)\n", "CrI3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we have to define the magnetic entities, which can be a list of orbitals from the Siesta Hamiltonian. We use ``sisl`` functions to extract this information based on a more human like definition. For example take two shells from two Cr atoms.\n" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "magnetic_entities = [dict(atom=0, l=2), dict(atom=1, l=2)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With this information we can create two ``MagneticEntity`` instances.\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Add magnetic entities: 100%|██████████| 2/2 [00:00<00:00, 95.47it/s]\n" ] } ], "source": [ "CrI3.add_magnetic_entities(magnetic_entities)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This would be enough to calculate the anisotropy on both sites, but it is not enough to build a spin model, for this we need the exchange tensor between all the pairs. Generally this can be done in a similar way. First a list of dictionaries must be created, where each dictionary contains ``ai``, ``aj`` and ``Ruc``, where the first two is the index from the magnetic_entities and the third is the supercell shift of the second magnetic entity.\n" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Add pairs: 100%|██████████| 2/2 [00:00<00:00, 4857.33it/s]\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pairs = [\n", " dict(ai=0, aj=1, Ruc=[0, 0, 0]),\n", " dict(ai=0, aj=1, Ruc=[1, 0, 0]),\n", "]\n", "CrI3.add_pairs(pairs)\n", "CrI3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now every information is contained in the ``CrI3`` instance to run the simulation. There are multiple parameters that can be changed to tune the runtime and the precision of the simulation, but for now let us use the default parameters." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Extracting exchange field: 100%|██████████| 101/101 [00:00<00:00, 646.84it/s]\n", "Rotating Exchange field: 100%|██████████| 3/3 [00:00<00:00, 78.04it/s]\n", "Rotation 1: 100%|██████████| 100/100 [00:08<00:00, 12.04it/s]\n", "Extracting exchange field: 100%|██████████| 101/101 [00:00<00:00, 599.39it/s]\n", "Setup perturbations for rotated hamiltonian: 100%|██████████| 2/2 [00:00<00:00, 7936.24it/s]\n", "Extracting exchange field: 100%|██████████| 101/101 [00:00<00:00, 1261.91it/s]\n", "Setup perturbations for rotated hamiltonian: 100%|██████████| 2/2 [00:00<00:00, 6311.97it/s]\n", "Extracting exchange field: 100%|██████████| 101/101 [00:00<00:00, 1386.36it/s]\n", "Setup perturbations for rotated hamiltonian: 100%|██████████| 2/2 [00:00<00:00, 10754.63it/s]\n", "Extracting exchange field: 100%|██████████| 101/101 [00:00<00:00, 871.12it/s]\n", "Rotating Exchange field: 100%|██████████| 3/3 [00:00<00:00, 92.28it/s]\n", "Rotation 2: 100%|██████████| 100/100 [00:07<00:00, 12.63it/s]\n", "Extracting exchange field: 100%|██████████| 101/101 [00:00<00:00, 505.36it/s]\n", "Setup perturbations for rotated hamiltonian: 100%|██████████| 2/2 [00:00<00:00, 4396.55it/s]\n", "Extracting exchange field: 100%|██████████| 101/101 [00:00<00:00, 995.65it/s]\n", "Setup perturbations for rotated hamiltonian: 100%|██████████| 2/2 [00:00<00:00, 6875.91it/s]\n", "Extracting exchange field: 100%|██████████| 101/101 [00:00<00:00, 1169.20it/s]\n", "Setup perturbations for rotated hamiltonian: 100%|██████████| 2/2 [00:00<00:00, 357.51it/s]\n", "Rotation 3: 100%|██████████| 100/100 [00:07<00:00, 13.30it/s]\n", "Extracting exchange field: 100%|██████████| 101/101 [00:00<00:00, 815.44it/s]\n", "Setup perturbations for rotated hamiltonian: 100%|██████████| 2/2 [00:00<00:00, 6927.01it/s]\n", "Extracting exchange field: 100%|██████████| 101/101 [00:00<00:00, 892.97it/s]\n", "Setup perturbations for rotated hamiltonian: 100%|██████████| 2/2 [00:00<00:00, 5194.18it/s]\n", "Extracting exchange field: 100%|██████████| 101/101 [00:00<00:00, 1119.77it/s]\n", "Setup perturbations for rotated hamiltonian: 100%|██████████| 2/2 [00:00<00:00, 7430.12it/s]\n" ] } ], "source": [ "CrI3.solve()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now the instance parameters are filled with the calculated exchane and on-site anisotropy parameters. We can print the instance ``CrI3`` to get the information of the simulation and use the ``grogupy.save_magnopy()`` function to return the results in ``magnopy``'s input format.\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--------------------------------------------------------------------------------\n", "Metadata\n", "grogupy version:\t0.3.1\n", "Architecture:\t\tCPU\n", "SLURM job ID:\t\tCould not be determined.\n", "Input file:\t\t/Users/danielpozsar/Documents/Documents_MacBook Air/studies/elte/phd/grogu/benchmarks/CrI3/CrI3.fdf\n", "--------------------------------------------------------------------------------\n", "Hamiltonian\n", "Spin model:\t\tgeneralised-grogu\n", "Spin mode:\t\tSPIN-ORBIT\n", "Number of orbitals:\t216\n", "Unique ID:\t8252670334522874585\t3429370498709139588\n", "--------------------------------------------------------------------------------\n", "Solver\n", "Number of threads in the parallel cluster:\t\t1\n", "Parallelization is over:\t\t\t\tNo parallelization\n", "Solver used for Greens function calculation:\t\tparallel\n", "Maximum number of Greens function samples per batch:\t50\n", "Low memory mode:\t\t\t\t\tFalse\n", "--------------------------------------------------------------------------------\n", "Cell [Ang]\n", "\t7.00000000e+00\t0.00000000e+00\t0.00000000e+00\n", "\t-3.50000000e+00\t6.06217782e+00\t0.00000000e+00\n", "\t0.00000000e+00\t0.00000000e+00\t3.00000000e+01\n", "--------------------------------------------------------------------------------\n", "Exchange field rotations\n", "DFT axis:\t[0. 0. 1.]\n", "Quantization axis and perpendicular directions:\n", "1.00000000e+00\t0.00000000e+00\t0.00000000e+00 -->\n", "\t0.00000000e+00\t0.00000000e+00\t-1.00000000e+00\n", "\t0.00000000e+00\t1.00000000e+00\t0.00000000e+00\n", "\t0.00000000e+00\t7.07106781e-01\t-7.07106781e-01\n", "0.00000000e+00\t1.00000000e+00\t0.00000000e+00 -->\n", "\t1.00000000e+00\t0.00000000e+00\t0.00000000e+00\n", "\t0.00000000e+00\t0.00000000e+00\t-1.00000000e+00\n", "\t7.07106781e-01\t0.00000000e+00\t-7.07106781e-01\n", "0.00000000e+00\t0.00000000e+00\t1.00000000e+00 -->\n", "\t1.00000000e+00\t0.00000000e+00\t0.00000000e+00\n", "\t0.00000000e+00\t1.00000000e+00\t0.00000000e+00\n", "\t7.07106781e-01\t7.07106781e-01\t0.00000000e+00\n", "--------------------------------------------------------------------------------\n", "Kspace\n", "Total number of k points:\t100\n", "K points in each directions:\t[10 10 1]\n", "--------------------------------------------------------------------------------\n", "Contour\n", "Eset:\t50\n", "Esetp:\t100\n", "Ebot:\t-35\n", "Etop:\t0\n", "--------------------------------------------------------------------------------\n", "\n" ] } ], "source": [ "print(CrI3)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "================================================================================\n", "GROGU INFORMATION\n", "================================================================================\n", "Hamiltonian convention\n", "Double counting true\n", "Normalized spins true\n", "Intra-atomic factor +1\n", "Exchange factor +0.5\n", "================================================================================\n", "Cell (Ang)\n", "7.00000000\t0.00000000\t0.00000000\n", "-3.50000000\t6.06217782\t0.00000000\n", "0.00000000\t0.00000000\t30.00000000\n", "================================================================================\n", "Magnetic sites\n", "Number of sites 2\n", "Name\t\tx (Ang)\t\ty (Ang)\t\tz (Ang)\t\ts\t\t\tsx\t\t\tsy\t\t\tsz\n", "0Cr(l:2)\t-0.00005220\t0.00003006\t15.00000000\t1.74787087\t0.00002581\t0.02469071\t0.99969514\n", "1Cr(l:2)\t3.50005256\t2.02069554\t14.99999997\t1.74787735\t0.00002145\t-0.02470149\t0.99969487\n", "================================================================================\n", "Intra-atomic anisotropy tensor (meV)\n", "--------------------------------------------------------------------------------\n", "0Cr(l:2)\n", "Matrix\n", "\t0.42677015\t-0.04533856\t-0.05362904\n", "\t-0.04533856\t0.51904088\t-0.06215431\n", "\t-0.05362904\t-0.06215431\t0.00000000\n", "--------------------------------------------------------------------------------\n", "1Cr(l:2)\n", "Matrix\n", "\t0.41333470\t0.04549295\t-0.04741143\n", "\t0.04549295\t0.51906709\t0.06198310\n", "\t-0.04741143\t0.06198310\t0.00000000\n", "--------------------------------------------------------------------------------\n", "================================================================================\n", "Exchange tensor (meV)\n", "Number of pairs 2\n", "--------------------------------------------------------------------------------\n", "Name1\t\tName2\t\ti\tj\tk\td (Ang)\n", "--------------------------------------------------------------------------------\n", "0Cr(l:2)\t1Cr(l:2)\t0\t0\t0\t4.041512368971766\n", "Matrix\n", "\t-1.82204027\t-0.28722064\t-0.31246363\n", "\t-0.72951690\t-1.26385375\t0.29209800\n", "\t-0.21129252\t0.51775736\t-1.66394270\n", "--------------------------------------------------------------------------------\n", "0Cr(l:2)\t1Cr(l:2)\t1\t0\t0\t10.69276805834447\n", "Matrix\n", "\t-0.02851866\t-0.00233102\t0.00177980\n", "\t0.00205790\t-0.02548159\t0.00216193\n", "\t-0.00146106\t-0.00290484\t-0.02175032\n", "--------------------------------------------------------------------------------\n", "================================================================================\n", "\n" ] } ], "source": [ "print(grogupy.save_magnopy(CrI3, comments=False))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "More information can be found in the Tutorials." ] } ], "metadata": { "kernelspec": { "display_name": ".venv (3.13.8)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.8" } }, "nbformat": 4, "nbformat_minor": 2 }