def test_opt_with_precon(atoms, forcefield_params):
    kw = dict(forcefield_params)
    kw.pop('vdws')
    precon = FF(**kw)
    opt = PreconLBFGS(atoms, use_armijo=True, precon=precon)
    opt.run(fmax=0.1)
    e = atoms.get_potential_energy()
    assert abs(e - ref_energy) < 0.01
def symmetrized_optimisation(at_init, filter):
    rng = np.random.RandomState(1)
    at = at_init.copy()
    at.calc = NoisyLennardJones(rng=rng)

    at_cell = filter(at)
    dyn = PreconLBFGS(at_cell, precon=None)
    print("Initial Energy", at.get_potential_energy(), at.get_volume())
    dyn.run(steps=300, fmax=0.001)
    print("n_steps", dyn.get_number_of_steps())
    print("Final Energy", at.get_potential_energy(), at.get_volume())
    print("Final forces\n", at.get_forces())
    print("Final stress\n", at.get_stress())

    print("initial symmetry at 1e-6")
    di = check_symmetry(at_init, 1.0e-6, verbose=True)
    print("final symmetry at 1e-6")
    df = check_symmetry(at, 1.0e-6, verbose=True)
    return di, df
Exemple #3
0
def do_lattice(bulk, elastic=True):
    tol = 1e-3  # max force tol for relaxation
    n_E_vs_V_steps = 10

    # use one of the routines from utilities module to relax the initial
    # unit cell and atomic positions
    bulk = relax_atoms_cell(bulk, tol=tol, traj_file=None, symmetrize=True)

    print("relaxed bulk")
    ase.io.write(sys.stdout, bulk, format='extxyz')

    if elastic:
        # reset calculator to non-symmetrized one (not optimal, but would otherwise need to have optimizer used by fit_elastic_constants to reset symmetry for each relaxation):w
        calc = bulk.get_calculator().calc
        bulk.set_calculator(calc)
        precon = Exp(3.0)
        opt = lambda atoms, **kwargs: PreconLBFGS(
            atoms, precon=precon, **kwargs)
        elastic_consts = matscipy.elasticity.fit_elastic_constants(
            bulk, symmetry='cubic', optimizer=opt)
        c11 = elastic_consts[0][0, 0] / GPa
        c12 = elastic_consts[0][0, 1] / GPa
        c44 = elastic_consts[0][3, 3] / GPa

    V0 = bulk.get_volume()
    E_vs_V = []

    f = open("relaxed_E_vs_V_configs.xyz", "w")
    cell_scalings = np.linspace(0.90**(1.0 / 3.0), 1.1**(1.0 / 3.0), 30)
    for cell_scaling in cell_scalings:
        scaled_bulk = bulk.copy()
        scaled_bulk.set_calculator(bulk.get_calculator())
        scaled_bulk.set_cell(scaled_bulk.get_cell() * cell_scaling,
                             scale_atoms=True)
        scaled_bulk = relax_atoms_cell(scaled_bulk,
                                       tol=tol,
                                       traj_file=None,
                                       constant_volume=True,
                                       method='fire',
                                       symmetrize=True)
        # evaluate(scaled_bulk)
        ase.io.write(f, scaled_bulk, format='extxyz')
        E_vs_V.insert(0, (scaled_bulk.get_volume() / len(scaled_bulk),
                          scaled_bulk.get_potential_energy() / len(bulk)))

    for (V, E) in E_vs_V:
        print("EV_final ", V, E)

    if elastic:
        return (c11, c12, c44, E_vs_V)
    else:
        return (E_vs_V)
