예제 #1
0
def test_sym_rot_adj_cell(filter):
    print("SYM POS+CELL ROT")
    at_init, at_rot = setup_cell()
    at_sym_3_rot = at_init.copy()
    at_sym_3_rot.set_constraint(
        FixSymmetry(at_sym_3_rot, adjust_positions=True, adjust_cell=True))
    di, df = symmetrized_optimisation(at_sym_3_rot, filter)
    assert di["number"] == 229 and is_subgroup(sub_data=di, sup_data=df)
예제 #2
0
def test_sym_adj_pot(filter):
    print("SYM POS")
    at_init, at_rot = setup_cell()
    at_sym_2 = at_init.copy()
    at_sym_2.set_constraint(
        FixSymmetry(at_sym_2, adjust_positions=True, adjust_cell=False))
    di, df = symmetrized_optimisation(at_sym_2, filter)
    assert di["number"] == 229 and not is_subgroup(sub_data=di, sup_data=df)
예제 #3
0
def opt_lammpslib(struc,
                  lmp,
                  parameters=None,
                  mask=None,
                  logfile='-',
                  path='tmp',
                  calc_type=None,
                  lmp_file=None,
                  molecule=False,
                  method='FIRE',
                  fmax=0.01,
                  opt_cell=False,
                  a=0.1,
                  steps=500):
    """
    mask: [1, 1, 1, 1, 1, 1], a, b, c, alpha, beta, gamma
          [1, 1, 0, 0, 0, 1]
    """

    if lmp_file is not None:
        lammps = LAMMPSlib(lmp=lmp, lmp_file=lmp_file, log_file='lammps.log', \
                           molecule=molecule, path=path)
    elif calc_type is not None:
        lammps = LAMMPSlib(lmp=lmp, lmpcmds=parameters, calc_type=calc_type, \
                           log_file='lammps.log', molecule=molecule, path=path)
    else:
        lammps = LAMMPSlib(lmp=lmp, lmpcmds=parameters, log_file='lammps.log', \
                           molecule=molecule, path=path)

    #check_symmetry(si, 1.0e-6, verbose=True)
    struc.set_calculator(lammps)
    struc.set_constraint(FixSymmetry(struc))
    if opt_cell:
        ecf = ExpCellFilter(struc, mask)
        if method == 'FIRE':
            dyn = FIRE(ecf, logfile=logfile, a=a)
        else:
            dyn = LBFGS(ecf, logfile=logfile)
    else:
        if method == 'FIRE':
            dyn = FIRE(struc, logfile=logfile)
        else:
            dyn = LBFGS(struc, logfile=logfile)
    dyn.run(fmax=fmax, steps=steps)
    return struc
예제 #4
0
def optimize(atoms,
             sym=True,
             box=False,
             method='FIRE',
             fmax=0.01,
             steps=1000,
             logfile='ase.log'):
    if sym:
        atoms.set_constraint(FixSymmetry(atoms))
    if box:
        ecf = ExpCellFilter(atoms)
        if method == 'FIRE':
            dyn = FIRE(ecf, logfile=logfile)
        else:
            dyn = LBFGS(ecf, logfile=logfile)
    else:
        if method == 'FIRE':
            dyn = FIRE(atoms, logfile=logfile)
        else:
            dyn = FIRE(atoms, logfile=logfile)

    dyn.run(fmax=fmax, steps=steps)
    atoms.set_constraint()
    return atoms
예제 #5
0
def test_fix_symmetry_shuffle_indices():
    atoms = Atoms('AlFeAl6',
                  cell=[6] * 3,
                  positions=[[0, 0, 0], [2.9, 2.9, 2.9], [0, 0, 3], [0, 3, 0],
                             [0, 3, 3], [3, 0, 0], [3, 0, 3], [3, 3, 0]],
                  pbc=True)
    atoms.set_constraint(FixSymmetry(atoms))
    at_permut = atoms[[0, 2, 3, 4, 5, 6, 7, 1]]
    pos0 = atoms.get_positions()

    def perturb(atoms, pos0, at_i, dpos):
        positions = pos0.copy()
        positions[at_i] += dpos
        atoms.set_positions(positions)
        new_p = atoms.get_positions()
        return pos0[at_i] - new_p[at_i]

    dp1 = perturb(atoms, pos0, 1, (0.0, 0.1, -0.1))
    dp2 = perturb(atoms, pos0, 2, (0.0, 0.1, -0.1))
    pos0 = at_permut.get_positions()
    permut_dp1 = perturb(at_permut, pos0, 7, (0.0, 0.1, -0.1))
    permut_dp2 = perturb(at_permut, pos0, 1, (0.0, 0.1, -0.1))
    assert np.max(np.abs(dp1 - permut_dp1)) < 1.0e-10
    assert np.max(np.abs(dp2 - permut_dp2)) < 1.0e-10
