def optimize(method, **kwargs): '''Optimize the geometry with the given method. ''' mol = copy.copy(method.mol) if 'log' in kwargs: log = lib.logger.new_logger(method, kwargs['log']) elif 'verbose' in kwargs: log = lib.logger.new_logger(method, kwargs['verbose']) else: log = lib.logger.new_logger(method) # geom = optimize_berny(as_berny_solver(method), to_berny_geom(mol), # log=to_berny_log(log), **kwargs) # temporary interface, taken from berny.py optimize function log = to_berny_log(log) solver = as_berny_solver(method, kwargs.get('assert_convergence', False)) geom = to_berny_geom(mol) next(solver) optimizer = Berny(geom, log=log, **kwargs) for geom in optimizer: energy, gradients = solver.send(list(geom)) optimizer.send((energy, gradients)) mol.set_geom_(geom_to_atom(geom)) return mol
def optimize(method, assert_convergence=ASSERT_CONV, include_ghost=INCLUDE_GHOST, **kwargs): '''Optimize the geometry with the given method. ''' mol = copy.copy(method.mol) if 'log' in kwargs: log = lib.logger.new_logger(method, kwargs['log']) elif 'verbose' in kwargs: log = lib.logger.new_logger(method, kwargs['verbose']) else: log = lib.logger.new_logger(method) # geom = optimize_berny(as_berny_solver(method), to_berny_geom(mol), # log=to_berny_log(log), **kwargs) # temporary interface, taken from berny.py optimize function log = to_berny_log(log) solver = as_berny_solver(method, assert_convergence, include_ghost) geom = to_berny_geom(mol, include_ghost) next(solver) optimizer = Berny(geom, log=log, **kwargs) for geom in optimizer: energy, gradients = solver.send(geom) optimizer.send((energy, gradients)) mol.set_geom_(_geom_to_atom(mol, geom, include_ghost), unit='Bohr') return mol
def optimize(method, assert_convergence=ASSERT_CONV, include_ghost=INCLUDE_GHOST, callback=None, **kwargs): '''Optimize the geometry with the given method. ''' mol = method.mol.copy() if 'log' in kwargs: log = lib.logger.new_logger(method, kwargs['log']) elif 'verbose' in kwargs: log = lib.logger.new_logger(method, kwargs['verbose']) else: log = lib.logger.new_logger(method) # temporary interface, taken from berny.py optimize function berny_log = to_berny_log(log) solver = as_berny_solver(method, assert_convergence, include_ghost) geom = to_berny_geom(mol, include_ghost) optimizer = Berny(geom, log=berny_log, **kwargs) e_last = 0 for cycle, geom in enumerate(optimizer): if log.verbose >= lib.logger.NOTE: log.note('\nGeometry optimization cycle %d', cycle + 1) _dump_mol_geometry(mol, geom, log) mol.set_geom_(_geom_to_atom(mol, geom, include_ghost), unit='Bohr') energy, gradients = solver(mol) log.note('cycle %d: E = %.12g dE = %g norm(grad) = %g', cycle + 1, energy, energy - e_last, numpy.linalg.norm(gradients)) e_last = energy optimizer.send((energy, gradients)) if callable(callback): callback(locals()) return mol
def optimize(self, solver): mol = self.mol_origin geom_outer = self.mol_to_geom(mol) optimizer = Berny(geom_outer, verbosity=(2 + LOGLEVEL), gradientmax=self.gradientmax, gradientrms=self.gradientrms, stepmax=self.stepmax, steprms=self.steprms) for geom in optimizer: mol_opt = self.geom_to_mol(mol, geom) print("In optimization: Molecular geom") print(mol_opt.atom_coords() * lib.param.BOHR) energy, gradients = solver(mol_opt) optimizer.send((energy, gradients)) geom_outer = geom return self.geom_to_mol(mol, geom_outer)
def run(self): if self.optg_berny: # now optg gconv = self.gconvs_berny[self.param['gconv']] gradientmax, gradientrms, stepmax, steprms = [ gconv[k] \ for k in ['gradientmax', 'gradientrms', 'stepmax', 'steprms'] ] optimizer = Berny(geomlib.readfile(self.fn+'.xyz'), \ gradientmax = gradientmax, \ gradientrms = gradientrms, \ steprms=steprms, stepmax=stepmax, \ maxsteps=self.param['maxit']) solver = self.get_energy_and_gradient() next(solver) coords_a = [] es_a = [] grads_a = [] idx = 0 for geom in optimizer: atoms = list(geom) if not isinstance(atoms[0], tuple): atoms = atoms[-1] print(' * idx = ', idx) #if idx == 0 and (self.gradients is not None): # energy, gradients = self.energy, self.gradients #else: energy, gradients = solver.send((atoms, None)) coords_a.append(geom.coords) es_a.append(energy) grads_a.append(gradients) idx += 1 optimizer.send((energy, gradients)) self.coords_a = coords_a self.grads_a = grads_a self.es_a = es_a self.coords = coords_a[-1] self.gradients = grads_a[-1] self.energy = es_a[-1] else: mol = cc.molecules(self.fn + '.xyz') gmol = cmc.RawMol(mol) self.get_energy(gmol)
def kernel(method, assert_convergence=ASSERT_CONV, include_ghost=INCLUDE_GHOST, callback=None, **kwargs): '''Optimize geometry with pyberny for the given method. To adjust the convergence threshold, parameters can be set in kwargs as below: .. code-block:: python conv_params = { # They are default settings 'gradientmax': 0.45e-3, # Eh/Angstrom 'gradientrms': 0.15e-3, # Eh/Angstrom 'stepmax': 1.8e-3, # Angstrom 'steprms': 1.2e-3, # Angstrom } from pyscf.geomopt import berny_solver opt = berny_solver.GeometryOptimizer(method) opt.params = conv_params opt.kernel() ''' t0 = time.clock(), time.time() mol = method.mol.copy() if 'log' in kwargs: log = lib.logger.new_logger(method, kwargs['log']) elif 'verbose' in kwargs: log = lib.logger.new_logger(method, kwargs['verbose']) else: log = lib.logger.new_logger(method) if isinstance(method, lib.GradScanner): g_scanner = method elif getattr(method, 'nuc_grad_method', None): g_scanner = method.nuc_grad_method().as_scanner() else: raise NotImplementedError('Nuclear gradients of %s not available' % method) if not include_ghost: g_scanner.atmlst = numpy.where(method.mol.atom_charges() != 0)[0] # When symmetry is enabled, the molecule may be shifted or rotated to make # the z-axis be the main axis. The transformation can cause inconsistency # between the optimization steps. The transformation is muted by setting # an explict point group to the keyword mol.symmetry (see symmetry # detection code in Mole.build function). if mol.symmetry: mol.symmetry = mol.topgroup # temporary interface, taken from berny.py optimize function berny_log = to_berny_log(log) geom = to_berny_geom(mol, include_ghost) optimizer = Berny(geom, log=berny_log, **kwargs) t1 = t0 e_last = 0 for cycle, geom in enumerate(optimizer): if log.verbose >= lib.logger.NOTE: log.note('\nGeometry optimization cycle %d', cycle+1) dump_mol_geometry(mol, geom.coords, log) if mol.symmetry: geom.coords = symmetrize(mol, geom.coords) mol.set_geom_(_geom_to_atom(mol, geom, include_ghost), unit='Bohr') energy, gradients = g_scanner(mol) log.note('cycle %d: E = %.12g dE = %g norm(grad) = %g', cycle+1, energy, energy - e_last, numpy.linalg.norm(gradients)) e_last = energy if callable(callback): callback(locals()) if assert_convergence and not g_scanner.converged: raise RuntimeError('Nuclear gradients of %s not converged' % method) optimizer.send((energy, gradients)) t1 = log.timer('geomoetry optimization cycle %d'%cycle, *t1) t0 = log.timer('geomoetry optimization', *t0) return optimizer._converged, mol
def TestBernyOpt(): from berny import Berny, geomlib # a=MSet("kaggle_opt") # a.Load() # m=a.mols[8804] # m = Mol() # m.FromXYZString("""73 xyz = """73 O 3.11000 4.22490 -0.75810 O 4.72290 2.06780 -2.02160 O 3.28790 0.27660 -2.12830 O 7.57740 -2.18410 0.83530 O 6.93870 -0.24500 1.85400 N -0.44900 1.57680 0.54520 N 0.67240 -1.09000 0.16920 N -3.08650 0.73580 0.30880 N -2.08930 -2.17120 0.36140 C 3.15530 1.80910 -0.26920 C 1.94310 0.99350 0.14610 C 1.10470 3.11900 -0.07220 C 0.85730 1.76100 0.25120 C 2.53600 3.20940 -0.40610 C -0.01170 3.83890 -0.00490 C 1.80260 -0.45930 0.35870 C -0.97430 2.76340 0.37660 C 2.91740 -1.33270 0.77810 C 2.32400 -2.53760 0.79670 C 3.70160 1.28460 -1.55560 C 0.92000 -2.41280 0.43150 C -2.41080 3.07580 0.55540 C -0.29110 5.26060 -0.27150 C -3.30810 2.07470 0.53020 C -4.22430 -0.01890 0.37480 C -1.33840 -3.26350 -0.02560 C 0.02500 -3.41140 0.34800 C -4.76240 2.20220 0.74210 C -5.29980 0.95570 0.65430 C -3.38890 -2.29630 -0.08630 C -2.18770 -4.11130 -0.70980 C -3.46520 -3.50710 -0.75000 C 4.24800 -0.96910 1.13640 C -4.40070 -1.34110 0.20870 C 2.93270 -3.85050 1.16890 C -6.72700 0.53540 0.79750 C -1.82240 -5.42330 -1.29120 C -5.50430 3.40910 1.00050 C -4.63100 -4.03780 -1.35240 C 5.32530 -1.71620 0.83820 C 5.31710 1.65030 -3.25560 C -6.03270 4.16680 0.03880 C -5.68440 -3.34470 -1.89440 C 6.67040 -1.26750 1.24620 H 3.91490 1.82320 0.51520 H -2.69930 4.10740 0.71860 H -0.66660 5.75450 0.62990 H 0.61110 5.79090 -0.59250 H -1.03960 5.36580 -1.06280 H 0.35400 -4.43150 0.53040 H -5.40880 -1.73500 0.30730 H 4.36030 -0.04870 1.70090 H 3.88280 -3.75330 1.69880 H 2.27760 -4.40220 1.85250 H 3.09460 -4.46420 0.27690 H -6.83900 -0.17840 1.62010 H -7.08680 0.06850 -0.12540 H -7.38530 1.38280 1.01220 H -2.13640 -6.23380 -0.62560 H -2.30250 -5.57200 -2.26410 H -0.74330 -5.51440 -1.45110 H -5.62320 3.69670 2.04090 H -4.70070 -5.12240 -1.41710 H 5.25800 -2.63030 0.25800 H 4.57150 1.65850 -4.05620 H 5.75710 0.65460 -3.14550 H 6.11050 2.35890 -3.50730 H -6.58170 5.06770 0.29090 H -5.93330 3.91260 -1.01130 H -6.51300 -3.89300 -2.33170 H -5.71990 -2.26400 -1.94770 H 8.49250 -1.93230 1.08330 Mg -1.34673 0.02041 -0.06327""" init_mol = Mol() init_mol.FromXYZString(xyz) # init_mol = a.mols[0] net = UniversalNetwork(name="SF_Universal_master_jeherr_Thu_May_31_16.20.05_2018") EF = net.GetEnergyForceRoutine(init_mol) optimizer = Berny( geomlib.loads(init_mol.__str__(), 'xyz'), maxsteps=5000) # gradientrms=0.0001, # gradientmax=0.003, # debug=True) debug = [] last_geom = "" init_mol.WriteXYZfile(fname="chlorophyll_berny") for geom in optimizer: molecule_xyz = geom.dumps('xyz') molecule = Mol() molecule.FromXYZString(molecule_xyz) molecule.WriteXYZfile(fname="chlorophyll_berny") energy, gradients = EF(molecule.coords) # calculate energy and gradients of geom info = optimizer.send((energy, gradients)) debug.append(info) print('Final Geometry:') print(geom.dumps('xyz'))
def optimize(method, assert_convergence=ASSERT_CONV, include_ghost=INCLUDE_GHOST, callback=None, **kwargs): '''Optimize geometry with pyberny for the given method. To adjust the convergence threshold, parameters can be set in kwargs as below: .. code-block:: python conv_params = { # They are default settings 'gradientmax': 0.45e-3, # Eh/Angstrom 'gradientrms': 0.15e-3, # Eh/Angstrom 'stepmax': 1.8e-3, # Angstrom 'steprms': 1.2e-3, # Angstrom } from pyscf import geometric_solver geometric_solver.optimize(method, **conv_params) ''' t0 = time.clock(), time.time() mol = method.mol.copy() if 'log' in kwargs: log = lib.logger.new_logger(method, kwargs['log']) elif 'verbose' in kwargs: log = lib.logger.new_logger(method, kwargs['verbose']) else: log = lib.logger.new_logger(method) if isinstance(method, lib.GradScanner): g_scanner = method elif getattr(method, 'nuc_grad_method', None): g_scanner = method.nuc_grad_method().as_scanner() else: raise NotImplementedError('Nuclear gradients of %s not available' % method) if not include_ghost: g_scanner.atmlst = numpy.where(method.mol.atom_charges() != 0)[0] # temporary interface, taken from berny.py optimize function berny_log = to_berny_log(log) geom = to_berny_geom(mol, include_ghost) optimizer = Berny(geom, log=berny_log, **kwargs) t1 = t0 e_last = 0 for cycle, geom in enumerate(optimizer): if log.verbose >= lib.logger.NOTE: log.note('\nGeometry optimization cycle %d', cycle+1) dump_mol_geometry(mol, geom.coords, log) mol.set_geom_(_geom_to_atom(mol, geom, include_ghost), unit='Bohr') energy, gradients = g_scanner(mol) log.note('cycle %d: E = %.12g dE = %g norm(grad) = %g', cycle+1, energy, energy - e_last, numpy.linalg.norm(gradients)) e_last = energy if callable(callback): callback(locals()) if assert_convergence and not g_scanner.converged: raise RuntimeError('Nuclear gradients of %s not converged' % method) optimizer.send((energy, gradients)) t1 = log.timer('geomoetry optimization cycle %d'%cycle, *t1) t0 = log.timer('geomoetry optimization', *t0) return mol
# Make wrapper functions for energy, force and dipole def EnergyAndForce(molecule): (Etotal, Ebp, Ebp_atom, Ecc, Evdw, mol_dipole, atom_charge, gradient) = manager.EvalBPDirectEEUpdateSingle(molecule, PARAMS["AN1_r_Rc"], PARAMS["AN1_a_Rc"], PARAMS["EECutoffOff"], True) energy = Etotal return energy[0], (-1.0 * gradient[0] / JOULEPERHARTREE) optimizer = Berny(geomlib.loads(xyz, 'xyz'), maxsteps=1000, gradientrms=0.0003, gradientmax=0.003, debug=True) debug = [] last_geom = "" for geom in optimizer: molecule_xyz = geom.dumps('xyz') molecule = Mol() molecule.FromXYZString(molecule_xyz) energy, gradients = EnergyAndForce( molecule) # calculate energy and gradients of geom info = optimizer.send((energy, gradients)) debug.append(info) print('Final Geometry:') print(geom.dumps('xyz'))
os.chdir('../') return etot, gtot #start of pyberny optimizer obj_list[0].write_xyz(coords_name) os.path.abspath(os.curdir) optimizer = Berny(geomlib.readfile(os.path.abspath(coords_name)), debug=True) count = 0 etot_opt = 0 grad_opt = 0 for geom in optimizer: print("\n opt cycle:", count, "\n") solver = opt_fnc(geom.coords, count) count = count + 1 optimizer.send(solver) etot_opt = solver[0] grad_opt = solver[1] relaxed = geom #writing optimized coords to .xyz file os.chdir(folder) coordsname = open("opt_coords.xyz", "w") string = str(len(relaxed.species)) + '\n' for i in range(0, len(relaxed.species)): string += str(relaxed.species[i]) + " " string += str(relaxed.coords[i]).replace("[", "").replace("]", "") + '\n' print(string) coordsname.write(string)
def optimize(self): fout_xyz = open(self._geomopt['fname_gopt_xyz'], 'w', 1) fout_log = open(self._geomopt['fname_gopt_log'], 'w', 1) optimizer = Berny(self._qm_geom) qm_natom = len(self._qm_geom) def step_func(x): if x < -0.5: x = -0.5 elif x > 0.5: x = 0.5 return x qm_crds_old = self._qm_geom.coords prt_crds = self._prt_geom.coords ener_last = 0.0 qm_grd_norm_last = 0.0 ener_QM0 = 0.0 for cycle, qm_geom in enumerate(optimizer): qm_crds_new = qm_geom.coords d_crds = qm_crds_new - qm_crds_old for atmId in self._qm2mm_index: resId, atomName = atmId.split(':') if resId not in ['LIG1']: mm_idx = self._qm2mm_index[atmId] qm_idx = self._qmatm_index[atmId] if atomName not in ['CA']: prt_crds[mm_idx] = qm_crds_new[qm_idx] ener_QMMM, ener_const, grds_QM, esp_QM, \ ener_QMMM_vdw, ener_PRT, grds_PRT = self.pot_grad( qm_geom, prt_crds) if cycle == 0: ener_QM0 = ener_QMMM ener_QMMM -= ener_QM0 ener = ener_QMMM + ener_const + ener_QMMM_vdw + ener_PRT qm_grd_norm = np.linalg.norm(grds_QM) print(' %5d' % qm_natom, file=fout_xyz) print('cycle %3d: E = %12.6f %12.6f %10.4f %10.4f %10.4f %12.6f' % (cycle + 1, ener, ener_QMMM, ener_const, ener_QMMM_vdw, ener_PRT, ener_QM0), file=fout_xyz) print( 'cycle %3d: E = %12.6f %12.6f %10.4f %10.4f %10.4f dE = %.6g norm(grad) = %g' % (cycle + 1, ener, ener_QMMM, ener_const, ener_QMMM_vdw, ener_PRT, ener - ener_last, qm_grd_norm), file=fout_log) for i in range(qm_natom): print('%4s %10.6f %10.6f %10.6f' % (self._qm_geom.species[i], qm_crds_new[i, 0], qm_crds_new[i, 1], qm_crds_new[i, 2]), file=fout_xyz) print('%5d %4s %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f' % ((i + 1), self._qm_geom.species[i], d_crds[i, 0], d_crds[i, 1], d_crds[i, 2], grds_QM[i, 0], grds_QM[i, 1], grds_QM[i, 2]), file=fout_log) if (cycle + 1) % 2 == 0: self.save_coordinates(qm_crds_new, prt_crds) dE = ener - ener_last if abs(dE) / qm_natom < 1.0e-8: break dG = qm_grd_norm - qm_grd_norm_last if abs(dG) / qm_natom < 1.0e-8: break ener_last = ener qm_grd_norm_last = qm_grd_norm qm_crds_old = qm_crds_new for atmId in self._qm2mm_index: resId, atomName = atmId.split(':') if resId[:3] not in ['LIG'] and atomName not in ['CA']: ''' 'CA' belongs to MM Except 'CA', bond, angle, and torsional gradients, which are estimated within MM, are copied to QM particles. ''' mm_idx = self._qm2mm_index[atmId] qm_idx = self._qmatm_index[atmId] grds_QM[qm_idx] += grds_PRT[mm_idx] grds_PRT[mm_idx, 0] = 0 grds_PRT[mm_idx, 1] = 0 grds_PRT[mm_idx, 2] = 0 grds_PRT = np.array([[step_func(x), step_func(y), step_func(z)] for x, y, z in grds_PRT]) prt_crds -= 0.01 * grds_PRT grds_QM = np.array([[step_func(x), step_func(y), step_func(z)] for x, y, z in grds_QM]) optimizer.send((ener, grds_QM)) self.save_coordinates(qm_crds_old, prt_crds)