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

Refactor energy corrections in Arkane and implement new bond additivity correction type #1605

Merged
merged 4 commits into from
Jul 12, 2019

Conversation

cgrambow
Copy link

Motivation or Problem

Applying energy corrections as part of a statmech job in Arkane takes place in a really messy function and does not allow for easy extension to new bond additivity correction types.

Description of Changes

This PR refactors energy corrections into separate modules and stores the data separately. Furthermore, it implements a new type of bond additivity correction scheme.

Testing

Existing unit tests pass.

Discussion

This PR provides the functionality to select either type of bond additivity correction, but it doesn't yet provide data for the new BAC type. My plan is to completely replace the current atom energies using just the calculated values at the respective levels of theory and to provide newly-derived bond additivity corrections for all levels of theory for both the existing type of BACs and the newly implemented type of BACs once we have selected a reference set of molecules and performed the quantum calculations at all the levels of theory.

This PR can be merged without the new data because it doesn't change current Arkane behavior. Alternatively, we can wait with merging until the new data is available. What do you think? In either case, the current changes are ready for review.

@cgrambow cgrambow added Arkane Status: Ready for Review PR is complete and ready to be reviewed Status: Discussion Needed Discussion needed for further progress labels May 22, 2019
@cgrambow cgrambow requested review from mliu49 and alongd May 22, 2019 22:54
@cgrambow cgrambow self-assigned this May 22, 2019
@codecov
Copy link

codecov bot commented May 23, 2019

Codecov Report

Merging #1605 into master will decrease coverage by 0.13%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1605      +/-   ##
==========================================
- Coverage    41.8%   41.67%   -0.14%     
==========================================
  Files         177      176       -1     
  Lines       29455    29374      -81     
  Branches     6059     6059              
==========================================
- Hits        12314    12241      -73     
+ Misses      16271    16263       -8     
  Partials      870      870
Impacted Files Coverage Δ
rmgpy/exceptions.py

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f6faa9f...cdca610. Read the comment docs.

Copy link
Member

@alongd alongd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this awesome PR. I really like the organization and methodology. I added relatively minor comments.

try:
atom_energies = data.atom_energies[model_chemistry]
except KeyError:
raise Exception('Missing atom energies for model chemistry {}'.format(model_chemistry))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make the exceptions (throughout the PR) more specific? For example, if we raise an AtomEnergyCorrectionException here, then a software like ARC calling Akane might know what the problem is and in this case be able to spawn AEC jobs for that model chemistry.


for symbol, count in atoms.items():
if symbol in atom_energies:
corr -= count * atom_energies[symbol] * 4.35974394e-18 * constants.Na
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment re the unit conversion factor (e.g., Hartree to J)?
Alternatively, and although it's not a "constant", would we like to add frequently used unit conversions to constants.py?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added comments everywhere but just kept the numerical values in there for now. I'm inclined to not add unit conversions to constants.py, but am open to other suggestions.

corr -= count * atom_energies[symbol] * 4.35974394e-18 * constants.Na
else:
raise Exception(
'Unknown element "{}". Turn off atom corrections if only running a kinetics jobs '
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of "unknown element", perhaps say "An energy correction for element X is unavailable in the data for model chemistry Y. Turn off..."


# Atom energy corrections to reach gas-phase reference state
# Experimental enthalpy of formation at 0 K, 1 bar for gas phase
# See Gaussian thermo whitepaper at http://www.gaussian.com/g_whitepap/thermo.htm)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove ) at the end of the line

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out the link has actually changed, so I replaced it with a more up-to-date link.

'Rb': 17.86, 'Ag': 66.61, 'Cd': 25.240, 'Sn': 70.50, 'I': 24.04, 'Xe': -1.481,
'Cs': 16.80, 'Hg': 13.19, 'Pb': 15.17}

# Thermal contribution to enthalpy Hss(298 K) - Hss(0 K) reported by Gaussian thermo whitepaper
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's Hss? If it's standard state, then Hss should be T-independent. Perhaps it should be "standard pressure"? Or did I read it wrong?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These terms just describe the enthalpy changes for the elements going from 0 K to 298 K. I think the Hss notation was left over from a previous version of Arkane, so I just replaced it.

