Skip to content

Commit

Permalink
Merge pull request #415 from ReactionMechanismGenerator/loop
Browse files Browse the repository at this point in the history
Delete a non-converged species from the running_jobs dict
  • Loading branch information
alongd committed Aug 3, 2020
2 parents 39c9669 + 74b6166 commit 9d53181
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 15 deletions.
12 changes: 8 additions & 4 deletions arc/job/trsh.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,13 +447,14 @@ def trsh_negative_freq(label: str,
neg_freqs_trshed = neg_freqs_trshed if neg_freqs_trshed is not None else list()
job_types = job_types if job_types is not None else ['rotors']
output_errors, output_warnings, conformers, current_neg_freqs_trshed = list(), list(), list(), list()
factor = 1.1
factor, factor_increase = 1.1, 0.2
max_times_to_trsh_neg_freq = 5
try:
freqs, normal_disp_modes = parse_normal_displacement_modes(path=log_file)
except NotImplementedError as e:
logger.error(f'Could not troubleshoot negative frequency for species {label}, got:\n{e}')
return [], [], output_errors, []
if len(neg_freqs_trshed) > 10:
if len(neg_freqs_trshed) > max_times_to_trsh_neg_freq:
logger.error(f'Species {label} was troubleshooted for negative frequencies too many times.')
if 'rotors' not in job_types:
logger.error('The rotor scans feature is turned off, '
Expand Down Expand Up @@ -483,7 +484,7 @@ def trsh_negative_freq(label: str,
elif len(neg_freqs_idx) == 1 and any([np.allclose(freqs[0], vf, rtol=1e-04, atol=1e-02)
for vf in neg_freqs_trshed]):
# species has one negative frequency, and has been troubleshooted for it before
factor = 1 + 0.1 * (len(neg_freqs_trshed) + 1)
factor = 1 + factor_increase * (len(neg_freqs_trshed) + 1)
logger.info(f'Species {label} has a negative frequency ({freqs[largest_neg_freq_idx]}) for the '
f'{len(neg_freqs_trshed)} time. Perturbing its geometry using the respective vibrational '
f'displacements, this time using a larger factor (x {factor})')
Expand Down Expand Up @@ -1317,6 +1318,7 @@ def scan_quality_check(label: str,
broken_bond_label = bond_change.sort_values().index[-1] # the largest change
# Freeze the bonds, no further freezing other ics to prevent over-constraining
broken_bonds = [scan_conformers['atoms'][broken_bond_label]]
invalidate = True
invalidation_reason = f'Bond ({broken_bonds}) broke during the scan.'
message = f'Rotor scan of {label} between pivots {pivots} has broken bonds: ' \
f'{broken_bonds}. ARC will attempt to troubleshoot this rotor scan.'
Expand Down Expand Up @@ -1345,16 +1347,18 @@ def scan_quality_check(label: str,
# 1.3 Check consistency
if 0 in changed_ic_dict.keys() and len(changed_ic_dict) == 1:
# Smooth scan with different initial and final conformer
invalidate = True
invalidation_reason = 'Inconsistent initial and final conformers'
message = f'Rotor scan of {label} between pivots {pivots} has inconsistent initial ' \
f'and final conformers. Internal coordinates {changed_ic_dict[0]} are different. ' \
f'and final conformers.\nInternal coordinates {changed_ic_dict[0]} are different. ' \
f'ARC will attempt to troubleshoot this rotor scan.'
logger.error(message)
actions = {'freeze': [scan_conformers['atoms'][ic_label]
for ic_label in changed_ic_dict[0]]}
return invalidate, invalidation_reason, message, actions
elif len(changed_ic_dict) > 0:
# Not smooth scan
invalidate = True
invalidation_reason = 'Significant difference observed between consecutive conformers'
message = f'Rotor scan of {label} between pivots {pivots} is inconsistent between ' \
f'two consecutive conformers.\nInconsistent consecutive conformers and problematic ' \
Expand Down
12 changes: 10 additions & 2 deletions arc/plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -985,8 +985,16 @@ def plot_torsion_angles(torsion_angles, torsions_sampling_points=None, wells_dic
return num_comb


def plot_1d_rotor_scan(angles=None, energies=None, results=None, path=None, scan=None, comment='', units='degrees',
original_dihedral=None, label=None):
def plot_1d_rotor_scan(angles=None,
energies=None,
results=None,
path=None,
scan=None,
comment='',
units='degrees',
original_dihedral=None,
label=None,
):
"""
Plots a 1D rotor PES for energy vs. angles. Either ``angles`` and ``energies`` or ``results`` must be given.
Expand Down
21 changes: 12 additions & 9 deletions arc/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ def schedule_jobs(self):
for label in self.unique_species_labels:
if self.output[label]['convergence'] is False:
# skip unconverged species
if label in self.running_jobs:
del self.running_jobs[label]
continue
# look for completed jobs and decide what jobs to run next
self.get_servers_jobs_ids() # updates `self.servers_jobs_ids`
Expand Down Expand Up @@ -1618,7 +1620,7 @@ def process_directed_scans(self, label, pivots):
'top': ``list``,
'scan': ``list``,
'number_of_running_jobs': ``int``,
'success': ``bool``,
'success': ``Optional[bool]``,
'invalidation_reason': ``str``,
'times_dihedral_set': ``int``,
'scan_path': <path to scan output file>,
Expand Down Expand Up @@ -2345,7 +2347,7 @@ def check_scan_job(self, label: str, job: Job) -> None:
'top': ``list``,
'scan': ``list``,
'number_of_running_jobs': ``int``,
'success': ``bool``,
'success': ``Optional[bool]``,
'invalidation_reason': ``str``,
'times_dihedral_set': ``int``,
'scan_path': <path to scan output file>,
Expand Down Expand Up @@ -2436,14 +2438,14 @@ def check_scan_job(self, label: str, job: Job) -> None:
else:
raise SchedulerError(f'Could not match rotor with pivots {job.pivots} in species {label}')

# This is a bad rotor scan, and we can do nothing about it at this moment.
if invalidate and not actions:
self.species_dict[label].rotors_dict[i]['success'] = False
# This is a bad rotor scan
if invalidate:
self.species_dict[label].rotors_dict[i]['success'] = None if len(actions) else False

# Better to save the path and invalidation reason for debugging and tracing the file
# if ``success`` is null, it means that the job is being troubleshot
# Better to save the path and invalidation reason for debugging and tracking the file
# if ``success`` is None, it means that the job is being troubleshooted
self.species_dict[label].rotors_dict[i]['scan_path'] = job.local_path_to_output_file
self.species_dict[label].rotors_dict[i]['invalidation_reason'] = invalidation_reason
self.species_dict[label].rotors_dict[i]['invalidation_reason'] += invalidation_reason

# If energies were obtained, draw the scan curve
if energies is not None and len(energies):
Expand Down Expand Up @@ -2479,7 +2481,8 @@ def check_directed_scan(self, label, pivots, scan, energies):
- adjust to ND, merge with check_directed_scan_job (this one isn't being called)
"""
# If the job has not converged, troubleshoot
invalidate, invalidation_reason, message, actions = scan_quality_check(label=label, pivots=pivots,
invalidate, invalidation_reason, message, actions = scan_quality_check(label=label,
pivots=pivots,
energies=energies)
if actions:
# the rotor scan is problematic, troubleshooting is required
Expand Down

0 comments on commit 9d53181

Please sign in to comment.