def relax_atoms(atoms,
                tol=1e-3,
                method='lbfgs_precon',
                max_steps=1000,
                traj_file=None,
                **kwargs):
    import model
    atoms.set_calculator(model.calculator)
    if hasattr(model, 'Optimizer'):
        method = 'model_optimizer'
        opt = model.Optimizer(atoms)
        opt.run(tol, max_steps)
    elif method.startswith('lbfgs') or method == 'fire' or method == 'cg_n':
        if method == 'lbfgs_ASE':
            from ase.optimize import LBFGS
            opt = LBFGS(atoms, **kwargs)
        elif method == 'cg_n':
            from quippy import Minim
            opt = Minim(atoms,
                        relax_positions=True,
                        relax_cell=False,
                        method='cg_n')
        else:
            from ase.optimize.precon.precon import Exp
            from ase.optimize.precon.lbfgs import PreconLBFGS
            precon = None
            if method.endswith('precon'):
                precon = Exp(3.0, recalc_mu=True)
            if method.startswith('lbfgs'):
                opt = PreconLBFGS(atoms, precon=precon, **kwargs)
            else:
                opt = FIRE(atoms, **kwargs)
        if traj_file is not None and method != 'cg_n':
            traj = open(traj_file, 'w')

            def write_trajectory():
                write(traj, atoms, format='extxyz')

            opt.attach(write_trajectory)
        opt.run(tol, max_steps)
        try:
            traj.close()
        except:
            pass
    else:
        raise ValueError('unknown method %s!' % method)

    return atoms
Exemple #5
0
        if vdw_list[i, j]:
            vdws.append(
                VdW(atomi=i,
                    atomj=j,
                    epsilonij=vdw_epsilonij,
                    rminij=vdw_rminij))

# set up ForceField calculator
calc = ForceField(morses=morses, angles=angles, dihedrals=dihedrals, vdws=vdws)

a1 = a.copy()
a1.set_calculator(calc)
a1.rattle(0.05)

# geometry optimisation without preconditioner
opt = PreconLBFGS(a1, use_armijo=True, precon='ID')
opt.run(fmax=0.1)
e1 = a1.get_potential_energy()

a2 = a.copy()
a2.set_calculator(calc)
a2.rattle(0.05)

# geometry optimisation with FF based preconditioner
precon = FF(morses=morses, angles=angles, dihedrals=dihedrals)

opt = PreconLBFGS(a2, use_armijo=True, precon=precon)
opt.run(fmax=0.1)
e2 = a2.get_potential_energy()

print(e1, e2)
def test_opt_no_precon(atoms):
    opt = PreconLBFGS(atoms, use_armijo=True, precon='ID')
    opt.run(fmax=0.1)
    e = atoms.get_potential_energy()
    assert abs(e - ref_energy) < 0.01
def relax_atoms_cell(atoms,
                     tol=1e-3,
                     stol=None,
                     method='lbfgs_precon',
                     max_steps=100,
                     mask=None,
                     traj_file=None,
                     hydrostatic_strain=False,
                     constant_volume=False,
                     precon_apply_positions=True,
                     precon_apply_cell=True,
                     symmetrize=False,
                     **kwargs):
    import model
    #print "relax_atoms_cell using method",method
    if symmetrize:
        atoms.set_calculator(SymmetrizedCalculator(model.calculator, atoms))
    else:
        atoms.set_calculator(model.calculator)
    ## print "relax_atoms_cell initial e ", atoms.get_potential_energy()
    ## print "relax_atoms_cell initial f ", atoms.get_forces()
    ## print "relax_atoms_cell initial s ", atoms.get_stress()
    if hasattr(model, 'Optimizer'):
        method = 'model_optimizer'
    if method != 'cg_n':
        atoms = UnitCellFilter(atoms,
                               mask=mask,
                               hydrostatic_strain=hydrostatic_strain,
                               constant_volume=constant_volume)
    if method.startswith('lbfgs') or method == 'fire' or method == 'cg_n':
        if method == 'cg_n':
            from quippy import Minim, fzeros
            atoms.info['Minim_Hydrostatic_Strain'] = hydrostatic_strain
            atoms.info['Minim_Constant_Volume'] = constant_volume
            if mask is not None:
                atoms.info['Minim_Lattice_Fix'] = fzeros((3, 3))
                if not mask[0]:
                    atoms.info['Minim_Lattice_Fix'][1, 1] = 1.0
                if not mask[1]:
                    atoms.info['Minim_Lattice_Fix'][2, 2] = 1.0
                if not mask[2]:
                    atoms.info['Minim_Lattice_Fix'][3, 3] = 1.0
                if not mask[3]:
                    atoms.info['Minim_Lattice_Fix'][1, 2] = 1.0
                    atoms.info['Minim_Lattice_Fix'][2, 1] = 1.0
                if not mask[4]:
                    atoms.info['Minim_Lattice_Fix'][2, 3] = 1.0
                    atoms.info['Minim_Lattice_Fix'][3, 2] = 1.0
                if not mask[5]:
                    atoms.info['Minim_Lattice_Fix'][1, 3] = 1.0
                    atoms.info['Minim_Lattice_Fix'][3, 1] = 1.0
            opt = Minim(atoms,
                        relax_positions=True,
                        relax_cell=True,
                        method='cg_n')
        else:
            from ase.optimize.precon.precon import Exp
            from ase.optimize.precon.lbfgs import PreconLBFGS
            precon = None
            if method.endswith('precon'):
                precon = Exp(3.0,
                             apply_positions=precon_apply_positions,
                             apply_cell=precon_apply_cell,
                             recalc_mu=True)
            if method.startswith('lbfgs'):
                opt = PreconLBFGS(atoms, precon=precon, **kwargs)
            else:
                opt = FIRE(atoms, **kwargs)
        if traj_file is not None:
            traj = open(traj_file, 'w')

            def write_trajectory():
                try:
                    write(traj, atoms.atoms, format='extxyz')
                except:
                    write(traj, atoms, format='extxyz')

            opt.attach(write_trajectory)
        if method != 'cg_n' and isinstance(opt, PreconLBFGS):
            opt.run(tol, max_steps, smax=stol)
        else:
            opt.run(tol, max_steps)
        if traj_file is not None:
            traj.close()
    elif method == 'model_optimizer':
        opt = model.Optimizer(atoms.atoms)
        opt.run()
    else:
        raise ValueError('unknown method %s!' % method)

    if isinstance(atoms, UnitCellFilter):
        return atoms.atoms
    else:
        return atoms
