From 38a3be0558f770506e6ae0e7166e7462f3cefa22 Mon Sep 17 00:00:00 2001 From: Daniel Pozsar Date: Sat, 9 Nov 2024 13:31:32 +0100 Subject: [PATCH] working on documentation --- .readthedocs.yaml | 4 +- docs/_build/doctrees/environment.pickle | Bin 29369 -> 124354 bytes docs/_build/doctrees/grogupy.doctree | Bin 0 -> 134083 bytes .../doctrees/implementation/index.doctree | Bin 2496 -> 6981 bytes docs/_build/doctrees/index.doctree | Bin 9502 -> 11227 bytes docs/_build/doctrees/modules.doctree | Bin 0 -> 2783 bytes docs/_build/html/_modules/grogupy/core.html | 525 +++++++++++ docs/_build/html/_modules/grogupy/grogu.html | 587 +++++++++++++ docs/_build/html/_modules/grogupy/io.html | 456 ++++++++++ .../html/_modules/grogupy/magnetism.html | 348 ++++++++ .../html/_modules/grogupy/utilities.html | 457 ++++++++++ docs/_build/html/_modules/index.html | 127 +++ docs/_build/html/_sources/grogupy.rst.txt | 53 ++ .../_sources/implementation/index.rst.txt | 11 +- docs/_build/html/_sources/index.rst.txt | 10 +- docs/_build/html/_sources/modules.rst.txt | 7 + docs/_build/html/environment.html | 4 +- docs/_build/html/genindex.html | 236 ++++- docs/_build/html/grogupy.html | 822 ++++++++++++++++++ docs/_build/html/implementation/index.html | 28 +- docs/_build/html/index.html | 8 + docs/_build/html/modules.html | 179 ++++ docs/_build/html/objects.inv | Bin 592 -> 1171 bytes docs/_build/html/py-modindex.html | 70 +- docs/_build/html/searchindex.js | 2 +- docs/conf.py | 11 +- docs/grogupy.rst | 53 ++ docs/implementation/index.rst | 11 +- docs/index.rst | 10 +- docs/modules.rst | 7 + docs/requirements.txt | 1 + 31 files changed, 4004 insertions(+), 23 deletions(-) create mode 100644 docs/_build/doctrees/grogupy.doctree create mode 100644 docs/_build/doctrees/modules.doctree create mode 100644 docs/_build/html/_modules/grogupy/core.html create mode 100644 docs/_build/html/_modules/grogupy/grogu.html create mode 100644 docs/_build/html/_modules/grogupy/io.html create mode 100644 docs/_build/html/_modules/grogupy/magnetism.html create mode 100644 docs/_build/html/_modules/grogupy/utilities.html create mode 100644 docs/_build/html/_modules/index.html create mode 100644 docs/_build/html/_sources/grogupy.rst.txt create mode 100644 docs/_build/html/_sources/modules.rst.txt create mode 100644 docs/_build/html/grogupy.html create mode 100644 docs/_build/html/modules.html create mode 100644 docs/grogupy.rst create mode 100644 docs/modules.rst diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 49c98f6..0f9c92a 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -24,8 +24,8 @@ sphinx: fail_on_warning: true # Optionally build your docs in additional formats such as PDF and ePub - formats: - - pdf +# formats: +# - pdf # - epub # Optional but recommended, declare the Python requirements required diff --git a/docs/_build/doctrees/environment.pickle b/docs/_build/doctrees/environment.pickle index 5717b2490d28ec252c191213f5b11a8e625b7800..12a06481576076a52b4349ab9cfdbab4e2391f61 100644 GIT binary patch literal 124354 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

oqBU>Wm#RU`&g$& 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 literal 29369 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 LuBZt4W%l5|7OGTp delta 81 zcmX?Vc0ic5fpzLu&WWr=8!PM>851`f31=~K^suJpl@wJ@**s6gjgcuMe)CJwd(5&K kMj86WJ)C)oxv3?U1*yeTYNuovbrxqR0%`rtA0$H=0iEF;@c;k- diff --git a/docs/_build/doctrees/index.doctree b/docs/_build/doctrees/index.doctree index 92bf0e873938ef7cb70d0982eafefd9979272c2a..65d681445df20b9bd81c2a3bfa93a7382e504fc7 100644 GIT binary patch delta 1283 zcmb7^TWb?R6vvaSxe;S%YP^uxTpA%Y28u62K=e^7h?j>xg*M5KnG8vk>@KFD)FKrN z^VFRRTC5=WY&Bm%KY>>);)8;I0N;G|oZZZB+CX8FSMGPE=(Z<$_&Chj5`ZWowSFxd92(e z*UO6y(rI>7(p$8X>B;Nt3C4o_Sj_A3%$yz6<+>B--s^>8LQ+wu`m z$+8zps|y}=DP;2uO*0Ln)P z5n69Y5uy8Uh@y5oX{6e%(~)LUlyQI@?=C>n3xEPz+|nDu6H)#jPe^eZDFKO$!82{+ z3E1gdO*qs)SD|h{YFPb)mKUw;k>UP9w}fMU52XkX*bh^1?+Hs$V3)YfCLgm=BQ%CX zW1=E>92yL#Lx>A#x#t(<4)piFiK zeg+SBs%?VLM#IU(ZbK4lbnAh2WX+%x82K7i*%D@_(oMQyU9@IReUW*@ delta 109 zcmcZ|KF^D_fpw~|>PA)`naRRRGMg_bH8U}-W7-_5`kh&?w1+bW%~Ld|FtUm>GcXiSZse9{EzeNM5}6#R M?awGQd7-uy00FHd(EtDd diff --git a/docs/_build/doctrees/modules.doctree b/docs/_build/doctrees/modules.doctree new file mode 100644 index 0000000000000000000000000000000000000000..120fcc72d9f43109a2456a191a7e73e3b115706e GIT binary patch literal 2783 zcmZ8jTWcIQ6n1Ry)w}CUl2Swpqbu?{g%{AEAU_;P)86C-^y&XTMuvngtdl&lP4WvA|L6%D#^Gm=fWE#~<1 zaL*Z{tR$&AslN-uY>l~&(~iix1dUEr5ug0s36tELgy^ir?`S2daUA-VIVaQtv^;Ei zHaA*127H9>3nD$*)e^O3>Hi=L!34d3rfHQM~V`QJ)^ZlsOa`GhC9<3 z_UaHa_`QI_uvvN|u^OWTS>i<6MJS!rzN;9H<}jnQV;h?v!Z`6C?a!8TZHo9IOe`>0 zW`K2?Di#JG)Dk9HCCM&@gdCp8@En|gOmV(XF2L4 zkx&d{Nz}rV1w*+h*4v9L^%Xqp@Db9gm|a3wJ2;0 zU~No&QD!Y3QPoNy07avSOa}KWNyUcL`n9OE%u}5$i-e{Fwk)+}+2+X#BDu?63oB~8 z?q^h3GLtEhCd%H5C*a%&$yhL>A{~s58?|gTzrrW!3r;YlD`GO0tWorP4+98&s+VVX z!eJsCV51g5p%jI1@#ljlVN$X(14S^!R9+Qqlq55P*b^_pr`);Hem|W;Y){K8$F(}u zW&t|gPnuN#(99ew&>n|&^dUca{Pnk}=fuqOTjrBwZT`!Zc`%nGyk0PKDwvyBJ}?cY z+!Yee29C@?A)4lNKO6&)MbUDY-gnm6rz+E6wC@R1WmpNh<45JBefrR3 zZx`J(Pw~iryqARaH-E`r*f2-}cU2<7H<7=*w)_$Pzu+Sq#+$vWPLFeejwko9SW6Nm zS9*1ro03`&!K1guOv|?YmFm4)!d825!{T7&wK{Zk!#+ld(f7@2GgG(L*BgeA^ zsK9lSYbjA! + + + + + grogupy.core — grogupy 1.0.0 documentation + + + + + + + + + + + + + + + + + +

