Skip to content

Commit

Permalink
Merge pull request #196 from avcopan/dev
Browse files Browse the repository at this point in the history
New: Adds PM3 semi-empirical method for Gaussian 16
  • Loading branch information
avcopan authored Sep 21, 2024
2 parents 650a78b + 8b126f0 commit d894175
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 30 deletions.
35 changes: 33 additions & 2 deletions elstruct/par.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def standard_case(name):
:type name: str
:rtype: str
"""
return name.lower()
return name.lower() if isinstance(name, str) else name


class Module():
Expand Down Expand Up @@ -101,6 +101,12 @@ class Method():
'hf', 'hf',
('R',), ('U', 'R'))})

class SemiEmpirical():
PM3 = ('pm3',
{Program.GAUSSIAN16: (
'pm3', 'pm3',
('R',), ('U', 'R'))})

class Corr():
""" Correlated method names """
MP2 = ('mp2',
Expand Down Expand Up @@ -353,6 +359,21 @@ def contains(cls, name):

return name in names

@classmethod
def is_semi_empirical(cls, name):
""" Assess if a method is a semi-empirical method.
:param cls: class object
:type cls: obj
:param name: name of method
:type name: str
"""

name = standard_case(name)
semi_emp_names = [row[0] for row in pclass.all_values(cls.SemiEmpirical)]

return name in semi_emp_names

@classmethod
def is_correlated(cls, name):
""" Assess if a method is a single-reference correlated method.
Expand Down Expand Up @@ -632,6 +653,16 @@ class Basis():
(name, {program: name})
"""
NONE = (None, {Program.CFOUR2: None,
Program.GAUSSIAN09: None,
Program.GAUSSIAN03: None,
Program.GAUSSIAN16: None,
Program.MOLPRO2015: None,
Program.MOLPRO2021: None,
Program.MRCC2018: None,
Program.NWCHEM6: None,
Program.ORCA4: None,
Program.PSI4: None})

STO3G = ('sto-3g', {Program.CFOUR2: None,
Program.GAUSSIAN09: None,
Expand Down Expand Up @@ -960,7 +991,7 @@ def is_nonstandard_basis(name):
:param name: name of basis set
:type name: str
"""
return name.lower().startswith('basis:')
return isinstance(name, str) and name.lower().startswith('basis:')

@classmethod
def nonstandard_basis_name(cls, name):
Expand Down
2 changes: 2 additions & 0 deletions elstruct/reader/_gaussian16/energ.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ def _doub_hyb_dft_energy(output_str):
ENERGY_READER_DCT[(METHOD, frozenset({}))] = _dft_energy
else:
ENERGY_READER_DCT[(METHOD, frozenset({}))] = _doub_hyb_dft_energy
elif Method.is_semi_empirical(METHOD):
ENERGY_READER_DCT[(METHOD, frozenset({}))] = _dft_energy

# Check if we have added any unsupported methods to the energy reader
READ_METHODS = set(method[0] for method in ENERGY_READER_DCT)
Expand Down
4 changes: 3 additions & 1 deletion elstruct/writer/_gaussian16/templates/all.mako
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ ${machine_options}
## 1. theoretical method block
% if reference:
#P ${reference} ${method}/${basis}
% else:
% elif basis:
#P ${method}/${basis}
% else:
#P ${method}
% endif
% if reference != 'rohf' and method != 'rohf':
# SCF=(xqc)
Expand Down
29 changes: 2 additions & 27 deletions elstruct/writer/fill.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,31 +126,6 @@ def _offset_planar_vals(val):
return geo_str, zmat_vval_str, zmat_cval_str


def _name_mat(zma, frozen_coordinates, job_key):
""" Build the name matrix for a Z-Matrix data structure:
used for cfour optimizations
:param zma: cartesian or z-matrix geometry
:type zma: tuple
:param frozen_coordinates: only with z-matrix geometries; list of
coordinate names to freeze
:type fozen_coordinates: tuple[str]
:param job_key: job contained in the inpit file
:type job_key: str
"""
if job_key == 'optimization':
name_mat = [
[name+'*'
if name is not None and name not in frozen_coordinates else name
for name in row]
for row in automol.zmat.name_matrix(zma)]
else:
name_mat = automol.zmat.name_matrix(zma)

return name_mat


def build_gen_lines(gen_lines, line1=None, line2=None, line3=None):
""" Set three lines for writing in various blocks of files.
Function either grabs lines from the dictionary and if nothing
Expand Down Expand Up @@ -300,7 +275,7 @@ def program_method_names(prog, method, basis, mult, orb_restricted):
elif method == Method.HF[0]:
if prog in (Program.GAUSSIAN09, Program.GAUSSIAN03,
Program.GAUSSIAN16):
prog_method = prog_reference
prog_method = prog_reference if prog_reference else method
else:
prog_method = program_method_name(prog, method, singlet=singlet)
else:
Expand Down Expand Up @@ -331,7 +306,7 @@ def _reference(prog, method, mult, orb_restricted):
:rtype: str
"""
# Need a multiref version
if Method.is_dft(method):
if Method.is_dft(method) or Method.is_semi_empirical(method):
reference = _dft_reference(prog, orb_restricted)
elif method == Method.HF[0]:
reference = _hf_reference(prog, mult, orb_restricted)
Expand Down

0 comments on commit d894175

Please sign in to comment.