def movie_maker(): grad = bohr2angstrom(np.array(get_gradients(), dtype=float)) coordinates = bohr2angstrom(get_coords()) energy = get_energy() atoms_list = [ c.split()[-1] for c in open('coord').read().split('$')[1].split('\n')[1:-1] ] with open('movie.xyz', 'w') as fp: fp.write("%3d\n" % len(coordinates)) fp.write('original:' + str(energy) + '\n') for a, c in zip(atoms_list, coordinates): fp.write("{:<2}{:12.5f}{:12.5f}{:12.5f}\n".format( a.upper(), c[0], c[1], c[2])) steps = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1 - 2, -3 - 4 - 5, -6, -7, -8. - 9, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0 ] for i in steps: with open('movie.xyz', 'a') as fp: fp.write("%3d\n" % len(coordinates)) fp.write(str(i) + ':' + str(energy) + '\n') for a, c, g in zip(atoms_list, coordinates, grad): fp.write("{:<2}{:12.5f}{:12.5f}{:12.5f}\n".format( a.upper(), c[0] + g[0] * i, c[1] + g[1] * i, c[2] + g[2] * i))
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, 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'
def run_turbomole_jobex(self, max_cycles=350): """ Run a turbomole optimisation. return one of the following: True: converged SCFFailed GradFailed UpdateFailed CycleExceeded False: unknown error or jebex execution 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.debug('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.debug( 'Error in module!\n chcek %s/GEO_OPT_FAILED' % os.getcwd()) return False elif 'ERROR in statpt step,' in message: turbomole_logger.debug( 'Statpt failed!\n chcek %s/GEO_OPT_FAILED' % os.getcwd()) return 'UpdateFailed' elif 'ERROR in relax step,' in message: turbomole_logger.debug( 'Relax failed!\n chcek %s/GEO_OPT_FAILED' % os.getcwd()) return 'UpdateFailed' elif 'ERROR: your energy calculation did not converge !!,' in message: turbomole_logger.debug( 'SCF failed!\n chcek %s/GEO_OPT_FAILED' % os.getcwd()) return 'SCFFailed' elif 'ERROR in dscf step' in message: turbomole_logger.debug( 'SCF failed!\n chcek %s/GEO_OPT_FAILED' % os.getcwd()) return 'SCFFailed' elif 'ERROR in gradient step' in message: turbomole_logger.debug( 'Gradient failed!\n chcek %s/GEO_OPT_FAILED' % os.getcwd()) return 'GradientFailed' elif 'OPTIMIZATION DID NOT CONVERGE' in message: turbomole_logger.debug( '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.debug( '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