+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for grogupy.core

+# Copyright (c) [2024] []
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import numpy as np
+from numpy.linalg import inv
+
+from grogupy.magnetism import blow_up_orbindx, parse_magnetic_entity
+from grogupy.utilities import commutator
+
+
+
+[docs] +def parallel_Gk(HK, SK, eran, eset): + """Calculates the Greens function by inversion. + + It calculates the Greens function on all the energy levels at the same time. + + Args: + HK : (NO, NO), np.array_like + Hamiltonian at a given k point + SK : (NO, NO), np.array_like + Overlap Matrix at a given k point + eran : (eset) np.array_like + Energy sample along the contour + eset : int + Number of energy samples along the contour + + Returns: + Gk : (eset, NO, NO), np.array_like + Green's function at a given k point + """ + + # Calculates the Greens function on all the energy levels + return inv(SK * eran.reshape(eset, 1, 1) - HK)
+ + + +
+[docs] +def sequential_GK(HK, SK, eran, eset): + """Calculates the Greens function by inversion. + + It calculates sequentially over the energy levels. + + Args: + HK : (NO, NO), np.array_like + Hamiltonian at a given k point + SK : (NO, NO), np.array_like + Overlap Matrix at a given k point + eran : (eset) np.array_like + Energy sample along the contour + eset : int + Number of energy samples along the contour + + Returns: + Gk : (eset, NO, NO), np.array_like + Green's function at a given k point + """ + + # creates an empty holder + Gk = np.zeros(shape=(eset, HK.shape[0], HK.shape[1]), dtype="complex128") + # fills the holder sequentially by the Greens function on a given energy + for j in range(eset): + Gk[j] = inv(SK * eran[j] - HK) + + return Gk
+ + + +
+[docs] +def calc_Vu(H, Tu): + """Calculates the local perturbation in case of a spin rotation. + + Args: + H : (NO, NO) np.array_like + Hamiltonian + Tu : (NO, NO) array_like + Rotation around u + + Returns: + Vu1 : (NO, NO) np.array_like + First order perturbed matrix + Vu2 : (NO, NO) np.array_like + Second order perturbed matrix + """ + + Vu1 = 1j / 2 * commutator(H, Tu) # equation 100 + Vu2 = 1 / 8 * commutator(commutator(Tu, H), Tu) # equation 100 + + return Vu1, Vu2
+ + + +
+[docs] +def remove_clutter_for_save(pairs, magnetic_entities): + """Removes unimportant data from the dictionaries. + + It is used before saving to throw away data that + is not needed for post processing. + + Args: + pairs : dict + Contains all the pair information + magnetic_entities : dict + Contains all the magnetic entity information + + Returns: + pairs : dict + Contains all the reduced pair information + magnetic_entities : dict + Contains all the reduced magnetic entity information + """ + + # remove clutter from magnetic entities and pair information + for pair in pairs: + del pair["Gij"] + del pair["Gij_tmp"] + del pair["Gji"] + del pair["Gji_tmp"] + for mag_ent in magnetic_entities: + del mag_ent["Gii"] + del mag_ent["Gii_tmp"] + del mag_ent["Vu1"] + del mag_ent["Vu2"] + + return pairs, magnetic_entities
+ + + +
+[docs] +def build_hh_ss(dh): + """It builds the Hamiltonian and Overlap matrix from the sisl.dh class. + + It restructures the data in the SPIN BOX representation, where NS is + the number of supercells and NO is the number of orbitals. + + Args: + dh : sisl.physics.Hamiltonian + Hamiltonian read in by sisl + + Returns: + hh : (NS, NO, NO) np.array_like + Hamiltonian in SPIN BOX representation + ss : (NS, NO, NO) np.array_like + Overlap matrix in SPIN BOX representation + """ + + NO = dh.no # shorthand for number of orbitals in the unit cell + + # preprocessing Hamiltonian and overlap matrix elements + h11 = dh.tocsr(dh.M11r) + h11 += dh.tocsr(dh.M11i) * 1.0j + h11 = h11.toarray().reshape(NO, dh.n_s, NO).transpose(0, 2, 1).astype("complex128") + + h22 = dh.tocsr(dh.M22r) + h22 += dh.tocsr(dh.M22i) * 1.0j + h22 = h22.toarray().reshape(NO, dh.n_s, NO).transpose(0, 2, 1).astype("complex128") + + h12 = dh.tocsr(dh.M12r) + h12 += dh.tocsr(dh.M12i) * 1.0j + h12 = h12.toarray().reshape(NO, dh.n_s, NO).transpose(0, 2, 1).astype("complex128") + + h21 = dh.tocsr(dh.M21r) + h21 += dh.tocsr(dh.M21i) * 1.0j + h21 = h21.toarray().reshape(NO, dh.n_s, NO).transpose(0, 2, 1).astype("complex128") + + sov = ( + dh.tocsr(dh.S_idx) + .toarray() + .reshape(NO, dh.n_s, NO) + .transpose(0, 2, 1) + .astype("complex128") + ) + + # Reorganization of Hamiltonian and overlap matrix elements to SPIN BOX representation + U = np.vstack( + [np.kron(np.eye(NO, dtype=int), [1, 0]), np.kron(np.eye(NO, dtype=int), [0, 1])] + ) + # This is the permutation that transforms ud1ud2 to u12d12 + # That is this transforms FROM SPIN BOX to ORBITAL BOX => U + # the inverse transformation is U.T u12d12 to ud1ud2 + # That is FROM ORBITAL BOX to SPIN BOX => U.T + + # From now on everything is in SPIN BOX!! + hh, ss = np.array( + [ + U.T +
+[docs] + @ np.block([[h11[:, :, i], h12[:, :, i]], [h21[:, :, i], h22[:, :, i]]]) + @ U + for i in range(dh.lattice.nsc.prod()) + ] + ), np.array( + [ + U.T + @ np.block( + [[sov[:, :, i], sov[:, :, i] * 0], [sov[:, :, i] * 0, sov[:, :, i]]] + ) + @ U + for i in range(dh.lattice.nsc.prod()) + ] + ) + + return hh, ss
+ + + +def setup_pairs_and_magnetic_entities( + magnetic_entities, pairs, dh, simulation_parameters +): + """It creates the complete structure of the dictionaries and fills some basic data. + + It creates orbital indexes, spin box indexes, coordinates and tags for magnetic entities. + Furthermore it creates the structures for the energies, the perturbed potentials and + the Greens function calculation. It dose the same for the pairs. + + Args: + pairs : dict + Contains the initial pair information + magnetic_entities : dict + Contains the initial magnetic entity information + dh : sisl.physics.Hamiltonian + Hamiltonian read in by sisl + simulation_parameters : dict + A set of parameters from the simulation + + Returns: + pairs : dict + Contains the initial information and the complete structure + magnetic_entities : dict + Contains the initial information and the complete structure + """ + + # for every site we have to store 3 Greens function (and the associated _tmp-s) in the 3 reference directions + for mag_ent in magnetic_entities: + parsed = parse_magnetic_entity(dh, **mag_ent) # parse orbital indexes + mag_ent["orbital_indices"] = parsed + mag_ent["spin_box_indices"] = blow_up_orbindx( + parsed + ) # calculate spin box indexes + # if orbital is not set use all + if "l" not in mag_ent.keys(): + mag_ent["l"] = "all" + + # tag creation for one atom + if isinstance(mag_ent["atom"], int): + mag_ent["tags"] = [ + f"[{mag_ent['atom']}]{dh.atoms[mag_ent['atom']].tag}({mag_ent['l']})" + ] + mag_ent["xyz"] = [dh.xyz[mag_ent["atom"]]] + # tag creation for more atoms + if isinstance(mag_ent["atom"], list): + mag_ent["tags"] = [] + mag_ent["xyz"] = [] + # iterate over atoms + for atom_idx in mag_ent["atom"]: + mag_ent["tags"].append( + f"[{atom_idx}]{dh.atoms[atom_idx].tag}({mag_ent['l']})" + ) + mag_ent["xyz"].append(dh.xyz[atom_idx]) + + # calculate size for Greens function generation + spin_box_shape = len(mag_ent["spin_box_indices"]) + + # we will store the second order energy derivations here + mag_ent["energies"] = [] + + # These will be the perturbed potentials from eq. 100 + mag_ent["Vu1"] = [] # so they are independent in memory + mag_ent["Vu2"] = [] + + mag_ent["Gii"] = [] # Greens function + mag_ent["Gii_tmp"] = [] # Greens function for parallelization + for _ in simulation_parameters["ref_xcf_orientations"]: + # Rotations for every quantization axis + mag_ent["Vu1"].append([]) + mag_ent["Vu2"].append([]) + # Greens functions for every quantization axis + mag_ent["Gii"].append( + np.zeros( + (simulation_parameters["eset"], spin_box_shape, spin_box_shape), + dtype="complex128", + ) + ) + mag_ent["Gii_tmp"].append( + np.zeros( + (simulation_parameters["eset"], spin_box_shape, spin_box_shape), + dtype="complex128", + ) + ) + + # for every site we have to store 2x3 Greens function (and the associated _tmp-s) + # in the 3 reference directions, because G_ij and G_ji are both needed + for pair in pairs: + # calculate distance + xyz_ai = magnetic_entities[pair["ai"]]["xyz"] + xyz_aj = magnetic_entities[pair["aj"]]["xyz"] + xyz_aj = xyz_aj + pair["Ruc"] @ simulation_parameters["cell"] + pair["dist"] = np.linalg.norm(xyz_ai - xyz_aj) + + # calculate size for Greens function generation + spin_box_shape_i = len(magnetic_entities[pair["ai"]]["spin_box_indices"]) + spin_box_shape_j = len(magnetic_entities[pair["aj"]]["spin_box_indices"]) + # tag generation + pair["tags"] = [] + for mag_ent in [magnetic_entities[pair["ai"]], magnetic_entities[pair["aj"]]]: + tag = "" + # get atoms of magnetic entity + atoms_idx = mag_ent["atom"] + orbitals = mag_ent["l"] + + # if magnetic entity contains one atoms + if isinstance(atoms_idx, int): + tag += f"[{atoms_idx}]{dh.atoms[atoms_idx].tag}({orbitals})" + + # if magnetic entity contains more than one atoms + if isinstance(atoms_idx, list): + # iterate over atoms + atom_group = "{" + for atom_idx in atoms_idx: + atom_group += f"[{atom_idx}]{dh.atoms[atom_idx].tag}({orbitals})--" + # end {} of the atoms in the magnetic entity + tag += atom_group[:-2] + "}" + pair["tags"].append(tag) + pair["energies"] = [] # we will store the second order energy derivations here + + pair["Gij"] = [] # Greens function + pair["Gji"] = [] + pair["Gij_tmp"] = [] # Greens function for parallelization + pair["Gji_tmp"] = [] + for _ in simulation_parameters["ref_xcf_orientations"]: + # Greens functions for every quantization axis + pair["Gij"].append( + np.zeros( + (simulation_parameters["eset"], spin_box_shape_i, spin_box_shape_j), + dtype="complex128", + ) + ) + pair["Gij_tmp"].append( + np.zeros( + (simulation_parameters["eset"], spin_box_shape_i, spin_box_shape_j), + dtype="complex128", + ) + ) + pair["Gji"].append( + np.zeros( + (simulation_parameters["eset"], spin_box_shape_j, spin_box_shape_i), + dtype="complex128", + ) + ) + pair["Gji_tmp"].append( + np.zeros( + (simulation_parameters["eset"], spin_box_shape_j, spin_box_shape_i), + dtype="complex128", + ) + ) + + return pairs, magnetic_entities
+ + + +
+[docs] +def onsite_projection(matrix, idx1, idx2): + """It produces the slices of a matrix for the on site projection. + + The slicing is along the last two axes as these contains the orbital indexing. + + Args: + matrix : (..., :, :) np.array_like + Some matrix + idx : np.array_like + The indexes of the orbitals + + Returns: + np.array_like + Reduced matrix based on the projection + """ + + return matrix[..., idx1, :][..., idx2]
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/grogupy/grogu.html b/docs/_build/html/_modules/grogupy/grogu.html new file mode 100644 index 0000000..bad6d5c --- /dev/null +++ b/docs/_build/html/_modules/grogupy/grogu.html @@ -0,0 +1,587 @@ + + + + + + + + grogupy.grogu — grogupy 1.0.0 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for grogupy.grogu

