Skip to content

Commit

Permalink
Merge pull request #6 from pierre-24/fixups_and_upgrades
Browse files Browse the repository at this point in the history
Fixups and upgrades
  • Loading branch information
pierre-24 authored Mar 8, 2023
2 parents 8ff7bbc + 81e20b8 commit 43e3dac
Show file tree
Hide file tree
Showing 23 changed files with 201 additions and 280 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Install dependencies
run: |
pip3 install pip-tools
make init
make install-dev
- name: Lint
run: |
make lint
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ help:
@echo " help to get this help"

init:
pip-sync && pip3 install -e .
pip3 install -e .

sync:
install-dev:
pip-sync

lint:
Expand Down
2 changes: 1 addition & 1 deletion docs/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ To contribute to the project,
+ Go in it: ``cd nachos``
+ Install pip-tools: ``pip3 install pip-tools``
+ Install virtualenv ``python3 -m venv venv; source venv/bin/activate``
+ Install dependencies: ``make init``.
+ Install dependencies: ``make install-dev``.
+ Add upstream: ``git remote add upstream https://github.com/pierre-24/nachos.git``
+ Don't forget to create a separate branch to implement your changes: ``git checkout -b my_branch upstream/dev``.

Expand Down
6 changes: 6 additions & 0 deletions docs/use.rst
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,12 @@ By using ``-d``, you can decide where the input files should be generated, but k

The ``-V 1`` option allows you to know how much files where generated.


.. warning::

When using electric fields, Gaussian compute the fields in an opposite direction to what is expected by Nachos.
So, e.g., if the title card say that the field is computed in the +x direction it is the **normal behavior** that the x component of the electric field has a negative sign.

.. note::

To helps the dalton program, a file called ``inputs_matching.txt`` is created for this *flavor*, where each lines contains the combination of dal and mol file to launch (because there may be different dal files).
Expand Down
28 changes: 0 additions & 28 deletions nachos/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,6 @@
__email__ = 'pierre.beaujean@unamur.be'
__status__ = 'Development'

# List of the scripts that are installed, without the .py extension. The name is used to give the command name.
provide_scripts = [
'make',
'prepare',
'cook',
'bake',
'shake',
'analyze',
'peek'
]


def make_console_scripts(package_name='nachos'):
"""Function used to generate the ``console_scripts`` list for ``setup.py``
:rtype: list
"""

console_scripts = []
for script in provide_scripts:
path = os.path.join(package_name, script + '.py')
if not os.path.isfile(path):
raise FileNotFoundError(path)

console_scripts.append('{0} = {1}.{2}:main'.format('nachos_' + script, package_name, script))

return console_scripts


def is_dir(dirname):
"""Checks if a path is an actual directory"""
Expand Down
7 changes: 7 additions & 0 deletions nachos/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@
}
}

GAUSSIAN_DOUBLE_HYBRIDS = [
'B2PLYP', 'B2PLYPD', 'B2PLYPD3',
'mPW2PLYP', 'mPW2PLYPD',
'DSDPBEP86',
'PBE0DH', 'PBEQIDH'
]


def compute_numerical_derivative_of_tensor(
recipe, basis, derivative_repr, tensor_func, frequency=None, dry_run=False, force_choice=None, **kwargs):
Expand Down
6 changes: 3 additions & 3 deletions nachos/core/baking.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,10 @@ def output_information(
basis_name))

out.write('\n------------------------------------------------------\n')
out.write(' F V(F) V(F)-V(0)\n')
out.write(' F V(F) V(F)-V(0)\n')
out.write('------------------------------------------------------\n')
zero_field_val = tensor_access(
[0] * len(field), 0, initial_derivative, False, b_coo, final_result.frequency, recipe)
[0] * len(field), 0, initial_derivative, b_coo, final_result.frequency, recipe)