예제 #6
0
def relax_config(atoms,
                 calculator,
                 relax_pos,
                 relax_cell,
                 tol=1e-3,
                 method='lbfgs',
                 max_steps=200,
                 traj_file=None,
                 constant_volume=False,
                 refine_symmetry_tol=None,
                 keep_symmetry=False,
                 strain_mask=None,
                 config_label=None,
                 from_base_model=False,
                 save_config=False,
                 fix_cell_dependence=False,
                 applied_P=0.0,
                 **kwargs):

    # get from base model if requested
    #import model
    if from_base_model:
        if config_label is None:
            raise ValueError(
                'from_base_model is set but no config_label provided')
        try:
            base_run_file = os.path.join(
                '..', base_run_root,
                base_run_root + '-' + config_label + '-relaxed.xyz')
            atoms_in = read(base_run_file, format='extxyz')
            # set positions from atoms_in rescaling to match current cell
            saved_cell = atoms.get_cell().copy()
            atoms.set_cell(atoms_in.get_cell())
            atoms.set_positions(atoms_in.get_positions())
            atoms.set_cell(saved_cell, scale_atoms=True)
            print("relax_config read config from ", base_run_file)
        except:
            try:
                print("relax_config failed to read base run config from ",
                      base_run_root + '-' + config_label + '-relaxed.xyz')
            except:
                print("relax_config failed to determined base_run_root")

    print("relax_config symmetry before refinement at default tol 1.0e-6")
    check_symmetry(atoms, 1.0e-6, verbose=True)
    if refine_symmetry_tol is not None:
        refine_symmetry(atoms, refine_symmetry_tol)
        print("relax_config symmetry after refinement")
        check_symmetry(atoms, refine_symmetry_tol, verbose=True)
    if keep_symmetry:
        print("relax_config trying to maintain symmetry")
        atoms.set_constraint(FixSymmetry(atoms))

    atoms.set_calculator(calculator)

    # if needed, fix cell dependence before running
    # if fix_cell_dependence and hasattr(model, "fix_cell_dependence"):
    #     model.fix_cell_dependence(atoms)

    if method == 'lbfgs' or method == 'sd2':
        if 'move_mask' in atoms.arrays:
            atoms.set_constraint(
                FixAtoms(np.where(atoms.arrays['move_mask'] == 0)[0]))
        if relax_cell:
            atoms_cell = ExpCellFilter(atoms,
                                       mask=strain_mask,
                                       constant_volume=constant_volume,
                                       scalar_pressure=applied_P * GPa)
        else:
            atoms_cell = atoms
        atoms.info["n_minim_iter"] = 0
        if method == 'sd2':
            (traj,
             run_stat) = sd2_run("", atoms_cell, tol,
                                 lambda i: sd2_converged(i, atoms_cell, tol),
                                 max_steps)
            #if traj_file is not None:
            #write(traj_file, traj)
        else:
            # precon="Exp" specified to resolve an error with the lbfgs not optimising
            opt = PreconLBFGS(atoms_cell, use_armijo=False, **kwargs)
            if traj_file is not None:
                traj = open(traj_file, "w")

                def write_trajectory():
                    if "n_minim_iter" in atoms.info:
                        atoms.info["n_minim_iter"] += 1
                    write(traj, atoms, format='extxyz')

                #opt.attach(write_trajectory)
    elif method == 'cg_n':
        raise ValueError(
            'minim method cg_n not supported in new python3 quippy')
        # if strain_mask is not None:
        # raise(Exception("strain_mask not supported with method='cg_n'"))
        # atoms.info['Minim_Constant_Volume'] = constant_volume
        # opt = Minim(atoms, relax_positions=relax_pos, relax_cell=relax_cell, method='cg_n')
    else:
        raise ValueError('unknown method %s!' % method)

    if method != 'sd2':
        opt.run(tol, max_steps)

    if refine_symmetry_tol is not None:
        print("symmetry at end of relaxation at desired tol")
        check_symmetry(atoms, refine_symmetry_tol, verbose=True)
    print("symmetry at end of relaxation at default tol 1e-6")
    check_symmetry(atoms, 1.0e-6, verbose=True)

    # in case we had a trajectory saved
    try:
        traj.close()
    except:
        pass

    if save_config:
        if config_label is None:
            raise ValueError('save_config is set but no config_label provided')
        #write('-'+config_label+'-relaxed.xyz', atoms, format='extxyz')

    if keep_symmetry:
        for (i_c, c) in enumerate(atoms.constraints):
            if isinstance(c, FixSymmetry):
                del atoms.constraints[i_c]
                break

    # undo fix cell dependence
    # if fix_cell_dependence and hasattr(model, "fix_cell_dependence"):
    #     sys.stderr.write("WARNING: relax_config undoing fix_cell_dependence, whether or not it was set before it started\n")
    #     model.fix_cell_dependence()

    return atoms
예제 #7
0
atoms_init.positions[0, 0] += 1.0e-7  # break symmetry by 1e-7

# We use an LJ calculator, and allow the cell and atomic positions to relax
atoms_unsym = atoms_init.copy()
atoms_unsym.calc = LennardJones()
ucf_unsym = UnitCellFilter(atoms_unsym)

dyn = BFGS(ucf_unsym)
print("Initial Energy", atoms_unsym.get_potential_energy())
dyn.run(fmax=0.001)
print("Final Energy", atoms_unsym.get_potential_energy())

# Now we repeat the optimisation with the symmetrization constraint in place
atoms_sym = atoms_init.copy()
atoms_sym.calc = LennardJones()
atoms_sym.set_constraint(FixSymmetry(atoms_sym))
ucf_sym = UnitCellFilter(atoms_sym)

dyn = BFGS(ucf_sym)
print("Initial Energy", atoms_sym.get_potential_energy())
dyn.run(fmax=0.001)
print("Final Energy", atoms_sym.get_potential_energy())

print("position difference", np.linalg.norm(atoms_unsym.get_positions() -
                                            atoms_sym.get_positions()))

# We print out the initial symmetry groups at two different precision levels
print("initial symmetry at precision 1e-6")
check_symmetry(atoms_init, 1.0e-6, verbose=True)
print("initial symmetry at precision 1e-8")
check_symmetry(atoms_init, 1.0e-8, verbose=True)