+# Copyright (c) [2024] []
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import warnings
+from sys import getsizeof
+from timeit import default_timer as timer
+
+# use numpy number of threads one
+try:
+    from threadpoolctl import threadpool_info, threadpool_limits
+
+    user_api = threadpool_info()["user_api"]
+    threadpool_limits(limits=1, user_api=user_api)
+except:
+    print("Warning: threadpoolctl could not make numpy use single thread!")
+
+import numpy as np
+import sisl
+from mpi4py import MPI
+
+try:
+    from tqdm import tqdm
+
+    tqdm_imported = True
+except:
+    print("Please install tqdm for nice progress bar.")
+    tqdm_imported = False
+
+from grogupy import *
+
+
+
+[docs] +def main(): + # runtime information + times = dict() + times["start_time"] = timer() + + # input output stuff + ###################################################################### + ###################################################################### + ###################################################################### + + infile = "/Users/danielpozsar/Downloads/nojij/Fe3GeTe2/monolayer/soc/lat3_791/Fe3GeTe2.fdf" + outfile = "./Fe3GeTe2_notebook" + + magnetic_entities = [ + dict(atom=3, l=2), + dict(atom=4, l=2), + dict(atom=5, l=2), + ] + pairs = [ + dict(ai=0, aj=1, Ruc=np.array([0, 0, 0])), + dict(ai=0, aj=2, Ruc=np.array([0, 0, 0])), + dict(ai=1, aj=2, Ruc=np.array([0, 0, 0])), + dict(ai=0, aj=2, Ruc=np.array([-1, -1, 0])), + dict(ai=1, aj=2, Ruc=np.array([-1, -1, 0])), + dict(ai=0, aj=2, Ruc=np.array([-1, 0, 0])), + dict(ai=1, aj=2, Ruc=np.array([-1, 0, 0])), + dict(ai=1, aj=2, Ruc=np.array([-2, 0, 0])), + dict(ai=1, aj=2, Ruc=np.array([-3, 0, 0])), + ] + simulation_parameters = default_args + simulation_parameters["infile"] = infile + simulation_parameters["outfile"] = outfile + simulation_parameters["kset"] = 20 + simulation_parameters["kdirs"] = "xy" + simulation_parameters["eset"] = 600 + simulation_parameters["esetp"] = 10000 + + ###################################################################### + ###################################################################### + ###################################################################### + + # MPI parameters + comm = MPI.COMM_WORLD + size = comm.Get_size() + rank = comm.Get_rank() + root_node = 0 + + if rank == root_node: + # include parallel size in simulation parameters + simulation_parameters["parallel_size"] = size + + # check versions for debugging + try: + print("sisl version: ", sisl.__version__) + except: + print("sisl version unknown.") + try: + print("numpy version: ", np.__version__) + except: + print("numpy version unknown.") + + # rename outfile + if not simulation_parameters["outfile"].endswith(".pickle"): + simulation_parameters["outfile"] += ".pickle" + + # if ebot is not given put it 0.1 eV under the smallest energy + if simulation_parameters["ebot"] is None: + try: + eigfile = simulation_parameters["infile"][:-3] + "EIG" + simulation_parameters["ebot"] = read_siesta_emin(eigfile) - 0.1 + simulation_parameters["automatic_ebot"] = True + except: + print("Could not determine ebot.") + print("Parameter was not given and .EIG file was not found.") + else: + simulation_parameters["automatic_ebot"] = False + + # read sile + fdf = sisl.get_sile(simulation_parameters["infile"]) + + # read in hamiltonian + dh = fdf.read_hamiltonian() + + # read unit cell vectors + simulation_parameters["cell"] = fdf.read_geometry().cell + + # unit cell index + uc_in_sc_idx = dh.lattice.sc_index([0, 0, 0]) + + if rank == root_node: + print("\n\n\n\n\n") + print( + "#################################################################### JOB INFORMATION ###########################################################################" + ) + print_job_description(simulation_parameters) + print( + "################################################################################################################################################################" + ) + print("\n\n\n\n\n") + + times["setup_time"] = timer() + print(f"Setup done. Elapsed time: {times['setup_time']} s") + print( + "================================================================================================================================================================" + ) + + NO = dh.no # shorthand for number of orbitals in the unit cell + + # reformat Hamltonian and Overlap matrix for manipulations + hh, ss = build_hh_ss(dh) + + # symmetrizing Hamiltonian and Overlap matrix to make them hermitian + for i in range(dh.lattice.sc_off.shape[0]): + j = dh.lattice.sc_index(-dh.lattice.sc_off[i]) + h1, h1d = hh[i], hh[j] + hh[i], hh[j] = (h1 + h1d.T.conj()) / 2, (h1d + h1.T.conj()) / 2 + s1, s1d = ss[i], ss[j] + ss[i], ss[j] = (s1 + s1d.T.conj()) / 2, (s1d + s1.T.conj()) / 2 + + # identifying TRS and TRB parts of the Hamiltonian + TAUY = np.kron(np.eye(NO), tau_y) + hTR = np.array([TAUY @ hh[i].conj() @ TAUY for i in range(dh.lattice.nsc.prod())]) + hTRS = (hh + hTR) / 2 + hTRB = (hh - hTR) / 2 + + # extracting the exchange field + traced = [spin_tracer(hTRB[i]) for i in range(dh.lattice.nsc.prod())] # equation 77 + XCF = np.array( + [ + np.array([f["x"] / 2 for f in traced]), + np.array([f["y"] / 2 for f in traced]), + np.array([f["z"] / 2 for f in traced]), + ] + ) + + # check if exchange field has scalar part + max_xcfs = abs(np.array(np.array([f["c"] / 2 for f in traced]))).max() + if max_xcfs > 1e-12: + warnings.warn( + f"Exchange field has non negligible scalar part. Largest value is {max_xcfs}" + ) + + if rank == root_node: + times["H_and_XCF_time"] = timer() + print( + f"Hamiltonian and exchange field rotated. Elapsed time: {times['H_and_XCF_time']} s" + ) + print( + "================================================================================================================================================================" + ) + + # initialize pairs and magnetic entities based on input information + pairs, magnetic_entities = setup_pairs_and_magnetic_entities( + magnetic_entities, pairs, dh, simulation_parameters + ) + + if rank == root_node: + times["site_and_pair_dictionaries_time"] = timer() + print( + f"Site and pair dictionaries created. Elapsed time: {times['site_and_pair_dictionaries_time']} s" + ) + print( + "================================================================================================================================================================" + ) + + # generate k space sampling + kset = make_kset( + dirs=simulation_parameters["kdirs"], NUMK=simulation_parameters["kset"] + ) + + # generate weights for k points + wkset = np.ones(len(kset)) / len(kset) + + # split the k points based on MPI size + kpcs = np.array_split(kset, size) + + # use progress bar if available + if rank == root_node and tqdm_imported: + kpcs[root_node] = tqdm(kpcs[root_node], desc="k loop") + + if rank == root_node: + times["k_set_time"] = timer() + print(f"k set created. Elapsed time: {times['k_set_time']} s") + print( + "================================================================================================================================================================" + ) + + # this will contain the three Hamiltonian in the + # reference directions needed to calculate the energy + # variations upon rotation + hamiltonians = [] + + # iterate over the reference directions (quantization axes) + for i, orient in enumerate(simulation_parameters["ref_xcf_orientations"]): + # obtain rotated exchange field and Hamiltonian + R = RotMa2b(simulation_parameters["scf_xcf_orientation"], orient["o"]) + rot_XCF = np.einsum("ij,jklm->iklm", R, XCF) + rot_H_XCF = sum( + [np.kron(rot_XCF[i], tau) for i, tau in enumerate([tau_x, tau_y, tau_z])] + ) + rot_H_XCF_uc = rot_H_XCF[uc_in_sc_idx] + + # obtain total Hamiltonian with the rotated exchange field + rot_H = hTRS + rot_H_XCF # equation 76 + + # store the relevant information of the Hamiltonian + hamiltonians.append(dict(orient=orient["o"], H=rot_H)) + + # these are the rotations (for now) perpendicular to the quantization axis + for u in orient["vw"]: + # section 2.H + Tu = np.kron(np.eye(NO, dtype=int), tau_u(u)) + Vu1, Vu2 = calc_Vu(rot_H_XCF_uc, Tu) + + for mag_ent in magnetic_entities: + idx = mag_ent["spin_box_indices"] + # fill up the perturbed potentials (for now) based on the on-site projections + mag_ent["Vu1"][i].append(onsite_projection(Vu1, idx, idx)) + mag_ent["Vu2"][i].append(onsite_projection(Vu2, idx, idx)) + + if rank == root_node: + times["reference_rotations_time"] = timer() + print( + f"Rotations done perpendicular to quantization axis. Elapsed time: {times['reference_rotations_time']} s" + ) + print( + "================================================================================================================================================================" + ) + + # provide helpful information to estimate the runtime and memory + # requirements of the Greens function calculations + if rank == root_node: + print("Starting matrix inversions.") + if simulation_parameters["padawan_mode"]: + print("Padawan mode: ") + print(f"Total number of k points: {kset.shape[0]}") + print( + f"Number of energy samples per k point: {simulation_parameters['eset']}" + ) + print(f"Total number of directions: {len(hamiltonians)}") + print( + f"Total number of matrix inversions: {kset.shape[0] * len(hamiltonians) * simulation_parameters['eset']}" + ) + print( + f"The shape of the Hamiltonian and the Greens function is {NO}x{NO}={NO*NO}" + ) + # https://stackoverflow.com/questions/70746660/how-to-predict-memory-requirement-for-np-linalg-inv + # memory is O(64 n**2) for complex matrices + memory_size = getsizeof(hamiltonians[0]["H"].base) / 1024 + print( + f"Memory taken by a single Hamiltonian is: {getsizeof(hamiltonians[0]['H'].base) / 1024} KB" + ) + print(f"Expected memory usage per matrix inversion: {memory_size * 32} KB") + print( + f"Expected memory usage per k point for parallel inversion: {memory_size * len(hamiltonians) * simulation_parameters['eset'] * 32} KB" + ) + print( + f"Expected memory usage on root node: {len(np.array_split(kset, size)[0]) * memory_size * len(hamiltonians) * simulation_parameters['eset'] * 32 / 1024} MB" + ) + print( + "================================================================================================================================================================" + ) + + # MPI barrier + comm.Barrier() + + # make energy contour + cont = make_contour( + emin=simulation_parameters["ebot"], + enum=simulation_parameters["eset"], + p=simulation_parameters["esetp"], + ) + eran = cont.ze + + # sampling the integrand on the contour and the BZ + for k in kpcs[rank]: + # weight of k point in BZ integral + wk = wkset[rank] + + # iterate over reference directions + for i, hamiltonian_orientation in enumerate(hamiltonians): + # calculate Hamiltonian and Overlap matrix in a given k point + H = hamiltonian_orientation["H"] + HK, SK = hsk(H, ss, dh.sc_off, k) + + if simulation_parameters["parallel_solver_for_Gk"]: + Gk = parallel_Gk(HK, SK, eran, simulation_parameters["eset"]) + else: + # solve Greens function sequentially for the energies, because of memory bound + Gk = sequential_GK(HK, SK, eran, simulation_parameters["eset"]) + + # store the Greens function slice of the magnetic entities + for mag_ent in magnetic_entities: + idx = mag_ent["spin_box_indices"] + mag_ent["Gii_tmp"][i] += onsite_projection(Gk, idx, idx) * wk + + for pair in pairs: + # add phase shift based on the cell difference + phase = np.exp(1j * 2 * np.pi * k @ pair["Ruc"].T) + + # get the pair orbital sizes from the magnetic entities + ai = magnetic_entities[pair["ai"]]["spin_box_indices"] + aj = magnetic_entities[pair["aj"]]["spin_box_indices"] + + # store the Greens function slice of the magnetic entities + pair["Gij_tmp"][i] += onsite_projection(Gk, ai, aj) * phase * wk + pair["Gji_tmp"][i] += onsite_projection(Gk, aj, ai) / phase * wk + + # summ reduce partial results of mpi nodes + for i in range(len(hamiltonians)): + for mag_ent in magnetic_entities: + comm.Reduce(mag_ent["Gii_tmp"][i], mag_ent["Gii"][i], root=root_node) + + for pair in pairs: + comm.Reduce(pair["Gij_tmp"][i], pair["Gij"][i], root=root_node) + comm.Reduce(pair["Gji_tmp"][i], pair["Gji"][i], root=root_node) + + if rank == root_node: + times["green_function_inversion_time"] = timer() + print( + f"Calculated Greens functions. Elapsed time: {times['green_function_inversion_time']} s" + ) + print( + "================================================================================================================================================================" + ) + + if rank == root_node: + # iterate over the magnetic entities + for tracker, mag_ent in enumerate(magnetic_entities): + # iterate over the quantization axes + for i, Gii in enumerate(mag_ent["Gii"]): + storage = [] + # iterate over the first and second order local perturbations + for Vu1, Vu2 in zip(mag_ent["Vu1"][i], mag_ent["Vu2"][i]): + # The Szunyogh-Lichtenstein formula + traced = np.trace( + (Vu2 @ Gii + 0.5 * Gii @ Vu1 @ Gii), axis1=1, axis2=2 + ) # this is the on site projection + # evaluation of the contour integral + storage.append(int_de_ke(traced, cont.we)) + # fill up the magnetic entities dictionary with the energies + magnetic_entities[tracker]["energies"].append(storage) + # convert to np array + magnetic_entities[tracker]["energies"] = np.array( + magnetic_entities[tracker]["energies"] + ) + + # iterate over the pairs + for tracker, pair in enumerate(pairs): + # iterate over the quantization axes + for i, (Gij, Gji) in enumerate(zip(pair["Gij"], pair["Gji"])): + site_i = magnetic_entities[pair["ai"]] + site_j = magnetic_entities[pair["aj"]] + storage = [] + # iterate over the first order local perturbations in all possible orientations for the two sites + for Vui in site_i["Vu1"][i]: + for Vuj in site_j["Vu1"][i]: + # The Szunyogh-Lichtenstein formula + traced = np.trace( + (Vui @ Gij @ Vuj @ Gji), axis1=1, axis2=2 + ) # this is the on site projection + # evaluation of the contour integral + storage.append(int_de_ke(traced, cont.we)) + # fill up the pairs dictionary with the energies + pairs[tracker]["energies"].append(storage) + # convert to np array + pairs[tracker]["energies"] = np.array(pairs[tracker]["energies"]) + + # calculate magnetic parameters + for mag_ent in magnetic_entities: + Kxx, Kyy, Kzz, consistency = calculate_anisotropy_tensor(mag_ent) + mag_ent["K"] = np.array([Kxx, Kyy, Kzz]) * sisl.unit_convert("eV", "meV") + mag_ent["K_consistency"] = consistency + + for pair in pairs: + J_iso, J_S, D, J = calculate_exchange_tensor(pair) + pair["J_iso"] = J_iso * sisl.unit_convert("eV", "meV") + pair["J_S"] = J_S * sisl.unit_convert("eV", "meV") + pair["D"] = D * sisl.unit_convert("eV", "meV") + pair["J"] = J * sisl.unit_convert("eV", "meV") + + times["end_time"] = timer() + print("\n\n\n\n\n") + print( + "##################################################################### GROGU OUTPUT #############################################################################" + ) + + print_parameters(simulation_parameters) + print_atoms_and_pairs(magnetic_entities, pairs) + print( + "################################################################################################################################################################" + ) + print_runtime_information(times) + print("") + + # remove unwanted stuff before saving + pairs, magnetic_entities = remove_clutter_for_save(pairs, magnetic_entities) + # create output dictionary with all the relevant data + results = dict( + parameters=simulation_parameters, + magnetic_entities=magnetic_entities, + pairs=pairs, + runtime=times, + ) + + # save results + save_pickle(simulation_parameters["outfile"], results) + + print("\n\n\n\n\n")
+ + + +if __name__ == "__main__": + main() +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/grogupy/io.html b/docs/_build/html/_modules/grogupy/io.html new file mode 100644 index 0000000..5794a71 --- /dev/null +++ b/docs/_build/html/_modules/grogupy/io.html @@ -0,0 +1,456 @@ + + + + + + + + grogupy.io — grogupy 1.0.0 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for grogupy.io

