Skip to content

Commit

Permalink
disp: propagate dispersion citations
Browse files Browse the repository at this point in the history
  • Loading branch information
loriab committed Oct 25, 2018
1 parent 60da95c commit fde5917
Show file tree
Hide file tree
Showing 9 changed files with 327 additions and 305 deletions.
34 changes: 25 additions & 9 deletions psi4/driver/procrouting/dft_funcs/dict_builder.py
Expand Up @@ -71,7 +71,7 @@
"dispersion": { definition of dispersion corrections "dispersion": { definition of dispersion corrections
"type": "", dispersion type - "d2", "d3zero", "d3bj" etc., see empirical_dispersion.py "type": "", dispersion type - "d2", "d3zero", "d3bj" etc., see empirical_dispersion.py
"params": {}, parameters for the dispersion correction "params": {}, parameters for the dispersion correction
"citation": "", special reference for the dispersion correction, appended to output "citation": "", special reference for the dispersion correction parameters, appended to output
}, },
} }
""" """
Expand Down Expand Up @@ -122,8 +122,7 @@ def get_functional_aliases(functional_dict):
# if the parent functional is already dispersion corrected, skip to next # if the parent functional is already dispersion corrected, skip to next
if "dispersion" in dict_functionals[functional_name]: if "dispersion" in dict_functionals[functional_name]:
disp = dict_functionals[functional_name]['dispersion'] disp = dict_functionals[functional_name]['dispersion']
dashcoeff_supplement[disp['type']]['definitions'][functional_name] = disp['params'] dashcoeff_supplement[disp['type']]['definitions'][functional_name] = disp
# TODO still needs citation
# this is to "bless" dft_funcs dispersion definitions # this is to "bless" dft_funcs dispersion definitions
continue continue


Expand All @@ -134,13 +133,8 @@ def get_functional_aliases(functional_dict):
if dispersion_functional.lower() in functional_aliases: if dispersion_functional.lower() in functional_aliases:
func = copy.deepcopy(dict_functionals[functional_name]) func = copy.deepcopy(dict_functionals[functional_name])
func["name"] += "-" + resolved_dispersion_level func["name"] += "-" + resolved_dispersion_level
func["dispersion"] = dict() func["dispersion"] = copy.deepcopy(intf_dftd3.dashcoeff[resolved_dispersion_level]['definitions'][dispersion_functional])

# we need to pop the citation as the EmpiricalDispersion class only expects dashparams
if "citation" in intf_dftd3.dashcoeff[resolved_dispersion_level]['definitions'][dispersion_functional]:
func["dispersion"]["citation"] = intf_dftd3.dashcoeff[resolved_dispersion_level]['definitions'][dispersion_functional].pop("citation")
func["dispersion"]["type"] = resolved_dispersion_level func["dispersion"]["type"] = resolved_dispersion_level
func["dispersion"]["params"] = intf_dftd3.dashcoeff[resolved_dispersion_level]['definitions'][dispersion_functional]


# this ensures that M06-2X-D3, M06-2X-D3ZERO, M062X-D3 or M062X-D3ZERO # this ensures that M06-2X-D3, M06-2X-D3ZERO, M062X-D3 or M062X-D3ZERO
# all point to the same method (M06-2X-D3ZERO) # all point to the same method (M06-2X-D3ZERO)
Expand Down Expand Up @@ -202,6 +196,28 @@ def check_consistency(func_dictionary):
raise ValidationError( raise ValidationError(
"SCF: Libxc parameters requested for an exchange functional not defined as a component of %s." % (name)) "SCF: Libxc parameters requested for an exchange functional not defined as a component of %s." % (name))


