def optimize(self, max_cycles=350, gamma=0.0, restart=False, convergence='normal'): """ :return:This object will return the optimization status. It will optimize a structure. """ # TODO: Add a return 'CycleExceeded' logfile = "trial_{}.log".format(self.job_name) with open(logfile, 'w') as fopt: out = subp.Popen(["mopac", self.inp_file], stdout=fopt, stderr=fopt) out.communicate() out.poll() exit_status = out.returncode if exit_status == 0: if os.path.exists(self.arc_file): self.energy = self.get_energy() self.optimized_coordinates = self.get_coords() interface.write_xyz(self.atoms_list, self.optimized_coordinates, self.result_xyz_file, self.job_name, energy=self.energy) return True else: print("Error: File ", self.arc_file, "was not found.") print("Check for partial optimization.") print("Location: {}".format(os.getcwd())) return False
def optimize(self, max_cycles=350, gamma=0.0, restart=False, convergence='normal'): """ :return:This object will return the optimization status. It will optimize a structure. """ # TODO: Add a return 'CycleExceeded' with open(self.out_file, 'w') as fopt: out = subp.Popen(["psi4", self.inp_file], stdout=fopt, stderr=fopt) out.communicate() out.poll() exit_status = out.returncode if exit_status == 0: f = open(self.out_file, "r") if " **** Optimization is complete!" in f.read(): print("Optimized") self.energy = self.get_energy() self.optimized_coordinates = self.get_coordinates() write_xyz(self.atoms_list, self.optimized_coordinates, self.result_xyz_file, energy=self.energy) f.close() return True else: print("Error: OPTIMIZATION PROBABLY FAILED. " "CHECK THE .out FILE FOR PARTIAL OPTIMIZTION ") print("Check for partial optimization.") print("Location: {}".format(os.getcwd())) return False
def run_turbomole_jobex(self, max_cycles=350): """ return one of the following: True: converged SCFFailed GradFailed UpdateFailed CycleExceeded False: unknown error or jebex excution error :rtype: string or boolean """ with open('jobex.out', 'w') as fj: try: subp.check_call(['jobex', '-ri', '-c', str(max_cycles)], stdout=fj, stderr=fj) except subp.CalledProcessError as e: turbomole_logger.error('jobex failed, check %s/jobex.out' % os.getcwd()) return False if os.path.isfile('GEO_OPT_FAILED'): message = open('GEO_OPT_FAILED').read() if 'ERROR: Module' in message: turbomole_logger.error('Error in module!\n chcek %s/GEO_OPT_FAILED' % os.getcwd()) return False elif 'ERROR in statpt step,' in message: turbomole_logger.error('Statpt failed!\n chcek %s/GEO_OPT_FAILED' % os.getcwd()) return 'UpdateFailed' elif 'ERROR in relax step,' in message: turbomole_logger.error('Relax failed!\n chcek %s/GEO_OPT_FAILED' % os.getcwd()) return 'UpdateFailed' elif 'ERROR: your energy calculation did not converge !!,' in message: turbomole_logger.error('SCF failed!\n chcek %s/GEO_OPT_FAILED' % os.getcwd()) return 'SCFFailed' elif 'ERROR in dscf step' in message: turbomole_logger.error('SCF failed!\n chcek %s/GEO_OPT_FAILED' % os.getcwd()) return 'SCFFailed' elif 'ERROR in gradient step' in message: turbomole_logger.error('Gradient failed!\n chcek %s/GEO_OPT_FAILED' % os.getcwd()) return 'GradientFailed' elif 'OPTIMIZATION DID NOT CONVERGE' in message: turbomole_logger.error('Geometry did not converge in %d cycles.\ncheck %s' % (max_cycles, os.getcwd())) self.energy = get_energy() self.optimized_coordinates = bohr2angstrom(get_coords()) return 'CycleExceeded' else: turbomole_logger.error('Unknown Error!\n chcek the files in %s' % os.getcwd()) return False elif os.path.isfile('GEO_OPT_CONVERGED'): turbomole_logger.debug('jobex done') self.energy = get_energy() self.optimized_coordinates = bohr2angstrom(get_coords()) interface.write_xyz(self.atoms_list, self.optimized_coordinates, self.result_xyz_file, self.job_name, energy=self.energy) return True
def optimize(self, options): """ :return:This object will return the optimization status. It will optimize a structure. """ # TODO: Add a return 'CycleExceeded' logfile = "trial_{}.out".format(self.job_name) max_opt_cycles = options['opt_cycles'] gamma = options['gamma'] opt_keywords = f"maxcycles={max_opt_cycles}" convergence = options['opt_threshold'] if convergence != 'normal': opt_keywords += f", {convergence}" self.keyword += f" opt=({opt_keywords})" self.prepare_input() with open(self.out_file, 'w') as fopt: out = subp.Popen(["g16", self.inp_file], stdout=fopt, stderr=fopt) out.communicate() out.poll() exit_status = out.returncode if exit_status == 0: file_pointer = open(self.out_file, "r") this_line = file_pointer.readlines() check_1 = 0 check_2 = 0 for j in this_line: if "Optimization completed" in j: check_1 = 1 if "SCF Done" in j: check_2 = 1 if ("Normal termination" in this_line[-1]) and check_1 == 1 and check_2 == 1: self.energy = self.get_energy() self.optimized_coordinates = self.get_coords() interface.write_xyz(self.atoms_list, self.optimized_coordinates, self.result_xyz_file, self.job_name, energy=self.energy) file_pointer.close() return True else: print("Error: OPTIMIZATION PROBABLY FAILED.") print("Location: {}".format(os.getcwd())) return False
def optimize(self, options): max_cycles = options['opt_cycles'] gamma = options['gamma'] convergence = options['opt_threshold'] pyar.interface.turbomole.make_coord(self.atoms_list, self.start_coords, self.coord_file) pyar.interface.turbomole.prepare_control() for cycle in range(max_cycles): xtb_turbo_logger.debug("Optimization Cycle {}".format(cycle)) # Calculate energy and gradient status, message, energy, gradients = self.calc_engrad if status is False: xtb_turbo_logger.critical('Energy/Gradient evaluation failed') return 'SCFFailed' # Calculate afir gradient if gamma is greater than zero afir_energy, afir_gradient = restraints.isotropic(self.atoms_in_fragments, self.atoms_list, pyar.interface.turbomole.get_coords(), gamma) pyar.interface.turbomole.rewrite_turbomole_energy_and_gradient_files(self.number_of_atoms, afir_energy, afir_gradient) # Update coordinates and check convergence. status = pyar.interface.turbomole.update_coord() if status is False: xtb_turbo_logger.critical('Coordinate update failed in cycle %d' % cycle) xtb_turbo_logger.critical('Check the job in %s' % os.getcwd()) return 'UpdateFailed' convergence_status = pyar.interface.turbomole.check_geometry_convergence() if convergence_status is True: xtb_turbo_logger.info('converged at {}'.format(cycle)) self.energy = pyar.interface.turbomole.get_energy() self.optimized_coordinates = bohr2angstrom(pyar.interface.turbomole.get_coords()) interface.write_xyz(self.atoms_list, self.optimized_coordinates, self.result_xyz_file, self.job_name, energy=self.energy) return True with open('energy.dat', 'a') as fe: fe.writelines("{:3d} {:15.8f} {:15.8f}\n".format(cycle, energy, energy + afir_energy)) else: xtb_turbo_logger.info("cycle exceeded") status = 'cycle_exceeded' self.energy = pyar.interface.turbomole.get_energy() self.optimized_coordinates = bohr2angstrom(pyar.interface.turbomole.get_coords()) return status
def optimize(self, max_cycles=350, gamma=None, restart=False, convergence='normal'): """ :returns: True, 'SCFFailed', 'GradFailed', 'UpdateFailed', 'CycleExceeded', False """ if gamma is not None: xtb_logger.error('not implemented in this module. Use xtb_turbo') with open('xtb.out', 'w') as output_file_pointer: try: out = subp.check_call(self.cmd.split(), stdout=output_file_pointer, stderr=output_file_pointer) except Exception as e: xtb_logger.info(' Optimization failed') xtb_logger.error(f" {e}") return False if os.path.isfile('.xtboptok'): write_xyz(self.atoms_list, self.optimized_coordinates, self.result_xyz_file, job_name=self.job_name, energy=self.energy) os.rename('xtbopt.log', self.trajectory_xyz_file) os.remove('.xtboptok') return True elif os.path.isfile('.sccnotconverged') or os.path.isfile( 'NOT_CONVERGED'): xtb_logger.info( ' SCF Convergence failure in {} run in {}'.format( self.start_xyz_file, os.getcwd())) return 'SCFFailed' else: xtb_logger.info( ' Something went wrong with {} run in {}'.format( self.start_xyz_file, os.getcwd())) return False
def optimize(self, options): """ :return:This object will return the optimization status. It will optimize a structure. """ # TODO: Add a return 'CycleExceeded' max_cycles = options['opt_cycles'] gamma = options['gamma'] convergence = options['opt_threshold'] self.keyword = self.keyword + '!Opt' self.prepare_input() with open(self.out_file, 'w') as fopt: out = subp.Popen([which("orca"), self.inp_file], stdout=fopt, stderr=fopt) out.communicate() out.poll() exit_status = out.returncode if exit_status == 0: f = open(self.out_file, "r") line = f.readlines() if "****ORCA TERMINATED NORMALLY****" in line[-2]: self.energy = self.get_energy() self.optimized_coordinates = np.loadtxt(self.inp_file[:-4] + ".xyz", dtype=float, skiprows=2, usecols=(1, 2, 3)) write_xyz(self.atoms_list, self.optimized_coordinates, self.result_xyz_file, energy=self.energy) f.close() return True else: print("Error: OPTIMIZATION PROBABLY FAILED. " "CHECK THE .out FILE FOR PARTIAL OPTIMIZTION ") print("Check for partial optimization.") print("Location: {}".format(os.getcwd())) return False
def optimize(self, options): """This is the python implementation of jobex of turbomole :returns: Union(True, 'SCFFailed', 'GradFailed', 'UpdateFailed', 'CycleExceeded', False) """ max_cycles = options['opt_cycles'] gamma = options['gamma'] convergence = options['opt_threshold'] if convergence == 'loose': scf_conv = 6 elif convergence == 'tight': scf_conv = 8 else: scf_conv = 7 basis_set = self.basis functional = 'bp' if self.method.lower() == 'bp86': functional = 'bp' if self.method.lower() == 'b3lyp': functional = 'b3-lyp' make_coord(self.atoms_list, self.start_coords) define_status = prepare_control(scf_conv=scf_conv, charge=self.charge, multiplicity=self.multiplicity, basis=basis_set, func=functional) if define_status is False: turbomole_logger.debug( 'Initial Define failed, converting to cartesian coordinate') remove('control') define_status = prepare_control(scf_conv=scf_conv, coordinates='cartesian', charge=self.charge, multiplicity=self.multiplicity) if define_status is False: turbomole_logger.debug('Initial Define failed again. Quit') return 'UpdateFailed' if gamma is None: return self.run_turbomole_jobex(max_cycles=max_cycles) # Test for Turbomole input if not os.path.isfile('control'): turbomole_logger.critical("Turbomole control file should exist") return False with open('not.converged', 'w') as fp: fp.write('$convcrit\n') fp.write(' energy 6\n') fp.write(' cartesian gradient 3\n') fp.write(' basis set gradient 3\n') fp.write(' cycles 1\n') fp.write('$convergence not reached\n') fp.write('$end\n') remove('statistics') remove('dscf_problem') turbomole_logger.info("Turbomole Optimization started\n") turbomole_logger.info(" at %s\n" % datetime.datetime.now()) turbomole_logger.info(" on machine %s\n" % socket.gethostname()) turbomole_logger.info(" by user %s\n" % os.getlogin()) turbomole_logger.info(" in directory %s\n" % os.getcwd()) initial_status, initial_energy = calc_energy() if initial_status is False: turbomole_logger.warning('Initial energy evaluation failed.') return 'SCFFailed' turbomole_logger.debug('First step: %s, %f' % (initial_status, initial_energy)) for cycle in range(max_cycles): # Calculate Gradients gradient_status = calc_gradients() if gradient_status is False: turbomole_logger.error( 'Gradient evaluation failed in cycle %d' % cycle) return 'GradFailed' for line in open('gradient').readlines(): if 'cycle' in line: turbomole_logger.debug(line.strip()) # Calculate afir gradient if gamma is greater than zero # if gamma > 0.0: afir_energy, afir_gradients = restraints.isotropic( self.atoms_in_fragments, self.atoms_list, get_coords(), gamma) rewrite_turbomole_energy_and_gradient_files( self.number_of_atoms, afir_energy, afir_gradients) turbomole_logger.debug(f'restraint energy = {afir_energy:f}') # Update coordinates and check convergence. update_status = update_coord() if update_status is False: turbomole_logger.critical( 'Coordinate update failed in cycle %d' % cycle) turbomole_logger.critical('Check the job in %s' % os.getcwd()) return 'UpdateFailed' convergence_status = check_geometry_convergence() if convergence_status is True: turbomole_logger.info('converged at %d' % cycle) self.energy = get_energy() self.optimized_coordinates = bohr2angstrom(get_coords()) interface.write_xyz(self.atoms_list, self.optimized_coordinates, self.result_xyz_file, self.job_name, energy=self.energy) return True # Calculate energy scf_status, energy = calc_energy() if scf_status is False: turbomole_logger.critical( 'Energy evaluation failed in cycle %d' % cycle) return 'SCFFailed' with open('energy.dat', 'a') as fe: # if gamma > 0.0: fe.writelines("{:3d} {:15.8f} {:15.8f}\n".format( cycle, energy, energy + afir_energy)) # else: # fe.writelines("{:3d} {:15.8f}\n".format(cycle, energy)) else: turbomole_logger.info( "OPTIMIZATION DID NOT CONVERGE WITHIN " "%d CYCLES\n Restarting it after checking " "the gradient norms\n might be a good idea..." " (grep cycle gradient)" % max_cycles) self.energy = get_energy() self.optimized_coordinates = bohr2angstrom(get_coords()) return 'CycleExceeded'