+# Copyright (c) [2024] []
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from argparse import ArgumentParser
+from pickle import dump, load
+
+import numpy as np
+
+default_args = dict(
+    infile=None,
+    outfile=None,
+    scf_xcf_orientation=np.array([0, 0, 1]),
+    ref_xcf_orientations=[
+        dict(o=np.array([1, 0, 0]), vw=[np.array([0, 1, 0]), np.array([0, 0, 1])]),
+        dict(o=np.array([0, 1, 0]), vw=[np.array([1, 0, 0]), np.array([0, 0, 1])]),
+        dict(o=np.array([0, 0, 1]), vw=[np.array([1, 0, 0]), np.array([0, 1, 0])]),
+    ],
+    kset=2,
+    kdirs="xyz",
+    ebot=None,
+    eset=42,
+    esetp=1000,
+    parallel_solver_for_Gk=False,
+    padawan_mode=True,
+)
+
+# parser = ArgumentParser()
+
+# parser.add_argument('--input'   , dest = 'infile' , default=None                       , help = 'Input file name')
+# parser.add_argument('--output'  , dest = 'outfile', default=None                       , help = 'Output file name')
+
+# parser.add_argument('--kset'    , dest = 'kset'   , default  = 2           , type=int  , help = 'k-space resolution of Jij calculation')
+# parser.add_argument('--kdirs'   , dest = 'kdirs'  , default  = 'xyz'                   , help = 'Definition of k-space dimensionality')
+# parser.add_argument('--ebot'    , dest = 'ebot'   , default  = None        , type=float, help = 'Bottom energy of the contour')
+# parser.add_argument('--eset'    , dest = 'eset'   , default  = 42          , type=int  , help = 'Number of energy points on the contour')
+# parser.add_argument('--eset-p'  , dest = 'esetp'  , default  = 1000        , type=int  , help = 'Parameter tuning the distribution on the contour')
+
+# cmd_line_args = parser.parse_args()
+
+
+
+[docs] +def save_pickle(outfile, data): + """Saves the data in the outfile with pickle. + + Args: + outfile : str + Path to outfile + data : dict + Contains the data + """ + + # save dictionary + with open(outfile, "wb") as output_file: + dump(data, output_file)
+ + + +
+[docs] +def load_pickle(infile): + """Loads the data from the infile with pickle. + + Args: + infile : str + Path to infile + + Returns: + data : dict + A dictionary of data + """ + + # open and read file + with open(infile, "wb") as input_file: + data = load(data, input_file) + + return data
+ + + + + + + + + + + + + + + + + +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/grogupy/magnetism.html b/docs/_build/html/_modules/grogupy/magnetism.html new file mode 100644 index 0000000..bf2e92a --- /dev/null +++ b/docs/_build/html/_modules/grogupy/magnetism.html @@ -0,0 +1,348 @@ + + + + + + + + grogupy.magnetism — grogupy 1.0.0 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for grogupy.magnetism

