Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V.2.0 #5

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
16 changes: 8 additions & 8 deletions example/input.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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]
Expand All @@ -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
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions pyGWBSE/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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<<"

18 changes: 9 additions & 9 deletions pyGWBSE/inputset.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@

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)
self.prev_incar = prev_incar
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()
Expand Down Expand Up @@ -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({
Expand All @@ -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)
Expand All @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion pyGWBSE/inputset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 16 additions & 8 deletions pyGWBSE/make_wflow.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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),
Expand Down
35 changes: 32 additions & 3 deletions pyGWBSE/out2db.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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("</modeling>")
vasprun = Vasprun(filename)
incar = vasprun.incar
parameters = vasprun.parameters
Expand Down Expand Up @@ -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):
"""
Expand Down
132 changes: 132 additions & 0 deletions pyGWBSE/parse_outputs.py
Original file line number Diff line number Diff line change
@@ -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__ = "[email protected], [email protected], [email protected]"

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)


Loading