diff --git a/README.md b/README.md index cd21319..d5773d7 100644 --- a/README.md +++ b/README.md @@ -53,4 +53,4 @@ To get started using *py*GWBSE, various tutorials and examples have been created If you use *py*GWBSE in your research, please consider citing the paper! > Tathagata Biswas, Arunima K. Singh. *pyGWBSE: A high throughput workflow package for GW-BSE calculations*. [https://doi.org/10.1038/s41524-023-00976-y](https://doi.org/10.1038/s41524-023-00976-y) - +BLAH BLAH diff --git a/example/input.yaml b/example/input.yaml index d9bdf51..510866e 100644 --- a/example/input.yaml +++ b/example/input.yaml @@ -1,11 +1,11 @@ PARAMS: - kpar: 4 + kpar: 2 # 'KPAR' tag to be used in VASP simulations - ppn: 13 + ppn: 12 # NPROCS/KPAR ; NPROCS: number of total processors to be used in VASP simulations - reciprocal_density: 50 + reciprocal_density: 50 # reciprocal density that determines the k-grid using 'automatic_density_by_vol' method of pymatgen encutgw: 100 @@ -14,7 +14,7 @@ PARAMS: nbgwfactor: 2 # NBANDS=nbgwfactor x nocc'; nocc' is the smallest multiple of ppn which is larger than number of occupied bands - nomegagw: 50 + nomegagw: 50 # NOMEGAGW to be used in VASP simulations convsteps: [50, 0, 0] @@ -33,7 +33,7 @@ STRUCTURE: source: MID # MID/POSCAR MID:get structure from MP database, POSCAR: structure from a file - mat_name: NEW_MAT + mat_name: MoS2 # unique identifier in the database when source=POSCAR material_id: mp-149 @@ -46,16 +46,16 @@ WFLOW_DESIGN: skip_emc: true # set true to skip effective mass calculation - skip_wannier: true + skip_wannier: false # set true to skip wannier bandstructure interpolation - skip_conv: false + skip_conv: true # set true to skip convergence test skip_gw: true # set true to skip GW calculation - scgw: true + scgw: false # set true to perform self-consistent GW instead of G0W0 skip_bse: true diff --git a/pyGWBSE/config.py b/pyGWBSE/config.py index fc27935..578b379 100644 --- a/pyGWBSE/config.py +++ b/pyGWBSE/config.py @@ -5,5 +5,7 @@ VASP_CMD = ">>vasp_cmd<<" SUMO_CMD = ">>sumo_cmd<<" WANNIER_CMD = ">>wannier_cmd<<" +PREWTB_CMD = ">>prewtb_cmd<<" +WTB_CMD = ">>wtb_cmd<<" DB_FILE = ">>db_file<<" diff --git a/pyGWBSE/inputset.py b/pyGWBSE/inputset.py index 12c9a23..1a15f13 100644 --- a/pyGWBSE/inputset.py +++ b/pyGWBSE/inputset.py @@ -6,21 +6,21 @@ from monty.serialization import loadfn from pymatgen.io.vasp.inputs import Incar, Kpoints -from pymatgen.io.vasp.sets import DictSet +from pymatgen.io.vasp.sets import VaspInputSet from pymatgen.symmetry.bandstructure import HighSymmKpath MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) -class CreateInputs(DictSet): +class CreateInputs(VaspInputSet): """ Your Comments Here """ CONFIG = loadfn(os.path.join(MODULE_DIR, "inputset.yaml")) - SUPPORTED_MODES = ("DIAG", "GW", "STATIC", "BSE", "CONV", "EMC") + SUPPORTED_MODES = ("DIAG", "GW", "STATIC", "BSE", "CONV", "EMC", "WANNIER") def __init__(self, structure, prev_incar=None, nbands=None, nomegagw=None, encutgw=None, - potcar_functional="PBE_54", reciprocal_density=100, kpoints_line_density = 100, kpar=None, nbandsgw=None, + user_potcar_functional="PBE_54", reciprocal_density=100, kpoints_line_density = 100, kpar=None, nbandsgw=None, mode="STATIC", copy_wavecar=True, nbands_factor=5, ncores=16,nbandso=None, nbandsv=None, wannier_fw=None, **kwargs): super().__init__(structure, CreateInputs.CONFIG, **kwargs) @@ -28,7 +28,7 @@ def __init__(self, structure, prev_incar=None, nbands=None, nomegagw=None, encut self.nbands = nbands self.encutgw = encutgw self.nomegagw = nomegagw - self.potcar_functional = potcar_functional + self.user_potcar_functional = user_potcar_functional self.reciprocal_density = reciprocal_density self.kpoints_line_density = kpoints_line_density self.mode = mode.upper() @@ -80,9 +80,9 @@ def incar(self): parent_incar = super().incar incar = Incar(self.prev_incar) if self.prev_incar is not None else \ Incar(parent_incar) - if self.wannier_fw == True: + if self.mode == "WANNIER": incar.update({ - "LWANNIER90": True + "LWRITE_MMN_AMN": True }) if self.mode == "EMC": incar.update({ @@ -94,7 +94,7 @@ def incar(self): "LWAVE": False, "NSW": 0, "ISYM": 0, - "ICHARG": 11 + "ICHARG": 11, }) incar.pop("LWANNIER90", None) incar.pop("LEPSILON", None) @@ -120,7 +120,7 @@ def incar(self): }) if self.wannier_fw == True: incar.update({ - "LWANNIER90": True + "LWRITE_MMN_AMN": True }) incar.pop("EDIFF", None) incar.pop("LOPTICS", None) diff --git a/pyGWBSE/inputset.yaml b/pyGWBSE/inputset.yaml index dd4665b..2963f0e 100644 --- a/pyGWBSE/inputset.yaml +++ b/pyGWBSE/inputset.yaml @@ -10,7 +10,9 @@ INCAR: NELM: 100 PREC: Accurate SIGMA: 0.01 - LEPSILON: true + LEPSILON: false + LWANNIER90: true + LWRITE_MMN_AMN: false LVHAR: false LOPTICS: true LPEAD: false diff --git a/pyGWBSE/make_wflow.py b/pyGWBSE/make_wflow.py index 9c115d5..07ffd40 100644 --- a/pyGWBSE/make_wflow.py +++ b/pyGWBSE/make_wflow.py @@ -1,11 +1,11 @@ #This code is to create the workflow based on inputs from input.yaml file from fireworks import Firework, Workflow -from pyGWBSE.wflows import ScfFW, convFW, BseFW, GwFW, EmcFW, WannierCheckFW, WannierFW +from pyGWBSE.wflows import ScfFW, convFW, BseFW, GwFW, EmcFW, WannierCheckFW, WannierFW, WtbFW from pyGWBSE.inputset import CreateInputs from pymatgen.core import Structure from fireworks import LaunchPad -from pyGWBSE.config import VASP_CMD, DB_FILE, SUMO_CMD, WANNIER_CMD +from pyGWBSE.config import VASP_CMD, DB_FILE, SUMO_CMD, PREWTB_CMD, WTB_CMD, WANNIER_CMD from pymatgen.symmetry.analyzer import SpacegroupAnalyzer from pymatgen.io.vasp.inputs import Kpoints from pymatgen.ext.matproj import MPRester @@ -57,6 +57,8 @@ def create_wfs(struct, params_dict, vasp_cmd=None, sumo_cmd=None, wannier_cmd=No c = c or {} vasp_cmd = c.get("VASP_CMD", VASP_CMD) sumo_cmd = c.get("SUMO_CMD", SUMO_CMD) + prewtb_cmd = c.get("PREWTB_CMD", PREWTB_CMD) + wtb_cmd = c.get("WTB_CMD", WTB_CMD) wannier_cmd = c.get("WANNIER_CMD", WANNIER_CMD) db_file = c.get("DB_FILE", DB_FILE) @@ -113,16 +115,22 @@ def create_wfs(struct, params_dict, vasp_cmd=None, sumo_cmd=None, wannier_cmd=No if skip_wannier==False: ifw=ifw+1 parents = fws[0] - fw = WannierCheckFW(structure=struct, mat_name=mat_name, kpar=kpar, ppn=ppn,vasp_cmd=vasp_cmd,wannier_cmd=wannier_cmd,db_file=db_file,parents=parents,reciprocal_density=rd) + fw = WannierCheckFW(structure=struct, mat_name=mat_name, kpar=kpar, ppn=ppn,vasp_cmd=vasp_cmd,wannier_cmd=wannier_cmd, prewtb_cmd=prewtb_cmd,db_file=db_file,parents=parents,reciprocal_density=rd) + fws.append(fw) + + ifw=ifw+1 + parents = fws[ifw-1] + fw = WtbFW(structure=struct,mat_name=mat_name, enwinbse=enwinbse, wtb_cmd=wtb_cmd,db_file=db_file,parents=parents) fws.append(fw) - ifw=ifw+1 - parents = fws[0] - fw = convFW(structure=struct, mat_name=mat_name, nbands=nbands, nbgwfactor=nbgwfactor, encutgw=encutgw, nomegagw=nomegagw, convsteps=convsteps, conviter=conviter, - tolerence=0.1, no_conv=skip_conv, vasp_cmd=vasp_cmd,db_file=db_file,parents=parents,kpar=kpar,nbandsgw=nbandsgw,reciprocal_density=rd) - fws.append(fw) if skip_gw==False: + ifw=ifw+1 + parents = fws[0] + fw = convFW(structure=struct, mat_name=mat_name, nbands=nbands, nbgwfactor=nbgwfactor, encutgw=encutgw, nomegagw=nomegagw, convsteps=convsteps, conviter=conviter, + tolerence=0.1, no_conv=skip_conv, vasp_cmd=vasp_cmd,db_file=db_file,parents=parents,kpar=kpar,nbandsgw=nbandsgw,reciprocal_density=rd) + fws.append(fw) + ifw=ifw+1 parents = fws[ifw-1] fw = GwFW(structure=struct, mat_name=mat_name, tolerence=0.1, no_conv=not(scgw), diff --git a/pyGWBSE/out2db.py b/pyGWBSE/out2db.py index d73f825..de9de56 100644 --- a/pyGWBSE/out2db.py +++ b/pyGWBSE/out2db.py @@ -9,7 +9,7 @@ from monty.json import jsanitize from pymatgen.io.vasp.outputs import Vasprun, Outcar -from pyGWBSE.tasks import read_emcpyout, read_epsilon, get_gap_from_dict, read_vac_level +from pyGWBSE.tasks import read_emcpyout, read_wtbout, read_epsilon, get_gap_from_dict, read_vac_level from pyGWBSE.wannier_tasks import read_vbm, read_wannier, read_vasp, read_special_kpts @@ -94,8 +94,6 @@ def run_task(self, fw_spec): job_tag = self["job_tag"] else: job_tag = None - with open(filename, "a") as file: - file.write("") vasprun = Vasprun(filename) incar = vasprun.incar parameters = vasprun.parameters @@ -186,6 +184,37 @@ def run_task(self, fw_spec): coll = mmdb.db[task_collection] coll.insert_one(d) +@explicit_serialize +class wtb2db(FiretaskBase): + """ + Insert effective masses for a SUMO-BANDSTATS calculation. + """ + required_params = ["structure", "db_file", "mat_name", "task_label"] + optional_params = ["defuse_unsuccessful"] + + def run_task(self, fw_spec): + """ + Your Comments Here + """ + # get adddtional tags to parse the directory for + db_file = env_chk(self.get('db_file'), fw_spec) + dir_name = os.getcwd() + '/out-exc-bs' + mmdb = VaspCalcDb.from_db_file(db_file, admin=True) + structure = self["structure"] + mat_name = self["mat_name"] + task_label = self["task_label"] + task_collection = 'WTB_Results' + filename = glob.glob('./out-exc-bs/bse_diel_xx.dat*')[-1] + en, eps1, eps2 = read_wtbout(filename) + # dictionary to update the database with + d = {"structure": structure.as_dict(), "task_label": task_label, + "formula_pretty": structure.composition.reduced_formula, + "material_id": mat_name, "run_directory": dir_name, + "frequency": en, "epsilon_1": eps1, "epsilon_2": eps2} + d = jsanitize(d) + coll = mmdb.db[task_collection] + coll.insert_one(d) + @explicit_serialize class eps2db(FiretaskBase): """ diff --git a/pyGWBSE/parse_outputs.py b/pyGWBSE/parse_outputs.py new file mode 100644 index 0000000..f6edfba --- /dev/null +++ b/pyGWBSE/parse_outputs.py @@ -0,0 +1,132 @@ +import json +import os +import re +from collections import defaultdict +from datetime import datetime + +import numpy as np +from fireworks import FiretaskBase, FWAction, explicit_serialize +from fireworks.utilities.fw_serializers import DATETIME_HANDLER +from monty.json import MontyEncoder, jsanitize +from monty.os.path import zpath +from pydash.objects import get, has +from pymatgen.analysis.elasticity.elastic import ElasticTensor, ElasticTensorExpansion +from pymatgen.analysis.elasticity.strain import Deformation, Strain +from pymatgen.analysis.elasticity.stress import Stress +from pymatgen.analysis.ferroelectricity.polarization import ( + EnergyTrend, + Polarization, + get_total_ionic_dipole, +) +from pymatgen.analysis.magnetism import ( + CollinearMagneticStructureAnalyzer, + Ordering, + magnetic_deformation, +) +from pymatgen.command_line.bader_caller import bader_analysis_from_path +from pymatgen.core.structure import Structure +from pymatgen.electronic_structure.boltztrap import BoltztrapAnalyzer +from pymatgen.io.vasp.sets import get_vasprun_outcar +from pymatgen.symmetry.analyzer import SpacegroupAnalyzer + +from atomate.common.firetasks.glue_tasks import get_calc_loc +from atomate.utils.utils import env_chk, get_logger, get_meta_from_structure +from atomate.vasp.config import DEFUSE_UNSUCCESSFUL, STORE_VOLUMETRIC_DATA +from atomate.vasp.database import VaspCalcDb +from atomate.vasp.drones import BADER_EXE_EXISTS, VaspDrone + +__author__ = "Anubhav Jain, Kiran Mathew, Shyam Dwaraknath" +__email__ = "ajain@lbl.gov, kmathew@lbl.gov, shyamd@lbl.gov" + +logger = get_logger(__name__) + + +@explicit_serialize +class BSEToDb(FiretaskBase): + """ + Enter a BSE run into the database. + + Optional params: + db_file (str): path to file containing the database credentials. + Supports env_chk. Default: write data to JSON file. + gwcalc_dir (str): path to GW step of the calculation + """ + + optional_params = [ + "gwcalc_dir", + "parse_dos", + "bandstructure_mode", + "additional_fields", + "db_file", + "fw_spec_field", + "defuse_unsuccessful", + "task_fields_to_push", + "parse_chgcar", + "parse_aeccar", + "parse_potcar_file", + "parse_bader", + "store_volumetric_data", + ] + + def run_task(self, fw_spec): + + calc_dir = get_calc_loc(self["gwcalc_dir"], + fw_spec["calc_locs"]) if self.get( + "gwcalc_dir") else {} + + # parse the VASP directory + logger.info(f"PARSING DIRECTORY: {calc_dir}") + + drone = VaspDrone( + additional_fields=self.get("additional_fields"), + parse_dos=self.get("parse_dos", False), + parse_potcar_file=self.get("parse_potcar_file", True), + bandstructure_mode=self.get("bandstructure_mode", False), + parse_bader=self.get("parse_bader", BADER_EXE_EXISTS), + parse_chgcar=self.get("parse_chgcar", False), # deprecated + parse_aeccar=self.get("parse_aeccar", False), # deprecated + store_volumetric_data=self.get( + "store_volumetric_data", STORE_VOLUMETRIC_DATA + ), + ) + + # assimilate (i.e., parse) + d = drone.assimilate(calc_dir["path"]) + + # add the structure + bse_dir = os.getcwd() + vrun, outcar = get_vasprun_outcar(bse_dir, parse_eigen=False, parse_dos=False) + structure = vrun.final_structure + d["optical_transition"]=vrun.optical_transition + d["dielectric"]=vrun.dielectric + + db_file = env_chk(self.get("db_file"), fw_spec) + d = jsanitize(d) + + if not db_file: + del d["optical_transition"] + with open(os.path.join(bse_dir, "BSE.json"), "w") as f: + f.write(json.dumps(d, default=DATETIME_HANDLER)) + else: + db = VaspCalcDb.from_db_file(db_file, admin=True) + + # optical transitions gets inserted into GridFS + optical_transition = json.dumps(d["optical_transition"], cls=MontyEncoder) + fsid, compression = db.insert_gridfs( + optical_transition, collection="optical_transition_fs", compress=True + ) + d["optical_transtiion_fs_id"] = fsid + + dielectric = json.dumps(d["dielectric"], cls=MontyEncoder) + fsid, compression = db.insert_gridfs( + dielectric, collection="dielectric_fs", compress=True + ) + + d["dielectric_fs_id"] = fsid + del d["dielectric"] + del d["optical_transition"] + + db.collection = db.db["BSE_results"] + db.collection.insert_one(d) + + diff --git a/pyGWBSE/run_calc.py b/pyGWBSE/run_calc.py index 6d376d2..544530c 100644 --- a/pyGWBSE/run_calc.py +++ b/pyGWBSE/run_calc.py @@ -76,3 +76,36 @@ def run_task(self, fw_spec): logger.info("Running command: {}".format(cmd)) return_code = subprocess.call(cmd, shell=True) logger.info("Command {} finished running with returncode: {}".format(cmd, return_code)) + +@explicit_serialize +class Run_PreWTB(FiretaskBase): + """ + Your Comments Here + """ + required_params = ["prewtb_cmd"] + + def run_task(self, fw_spec): + """ + Your Comments Here + """ + cmd = env_chk(self["prewtb_cmd"], fw_spec) + logger.info("Running command: {}".format(cmd)) + return_code = subprocess.call(cmd, shell=True) + logger.info("Command {} finished running with returncode: {}".format(cmd, return_code)) + +@explicit_serialize +class Run_WTB(FiretaskBase): + """ + Your Comments Here + """ + required_params = ["wtb_cmd"] + + def run_task(self, fw_spec): + """ + Your Comments Here + """ + cmd = env_chk(self["wtb_cmd"], fw_spec) + logger.info("Running command: {}".format(cmd)) + return_code = subprocess.call(cmd, shell=True) + logger.info("Command {} finished running with returncode: {}".format(cmd, return_code)) + diff --git a/pyGWBSE/tasks.py b/pyGWBSE/tasks.py index 691aaa8..74b07b0 100644 --- a/pyGWBSE/tasks.py +++ b/pyGWBSE/tasks.py @@ -4,6 +4,7 @@ import gzip import os import re +from monty.serialization import loadfn from atomate.common.firetasks.glue_tasks import CopyFiles, get_calc_loc from atomate.utils.utils import env_chk, get_logger from fireworks import explicit_serialize, FiretaskBase, FWAction @@ -24,6 +25,7 @@ __author__ = 'Anubhav Jain, Kiran Mathew' __email__ = 'ajain@lbl.gov, kmathew@lbl.gov' +MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) @explicit_serialize class CheckBeConv(FiretaskBase): @@ -176,6 +178,20 @@ def run_task(self, fw_spec): encutgw=encutgw, nomegagw=nomegagw, nbands=nbands, nbandsgw=nbandsgw, wannier_fw=wannier_fw) vis.write_input(".") +def read_wtbout(fname): + f = open(fname) + contents = f.readlines() + f.close() + en=[] + eps1=[] + eps2=[] + for content in contents: + if "#" not in content: + lines=str.split(content) + en.append(eval(lines[0])) + eps1.append(eval(lines[1])) + eps2.append(eval(lines[2])) + return en, eps1, eps2 def read_emcpyout(fname): f = open(fname) @@ -429,3 +445,44 @@ def copy_files(self): f_out.writelines(file_content) f.close() os.remove(dest_path + gz_ext) + + +@explicit_serialize +class WriteWTBInput(FiretaskBase): + """ + Your Comments Here + """ + CONFIG = loadfn(os.path.join(MODULE_DIR, "wtb_in.yaml")) + required_params = ["enwinbse"] + optional_params = ["RK", "EDIEL, CSHIFT", "NTHREADS"] + + def run_task(self, fw_spec): + + file = glob.glob('vasprun.xml*')[-1] + vasprun = Vasprun(file) + enwinbse = self["enwinbse"] + + qp_energies = vasprun.eigenvalues + igap, dgap = get_gap_from_dict(qp_energies) + bgap, cbm, vbm, is_band_gap_direct = vasprun.eigenvalue_band_properties + nv, nc = get_nbandsov(qp_energies, vbm, cbm, enwinbse) + self.CONFIG["NBANDSC"]=nc + self.CONFIG["NBANDSV"]=nv + self.CONFIG["ENSPECI"]=round((dgap-1.0),4) + self.CONFIG["ENSPECF"]=round((dgap+enwinbse+5),4) + self.write_wtbinput() + + def write_wtbinput(self): + wann_inp = str(os.getcwd()) + '/input.dat' + newpath = str(os.getcwd()) + str(self.CONFIG["OUTPUT"][1:]) + if not os.path.isdir(newpath): + os.makedirs(newpath) + f=open(wann_inp, "w") + for tag in self.CONFIG.keys(): + if tag in ["OUTPUT", "CALC_DATA", "PARAMS_FILE"]: + f.writelines([tag, "= ", '"', str(self.CONFIG[tag]), '"',"\n"]) + else: + f.writelines([tag, "= ", str(self.CONFIG[tag]), "\n"]) + f.close() + + diff --git a/pyGWBSE/wannier_tasks.py b/pyGWBSE/wannier_tasks.py index d48540d..25561e7 100644 --- a/pyGWBSE/wannier_tasks.py +++ b/pyGWBSE/wannier_tasks.py @@ -60,7 +60,7 @@ def run_task(self, fw_spec): prev_incar=prev_incar, encutgw=encutgw, nomegagw=nomegagw, nbands=nbands, nbandsgw=nbandsgw) vis.write_input(".") labels, kpts = kpath_finder(poscarfile) - write_wannier_input(numwan, nbands, labels, kpts, wann_inp, elements,False) + write_wannier_input(numwan, nbands, labels, kpts, wann_inp, elements, False) @explicit_serialize @@ -86,19 +86,19 @@ def run_task(self, fw_spec): potcarfile = str(os.getcwd()) + '/POTCAR' vasprun = Vasprun(vasprunfile) incar = vasprun.incar + mesh = vasprun.kpoints.kpts[0] nbands = incar["NBANDS"] elements = read_potcar(potcarfile, poscarfile) numwan = 0 for element in elements: numwan = numwan + element[5] - print(numwan, nbands) if numwan > nbands: nbands = (int(numwan / ppn) + 1) * ppn - vis = CreateInputs(structure, mode='STATIC', prev_incar=prev_incar, reciprocal_density=reciprocal_density, - nbands=nbands) + vis = CreateInputs(structure, mode='WANNIER', prev_incar=prev_incar, reciprocal_density=reciprocal_density, + kpar=1, nbands=nbands) vis.write_input(".") labels, kpts = kpath_finder(poscarfile) - write_wannier_input(numwan, nbands, labels, kpts, wann_inp, elements,write_hr) + write_wannier_input(numwan, nbands, labels, kpts, wann_inp, elements, write_hr) @explicit_serialize @@ -113,7 +113,7 @@ def run_task(self, fw_spec): """ f_wannkpt = str(os.getcwd()) + '/wannier90_band.kpt' f_vaspkpt = str(os.getcwd()) + '/KPOINTS' - f = open(f_wannkpt) + f = open(f_wannkpt, "r") contents = f.readlines() f.close() lines = str.split(contents[0]) @@ -127,7 +127,7 @@ def run_task(self, fw_spec): f.close() -def write_wannier_input(numwan, nbands, labels, kpts, wann_inp, elements,write_hr): +def write_wannier_input(numwan, nbands, labels, kpts, wann_inp, elements, write_hr): """ Your Comments Here """ @@ -136,12 +136,19 @@ def write_wannier_input(numwan, nbands, labels, kpts, wann_inp, elements,write_h f.write("write_hr = true" + "\n") f.close() else: - f = open(wann_inp, 'w') + f = open(wann_inp, "r") + contents = f.readlines() + f.close() + f = open(wann_inp, "w") + for content in contents[5:]: + f.write(content) + f.close() + f = open(wann_inp, 'a') f.write("num_wann = " + str(numwan) + "\n") - if numwan < nbands: - f.write("exclude_bands " + str(numwan + 1) + "-" + str(nbands) + "\n") + if numwan < nbands-1: + f.write("exclude_bands: " + str(numwan + 1) + "-" + str(nbands) + "\n") if numwan == nbands - 1: - f.write("exclude_bands " + str(numwan + 1) + "\n") + f.write("exclude_bands: " + str(numwan + 1) + "\n") f.write("bands_plot = true" + "\n") f.write("begin kpoint_path" + "\n") for i in range(len(labels)): @@ -156,16 +163,33 @@ def write_wannier_input(numwan, nbands, labels, kpts, wann_inp, elements,write_h f.write("Begin Projections" + "\n") f.write("random" + "\n") for element in elements: - f.write(element[0] + ':') + el_string=[] + el_string.append(element[0]) for l in range(4): if element[l + 1] > 0: - if l == 0: - f.write('l=' + str(l)) - else: - f.write(';' + 'l=' + str(l)) - f.write('\n') + el_string.append("l="+str(l)) + f_string=";".join(el_string) + w_string=f_string.replace(";",":",1) + f.write(w_string+"\n") f.write("End Projections" + "\n") f.write("num_iter = 500" + "\n") + #f.write("begin unit_cell_cart" + "\n") + #for i in range(3): + # f.write("%14.7f" %lattice[i][0]+" "+"%14.7f" %lattice[i][1]+" "+"%14.7f" %lattice[i][2]+ "\n") + #f.write("end unit_cell_cart" + "\n") + #f.write("begin atoms_cart" + "\n") + #for site in sites: + # coord=site.coords + # f.write(str(site.specie)+" "+"%14.7f" %coord[0]+" "+"%14.7f" %coord[1]+" "+"%14.7f" %coord[2]+ "\n") + #f.write("end atoms_cart" + "\n") + #f.write("mp_grid ="+" "+str(mesh[0])+" "+str(mesh[1])+" "+str(mesh[2])+"\n") + #f.write("begin kpoints" + "\n") + #for i in range(0, mesh[0]): + # for j in range(0, mesh[1]): + # for k in range(0, mesh[2]): + # f.write('%12.8f' %( i*1./mesh[0])+" "+'%12.8f' %( j*1./mesh[1])+" "+'%12.8f' %( k*1./mesh[2])+ '\n') + #f.write("end kpoints" + "\n") + f.write("write_hr = true" + "\n") f.close() diff --git a/pyGWBSE/wflows.py b/pyGWBSE/wflows.py index c2da180..6eb4d0e 100644 --- a/pyGWBSE/wflows.py +++ b/pyGWBSE/wflows.py @@ -8,14 +8,16 @@ import numpy as np from atomate.common.firetasks.glue_tasks import PassCalcLocs from atomate.vasp.firetasks.write_inputs import WriteVaspFromIOSet +from atomate.vasp.firetasks.parse_outputs import VaspToDb from fireworks import Firework, Tracker from pyGWBSE.inputset import CreateInputs -from pyGWBSE.out2db import gw2db, bse2db, emc2db, eps2db, Wannier2DB, rpa2db -from pyGWBSE.run_calc import Run_Vasp, Run_Sumo, Run_Wannier +from pyGWBSE.out2db import gw2db, bse2db, emc2db, eps2db, Wannier2DB, rpa2db, wtb2db +from pyGWBSE.parse_outputs import BSEToDb +from pyGWBSE.run_calc import Run_Vasp, Run_Sumo, Run_Wannier, Run_WTB, Run_PreWTB from pyGWBSE.tasks import CopyOutputFiles, CheckBeConv, StopIfConverged, PasscalClocsCond, WriteBSEInput, \ - WriteGWInput, MakeWFilesList, SaveNbandsov, SaveConvParams + WriteGWInput, MakeWFilesList, SaveNbandsov, SaveConvParams, WriteWTBInput from pyGWBSE.wannier_tasks import WriteWannierInputForDFT, WriteWannierInputForGW, CopyKptsWan2vasp @@ -36,8 +38,9 @@ def __init__(self, mat_name=None, structure=None, nbands=None, kpar=None, recipr vasp_input_set=vasp_input_set, vasp_input_params=vasp_input_params)) t.append(Run_Vasp(vasp_cmd=vasp_cmd)) - t.append(eps2db(structure=structure, mat_name=mat_name, db_file=db_file, defuse_unsuccessful=False)) - t.append(rpa2db(structure=structure, mat_name=mat_name, task_label=name, db_file=db_file, defuse_unsuccessful=False)) + #t.append(eps2db(structure=structure, mat_name=mat_name, db_file=db_file, defuse_unsuccessful=False)) + #t.append(rpa2db(structure=structure, mat_name=mat_name, task_label=name, db_file=db_file, defuse_unsuccessful=False)) + t.append(VaspToDb(db_file=db_file, additional_fields={"task_label": name, "mat_name": mat_name})) t.append(PassCalcLocs(name=name)) super(ScfFW, self).__init__(t, name=fw_name, **kwargs) @@ -56,7 +59,7 @@ def __init__(self, mat_name=None, structure=None, tolerence=None, no_conv=None, convsteps=np.array(convsteps)*0.01 for niter in range(conviter): niter = niter + 1 - files2copy = ['WAVECAR'] + files2copy = ['WAVECAR', "wannier90.win"] task_label = 'Convergence_Iteration: ' + str(niter) hviter=np.heaviside((niter-1),0) @@ -102,7 +105,8 @@ def __init__(self, mat_name=None, structure=None, tolerence=None, no_conv=None, t.append(CheckBeConv(niter=niter, tolerence=tolerence, no_conv=no_conv)) t.append(PasscalClocsCond(name=name)) if no_conv==False: - t.append(gw2db(structure=structure, mat_name=mat_name, task_label=task_label, db_file=db_file, defuse_unsuccessful=False)) + #t.append(gw2db(structure=structure, mat_name=mat_name, task_label=task_label, db_file=db_file, defuse_unsuccessful=False)) + t.append(VaspToDb(db_file=db_file, additional_fields={"task_label": name, "mat_name": mat_name})) t.append(StopIfConverged()) tracker = Tracker('vasp.log', nlines=100) super(convFW, self).__init__(t, parents=parents, name=fw_name, spec={"_trackers": [tracker]}, **kwargs) @@ -119,7 +123,7 @@ def __init__(self, mat_name=None, structure=None, tolerence=None, no_conv=None, t = [] name = "GW" fw_name = "{}-{}".format(mat_name, name) - files2copy = ['WAVECAR', 'WAVEDER'] + files2copy = ['WAVECAR', 'WAVEDER', "wannier90.win"] if prev_calc_dir: t.append(CopyOutputFiles(additional_files=files2copy, calc_dir=prev_calc_dir, contcar_to_poscar=True)) elif parents: @@ -135,9 +139,10 @@ def __init__(self, mat_name=None, structure=None, tolerence=None, no_conv=None, t.append(CheckBeConv(niter=niter, tolerence=tolerence, no_conv=no_conv)) t.append(PasscalClocsCond(name=name)) t.append(MakeWFilesList()) - t.append( - gw2db(structure=structure, mat_name=mat_name, task_label=task_label, job_tag=job_tag, db_file=db_file, - defuse_unsuccessful=False)) + #t.append( + # gw2db(structure=structure, mat_name=mat_name, task_label=task_label, job_tag=job_tag, db_file=db_file, + # defuse_unsuccessful=False)) + t.append(VaspToDb(db_file=db_file, additional_fields={"task_label": name, "mat_name": mat_name, "job_tag": job_tag})) t.append(StopIfConverged()) tracker = Tracker('vasp.log', nlines=100) @@ -164,11 +169,13 @@ def __init__(self, mat_name=None, structure=None, reciprocal_density=None, vasp_ t.append(SaveNbandsov(enwinbse=enwinbse)) t.append(WriteBSEInput(structure=structure, reciprocal_density=reciprocal_density)) t.append(Run_Vasp(vasp_cmd=vasp_cmd)) - t.append(bse2db(structure=structure, mat_name=mat_name, task_label=name, job_tag=job_tag, db_file=db_file, - defuse_unsuccessful=False)) + #t.append(bse2db(structure=structure, mat_name=mat_name, task_label=name, job_tag=job_tag, db_file=db_file, + # defuse_unsuccessful=False)) + print(prev_calc_loc) + t.append(BSEToDb(db_file=db_file, gwcalc_dir=prev_calc_loc, additional_fields={"task_label": name, "mat_name": mat_name, "job_tag": job_tag})) tracker = Tracker('vasp.log', nlines=100) - super(BseFW, self).__init__(t, parents=parents, name=fw_name, state='PAUSED', spec={"_trackers": [tracker]}, + super(BseFW, self).__init__(t, parents=parents, name=fw_name, spec={"_trackers": [tracker], "_category": "nokpar"}, **kwargs) @@ -204,7 +211,7 @@ def __init__(self, mat_name=None, structure=None, nbands=None, kpar=None, recipr class WannierCheckFW(Firework): def __init__(self, ppn=None, kpar=None, mat_name=None, structure=None, reciprocal_density=None, vasp_input_set=None, vasp_input_params=None, - vasp_cmd="vasp", wannier_cmd=None, prev_calc_loc=True, prev_calc_dir=None, db_file=None, + vasp_cmd="vasp", wannier_cmd=None, prewtb_cmd=None, prev_calc_loc=True, prev_calc_dir=None, db_file=None, vasptodb_kwargs={}, parents=None, **kwargs): """ Your Comments Here @@ -212,22 +219,22 @@ def __init__(self, ppn=None, kpar=None, mat_name=None, structure=None, reciproca t = [] name = "WANNIER_CHECK" fw_name = "{}-{}".format(mat_name, name) - t.append(CopyOutputFiles(calc_loc=prev_calc_loc, contcar_to_poscar=True)) + t.append(CopyOutputFiles(calc_loc=prev_calc_loc, contcar_to_poscar=True, additional_files=['WAVECAR', "wannier90.win"])) t.append(WriteWannierInputForDFT(structure=structure, reciprocal_density=reciprocal_density, ppn=ppn, write_hr=False)) t.append(Run_Vasp(vasp_cmd=vasp_cmd)) - t.append(WriteWannierInputForDFT(structure=structure, reciprocal_density=reciprocal_density, ppn=ppn, write_hr=True)) t.append(Run_Wannier(wannier_cmd=wannier_cmd)) - vasp_input_set = CreateInputs(structure, mode='EMC', kpar=kpar, reciprocal_density=reciprocal_density) + vasp_input_set = CreateInputs(structure, mode='EMC', kpar=1, reciprocal_density=reciprocal_density) t.append(WriteVaspFromIOSet(structure=structure, vasp_input_set=vasp_input_set, vasp_input_params=vasp_input_params)) t.append(CopyKptsWan2vasp()) t.append(Run_Vasp(vasp_cmd=vasp_cmd)) + t.append(Run_PreWTB(prewtb_cmd=prewtb_cmd)) t.append(Wannier2DB(structure=structure, mat_name=mat_name, task_label='CHECK_WANNIER_INTERPOLATION', db_file=db_file, compare_vasp=True, defuse_unsuccessful=False)) tracker = Tracker('vasp.log', nlines=100) - - super(WannierCheckFW, self).__init__(t, parents=parents, name=fw_name, spec={"_trackers": [tracker]}, **kwargs) + t.append(PassCalcLocs(name=name)) + super(WannierCheckFW, self).__init__(t, parents=parents, name=fw_name, spec={"_trackers": [tracker], "_category": "nokpar"}, **kwargs) class WannierFW(Firework): @@ -247,3 +254,21 @@ def __init__(self, structure=None, mat_name=None, wannier_cmd=None, prev_calc_lo tracker = Tracker('wannier90.wout', nlines=100) super(WannierFW, self).__init__(t, parents=parents, name=fw_name, spec={"_trackers": [tracker]}, **kwargs) + +class WtbFW(Firework): + def __init__(self, structure=None, mat_name=None, enwinbse=None, wtb_cmd=None, prev_calc_loc=True, prev_calc_dir=None, + db_file=None, parents=None, **kwargs): + """ + Your Comments Here + """ + t = [] + name = "WTB" + fw_name = "{}-{}".format(mat_name, name) + files2copy = ['wannier90.win', 'tb_hr.dat'] + t.append(CopyOutputFiles(additional_files=files2copy, calc_loc=prev_calc_loc)) + t.append(WriteWTBInput(enwinbse=enwinbse)) + t.append(Run_WTB(wtb_cmd=wtb_cmd)) + t.append(wtb2db(structure=structure, mat_name=mat_name, task_label='Wannier BSE', db_file=db_file, defuse_unsuccessful=False)) + tracker = Tracker('wannier90.wout', nlines=100) + + super(WtbFW, self).__init__(t, parents=parents, name=fw_name, spec={"_trackers": [tracker], "_category": "openmp"}, **kwargs) diff --git a/pyGWBSE/wtb_in.yaml b/pyGWBSE/wtb_in.yaml new file mode 100644 index 0000000..8450242 --- /dev/null +++ b/pyGWBSE/wtb_in.yaml @@ -0,0 +1,25 @@ +NTHREADS: 16 +SYSDIM: "3D" +DFT: "V" + +OUTPUT: "./out-exc-bs/" +CALC_DATA: "./out-exc-bs/" +PARAMS_FILE: "./tb_hr.dat" + +MESH_TYPE: "RK3D" +RK: 25 + +COULOMB_POT: V3D +NBANDSC: 4 +NBANDSV: 4 + +BSE: T +SPEC: T +DTDIAG: T + +EDIEL: 1 + +CSHIFT: 0.1 +ENSPECI: 0.0 +ENSPECF: 6.0 +