Exemple #8
0
def do_lattice(bulk, use_precon=True, elastic=True, tol=1.0e-3):

    print "unrelaxed bulk"
    ase.io.write(sys.stdout, bulk, format='extxyz')

    # use one of the routines from utilities module to relax the initial
    # unit cell and atomic positions
    if use_precon:
        bulk = relax_atoms_cell(bulk,
                                tol=tol,
                                traj_file="bulk.relax.extxyz",
                                symmetrize=True)
    else:
        bulk = relax_atoms_cell(bulk,
                                tol=tol,
                                traj_file=None,
                                method='cg_n',
                                symmetrize=True)

    print "relaxed bulk"
    ase.io.write(sys.stdout, bulk, format='extxyz')

    print "calculating elastic constants"
    precon = None
    if use_precon:
        precon = Exp(3.0)
    opt = lambda atoms, **kwargs: PreconLBFGS(atoms, precon=precon, **kwargs)
    if elastic:
        # reset calculator to non-symmetrized one (not optimal, but would otherwise need to have optimizer used by fit_elastic_constants to reset symmetry for each relaxation):w
        bulk.set_calculator(model.calculator)
        try:
            elastic_consts = matscipy.elasticity.fit_elastic_constants(
                bulk,
                symmetry='tetragonal_high',
                optimizer=opt,
                logfile=sys.stdout)
        except RuntimeError:
            # fallback on FIRE if we get a linesearch failure with LBFGS
            opt = FIRE
            elastic_consts = matscipy.elasticity.fit_elastic_constants(
                bulk,
                symmetry='tetragonal_high',
                optimizer=opt,
                logfile=sys.stdout)

        c11 = elastic_consts[0][0, 0] / GPa
        c33 = elastic_consts[0][2, 2] / GPa
        c12 = elastic_consts[0][0, 1] / GPa
        c13 = elastic_consts[0][0, 2] / GPa
        c44 = elastic_consts[0][3, 3] / GPa
        c66 = elastic_consts[0][5, 5] / GPa

    print "calculating E vs. V"
    V0 = bulk.get_volume()
    dV = bulk.get_volume() * 0.025
    E_vs_V = []
    scaled_bulk = bulk.copy()
    print "bulk going into E vs. V"
    ase.io.write(sys.stdout, scaled_bulk, format='extxyz')
    f = open("relaxed_E_vs_V_configs.xyz", "w")

    scaled_bulk = bulk.copy()
    constraints = []
    # scaled_bulk.arrays["move_mask_3"] = np.zeros((len(scaled_bulk),3), dtype=np.int)
    # scaled_bulk.arrays["move_mask_3"][:,0] = 1
    # for i in range(len(scaled_bulk)):
    # constraints.append(FixedLine_forces_only(i, (0.0, 0.0, 1.0)))
    # scaled_bulk.set_constraint(constraints)
    for i in range(0, -5 - 1, -1):
        print "doing volume step", i
        vcur = scaled_bulk.get_volume()
        scaled_bulk.set_cell(scaled_bulk.get_cell() *
                             ((V0 + i * dV) / vcur)**(1.0 / 3.0),
                             scale_atoms=True)
        try:
            scaled_bulk = relax_atoms_cell(scaled_bulk,
                                           tol=tol,
                                           traj_file=None,
                                           constant_volume=True,
                                           method='cg_n',
                                           symmetrize=True,
                                           max_steps=500)
        except:
            break
        print "done relaxing step", i
        ase.io.write(f, scaled_bulk, format='extxyz')
        f.flush()
        E_vs_V.insert(0, (scaled_bulk.get_volume() / len(bulk),
                          scaled_bulk.get_potential_energy() / len(bulk)))
        evaluate(scaled_bulk)
        print "done evaluate step", i
        print "EV ", i, scaled_bulk.get_volume(
        ), scaled_bulk.get_potential_energy(), scaled_bulk.get_stress()

    scaled_bulk = bulk.copy()
    # scaled_bulk.arrays["move_mask_3"] = np.zeros((len(scaled_bulk),3), dtype=np.int)
    # scaled_bulk.arrays["move_mask_3"][:,0] = 1
    # scaled_bulk.set_constraint(constraints)
    for i in range(1, 6 + 1):
        print "doing volume step", i
        vcur = scaled_bulk.get_volume()
        scaled_bulk.set_cell(scaled_bulk.get_cell() *
                             ((V0 + i * dV) / vcur)**(1.0 / 3.0),
                             scale_atoms=True)
        try:
            scaled_bulk = relax_atoms_cell(scaled_bulk,
                                           tol=tol,
                                           traj_file=None,
                                           constant_volume=True,
                                           method='cg_n',
                                           symmetrize=True,
                                           max_steps=500)
        except:
            break
        print "done relaxing step", i
        ase.io.write(f, scaled_bulk, format='extxyz')
        f.flush()
        E_vs_V.append((scaled_bulk.get_volume() / len(bulk),
                       scaled_bulk.get_potential_energy() / len(bulk)))
        evaluate(scaled_bulk)
        print "done evaluate step", i
        print "EV ", i, scaled_bulk.get_volume(
        ), scaled_bulk.get_potential_energy(), scaled_bulk.get_stress()

    for (V, E) in E_vs_V:
        print "EV_final ", V, E

    if elastic:
        return (c11, c33, c12, c13, c44, c66, E_vs_V)
    else:
        return (E_vs_V)
Exemple #9
0
# create list of van der Waals interactions
for i in range(len(a)):
    for j in range(i + 1, len(a)):
        if vdw_list[i, j]:
            vdws.append(VdW(atomi=i, atomj=j, epsilonij=vdw_epsilonij,
                            rminij=vdw_rminij))

# set up ForceField calculator
calc = ForceField(morses=morses, angles=angles, dihedrals=dihedrals, vdws=vdws)

a1 = a.copy()
a1.set_calculator(calc)
a1.rattle(0.05)

# geometry optimisation without preconditioner
opt = PreconLBFGS(a1, use_armijo=True, precon='ID')
opt.run(fmax=0.1)
e1 = a1.get_potential_energy()

a2 = a.copy()
a2.set_calculator(calc)
a2.rattle(0.05)

# geometry optimisation with FF based preconditioner
precon = FF(morses=morses, angles=angles, dihedrals=dihedrals, use_pyamg=False)

opt = PreconLBFGS(a2, use_armijo=True, precon=precon)
opt.run(fmax=0.1)
e2 = a2.get_potential_energy()

print(e1, e2)