From b83829caa9db63d858cedcc76319c1cc9304e573 Mon Sep 17 00:00:00 2001 From: Calvin Date: Sat, 24 Aug 2024 16:25:51 +0300 Subject: [PATCH] Updates --- arc/job/adapters/gaussian.py | 18 +++++++++++++----- arc/job/adapters/gaussian_test.py | 20 ++++++++++---------- arc/job/trsh.py | 16 ++++++++-------- arc/job/trsh_test.py | 3 ++- arc/scheduler.py | 5 +++-- 5 files changed, 36 insertions(+), 26 deletions(-) diff --git a/arc/job/adapters/gaussian.py b/arc/job/adapters/gaussian.py index 8f05d32450..d87e0047ec 100644 --- a/arc/job/adapters/gaussian.py +++ b/arc/job/adapters/gaussian.py @@ -267,17 +267,25 @@ def write_input_file(self) -> None: self.level.method = 'cbs-qb3' # Job type specific options - max_c = self.args['trsh'].split()[1] if 'max_cycles' in self.args['trsh'] else 100 + max_c = 100 + if 'trsh' in self.args and 'trsh' in self.args['trsh']: + for item in self.args['trsh']['trsh']: + match = re.search(r'maxcycle=(\d+)', item) + if match: + max_c = int(match.group(1)) + break + + if self.job_type in ['opt', 'conformers', 'optfreq', 'composite']: - keywords = ['ts', 'calcfc', 'noeigentest', f'maxcycles={max_c}'] if self.is_ts else ['calcfc'] + keywords = ['ts', 'calcfc', 'noeigentest', f'maxcycle={max_c}'] if self.is_ts else ['calcfc'] if self.level.method in ['rocbs-qb3']: # There are no analytical 2nd derivatives (FC) for this method. - keywords = ['ts', 'noeigentest', 'maxcycles=100'] if self.is_ts else [] + keywords = ['ts', 'noeigentest', f'maxcycle={max_c}'] if self.is_ts else [] if self.fine: if self.level.method_type in ['dft', 'composite']: # Note that the Acc2E argument is not available in Gaussian03 input_dict['fine'] = f'integral=(grid=ultrafine, {integral_algorithm})' - # input_dict['trsh'] may have scf=(...) in it, so we need to add the tight and direct keywords to it + # input_dict['trsh'] may have scf=(...) in it, so we need to add the tight and direct keywords to it scf_start = input_dict['trsh'].find('scf=(') scf_end = input_dict['trsh'].find(')', scf_start) scf_fine_content = 'tight,direct' @@ -295,7 +303,7 @@ def write_input_file(self) -> None: if self.is_ts: keywords.extend(['tight', 'maxstep=5']) else: - keywords.extend(['tight', 'maxstep=5']) + keywords.extend(['tight', 'maxstep=5', f'maxcycle={max_c}']) input_dict['job_type_1'] = "opt" if self.level.method_type not in ['dft', 'composite', 'wavefunction']\ else f"opt=({', '.join(key for key in keywords)})" diff --git a/arc/job/adapters/gaussian_test.py b/arc/job/adapters/gaussian_test.py index 162f5fde6f..3ca85821a1 100644 --- a/arc/job/adapters/gaussian_test.py +++ b/arc/job/adapters/gaussian_test.py @@ -789,7 +789,7 @@ def test_trsh_write_input_file(self): %mem=14336mb %NProcShared=8 -#P opt=(calcfc,maxstep=5,tight) uwb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) scf=(direct,tight) +#P opt=(calcfc,maxcycle=100,maxstep=5,tight) uwb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) scf=(direct,tight) anion @@ -807,7 +807,7 @@ def test_trsh_write_input_file(self): %mem=14336mb %NProcShared=8 -#P opt=(calcfc,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) scf=(direct,tight) +#P opt=(calcfc,maxcycle=100,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) scf=(direct,tight) ethanol @@ -833,7 +833,7 @@ def test_trsh_write_input_file(self): %mem=14336mb %NProcShared=8 -#P opt=(calcfc,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) nosymm scf=(direct,tight,xqc) +#P opt=(calcfc,maxcycle=100,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) nosymm scf=(direct,tight,xqc) ethanol @@ -859,7 +859,7 @@ def test_trsh_write_input_file(self): %mem=14336mb %NProcShared=8 -#P opt=(calcfc,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) nosymm scf=(NDamp=30,direct,tight,xqc) +#P opt=(calcfc,maxcycle=100,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) nosymm scf=(NDamp=30,direct,tight,xqc) ethanol @@ -885,7 +885,7 @@ def test_trsh_write_input_file(self): %mem=14336mb %NProcShared=8 -#P opt=(calcfc,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) nosymm scf=(NDamp=30,NoDIIS,direct,tight,xqc) +#P opt=(calcfc,maxcycle=100,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) nosymm scf=(NDamp=30,NoDIIS,direct,tight,xqc) ethanol @@ -911,7 +911,7 @@ def test_trsh_write_input_file(self): %mem=14336mb %NProcShared=8 -#P opt=(calcfc,cartesian,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) nosymm scf=(NDamp=30,NoDIIS,direct,tight,xqc) +#P opt=(calcfc,cartesian,maxcycle=100,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) nosymm scf=(NDamp=30,NoDIIS,direct,tight,xqc) ethanol @@ -991,7 +991,7 @@ def test_trsh_write_input_file(self): %mem=14336mb %NProcShared=8 -#P opt=(calcfc,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) int=grid=300590 scf=(direct,tight) +#P opt=(calcfc,maxcycle=100,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) int=grid=300590 scf=(direct,tight) ethanol @@ -1017,7 +1017,7 @@ def test_trsh_write_input_file(self): %mem=14336mb %NProcShared=8 -#P opt=(calcfc,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) nosymm scf=(Fermi,NDamp=30,NoDIIS,NoVarAcc,Noincfock,direct,tight,xqc) +#P opt=(calcfc,maxcycle=100,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) nosymm scf=(Fermi,NDamp=30,NoDIIS,NoVarAcc,Noincfock,direct,tight,xqc) ethanol @@ -1043,7 +1043,7 @@ def test_trsh_write_input_file(self): %mem=14336mb %NProcShared=8 -#P opt=(calcfc,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) scf=(NDamp=30,NoDIIS,NoVarAcc,direct,tight,xqc) +#P opt=(calcfc,maxcycle=100,maxstep=5,tight) guess=mix wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) scf=(NDamp=30,NoDIIS,NoVarAcc,direct,tight,xqc) ethanol @@ -1070,7 +1070,7 @@ def test_trsh_write_input_file(self): %mem=14336mb %NProcShared=8 -#P opt=(calcfc,maxstep=5,tight) guess=INDO wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) int=grid=300590 scf=(NDamp=30,NoDIIS,NoVarAcc,direct,tight,xqc) +#P opt=(calcfc,maxcycle=100,maxstep=5,tight) guess=INDO wb97xd integral=(grid=ultrafine, Acc2E=14) IOp(2/9=2000) int=grid=300590 scf=(NDamp=30,NoDIIS,NoVarAcc,direct,tight,xqc) ethanol diff --git a/arc/job/trsh.py b/arc/job/trsh.py index a3736fcd57..03697472b6 100644 --- a/arc/job/trsh.py +++ b/arc/job/trsh.py @@ -4,11 +4,11 @@ import math import os -import re from typing import List, Optional, Tuple, Union import numpy as np import pandas as pd +import re from arc.common import (check_torsion_change, convert_to_hours, @@ -18,19 +18,18 @@ get_number_with_ordinal_indicator, is_same_pivot, is_same_sequence_sublist, - is_str_float, + is_str_float ) from arc.exceptions import InputError, SpeciesError, TrshError from arc.imports import settings +from arc.level import Level from arc.job.local import execute_command from arc.job.ssh import SSHClient -from arc.level import Level from arc.species import ARCSpecies from arc.species.conformers import determine_smallest_atom_index_in_scan -from arc.species.converter import displace_xyz, ics_to_scan_constraints +from arc.species.converter import (displace_xyz, ics_to_scan_constraints) from arc.species.species import determine_rotor_symmetry from arc.species.vectors import calculate_dihedral_angle, calculate_distance - from arc.parser import (parse_1d_scan_coords, parse_normal_mode_displacement, parse_scan_args, @@ -38,6 +37,7 @@ parse_xyz_from_file, ) + logger = get_logger() @@ -947,6 +947,7 @@ def trsh_ess_job(label: str, if attempted_ess_trsh_methods: if attempted_ess_trsh_methods == ess_trsh_methods: logger.info(f'{logger_phrase} was not successful. Already attempted all possible troubleshooting methods. Will not troubleshoot again.') + ess_trsh_methods.append("all_attempted") couldnt_trsh = True else: if logger_info: @@ -1543,9 +1544,8 @@ def scan_quality_check(label: str, # Find the dihedrals in degrees of the lowest conformer: min_index = np.argmin(energies) conf_xyzs = parse_1d_scan_coords(log_file) - if len(conf_xyzs) > min_index: - actions = {'change conformer': conf_xyzs[min_index]} - return invalidate, invalidation_reason, message, actions + actions = {'change conformer': conf_xyzs[min_index]} + return invalidate, invalidation_reason, message, actions # 1.3 Check consistency if 0 in changed_ic_dict.keys() and len(changed_ic_dict) == 1: diff --git a/arc/job/trsh_test.py b/arc/job/trsh_test.py index 497512f477..4ef65d1508 100644 --- a/arc/job/trsh_test.py +++ b/arc/job/trsh_test.py @@ -423,7 +423,7 @@ def test_trsh_ess_job(self): num_heavy_atoms, cpu_cores, ess_trsh_methods) self.assertTrue(couldnt_trsh) self.assertIn( - "Error: Could not troubleshoot opt for ethanol! Tried troubleshooting with the following methods: ['scf=(NoDIIS)', 'int=(Acc2E=14)', 'checkfile=None', 'scf=(qc)', 'NoSymm', 'scf=(NDamp=30)', 'guess=INDO', 'scf=(Fermi)', 'scf=(Noincfock)', 'scf=(NoVarAcc)']; ", + "Error: Could not troubleshoot opt for ethanol! Tried troubleshooting with the following methods: ['scf=(NoDIIS)', 'int=(Acc2E=14)', 'checkfile=None', 'scf=(qc)', 'NoSymm', 'scf=(NDamp=30)', 'guess=INDO', 'scf=(Fermi)', 'scf=(Noincfock)', 'scf=(NoVarAcc)', 'all_attempted']; ", output_errors, ) @@ -545,6 +545,7 @@ def test_trsh_ess_job(self): memory, shift, cpu_cores, couldnt_trsh = trsh.trsh_ess_job(label, level_of_theory, server, job_status, job_type, software, fine, memory_gb, num_heavy_atoms, cpu_cores, ess_trsh_methods) + self.assertIn('all_attempted', ess_trsh_methods) self.assertTrue(couldnt_trsh) # Test Q-Chem diff --git a/arc/scheduler.py b/arc/scheduler.py index dc2435cf67..d779aa6b18 100644 --- a/arc/scheduler.py +++ b/arc/scheduler.py @@ -3355,12 +3355,13 @@ def troubleshoot_opt_jobs(self, label): if previous_job_num >= 0 and job.fine: previous_job = self.job_dict[label]['opt']['opt_a' + str(previous_job_num)] if not previous_job.fine and previous_job.job_status[0] == 'done' \ - and previous_job.job_status[1]['status'] == 'done': + and previous_job.job_status[1]['status'] == 'done' \ + and 'all_attempted' not in job.ess_trsh_methods: # The present job with a fine grid failed in the ESS calculation. # A *previous* job without a fine grid terminated successfully on the server and ESS. # So use the xyz determined w/o the fine grid, and output an error message to alert users. logger.error(f'Optimization job for {label} with a fine grid terminated successfully ' - f'on the server, but crashed during calculation. NOT running with fine ' + f'on the server, but crashed during calculation after troubleshooting. NOT running with fine ' f'grid again.') self.parse_opt_geo(label=label, job=previous_job) trsh_opt = False