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

Pynta calculate IRC in different mode by user's choice #44

Closed
wants to merge 35 commits into from
Closed
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d6e8ede
Add irc_mode to pynta class
Apr 10, 2024
16b9599
add irc_mode to setup_transition_states()
Apr 10, 2024
bfad289
add irc_mode to setup_transition_states
Apr 10, 2024
abd7c2e
define irc_obj_dict based on irc_mode and ts_task
Apr 10, 2024
2ff2528
call MolecularTSEstimate_noIRC for irc_mode="skip"
Apr 10, 2024
882f3e8
create MolecularTSEstimate_noIRC class
Apr 10, 2024
282ca1e
delete irc_firework from ctask in TSestimate_noIRC
Apr 11, 2024
258ed19
clean up print statement for error checking
Apr 11, 2024
af06e7c
irc calculation documentation added
sakim8048 Apr 11, 2024
e4113cb
Printing statement added
sakim8048 Apr 11, 2024
99b088c
fixed entire slab for IRC when irc mode is fixed
sakim8048 Apr 12, 2024
886da00
delete duplicated code lines
sakim8048 Apr 12, 2024
eb83437
delete molecularTSest_noIRC
sakim8048 Apr 12, 2024
cbf746f
change to logging.info
sakim8048 Apr 12, 2024
662aea0
define irc_obj_dict based on irc_mode
sakim8048 Apr 15, 2024
583ead2
add printing statement to test logger
sakim8048 Apr 15, 2024
4a793b4
make irc_obj_dict optional in MolecularTSEstimate
sakim8048 Apr 15, 2024
34e9aaa
fix typo
sakim8048 Apr 15, 2024
4346a22
add irc_mode to ts_task
sakim8048 Apr 15, 2024
e757fc3
typo fixed (stupid uppercase)...
sakim8048 Apr 15, 2024
f7abdc9
typo fix
sakim8048 Apr 15, 2024
5de1100
delete empty IRC_obj_dict
sakim8048 Apr 15, 2024
1d93842
collect_firework() added again
sakim8048 Apr 15, 2024
80bacf6
if irc_mode is not defined, define irc_mode = skip
sakim8048 Apr 15, 2024
babb3e0
define IRC_obj_dict key value in run_task
sakim8048 Apr 15, 2024
653e858
fix typo (case sensitive)
sakim8048 Apr 15, 2024
a421ced
delete prints() and redundent info for logger
sakim8048 Apr 19, 2024
42e309f
add IRC_opj_dict in optional_params
sakim8048 Apr 19, 2024
778bc02
indentation fix
sakim8048 Apr 19, 2024
3169d45
make irc_obj_dict optional in MolecularTSEstimate
sakim8048 Apr 15, 2024
b6fb2e3
add irc_mode to ts_task
sakim8048 Apr 15, 2024
a4d60bd
define IRC_obj_dict key value in run_task
sakim8048 Apr 15, 2024
54e5dfe
add IRC_opj_dict in optional_params
sakim8048 Apr 19, 2024
8a5c2fc
add irc_mode to ts_task
sakim8048 Apr 15, 2024
5f15561
make irc_obj_dict optional in MolecularTSEstimate
sakim8048 Apr 15, 2024
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
48 changes: 43 additions & 5 deletions pynta/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
import fireworks.fw_config
import logging

#logger
logger = logging.getLogger(__name__)
logging.basicConfig(filename='pynta.log', level=logging.INFO)


