-
Notifications
You must be signed in to change notification settings - Fork 3
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
Added support for Turbomole #101
base: main
Are you sure you want to change the base?
Added support for Turbomole #101
Conversation
Signed-off-by: Jonathan Schöps <[email protected]>
Signed-off-by: Jonathan Schöps <[email protected]>
Merge latest changes to dev branche
Signed-off-by: Jonathan Schöps <[email protected]>
Signed-off-by: Jonathan Schöps <[email protected]>
Update the branch
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.
Some things to do, but it's already on a very good track!
# > Functional/Method: Options: <str> | ||
functional = "PBE" | ||
# > Basis set: Options: <str> | ||
basis = "def2-SVP" |
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.
Have you tested if this combination works if you directly use this mindlessgen.toml
? If yes, just resolve this question.
@@ -1048,6 +1133,9 @@ def load_from_dict(self, config_dict: dict) -> None: | |||
}, | |||
"orca": { | |||
"orca_option": "opt" | |||
}, |
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.
This is a simplified and exemplary structure only anyway. You can make this whole dictionary example also a bit shorter to save some lines of code (or comment, in this case).
def get_turbomole_path(binary_name: str | Path | None = None) -> Path: | ||
""" | ||
Get the path to the turbomole binary based on different possible names | ||
that are searched for in the PATH. | ||
""" | ||
default_turbomole_names: list[str | Path] = ["ridft", "jobex"] | ||
# put binary name at the beginning of the lixt to prioritize it | ||
if binary_name is not None: | ||
binary_names = [binary_name] + default_turbomole_names | ||
else: | ||
binary_names = default_turbomole_names | ||
# Get turbomole path from 'which ridft' command | ||
for binpath in binary_names: | ||
which_ridft = shutil.which(binpath) | ||
if which_ridft: | ||
ridft_path = Path(which_ridft).resolve() | ||
return ridft_path | ||
raise ImportError("'turbomole' binary could not be found.") |
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.
This whole part does not yet resolve the problem of TURBOMOLE having two instead of only one binary name.
My suggestion (to be in-line with how it's handled for ORCA and xTB):
Document everything in a way that the ridft
binary can be handled and only this full path (including the binary itself) is then handled from now on.
For geometry optimizations or other methods, the jobex
path is then assumed to be the same as the ridft
one, just with a different suffix (xx/yy/ridft
-> xx/yy/jobex
).
Currently the return variable can contain either ridft
, jobex
or whatever the user puts in there.
molecule.write_xyz_to_file(temp_path / molfile) | ||
|
||
# convert molfile to coord file (tm format) | ||
command = f"x2t {temp_path / molfile} > {temp_path / 'coord'}" |
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.
Let's do this rather in the code and not relying on another part in the code.
Using Copilot or ChatGPT, this should be quite easy (just add a new function write_coord_to_file
similar to write_xyz_to_file
in molecule.py
in Molecule
.
The conversion constant is already included in refinement.py
.
|
||
try: | ||
# run the command in a shell | ||
sp.run(command, shell=True, check=True) | ||
except sp.CalledProcessError as e: | ||
print(f"The xyz file could not be converted to a coord file: {e}") | ||
|
||
if verbosity > 2: | ||
with open(temp_path / "coord", encoding="utf8") as f: | ||
tm_coordinates = f.read() | ||
print(tm_coordinates) |
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.
Then we'd get rid of this code as well (printing out coordinates is just for debugging).
f.write(tm_input) | ||
|
||
# Setup the turbomole optimization command including the max number of optimization cycles | ||
arguments = [f"PARNODES=1 jobex -ri -c {max_cycles} > jobex.out"] |
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.
- Arguments should be a list of strings, e.g.
["jobex", "-ri"]
and so on. - We don't include the pipe command in the arguments, as this belongs to the handling of the subprocess in
_run
.
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.
orca_out = sp.run(
[str(self.path)] + arguments,
cwd=temp_path,
capture_output=True,
check=True,
)
This does the piping of the output for you. (See comment below at: #101 (comment))
check=True, | ||
shell=True, | ||
) | ||
if "PARNODES=1 ridft > ridft.out" in arguments[0]: |
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.
See above.
and the return code | ||
""" | ||
try: | ||
sp.run( |
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.
Look at the orca.py
, how it's handled there:
orca_out = sp.run(
[str(self.path)] + arguments,
cwd=temp_path,
capture_output=True,
check=True,
)
# get the output of the ORCA calculation (of both stdout and stderr)
orca_log_out = orca_out.stdout.decode("utf8", errors="replace")
orca_log_err = orca_out.stderr.decode("utf8", errors="replace")
A new interface for Turbomole has been implemented to facilitate its use in post-processing step, including both single-point energy calculations and geometry optimizations.