示例#1
0
    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()}
示例#2
0
    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)
        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, gradients.ravel()
示例#3
0
    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()}
示例#4
0
 def calc_new(self, coords, dirname):
     scanner = self.scanner
     mol = scanner.mol
     lib.logger.note(scanner, '\nGeometry optimization step %d', self.cycle)
     self.cycle += 1
     # geomeTRIC handles coords and gradients in atomic unit
     coords = coords.reshape(-1,3)
     if scanner.verbose >= lib.logger.NOTE:
         dump_mol_geometry(self.scanner.mol, coords*lib.param.BOHR)
     mol.set_geom_(coords, unit='Bohr')
     energy, gradient = scanner(mol)
     if scanner.assert_convergence and not scanner.converged:
         raise RuntimeError('Nuclear gradients of %s not converged' % scanner.base)
     return energy, gradient.ravel()
示例#5
0
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
示例#6
0
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