Beispiel #1
0
def relax_atoms(outpath, atoms):
    from ase import optimize

    if os.path.exists(outpath):
        parprint(f'Found existing {outpath}')
        return
    world.barrier()
    parprint(f'Relaxing structure... ({outpath})')

    dyn = optimize.FIRE(atoms)
    dyn.run(fmax=0.05)
    # FIXME: consider using something else to write, like pymatgen.io.vasp.Poscar with significant_figures=15.
    #        ASE always writes {:11.8f} in frac coords, which can be a dangerous amount of rounding
    #        for large unit cells.
    atoms.write(outpath, format='vasp')
Beispiel #2
0
from ase.build import molecule
from ase import optimize
from ase.vibrations.infrared import InfraRed

from gpaw.cluster import Cluster
from gpaw import GPAW, FermiDirac

h = 0.22

atoms = Cluster(molecule('H2'))
atoms.minimal_box(3.5, h=h)

# relax the molecule
calc = GPAW(h=h, occupations=FermiDirac(width=0.1))
atoms.calc = calc
dyn = optimize.FIRE(atoms)
dyn.run(fmax=0.05)
atoms.write('relaxed.traj')

# finite displacement for vibrations
ir = InfraRed(atoms)
ir.run()
def supercell_ionic_relaxation(superCellDefect, optimizer_type = 'QuasiNewton',
                               ladder_begin = 0, ladder_end = 2,
                               charge=0):
	# structure relaxation witht he calculator already existing in the atoms object
	# returns the potential energy of the supercell before and after the relaxation as a tuple
	# 	usage: BR, AR = supercell_ionic_relaxation(defect_supercell)
	# if log ==  False, both potential energy will be 0

	# added support for different types of optimizer
	# local optimizer:  QuasiNewton, BFGS, LBFGS, GPMin, MDMin and FIRE.
	# preconditioned optimizer: to be added
	# global optimizer: to be added 

	# added support for the jacob's ladder
	# the ladder: 
	#			LDA,
	# 			PBE,
	# 			revPBE
	#			RPBE,
	#			PBE0,
	#			B3LYP.

	# ladder_begin, beginning step of the ladder, included
	# ladder_end, ending step of the ladder, NOT INCLUDED

	potential_energy_BR = 0.0
	potential_energy_AR = 0.0

	ladder = ['LDA', 'PBE', 'revPBE', 'RPBE', 'PBE0', 'B3LYP']
	# calc = superCellDefect.get_calculator()
	# calc_backup = calc.get_xc_functional()

	# if log:
	# 	io.write('defect_supercell_before_relaxation.cube', superCellDefect)
	# 	potential_energy_BR = superCellDefect.get_potential_energy()
	# else:
	# 	pass

	if ladder_end > len(ladder):
		ladder_end = len(ladder)

	# loop climbing the ladder
	for calc_step in ladder[ ladder_begin : ladder_end ]:
		# print('=====================', file = log_file)
		# print('starting:', file = log_file)
		# print(calc_step, file = log_file)

		calc = GPAW(mode='fd',
		            kpts={'size': (2, 2, 2), 'gamma': False},
		            xc=calc_step,
		            charge=charge,
		            occupations=FermiDirac(0.01)
		            )

		# calc.set(xc = calc_step)
		superCellDefect.set_calculator(calc)

		if optimizer_type == 'QuasiNewton':
			relax = optimize.QuasiNewton(superCellDefect)
		elif optimizer_type == 'BFGS':
			relax = optimize.BFGS(superCellDefect)
		elif optimizer_type == 'LBFGS':	
			relax = optimize.BFGSLineSearch(superCellDefect)
		elif optimizer_type == 'GPMin':
			relax = optimize.GPMin(superCellDefect)
		elif optimizer_type == 'FIRE':
			relax = optimize.FIRE(superCellDefect)
		elif optimizer_type == 'MDMin':
			relax = optimize.MDMin(superCellDefect)
		else:
			print('optimizer not supported at the moment, falling back to QuasiNewton')
			relax = optimize.QuasiNewton(superCellDefect)

		relax.run(fmax = 0.05)

		potential_current = superCellDefect.get_potential_energy()
		# print('lattice energy after relaxation: %5.7f eV' % potential_current, file = log_file)
		# print('=====================', file = log_file)

	# put the original xc back to the calculator
	# calc.set(xc = calc_backup)

	# relax = QuasiNewton(superCellDefect)
	# relax.run(fmax=0.05)
	
	# if log:
	# 	io.write('defect_supercell_after_relaxation.cube', superCellDefect)
	# 	potential_energy_AR = superCellDefect.get_potential_energy()
	# else:
	# 	pass

	return potential_energy_BR, potential_energy_AR
