Skip to content

Commit

Permalink
Report electronic energy in an output file (#708)
Browse files Browse the repository at this point in the history
1. Add the "report_e_elect" as the argument/attribute, and method
"save_e_elect" to decide whether electronic energy will be in the output
or not, after the single-point energy calculation.
2. A test case is also added for this purpose to check if
e_elect_summary.yml is created and have the electronic energy info
  • Loading branch information
alongd authored Oct 23, 2023
2 parents 067e76c + 4fcf5c6 commit 6b51ce5
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
8 changes: 8 additions & 0 deletions arc/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ class ARC(object):
Only used for restarting.
running_jobs (dict, optional): A dictionary of jobs submitted in a precious ARC instance, used for restarting.
ts_adapters (list, optional): Entries represent different TS adapters.
report_e_elect (bool, optional): Whether to report electronic energy. Default is ``False``.
Attributes:
project (str): The project's name. Used for naming the working directory.
Expand Down Expand Up @@ -221,6 +222,8 @@ class ARC(object):
format (``True``) or classical two-parameter Arrhenius equation format (``False``).
trsh_ess_jobs (bool): Whether to attempt troubleshooting failed ESS jobs. Default is ``True``.
ts_adapters (list): Entries represent different TS adapters.
report_e_elect (bool): Whether to report electronic energy.
"""

def __init__(self,
Expand Down Expand Up @@ -269,6 +272,7 @@ def __init__(self,
ts_adapters: List[str] = None,
ts_guess_level: Optional[Union[str, dict, Level]] = None,
verbose=logging.INFO,
report_e_elect: Optional[bool] = False,
):

if project is None:
Expand Down Expand Up @@ -320,6 +324,7 @@ def __init__(self,
self.arkane_level_of_theory = Level(repr=arkane_level_of_theory) if arkane_level_of_theory is not None else None
self.freq_scale_factor = freq_scale_factor
self.ts_adapters = ts_adapters
self.report_e_elect = report_e_elect
for ts_adapter in self.ts_adapters or list():
if ts_adapter.lower() not in _registered_job_adapters.keys():
raise InputError(f'Unknown TS adapter: "{ts_adapter}"')
Expand Down Expand Up @@ -526,6 +531,8 @@ def as_dict(self) -> dict:
if not isinstance(self.ts_guess_level, (dict, str)) else self.ts_guess_level
if self.verbose != logging.INFO:
restart_dict['verbose'] = int(self.verbose)
if self.report_e_elect:
restart_dict['report_e_elect'] = self.report_e_elect
return restart_dict

def write_input_file(self, path=None):
Expand Down Expand Up @@ -592,6 +599,7 @@ def execute(self) -> dict:
trsh_ess_jobs=self.trsh_ess_jobs,
fine_only=self.fine_only,
ts_adapters=self.ts_adapters,
report_e_elect=self.report_e_elect,
)

save_yaml_file(path=os.path.join(self.project_directory, 'output', 'status.yml'), content=self.scheduler.output)
Expand Down
20 changes: 20 additions & 0 deletions arc/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
get_logger,
get_number_with_ordinal_indicator,
is_angle_linear,
read_yaml_file,
safe_copy_file,
save_yaml_file,
sort_two_lists_by_the_first,
Expand Down Expand Up @@ -160,6 +161,7 @@ class Scheduler(object):
freq_scale_factor (float, optional): The harmonic frequencies scaling factor.
trsh_ess_jobs (bool, optional): Whether to attempt troubleshooting failed ESS jobs. Default is ``True``.
ts_adapters (list, optional): Entries represent different TS adapters.
report_e_elect (bool, optional): Whether to report electronic energy. Default is ``False``.
Attributes:
project (str): The project's name. Used for naming the working directory.
Expand Down Expand Up @@ -214,6 +216,7 @@ class Scheduler(object):
freq_scale_factor (float): The harmonic frequencies scaling factor.
trsh_ess_jobs (bool): Whether to attempt troubleshooting failed ESS jobs. Default is ``True``.
ts_adapters (list): Entries represent different TS adapters.
report_e_elect (bool): Whether to report electronic energy.
"""

def __init__(self,
Expand Down Expand Up @@ -248,6 +251,7 @@ def __init__(self,
kinetics_adapter: str = 'arkane',
freq_scale_factor: float = 1.0,
ts_adapters: List[str] = None,
report_e_elect: Optional[bool] = False,
) -> None:

self.project = project
Expand Down Expand Up @@ -279,6 +283,7 @@ def __init__(self,
self.ts_adapters = ts_adapters if ts_adapters is not None else default_ts_adapters
self.ts_adapters = [ts_adapter.lower() for ts_adapter in self.ts_adapters]
self.output = dict()
self.report_e_elect = report_e_elect

self.species_dict, self.rxn_dict = dict(), dict()
for species in self.species_list:
Expand Down Expand Up @@ -2552,6 +2557,9 @@ def post_sp_actions(self,
if species_has_freq(self.output[label], self.species_dict[label].yml_path):
self.check_rxn_e0_by_spc(label)

if self.report_e_elect:
self.save_e_elect(label)

# set *at the end* to differentiate between sp jobs when using complex solvation corrections
self.output[label]['job_types']['sp'] = True

Expand Down Expand Up @@ -3614,6 +3622,18 @@ def generate_final_ts_guess_report(self):
if content:
save_yaml_file(path=path, content=content)

def save_e_elect(self, label: str):
"""
Save the electronic energy of the corresponding species.
It will append if the file already exists.
"""
path = os.path.join(self.project_directory, 'output', 'e_elect_summary.yml')
content = dict()
if os.path.isfile(path):
content = read_yaml_file(path)
content[label] = self.species_dict[label].e_elect
save_yaml_file(path=path, content=content)


def species_has_freq(species_output_dict: dict,
yml_path: Optional[str] = None,
Expand Down
33 changes: 32 additions & 1 deletion arc/scheduler_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import arc.rmgdb as rmgdb
import arc.parser as parser
from arc.checks.ts import check_ts
from arc.common import ARC_PATH, almost_equal_coords_lists, initialize_job_types
from arc.common import ARC_PATH, almost_equal_coords_lists, initialize_job_types, read_yaml_file
from arc.job.factory import job_factory
from arc.level import Level
from arc.plotter import save_conformers_file
Expand Down Expand Up @@ -701,6 +701,37 @@ def test_check_rxn_e0_by_spc(self):
self.assertEqual(rxn.ts_species.ts_checks,
{'E0': True, 'e_elect': True, 'IRC': None, 'freq': True, 'normal_mode_displacement': True, 'warnings': ''})

def test_save_e_elect(self):
"""Test the save_e_elect() method."""
project_directory = os.path.join(ARC_PATH, 'Projects', 'save_e_elect')
e_elect_summary_path = os.path.join(project_directory, 'output', 'e_elect_summary.yml')
self.assertFalse(os.path.isfile(os.path.join(project_directory, 'output', 'e_elect_summary.yml')))
sched = Scheduler(project='test_save_e_elect',
ess_settings=self.ess_settings,
project_directory=project_directory,
species_list=[ARCSpecies(label='formaldehyde', smiles='C=O'),
ARCSpecies(label='mehylamine', smiles='CN')],
freq_scale_factor=1.0,
opt_level=Level(method='B3LYP', basis='6-31G(d,p)', software='gaussian'),
sp_level=Level(method='B3LYP', basis='6-31G(d,p)', software='gaussian'),
job_types={'opt': True, 'fine_grid': False, 'freq': False, 'sp': True, 'rotors': False,
'conformers': False, 'irc': False},
report_e_elect=True,
testing=True,
)
sched.post_sp_actions(label='formaldehyde',
sp_path=os.path.join(ARC_PATH, 'arc', 'testing', 'sp', 'formaldehyde_sp_terachem_output.out'))
self.assertTrue(os.path.isfile(e_elect_summary_path))
content = read_yaml_file(e_elect_summary_path)
self.assertEqual(content, {'formaldehyde': -300621.95378630824})

sched.post_sp_actions(label='mehylamine',
sp_path=os.path.join(ARC_PATH, 'arc', 'testing', 'sp', 'mehylamine_CCSD(T).out'))
content = read_yaml_file(e_elect_summary_path)
self.assertEqual(content, {'formaldehyde': -300621.95378630824,
'mehylamine': -251377.49160993524})
shutil.rmtree(project_directory, ignore_errors=True)

def test_species_has_geo_sp_freq(self):
"""Test the species_has_geo() / species_has_sp() / species_has_freq() functions."""
for property_, species_has_property in zip(['geo', 'sp', 'freq'], [species_has_geo, species_has_sp, species_has_freq]):
Expand Down

0 comments on commit 6b51ce5

Please sign in to comment.