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

Allow birad singlet to be defined and run as unrestricted #114

Merged
merged 4 commits into from
Apr 10, 2019
Merged
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
20 changes: 14 additions & 6 deletions arc/job/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ class Job(object):
`species_name` ``str`` The species/TS name. Used for naming the directory.
`charge` ``int`` The species net charge. Default is 0
`multiplicity` ``int`` The species multiplicity.
`number_of_radicals` ``int`` The number of radicals (inputted by the user, ARC won't attempt to determine
it). Defaults to None. Important, e.g., if a Species is a bi-rad singlet,
in which case the job should be unrestricted, but the multiplicity does not
have the required information to make that descision (r vs. u)
`spin` ``int`` The spin. automatically derived from the multiplicity
`xyz` ``str`` The xyz geometry. Used for the calculation
`n_atoms` ``int`` The number of atoms in self.xyz
Expand Down Expand Up @@ -88,7 +92,7 @@ def __init__(self, project, ess_settings, species_name, xyz, job_type, level_of_
project_directory, charge=0, conformer=-1, fine=False, shift='', software=None, is_ts=False, scan='',
pivots=None, memory=15000, comments='', trsh='', scan_trsh='', ess_trsh_methods=None, initial_trsh=None,
job_num=None, job_server_name=None, job_name=None, job_id=None, server=None, initial_time=None,
occ=None, max_job_time=120, scan_res=None, checkfile=None, testing=False):
occ=None, max_job_time=120, scan_res=None, checkfile=None, number_of_radicals=None, testing=False):
self.project = project
self.ess_settings = ess_settings
self.initial_time = initial_time
Expand All @@ -99,6 +103,7 @@ def __init__(self, project, ess_settings, species_name, xyz, job_type, level_of_
self.charge = charge
self.multiplicity = multiplicity
self.spin = self.multiplicity - 1
self.number_of_radicals = number_of_radicals
self.xyz = xyz
self.n_atoms = self.xyz.count('\n')
self.conformer = conformer
Expand Down Expand Up @@ -452,7 +457,8 @@ def write_input_file(self):
if self.software == 'gaussian' and not self.job_type == 'composite':
slash = '/'

if self.multiplicity > 1 and '/' in self.level_of_theory: # only applies for non-composite jobs
if (self.multiplicity > 1 and '/' in self.level_of_theory) or self.number_of_radicals > 1:
# don't add 'u' to composite jobs. Do add 'u' for bi-rad singlets if `number_of_radicals` > 1
if self.software == 'qchem':
restricted = 'True' # In QChem this attribute is "unrestricted"
else:
Expand Down Expand Up @@ -732,14 +738,16 @@ def _download_output_file(self):
if self.job_type == 'orbitals':
remote_file_path = os.path.join(self.remote_path, 'input.FChk')
ssh.download_file(remote_file_path=remote_file_path, local_file_path=self.local_path_to_orbitals_file)
if not os.path.isfile(self.local_path_to_orbitals_file):
logging.warning('Orbitals FChk file {0} was not downloaded properly'.format(self.job_name))
if not os.path.isfile(self.local_path_to_orbitals_file):
logging.warning('Orbitals FChk file {0} was not downloaded properly '
'(this is not the Gaussian formatted check file...)'.format(self.job_name))

# download Gaussian check file
if self.software.lower() == 'gaussian':
remote_check_file_path = os.path.join(self.remote_path, 'check.chk')
local_check_file_path = os.path.join(self.local_path, 'check.chk')
ssh.download_file(remote_file_path=remote_check_file_path, local_file_path=local_check_file_path)
ssh.download_file(remote_file_path=remote_check_file_path, local_file_path=self.local_path_to_check_file)
if not os.path.isfile(self.local_path_to_check_file):
logging.warning('Gaussian check file {0} was not downloaded properly'.format(self.job_name))

def run(self):
"""Execute the Job"""
Expand Down
6 changes: 4 additions & 2 deletions arc/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,8 @@ def run_job(self, label, xyz, level_of_theory, job_type, fine=False, software=No
shift=shift, software=software, is_ts=species.is_ts, memory=memory, trsh=trsh,
ess_trsh_methods=ess_trsh_methods, scan=scan, pivots=pivots, occ=occ, initial_trsh=self.initial_trsh,
project_directory=self.project_directory, max_job_time=max_job_time, scan_trsh=scan_trsh,
scan_res=scan_res, conformer=conformer, checkfile=checkfile)
scan_res=scan_res, conformer=conformer, checkfile=checkfile,
number_of_radicals=species.number_of_radicals)
if job.software is not None:
if conformer < 0:
# this is NOT a conformer job
Expand Down Expand Up @@ -1710,7 +1711,8 @@ def restore_running_jobs(self):
initial_time=job_description['initial_time'], conformer=conformer,
software=job_description['software'], comments=job_description['comments'],
scan_trsh=job_description['scan_trsh'], initial_trsh=job_description['initial_trsh'],
max_job_time=job_description['max_job_time'], scan_res=job_description['scan_res'])
max_job_time=job_description['max_job_time'], scan_res=job_description['scan_res'],
number_of_radicals=species.number_of_radicals)
if spc_label not in self.job_dict:
self.job_dict[spc_label] = dict()
if job_description['job_type'] not in self.job_dict[spc_label]:
Expand Down
10 changes: 9 additions & 1 deletion arc/species/species.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class ARCSpecies(object):
`multiplicity` ``int`` The species' multiplicity. Can be determined from adjlist/smiles/xyz
The algorithm assumes it's either a singlet or a doublet
`charge` ``int'' The species' net charge. Assumed to be 0 be default.
`number_of_radicals` ``int`` The number of radicals (inputted by the user, ARC won't attempt to determine
it). Defaults to None. Important, e.g., if a Species is a bi-rad singlet,
in which case the job should be unrestricted, but the multiplicity does not
have the required information to make that descision (r vs. u)
`e0` ``float`` The total electronic energy E0 of the species at the chosen sp level (kJ/mol)
`is_ts` ``bool`` Whether or not the species represents a transition state
`number_of_rotors` ``int`` The number of potential rotors to scan
Expand Down Expand Up @@ -111,7 +115,7 @@ class ARCSpecies(object):
def __init__(self, is_ts=False, rmg_species=None, mol=None, label=None, xyz=None, multiplicity=None, charge=None,
smiles='', adjlist='', inchi='', bond_corrections=None, generate_thermo=True, species_dict=None,
yml_path=None, ts_methods=None, ts_number=None, rxn_label=None, external_symmetry=None,
optical_isomers=None, run_time=None, checkfile=None):
optical_isomers=None, run_time=None, checkfile=None, number_of_radicals=None):
self.t1 = None
self.ts_number = ts_number
self.conformers = list()
Expand All @@ -125,6 +129,7 @@ def __init__(self, is_ts=False, rmg_species=None, mol=None, label=None, xyz=None
self.mol = mol
self.mol_list = None
self.multiplicity = multiplicity
self.number_of_radicals = number_of_radicals
self.external_symmetry = external_symmetry
self.optical_isomers = optical_isomers
self.charge = charge
Expand Down Expand Up @@ -316,6 +321,8 @@ def as_dict(self):
species_dict['label'] = self.label
species_dict['long_thermo_description'] = self.long_thermo_description
species_dict['multiplicity'] = self.multiplicity
if self.number_of_radicals is not None:
species_dict['number_of_radicals'] = self.number_of_radicals
species_dict['charge'] = self.charge
species_dict['generate_thermo'] = self.generate_thermo
if self.opt_level is not None:
Expand Down Expand Up @@ -407,6 +414,7 @@ def from_dict(self, species_dict):
self.generate_thermo = False
else:
self.generate_thermo = species_dict['generate_thermo'] if 'generate_thermo' in species_dict else True
self.number_of_radicals = species_dict['number_of_radicals'] if 'number_of_radicals' in species_dict else None
self.opt_level = species_dict['opt_level'] if 'opt_level' in species_dict else None
self.number_of_rotors = species_dict['number_of_rotors'] if 'number_of_rotors' in species_dict else 0
self.rotors_dict = species_dict['rotors_dict'] if 'rotors_dict' in species_dict else dict()
Expand Down