# Copyright (c) [2024] [Daniel Pozsar] # # 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 timeit import default_timer as timer # runtime information times = dict() times["start_time"] = timer() import warnings from sys import getsizeof import sisl from mpi4py import MPI from src.grogu_magn import * # input output stuff ###################################################################### ###################################################################### ###################################################################### path = ( "/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 ###################################################################### ###################################################################### ###################################################################### # MPI parameters comm = MPI.COMM_WORLD size = comm.Get_size() rank = comm.Get_rank() root_node = 0 # check versions for debugging if rank == root_node: try: print(sisl.__version__) except: print("sisl version unknown.") try: print(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 except: print("Could not determine ebot.") print("Parameter was not given and .EIG file was not found.") # 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_parameters(simulation_parameters) times["setup_time"] = timer() print(f"Setup done. Elapsed time: {times['setup_time']} s") print( "================================================================================================================================================================" ) # reformat Hamltonian and Overlap matrix for manipulations hh, ss, NO = 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"] ) wkset = np.ones(len(kset)) / len(kset) # generate weights for k points kpcs = np.array_split(kset, size) # split the k points based on MPI size if 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( "================================================================================================================================================================" )