.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "master-tutorial/3_exercises/plot_6_energy.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_master-tutorial_3_exercises_plot_6_energy.py: Classical Energy **************** .. include:: ../../exercises/6.inc .. GENERATED FROM PYTHON SOURCE LINES 7-12 .. code-block:: Python import numpy as np import magnopy import matplotlib.pyplot as plt .. GENERATED FROM PYTHON SOURCE LINES 13-15 Exercise 1 ========== .. GENERATED FROM PYTHON SOURCE LINES 16-21 .. code-block:: Python spinham = magnopy.examples.cubic_ferro_nn(S=1, J_iso=1) print(magnopy.Energy(spinham)([[0, 0, 1]])) .. rst-class:: sphx-glr-script-out .. code-block:: none -3.0 .. GENERATED FROM PYTHON SOURCE LINES 22-24 Exercise 2 ========== .. GENERATED FROM PYTHON SOURCE LINES 25-34 .. code-block:: Python print(spinham.convention) spinham.convention = spinham.convention.get_modified(c22=0.3333) print(spinham.convention) print(magnopy.Energy(spinham)([[0, 0, 1]])) .. rst-class:: sphx-glr-script-out .. code-block:: none "custom" convention where * Bonds are counted multiple times in the sum; * Spin vectors are not normalized; * Undefined c1 factor; * c21 = 1.0; * c22 = 0.5; * Undefined c31 factor; * Undefined c32 factor; * Undefined c33 factor; * Undefined c41 factor; * Undefined c421 factor; * Undefined c422 factor; * Undefined c43 factor; * Undefined c44 factor. "custom" convention where * Bonds are counted multiple times in the sum; * Spin vectors are not normalized; * Undefined c1 factor; * c21 = 1.0; * c22 = 0.3333; * Undefined c31 factor; * Undefined c32 factor; * Undefined c33 factor; * Undefined c41 factor; * Undefined c421 factor; * Undefined c422 factor; * Undefined c43 factor; * Undefined c44 factor. -3.0 .. GENERATED FROM PYTHON SOURCE LINES 35-39 No, energy, being a physical property, does not depend on Hamiltonians convention. Exercise 3 ========== .. GENERATED FROM PYTHON SOURCE LINES 40-94 .. code-block:: Python # Orthorhombic cell with a = 1, b=1.5, c=2 cell = np.diag([1, 1.5, 2]) # One atom per unit cell atoms = dict( names=["Fe"], positions=[[0.0, 0.0, 0.0]], spins=[2.5], g_factors=[2], ) # Convention convention = magnopy.Convention( multiple_counting=True, spin_normalized=False, c21=1, c22=1 / 2 ) # Create three terms iso_term = magnopy.SpinHamiltonian(cell=cell, atoms=atoms, convention=convention) aniso_term = iso_term.get_empty() dmi_term = iso_term.get_empty() # Add nearest neighbor isotropic exchange for nu in [(1, 0, 0), (0, 1, 0), (0, 0, 1)]: iso_term.add_22( alpha=0, beta=0, nu=nu, parameter=magnopy.converter22.from_iso(iso=-1) ) # Add triaxial anisotropy aniso_term.add_21(alpha=0, parameter=np.diag([-0.1, -0.3, -0.2])) # Add DMI to one of the nearest neighbors dmi_term.add_22( alpha=0, beta=0, nu=(0, 1, 0), parameter=magnopy.converter22.from_dmi(dmi=(0.5, 0, 0)), ) # Get an energy instance for the full Hamiltonian energy_full = magnopy.Energy(iso_term + aniso_term + dmi_term) # Get optimized spin directions optimized_sd = energy_full.optimize() print(f"Optimized spin directions are\n{optimized_sd}") # Print energy contributions print(f"Total energy is {energy_full(optimized_sd):.4f} meV") print(f"Isotropic contribution is {magnopy.Energy(iso_term)(optimized_sd):.4f} meV") print(f"Anisotropic contribution is {magnopy.Energy(aniso_term)(optimized_sd):.4f} meV") print(f"DMI contribution is {magnopy.Energy(dmi_term)(optimized_sd):.4f} meV") .. rst-class:: sphx-glr-script-out .. code-block:: none ─────┬─────────────┬─────────────┬───────────── step │ E_0 │ delta E_0 │ max torque ─────┴─────────────┴─────────────┴───────────── 1 -20.6106991 0.1218815 0.1976675 2 -20.6236014 0.0129023 0.0665848 3 -20.6249387 0.0013373 0.0160851 4 -20.6250000 0.0000613 0.0003449 5 -20.6250000 0.0000000 0.0000089 ─────────────────────────────────────────────── Optimized spin directions are [[-2.50504806e-06 -1.00000000e+00 -5.10432729e-06]] Total energy is -20.6250 meV Isotropic contribution is -18.7500 meV Anisotropic contribution is -1.8750 meV DMI contribution is 0.0000 meV .. GENERATED FROM PYTHON SOURCE LINES 95-100 Exercise 4 ========== .. hint:: Magnetic field tends to orient magnetic moment along itself, but the spin along the opposite direction. .. GENERATED FROM PYTHON SOURCE LINES 101-138 .. code-block:: Python # Create a Hamiltonian # Parameters are in meV by default spinham = magnopy.examples.cubic_ferro_nn(S=3 / 2, J_iso=1, J_21=np.diag([0, 0, -0.04])) # Create a Zeeman term with the small magnetic field step value of (-0.02, 0, 0) Tesla zeeman_step = spinham.get_empty() print(f"Number of atoms: {len(zeeman_step.atoms.names)} -> {zeeman_step.atoms.names}") B_step = -0.02 zeeman_step.add_magnetic_field(B=(B_step, 0, 0), alphas=[0]) energy = magnopy.Energy(spinham) # Lists for saving the intermediate steps energies_along_z = [energy([[0, 0, 1]])] energies_along_x = [energy([[1, 0, 0]])] optimized_sds = [energy.optimize(quiet=True)] energies_optimized = [energy(optimized_sds[-1])] steps = 0 # Avoid using S^x == 1, due to the numerical noise while abs(optimized_sds[-1][0][0]) < 0.9999: # Increase magnetic field spinham = spinham + zeeman_step steps += 1 # Update energy energy = magnopy.Energy(spinham) # Save info about the step energies_along_z.append(energy([[0, 0, 1]])) energies_along_x.append(energy([[1, 0, 0]])) optimized_sds.append(energy.optimize(quiet=True)) energies_optimized.append(energy(optimized_sds[-1])) print(f"({B_step * steps:.4f}, 0.0, 0.0) Tesla is enough.") .. rst-class:: sphx-glr-script-out .. code-block:: none Number of atoms: 1 -> ['X'] (-1.0400, 0.0, 0.0) Tesla is enough. .. GENERATED FROM PYTHON SOURCE LINES 139-145 Plot the results as well .. hint:: We display absolute values of spin components as +z and -z are degenerate in the model and optimized directions will oscillate is raw value is plotted. .. GENERATED FROM PYTHON SOURCE LINES 146-185 .. code-block:: Python B_x = np.abs([_ * B_step for _ in range(steps + 1)]) optimized_sds = np.array(optimized_sds) fig, ax = plt.subplots() # Plot energies ax.plot(B_x, energies_along_x, label="E (S || x)", lw=3, color="#FFB956") ax.plot(B_x, energies_along_z, label="E (S || z)", lw=3, color="#53EBFF") ax.plot(B_x, energies_optimized, label="E (optimized)", lw=3, color="#000000") ax.set_xlabel(R"$|B^x|$ (Tesla)", fontsize=15) ax.set_ylabel(R"Energy (meV)", fontsize=15) ax.set_xlim(B_x[0], B_x[-1]) ax.legend(frameon=False, loc="upper left") # Plot optimized spin directions twinax = ax.twinx() twinax.plot( B_x, np.abs(optimized_sds[:, 0, 0]), label=R"$|S^x|$", lw=1, color="#FF5656" ) twinax.plot( B_x, np.abs(optimized_sds[:, 0, 1]), label=R"$|S^y|$", lw=1, color="#67FF56" ) twinax.plot( B_x, np.abs(optimized_sds[:, 0, 2]), label=R"$|S^z|$", lw=1, color="#5659FF" ) twinax.set_ylabel(R"Optimized spin direction", fontsize=15) twinax.set_ylim(0, 1) twinax.legend(frameon=False, loc="lower center") fig.tight_layout() fig.show() .. image-sg:: /master-tutorial/3_exercises/images/sphx_glr_plot_6_energy_001.png :alt: plot 6 energy :srcset: /master-tutorial/3_exercises/images/sphx_glr_plot_6_energy_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.263 seconds) .. _sphx_glr_download_master-tutorial_3_exercises_plot_6_energy.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_6_energy.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_6_energy.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_6_energy.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_