From 27f642b11dec6fc3da3f449373ff3db4a5b25a9a Mon Sep 17 00:00:00 2001 From: harrisonlabollita Date: Fri, 15 Oct 2021 14:24:45 -0700 Subject: [PATCH 1/8] helper script to write inmdftpr file --- bin/init_dmftpr | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100755 bin/init_dmftpr diff --git a/bin/init_dmftpr b/bin/init_dmftpr new file mode 100755 index 00000000..191be6a8 --- /dev/null +++ b/bin/init_dmftpr @@ -0,0 +1,86 @@ +#!/usr/bin/env python + +import glob, sys, os +import itertools +from numpy import array + +def write_indmftpr(): + orbitals = {"s" : [1, 0, 0, 0], + "p" : [0, 1, 0, 0], + "d" : [0, 0, 1, 0], + "f" : [0, 0, 0, 1]} + corr_orbitals = {"s" : [2, 0, 0, 0], + "p" : [0, 2, 0, 0], + "d" : [0, 0, 2, 0], + "f" : [0, 0, 0, 2]} + dirname = os.getcwd().rpartition('/')[2] + if os.path.isfile(dirname + ".indmftpr"): + found = input("Previous {}.indmftpr detected! Continue? (y/n)\n".format(dirname)) + if found == "n": + sys.exit(0) + with open(dirname + ".indmftpr", "w") as out: + print("Preparing dmftproj input file : {}\n".format(dirname + ".indmftpr")) + struct = open(glob.glob("*.struct")[0], "r").readlines() + species = [line.split()[0] for line in struct if "NPT" in line] + num_atoms = len(species) + out.write(str(num_atoms)+"\n") + mult = [line.split("=")[1].split()[0] for line in struct if "MULT" in line ] + out.write(" ".join(mult)+"\n") + out.write("3\n") + for atom in range(num_atoms): + while True: # input choice of spherical harmonics for atom + sph_harm=input("What flavor of spherical harmonics do you want to use for ATOM {} ({})? (cubic/complex)\n".format(atom+1, species[atom])) + if sph_harm in ["cubic", "complex"]: + out.write(sph_harm+"\n") + break + else: + print("Did not recognize that input. Try again.") + corr=input("Do you want to treat ATOM {} ({}) as correlated (y/n)?\n".format(atom+1, species[atom])) + if corr == "y": + proj=input("Specify the correlated orbital? (d,f)\n") + non_corr=input("projectors for non-correlated orbitals?\n") + projectors=array([0, 0, 0, 0]) + projectors += array(corr_orbitals[proj]) + if len(non_corr) > 0: + for p in non_corr: + projectors += array(orbitals[p]) + out.write(" ".join(list(map(str, projectors)))+"\n") + if proj == "d": + irrep=input("Split this orbital into it's irreps? (t2g/eg/n)\n") + if irrep == "t2g": + out.write("0 0 2 0\n") + out.write("01\n") + elif irrep == "t2g": + out.write("0 0 2 0\n") + out.write("10\n") + else: + out.write("0 0 0 0\n") + soc=input("Do you want to include soc? (y/n)\n") + if soc == "y": + out.write("1\n") + else: + out.write("0\n") + else: # still identify the projectors + while True: + proj=input("Specify the projectors that you would like to include? (type h for help)\n") + if proj == "h": + print("indicate orbital projectors using (s, p, d, or f). For multiple, combine them (sp, pd, spd, etc.)") + else: + projectors = array([0, 0, 0, 0], dtype=int) + for p in proj: projectors += array(orbitals[p], dtype=int) + out.write(" ".join(list(map(str, projectors)))+"\n") + out.write("0 0 0 0\n") + break + while True: + window=input("Specify the projection window around eF (in Ry)\n") + if float(window.split()[0]) < 0 and float(window.split()[1]) > 0: + out.write(window) + break + else: + print("The energy window ({}) does not contain the Fermi energy!".format(window)) + + print("initialize {} file ok!".format(dirname + ".indmftpr")) + + +if __name__ == "__main__": + write_indmftpr() From 5ff53d6dc63b73efcf75607a5748b7bfae6c18b6 Mon Sep 17 00:00:00 2001 From: harrisonlabollita Date: Mon, 18 Oct 2021 09:44:56 -0700 Subject: [PATCH 2/8] minor tweaks --- bin/init_dmftpr | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/bin/init_dmftpr b/bin/init_dmftpr index 191be6a8..3ad72fce 100755 --- a/bin/init_dmftpr +++ b/bin/init_dmftpr @@ -1,7 +1,5 @@ #!/usr/bin/env python - import glob, sys, os -import itertools from numpy import array def write_indmftpr(): @@ -16,13 +14,14 @@ def write_indmftpr(): dirname = os.getcwd().rpartition('/')[2] if os.path.isfile(dirname + ".indmftpr"): found = input("Previous {}.indmftpr detected! Continue? (y/n)\n".format(dirname)) - if found == "n": - sys.exit(0) + if found == "n": sys.exit(0) with open(dirname + ".indmftpr", "w") as out: print("Preparing dmftproj input file : {}\n".format(dirname + ".indmftpr")) + if not os.path.isfile(dirname + ".struct"): print("Could not identify a case.struct file!"); sys.exit(-1); struct = open(glob.glob("*.struct")[0], "r").readlines() species = [line.split()[0] for line in struct if "NPT" in line] num_atoms = len(species) + print("number of atoms = {} ({})\n".format(str(num_atoms), " ".join(species))) out.write(str(num_atoms)+"\n") mult = [line.split("=")[1].split()[0] for line in struct if "MULT" in line ] out.write(" ".join(mult)+"\n") @@ -38,19 +37,23 @@ def write_indmftpr(): corr=input("Do you want to treat ATOM {} ({}) as correlated (y/n)?\n".format(atom+1, species[atom])) if corr == "y": proj=input("Specify the correlated orbital? (d,f)\n") - non_corr=input("projectors for non-correlated orbitals?\n") - projectors=array([0, 0, 0, 0]) - projectors += array(corr_orbitals[proj]) - if len(non_corr) > 0: - for p in non_corr: - projectors += array(orbitals[p]) - out.write(" ".join(list(map(str, projectors)))+"\n") + while True: + non_corr=input("projectors for non-correlated orbitals? (type h for help)\n") + if non_corr == "h": + print("indicate orbital projectors using (s, p, d, or f). For multiple, combine them (sp, pd, spd, etc.)") + else: + projectors=array([0, 0, 0, 0]) + projectors += array(corr_orbitals[proj]) + if len(non_corr) > 0: + for p in non_corr: projectors += array(orbitals[p]) + out.write(" ".join(list(map(str, projectors)))+"\n") + break if proj == "d": irrep=input("Split this orbital into it's irreps? (t2g/eg/n)\n") if irrep == "t2g": out.write("0 0 2 0\n") out.write("01\n") - elif irrep == "t2g": + elif irrep == "eg": out.write("0 0 2 0\n") out.write("10\n") else: @@ -78,7 +81,6 @@ def write_indmftpr(): break else: print("The energy window ({}) does not contain the Fermi energy!".format(window)) - print("initialize {} file ok!".format(dirname + ".indmftpr")) From df7c885705c5ea755faf31418d4bb77b884daf3f Mon Sep 17 00:00:00 2001 From: harrisonlabollita Date: Tue, 2 Nov 2021 10:13:03 -0700 Subject: [PATCH 3/8] fixed edge cases --- bin/init_dmftpr | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/bin/init_dmftpr b/bin/init_dmftpr index 3ad72fce..6cc85b6a 100755 --- a/bin/init_dmftpr +++ b/bin/init_dmftpr @@ -34,6 +34,7 @@ def write_indmftpr(): break else: print("Did not recognize that input. Try again.") + corr=input("Do you want to treat ATOM {} ({}) as correlated (y/n)?\n".format(atom+1, species[atom])) if corr == "y": proj=input("Specify the correlated orbital? (d,f)\n") @@ -41,6 +42,8 @@ def write_indmftpr(): non_corr=input("projectors for non-correlated orbitals? (type h for help)\n") if non_corr == "h": print("indicate orbital projectors using (s, p, d, or f). For multiple, combine them (sp, pd, spd, etc.)") + elif len(non_corr) > 0 and proj in non_corr: + print("Error: User can not choose orbital {} as both correlated and uncorrelated!".format(proj)) else: projectors=array([0, 0, 0, 0]) projectors += array(corr_orbitals[proj]) @@ -50,19 +53,27 @@ def write_indmftpr(): break if proj == "d": irrep=input("Split this orbital into it's irreps? (t2g/eg/n)\n") + to_write="" if irrep == "t2g": - out.write("0 0 2 0\n") - out.write("01\n") + to_write += "0 0 2 0\n01\n" elif irrep == "eg": - out.write("0 0 2 0\n") - out.write("10\n") + to_write += "0 0 2 0\n10\n" else: - out.write("0 0 0 0\n") + to_write += "0 0 0 0\n" + soc=input("Do you want to include soc? (y/n)\n") if soc == "y": - out.write("1\n") + if irrep == "t2g" or irrep == "eg": + print("Warning: For SOC, dmftproj will use the entire d-shell. Using entire d-shell!") + out.write("0 0 0 0\n") + out.write("1\n") + else: + out.write(to_write) + out.write("1\n") else: + out.write(to_write) out.write("0\n") + else: # still identify the projectors while True: proj=input("Specify the projectors that you would like to include? (type h for help)\n") @@ -75,9 +86,14 @@ def write_indmftpr(): out.write("0 0 0 0\n") break while True: - window=input("Specify the projection window around eF (in Ry)\n") + window=input("Specify the projection window around eF (default unit is Ry, specify eV with -X.XX X.XX eV)\n") if float(window.split()[0]) < 0 and float(window.split()[1]) > 0: - out.write(window) + try: + eV2Ry=1.0/13.60566 + if window.split()[2] == "ev" or window.split()[2] == "eV" or window.split()[2] == "Ev": + out.write("{0:0.2f} {1:0.2f}".format(float(window.split()[0])*eV2Ry, float(window.split()[1])*eV2Ry)) + except: + out.write(window) break else: print("The energy window ({}) does not contain the Fermi energy!".format(window)) From ab7d2f5151ef1172107c31d05bc8001cdab429f0 Mon Sep 17 00:00:00 2001 From: harrisonlabollita Date: Tue, 2 Nov 2021 10:28:52 -0700 Subject: [PATCH 4/8] add basis from file --- bin/init_dmftpr | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/bin/init_dmftpr b/bin/init_dmftpr index 6cc85b6a..236f8709 100755 --- a/bin/init_dmftpr +++ b/bin/init_dmftpr @@ -28,10 +28,24 @@ def write_indmftpr(): out.write("3\n") for atom in range(num_atoms): while True: # input choice of spherical harmonics for atom - sph_harm=input("What flavor of spherical harmonics do you want to use for ATOM {} ({})? (cubic/complex)\n".format(atom+1, species[atom])) - if sph_harm in ["cubic", "complex"]: + sph_harm=input("What flavor of spherical harmonics do you want to use for ATOM {} ({})? (cubic/complex/fromfile)\n".format(atom+1, species[atom])) + if sph_harm in ["cubic", "complex", "fromfile"]: out.write(sph_harm+"\n") + if sph_harm == "fromfile": + filename=input("name of file defining the basis?\n") + if len(filename) < 25: # name of file must be less than 25 characters + out.write(filename) + else: + print("{} is too long!".format(filename)) + rename=input("Rename the file to: \n") + if os.path.isfile(filename): + os.rename(filename, rename) + out.write(rename+"\n") + else: + print("{} could not be found in the current directory!".format(filename)) + sys.exit(1) break + else: print("Did not recognize that input. Try again.") From 0c4c63f9179110a418c6caa4d2335386ba02510b Mon Sep 17 00:00:00 2001 From: Harry LaBollita <40074811+harrisonlabollita@users.noreply.github.com> Date: Wed, 3 Nov 2021 11:28:28 -0700 Subject: [PATCH 5/8] Update bin/init_dmftpr Co-authored-by: Hermann Schnait <42941106+hschnait@users.noreply.github.com> --- bin/init_dmftpr | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/bin/init_dmftpr b/bin/init_dmftpr index 236f8709..5ed6acf9 100755 --- a/bin/init_dmftpr +++ b/bin/init_dmftpr @@ -65,15 +65,13 @@ def write_indmftpr(): for p in non_corr: projectors += array(orbitals[p]) out.write(" ".join(list(map(str, projectors)))+"\n") break + to_write = "0 0 0 0\n" if proj == "d": irrep=input("Split this orbital into it's irreps? (t2g/eg/n)\n") - to_write="" if irrep == "t2g": - to_write += "0 0 2 0\n01\n" + to_write = "0 0 2 0\n01\n" elif irrep == "eg": - to_write += "0 0 2 0\n10\n" - else: - to_write += "0 0 0 0\n" + to_write = "0 0 2 0\n10\n" soc=input("Do you want to include soc? (y/n)\n") if soc == "y": From 0d25d7eb15f35989091dedcee66cef2b116bac7c Mon Sep 17 00:00:00 2001 From: Harry LaBollita <40074811+harrisonlabollita@users.noreply.github.com> Date: Wed, 3 Nov 2021 11:28:36 -0700 Subject: [PATCH 6/8] Update bin/init_dmftpr Co-authored-by: Hermann Schnait <42941106+hschnait@users.noreply.github.com> --- bin/init_dmftpr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/init_dmftpr b/bin/init_dmftpr index 5ed6acf9..4f6df735 100755 --- a/bin/init_dmftpr +++ b/bin/init_dmftpr @@ -75,7 +75,7 @@ def write_indmftpr(): soc=input("Do you want to include soc? (y/n)\n") if soc == "y": - if irrep == "t2g" or irrep == "eg": + if proj=="d" and ( irrep == "t2g" or irrep == "eg" ): print("Warning: For SOC, dmftproj will use the entire d-shell. Using entire d-shell!") out.write("0 0 0 0\n") out.write("1\n") From b16374be5f8f2548cb360f5475ef436bdc08c0b9 Mon Sep 17 00:00:00 2001 From: Alexander Hampel Date: Tue, 9 Nov 2021 08:27:04 -0500 Subject: [PATCH 7/8] add init_dmftpr to cmake lists and adapt documentation --- bin/CMakeLists.txt | 4 ++++ bin/{init_dmftpr => init_dmftpr.in} | 0 doc/guide/conv_wien2k.rst | 2 ++ 3 files changed, 6 insertions(+) rename bin/{init_dmftpr => init_dmftpr.in} (100%) diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt index 0d5af60b..8e0eb094 100644 --- a/bin/CMakeLists.txt +++ b/bin/CMakeLists.txt @@ -7,3 +7,7 @@ configure_file(vasp_dmft.in vasp_dmft) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/vasp_dmft DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) +configure_file(init_dmftpr.in init_dmftpr) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/init_dmftpr DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + diff --git a/bin/init_dmftpr b/bin/init_dmftpr.in similarity index 100% rename from bin/init_dmftpr rename to bin/init_dmftpr.in diff --git a/doc/guide/conv_wien2k.rst b/doc/guide/conv_wien2k.rst index ff37042a..895bdaa0 100644 --- a/doc/guide/conv_wien2k.rst +++ b/doc/guide/conv_wien2k.rst @@ -93,6 +93,8 @@ The third number is an optional flag to switch between different modes: In all modes the used energy range, i.e. band range, is printed to the :program:`dmftproj` output. +We also provide a simple python script `init_dmftpr` that creates the input file +interactively with user input in the shell, when executed in the wien2k run dir. After setting up the :file:`case.indmftpr` input file, you run: `dmftproj` From b15e9bef0349f62bcd3da378b5b625e539ebc05c Mon Sep 17 00:00:00 2001 From: harrisonlabollita Date: Tue, 16 Nov 2021 06:59:32 -0700 Subject: [PATCH 8/8] docstring fro init_dmftpr --- bin/init_dmftpr.in | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bin/init_dmftpr.in b/bin/init_dmftpr.in index 4f6df735..ec572315 100755 --- a/bin/init_dmftpr.in +++ b/bin/init_dmftpr.in @@ -3,6 +3,14 @@ import glob, sys, os from numpy import array def write_indmftpr(): + """ + Usage: init_dmftpr + + **case.struct file is required for this script.** + + An interactive script to generate the input file (case.indmftpr) for + the dmftproj program. + """ orbitals = {"s" : [1, 0, 0, 0], "p" : [0, 1, 0, 0], "d" : [0, 0, 1, 0],