@@ -32,9 +32,6 @@ def __init__(
3232 raise TypeError ("orca_path should be a string or a Path object." )
3333 self .cfg = orcacfg
3434 self .xtb_cfg = xtb_config
35- self .xtb_driver_enabled = bool (xtb_config ) and bool (
36- getattr (self .cfg , "use_xtb_driver" , False )
37- )
3835 # must be explicitly initialized in current parallelization implementation
3936 # as accessing parent class variables might not be possible
4037 self .tmp_dir = self .__class__ .get_temporary_directory ()
@@ -61,7 +58,7 @@ def optimize(
6158 xyz_filename = "molecule.xyz"
6259 molecule .write_xyz_to_file (temp_path / xyz_filename )
6360
64- if self ._should_use_xtb_driver () :
61+ if self .cfg . use_xtb_driver :
6562 optimized_molecule = self .optimize_xtb_driver (
6663 temp_path = temp_path ,
6764 molecule = molecule ,
@@ -70,39 +67,39 @@ def optimize(
7067 max_cycles = max_cycles ,
7168 verbosity = verbosity ,
7269 )
73- else :
74- inputname = "orca_opt.inp"
75- orca_input = self ._gen_input (
76- molecule ,
77- xyz_filename ,
78- temp_path ,
79- ncores ,
80- True ,
81- max_cycles ,
82- )
83- if verbosity > 1 :
84- print ("ORCA input file:\n ##################" )
85- print (orca_input )
86- print ("##################" )
87- with open (temp_path / inputname , "w" , encoding = "utf8" ) as f :
88- f .write (orca_input )
89- # run orca
90- arguments = [
91- inputname ,
92- ]
93- orca_log_out , orca_log_err , return_code = self ._run (
94- temp_path = temp_path , arguments = arguments
70+ return optimized_molecule
71+ inputname = "orca_opt.inp"
72+ orca_input = self ._gen_input (
73+ molecule ,
74+ xyz_filename ,
75+ temp_path ,
76+ ncores ,
77+ True ,
78+ max_cycles ,
79+ )
80+ if verbosity > 1 :
81+ print ("ORCA input file:\n ##################" )
82+ print (orca_input )
83+ print ("##################" )
84+ with open (temp_path / inputname , "w" , encoding = "utf8" ) as f :
85+ f .write (orca_input )
86+ # run orca
87+ arguments = [
88+ inputname ,
89+ ]
90+ orca_log_out , orca_log_err , return_code = self ._run (
91+ temp_path = temp_path , arguments = arguments
92+ )
93+ if verbosity > 2 :
94+ print (orca_log_out )
95+ if return_code != 0 :
96+ raise RuntimeError (
97+ f"ORCA failed with return code { return_code } :\n { orca_log_err } "
9598 )
96- if verbosity > 2 :
97- print (orca_log_out )
98- if return_code != 0 :
99- raise RuntimeError (
100- f"ORCA failed with return code { return_code } :\n { orca_log_err } "
101- )
102- # read the optimized molecule from the output file
103- xyzfile = Path (temp_path / inputname ).resolve ().with_suffix (".xyz" )
104- optimized_molecule = molecule .copy ()
105- optimized_molecule .read_xyz_from_file (xyzfile )
99+ # read the optimized molecule from the output file
100+ xyzfile = Path (temp_path / inputname ).resolve ().with_suffix (".xyz" )
101+ optimized_molecule = molecule .copy ()
102+ optimized_molecule .read_xyz_from_file (xyzfile )
106103 return optimized_molecule
107104
108105 def singlepoint (self , molecule : Molecule , ncores : int , verbosity : int = 1 ) -> str :
@@ -221,17 +218,6 @@ def _gen_input(
221218 orca_input += f"* xyzfile { molecule .charge } { molecule .uhf + 1 } { xyzfile } \n "
222219 return orca_input
223220
224- def _should_use_xtb_driver (self ) -> bool :
225- """
226- Determine whether the xTB driver should be used for this optimization.
227- """
228- if not self .xtb_driver_enabled or not self .xtb_cfg :
229- return False
230- if hasattr (self .xtb_cfg , "has_constraints" ):
231- return self .xtb_cfg .has_constraints ()
232- constraints = getattr (self .xtb_cfg , "distance_constraints" , None )
233- return bool (constraints )
234-
235221 def optimize_xtb_driver (
236222 self ,
237223 temp_path : Path ,
@@ -260,6 +246,9 @@ def optimize_xtb_driver(
260246 print ("ORCA input file:\n ##################" )
261247 print (orca_input )
262248 print ("##################" )
249+ print ("XTB input file:\n ##################" )
250+ print (xtb_input )
251+ print ("##################" )
263252 with open (temp_path / inputname , "w" , encoding = "utf8" ) as f :
264253 f .write (orca_input )
265254 # run orca with xTB as a driver
@@ -296,55 +285,24 @@ def _run_xtb_driver(
296285 """
297286 Run the optimization through the xTB external driver when constraints are requested.
298287 """
299- xtb_executable = self ._get_xtb_executable ()
288+ xtb_executable = get_xtb_path ()
289+ if self .xtb_cfg is None :
290+ raise RuntimeError (
291+ "xTB driver requested but no xTB configuration provided."
292+ )
293+ xtb_runner = XTB (path = xtb_executable , xtb_config = self .xtb_cfg )
300294 arguments = [
301- str (xtb_executable ),
302295 geometry_filename ,
303296 "--opt" ,
304297 ]
305298 opt_level = getattr (self .cfg , "optlevel" , None )
306299 if opt_level not in (None , "" ):
307300 arguments .append (str (opt_level ))
308301 arguments .extend (["--orca" , "-I" , xcontrol_name ])
309- try :
310- xtb_out = sp .run (
311- arguments ,
312- cwd = temp_path ,
313- capture_output = True ,
314- check = True ,
315- )
316- xtb_log_out = xtb_out .stdout .decode ("utf8" , errors = "replace" )
317- xtb_log_err = xtb_out .stderr .decode ("utf8" , errors = "replace" )
318- return xtb_log_out , xtb_log_err , 0
319- except sp .CalledProcessError as e :
320- xtb_log_out = e .stdout .decode ("utf8" , errors = "replace" )
321- xtb_log_err = e .stderr .decode ("utf8" , errors = "replace" )
322- return xtb_log_out , xtb_log_err , e .returncode
323-
324- def _get_xtb_executable (self ) -> Path :
325- """
326- Determine the path to the xTB executable for external ORCA optimizations.
327- """
328- candidates : list [ORCAConfig | XTBConfig | None ] = [self .xtb_cfg , self .cfg ]
329- for source in candidates :
330- if source is None :
331- continue
332- for attr_name in ("xtb_path" ,):
333- candidate = getattr (source , attr_name , None )
334- if not candidate :
335- continue
336- try :
337- return get_xtb_path (candidate )
338- except ImportError as exc :
339- raise RuntimeError (
340- f"xTB executable defined via '{ attr_name } ' could not be found."
341- ) from exc
342- try :
343- return get_xtb_path (None )
344- except ImportError as exc :
345- raise RuntimeError (
346- "xTB executable not found. Required for constrained ORCA optimizations."
347- ) from exc
302+ xtb_log_out , xtb_log_err , returncode = xtb_runner ._run (
303+ temp_path = temp_path , arguments = arguments
304+ )
305+ return xtb_log_out , xtb_log_err , returncode
348306
349307 def _write_xtb_input (
350308 self , molecule : Molecule , xtb_input : Path , input_file : str
@@ -356,7 +314,7 @@ def _write_xtb_input(
356314 raise RuntimeError (
357315 "xTB configuration missing but constraints were requested."
358316 )
359- xtb_path = self . _get_xtb_executable ()
317+ xtb_path = get_xtb_path ()
360318 xtb_writer = XTB (xtb_path , self .xtb_cfg )
361319 generated = xtb_writer ._prepare_distance_constraint_file (
362320 molecule , xtb_input .parent
0 commit comments