Beispiel #4
0
def relax_standard(atoms,
                   calc,
                   fmax=5e-2,
                   smax=1e-4,
                   variable_cell=False,
                   trajfile=None,
                   logfile=None,
                   maxsteps=10000,
                   verbose=False,
                   dEmin=1e-3,
                   optimizer='BFGSLineSearch',
                   ucf=False):
    """ Locally optimizes the geometry using the non-preconditioned
    optimizers. Cell optimization is done by alternating
    between fixed-cell and variable-cell relaxations.
    
    atoms: the Atoms object
    calc: a calculator instance to attach to the Atoms object
    fmax: the force convergence criterion (in eV/Angstrom)
    smax: the stress convergence criterion (in eV/Angstrom^3)
    variable_cell: whether to also optimize the cell vectors
    trajfile: filename of the trajectory to attach to the optimizers
    logfile: filename of the logfile for the optimizers
    maxsteps: maximum allowed total number of ionic steps
    verbose: whether to print output or remain silent
    dEmin: minimum (absolute) energy difference for the main loop
           iterations; if the energy difference is smaller, the
           minimization is aborted
    optimizer: name of the ASE optimizer
    ucf: whether to use a UnitCellFilter (True) or StrainFilter(False)
         during the variable-cell relaxations
    """
    if variable_cell:
        atoms.set_pbc(True)
    else:
        smax = None

    atoms.wrap()
    atoms.set_calculator(calc)
    nsteps = 0

    if trajfile is not None:
        if os.path.exists(trajfile):
            os.remove(trajfile)
        traj = Trajectory(trajfile, 'a', atoms)
    else:
        traj = None

    niter = 0
    maxiter = 100
    steps = 50 if variable_cell else 125
    while nsteps < maxsteps and niter < maxiter:
        try:
            if optimizer in ['BFGS', 'BFGSLineSearch', 'LBFGSLineSearch']:
                dyn = getattr(optimize, optimizer)(atoms,
                                                   logfile=logfile,
                                                   maxstep=0.2)
            elif optimizer == 'FIRE':
                dyn = optimize.FIRE(atoms,
                                    logfile=logfile,
                                    dt=0.025,
                                    finc=1.25,
                                    dtmax=0.3,
                                    maxmove=0.2)
            if traj is not None:
                dyn.attach(traj)
            vb = VarianceError(atoms, dyn)
            dyn.attach(vb)
            dyn.run(fmax=fmax, steps=steps)
            nsteps += dyn.get_number_of_steps()
        except (RuntimeError, np.linalg.linalg.LinAlgError) as err:
            # Sometimes, BFGS can fail due to
            # numpy.linalg.linalg.LinAlgError:
            # Eigenvalues did not converge
            nsteps += dyn.get_number_of_steps()
            dyn = optimize.FIRE(atoms,
                                logfile=logfile,
                                dt=0.05,
                                finc=1.25,
                                dtmax=0.3,
                                maxmove=0.2)
            if traj is not None:
                dyn.attach(traj)
            vb = VarianceError(atoms, dyn)
            dyn.attach(vb)
            try:
                dyn.run(fmax=fmax, steps=steps)
            except RuntimeError:
                pass
            nsteps += dyn.get_number_of_steps()

        if variable_cell:
            filt = UnitCellFilter(atoms) if ucf else StrainFilter(atoms)
            dyn = optimize.MDMin(filt, dt=0.05, logfile=logfile)
            if traj is not None:
                dyn.attach(traj)
            dyn.run(fmax=fmax, steps=5)
            nsteps += dyn.get_number_of_steps()

        niter += 1

        if is_converged(atoms, fmax=fmax, smax=smax):
            break

    E = atoms.get_potential_energy()
    F = atoms.get_forces()
    S = atoms.get_stress() if variable_cell else None

    if verbose:
        print('Done E=%8.3f, maxF=%5.3f, maxS=%5.3e, ncalls=%d'% \
              (E, (F ** 2).sum(axis=1).max() ** 0.5,
               0. if S is None else np.max(np.abs(S)), nsteps))

    finalize(atoms, energy=E, forces=F, stress=S)
    return atoms
Beispiel #5
0
    txt='polyethene.cal')
calc3 = Hotbit(SCC=True,
               coulomb_solver=MultipoleExpansion(8, 3, (1, 1, 5)),
               verbose_SCC=True,
               kpts=(1, 1, 20),
               mixer={
                   'name': 'anderson',
                   'convergence': 1e-6
               },
               txt='polyethene.cal')

for calc in [calc2, calc3]:
    atoms.set_calculator(calc)

    # Relax (twist) the structure
    q = optimize.FIRE(atoms, trajectory='polyethene.trj', logfile=None)
    q.run(fmax=0.5)

    # Displace atoms from their equilibrium positions and check forces
    atoms.rattle(0.1)

    # Check electrostatics only
    #    atoms.set_initial_charges([1.0,1.0,1.0,1.0,-1.0,-1.0,-1.0,-1.0])
    #    atoms.set_calculator(calc.st.es)

    # Check forces from finite differences
    ffd, f0, err = check_forces(atoms, dx=1e-6)
    if debug:
        print "Finite differences forces:"
        print ffd
        print "Analytical forces:"
box = 5.     # box dimension
h = 0.25     # grid spacing
width = 0.01 # Fermi width
nbands = 6   # bands in GS calculation
nconv = 4    # bands in GS calculation to converge
R = 2.99     # starting distance
iex = 1      # excited state index
d = 0.01     # step for numerical force evaluation
exc = 'LDA'  # xc for the linear response TDDFT kernel

s = Cluster([Atom('Na'), Atom('Na', [0, 0, R])])
s.minimal_box(box, h=h)

c = GPAW(h=h, nbands=nbands, eigensolver='cg',
         occupations=FermiDirac(width=width),
         setups={'Na': '1'},
         convergence={'bands':nconv})
c.calculate(s)
lr = LrTDDFT(c, xc=exc, eps=0.1, jend=nconv-1)

ex = ExcitedState(lr, iex, d=d)
s.set_calculator(ex)

ftraj='relax_ex' + str(iex)
ftraj += '_box' + str(box) + '_h' + str(h)
ftraj += '_d' + str(d) + '.traj'
traj = io.PickleTrajectory(ftraj, 'w', s)
dyn = optimize.FIRE(s)
dyn.attach(traj.write)
dyn.run(fmax=0.05)