def calc_new(self, coords, dirname): if self.cycle >= self.maxsteps: raise NotConvergedError( 'Geometry optimization is not converged in ' '%d iterations' % self.maxsteps) g_scanner = self.scanner mol = self.mol self.cycle += 1 lib.logger.note(g_scanner, '\nGeometry optimization cycle %d', self.cycle) # geomeTRIC requires coords and gradients in atomic unit coords = coords.reshape(-1, 3) if g_scanner.verbose >= lib.logger.NOTE: dump_mol_geometry(mol, coords * lib.param.BOHR) if mol.symmetry: coords = symmetrize(mol, coords) mol.set_geom_(coords, unit='Bohr') energy, gradients = g_scanner(mol) lib.logger.note(g_scanner, 'cycle %d: E = %.12g dE = %g norm(grad) = %g', self.cycle, energy, energy - self.e_last, numpy.linalg.norm(gradients)) self.e_last = energy if callable(self.callback): self.callback(locals()) if self.assert_convergence and not g_scanner.converged: raise RuntimeError('Nuclear gradients of %s not converged' % g_scanner.base) return {"energy": energy, "gradient": gradients.ravel()}
def calc_new(self, coords, dirname): if self.cycle >= self.maxsteps: raise NotConvergedError('Geometry optimization is not converged in ' '%d iterations' % self.maxsteps) g_scanner = self.scanner mol = self.mol lib.logger.note(g_scanner, '\nGeometry optimization step %d', self.cycle) self.cycle += 1 # geomeTRIC requires coords and gradients in atomic unit coords = coords.reshape(-1,3) if g_scanner.verbose >= lib.logger.NOTE: dump_mol_geometry(mol, coords*lib.param.BOHR) if mol.symmetry: coords = symmetrize(mol, coords) mol.set_geom_(coords, unit='Bohr') energy, gradients = g_scanner(mol) if callable(self.callback): self.callback(locals()) if self.assert_convergence and not g_scanner.converged: raise RuntimeError('Nuclear gradients of %s not converged' % g_scanner.base) return {"energy": energy, "gradient": gradients.ravel()}
def test_symmetrize(self): mol = gto.M(atom=''' O 0. 0. 0. H 0. -0.757 0.587 H 0. 0.757 0.587 ''', symmetry=True) coords = mol.atom_coords() sym_coords = addons.symmetrize(mol, coords) self.assertAlmostEqual(abs(coords-sym_coords).max(), 0, 9)
def test_symmetrize(self): mol = gto.M(atom=''' O 0. 0. 0. H 0. -0.757 0.587 H 0. 0.757 0.587 ''', symmetry=True) coords = mol.atom_coords() sym_coords = addons.symmetrize(mol, coords) self.assertAlmostEqual(abs(coords - sym_coords).max(), 0, 9)
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