for i, c in enumerate(all_fields):
k = i - recipe['k_max']
Expand All @@ -274,7 +274,7 @@ def output_information(
field_val = recipe['min_field'] * recipe['ratio'] ** (abs(k) - 1) * (-1 if k < 0 else 1)

val = tensor_access(
c, 0, initial_derivative, False, b_coo, final_result.frequency, recipe)
c, 0, initial_derivative, b_coo, final_result.frequency, recipe)
dV = val - zero_field_val
out.write(
'{: .7f} {: .14e} {: .14e}\n'.format(
Expand Down
9 changes: 8 additions & 1 deletion nachos/core/cooking.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from qcip_tools import quantities, derivatives, derivatives_e
from qcip_tools.chemistry_files import helpers, PropertyNotPresent, PropertyNotDefined

from nachos.core import files, preparing
from nachos.core import files, preparing, GAUSSIAN_DOUBLE_HYBRIDS
from nachos.qcip_tools_ext import gaussian, qchem # noqa


Expand Down Expand Up @@ -110,6 +110,11 @@ def almost_the_same(a, b, threshold=1e-3):
if self.recipe['type'] == 'F':
try:
real_fields = f.property('n:input_electric_field')[1:4]

if f.file_type in ['GAUSSIAN_FCHK', 'GAUSSIAN_LOG']:
# Gaussian computes actually for the opposite field!
real_fields = list(-x for x in real_fields)

except PropertyNotPresent:
raise BadCooking('F derivative but not electric field for {}'.format(name))
else:
Expand Down Expand Up @@ -143,6 +148,8 @@ def almost_the_same(a, b, threshold=1e-3):
key = self.recipe['method']
if key == 'DFT':
key = 'SCF/DFT'
if self.recipe['flavor_extra']['XC'] in GAUSSIAN_DOUBLE_HYBRIDS:
key = 'MP2' # Gaussian puts the result in the MP2 field instead of SCF/DFT.
energy = energies[key] # tries to catch the energy for the correct method
obtained.append('energy:' + self.recipe['method'])
else: # ?!?
Expand Down
4 changes: 2 additions & 2 deletions nachos/core/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ def read(self, path):
self.results[t_fields] = chemistry_datafile.ChemistryDataFile.read_derivatives_from_group(
fields_group[i], dof)

def tensor_element_access(self, fields, min_field, basis, inverse, component, frequency, recipe):
def tensor_element_access(self, fields, min_field, basis, component, frequency, recipe):
t_fields = tuple(fields)
if t_fields not in self.results:
raise BadResult('fields {} is not available'.format(fields))
Expand All @@ -398,7 +398,7 @@ def tensor_element_access(self, fields, min_field, basis, inverse, component, fr
if len(component) != results.representation.order():
raise BadResult('shape does not match for {}'.format(b_repr))

return (-1. if inverse else 1.) * results.components[component]
return results.components[component]

@staticmethod
def get_recipe_check_data(recipe):
Expand Down
5 changes: 4 additions & 1 deletion nachos/core/preparing.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ def prepare_gaussian_inputs(self, dry_run=False):
fi.title = 'field({})='.format(level) + \
','.join(Preparer.nonzero_fields(fields, self.recipe.geometry, self.recipe['type']))

if self.recipe['type'] == 'F':
fi.title += '\nNote: E-field in the opposite direction is used.'

fi.options['nprocshared'] = self.recipe['flavor_extra']['procs']
fi.options['mem'] = self.recipe['flavor_extra']['memory']
fi.options['chk'] = 'xxx'
Expand Down Expand Up @@ -281,7 +284,7 @@ def prepare_gaussian_inputs(self, dry_run=False):
fi.other_blocks.extend(extra_sections_before)

if self.recipe['type'] == 'F':
fi.other_blocks.append(['\t'.join(['{: .10f}'.format(a) for a in real_fields])])
fi.other_blocks.append(['\t'.join(['{: .10f}'.format(-a) for a in real_fields])])

if extra_sections:
fi.other_blocks.extend(extra_sections)
Expand Down
75 changes: 0 additions & 75 deletions nachos/qcip_tools_ext/gaussian.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,81 +46,6 @@ def _find_in_links(obj, q, links):
return -1


@gaussian.Output.define_property('computed_energies')
def gaussian__Output__get_computed_energies(obj, *args, **kwargs):
"""Get the energies... Actually, "only"
+ HF and DFT energy (in link 502/503/506/508)
+ MP2 energy (in link 804/903/905/906)
+ MP3, CCSD and CCSD(T) energy (in link 913)
:param obj: object
:type obj: qcip_tools.chemistry_files.gaussian.Output
:rtype: dict
"""
energies = {}
modified_gaussian = False # pristine Gaussian 16

# fetch HF or DFT energy
n = _find_in_links(obj, 'SCF Done:', [502, 503, 506, 508])
if n > 0:
chunks = obj.lines[n][12:].split()
e = float(chunks[2])
if (len(chunks[2]) - chunks[2].find('.')) != 9:
modified_gaussian = True
else: # try to fetch more decimals above: "E = xxx" contains eleven of them
for line in reversed(obj.lines[:n]):
if 'Delta-E=' in line:
e = float(line.split()[1])
break
elif 'Cycle' in line:
break

if 'HF' in chunks[0]:
energies['HF'] = e
else:
energies['SCF/DFT'] = e

energies['total'] = e

# fetch MP2 energies
n = _find_in_links(obj, 'EUMP2 =', [804, 903, 905, 906])
if n > 0:
chunk = obj.lines[n].split()[-1]
if not modified_gaussian:
chunk = chunk.replace('D', 'E')

energies['MP2'] = float(chunk)
energies['total'] = energies['MP2']

# fetch MP3 energies
n = _find_in_links(obj, 'EUMP3=', [913])
if n > 0:
chunk = obj.lines[n].split()[-1]
if not modified_gaussian:
chunk = chunk.replace('D', 'E')
energies['MP3'] = float(chunk)

# fetch CCSD energies
n = obj.search('Wavefunction amplitudes converged.', into=913)
if n > 0:
chunk = obj.lines[n - 3][:-16].split()[-1]
if not modified_gaussian:
chunk = chunk.replace('D', 'E')
energies['CCSD'] = float(chunk)
energies['total'] = energies['CCSD']

# fetch CCSD(T) energies
n = obj.search('CCSD(T)=', into=913)
if n > 0:
chunk = obj.lines[n].split()[-1]
if not modified_gaussian:
chunk = chunk.replace('D', 'E')
energies['CCSD(T)'] = float(chunk)
energies['total'] = energies['CCSD(T)']

return energies


@gaussian.Output.define_property('n:spin_components_e2')
def gaussian__Output__get_spin_component_e2(obj, *args, **kwargs):
"""Get the spin components of E(2) (link 906)
Expand Down
51 changes: 51 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
[project]
name = "nachos"
dynamic = ["version"]
authors = [
{name = "Pierre Beaujean", email = "pierre.beaujean@unamur.be"},
]
description = "NACHOS: numerical differentiation code"
readme = "README.md"
requires-python = ">=3.7"
classifiers = [
"Development Status :: 3 - Alpha",
"License :: OSI Approved :: MIT License",
"Natural Language :: English",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
]
dependencies = [
'pyyaml>=5.0',
'h5py',
'qcip-tools @ git+https://github.com/pierre-24/qcip_tools.git@v0.7.1',
'prompt_toolkit==1.0.15',
'pandas>=1.2',
'scipy>=1.7',
'numpy>=1.20'
]


[project.urls]
documentation = "https://pierre-24.github.io/nachos/"
repository = "https://github.com/pierre-24/nachos.git"

[project.scripts]

# keep that alphabetical
nachos_make = 'nachos.make:main'
nachos_prepare = 'nachos.prepare:main'
nachos_cook = 'nachos.cook:main'
nachos_bake = 'nachos.bake:main'
nachos_shake = 'nachos.shake:main'
nachos_analyze = 'nachos.analyze:main'
nachos_peek = 'nachos.peek:main'

[tool.setuptools]
packages = ['nachos', 'nachos.core', 'nachos.qcip_tools_ext']

[tool.setuptools.dynamic]
version = {attr = "nachos.__version__"}
4 changes: 2 additions & 2 deletions requirements/requirements.in → requirements.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-r requirements-base.in
flake8
-e file:. #egg=nachos
flake8<6.0
flake8-quotes
autopep8
sphinxcontrib-autoprogram
Expand Down
Loading

0 comments on commit 43e3dac

Please sign in to comment.