+# Copyright (c) [2024] []
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import numpy as np
+
+
+
+[docs] +def blow_up_orbindx(orb_indices): + """Function to blow up orbital indices to make SPIN BOX indices. + + Args: + orb_indices : np.array_like + These are the indices in ORBITAL BOX + + Returns: + orb_indices : np.array_like + These are the indices in SPIN BOX + """ + + orb_indices = np.array([[2 * o, 2 * o + 1] for o in orb_indices]).flatten() + + return orb_indices
+ + + +
+[docs] +def spin_tracer(M): + """Spin tracer utility. + + This takes an operator with the orbital-spin sequence: + orbital 1 up, + orbital 1 down, + orbital 2 up, + orbital 2 down, + that is in the SPIN-BOX representation, + and extracts orbital dependent Pauli traces. + + + Args: + M : np.array_like + Traceable matrix + + Returns: + dict + It contains the traced matrix with "x", "y", "z" and "c" + """ + M11 = M[0::2, 0::2] + M12 = M[0::2, 1::2] + M21 = M[1::2, 0::2] + M22 = M[1::2, 1::2] + + M_o = dict() + M_o["x"] = M12 + M21 + M_o["y"] = 1j * (M12 - M21) + M_o["z"] = M11 - M22 + M_o["c"] = M11 + M22 + + return M_o
+ + + +
+[docs] +def parse_magnetic_entity(dh, atom=None, l=None, **kwargs): + """Function to define orbital indexes of a given magnetic entity. + + Args: + dh : sisl.physics.Hamiltonian + Hamiltonian from sisl + atom : integer or list of integers, optional + Defining atom (or atoms) in the unit cell forming the magnetic entity. Defaults to None + l : integer, optional + Defining the angular momentum channel. Defaults to None + + Returns: + list + The orbital indexes of the given magnetic entity + """ + # case where we deal with more than one atom defining the magnetic entity + if type(atom) == list: + dat = [] + for a in atom: + a_orb_idx = dh.geometry.a2o(a, all=True) + if ( + type(l) == int + ): # if specified we restrict to given l angular momentum channel inside each atom + a_orb_idx = a_orb_idx[[o.l == l for o in dh.geometry.atoms[a].orbitals]] + dat.append(a_orb_idx) + orbital_indeces = np.hstack(dat) + # case where we deal with a singel atom magnetic entity + elif type(atom) == int: + orbital_indeces = dh.geometry.a2o(atom, all=True) + if ( + type(l) == int + ): # if specified we restrict to given l angular momentum channel + orbital_indeces = orbital_indeces[ + [o.l == l for o in dh.geometry.atoms[atom].orbitals] + ] + + return orbital_indeces # numpy array containing integers labeling orbitals associated to a magnetic entity.
+ + + +
+[docs] +def calculate_anisotropy_tensor(mag_ent): + """Calculates the renormalized anisotropy tensor from the energies. + + It uses the grogu convention for output. + + Args: + mag_ent : dict + An element from the magnetic entities + + Returns: + K : np.array_like + elements of the anisotropy tensor + """ + + # get the energies + energies = mag_ent["energies"] + + # calculate the diagonal tensor elements + Kxx = energies[1, 1] - energies[1, 0] + Kyy = energies[0, 1] - energies[0, 0] + Kzz = 0 + + # perform consistency check + calculated_diff = Kyy - Kxx + expected_diff = energies[2, 0] - energies[2, 1] + consistency_check = abs(calculated_diff - expected_diff) + + return Kxx, Kyy, Kzz, consistency_check
+ + + +
+[docs] +def calculate_exchange_tensor(pair): + """Calculates the exchange tensor from the energies. + + It produces the isotropic exchange, the relevant elements + from the Dzyaloshinskii-Morilla (Dm) tensor, the symmetric-anisotropy + and the complete exchange tensor. + + Args: + pair : dict + An element from the pairs + + Returns: + J_iso : float + Isotropic exchange (Tr[J] / 3) + J_S : np.array_like + Symmetric-anisotropy (J_S = J - J_iso * I ––> Jxx, Jyy, Jxy, Jxz, Jyz) + D : np.array_like + DM elements (Dx, Dy, Dz) + J : np.array_like + Complete exchange tensor flattened (Jxx, Jxy, Jxz, Jyx, Jyy, Jyz, Jzx, Jzy, Jzz) + """ + + # energies from rotations + energies = pair["energies"] + # Initialize output arrays + J = np.zeros((3, 3)) + D = np.zeros(3) + + # J matrix calculations + # J(1,1) = mean([DEij(2,2,2), DEij(2,2,3)]) + J[0, 0] = np.mean([energies[1, 3], energies[2, 3]]) + + # J(1,2) = -mean([DEij(1,2,3), DEij(2,1,3)]) + J[0, 1] = -np.mean([energies[2, 1], energies[2, 2]]) + J[1, 0] = J[0, 1] + + # J(1,3) = -mean([DEij(1,2,2), DEij(2,1,2)]) + J[0, 2] = -np.mean([energies[1, 1], energies[1, 2]]) + J[2, 0] = J[0, 2] + + # J(2,2) = mean([DEij(2,2,1), DEij(1,1,3)]) + J[1, 1] = np.mean([energies[0, 3], energies[2, 0]]) + + # J(2,3) = -mean([DEij(1,2,1), DEij(2,1,1)]) + J[1, 2] = -np.mean([energies[0, 1], energies[0, 2]]) + J[2, 1] = J[1, 2] + + # J(3,3) = mean([DEij(1,1,1), DEij(1,1,2)]) + J[2, 2] = np.mean([energies[0, 0], energies[1, 0]]) + + # D vector calculations + # D(1) = mean([DEij(1,2,1), -DEij(2,1,1)]) + D[0] = np.mean([energies[0, 1], -energies[0, 2]]) + + # D(2) = mean([DEij(2,1,2), -DEij(1,2,2)]) + D[1] = np.mean([energies[1, 2], -energies[1, 1]]) + + # D(3) = mean([DEij(1,2,3), -DEij(2,1,3)]) + D[2] = np.mean([energies[2, 1], -energies[2, 2]]) + + J_iso = np.trace(J) / 3 + # based on the grogu output pdf + # traceless symmetric exchange matrix: + # Jxx, Jyy, Jxy, Jxz, Jyz + J_S = np.array([J[0, 0] - J_iso, J[1, 1] - J_iso, J[0, 1], J[0, 2], J[1, 2]]) + + return J_iso, J_S, D, J
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/grogupy/utilities.html b/docs/_build/html/_modules/grogupy/utilities.html new file mode 100644 index 0000000..c7f9775 --- /dev/null +++ b/docs/_build/html/_modules/grogupy/utilities.html @@ -0,0 +1,457 @@ + + + + + + + + grogupy.utilities — grogupy 1.0.0 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for grogupy.utilities