# 3) checks would be caught at runtime or involve only formatting.
# included here to preempt driver definition problems, if specific fctl not in tests.
# 3a) check formatting for citation
if "citation" in func_dictionary:
cit = func_dictionary["citation"]
if cit and not (cit.startswith(' ') and cit.endswith('\n')):
raise ValidationError("SCF: All citations should have the form ' A. Student, B. Prof, J. Goodstuff Vol, Page, Year\n', not : {}".format(cit))
if "dispersion" in func_dictionary:
disp = func_dictionary["dispersion"]
# 3b) check dispersion type present and known
if "type" not in disp or disp["type"] not in _dispersion_aliases:
raise ValidationError("SCF: Dispersion type ({}) should be among ({})".format(disp['type'], _dispersion_aliases.keys()))
# 3c) check dispersion params complete
allowed_params = sorted(intf_dftd3.dashcoeff[_dispersion_aliases[disp["type"]]]["default"].keys())
if "params" not in disp or sorted(disp["params"].keys()) != allowed_params:
raise ValidationError("SCF: Dispersion params ({}) must include all ({})".format(list(disp['params'].keys()), allowed_params))
# 3d) check formatting for dispersion citation
if "citation" in disp:
cit = disp["citation"]
if cit and not (cit.startswith(' ') and cit.endswith('\n')):
raise ValidationError("SCF: All citations should have the form ' A. Student, B. Prof, J. Goodstuff Vol, Page, Year\n', not : {}".format(cit))



def build_superfunctional_from_dictionary(func_dictionary, npoints, deriv, restricted): def build_superfunctional_from_dictionary(func_dictionary, npoints, deriv, restricted):
""" """
Expand Down
4 changes: 2 additions & 2 deletions psi4/driver/procrouting/dft_funcs/dict_gga_funcs.py
Expand Up @@ -166,8 +166,8 @@
"GGA_C_P86": {} "GGA_C_P86": {}
}, },
"citation": "citation":
' A. D. Becke, Phys. Rev. A, 38, 3098-3100, 1988\n' + \ ' A. D. Becke, Phys. Rev. A, 38, 3098-3100, 1988\n' + \
' J. P. Perdew, Phys. Rev. B, 33, 8822, 1986\n', ' J. P. Perdew, Phys. Rev. B, 33, 8822, 1986\n',
"description": "description":
' BP86 GGA Exchange-Correlation Functional\n', ' BP86 GGA Exchange-Correlation Functional\n',
}) })
Expand Down
6 changes: 3 additions & 3 deletions psi4/driver/procrouting/dft_funcs/dict_mgga_funcs.py
Expand Up @@ -146,7 +146,7 @@
"MGGA_C_TPSS": {} "MGGA_C_TPSS": {}
}, },
"description": ' TPSS Meta-GGA XC Functional\n', "description": ' TPSS Meta-GGA XC Functional\n',
"citation": ' J. Tao, et al., Phys. Rev. Lett., 91, 146401, 2003\n', "citation": ' J. Tao, et al., Phys. Rev. Lett., 91, 146401, 2003\n',
}) })


funcs.append({ funcs.append({
Expand All @@ -158,7 +158,7 @@
"MGGA_C_REVTPSS": {} "MGGA_C_REVTPSS": {}
}, },
"description": ' revised TPSS Meta-GGA XC Functional\n', "description": ' revised TPSS Meta-GGA XC Functional\n',
"citation": ' J. Sun et. al., Phys. Rev. B, 84, 035117, 2011\n', "citation": ' J. Sun et. al., Phys. Rev. B, 84, 035117, 2011\n',
}) })


funcs.append({ funcs.append({
Expand All @@ -170,7 +170,7 @@
"MGGA_C_PKZB": {} "MGGA_C_PKZB": {}
}, },
"description": ' PKZB Meta-GGA XC Functional\n', "description": ' PKZB Meta-GGA XC Functional\n',
"citation": ' J.P. Perdew, S. Kurth, A. Zupan, P. Blaha, Phys. Rev. Lett. 82, 2544, 1999\n', "citation": ' J.P. Perdew, S. Kurth, A. Zupan, P. Blaha, Phys. Rev. Lett. 82, 2544, 1999\n',
}) })


funcs.append({ funcs.append({
Expand Down
8 changes: 4 additions & 4 deletions psi4/driver/procrouting/dft_funcs/dict_xc_funcs.py
Expand Up @@ -37,9 +37,9 @@
funcs.append({"name": "TETER93" , "xc_functionals": {"LDA_XC_TETER93" : {}}}) funcs.append({"name": "TETER93" , "xc_functionals": {"LDA_XC_TETER93" : {}}})
funcs.append({"name": "ZLP" , "xc_functionals": {"LDA_XC_ZLP" : {}}}) funcs.append({"name": "ZLP" , "xc_functionals": {"LDA_XC_ZLP" : {}}})
funcs.append({"name": "KSDT" , "xc_functionals": {"LDA_XC_KSDT" : {}}}) funcs.append({"name": "KSDT" , "xc_functionals": {"LDA_XC_KSDT" : {}}})
funcs.append({"name": "OPBE-D" , "xc_functionals": {"GGA_XC_OPBE_D" : {}}, "dispersion": {"type": "d2", "params": {'s6': 1.0, 'alpha6': 20.0, 'sr6': 1.15}, "citation": ' L. Goerigk, S. Grimme, J. Chem. Theory. Comput. 6, 107-126, 2010'}}) funcs.append({"name": "OPBE-D" , "xc_functionals": {"GGA_XC_OPBE_D" : {}}, "dispersion": {"type": "d2", "params": {'s6': 1.0, 'alpha6': 20.0, 'sr6': 1.15}, "citation": ' L. Goerigk, S. Grimme, J. Chem. Theory. Comput. 6, 107-126, 2010\n'}, 'alias': ['OPBE-D2']})
funcs.append({"name": "OPWLYP-D" , "xc_functionals": {"GGA_XC_OPWLYP_D" : {}}, "dispersion": {"type": "d2", "params": {'s6': 1.0, 'alpha6': 20.0, 'sr6': 1.15}, "citation": ' L. Goerigk, S. Grimme, J. Chem. Theory. Comput. 6, 107-126, 2010'}}) funcs.append({"name": "OPWLYP-D" , "xc_functionals": {"GGA_XC_OPWLYP_D" : {}}, "dispersion": {"type": "d2", "params": {'s6': 1.0, 'alpha6': 20.0, 'sr6': 1.15}, "citation": ' L. Goerigk, S. Grimme, J. Chem. Theory. Comput. 6, 107-126, 2010\n'}, 'alias': ['OPWLYP-D2']})
funcs.append({"name": "OBLYP-D" , "xc_functionals": {"GGA_XC_OBLYP_D" : {}}, "dispersion": {"type": "d2", "params": {'s6': 1.0, 'alpha6': 20.0, 'sr6': 1.15}, "citation": ' L. Goerigk, S. Grimme, J. Chem. Theory. Comput. 6, 107-126, 2010'}}) funcs.append({"name": "OBLYP-D" , "xc_functionals": {"GGA_XC_OBLYP_D" : {}}, "dispersion": {"type": "d2", "params": {'s6': 1.0, 'alpha6': 20.0, 'sr6': 1.15}, "citation": ' L. Goerigk, S. Grimme, J. Chem. Theory. Comput. 6, 107-126, 2010\n'}, 'alias': ['OBLYP-D2']})
funcs.append({"name": "HCTH407P" , "xc_functionals": {"GGA_XC_HCTH_407P" : {}}}) funcs.append({"name": "HCTH407P" , "xc_functionals": {"GGA_XC_HCTH_407P" : {}}})
funcs.append({"name": "HCTHP76" , "xc_functionals": {"GGA_XC_HCTH_P76" : {}}}) funcs.append({"name": "HCTHP76" , "xc_functionals": {"GGA_XC_HCTH_P76" : {}}})
funcs.append({"name": "HCTHP14" , "xc_functionals": {"GGA_XC_HCTH_P14" : {}}}) funcs.append({"name": "HCTHP14" , "xc_functionals": {"GGA_XC_HCTH_P14" : {}}})
Expand Down Expand Up @@ -135,7 +135,7 @@
funcs.append({"name": "revTPSSh" , "xc_functionals": {"HYB_MGGA_XC_REVTPSSH" : {}}}) funcs.append({"name": "revTPSSh" , "xc_functionals": {"HYB_MGGA_XC_REVTPSSH" : {}}})
funcs.append({"name": "wB97M-V" , "xc_functionals": {"HYB_MGGA_XC_WB97M_V" : {}}, "alias": ["WB97MV"]}) funcs.append({"name": "wB97M-V" , "xc_functionals": {"HYB_MGGA_XC_WB97M_V" : {}}, "alias": ["WB97MV"]})
funcs.append({"name": "ZLP" , "xc_functionals": {"MGGA_XC_ZLP" : {}}}) funcs.append({"name": "ZLP" , "xc_functionals": {"MGGA_XC_ZLP" : {}}})
funcs.append({"name": "OTPSS-D" , "xc_functionals": {"MGGA_XC_OTPSS_D" : {}}, "dispersion": {"type": "d2", "params": {'s6': 1.0, 'alpha6': 20.0, 'sr6': 1.15}, "citation": ' L. Goerigk, S. Grimme, J. Chem. Theory. Comput. 6, 107-126, 2010'}}) funcs.append({"name": "OTPSS-D" , "xc_functionals": {"MGGA_XC_OTPSS_D" : {}}, "dispersion": {"type": "d2", "params": {'s6': 1.0, 'alpha6': 20.0, 'sr6': 1.15}, "citation": ' L. Goerigk, S. Grimme, J. Chem. Theory. Comput. 6, 107-126, 2010\n'}, 'alias': ['OTPSS-D2']})
funcs.append({"name": "TPSSLYP1W" , "xc_functionals": {"MGGA_XC_TPSSLYP1W" : {}}}) funcs.append({"name": "TPSSLYP1W" , "xc_functionals": {"MGGA_XC_TPSSLYP1W" : {}}})
funcs.append({"name": "B97M-V" , "xc_functionals": {"MGGA_XC_B97M_V" : {}}}) funcs.append({"name": "B97M-V" , "xc_functionals": {"MGGA_XC_B97M_V" : {}}})
funcs.append({"name": "B5050LYP" , "xc_functionals": {"HYB_GGA_XC_B5050LYP" : {}}}) funcs.append({"name": "B5050LYP" , "xc_functionals": {"HYB_GGA_XC_B5050LYP" : {}}})
Expand Down
45 changes: 17 additions & 28 deletions psi4/driver/procrouting/empirical_dispersion.py
Expand Up @@ -71,6 +71,10 @@ class EmpiricalDispersion(object):
dashlevel_citation : str dashlevel_citation : str
Literature reference for dispersion `dashlevel` in general, Literature reference for dispersion `dashlevel` in general,
*not necessarily* for `dashparams`. *not necessarily* for `dashparams`.
dashparams_citation : str
Literature reference for dispersion parameters, if `dashparams`
corresponds to a defined, named, untweaked "functional-dashlevel"
set with a citation. Otherwise, empty string.
dashcoeff_supplement : dict dashcoeff_supplement : dict
See description in `qcdb.intf_dftd3.dashparam.from_arrays`. Used See description in `qcdb.intf_dftd3.dashparam.from_arrays`. Used
here to "bless" the dispersion definitions attached here to "bless" the dispersion definitions attached
Expand Down Expand Up @@ -127,6 +131,7 @@ def __init__(self, name_hint=None, level_hint=None, param_tweaks=None, **kwargs)
self.description = intf_dftd3.dashcoeff[self.dashlevel]['description'] self.description = intf_dftd3.dashcoeff[self.dashlevel]['description']
self.ordered_params = intf_dftd3.dashcoeff[self.dashlevel]['default'].keys() self.ordered_params = intf_dftd3.dashcoeff[self.dashlevel]['default'].keys()
self.dashlevel_citation = intf_dftd3.dashcoeff[self.dashlevel]['citation'] self.dashlevel_citation = intf_dftd3.dashcoeff[self.dashlevel]['citation']
self.dashparams_citation = resolved['dashparams_citation']


engine = kwargs.pop('engine', None) engine = kwargs.pop('engine', None)
if engine is None: if engine is None:
Expand All @@ -140,38 +145,22 @@ def __init__(self, name_hint=None, level_hint=None, param_tweaks=None, **kwargs)
if self.engine == 'libdisp': if self.engine == 'libdisp':
self.disp = core.Dispersion.build(self.dashlevel, **resolved['dashparams']) self.disp = core.Dispersion.build(self.dashlevel, **resolved['dashparams'])


# # 5) Override parameters from user input
# # 5a) pop citation if present
# if "citation" in kwargs:
# custom_citation = kwargs.pop("citation")
# else:
# custom_citation = False

# if len(kwargs):
# raise Exception("The following parameters in empirical_dispersion.py were not understood for %s dispersion type: %s" %
# (dtype, ', '.join(kwargs.keys())))

# # 6) Process citations
# # 6a) Set default citations for method
# self.description = intf_dftd3.dashcoeff[self.dtype[1:]]['description']
# # 6b) add custom citations if available
# if custom_citation:
# self.citation += "\n Parametrisation from: \n" + custom_citation

def print_out(self): def print_out(self):
"""Format dispersion parameters of `self` for output file.""" """Format dispersion parameters of `self` for output file."""


core.print_out(" => %s: Empirical Dispersion <=\n\n" % self.fctldash.upper()) text = []
core.print_out(self.description + "\n") text.append(" => %s: Empirical Dispersion <=" % (self.fctldash.upper() if self.fctldash.upper() else 'Custom'))

text.append('')
# TODO core.print_out(self.citation + "\n\n") text.append(self.description)

text.append(self.dashlevel_citation.rstrip())
if self.engine == 'nl': if self.dashparams_citation:
return text.append(" Parametrisation from:{}".format(self.dashparams_citation.rstrip()))

text.append('')
for op in self.ordered_params: for op in self.ordered_params:
core.print_out(" %6s = %14.6f\n" % (op, self.dashparams[op])) text.append(" %6s = %14.6f" % (op, self.dashparams[op]))
core.print_out("\n") text.append('\n')

core.print_out('\n'.join(text))


def compute_energy(self, molecule): def compute_energy(self, molecule):
"""Compute dispersion energy based on engine, dispersion level, and parameters in `self`. """Compute dispersion energy based on engine, dispersion level, and parameters in `self`.
Expand Down
11 changes: 6 additions & 5 deletions psi4/driver/procrouting/proc.py
Expand Up @@ -1016,17 +1016,18 @@ def scf_wavefunction_factory(name, ref_wfn, reference, **kwargs):


if disp_type: if disp_type:
if isinstance(name, dict): if isinstance(name, dict):
# user dft_functional={} spec - type for lookup, dict val for param defs,
# name & citation discarded so only param matches to existing defs will print labels
wfn._disp_functor = empirical_dispersion.EmpiricalDispersion( wfn._disp_functor = empirical_dispersion.EmpiricalDispersion(
name_hint='', name_hint='',
level_hint=disp_type["type"], level_hint=disp_type["type"],
citation=disp_type["citation"],
param_tweaks=disp_type["params"], param_tweaks=disp_type["params"],
engine=kwargs.get('engine', None)) engine=kwargs.get('engine', None))
else: else:
# dft/*functionals.py spec - name & type for lookup, option val for param tweaks
wfn._disp_functor = empirical_dispersion.EmpiricalDispersion( wfn._disp_functor = empirical_dispersion.EmpiricalDispersion(
name_hint=superfunc.name(), name_hint=superfunc.name(),
level_hint=disp_type["type"], level_hint=disp_type["type"],
citation=disp_type["citation"],
param_tweaks=modified_disp_params, param_tweaks=modified_disp_params,
engine=kwargs.get('engine', None)) engine=kwargs.get('engine', None))


Expand All @@ -1035,12 +1036,12 @@ def scf_wavefunction_factory(name, ref_wfn, reference, **kwargs):
# ever again sighted, make an issue so this code can accommodate. # ever again sighted, make an issue so this code can accommodate.


wfn._disp_functor.print_out() wfn._disp_functor.print_out()
if (disp_type["type"] == 'nl'): if disp_type["type"] == 'nl':
del wfn._disp_functor del wfn._disp_functor


# Set the DF basis sets # Set the DF basis sets
if ("DF" in core.get_global_option("SCF_TYPE")) or \ if (("DF" in core.get_global_option("SCF_TYPE")) or
(core.get_option("SCF", "DF_SCF_GUESS") and (core.get_global_option("SCF_TYPE") == "DIRECT")): (core.get_option("SCF", "DF_SCF_GUESS") and (core.get_global_option("SCF_TYPE") == "DIRECT"))):
aux_basis = core.BasisSet.build(wfn.molecule(), "DF_BASIS_SCF", aux_basis = core.BasisSet.build(wfn.molecule(), "DF_BASIS_SCF",
core.get_option("SCF", "DF_BASIS_SCF"), core.get_option("SCF", "DF_BASIS_SCF"),
"JKFIT", core.get_global_option('BASIS'), "JKFIT", core.get_global_option('BASIS'),
Expand Down

0 comments on commit fde5917

Please sign in to comment.