-
Notifications
You must be signed in to change notification settings - Fork 42
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
Add perturbation-based quasi-IRC workflows for ORCA and Q-Chem #2042
Conversation
Can one of the admins verify this patch? |
Pinging @Andrew-S-Rosen |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #2042 +/- ##
=======================================
Coverage 99.11% 99.12%
=======================================
Files 81 81
Lines 3269 3299 +30
=======================================
+ Hits 3240 3270 +30
Misses 29 29 ☔ View full report in Codecov by Sentry. |
src/quacc/recipes/orca/core.py
Outdated
default_inputs = [xc, basis, "normalprint"] | ||
|
||
if numeric: | ||
default_inputs.append("numfreq") | ||
else: | ||
default_inputs.append("freq") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can make this simpler:
default_inputs = [xc, basis, "normalprint", "numfreq" if numeric else "freq"]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @espottesmith!! Thank you very much for your PR and for making my life easy with this review process.
This is nearly ready to go. I just have a few very minor comments that would be great if you can address. 🙏 Happy to merge afterwards!
Edit: Looks like one of my review comments landed above this message by accident.
src/quacc/recipes/orca/core.py
Outdated
@job | ||
def ase_quasi_irc_perturb_job( | ||
atoms: Atoms, | ||
mode: list[list[float]], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
Can we move
mode
to afterspin_multiplicity
for consistency? This will also match your docstring 😉 -
It's not immediately clear from the docstring or type hint what "mode" is supposed to be structured as. It might be helpful to say "an NxM matrix where..." in the docstring.
-
It seems like the type hint is actually
list[list[float]] | NDArray
whereNDArray
is taken fromfrom numpy.typing import NDArray
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't move it after because charge and spin_muiltiplicity are keyword arguments (following the pattern for other ORCA jobs), while mode is a required argument with no default.
Good point about the type and the docstring, though.
src/quacc/recipes/qchem/ts.py
Outdated
atoms: Atoms, | ||
charge: int, | ||
spin_multiplicity: int, | ||
mode: list[list[float]], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment here regarding type hint and docstring for mode
. 👍
src/quacc/recipes/qchem/ts.py
Outdated
calc_defaults = recursive_dict_merge( | ||
_BASE_SET, {"rem": {"job_type": "force", "method": method, "basis": basis}} | ||
) | ||
opt_defaults = {"optimizer": Sella} if (Sella is not False) else {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mind if we change this to:
{"optimizer": Sella} if has_sella else {}
to match what's in core.py
? This would involve having
try:
from sella import IRC, Sella
except ImportError:
Sella = False
changed to
try:
from sella import IRC, Sella
has_sella = True
except ImportError:
has_sella = False
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that seems fine. Mostly I just didn't want to mess with existing code if I didn't have to. New repo for me, and all that.
src/quacc/utils/coords.py
Outdated
from ase import Atoms | ||
|
||
|
||
def perturb(mol: Atoms, vector: list[list[float]], scale: float): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a docstring for the function? 🙏
src/quacc/utils/coords.py
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function you added is best suited in quacc.atoms.core.py
. I try to keep utils for boring Python things, e.g. handling lists and dicts and such. The Atoms handling utilities are in quacc.atoms
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool. Will move.
src/quacc/utils/coords.py
Outdated
|
||
|
||
def perturb(mol: Atoms, vector: list[list[float]], scale: float): | ||
mol_copy = copy.deepcopy(mol) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use quacc.atoms.core.copy_atoms()
here? There are some rare edge cases where a deepcopy()
can yield a crash (e.g. if someone attaches really weird things to the Atoms
object... it happens).
src/quacc/utils/coords.py
Outdated
mode_copy = copy.deepcopy(vector) | ||
|
||
orig_pos = mol_copy.get_positions() | ||
|
||
if not isinstance(mode_copy, np.ndarray): | ||
mode_copy = np.asarray(mode_copy) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you modify vector
in-place so there is no need to copy it.
I'd suggest just doing
mode = np.asarray(vector)
and then you can skip both the deepcopy()
call and the isinstance
check (i..e just call the np.asarray
). Note that np.asarray
doesn't modify in-place, so you're good.
basis="def2-svp", | ||
charge=0, | ||
spin_multiplicity=1, | ||
nprocs=2, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind removing nprocs=2
so we can run this on Windows too (i.e. you can remove the decorator afterwards)? Same as below. I don't think nprocs
is needed for this test.
src/quacc/recipes/orca/core.py
Outdated
spin_multiplicity: int = 1, | ||
xc: str = "wb97x-d3bj", | ||
basis: str = "def2-tzvp", | ||
numeric: bool = False, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mind if we change this to numerical
? Feels more boolean to me. (now I'm thinking of alphabet vs alphabetical in my head...).
Alright, think we're looking good! |
Thank you very much, @espottesmith, for the contribution and addressing the comments! I can confirm this is good to go. At some point, we will probably want to add a specific test for |
Yeah, fair enough. It's a tiny function, and it's indirectly tested by other functions, but a dedicated unit test would be a good idea. Thanks for your quick response! |
Summary of Changes
Title says most of it. I also added a frequency workflow for ORCA; felt strange that there wasn't one already.
Checklist
main
.Notes