+# Copyright (c) [2024] []
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import numpy as np
+from scipy.special import roots_legendre
+from sisl.io.siesta import eigSileSiesta
+
+# Pauli matrices
+tau_x = np.array([[0, 1], [1, 0]])
+tau_y = np.array([[0, -1j], [1j, 0]])
+tau_z = np.array([[1, 0], [0, -1]])
+tau_0 = np.array([[1, 0], [0, 1]])
+
+
+
+[docs] +def commutator(a, b): + """Shorthand for commutator. + + Commutator of two matrices in the mathematical sense. + + Args: + a : np.array_like + The first matrix + b : np.array_like + The second matrix + + Returns: + np.array_like + The commutator of a and b + """ + + return a @ b - b @ a
+ + + +# define some useful functions +
+[docs] +def hsk(H, ss, sc_off, k=(0, 0, 0)): + """Speed up Hk and Sk generation. + + Calculates the Hamiltonian and the Overlap matrix at a given k point. It is faster that the sisl version. + + Args: + H : np.array_like + Hamiltonian in spin box form + ss : np.array_like + Overlap matrix in spin box form + sc_off : list + supercell indexes of the Hamiltonian + k : tuple, optional + The k point where the matrices are set up. Defaults to (0, 0, 0) + + Returns: + np.array_like + Hamiltonian at the given k point + np.array_like + Overlap matrix at the given k point + """ + + # this two conversion lines are from the sisl source + k = np.asarray(k, np.float64) + k.shape = (-1,) + + # this generates the list of phases + phases = np.exp(-1j * 2 * np.pi * k @ sc_off.T) + + # phases applied to the hamiltonian + HK = np.einsum("abc,a->bc", H, phases) + SK = np.einsum("abc,a->bc", ss, phases) + + return HK, SK
+ + + +
+[docs] +def make_kset(dirs="xyz", NUMK=20): + """Simple k-grid generator to sample the Brillouin zone. + + Depending on the value of the dirs + argument k sampling in 1,2 or 3 dimensions is generated. + If dirs argument does not contain either of x, y or z + a kset of a single k-pont at the origin is returned. The total number of k points is the NUMK**(dimensions) + + + Args: + dirs : str, optional + Directions of the k points in the Brillouin zone. They are the three lattice vectors. Defaults to "xyz" + NUMK : int, optional + The number of k points in a direction. Defaults to 20 + + Returns: + np.array_like + An array of k points that uniformly sample the Brillouin zone in the given directions + """ + + # if there is no xyz in dirs return the Gamma point + if not (sum([d in dirs for d in "xyz"])): + return np.array([[0, 0, 0]]) + + kran = len(dirs) * [np.linspace(0, 1, NUMK, endpoint=False)] + mg = np.meshgrid(*kran) + dirsdict = dict() + + for d in enumerate(dirs): + dirsdict[d[1]] = mg[d[0]].flatten() + for d in "xyz": + if not (d in dirs): + dirsdict[d] = 0 * dirsdict[dirs[0]] + kset = np.array([dirsdict[d] for d in "xyz"]).T + + return kset
+ + + +
+[docs] +def make_contour(emin=-20, emax=0.0, enum=42, p=150): + """A more sophisticated contour generator. + + Calculates the parameters for the complex contour integral. It uses the + Legendre-Gauss quadrature method. It returns a class that contains + the information for the contour integral. + + Args: + emin : int, optional + Energy minimum of the contour. Defaults to -20 + emax : float, optional + Energy maximum of the contour. Defaults to 0.0, so the Fermi level + enum : int, optional + Number of sample points along the contour. Defaults to 42 + p : int, optional + Shape parameter that describes the distribution of the sample points. Defaults to 150 + + Returns: + ccont + Contains all the information for the contour integral + """ + x, wl = roots_legendre(enum) + R = (emax - emin) / 2 # radius + z0 = (emax + emin) / 2 # center point + y1 = -np.log(1 + np.pi * p) # lower bound + y2 = 0 # upper bound + + y = (y2 - y1) / 2 * x + (y2 + y1) / 2 + phi = (np.exp(-y) - 1) / p # angle parameter + ze = z0 + R * np.exp(1j * phi) # complex points for path + we = -(y2 - y1) / 2 * np.exp(-y) / p * 1j * (ze - z0) * wl + + # just an empty container class + class ccont: + pass + + cont = ccont() + cont.R = R + cont.z0 = z0 + cont.ze = ze + cont.we = we + cont.enum = enum + + return cont
+ + + +
+[docs] +def tau_u(u): + """Pauli matrix in direction u. + + Returns the vector u in the basis of the Pauli matrices. + + Args: + u : list or np.array_like + The direction + + Returns: + np.array_like + Arbitrary direction in the base of the Pauli matrices + """ + + # u is force to be of unit length + u = u / np.linalg.norm(u) + + return u[0] * tau_x + u[1] * tau_y + u[2] * tau_z
+ + + +# +
+[docs] +def crossM(u): + """Definition for the cross-product matrix. + + It acts as a cross product with vector u. + + Args: + u : list or np.array_like + The second vector in the cross product + + Returns: + np.array_like + The matrix that represents teh cross product with a vector + """ + return np.array([[0, -u[2], u[1]], [u[2], 0, -u[0]], [-u[1], u[0], 0]])
+ + + +
+[docs] +def RotM(theta, u, eps=1e-10): + """Definition of rotation matrix with angle theta around direction u. + + + Args: + theta : float + The angle of rotation + u : np.array_like + The rotation axis + eps : float, optional + Cutoff for small elements in the resulting matrix. Defaults to 1e-10 + + Returns: + np.array_like + The rotation matrix + """ + + u = u / np.linalg.norm(u) + + M = ( + np.cos(theta) * np.eye(3) + + np.sin(theta) * crossM(u) + + (1 - np.cos(theta)) * np.outer(u, u) + ) + + # kill off small numbers + M[abs(M) < eps] = 0.0 + return M
+ + + +
+[docs] +def RotMa2b(a, b, eps=1e-10): + """Definition of rotation matrix rotating unit vector a to unit vector b. + + Function returns array R such that R @ a = b holds. + + Args: + a : np.array_like + First vector + b : np.array_like + Second vector + eps : float, optional + Cutoff for small elements in the resulting matrix. Defaults to 1e-10 + + Returns: + np.array_like + The rotation matrix with the above property + """ + + v = np.cross(a, b) + c = a @ b + M = np.eye(3) + crossM(v) + crossM(v) @ crossM(v) / (1 + c) + + # kill off small numbers + M[abs(M) < eps] = 0.0 + return M
+ + + +
+[docs] +def read_siesta_emin(eigfile): + """It reads the lowest energy level from the siesta run. + + It uses the .EIG file from siesta that contains the eigenvalues. + + Args: + eigfile : str + The path to the .EIG file + + Returns: + float + The energy minimum + """ + + # read the file + eigs = eigSileSiesta(eigfile).read_data() + + return eigs.min()
+ + + +
+[docs] +def int_de_ke(traced, we): + """It numerically integrates the traced matrix. + + It is a wrapper from numpy.trapz and it contains the + relevant constants to calculate the energy integral from + equation 93 or 96. + + Args: + traced : np.array_like + The trace of a matrix or a matrix product + we : float + The weight of a point on the contour + + Returns: + float + The energy calculated from the integral formula + """ + + return np.trapz(-1 / np.pi * np.imag(traced * we))
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/index.html b/docs/_build/html/_modules/index.html new file mode 100644 index 0000000..420bb05 --- /dev/null +++ b/docs/_build/html/_modules/index.html @@ -0,0 +1,127 @@ + + + + + + + + Overview: module code — grogupy 1.0.0 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ +

All modules for which code is available

+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/_build/html/_sources/grogupy.rst.txt b/docs/_build/html/_sources/grogupy.rst.txt new file mode 100644 index 0000000..18af50d --- /dev/null +++ b/docs/_build/html/_sources/grogupy.rst.txt @@ -0,0 +1,53 @@ +grogupy package +=============== + +Submodules +---------- + +grogupy.core module +------------------- + +.. automodule:: grogupy.core + :members: + :undoc-members: + :show-inheritance: + +grogupy.grogu module +-------------------- + +.. automodule:: grogupy.grogu + :members: + :undoc-members: + :show-inheritance: + +grogupy.io module +----------------- + +.. automodule:: grogupy.io + :members: + :undoc-members: + :show-inheritance: + +grogupy.magnetism module +------------------------ + +.. automodule:: grogupy.magnetism + :members: + :undoc-members: + :show-inheritance: + +grogupy.utilities module +------------------------ + +.. automodule:: grogupy.utilities + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: grogupy + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_build/html/_sources/implementation/index.rst.txt b/docs/_build/html/_sources/implementation/index.rst.txt index 2e4c4a7..cca03c6 100644 --- a/docs/_build/html/_sources/implementation/index.rst.txt +++ b/docs/_build/html/_sources/implementation/index.rst.txt @@ -1,2 +1,11 @@ Implementation -============== \ No newline at end of file +============== + +.. autosummary:: + :toctree: generated + :recursive: + + core + magnetism + utilities + io \ No newline at end of file diff --git a/docs/_build/html/_sources/index.rst.txt b/docs/_build/html/_sources/index.rst.txt index ada1368..e4aad29 100644 --- a/docs/_build/html/_sources/index.rst.txt +++ b/docs/_build/html/_sources/index.rst.txt @@ -71,4 +71,12 @@ More on the theoretical background can be seen `here - + @@ -101,7 +101,7 @@