class Pynta:
def __init__(self,path,rxns_file,surface_type,metal,label,launchpad_path=None,fworker_path=None,
vacuum=8.0,repeats=(3,3,4),slab_path=None,software="Espresso", pbc=(True,True,False),socket=False,queue=False,njobs_queue=0,a=None,
Expand All @@ -33,6 +38,7 @@ def __init__(self,path,rxns_file,surface_type,metal,label,launchpad_path=None,fw
}, },
software_kwargs_gas=None,
TS_opt_software_kwargs=None,
irc_mode=None, #choose irc mode: 'skip', 'relaxed', 'fixed'
lattice_opt_software_kwargs={'kpts': (25,25,25), 'ecutwfc': 70, 'degauss':0.02, 'mixing_mode': 'plain'},
reset_launchpad=False,queue_adapter_path=None,num_jobs=25,max_num_hfsp_opts=None,#max_num_hfsp_opts is mostly for fast testing
Eharmtol=3.0,Eharmfiltertol=30.0,Ntsmin=5,frozen_layers=2,fmaxopt=0.05,fmaxirc=0.1,fmaxopthard=0.05):
Expand All @@ -59,6 +65,7 @@ def __init__(self,path,rxns_file,surface_type,metal,label,launchpad_path=None,fw
self.metal = metal
self.adsorbate_fw_dict = dict()
self.software_kwargs = software_kwargs
self.irc_mode = irc_mode

if software.lower() == 'vasp':
self.pbc = (True,True,True)
Expand Down Expand Up @@ -116,6 +123,8 @@ def __init__(self,path,rxns_file,surface_type,metal,label,launchpad_path=None,fw
self.fmaxirc = fmaxirc
self.fmaxopthard = fmaxopthard

logger.info('Pynta class is initiated')

def generate_slab(self,skip_launch=False):
"""
generates and optimizes a small scale slab that can be scaled to a large slab as needed
Expand All @@ -129,6 +138,7 @@ def generate_slab(self,skip_launch=False):
self.a = a
else:
a = self.a
logger.info('Construct slab with optimal lattice constant')
#construct slab with optimial lattice constant
slab = slab_type(self.metal,self.repeats,a,self.vacuum)
slab.pbc = self.pbc
Expand Down Expand Up @@ -440,24 +450,52 @@ def setup_transition_states(self,adsorbates_finished=False):
Sets up fireworks to generate and filter a set of TS estimates, optimize each unique TS estimate,
and run vibrational and IRC calculations on the each unique final transition state
Note the vibrational and IRC calculations are launched at the same time

If irc_mode is "fixed", entire slab layers are fixed.
If irc_mode is "relaxed", bottom half of slab layers are fixed and top half of slab layers are relaxed.
If irc_mode is not "fixed" nor "relaxed", IRC is not calculated
"""
if self.software != "XTB":
opt_obj_dict = {"software":self.software,"label":"prefix","socket":self.socket,"software_kwargs":self.software_kwargs_TS,
"run_kwargs": {"fmax" : self.fmaxopt, "steps" : 70},"constraints": ["freeze up to {}".format(self.freeze_ind)],"sella":True,"order":1,}
else:
opt_obj_dict = {"software":self.software,"label":"prefix","socket":self.socket,"software_kwargs":self.software_kwargs_TS,
"run_kwargs": {"fmax" : 0.02, "steps" : 70},"constraints": ["freeze up to "+str(self.nslab)],"sella":True,"order":1,}

vib_obj_dict = {"software":self.software,"label":"prefix","socket":self.socket,"software_kwargs":self.software_kwargs,
"constraints": ["freeze up to "+str(self.nslab)]}
IRC_obj_dict = {"software":self.software,"label":"prefix","socket":self.socket,"software_kwargs":self.software_kwargs,
"run_kwargs": {"fmax" : self.fmaxirc, "steps" : 70},"constraints":["freeze up to "+str(self.nslab)]}

#logging.info
print(f"================= IRC mode is: {self.irc_mode} =======================")
sakim8048 marked this conversation as resolved.
Show resolved Hide resolved
logger.info(f"================= IRC mode is: {self.irc_mode} =======================")
#pass through

for i,rxn in enumerate(self.rxns_dict):
#if irc_mode is "fixed" freeze all slab and conduct MolecularTSEstimate.
if self.irc_mode == "fixed":
print("==Entire slab layers are frozen==")
logging.info("Entire slab layers are frozen")
sakim8048 marked this conversation as resolved.
Show resolved Hide resolved
IRC_obj_dict = {"software":self.software,"label":"prefix","socket":self.socket,"software_kwargs":self.software_kwargs,
"run_kwargs": {"fmax" : self.fmaxopt, "steps" : 70},"constraints": ["freeze up to "+str(self.nslab)]}

elif self.irc_mode == "relaxed":
print("==Top half of the slab is relaxed==")
logger.info("==Top half of the slab is relaxed==")
IRC_obj_dict = {"software":self.software,"label":"prefix","socket":self.socket,"software_kwargs":self.software_kwargs,
"run_kwargs": {"fmax" : self.fmaxopt, "steps" : 70},"constraints": ["freeze up to {}".format(self.freeze_ind)]}
# if irc_mode = "skip" : do not conduct IRC
else:
print("==Skip IRC: IRC is not conducted==")
logger.info("==Skip IRC: IRC is not conducted==")
IRC_obj_dict = {}
pass

ts_path = os.path.join(self.path,"TS"+str(i))
os.makedirs(ts_path)
ts_task = MolecularTSEstimate({"rxn": rxn,"ts_path": ts_path,"slab_path": self.slab_path,"adsorbates_path": os.path.join(self.path,"Adsorbates"),
"rxns_file": self.rxns_file,"path": self.path,"metal": self.metal,"facet": self.surface_type, "out_path": ts_path,
"spawn_jobs": True, "opt_obj_dict": opt_obj_dict, "vib_obj_dict": vib_obj_dict,
"IRC_obj_dict": IRC_obj_dict, "nprocs": 48, "name_to_adjlist_dict": self.name_to_adjlist_dict,
"rxns_file": self.rxns_file,"path": self.path,"metal": self.metal,"facet": self.surface_type, "out_path": ts_path, "irc_mode": self.irc_mode,
"spawn_jobs": True, "opt_obj_dict": opt_obj_dict, "vib_obj_dict": vib_obj_dict, "IRC_obj_dict": IRC_obj_dict,
"nprocs": 48, "name_to_adjlist_dict": self.name_to_adjlist_dict,
"gratom_to_molecule_atom_maps":{sm: {str(k):v for k,v in d.items()} for sm,d in self.gratom_to_molecule_atom_maps.items()},
"gratom_to_molecule_surface_atom_maps":{sm: {str(k):v for k,v in d.items()} for sm,d in self.gratom_to_molecule_surface_atom_maps.items()},
"nslab":self.nslab,"Eharmtol":self.Eharmtol,"Eharmfiltertol":self.Eharmfiltertol,"Ntsmin":self.Ntsmin,
Expand Down
39 changes: 26 additions & 13 deletions pynta/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,15 +468,16 @@ def run_task(self, fw_spec):
class MolecularTSEstimate(FiretaskBase):
required_params = ["rxn","ts_path","slab_path","adsorbates_path","rxns_file","path","metal","facet",
"name_to_adjlist_dict", "gratom_to_molecule_atom_maps",
"gratom_to_molecule_surface_atom_maps","opt_obj_dict",
"vib_obj_dict","IRC_obj_dict","nslab","Eharmtol","Eharmfiltertol","Ntsmin","max_num_hfsp_opts"]
optional_params = ["out_path","spawn_jobs","nprocs",]
"gratom_to_molecule_surface_atom_maps","irc_mode",
"vib_obj_dict","opt_obj_dict","nslab","Eharmtol","Eharmfiltertol","Ntsmin","max_num_hfsp_opts"]
optional_params = ["out_path","spawn_jobs","nprocs"]
sakim8048 marked this conversation as resolved.
Show resolved Hide resolved
def run_task(self, fw_spec):
gratom_to_molecule_atom_maps = {sm: {int(k):v for k,v in d.items()} for sm,d in self["gratom_to_molecule_atom_maps"].items()}
gratom_to_molecule_surface_atom_maps = {sm: {int(k):v for k,v in d.items()} for sm,d in self["gratom_to_molecule_surface_atom_maps"].items()}
out_path = self["out_path"] if "out_path" in self.keys() else ts_path
spawn_jobs = self["spawn_jobs"] if "spawn_jobs" in self.keys() else False
nprocs = self["nprocs"] if "nprocs" in self.keys() else 1
IRC_obj_dict = self["IRC_obj_dict"] if "IRC_obj_dict" in self.keys() else None

ts_path = self["ts_path"]
rxn = self["rxn"]
Expand All @@ -490,6 +491,7 @@ def run_task(self, fw_spec):
max_num_hfsp_opts = self["max_num_hfsp_opts"]
slab_path = self["slab_path"]
slab = read(slab_path)
irc_mode = self["irc_mode"]

cas = SlabAdsorptionSites(slab,facet,allow_6fold=False,composition_effect=False,
label_sites=True,
Expand Down Expand Up @@ -614,17 +616,28 @@ def run_task(self, fw_spec):
xyzsout.append(xyzs[Eind])

if spawn_jobs:
irc_obj_dict_forward = deepcopy(self["IRC_obj_dict"])
irc_obj_dict_forward["forward"] = True
irc_obj_dict_reverse = deepcopy(self["IRC_obj_dict"])
irc_obj_dict_reverse["forward"] = False

ctask = MolecularCollect({"xyzs":xyzsout,"check_symm":True,"fw_generators": ["optimize_firework",["vibrations_firework","IRC_firework","IRC_firework"]],
"fw_generator_dicts": [self["opt_obj_dict"],[self["vib_obj_dict"],irc_obj_dict_forward,irc_obj_dict_reverse]],
print(irc_mode)
if irc_mode == "relaxed" or irc_mode == "fixed":
irc_obj_dict_forward = deepcopy(self["IRC_obj_dict"])
irc_obj_dict_forward["forward"] = True
irc_obj_dict_reverse = deepcopy(self["IRC_obj_dict"])
irc_obj_dict_reverse["forward"] = False

ctask = MolecularCollect({"xyzs":xyzsout,"check_symm":True,"fw_generators": ["optimize_firework",["vibrations_firework","IRC_firework","IRC_firework"]],
"fw_generator_dicts": [self["opt_obj_dict"],[self["vib_obj_dict"],irc_obj_dict_forward,irc_obj_dict_reverse]],
"out_names": ["opt.xyz",["vib.json","irc_forward.traj","irc_reverse.traj"]],"future_check_symms": [True,False], "label": "TS"+str(index)+"_"+rxn_name})
cfw = Firework([ctask],name="TS"+str(index)+"_"+rxn_name+"_collect",spec={"_allow_fizzled_parents": True, "_priority": 5})
newwf = Workflow([cfw],name='rxn_'+str(index)+str(rxn_name))
return FWAction(detours=newwf) #using detour allows us to inherit children from the original collect to the subsequent collects
cfw = Firework([ctask],name="TS"+str(index)+"_"+rxn_name+"_collect",spec={"_allow_fizzled_parents": True, "_priority": 5})
newwf = Workflow([cfw],name='rxn_'+str(index)+str(rxn_name))
return FWAction(detours=newwf) #using detour allows us to inherit children from the original collect to the subsequent collects

#if irc_mode == "skip":
else:
ctask = MolecularCollect({"xyzs":xyzsout,"check_symm":True,"fw_generators": ["optimize_firework",["vibrations_firework"]],
"fw_generator_dicts": [self["opt_obj_dict"],[self["vib_obj_dict"]]],
"out_names": ["opt.xyz",["vib.json"]],"future_check_symms": [True,False], "label": "TS"+str(index)+"_"+rxn_name})
cfw = Firework([ctask],name="TS"+str(index)+"_"+rxn_name+"_collect",spec={"_allow_fizzled_parents": True, "_priority": 5})
newwf = Workflow([cfw],name='rxn_'+str(index)+str(rxn_name))
return FWAction(detours=newwf) #using detour allows us to inherit children from the original collect to the subsequent collects
else:
return FWAction()

Expand Down
Loading