long bonds. Use RMG for hydrogen because Open Babel can't do it for
mysterious reasons.
"""
if len(nums) == 2 and all(n == 1 for n in nums):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps if nums == [1, 1] instead?
Why hard code for H2, or am I not reading it correctly?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to make sure that the check works for all sequence types and not just lists.

I'm hardcoding for H2 because I've observed in the past that Open Babel would not recognize correctly that two hydrogens are bonded to each other.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will if list(nums) == [1, 1] work?

OK. Could you add a small comment explaining why H2 was hardcoded?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's mentioned in the docstring of the function. Is that not enough?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect! (I missed it)

mol.fromXYZ(nums, coords)
else:
xyz = '{}\n\n'.format(len(nums))
xyz += '\n'.join('{0} {1[0]: .10f} {1[1]: .10f} {1[2]: .10f}'.format(s, c) for s, c in zip(coords, nums))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you take another look here? Looks like coords and nums should be switched in the zip

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, great catch.

@@ -28,6 +28,7 @@ Component Description
``useHinderedRotors`` ``True`` (by default) if hindered rotors are used, ``False`` if not
``useAtomCorrections`` ``True`` (by default) if atom corrections are used, ``False`` if not
``useBondCorrections`` ``True`` if bond corrections are used, ``False`` (by default) if not
``bondCorrectionType`` ``'p'`` for Petersson-type or ``'m'`` for Melius-type bond additivity corrections
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you specify what the default is?

@@ -188,7 +189,12 @@ to apply atomization energy corrections (AEC) and spin orbit corrections (SOC) f
(see `Model Chemistry`_). If not interested in accurate thermodynamics (e.g., if only using ``kinetics()``), then
atom corrections can be turned off by setting ``useAtomCorrections`` to ``False``.

The ``bond`` parameter is used to apply bond corrections (BC) for a given ``modelChemistry``.
The ``bond`` parameter is used to apply bond corrections (BC) for a given ``modelChemistry`` if using Petersson-type
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change to apply bond corrections (BC) into to apply bond additivity corrections (BAC), and then just use BAC later on?

The ``bond`` parameter is used to apply bond corrections (BC) for a given ``modelChemistry``.
The ``bond`` parameter is used to apply bond corrections (BC) for a given ``modelChemistry`` if using Petersson-type
bond additivity corrections (BACs) (``bondCorrectionType = 'p'``). When using Melius-type bond additivity corrections
(``bondCorrectionType = 'm'``), specifying bonds is not required because the molecular connectivity is automatically
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps change specifying bonds is not required into specifying bond orders is not required

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means that the bonds dictionary is not required in the input file. To highlight that, I added `` around it so that it gets parsed as plain text in the documentation.

else:
raise Exception(
'Element "{}" is not yet supported in Arkane.'
' To include it, add its experimental heat of formation'.format(symbol)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could consider indicating where one would add it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cgrambow, was this comment addressed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now it has been.

if symbol in params:
bac += count * params[symbol] * 4184.0
elif symbol[::-1] in params:
bac += count * params[symbol[::-1]] * 4184.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method will break once we start supporting elements with two letter symbols, right? Although it might be a moot point if we're deprecating this type of correction anyway.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't even think of that. I replaced it with a regex which works for all possible scenarios.

@cgrambow
Copy link
Author

I think I addressed all your comments and made some fixup commits. I just realized that I caused a circular import issue, so I'll fix that, too.

@cgrambow
Copy link
Author

Added two more fixup commits. I introduced an exceptions.py file in the main Arkane directory and added the exceptions there to get rid of the circular imports.

"""
Calculate a correction to the electronic energy obtained from a
quantum chemistry calculation at a given model chemistry such that
it is consistent with the normal gas-phase reference states.
Optionally, correct the energy using bond additivity corrections.

model_chemistry: The model chemistry, typically specified as method/basis.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can format the arguments to get nice styling when we compile the API documentation. Minimum would be adding the Args keyword and indenting:

Args:
    model_chemistry: The model chemistry, typically specified as method/basis.
    ...

See https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html for even more details.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know!

@alongd
Copy link
Member

alongd commented Jul 11, 2019

@cgrambow, can you rebase?
What else is needed for this PR?
Let's get it in before the Py3 transision

@alongd alongd mentioned this pull request Jul 11, 2019
@cgrambow cgrambow force-pushed the new_bacs branch 2 times, most recently from 5468be1 to 4f792b4 Compare July 11, 2019 21:44
@cgrambow
Copy link
Author

Squashed and rebased. Nothing else is needed for this PR, except for BAC data, but we don't have that yet, so we can add it after Py3 transition.

@alongd
Copy link
Member

alongd commented Jul 12, 2019

Could you take a look at the Codacy comment?

@cgrambow
Copy link
Author

The Codacy comment can be ignored. Apparently Codacy isn't smart enough to figure out that c in coords can be indexed.

Colin Grambow added 4 commits July 12, 2019 14:09
Make new encorr package which handles all energy corrections. Store all
correction parameters in a dedicated data file. Handle bond additivity
corrections in its own module, so that new types of bond additivity
corrections can easily be implemented in the future.
Instead of correcting the electronic energy using explicitly defined bond
types, Anantharaman and Melius (JPCA, 2005) only use three fitted
parameters per atom type to correct the energy. Implement the framework
for this type of correction in the encorr package.
bondCorrectionType can be set to 'p' to use conventional bond additivity
corrections or to 'm' to use the newly implemented Melius-type corrections.
Copy link
Member

@alongd alongd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this contribution!

@mliu49 mliu49 merged commit 58c1a06 into master Jul 12, 2019
@mliu49 mliu49 deleted the new_bacs branch July 12, 2019 20:01
@mliu49 mliu49 mentioned this pull request Jul 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Arkane Status: Discussion Needed Discussion needed for further progress Status: Ready for Review PR is complete and ready to be reviewed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants