Beispiel #1
0
def traj_to_json(atoms : ase.Atoms) -> str:
	"""
	Serialize an Atoms object in a human readable way
	"""

	def rounder(y : float)->float:
		return round(y,3) + 0 #+0 turns -0 into 0

	atomdata = []
	const    = atoms.constraints
	if const: const_list = const[0].get_indices().tolist()
	else:     const_list = []
	for a in atoms: atomdata.append({'number'		: int(a.number)
									,'x'			: rounder(a.x)
									,'y'			: rounder(a.y)
									,'z'			: rounder(a.z)
									,'magmom'		: rounder(a.magmom)
									,'tag'			: int(a.tag)
									,'constrained'	: int(a.index in const_list)
									,'index'		: int(a.index)})

	out = {'cell': [[rounder(x) for x in xx] for xx in atoms.get_cell().tolist()]
		  ,'atomdata':atomdata}

	return json.dumps(out)
Beispiel #2
0
def get_system_type(atoms: ase.Atoms) -> str:
    """
	Helpful docstring
	"""
    ############################################################################
    # Parameters
    #------------
    cutoff = 6  # A

    # Preprocessing
    atoms.center()  # In case dealing with Nerds Rope & Co.
    minx, miny, minz, maxx, maxy, maxz = 1000, 1000, 1000, -1000, -1000, -1000
    for a in atoms:
        if a.position[0] < minx: minx = a.position[0]
        if a.position[1] < miny: miny = a.position[1]
        if a.position[2] < minz: minz = a.position[2]
        if a.position[0] > maxx: maxx = a.position[0]
        if a.position[1] > maxy: maxy = a.position[1]
        if a.position[2] > maxz: maxz = a.position[2]

    cell_abc = list(map(np.linalg.norm, atoms.get_cell()[:3]))
    thickness = [maxx - minx, maxy - miny, maxz - minz]
    pbc = [cell_abc[i] - thickness[i] < cutoff for i in range(3)]

    if all(pbc): return 'bulk'
    elif any(pbc): return 'surface'
    else: return 'molecule'
Beispiel #3
0
def test_struc_from_ase():
    from ase import Atoms
    from ase.calculators.singlepoint import SinglePointCalculator

    results = {
        "forces": np.random.randn(20, 3),
        "energy": np.random.rand(),
        "stress": np.random.randn(6),
    }

    uc = Atoms(
        ["Pd" for i in range(10)] + ["Ag" for i in range(10)],
        positions=np.random.rand(20, 3),
        cell=np.random.rand(3, 3),
    )

    calculator = SinglePointCalculator(uc, **results)
    uc.set_calculator(calculator)

    new_struc = Structure.from_ase_atoms(uc)

    assert np.all(new_struc.species_labels == uc.get_chemical_symbols())
    assert np.all(new_struc.positions == uc.get_positions())
    assert np.all(new_struc.cell == uc.get_cell())
    assert np.all(new_struc.forces == results["forces"])
    assert np.all(new_struc.energy == results["energy"])
    assert np.all(new_struc.stress == results["stress"])
Beispiel #4
0
    def test_electrostatics(self):
        """Tests that the results are consistent with the electrostatic
        interpretation. Each matrix [i, j] element should correspond to the
        Coulomb energy of a system consisting of the pair of atoms i, j.
        """
        system = H2O
        n_atoms = len(system)
        a = 0.5
        desc = EwaldSumMatrix(n_atoms_max=3, permutation="none", flatten=False)

        # The Ewald matrix contains the electrostatic interaction between atoms
        # i and j. Here we construct the total electrostatic energy for a
        # system consisting of atoms i and j.
        matrix = desc.create(system, a=a, rcut=rcut, gcut=gcut)
        energy_matrix = np.zeros(matrix.shape)
        for i in range(n_atoms):
            for j in range(n_atoms):
                if i == j:
                    energy_matrix[i, j] = matrix[i, j]
                else:
                    energy_matrix[i, j] = matrix[i, j] + matrix[i, i] + matrix[j, j]

        # Converts unit of q*q/r into eV
        conversion = 1e10 * scipy.constants.e / (4 * math.pi * scipy.constants.epsilon_0)
        energy_matrix *= conversion

        # The value in each matrix element should correspond to the Coulomb
        # energy of a system with with only those atoms. Here the energies from
        # the Ewald matrix are compared against the Ewald energy calculated
        # with pymatgen.
        positions = system.get_positions()
        atomic_num = system.get_atomic_numbers()
        for i in range(n_atoms):
            for j in range(n_atoms):
                if i == j:
                    pos = [positions[i]]
                    sym = [atomic_num[i]]
                else:
                    pos = [positions[i], positions[j]]
                    sym = [atomic_num[i], atomic_num[j]]

                i_sys = Atoms(
                    cell=system.get_cell(),
                    positions=pos,
                    symbols=sym,
                    pbc=True,
                )

                structure = Structure(
                    lattice=i_sys.get_cell(),
                    species=i_sys.get_atomic_numbers(),
                    coords=i_sys.get_scaled_positions(),
                )
                structure.add_oxidation_state_by_site(i_sys.get_atomic_numbers())
                ewald = EwaldSummation(structure, eta=a, real_space_cut=rcut, recip_space_cut=gcut)
                energy = ewald.total_energy

                # Check that the energy given by the pymatgen implementation is
                # the same as given by the descriptor
                self.assertTrue(np.allclose(energy_matrix[i, j], energy, atol=0.00001, rtol=0))
Beispiel #5
0
def sphere(atomlist, fill_factor=0.74, radius=None, cell=None):
    """Generates a random sphere of particles given an
    atomlist and radius. If radius is None, one is 
    automatically estimated. min_dist and tries_b4_expand
    are parameters that govern how stricly the proximity
    of atoms are enforced.
    """

    if radius is None:
        radius = get_particle_radius(atomlist, fill_factor)

    # Create a list of random order of the atoms
    chemical_symbols = []
    for atom in atomlist:
        chemical_symbols += [atom[0]] * atom[1]

    random.shuffle(chemical_symbols)

    unit_vec = np.array([random_three_vector() for i in range(len(chemical_symbols))])
    D = radius * np.random.sample(size=len(chemical_symbols)) ** (1.0/3.0)
    positions = np.array([D]).T * unit_vec

    indiv = Atoms(symbols=chemical_symbols, positions=positions)

    if cell is not None:
        indiv.set_cell(cell)
        cell_center = np.sum(indiv.get_cell(), axis=1) / 2.0
        indiv.translate(indiv.get_center_of_mass() + cell_center)
        indiv.set_pbc(True)

    return indiv
    def get_structure_info(self):
        path = os.path.join(self.maindir, 'sgroup.out')
        if not os.path.isfile(path):
            return

        self.structure.mainfile = path

        cellpar = self.structure.get('cellpar', None)
        sym_pos = self.structure.get('sym_pos', {})

        sym = sym_pos.get('symbols', None)
        pos = sym_pos.get('positions', None)

        if cellpar is None or sym is None or pos is None:
            return

        structure = Atoms(cell=cellpar,
                          scaled_positions=pos,
                          symbols=sym,
                          pbc=True)

        positions = structure.get_positions()
        positions = positions * ureg.angstrom
        cell = structure.get_cell()
        cell = cell * ureg.angstrom

        return sym, positions, cell
Beispiel #7
0
def _compute_rdf_1frame(box,
                        posis,
                        atype,
                        sel_type=[None, None],
                        max_r=5,
                        nbins=100):
    all_types = list(set(list(np.sort(atype))))
    if sel_type[0] is None:
        sel_type[0] = all_types
    if sel_type[1] is None:
        sel_type[1] = all_types
    if type(sel_type[0]) is not list:
        sel_type[0] = [sel_type[0]]
    if type(sel_type[1]) is not list:
        sel_type[1] = [sel_type[1]]
    natoms = len(posis)
    from ase import Atoms
    import ase.neighborlist
    atoms = Atoms(positions=posis, cell=box, pbc=[1, 1, 1])
    nlist = ase.neighborlist.NeighborList(
        max_r,
        self_interaction=False,
        bothways=True,
        primitive=ase.neighborlist.NewPrimitiveNeighborList)
    nlist.update(atoms)
    stat = np.zeros(nbins)
    hh = max_r / float(nbins)
    for ii in range(natoms):
        # atom "0"
        if atype[ii] in sel_type[0]:
            indices, offsets = nlist.get_neighbors(ii)
            for jj, os in zip(indices, offsets):
                # atom "1"
                if atype[jj] in sel_type[1]:
                    posi_jj = atoms.positions[jj] + np.dot(
                        os, atoms.get_cell())
                    diff = posi_jj - atoms.positions[ii]
                    dr = np.linalg.norm(diff)
                    # if (np.linalg.norm(diff- diff_1)) > 1e-12 :
                    #     raise RuntimeError
                    si = int(dr / hh)
                    if si < nbins:
                        stat[si] += 1
    # count the number of atom1
    c0 = 0
    for ii in sel_type[0]:
        c0 += np.sum(atype == ii)
    # count the number of atom1
    c1 = 0
    for ii in sel_type[1]:
        c1 += np.sum(atype == ii)
    rho1 = c1 / np.linalg.det(box)
    # compute rdf
    for ii in range(nbins):
        vol = 4. / 3. * np.pi * (((ii + 1) * hh)**3 - ((ii) * hh)**3)
        rho = stat[ii] / vol
        stat[ii] = rho / rho1 / c0
    xx = np.arange(0, max_r - 1e-12, hh)
    return xx, stat
Beispiel #8
0
def test_struc_from_ase():
    from ase import Atoms
    uc = Atoms(['Pd' for i in range(10)] + ['Ag' for i in range(10)],
               positions=np.random.rand(20, 3),
               cell=np.random.rand(3, 3))
    new_struc = Structure.from_ase_atoms(uc)
    assert np.all(new_struc.species_labels == uc.get_chemical_symbols())
    assert np.all(new_struc.positions == uc.get_positions())
    assert np.all(new_struc.cell == uc.get_cell())
Beispiel #9
0
    def test_k2_weights_and_geoms_periodic(self):
        """Tests that the values of the weight and geometry functions are
        correct for the k=2 term in periodic systems.
        """
        atoms = Atoms(
            cell=[
                [10, 0, 0],
                [10, 10, 0],
                [10, 0, 10],
            ],
            symbols=["H", "C"],
            scaled_positions=[
                [0.1, 0.5, 0.5],
                [0.9, 0.5, 0.5],
            ]
        )

        mbtr = MBTR(
            [1, 6],
            k=[2],
            grid=default_grid,
            periodic=True,
            weighting={
                "k2": {
                    "function": "exponential",
                    "scale": 0.8,
                    "cutoff": 1e-3
                },
            },
        )
        mbtr.create(atoms)
        weights = mbtr._k2_weights
        geoms = mbtr._k2_geoms

        # Test against the assumed geometry values
        pos = atoms.get_positions()
        distances = np.array([
            np.linalg.norm(pos[0] - pos[1]),
            np.linalg.norm(pos[0] - pos[1] + atoms.get_cell()[0, :]),
            np.linalg.norm(pos[1] - pos[0] - atoms.get_cell()[0, :])
        ])
        assumed_geoms = {
            (0, 1): 1/distances
        }
        self.dict_comparison(geoms, assumed_geoms)

        # Test against the assumed weights
        weight_list = np.exp(-0.8*distances)

        # The periodic distances are halved
        weight_list[1:3] /= 2
        assumed_weights = {
            (0, 1): weight_list
        }

        self.dict_comparison(weights, assumed_weights)
def test_change_cell_dimensions_and_pbc(factory, dimer_params, lj_epsilons):
    """Ensure that post_change_box commands are actually executed after
    changing the dimensions of the cell or its periodicity.  This is done by
    setting up an isolated dimer with a Lennard-Jones potential and a set of
    post_changebox_cmds that specify the same potential but with a rescaled
    energy (epsilon) parameter.  The energy is then computed twice, once before
    changing the cell dimensions and once after, and the values are compared to
    the expected values based on the two different epsilons to ensure that the
    modified LJ potential is used for the second calculation.  The procedure is
    repeated but where the periodicity of the cell boundaries is changed rather
    than the cell dimensions.
    """
    # Make a dimer in a large nonperiodic box
    dimer = Atoms(**dimer_params)
    spec, a = extract_dimer_species_and_separation(dimer)

    # Ensure LJ cutoff is large enough to encompass the dimer
    lj_cutoff = 3 * a

    calc_params = calc_params_lj_changebox(spec, lj_cutoff, **lj_epsilons)

    dimer.calc = factory.calc(**calc_params)

    energy_orig = dimer.get_potential_energy()

    # Shrink the box slightly to invalidate cached energy and force change_box
    # to be issued.  This shouldn't actually affect the energy in and of itself
    # since our dimer has non-periodic boundaries.
    cell_orig = dimer.get_cell()
    dimer.set_cell(cell_orig * 1.01, scale_atoms=False)

    energy_modified = dimer.get_potential_energy()

    eps_scaling_factor = lj_epsilons["eps_modified"] / lj_epsilons["eps_orig"]
    assert energy_modified == pytest.approx(eps_scaling_factor * energy_orig,
                                            rel=1e-4)

    # Reset dimer cell.  Also, create and attach new calculator so that
    # previous post_changebox_cmds won't be in effect.
    dimer.set_cell(cell_orig, scale_atoms=False)
    dimer.calc = factory.calc(**calc_params)

    # Compute energy of original configuration again so that a change_box will
    # be triggered on the next calculation after we change the pbcs
    energy_orig = dimer.get_potential_energy()

    # Change the periodicity of the cell along one direction.  This shouldn't
    # actually affect the energy in and of itself since the cell is large
    # relative to the dimer
    dimer.set_pbc([False, True, False])

    energy_modified = dimer.get_potential_energy()

    assert energy_modified == pytest.approx(eps_scaling_factor * energy_orig,
                                            rel=1e-4)
Beispiel #11
0
def view_atoms_classifier(image, mg_label, mn_label, o_label, view=True):
    x = image.reshape(-1, 3)
    mg = x[2:10, :]
    mn = x[10:18, :]
    o = x[18:, :]

    l = x[0, :] * 30
    a = x[1, :] * 180
    c = np.hstack((l, a))
    atoms = Atoms('H')
    atoms.set_cell(c)
    cell = atoms.get_cell()
    t = np.isnan(cell)
    tt = np.sum(t)
    isnan = False
    if not tt == 0:
        isnan = True
        print(cell)
        print(l)
        print(a)
    _, mg_index = torch.max(mg_label, dim=1)
    _, mn_index = torch.max(mn_label, dim=1)
    _, o_index = torch.max(o_label, dim=1)

    mg_index = mg_index.reshape(8, ).detach().cpu().numpy()
    mn_index = mn_index.reshape(8, ).detach().cpu().numpy()
    o_index = o_index.reshape(12, ).detach().cpu().numpy()

    mg_pos = mg[np.where(mg_index)]
    mn_pos = mn[np.where(mn_index)]
    o_pos = o[np.where(o_index)]

    n_mg = len(mg_pos)
    n_mn = len(mn_pos)
    n_o = len(o_pos)

    if n_mg == 0:
        mg_pos = np.array([0.1667, 0.1667, 0.1667]).reshape(1, 3)
        n_mg = 1
    if n_mn == 0:
        mn_pos = np.array([0.1667, 0.1667, 0.1667]).reshape(1, 3)
        n_mn = 1

    if n_o == 0:
        o_pos = np.array([0.1667, 0.1667, 0.1667]).reshape(1, 3)
        n_o = 1

    pos = np.vstack((mg_pos, mn_pos, o_pos))
    scaled_pos = back_to_10_cell(pos, n_mg, n_mn, n_o)
    atoms = back_to_real_cell(scaled_pos, cell, n_mg, n_mn, n_o)
    atoms.set_pbc([1, 1, 1])
    if view:
        atoms.edit()

    return atoms, x, isnan
Beispiel #12
0
def test_emt():
    import numpy as np
    from ase.calculators.emt import EMT
    from ase import Atoms

    a = 3.60
    b = a / 2
    cu = Atoms('Cu',
               positions=[(0, 0, 0)],
               cell=[(0, b, b), (b, 0, b), (b, b, 0)],
               pbc=1,
               calculator=EMT())
    e0 = cu.get_potential_energy()
    print(e0)

    cu.set_cell(cu.get_cell() * 1.001, scale_atoms=True)
    e1 = cu.get_potential_energy()
    V = a**3 / 4
    B = 2 * (e1 - e0) / 0.003**2 / V * 160.2
    print(B)

    for i in range(4):
        x = 0.001 * i
        A = np.array([(x, b, b + x), (b, 0, b), (b, b, 0)])
        cu.set_cell(A, scale_atoms=True)
        e = cu.get_potential_energy() - e0
        if i == 0:
            print(i, e)
        else:
            print(i, e, e / x**2)

    A = np.array([(0, b, b), (b, 0, b), (6 * b, 6 * b, 0)])
    R = np.zeros((2, 3))
    for i in range(1, 2):
        R[i] = i * A[2] / 6
    print((Atoms('Cu2', positions=R, pbc=1, cell=A,
                 calculator=EMT()).get_potential_energy() - 2 * e0) / 2)

    A = np.array([(0, b, b), (b, 0, b), (10 * b, 10 * b, 0)])
    R = np.zeros((3, 3))
    for i in range(1, 3):
        R[i] = i * A[2] / 10
    print((Atoms('Cu3', positions=R, pbc=1, cell=A,
                 calculator=EMT()).get_potential_energy() - 3 * e0) / 2)

    A = np.array([(0, b, b), (b, 0, b), (b, b, 0)])
    R = np.zeros((3, 3))
    for i in range(1, 3):
        R[i] = i * A[2]
    print((Atoms('Cu3', positions=R, pbc=(1, 1, 0), cell=A,
                 calculator=EMT()).get_potential_energy() - 3 * e0) / 2)
Beispiel #13
0
def _get_reduced_indices(atoms: Atoms, tol: float = 1e-5) -> List[int]:
    """Get a list of the reduced atomic indices using spglib.
    Note: Does no checks to see if spglib is installed.
    
    :param atoms: ase Atoms object to reduce
    :param tol: ``float``, numeric tolerance for positional comparisons
    """
    import spglib

    # Create input for spglib
    spglib_cell = (atoms.get_cell(), atoms.get_scaled_positions(),
                   atoms.numbers)
    symmetry_data = spglib.get_symmetry_dataset(spglib_cell, symprec=tol)
    return list(set(symmetry_data['equivalent_atoms']))
Beispiel #14
0
 def _preprocess_atoms(self, atoms: Atoms) -> Dict[str, Optional[Tensor]]:
     pos = torch.tensor(
         atoms.get_positions(), device=self.device, dtype=self.dtype, requires_grad=True
     )
     Z = torch.tensor(atoms.get_atomic_numbers(), device=self.device)
     if any(atoms.pbc):
         cell = torch.tensor(
             atoms.get_cell(), device=self.device, dtype=self.dtype, requires_grad=True
         )
     else:
         cell = None
     pbc = torch.tensor(atoms.pbc, device=self.device)
     edge_index, S = self._calc_edge_index(pos, cell, pbc)
     input_dicts = dict(pos=pos, Z=Z, cell=cell, pbc=pbc, edge_index=edge_index, shift=S)
     return input_dicts
Beispiel #15
0
def prepare_ga(dbfile='godb.db', N=20):
    ''' This method creates a database with the desired number
    of randomly generated structures.
    '''
    blocks = [('Si', 7)]  # the building blocks
    l = [list(Atoms(block).numbers) * count for block, count in blocks]
    stoichiometry = [int(item) for sublist in l for item in sublist]
    atom_numbers = list(set(stoichiometry))

    # This dictionary will be used to check that the shortest
    # Si-Si distances are above a certain threshold 
    # (here 1.5 Angstrom):
    blmin = {(14, 14): 1.5}

    # This defines the cubic simulation cell:
    slab = Atoms('', positions=np.zeros((0, 3)), cell=[16] * 3)

    # This defines the smaller box in which the 
    # initial coordinates are allowed to vary
    density = 0.12  # in atoms per cubic Angstrom
    aspect_ratios = np.array([1.0, 1.0, 1.0])
    v = len(stoichiometry) / density
    l = np.cbrt(v / np.product(aspect_ratios))
    cell = np.identity(3) * aspect_ratios * l
    p0 = 0.5 * (np.diag(slab.get_cell() - cell))
    box = [p0, cell]

    # Seed the random number generators using the system time,
    # to ensure that no two runs produce the same results:
    np.random.seed()
    seed()

    # Generate the random structures and add them to the database:
    sg = StartGenerator(slab=slab, atom_numbers=stoichiometry,
                        closest_allowed_distances=blmin,
                        box_to_place_in=box)

    da = PrepareDB(db_file_name=dbfile,
                   simulation_cell=slab,
                   stoichiometry=stoichiometry)

    for i in range(N):
        a = sg.get_new_candidate()
        da.add_unrelaxed_candidate(a)

    return
def create_water_region(cell):
    """Creates a region of water for the cell specified. The density is assumed to be that
    of normal water at 1atm and 300K.

    Internally, this first creates a grid of Ne atoms, and then rattle them very slightly
    (std = 1/10 of a H2O molecule size). The Ne atoms are then replaced with H2O molecules
    centered on Ne. Be _very_ careful that the atoms are not out of bounds. It can happen
    after some rotations. Recommend to put in a slightly smaller cell to give some margins.

    Parameters:

    cell: list | numpy array

    Returns:

    H2O_bulk: Atoms | list of Atom
    """

    aq_cell = cell
    H2O_volume = (1e+27)/(1000/18 * units.mol)
    Atoms_grid = Atoms('Ne', pbc=True, cell=[H2O_volume**(1/3)]*3)

    Atoms_grid = Atoms_grid.repeat(
        tuple([int(x/(H2O_volume**(1/3))) for x in aq_cell]))

    Atoms_grid.set_cell(aq_cell)
    Atoms_grid.center()
    Atoms_grid.rattle(stdev=H2O_volume**(1/3)/10)

    H2O_bulk = molecule('H2O')
    H2O_bulk.euler_rotate(rand()*360, rand()*360, rand()*360, center="COM")
    H2O_bulk.translate(Atoms_grid.get_positions()[0])
    H2O_bulk.set_cell(Atoms_grid.get_cell())
    H2O_bulk.set_pbc(True)

    for new_pos in Atoms_grid.get_positions()[1:]:
        new_molecule = molecule('H2O')
        new_molecule.euler_rotate(
            rand()*360, rand()*360, rand()*360, center="COM")
        new_molecule.translate(new_pos)

        H2O_bulk += new_molecule.copy()
    H2O_bulk.center()

    return H2O_bulk
Beispiel #17
0
def is_cell_hexagonal(atoms: Atoms):
    """
    Function to check whether the cell of an ASE atoms object is hexagonal.

    Parameters
    ----------
    atoms : ASE atoms object
        The atoms that should be checked.
    """
    cell = atoms.get_cell()

    a = np.linalg.norm(cell[0], axis=0)
    b = np.linalg.norm(cell[1], axis=0)
    c = np.linalg.norm(cell[2], axis=0)
    angle = np.arccos(np.dot(cell[0], cell[1]) / (a * b))

    return np.isclose(a, b) & (np.isclose(angle, np.pi / 3) | np.isclose(
        angle, 2 * np.pi / 3)) & (c == cell[2, 2])
Beispiel #18
0
def ase_to_quip(ase_atoms: ase.Atoms, quip_atoms=None):
    """
    Converter to put the info from an ase atoms object into a quip atoms object.
    Copies everything to make sure there is not linking back.

    Checks if the

    :param ase_atoms:
    :param quip_atoms:
    :return:
    """

    lattice = ase_atoms.get_cell().T.copy()
    if quip_atoms is not None:
        if isinstance(quip_atoms, quippy.atoms_types_module.Atoms):
            # check if the length matches, otherwise make a new one in place of that
            if len(ase_atoms) != quip_atoms.n:
                # need to regenerate the quip atoms object
                quip_atoms = quippy.atoms_types_module.Atoms(len(ase_atoms), lattice)
            else:
                # but the cell needs to be set anyways
                quip_atoms.set_lattice(lattice, scale_positions=False)
        else:
            # raise an error for the wrong object given
            raise TypeError('quip_atoms argument is not of valid type, cannot work with it')

    else:
        # need to regenerate the quip atoms object
        quip_atoms = quippy.atoms_types_module.Atoms(len(ase_atoms), lattice)

    quip_atoms.pos[:] = ase_atoms.get_positions().T.copy()
    quip_atoms.is_periodic[:] = ase_atoms.get_pbc()
    quip_atoms.z[:] = ase_atoms.numbers
    quip_atoms.set_atoms(quip_atoms.z)  # set species and mass

    if ase_atoms.has('momenta'):
        # if ase atoms has momenta then add velocities to the quip object
        # workaround for the interfaces not behaving properly in the wrapped code, see f90wrap issue #86
        _quippy.f90wrap_atoms_add_property_real_2da(this=quip_atoms._handle, name='velo',
                                                    value=velocities_ase_to_quip(ase_atoms.get_velocities()))

    # go through all properties
    return quip_atoms
Beispiel #19
0
    def get_charge(self):
        q, ecoul, eself, evdw = [], [], [], []
        print('-  get charges by QEq ... \n')
        A = Atoms(symbols=self.atom_name,
                  positions=self.x[0],
                  cell=self.cell,
                  pbc=(1, 1, 1))
        Qe = qeq(p=self.p, atoms=A)

        for nf in range(self.batch):
            # print('*  get charges of batch {0}/{1} ...\r'.format(nf,self.batch),end='\r')
            A = Atoms(symbols=self.atom_name,
                      positions=self.x[nf],
                      cell=self.cell,
                      pbc=(1, 1, 1))
            positions = A.get_positions()
            cell = A.get_cell()
            Qe.calc(cell, positions)
            q.append(Qe.q[:-1])
        self.q = np.array(q)
Beispiel #20
0
def sphere(atomlist, cell, fill_factor=0.74, radius=None):
    """Generates a random sphere of particles given an
    atomlist and radius.

    Parameters
    ----------
    atomlist : list
        A list of [sym, n] pairs where sym is the chemical symbol
        and n is the number of of sym's to include in the individual
    cell : list
        The x, y, and z dimensions of the cell which holds the particle.
    fill_factor : float
        How densely packed the sphere should be. Ranges from 0 to 1.
    radius : float
        The radius of the sphere. If None, estimated from the
        atomic radii
    """

    if radius is None:
        radius = get_particle_radius(atomlist, fill_factor)

    # Create a list of random order of the atoms
    chemical_symbols = []
    for atom in atomlist:
        chemical_symbols += [atom[0]] * atom[1]

    random.shuffle(chemical_symbols)

    unit_vec = np.array([random_three_vector() for i in range(len(chemical_symbols))])
    D = radius * np.random.sample(size=len(chemical_symbols)) ** (1.0/3.0)
    positions = np.array([D]).T * unit_vec

    indiv = Atoms(symbols=chemical_symbols, positions=positions)

    if cell is not None:
        indiv.set_cell(cell)
        cell_center = np.sum(indiv.get_cell(), axis=1) / 2.0
        indiv.translate(indiv.get_center_of_mass() + cell_center)
        indiv.set_pbc(True)

    return indiv
Beispiel #21
0
def standardize_cell(atoms: Atoms, tol: float = 1e-12):
    """
    Standardize the cell of an ASE atoms object. The atoms are rotated so one of the lattice vectors in the xy-plane
    aligns with the x-axis, then all of the lattice vectors are made positive.

    Parameters
    ----------
    atoms : ASE atoms object
        The atoms that should be standardized
    tol : float
        Components of the lattice vectors below this value are considered to be zero.

    Returns
    -------
    atoms : ASE atoms object
        The standardized atoms.
    """
    cell = np.array(atoms.cell)

    vertical_vector = np.where(np.all(np.abs(cell[:, :2]) < tol, axis=1))[0]

    if len(vertical_vector) != 1:
        raise RuntimeError('Invalid cell: no vertical lattice vector')

    cell[[vertical_vector[0], 2]] = cell[[2, vertical_vector[0]]]
    r = np.arctan2(atoms.cell[0, 1], atoms.cell[0, 0]) / np.pi * 180

    atoms.set_cell(cell)

    if r != 0.:
        atoms.rotate(-r, 'z', rotate_cell=True)

    if not is_cell_valid(atoms, tol):
        raise RuntimeError(
            'This cell cannot be made orthogonal using currently implemented methods.'
        )

    atoms.set_cell(np.abs(atoms.get_cell()))

    atoms.wrap()
    return atoms
Beispiel #22
0
def test():
    """Simple test function to test atoms2json and json2atoms function"""

    from ase import Atoms
    teststructure = Atoms('N2', [(0, 0, 0), (0, 0, 1.1)])

    teststring = atoms2json(teststructure,
                            additional_information={"abc": "def"
                                                    })  #convert to the string

    newstructure = json2atoms(teststring)  #and convert back

    assert (newstructure.get_atomic_numbers() ==
            teststructure.get_atomic_numbers()).all()
    assert (
        newstructure.get_positions() == teststructure.get_positions()).all()
    assert (newstructure.get_cell() == teststructure.get_cell()).all()
    assert (newstructure.get_pbc() == teststructure.get_pbc()).all()
    assert newstructure.info["key_value_pairs"]["abc"] == "def"

    print("JSON Conversion in both directions: apparently no issue")
Beispiel #23
0
from ase import Atoms
from ase.lattice import bulk
from ase.optimize.bfgs import BFGS
from ase.constraints import UnitCellFilter
from gpaw import GPAW
from gpaw import PW
import numpy as np

cell = bulk('Si', 'fcc', a=6.0).get_cell()
# Experimental Lattice constant is a=5.421 A
a = Atoms('Si2', cell=cell, pbc=True,
          scaled_positions=((0,0,0), (0.25,0.25,0.25)))

calc = GPAW(xc='PBE',
            mode=PW(400),
            #mode=PW(400, cell=a.get_cell()),  # fix no of planewaves!
            kpts=(4,4,4),
            #convergence={'eigenstates': 1.e-10},  # converge tightly!
            txt='stress.txt')
a.set_calculator(calc)

uf = UnitCellFilter(a)
relax = BFGS(uf)
relax.run(fmax=0.05)  # Consider much tighter fmax!

a = np.dot(a.get_cell()[0], a.get_cell()[0])**0.5 * 2**0.5
print 'Relaxed lattice parameter: a = %s A' % a
Beispiel #24
0
def rotct_rand(ind1, ind2, Optimizer):
    """Rotate atoms cut and splice
    Rotates atoms randomly around center of mass and cuts with xy plane
    Maintains number of atoms
    Maintains concentration of atoms
    Returns individuals to standard positions at end (un-rotates)
    """
    if 'CX' in Optimizer.debug:
        debug = True
    else:
        debug = False
    Optimizer.output.write('Random Rotate Cut/Splice Cx between individual '+repr(ind1.index)+' and individual '+repr(ind2.index)+'\n')
    
    #Perserve starting conditions of individual
    indi1 = ind1[0].copy()
    indi2 =ind2[0].copy()
    #Translate individuals so COM is at (0,0,0)
    com1 = indi1.get_center_of_mass()
    indi1.translate(-1*com1)
    com2 = indi2.get_center_of_mass()
    indi2.translate(-1*com2)
    #Select random axis, random angle, and random position and rotate individuals
    cmax = [min(numpy.maximum.reduce(indi1.get_positions())[i],numpy.maximum.reduce(indi2.get_positions())[i]) for i in range(3)]
    cmin = [min(numpy.minimum.reduce(indi1.get_positions())[i],numpy.minimum.reduce(indi2.get_positions())[i]) for i in range(3)]
    n=0
    while n<10:
        rax = random.choice(['x', '-x','y','-y','z','-z'])
        rang = random.random()*90
        rpos = [random.uniform(cmin[i]*0.8,cmax[i]*0.8) for i in range(3)]
        indi1.rotate(rax,a=rang,center=rpos,rotate_cell=False)
        #Search for atoms in individual 1 that are above the xy plane
        group1 = Atoms(cell=ind1[0].get_cell(),pbc=ind1[0].get_pbc())
        indices1=[]
        for one in indi1:
            if one.position[2] >= 0:
                group1.append(one)
                indices1.append(one.index)
        if len(group1) > 2 and len(group1) < len(indi1):
            break
        else:
            n+=1
            indi1.rotate(rax,a=-1*rang,center=rpos, rotate_cell=False)
    indi2.rotate(rax,a=rang,center=rpos,rotate_cell=False)
    if debug: 
        print 'Group1 size = ', len(group1)
        print 'Position = ', rpos
        print 'Angle = ', rang
        print 'Axis = ', rax
        print 'Number of tries = ', n
    if len(group1) != 0:
        #Apply concentration forcing if needed
        group2 = Atoms(cell=ind2[0].get_cell(),pbc=ind2[0].get_pbc())
        indices2 = []
        dellist = []
        for one in indi2:
            if one.position[2] >= 0:
                group2.append(one)
                indices2.append(one.index)
        if Optimizer.forcing=='Concentration':
            symlist = list(set(indi1.get_chemical_symbols()))
            seplist = [[atm for atm in group2 if atm.symbol == sym] for sym in symlist]
            group2n=Atoms(cell=group2.get_cell(),pbc=group2.get_pbc())
            indices2n = []
            dellist = []
            for one in group1:
                sym1=one.symbol
                listpos=[i for i,s in enumerate(symlist) if s==sym1][0]
                if len(seplist[listpos]) > 0:
                    pos = random.choice(range(len(seplist[listpos])))
                    group2n.append(seplist[listpos][pos])
                    indices2n.append(indices2[seplist[listpos][pos].index])
                    del seplist[listpos][pos]
                else:
                    dellist.append(one.index)
            if len(dellist) != 0:
                dellist.sort(reverse=True)
                for one in dellist:
                    del group1[one]
                    del indices1[one]
            indices2=indices2n
            group2=group2n.copy()
        else:
            dellist = []
            while len(group2) < len(group1)-len(dellist):
                #Too many atoms in group 1
                dellist.append(random.choice(group1).index)
            if len(dellist) != 0:
                dellist.sort(reverse=True)
                for one in dellist:
                    del group1[one]
                    del indices1[one]
            dellist = []
            while len(group1) < len(group2)-len(dellist):
                #Too many atoms in group 2
                dellist.append(random.choice(group2).index)
            if len(dellist) != 0:
                dellist.sort(reverse=True)
                for one in dellist:
                    del group2[one]
                    del indices2[one]
    
        other2 = Atoms(cell=ind2[0].get_cell(),pbc=ind2[0].get_pbc())
        for one in indi2:
            if one.index not in indices2:
                other2.append(one)
        other1 = Atoms(cell=ind1[0].get_cell(),pbc=ind1[0].get_pbc())
        for one in indi1:
            if one.index not in indices1:
                other1.append(one)
        indi1 = group2.copy()
        indi1.extend(other1)
        indi2 = group1.copy()
        indi2.extend(other2)
    
        #DEBUG: Write crossover to file
        if debug: 
            write_xyz(Optimizer.debugfile, group1,'group1')
            write_xyz(Optimizer.debugfile, other1,'other1')
            write_xyz(Optimizer.debugfile, group2,'group2')
            write_xyz(Optimizer.debugfile, other2,'other2')
            print 'Length of group1 = ',len(group1),'Length of group2',len(group2)
    
        #DEBUG: Check structure of atoms exchanged
        for sym,c,m,u in Optimizer.atomlist:
            nc=len([atm for atm in indi1 if atm.symbol==sym])
            Optimizer.output.write('CX RANDROTCT: Individual 1 contains '+repr(nc)+' '+repr(sym)+' atoms\n')
            nc=len([atm for atm in indi2 if atm.symbol==sym])
            Optimizer.output.write('CX RANDROTCT: Individual 2 contains '+repr(nc)+' '+repr(sym)+' atoms\n')
        if Optimizer.forcing !='Concentration':
            for i in range(len(Optimizer.atomlist)):
                atms1=[inds for inds in indi1 if inds.symbol==Optimizer.atomlist[i][0]]
                atms2=[inds for inds in indi2 if inds.symbol==Optimizer.atomlist[i][0]]
                if len(atms1)==0:
                    if len(atms2)==0:
                        indi1[random.randint(0,len(indi1)-1)].symbol==Optimizer.atomlist[i][0]
                        indi2[random.randint(0,len(indi2)-1)].symbol==Optimizer.atomlist[i][0]
                    else:
                        indi1.append(atms2[random.randint(0,len(atms2)-1)])
                        indi1.pop(random.randint(0,len(indi1)-2))
                else:
                    if len(atms2)==0:
                        indi2.append(atms1[random.randint(0,len(atms1)-1)])
                        indi2.pop(random.randint(0,len(indi2)-2))	
        indi1.rotate(rax,a=-1*rang,center=rpos, rotate_cell=False)
        indi2.rotate(rax,a=-1*rang,center=rpos, rotate_cell=False)
        indi1.translate(com1)
        indi2.translate(com2)
    
    #DEBUG: Check structure and number of atoms in crystal
    if Optimizer.structure=='Defect':
        solid1=Atoms()
        solid1.extend(indi1)
        solid1.extend(ind1.bulki)
        solid2=Atoms()
        solid2.extend(indi2)
        solid2.extend(ind2.bulki)
        for sym,c,m,u in Optimizer.atomlist:
            nc=len([atm for atm in solid1 if atm.symbol==sym])
            Optimizer.output.write('CX RANDROTCT: Defect 1 configuration contains '+repr(nc)+' '+repr(sym)+' atoms\n')
            nc=len([atm for atm in solid2 if atm.symbol==sym])
            Optimizer.output.write('CX RANDROTCT: Defect 2 configuration contains '+repr(nc)+' '+repr(sym)+' atoms\n')
    if debug: Optimizer.output.flush()
    #pdb.set_trace()
    ind1[0]=indi1
    ind2[0]=indi2
    
    return ind1, ind2
Beispiel #25
0
def eval_energy(input):
    """Function to evaluate energy of an individual
    Inputs:
        input = [Optimizer class object with parameters, Individual class structure to be evaluated]
    Outputs:
        energy, bul, individ, signal
        energy = energy of Individual evaluated
        bul = bulk structure of Individual if simulation structure is Defect
        individ = Individual class structure evaluated
        signal = string of information about evaluation
    """
    if input[0]==None:
        energy=0
        bul=0
        individ=0
        rank = MPI.COMM_WORLD.Get_rank()
        signal='Evaluated none individual on '+repr(rank)+'\n'
    else:
        [Optimizer, individ]=input
    if Optimizer.calc_method=='MAST':
        energy = individ.energy
        bul = individ.energy
        signal = 'Recieved MAST structure\n'
    else:
        if Optimizer.parallel: rank = MPI.COMM_WORLD.Get_rank()
        if not Optimizer.genealogy:
            STR='----Individual ' + str(individ.index)+ ' Optimization----\n'
        else:
            STR='----Individual ' + str(individ.history_index)+ ' Optimization----\n'
        indiv=individ[0]
        if 'EE' in Optimizer.debug:
            debug = True
        else:
            debug = False
        if debug: 
            write_xyz(Optimizer.debugfile,indiv,'Recieved by eval_energy')
            Optimizer.debugfile.flush()
        if Optimizer.structure=='Defect':
            indi=indiv.copy()
            if Optimizer.alloy==True:
                bulk=individ.bulki
            else:
                bulk=individ.bulko
            nat=indi.get_number_of_atoms()
            csize=bulk.get_cell()                                                                                                         
            totalsol=Atoms(cell=csize, pbc=True)
            totalsol.extend(indi)
            totalsol.extend(bulk)
            for sym,c,m,u in Optimizer.atomlist:
                nc=len([atm for atm in totalsol if atm.symbol==sym])
                STR+='Defect configuration contains '+repr(nc)+' '+repr(sym)+' atoms\n'
    
        elif Optimizer.structure=='Surface':
            totalsol=Atoms()
            totalsol.extend(indiv)
            nat=indiv.get_number_of_atoms()
            totalsol.extend(individ.bulki)
            for sym,c,m,u in Optimizer.atomlist:
                nc=len([atm for atm in totalsol if atm.symbol==sym])
                STR+='Surface-Bulk configuration contains '+repr(nc)+' '+repr(sym)+' atoms\n'
            cell=numpy.maximum.reduce(indiv.get_cell())
            totalsol.set_cell([cell[0],cell[1],500])
            totalsol.set_pbc([True,True,False])
    
        if Optimizer.constrain_position:
            ts = totalsol.copy()
            indc,indb,vacant,swap,stro = find_defects(ts,Optimizer.solidbulk,0)
            sbulk = Optimizer.solidbulk.copy()
            bcom = sbulk.get_center_of_mass()
            #totalsol.translate(-bulkcom)
            #indc.translate(-bulkcom)
            #totalsol.append(Atom(position=[0,0,0]))
    # 			for one in indc:
    # 				index = [atm.index for atm in totalsol if atm.position[0]==one.position[0] and atm.position[1]==one.position[1] and atm.position[2]==one.position[2]][0]
    # 				if totalsol.get_distance(-1,index) > Optimizer.sf:
    # 					r = random.random()
    # 					totalsol.set_distance(-1,index,Optimizer.sf*r,fix=0)
    # 			totalsol.pop()
    # 			totalsol.translate(bulkcom)
            com = indc.get_center_of_mass()
            dist = (sum((bcom[i] - com[i])**2 for i in range(3)))**0.5
            if dist > Optimizer.sf:
                STR+='Shifting structure to within region\n'
                r = random.random()*Optimizer.sf
                comv = numpy.linalg.norm(com)
                ncom = [one*r/comv for one in com]
                trans = [ncom[i]-com[i] for i in range(3)]
                indices = []
                for one in indc:
                    id = [atm.index for atm in totalsol if atm.position[0]==one.position[0] and atm.position[1]==one.position[1] and atm.position[2]==one.position[2]][0]
                    totalsol[id].position += trans
    
        # Check for atoms that are too close
        min_len=0.7
        #pdb.set_trace()
        if not Optimizer.fixed_region:
            if Optimizer.structure=='Defect' or Optimizer.structure=='Surface':
                cutoffs=[2.0 for one in totalsol]
                nl=NeighborList(cutoffs,bothways=True,self_interaction=False)
                nl.update(totalsol)
                for one in totalsol[0:nat]:
                    nbatoms=Atoms()
                    nbatoms.append(one)
                    indices, offsets=nl.get_neighbors(one.index)
                    for index, d in zip(indices,offsets):
                        index = int(index)
                        sym=totalsol[index].symbol
                        pos=totalsol[index].position + numpy.dot(d,totalsol.get_cell())
                        at=Atom(symbol=sym,position=pos)
                        nbatoms.append(at)
                    while True:
                        dflag=False
                        for i in range(1,len(nbatoms)):
                            d=nbatoms.get_distance(0,i)
                            if d < min_len:
                                nbatoms.set_distance(0,i,min_len+.01,fix=0.5)
                                STR+='--- WARNING: Atoms too close (<0.7A) - Implement Move ---\n'
                                dflag=True
                        if dflag==False:
                            break
                    for i in range(len(indices)):
                        totalsol[indices[i]].position=nbatoms[i+1].position
                    totalsol[one.index].position=nbatoms[0].position
                    nl.update(totalsol)
                if debug:
                    write_xyz(Optimizer.debugfile,totalsol,'After minlength check')
                    Optimizer.debugfile.flush()
            else:
                for i in range(len(indiv)):
                    for j in range(len(indiv)):
                        if i != j:
                            d=indiv.get_distance(i,j)
                            if d < min_len:
                                indiv.set_distance(i,j,min_len,fix=0.5)
                                STR+='--- WARNING: Atoms too close (<0.7A) - Implement Move ---\n'
                if debug:
                    write_xyz(Optimizer.debugfile,indiv,'After minlength check')
                    Optimizer.debugfile.flush()
    
        # Set calculator to use to get forces/energies
        if Optimizer.parallel:
            calc = setup_calculator(Optimizer)
            if Optimizer.fixed_region:
                pms=copy.deepcopy(calc.parameters)
                try:
                    pms['mass'][len(pms['mass'])-1] += '\ngroup RO id >= '+repr(nat)+'\nfix freeze RO setforce 0.0 0.0 0.0\n'
                except KeyError:
                    pms['pair_coeff'][0] += '\ngroup RO id >= '+repr(nat)+'\nfix freeze RO setforce 0.0 0.0 0.0\n'
                calc = LAMMPS(parameters=pms, files=calc.files, keep_tmp_files=calc.keep_tmp_files, tmp_dir=calc.tmp_dir)
                lmin = copy.copy(Optimizer.lammps_min)
                Optimizer.lammps_min = None
                Optimizer.static_calc = setup_calculator(Optimizer)
                Optimizer.lammps_min = lmin
        else:
            calc=Optimizer.calc
        if Optimizer.structure=='Defect' or Optimizer.structure=='Surface':
            totalsol.set_calculator(calc)
            totalsol.set_pbc(True)
        else:
            indiv.set_calculator(calc)
            indiv.set_pbc(True)	#Current bug in ASE optimizer-Lammps prevents pbc=false 
            if Optimizer.structure=='Cluster':
                indiv.set_cell([500,500,500])
                indiv.translate([250,250,250])
    
        cwd=os.getcwd()
        # Perform Energy Minimization
        if not Optimizer.parallel:
            Optimizer.output.flush()
        if Optimizer.ase_min == True:
            try:
                if Optimizer.structure=='Defect' or Optimizer.structure=='Surface':
                    dyn=BFGS(totalsol)
                else:
                    dyn=BFGS(indiv)
                dyn.run(fmax=Optimizer.ase_min_fmax, steps=Optimizer.ase_min_maxsteps)
            except OverflowError:
                STR+='--- Error: Infinite Energy Calculated - Implement Random ---\n'
                box=Atoms()
                indiv=gen_pop_box(Optimizer.natoms, Optimizer.atomlist, Optimizer.size)
                indiv.set_calculator(calc)
                dyn=BFGS(indiv)
                dyn.run(fmax=fmax, steps=steps)
            except numpy.linalg.linalg.LinAlgError:
                STR+='--- Error: Singular Matrix - Implement Random ---\n'
                indiv=gen_pop_box(Optimizer.natoms, Optimizer.atomlist, Optimizer.size)
                indiv.set_calculator(calc)
                dyn=BFGS(indiv)
                dyn.run(fmax=fmax, steps=steps)
            # Get Energy of Minimized Structure
            if Optimizer.structure=='Defect' or Optimizer.structure=='Surface':
                en=totalsol.get_potential_energy()
                #force=numpy.maximum.reduce(abs(totalsol.get_forces()))
                if Optimizer.fitness_scheme == 'enthalpyfit':
                    pressure=totalsol.get_isotropic_pressure(totalsol.get_stress())
                    cell_max=numpy.maximum.reduce(totalsol.get_positions())
                    cell_min=numpy.minimum.reduce(totalsol.get_positions())
                    cell=cell_max-cell_min
                    volume=cell[0]*cell[1]*cell[2]
                else:
                    pressure=0
                    volume=0
                na=totalsol.get_number_of_atoms()
                ena=en/na
                energy=en
                individ[0]=totalsol[0:nat]
                bul=totalsol[(nat):len(totalsol)]
                STR+='Number of positions = '+repr(len(bul)+len(individ[0]))+'\n'
                individ[0].set_cell(csize)
                indiv=individ[0]
            else:
                en=indiv.get_potential_energy()
                if Optimizer.fitness_scheme == 'enthalpyfit':
                    pressure=indiv.get_isotropic_pressure(indiv.get_stress())
                    cell_max=numpy.maximum.reduce(indiv.get_positions())
                    cell_min=numpy.minimum.reduce(indiv.get_positions())
                    cell=cell_max-cell_min
                    volume=cell[0]*cell[1]*cell[2]
                else: 
                    pressure=0
                    volume=0
                na=indiv.get_number_of_atoms()
                ena=en/na
                energy=ena
                individ[0]=indiv
                bul=0
        else:
            if Optimizer.structure=='Defect' or Optimizer.structure=='Surface':
                if Optimizer.calc_method=='VASP':
                    en=totalsol.get_potential_energy()
                    calcb=Vasp(restart=True)
                    totalsol=calcb.get_atoms()
                    stress=calcb.read_stress()
                else:
                    try:
                        totcop=totalsol.copy()
                        if debug: write_xyz(Optimizer.debugfile,totcop,'Individual sent to lammps')
                        OUT=totalsol.calc.calculate(totalsol)
                        totalsol=OUT['atoms']
                        totalsol.set_pbc(True)
                        if Optimizer.fixed_region:
                            if debug:
                                print 'Energy of fixed region calc = ', OUT['thermo'][-1]['pe']
                            totalsol.set_calculator(Optimizer.static_calc)
                            OUT=totalsol.calc.calculate(totalsol)
                            totalsol=OUT['atoms']
                            totalsol.set_pbc(True)
                            if debug:
                                print 'Energy of static calc = ', OUT['thermo'][-1]['pe']
                        en=OUT['thermo'][-1]['pe']
                        stress=numpy.array([OUT['thermo'][-1][i] for i in ('pxx','pyy','pzz','pyz','pxz','pxy')])*(-1e-4*GPa)
                        #force=numpy.maximum.reduce(abs(totalsol.get_forces()))
                        if debug:
                            write_xyz(Optimizer.debugfile,totalsol,'After Lammps Minimization')
                            Optimizer.debugfile.flush()
                    except Exception, e:
                        os.chdir(cwd)
                        STR+='WARNING: Exception during energy eval:\n'+repr(e)+'\n'
                        f=open('problem-structures.xyz','a')
                        write_xyz(f,totcop,data='Starting structure hindex='+individ.history_index)
                        write_xyz(f,totalsol,data='Lammps Min structure')
                        en=10
                        stress=0
                        f.close()
                if Optimizer.fitness_scheme == 'enthalpyfit':
                    pressure=totalsol.get_isotropic_pressure(stress)
                    cell_max=numpy.maximum.reduce(totalsol.get_positions())
                    cell_min=numpy.minimum.reduce(totalsol.get_positions())
                    cell=cell_max-cell_min
                    volume=cell[0]*cell[1]*cell[2]
                else:
                    pressure=totalsol.get_isotropic_pressure(stress)
                    volume=0
                na=totalsol.get_number_of_atoms()
                ena=en/na
                energy=en
                if Optimizer.structure=='Defect':
                    if Optimizer.fixed_region==True or Optimizer.finddefects==False:
                        individ[0]=totalsol[0:nat]
                        bul=totalsol[(nat):len(totalsol)]
                        individ[0].set_cell(csize)
                    else:
                        if 'FI' in Optimizer.debug:
                            outt=find_defects(totalsol,Optimizer.solidbulk,Optimizer.sf,atomlistcheck=Optimizer.atomlist,trackvacs=Optimizer.trackvacs,trackswaps=Optimizer.trackswaps,debug=Optimizer.debugfile)
                        else:
                            outt=find_defects(totalsol,Optimizer.solidbulk,Optimizer.sf,atomlistcheck=Optimizer.atomlist,trackvacs=Optimizer.trackvacs,trackswaps=Optimizer.trackswaps,debug=False)
                        individ[0]=outt[0]
                        bul=outt[1]
                        individ.vacancies = outt[2]
                        individ.swaps = outt[3]
                        STR += outt[4]
                    indiv=individ[0]
                else:
                    top,bul=find_top_layer(totalsol,Optimizer.surftopthick)
                    indiv=top.copy()
                    individ[0]=top.copy()
            else:
Beispiel #26
0
# Takes 30 mins with 8 cores in domain-parallel (memory ~500mb, max 1.5gb)

import numpy as np
from ase import Atom, Atoms
from gpaw import GPAW, MixerDif, mpi
from gpaw.lrtddft import LrTDDFT
from gpaw.pes.dos import DOSPES
from gpaw.pes.tddft import TDDFTPES

atoms = Atoms([Atom('C', (7.666263598984184, 7.637780850431168, 8.289450797111844)),
               Atom('O', (8.333644370007132, 8.362384430165646, 7.710230973847514))])
atoms.center(vacuum=8)

h = 0.15
N_c = np.round(atoms.get_cell().diagonal() / h / 16) * 16

m_c = GPAW(gpts=N_c, nbands=6, mixer=MixerDif(0.1, 5, weight=100.0),
           #convergence={'bands':10},
           parallel={'domain': mpi.size},
           xc='PBE', txt='CO-m.txt', spinpol=True)

m = atoms.copy()
m.set_initial_magnetic_moments([-1,1])
m.set_calculator(m_c)
m.get_potential_energy()

d_c = GPAW(gpts=N_c, nbands=16, mixer=MixerDif(0.1, 5, weight=100.0),
           convergence={'bands':10},
           parallel={'domain': mpi.size},
           xc='PBE', txt='CO-d.txt', spinpol=True)
Beispiel #27
0
# Calculate potential energy per atom for orthogonal unitcell
atoms = hcp0001('C', a=a / sqrt(3), vacuum=d, size=(3, 2, 1), orthogonal=True)
del atoms[[1, -1]]
atoms.center(axis=0)
atoms.set_calculator(calc)

kpts_c = np.ceil(50 / np.sum(atoms.get_cell()**2, axis=1)**0.5).astype(int)
kpts_c[~atoms.get_pbc()] = 1
calc.set(kpts=kpts_c)
eppa1 = atoms.get_potential_energy() / len(atoms)
F1_av = atoms.get_forces()
equal(np.abs(F1_av).max(), 0, 5e-3)

# Redo calculation with non-orthogonal unitcell
atoms = Atoms(symbols='C2',
              pbc=(True, True, False),
              positions=[(a / 2, -sqrt(3) / 6 * a, d),
                         (a / 2, sqrt(3) / 6 * a, d)],
              cell=[(a / 2, -sqrt(3) / 2 * a, 0), (a / 2, sqrt(3) / 2 * a, 0),
                    (0, 0, 2 * d)])
atoms.set_calculator(calc)

kpts_c = np.ceil(50 / np.sum(atoms.get_cell()**2, axis=1)**0.5).astype(int)
kpts_c[~atoms.get_pbc()] = 1
calc.set(kpts=kpts_c)
eppa2 = atoms.get_potential_energy() / len(atoms)
F2_av = atoms.get_forces()
equal(np.abs(F2_av).max(), 0, 5e-3)

equal(eppa1, eppa2, 1e-3)
Beispiel #28
0
def rotct_rand_defect(ind1, ind2, Optimizer):
    """Rotate atoms cut and splice
    Translates atoms to center of positions first
    Rotates atoms randomly around center of mass and cuts with xy plane
    Maintains number of atoms
    Maintains concentration of atoms
    Returns individuals to standard positions at end (un-rotates)
    """
    if "CX" in Optimizer.debug:
        debug = True
    else:
        debug = False
    Optimizer.output.write(
        "Random Rotate Cut/Splice Cx for defects between individual "
        + repr(ind1.index)
        + " and individual "
        + repr(ind2.index)
        + "\n"
    )

    # Perserve starting conditions of individual
    indi1 = ind1[0].copy()
    indi2 = ind2[0].copy()
    # Translate individuals so COP is at (0,0,0)
    if Optimizer.structure == "Defect":
        # Identify center of positions for defect structure
        indi1c, indi1b, vacant1, swap1, stro1 = find_defects(indi1, Optimizer.solidbulk, 0)
        com1 = position_average(indi1c)
        indi1 = shift_atoms(indi1, com1)
        # Do the same for second individual
        indi2c, indi2b, vacant2, swap2, stro2 = find_defects(indi2, Optimizer.solidbulk, 0)
        com2 = position_average(indi2c)
        indi2 = shift_atoms(indi2, com2)
    else:
        com1 = indi1.get_center_of_mass()
        indi1.translate(-1 * com1)
        com2 = indi2.get_center_of_mass()
        indi2.translate(-1 * com2)
    # Select random axis, random angle, and random position and rotate individuals
    cmax = [
        min(numpy.maximum.reduce(indi1.get_positions())[i], numpy.maximum.reduce(indi2.get_positions())[i])
        for i in range(3)
    ]
    cmin = [
        min(numpy.minimum.reduce(indi1.get_positions())[i], numpy.minimum.reduce(indi2.get_positions())[i])
        for i in range(3)
    ]
    n = 0
    while n < 10:
        rax = random.choice(["x", "-x", "y", "-y", "z", "-z"])
        rang = random.random() * 90
        rpos = [random.uniform(cmin[i] * 0.8, cmax[i] * 0.8) for i in range(3)]
        indi1.rotate(rax, a=rang, center=rpos, rotate_cell=False)
        # Search for atoms in individual 1 that are above the xy plane
        group1 = Atoms(cell=ind1[0].get_cell(), pbc=ind1[0].get_pbc())
        indices1 = []
        for one in indi1:
            if one.position[2] >= 0:
                group1.append(one)
                indices1.append(one.index)
        if len(group1) > 2 and len(group1) < len(indi1):
            break
        else:
            n += 1
            indi1.rotate(rax, a=-1 * rang, center=rpos, rotate_cell=False)
    indi2.rotate(rax, a=rang, center=rpos, rotate_cell=False)
    if debug:
        print "Group1 size = ", len(group1)
        print "Position = ", rpos
        print "Angle = ", rang
        print "Axis = ", rax
        print "Number of tries = ", n
    if len(group1) != 0:
        # Apply concentration forcing if needed
        group2 = Atoms(cell=ind2[0].get_cell(), pbc=ind2[0].get_pbc())
        indices2 = []
        dellist = []
        for one in indi2:
            if one.position[2] >= 0:
                group2.append(one)
                indices2.append(one.index)
        if Optimizer.forcing == "Concentration":
            symlist = list(set(indi1.get_chemical_symbols()))
            seplist = [[atm for atm in group2 if atm.symbol == sym] for sym in symlist]
            group2n = Atoms(cell=group2.get_cell(), pbc=group2.get_pbc())
            indices2n = []
            dellist = []
            for one in group1:
                sym1 = one.symbol
                listpos = [i for i, s in enumerate(symlist) if s == sym1][0]
                if len(seplist[listpos]) > 0:
                    pos = random.choice(range(len(seplist[listpos])))
                    group2n.append(seplist[listpos][pos])
                    indices2n.append(indices2[seplist[listpos][pos].index])
                    del seplist[listpos][pos]
                else:
                    dellist.append(one.index)
            if len(dellist) != 0:
                dellist.sort(reverse=True)
                for one in dellist:
                    del group1[one]
                    del indices1[one]
            indices2 = indices2n
            group2 = group2n.copy()
        else:
            dellist = []
            while len(group2) < len(group1) - len(dellist):
                # Too many atoms in group 1
                dellist.append(random.choice(group1).index)
            if len(dellist) != 0:
                dellist.sort(reverse=True)
                for one in dellist:
                    del group1[one]
                    del indices1[one]
            dellist = []
            while len(group1) < len(group2) - len(dellist):
                # Too many atoms in group 2
                dellist.append(random.choice(group2).index)
            if len(dellist) != 0:
                dellist.sort(reverse=True)
                for one in dellist:
                    del group2[one]
                    del indices2[one]

        other2 = Atoms(cell=ind2[0].get_cell(), pbc=ind2[0].get_pbc())
        for one in indi2:
            if one.index not in indices2:
                other2.append(one)
        other1 = Atoms(cell=ind1[0].get_cell(), pbc=ind1[0].get_pbc())
        for one in indi1:
            if one.index not in indices1:
                other1.append(one)
        indi1 = group2.copy()
        indi1.extend(other1)
        indi2 = group1.copy()
        indi2.extend(other2)

        # DEBUG: Write crossover to file
        if debug:
            write_xyz(Optimizer.debugfile, group1, "group1")
            write_xyz(Optimizer.debugfile, other1, "other1")
            write_xyz(Optimizer.debugfile, group2, "group2")
            write_xyz(Optimizer.debugfile, other2, "other2")
            print "Length of group1 = ", len(group1), "Length of group2", len(group2)

        # DEBUG: Check structure of atoms exchanged
        for sym, c, m, u in Optimizer.atomlist:
            nc = len([atm for atm in indi1 if atm.symbol == sym])
            Optimizer.output.write(
                "CX RANDROTCT_Defect: Individual 1 contains " + repr(nc) + " " + repr(sym) + " atoms\n"
            )
            nc = len([atm for atm in indi2 if atm.symbol == sym])
            Optimizer.output.write(
                "CX RANDROTCT_Defect: Individual 2 contains " + repr(nc) + " " + repr(sym) + " atoms\n"
            )
        if Optimizer.forcing != "Concentration":
            for i in range(len(Optimizer.atomlist)):
                atms1 = [inds for inds in indi1 if inds.symbol == Optimizer.atomlist[i][0]]
                atms2 = [inds for inds in indi2 if inds.symbol == Optimizer.atomlist[i][0]]
                if len(atms1) == 0:
                    if len(atms2) == 0:
                        indi1[random.randint(0, len(indi1) - 1)].symbol == Optimizer.atomlist[i][0]
                        indi2[random.randint(0, len(indi2) - 1)].symbol == Optimizer.atomlist[i][0]
                    else:
                        indi1.append(atms2[random.randint(0, len(atms2) - 1)])
                        indi1.pop(random.randint(0, len(indi1) - 2))
                else:
                    if len(atms2) == 0:
                        indi2.append(atms1[random.randint(0, len(atms1) - 1)])
                        indi2.pop(random.randint(0, len(indi2) - 2))
        indi1.rotate(rax, a=-1 * rang, center=rpos, rotate_cell=False)
        indi2.rotate(rax, a=-1 * rang, center=rpos, rotate_cell=False)
        if Optimizer.structure == "Defect":
            indi1 = shift_atoms(indi1, [-p for p in com1])
            indi2 = shift_atoms(indi2, [-p for p in com2])
        else:
            indi1.translate(com1)
            indi2.translate(com2)

        # DEBUG: Check structure and number of atoms in crystal
        if Optimizer.structure == "Defect":
            solid1 = Atoms()
            solid1.extend(indi1)
            solid1.extend(ind1.bulki)
            solid2 = Atoms()
            solid2.extend(indi2)
            solid2.extend(ind2.bulki)
            for sym, c, m, u in Optimizer.atomlist:
                nc = len([atm for atm in solid1 if atm.symbol == sym])
                Optimizer.output.write(
                    "CX RANDROTCT_Defect: Defect 1 configuration contains " + repr(nc) + " " + repr(sym) + " atoms\n"
                )
                nc = len([atm for atm in solid2 if atm.symbol == sym])
                Optimizer.output.write(
                    "CX RANDROTCT_Defect: Defect 2 configuration contains " + repr(nc) + " " + repr(sym) + " atoms\n"
                )
        if debug:
            Optimizer.output.flush()
        # pdb.set_trace()
        ind1[0] = indi1
        ind2[0] = indi2

    return ind1, ind2
Beispiel #29
0
def write_pw_in(d,a,p):

    if 'iofile' in p.keys() :
        # write special varians of the pw input
        fh=open(os.path.join(d,p['iofile']+'.in'),'w')
    else :
        # write standard pw input
        fh=open(os.path.join(d,'pw.in'),'w')

    # ----------------------------------------------------------
    # CONTROL section
    # ----------------------------------------------------------

    fh.write(' &CONTROL\n')
    fh.write("    calculation = '%s',\n" % p['calc'])

    pwin_k=['tstress', 'tprnfor','nstep','pseudo_dir','outdir',
            'wfcdir', 'prefix','forc_conv_thr', 'etot_conv_thr']
    write_section_params(fh, pwin_k, p)
    fh.write(' /\n')
    
    # ----------------------------------------------------------
    # SYSTEM section
    # ----------------------------------------------------------

    fh.write(' &SYSTEM\n')
    if p['use_symmetry'] :
        # Need to use symmetry properly
        # create a dummy atoms object for primitive cell
        primcell=write_cell_params(fh,a,p)
        if primcell :
            # primitive cell has been found - let us use it
            cr=Atoms(cell=primcell[0],scaled_positions=primcell[1],numbers=primcell[2],pbc=True)
        else :
            # no primitive cell found - drop the symmetry
            cr=a
    else :
        cr=a
        p['ibrav']=0
    fh.write("    nat = %d,\n" % (cr.get_number_of_atoms()))
    fh.write("    ntyp = %d,\n" % (len(set(cr.get_atomic_numbers()))))
    pwin_k=['ecutwfc','ibrav','nbnd','occupations','degauss','smearing','ecutrho','nbnd']
    # must also take into account degauss and smearing
    write_section_params(fh, pwin_k, p)
    fh.write(' /\n')

    # ----------------------------------------------------------
    # ELECTRONS section
    # ----------------------------------------------------------

    fh.write(' &ELECTRONS\n')
    # must also take into account mixing_beta mixing_mode and diagonalization
    pwin_k=['conv_thr','mixing_beta','mixing_mode','diagonalization',
        'mixing_ndim','electron_maxstep']
    write_section_params(fh, pwin_k, p)
    fh.write(' /\n')

    # ----------------------------------------------------------
    # | IONS section
    # ----------------------------------------------------------

    if p['calc'] in ['vc-relax', 'vc-md', 'md', 'relax']:
        fh.write(' &IONS\n')
        pwin_k=['ion_dynamics','ion_positions', 'phase_space', 'pot_extrapolation']
        write_section_params(fh, pwin_k, p)
        
        fh.write(' /\n')


    # ----------------------------------------------------------
    # | CELL section
    # ----------------------------------------------------------

    if p['calc'] in ['vc-relax', 'vc-md']:
        fh.write('&CELL\n')
        pwin_k=['cell_dynamics','press', 'cell_dofree']
        write_section_params(fh, pwin_k, p)
    
        fh.write('/\n')


    # ----------------------------------------------------------
    # Card: ATOMIC_SPECIES
    # ----------------------------------------------------------
        
    fh.write('ATOMIC_SPECIES\n')
    
    xc=p['xc']
    pp_type=p['pp_type']
    pp_format=p['pp_format']
    # we check if the desired potential exists. Get the PP locations
    if 'ESPRESSO_PSEUDO' in os.environ:
        pppaths = os.environ['ESPRESSO_PSEUDO']
    else:
        pppaths = p['pseudo_dir']  # default
    pppaths = pppaths.split(':')
    # search for element PP in each location (in principle with QE only one location)
    for nm, mass in set(zip(cr.get_chemical_symbols(),cr.get_masses())):
        name = "%s_%s_%s.%s" % (nm, xc, pp_type, pp_format)
        found = False
        
        for path in pppaths:
            filename = os.path.join(path, name)

            match = glob.glob(filename)
            if match: # the exact name as expected
                found = True
                name = match[0]
                
            if not found: # a more permissive name with element.*.format
                name = "%s.*.%s" % (nm, pp_format)
                filename = os.path.join(path, name)
                match = glob.glob(filename)
                if match:
                    found = True
                    name = match[0] # the first match
            if not found: # a more permissive name with element_*.format
                name = "%s_*.%s" % (nm, pp_format)
                filename = os.path.join(path, name)
                match = glob.glob(filename)
                if match:
                    found = True
                    name = match[0] # the first match
            if not found: # a more permissive name with just the element_*
                name = "%s_*" % (nm)
                filename = os.path.join(path, name)
                match = glob.glob(filename)
                if match:
                    found = True
                    name = match[0] # the first match
            if not found: # a more permissive name with just the element.*
                name = "%s.*" % (nm)
                filename = os.path.join(path, name)
                match = glob.glob(filename)
                if match:
                    found = True
                    name = match[0] # the first match

        if not found:
            raise RuntimeError('Espresso: No pseudopotential for %s. Aborting.' % nm)
        
        fh.write("    %s %g %s \n" % (nm, mass, os.path.basename(name)))

    # ----------------------------------------------------------
    # Card: ATOMIC_POSITIONS
    # ----------------------------------------------------------
    
    fh.write('ATOMIC_POSITIONS crystal\n')
    # Now we can write it out
    for n,v in zip(cr.get_chemical_symbols(),cr.get_scaled_positions()):
        fh.write("    %s %g %g %g\n" % (n, v[0], v[1], v[2]))

    # ----------------------------------------------------------
    # Card: CELL_PARAMETERS
    # ----------------------------------------------------------
    # Write out only if ibrav==0 - no symmetry used
    if not p['use_symmetry'] or p['ibrav']==0:
        fh.write('CELL_PARAMETERS angstrom\n')
        
        for v in cr.get_cell():
            fh.write('    %f %f %f\n' % tuple(v))
        
    # ----------------------------------------------------------
    # Card: K_POINTS
    # ----------------------------------------------------------

    if p['kpt_type'] in ['automatic','edos'] :
        fh.write('K_POINTS %s\n' % 'automatic')
    else :
        fh.write('K_POINTS %s\n' % p['kpt_type'])
        
    if p['kpt_type'] is 'automatic':
        fh.write('   %d %d %d   %d %d %d\n' % (tuple(p['kpts'])+tuple(p['kpt_shift'])))
    elif p['kpt_type'] is 'edos':
        fh.write('   %d %d %d   %d %d %d\n' % (tuple(p['nkdos'])+tuple([0,0,0])))
    elif not p['kpt_type'] is 'gamma':
        write_q_path(fh,p['qpath'],p['points'])
    fh.close()
Beispiel #30
0
def write_cell_params(fh, a, p):
    '''
    Write the specification of the cell using a traditional A,B,C, 
    alpha, beta, gamma scheme. The symmetry and parameters are determined
    from the atoms (a) object. The atoms object is translated into a 
    primitive unit cell but *not* converted. This is just an internal procedure.
    If you wish to work with primitive unit cells in ASE, you need to make 
    a conversion yourself. The cell params are in angstrom.
    
    Input
    -----
        fh  file handle of the opened pw.in file
        a   atoms object
        p   parameters dictionary
        
    Output
    ------
        Primitive cell tuple of arrays: (lattice, atoms, atomic numbers)
    '''
    
    assert(p['use_symmetry'])
    
    # Get a spacegroup name and number for the a
    sg,sgn=spglib.get_spacegroup(a).split()
    # Extract the number
    sgn=int(sgn[1:-1])
    # Extract the lattice type
    ltyp=sg[0]
    
    # Find a primitive unit cell for the system
    # puc is a tuple of (lattice, atoms, atomic numbers)
    puc=spglib.find_primitive(a)
    cell=puc[0]
    apos=puc[1]
    anum=puc[2]
    icell=a.get_cell()
    A=norm(icell[0])
    B=norm(icell[1])
    C=norm(icell[2])

    # Select appropriate ibrav
    if sgn >= 195 :
        # Cubic lattice
        if   ltyp=='P':  
            p['ibrav']=1  # Primitive
            qepc=array([[1,0,0],[0,1,0],[0,0,1]])
        elif ltyp=='F':  
            p['ibrav']=2  # FCC
            qepc=array([[-1,0,1],[0,1,1],[-1,1,0]])/2.0
        elif ltyp=='I':  
            p['ibrav']=3  # BCC
            qepc=array([[1,1,1],[-1,1,1],[-1,-1,1]])/2.0
        else :
            print 'Impossible lattice symmetry! Contact the author!'
            raise NotImplementedError
        #a=sqrt(2)*norm(cell[0])
        qepc=A*qepc
        fh.write('      A = %f,\n' % (A,))
    elif sgn >= 143 :
        # Hexagonal and trigonal 
        if   ltyp=='P' :  
            p['ibrav']=4  # Primitive
            qepc=array([[1,0,0],[-1/2,sqrt(3)/2,0],[0,0,C/A]])
        elif ltyp=='R' :  
            p['ibrav']=5  # Trigonal rhombohedral
            raise NotImplementedError
        else :
            print 'Impossible lattice symmetry! Contact the author!'
            raise NotImplementedError
        qepc=A*qepc
        fh.write('      A = %f,\n' % (A,))
        fh.write('      C = %f,\n' % (C,))
    elif sgn >= 75 :
        raise NotImplementedError
    elif sgn ==1 :
        # P1 symmetry - no special primitive cell signal to the caller
        p['ibrav']=0
        return None
    else :
        raise NotImplementedError
    cp=Atoms(cell=puc[0], scaled_positions=puc[1], numbers=puc[2], pbc=True)
    qepc=Atoms(cell=qepc, 
        positions=cp.get_positions(), 
        numbers=cp.get_atomic_numbers(), pbc=True)
    return qepc.get_cell(), qepc.get_scaled_positions(), qepc.get_atomic_numbers()
Beispiel #31
0
    return ed


if __name__ == '__main__':
    import matplotlib.pyplot as plt
    from ase import Atoms
    from ase.visualize import view
    from ase.cluster import FaceCenteredCubic
    import ase.io as aseio

    # atoms = Atoms('Pt', [(0, 0, 0)])
    atoms = Atoms(
        FaceCenteredCubic('Pt', [[1, 0, 0], [1, 1, 0], [1, 1, 1]], (2, 3, 2)))
    # atoms = atoms[[atom.index for atom in atoms if atom.position[2]< 1.5]]
    view(atoms)
    atoms.set_cell(atoms.get_cell() * 1.2)
    atoms.center()
    cell = atoms.get_cell()
    print(cell, len(atoms))
    resolution = .3 * np.ones(3)
    c = np.diagonal(cell)
    v = tuple(np.int32(np.ceil(c / resolution)))
    voxels = np.zeros(v)
    ed = np.zeros(v)
    i = 0
    for atom in atoms:
        print(i)
        ed += get_atomic_electron_density(atom, voxels, resolution)
        i += 1
    print(ed[:, :, 0])
    plt.imshow(np.sum(ed, axis=2), cmap='viridis')
import numpy as np

from ase import Atom, Atoms
from ase.optimize import BFGS
from ase.parallel import parprint
from ase.units import Hartree
import gpaw.mpi as mpi
from gpaw import GPAW
from gpaw.test import equal
from gpaw.lrtddft.kssingle import KSSingles

Be = Atoms('Be')
Be.center(vacuum=6)
if 1:
# introduce a sligth non-orthgonality
    cell = Be.get_cell()
    cell[1] += 0.001 * cell[0]
    Be.set_cell(cell)

txt = None
#txt='-'
eigensolver = None
#eigensolver = 'rmm-diis'

#modes = ['lcao', 'fd']
modes = ['fd']

for mode in modes:
    energy = {}
    osz = {}
    for pbc in [False, True]:
Beispiel #33
0
def write_pw_in(d,a,p):

    if 'iofile' in p.keys() :
        # write special varians of the pw input
        fh=open(os.path.join(d,p['iofile']+'.in'),'w')
    else :
        # write standard pw input
        fh=open(os.path.join(d,'pw.in'),'w')

    # ----------------------------------------------------------
    # CONTROL section
    # ----------------------------------------------------------

    fh.write(' &CONTROL\n')
    fh.write("    calculation = '%s',\n" % p['calc'])

    pwin_k=['tstress', 'tprnfor','nstep','pseudo_dir','outdir',
            'wfcdir', 'prefix','forc_conv_thr', 'etot_conv_thr']
    write_section_params(fh, pwin_k, p)
    fh.write(' /\n')
    
    # ----------------------------------------------------------
    # SYSTEM section
    # ----------------------------------------------------------

    fh.write(' &SYSTEM\n')
    if p['use_symmetry'] :
        # Need to use symmetry properly
        # create a dummy atoms object for primitive cell
        primcell=write_cell_params(fh,a,p)
        if primcell :
            # primitive cell has been found - let us use it
            cr=Atoms(cell=primcell[0],scaled_positions=primcell[1],numbers=primcell[2],pbc=True)
        else :
            # no primitive cell found - drop the symmetry
            cr=a
    else :
        cr=a
        p['ibrav']=0
    fh.write("    nat = %d,\n" % (cr.get_number_of_atoms()))
    fh.write("    ntyp = %d,\n" % (len(set(cr.get_atomic_numbers()))))
    pwin_k=['ecutwfc','ibrav','nbnd','occupations']
    write_section_params(fh, pwin_k, p)
    fh.write(' /\n')

    # ----------------------------------------------------------
    # ELECTRONS section
    # ----------------------------------------------------------

    fh.write(' &ELECTRONS\n')
    fh.write(' /\n')

    # ----------------------------------------------------------
    # | IONS section
    # ----------------------------------------------------------

    if p['calc'] in ['vc-relax', 'vc-md', 'md', 'relax']:
        fh.write(' &IONS\n')
        pwin_k=['ion_dynamics','ion_positions', 'phase_space', 'pot_extrapolation']
        write_section_params(fh, pwin_k, p)
        
        fh.write(' /\n')


    # ----------------------------------------------------------
    # | CELL section
    # ----------------------------------------------------------

    if p['calc'] in ['vc-relax', 'vc-md']:
        fh.write('&CELL\n')
        pwin_k=['cell_dynamics','press', 'cell_dofree']
        write_section_params(fh, pwin_k, p)
    
        fh.write('/\n')


    # ----------------------------------------------------------
    # Card: ATOMIC_SPECIES
    # ----------------------------------------------------------
        
    fh.write('ATOMIC_SPECIES\n')
    
    xc=p['xc']
    pp_type=p['pp_type']
    pp_format=p['pp_format']
    for nm, mass in set(zip(cr.get_chemical_symbols(),cr.get_masses())):
        fh.write("    %s %g %s_%s_%s.%s \n" % (nm, mass, nm, xc, pp_type, pp_format))

    # ----------------------------------------------------------
    # Card: ATOMIC_POSITIONS
    # ----------------------------------------------------------
    
    fh.write('ATOMIC_POSITIONS crystal\n')
    # Now we can write it out
    for n,v in zip(cr.get_chemical_symbols(),cr.get_scaled_positions()):
        fh.write("    %s %g %g %g\n" % (n, v[0], v[1], v[2]))

    # ----------------------------------------------------------
    # Card: CELL_PARAMETERS
    # ----------------------------------------------------------
    # Write out only if ibrav==0 - no symmetry used
    if not p['use_symmetry'] or p['ibrav']==0:
        fh.write('CELL_PARAMETERS angstrom\n')
        
        for v in cr.get_cell():
            fh.write('    %f %f %f\n' % tuple(v))
        
    # ----------------------------------------------------------
    # Card: K_POINTS
    # ----------------------------------------------------------

    if p['kpt_type'] in ['automatic','edos'] :
        fh.write('K_POINTS %s\n' % 'automatic')
    else :
        fh.write('K_POINTS %s\n' % p['kpt_type'])
        
    if p['kpt_type'] is 'automatic':
        fh.write('   %d %d %d   %d %d %d\n' % (tuple(p['kpts'])+tuple(p['kpt_shift'])))
    elif p['kpt_type'] is 'edos':
        fh.write('   %d %d %d   %d %d %d\n' % (tuple(p['nkdos'])+tuple([0,0,0])))
    elif not p['kpt_type'] is 'gamma':
        write_q_path(fh,p['qpath'],p['points'])
    fh.close()
Beispiel #34
0
from ase import Atoms, Atom
import numpy as np
b = 7.1
atoms = Atoms([Atom('C', [0., 0., 0.]),
               Atom('O', [1.1, 0., 0.])],
              cell=[[b, b, 0.],
                    [b, 0., b],
                    [0., b, b]])
# get unit cell vectors and their lengths
(a1, a2, a3) = atoms.get_cell()
print '|a1| = {0:1.2f} Ang'.format(np.sum(a1**2)**0.5)
print '|a2| = {0:1.2f} Ang'.format(np.linalg.norm(a2))
print '|a3| = {0:1.2f} Ang'.format(np.sum(a3**2)**0.5)
Beispiel #35
0
import numpy as np

from ase import Atom,Atoms
from ase.io import write

atoms = Atoms('Ni4', positions= [(0, 0, 0),
                                 (0.45, 0, 0),
                                 (0, 0.5, 0),
                                 (0.5, 0.5, 0),])
atoms[1].x = 0.5
a = 3.55
cell = [(2 / np.sqrt(2.0) * a, 0, 0),
        (1 / np.sqrt(2.0) * a, np.sqrt(3.0 / 2.0) * a, 0),
        (0, 0, 10 * np.sqrt(3.0) / 3.0 * a)]
atoms.set_cell(cell, scale_atoms=True)
write('a1.png', atoms, rotation='-73x', show_unit_cell=2)

a = atoms.repeat((3, 3, 2))
a.set_cell(atoms.get_cell())
write('a2.png', a, rotation='-73x', show_unit_cell=True)

xyzcell = np.identity(3) # The 3x3 unit matrix
atoms.set_cell(xyzcell, scale_atoms=True)  # Set the unit cell and rescale
atoms.append(Atom('Ni', (1/6., 1/6., .1)))  
atoms.set_cell(cell, scale_atoms=True)  # Set the unit cell and scale back
a = atoms.repeat((3, 3, 1))
a.set_cell(atoms.get_cell())
write('a3.png', a, show_unit_cell=True)

Beispiel #36
0
     [-3.68163760377696e+00, -5.94997793843316e+00, +1.14910098375475e+01]],
    [[+1.13578166916005e+01, +0.00000000000000e+00, +0.00000000000000e+00],
     [-4.62236725820948e+00, +1.28309672640153e+01, +0.00000000000000e+00],
     [-3.36772471669551e+00, -6.41548363200768e+00, +1.15542200082913e+01]],
    [[+1.18321595661992e+01, +0.00000000000000e+00, +0.00000000000000e+00],
     [-4.71877792223422e+00, +1.29511827614560e+01, +0.00000000000000e+00],
     [-3.55669082198251e+00, -6.47559138072800e+00, +1.16368667031408e+01]],
    [[+4.81947971142972e-03, +0.00000000000000e+00, +0.00000000000000e+00],
     [+4.12397039845618e-03, +4.86743859122682e+01, +0.00000000000000e+00],
     [+4.62732595971025e-03, +1.13797841621313e+01, +6.81149615940608e+01]],
    [[+1.43683914413843e-01, +0.00000000000000e+00, +0.00000000000000e+00],
     [+4.73841211849216e-02, +8.02075186538656e+00, +0.00000000000000e+00],
     [+9.29303317118020e-03, +8.28854375915883e-01, +1.93660401476964e+01]],
    [[+5.02420000000000e+00, +0.00000000000000e+00, +0.00000000000000e+00],
     [-2.40035596861745e+00, +1.25083680303996e+01, +0.00000000000000e+00],
     [-2.37319883118274e+00, -5.49894680458153e+00, +2.86098306766757e+01]],
    [[+5.02419976114664e+00, +0.00000000000000e+00, +0.00000000000000e+00],
     [-2.40036499209593e+00, +1.25083662987906e+01, +0.00000000000000e+00],
     [-2.37320481266200e+00, -5.49892622854049e+00, +2.86097847514890e+01]],
    ])

conf = Atoms(pbc=True)

for i, cell in enumerate(cells_in):
    conf.set_cell(cell)
    niggli_reduce(conf)
    cell = conf.get_cell()
    diff = np.linalg.norm(cell - cells_out[i])
    assert diff < 1e-5, \
            'Difference between unit cells is too large! ({0})'.format(diff)
Beispiel #37
0
from ase.optimize import QuasiNewton, FIRE
from ase.constraints import FixAtoms
from ase.neb import NEB
from ase.io import write, PickleTrajectory
from ase.calculators.emt import ASAP

# Distance between Cu atoms on a (100) surface:
d = 2.74
h1 = d * sqrt(3) / 2
h2 = d * sqrt(2.0 / 3)
initial = Atoms(symbols='Pt',
                positions=[(0, 0, 0)],#(1.37,0.79,2.24),(2.74,1.58,4.48),(0,0,6.72),(1.37,0.79,8.96),(2.74,1.58,11.2)],
                cell=([(d,0,0),(d/2,h1,0),(d/2,h1/3,-h2)]),
                pbc=(True, True, True))
initial *= (7, 8, 6)  # 5x5 (100) surface-cell
cell = initial.get_cell()
cell[2] = (0, 0, 22)
initial.set_cell(cell)
#initial.set_pbc((True,True,False))
# Approximate height of Ag atom on Cu(100) surfece:
h0 = 2.2373
initial += Atom('Pt', (10.96, 11.074, h0))
initial += Atom('Pt', (13.7, 11.074, h0))
initial += Atom('Pt', (9.59, 8.701, h0))
initial += Atom('Pt', (12.33, 8.701, h0))
initial += Atom('Pt', (15.07, 8.701, h0))
initial += Atom('Pt', (10.96, 6.328, h0))
initial += Atom('Pt', (13.7, 6.328, h0))

if 0:
    view(initial)
calc.set(kpts=(20, 20, 7), fixdensity=True)
atoms.get_potential_energy()

# The result should also be converged with respect to bands:
calc.diagonalize_full_hamiltonian(nbands=60)
calc.write('graphite.gpw', 'all')

# Part 2: Spectra calculations
f = paropen('graphite_q_list', 'w')  # write q

for i in range(1, 6):  # loop over different q
    df = DielectricFunction(calc='graphite.gpw',
                            domega0=0.01,
                            eta=0.2,  # Broadening parameter.
                            ecut=100,
                            # write different output for different q:
                            txt='out_df_%d.txt' % i)

    q_c = [i / 20.0, 0.0, 0.0]  # Gamma - M excitation
    
    df.get_eels_spectrum(q_c=q_c, filename='graphite_EELS_%d' % i)

    # Calculate cartesian momentum vector:
    cell_cv = atoms.get_cell()
    bcell_cv = 2 * np.pi * np.linalg.inv(cell_cv).T
    q_v = np.dot(q_c, bcell_cv)
    print(sqrt(np.inner(q_v, q_v)), file=f)

f.close()
Beispiel #39
0
def read_pmd(fname='pmd0000',specorder=[],fmvs=[(True,True,True),]):
    """
    Import pmd format file.

    fname
        Name of the file to be read.
    specorder
        Order of species appeared in pmd file.
    fmvs
        Constraints of motion in bool of x,y,z direction.
        e.g., fmv = ((True,True,True),(True,True,False),)
        True means fix and False means free.
    """
    
    f = open(fname,'r')
    # 1st line: lattice_constant
    lattice_constant = float(f.readline().split()[0])
    # 2-4 lines: lattice vectors
    a = []
    for ii in range(3):
        s = f.readline().split()
        floatvect = float(s[0]), float(s[1]), float(s[2])
        a.append(floatvect)
    basis_vectors = np.array(a) * lattice_constant
    # 5-7 lines: velocities of lattice vectors
    tmp = f.readline()
    tmp = f.readline()
    tmp = f.readline()
    natm = int(f.readline().split()[0])
    positions = np.zeros((natm,3),dtype=float)
    symbols = []
    ifmvs = np.zeros((natm),dtype=int)
    maxifmv = 0
    for ia in range(natm):
        data = f.readline().split()
        tag = float(data[0])
        for ii in range(3):
            positions[ia,ii] = float(data[ii+1])
        sid,symbol,ifmv,aid = decode_tag(tag,specorder)
        symbols.append(symbol)
        ifmvs[ia] = ifmv
        maxifmv = max(maxifmv,ifmv)
    f.close()
    if maxifmv > len(fmvs)+1:
        raise ValueError('Length of fmvs are too short.')

    atoms = Atoms(symbols=symbols,cell=basis_vectors,pbc=True)
    atoms.set_scaled_positions(positions)
    #set constraints
    constraints = []
    indices = []
    for ia in range(natm):
        if ifmvs[ia] == 0:
            indices.append(ia)
        else:
            ifmv = ifmvs[ia]
            fmv = fmvs[ifmv-1]
            if all(fmv):
                indices.append(ia)
            elif any(fmv):
                constraints.append(FixScaled(atoms.get_cell(),ia,fmv))
    if indices:
        constraints.append(FixAtoms(indices))
    if constraints:
        atoms.set_constraint(constraints)
    return atoms
Beispiel #40
0
def newclus(ind1, ind2, Optimizer):
    """Select a box in the cluster configuration"""

    if 'CX' in Optimizer.debug:
        debug = True
    else:
        debug = False
    Optimizer.output.write('Box Cluster Cx between individual {} and individual {}'.format(repr(ind1.index), repr(ind2.index)))

    # Perserve starting conditions of individual
    solid1 = ind1[0].copy()
    solid2 = ind2[0].copy()
    cello1 = ind1[0].get_cell()
    cello2 = ind2[0].get_cell()
    cell1 = numpy.maximum.reduce(solid1.get_positions())
    cell1m = numpy.minimum.reduce(solid1.get_positions())
    cell2 = numpy.maximum.reduce(solid2.get_positions())
    cell2m = numpy.minimum.reduce(solid2.get_positions())
    cell = numpy.minimum(cell1, cell2)
    pbc1 = solid1.get_pbc()
    pbc2 = solid2.get_pbc()

    # Get starting concentrations and number of atoms
    nat1 = len(solid1)
    nat2 = len(solid2)

    # Pick a origin point for box in the cell
    pt1 = random.choice(solid1)
    pt1f = [(pt1.position[i]-cell1m[i])/cell1[i] for i in range(3)]
    pt2 = [pt1f[i]*cell2[i]+cell2m[i] for i in range(3)]
    solid2.append(Atom(position=pt2))
    pt2 = solid2[len(solid2)-1]

    # Find max neighborsize of circle cut
    r = random.uniform(0, min(nat1, nat2)/5.0)
    if debug:
        print('DEBUG CX: Point one = {}'.format(pt1.position))
        print('DEBUG CX: Point two = {}'.format(pt2.position))

    # Find atoms within sphere of neighborsize r for both individuals
    # Make sure that crossover is only selection of atoms not all
    while True:
        ctoff = [r for on in solid1]
        nl = NeighborList(ctoff, bothways=True, self_interaction=False)
        nl.update(solid1)
        indices1, offsets = nl.get_neighbors(pt1.index)
        if len(indices1) == 0:
            r = r*1.2
        elif len(indices1) < nat1*.75:
            break
        else:
            r = r*0.8

    if debug:
        print('Neighborsize of box = {}'.format(repr(r)))
        print('Position in solid1 = {}'.format(repr(pt1.position)))
        print('Position in solid2 = {}'.format(repr(pt2.position)))

    group1 = Atoms(cell=solid1.get_cell(), pbc=solid1.get_pbc())
    group1.append(pt1)
    indices1a = [pt1.index]
    for index, d in zip(indices1, offsets):
        if index not in indices1a:
            index = int(index)
            pos = solid1[index].position + numpy.dot(d, solid1.get_cell())
            group1.append(Atom(symbol=solid1[index].symbol, position=pos))
            indices1a.append(index)
    indices1 = indices1a
    ctoff = [r for on in solid2]
    nl = NeighborList(ctoff, bothways=True, self_interaction=False)
    nl.update(solid2)
    indices2, offsets = nl.get_neighbors(pt2.index)
    group2 = Atoms(cell=solid2.get_cell(), pbc=solid2.get_pbc())
    indices2a = []
    for index, d in zip(indices2, offsets):
        if index not in indices2a:
            index = int(index)
            pos = solid2[index].position + numpy.dot(d, solid2.get_cell())
            group2.append(Atom(symbol=solid2[index].symbol, position=pos))
            indices2a.append(index)
    indices2 = indices2a
    if len(indices2) == 0:
        for one in group1:
            while True:
                sel = random.choice(solid2)
                if sel.symbol == one.symbol:
                    if sel.index not in indices2:
                        group2.append(sel)
                        indices2.append(sel.index)
                        break

    if Optimizer.forcing == 'Concentration':
        symlist = list(set(group1.get_chemical_symbols()))
        seplist = [[atm for atm in group2 if atm.symbol == sym] for sym in symlist]
        group2n = Atoms(cell=group2.get_cell(), pbc=group2.get_pbc())
        indices2n = []
        dellist = []
        for one in group1:
            sym1 = one.symbol
            listpos = [i for i, s in enumerate(symlist) if s == sym1][0]
            if len(seplist[listpos]) > 0:
                pos = random.choice(range(len(seplist[listpos])))
                group2n.append(seplist[listpos][pos])
                indices2n.append(indices2[seplist[listpos][pos].index])
                del seplist[listpos][pos]
            else:
                dellist.append(one.index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group1[one]
                del indices1[one]
        indices2n.append(pt2.index)
        indices2 = indices2n
        group2 = group2n.copy()
    else:
        dellist = []
        while len(group2) < len(group1)-len(dellist):
            # Too many atoms in group 1
            dellist.append(random.choice(group1).index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group1[one]
                del indices1[one]
        dellist = []
        while len(group1) < len(group2)-len(dellist):
            # Too many atoms in group 2
            dellist.append(random.choice(group2).index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group2[one]
                del indices2[one]

    other2 = Atoms(cell=solid2.get_cell(), pbc=solid2.get_pbc())
    for one in solid2:
        if one.index not in indices2:
            other2.append(one)
    other1 = Atoms(cell=solid1.get_cell(), pbc=solid1.get_pbc())
    for one in solid1:
        if one.index not in indices1:
            other1.append(one)

    # Exchange atoms in sphere and build new solids
    nsolid1 = other1.copy()
    nsolid1.extend(group2.copy())
    nsolid2 = other2.copy()
    nsolid2.extend(group1.copy())

    # DEBUG: Write crossover to file
    if debug:
        write_xyz(Optimizer.debugfile, nsolid1, 'CX(randalloybx):nsolid1')
        write_xyz(Optimizer.debugfile, nsolid2, 'CX(randalloybx):nsolid2')


    # DEBUG: Check structure of atoms exchanged
    for sym, c, m, u in Optimizer.atomlist:
        if Optimizer.structure == 'Defect':
            nc = len([atm for atm in nsolid1 if atm.symbol == sym])
            nc += len([atm for atm in ind1.bulki if atm.symbol == sym])
            oc = len([atm for atm in solid1 if atm.symbol == sym])
            oc += len([atm for atm in ind1.bulki if atm.symbol == sym])
        else:
            nc = len([atm for atm in nsolid1 if atm.symbol == sym])
            oc = len([atm for atm in solid1 if atm.symbol == sym])
        Optimizer.output.write('CX(clustbx):New solid1 contains '+repr(nc)+' '+repr(sym)+' atoms\n')
        if debug:
            print('DEBUG CX: New solid1 contains {} {} atoms'.format(repr(nc), repr(sym)))
        if oc != nc:
            # pdb.set_trace()
            print('CX: Issue in maintaining atom concentration\n Dropping new individual')
            Optimizer.output.write('CX: Issue in maintaining atom concentration\n Dropping new individual 1\n')
            nsolid1 = solid1
    for sym, c, m, u in Optimizer.atomlist:
        if Optimizer.structure == 'Defect':
            nc = len([atm for atm in nsolid2 if atm.symbol == sym])
            nc += len([atm for atm in ind2.bulki if atm.symbol == sym])
            oc = len([atm for atm in solid2 if atm.symbol == sym])
            oc += len([atm for atm in ind2.bulki if atm.symbol == sym])
        else:
            nc = len([atm for atm in nsolid2 if atm.symbol == sym])
            oc = len([atm for atm in solid2 if atm.symbol == sym])
        Optimizer.output.write('CX(clustbx):New solid2 contains '+repr(nc)+' '+repr(sym)+' atoms\n')
        if debug:
            print('DEBUG CX: New solid2 contains {} and {} atoms'.format(repr(nc), repr(sym)))
        if oc != nc:
            #pdb.set_trace()
            print('CX: Issue in maintaining atom concentration\n Dropping new individual')
            Optimizer.output.write('CX: Issue in maintaining atom concentration\n Dropping new individual 2\n')
            solid2.pop()
            nsolid2 = solid2
    if Optimizer.forcing != 'Concentration':
        for i in range(len(Optimizer.atomlist)):
            atms1 = [inds for inds in nsolid1 if inds.symbol == Optimizer.atomlist[i][0]]
            atms2 = [inds for inds in nsolid2 if inds.symbol == Optimizer.atomlist[i][0]]
            if len(atms1) == 0:
                if len(atms2) == 0:
                    nsolid1[random.randint(0, len(indi1)-1)].symbol == Optimizer.atomlist[i][0]
                    nsolid2[random.randint(0, len(indi2)-1)].symbol == Optimizer.atomlist[i][0]
                else:
                    nsolid1.append(atms2[random.randint(0, len(atms2)-1)])
                    nsolid1.pop(random.randint(0, len(nsolid1)-2))
            else:
                if len(atms2) == 0:
                    nsolid2.append(atms1[random.randint(0, len(atms1)-1)])
                    nsolid2.pop(random.randint(0, len(nsolid2)-2))

    nsolid1.set_cell(cello1)
    nsolid2.set_cell(cello2)
    nsolid1.set_pbc(pbc1)
    nsolid2.set_pbc(pbc2)

    ind1[0] = nsolid1.copy()
    ind2[0] = nsolid2.copy()

    return ind1, ind2
Beispiel #41
0
from ase.calculators.emt import EMT
from ase import Atoms

a = 3.60
b = a / 2
cu = Atoms('Cu',
           positions=[(0, 0, 0)],
           cell=[(0, b, b),
                 (b, 0, b),
                 (b, b, 0)],
           pbc=1,
           calculator=EMT())
e0 = cu.get_potential_energy()
print e0

cu.set_cell(cu.get_cell() * 1.001, scale_atoms=True)
e1 = cu.get_potential_energy()
V = a**3 / 4
B = 2 * (e1 - e0) / 0.003**2 / V * 160.2
print B

for i in range(4):
    x = 0.001 * i
    A = np.array([(x, b, b+x),
                  (b, 0, b),
                  (b, b, 0)])
    cu.set_cell(A, scale_atoms=True)
    e = cu.get_potential_energy() - e0
    if i == 0:
        print i, e
    else:
d_bond = 1.1
d_disp = 0.04

# Timestep and expected oscillatory period in attoseconds
timestep = 5.0
period = 1.414e4 # ~292.4 meV cf. CRC Handbook of Phys. & Chem. #09_08_91

ndiv = int(np.ceil(0.1e3 / timestep)) # update stats every 0.1 fs
niter = ndiv * int(np.ceil(2 * period / (ndiv * timestep)))

if __name__ == '__main__':
    if not os.path.isfile(name + '_gs.gpw'):
        atoms = Atoms('N2', positions=[(0, 0, 0), (0, 0, d_bond + d_disp)])
        atoms.set_pbc(False)
        atoms.center(vacuum=6.0)
        cell_c = np.sum(atoms.get_cell()**2, axis=1)**0.5
        N_c = 8 * np.round(cell_c / (0.2 * 8))
        calc = GPAW(gpts=N_c, nbands=5, basis='dzp', txt=name + '_gs.txt',
                    eigensolver='rmm-diis')
        atoms.set_calculator(calc)
        atoms.get_potential_energy()
        calc.write(name + '_gs.gpw', mode='all')
        del atoms, calc
        time.sleep(10)

    while not os.path.isfile(name + '_gs.gpw'):
        print('Node %d waiting for file...' % world.rank)
        time.sleep(10)
    world.barrier()

    tdcalc = TDDFT(name + '_gs.gpw', txt=name + '_td.txt', propagator='EFSICN')
Beispiel #43
0
import numpy as np

from ase import Atoms
from ase.io.trajectory import PickleTrajectory
from ase.calculators.emt import EMT

a = 4.0  # approximate lattice constant
b = a / 2
ag = Atoms('Ag', 
           cell=[(0,b,b), (b,0,b), (b,b,0)],
           pbc=1,
           calculator=EMT())  # use EMT potential
cell = ag.get_cell()
traj = PickleTrajectory('Ag.traj', 'w')
for x in np.linspace(0.95, 1.05, 5):
    ag.set_cell(cell * x, scale_atoms=True)
    traj.write(ag)
Beispiel #44
0
def read_vasp(filename='CONTCAR'):
    """Import POSCAR/CONTCAR type file.

    Reads unitcell, atom positions and constraints from the POSCAR/CONTCAR
    file and tries to read atom types from POSCAR/CONTCAR header, if this fails
    the atom types are read from OUTCAR or POTCAR file.
    """
 
    from ase import Atoms, Atom
    from ase.constraints import FixAtoms, FixScaled
    from ase.data import chemical_symbols
    import numpy as np

    if isinstance(filename, str):
        f = open(filename)
    else:  # Assume it's a file-like object
        f = filename

    # The first line is in principle a comment line, however in VASP
    # 4.x a common convention is to have it contain the atom symbols,
    # eg. "Ag Ge" in the same order as later in the file (and POTCAR
    # for the full vasp run). In the VASP 5.x format this information
    # is found on the fifth line. Thus we save the first line and use
    # it in case we later detect that we're reading a VASP 4.x format
    # file.
    line1 = f.readline()

    lattice_constant = float(f.readline().split()[0])

    # Now the lattice vectors
    a = []
    for ii in range(3):
        s = f.readline().split()
        floatvect = float(s[0]), float(s[1]), float(s[2])
        a.append(floatvect)

    basis_vectors = np.array(a) * lattice_constant

    # Number of atoms. Again this must be in the same order as
    # in the first line
    # or in the POTCAR or OUTCAR file
    atom_symbols = []
    numofatoms = f.readline().split()
    # Check whether we have a VASP 4.x or 5.x format file. If the
    # format is 5.x, use the fifth line to provide information about
    # the atomic symbols.
    vasp5 = False
    try:
        int(numofatoms[0])
    except ValueError:
        vasp5 = True
        atomtypes = numofatoms
        numofatoms = f.readline().split()

    # check for comments in numofatoms line and get rid of them if necessary
    commentcheck = np.array(['!' in s for s in numofatoms])
    if commentcheck.any():
        # only keep the elements up to the first including a '!':
        numofatoms = numofatoms[:np.arange(len(numofatoms))[commentcheck][0]]

    if not vasp5:
        atomtypes = line1.split()
       
        numsyms = len(numofatoms)
        if len(atomtypes) < numsyms:
            # First line in POSCAR/CONTCAR didn't contain enough symbols.

            # Sometimes the first line in POSCAR/CONTCAR is of the form
            # "CoP3_In-3.pos". Check for this case and extract atom types
            if len(atomtypes) == 1 and '_' in atomtypes[0]:
                atomtypes = get_atomtypes_from_formula(atomtypes[0])
            else:
                atomtypes = atomtypes_outpot(f.name, numsyms)
        else:
            try:
                for atype in atomtypes[:numsyms]:
                    if atype not in chemical_symbols:
                        raise KeyError
            except KeyError:
                atomtypes = atomtypes_outpot(f.name, numsyms)

    for i, num in enumerate(numofatoms):
        numofatoms[i] = int(num)
        [atom_symbols.append(atomtypes[i]) for na in range(numofatoms[i])]

    # Check if Selective dynamics is switched on
    sdyn = f.readline()
    selective_dynamics = sdyn[0].lower() == 's'

    # Check if atom coordinates are cartesian or direct
    if selective_dynamics:
        ac_type = f.readline()
    else:
        ac_type = sdyn
    cartesian = ac_type[0].lower() == 'c' or ac_type[0].lower() == 'k'
    tot_natoms = sum(numofatoms)
    atoms_pos = np.empty((tot_natoms, 3))
    if selective_dynamics:
        selective_flags = np.empty((tot_natoms, 3), dtype=bool)
    for atom in range(tot_natoms):
        ac = f.readline().split()
        atoms_pos[atom] = (float(ac[0]), float(ac[1]), float(ac[2]))
        if selective_dynamics:
            curflag = []
            for flag in ac[3:6]:
                curflag.append(flag == 'F')
            selective_flags[atom] = curflag
    # Done with all reading
    if isinstance(filename, str):
        f.close()
    if cartesian:
        atoms_pos *= lattice_constant
    atoms = Atoms(symbols=atom_symbols, cell=basis_vectors, pbc=True)
    if cartesian:
        atoms.set_positions(atoms_pos)
    else:
        atoms.set_scaled_positions(atoms_pos)
    if selective_dynamics:
        constraints = []
        indices = []
        for ind, sflags in enumerate(selective_flags):
            if sflags.any() and not sflags.all():
                constraints.append(FixScaled(atoms.get_cell(), ind, sflags))
            elif sflags.all():
                indices.append(ind)
        if indices:
            constraints.append(FixAtoms(indices))
        if constraints:
            atoms.set_constraint(constraints)
    return atoms
Beispiel #45
0
def gen_pop_box(atomlist,size,crystal=False):
    """Function to generate a random structure of atoms.
    Inputs:
        atomlist = List of tuples with structure of atoms and quantity
            [('Sym1',int(concentration1), float(mass1),float(chempotential1)),
            ('Sym2',int(concentration2), float(mass2),float(chempotential2)),...]
        size = Float of length of side of cube within which to generate atoms
        crystal = False/List of crystal cell shape options
            list('cubic','orthorhombic','tetragonal','hexagonal','monoclinic','triclinic')
            cell shape will be adjusted accordingly
    Outputs:
        Returns individual of class Atoms (see ase manual for info on Atoms class)
        and if crystal list provided also outputs combined string with output information
    """
    indiv=Atoms()
    indiv.set_cell([size,size,size])
    # Get list of atom types for all atoms in cluster
    for s,c,m,u in atomlist:
        if c > 0:
            for i in range(c):
                pos = [random.uniform(0,size) for j in range(3)]
                at=Atom(symbol=s,position=pos)
                indiv.append(at)
    if crystal:
        stro=''
        natoms=sum([c for s,c,m,u in atomlist])
        pos=indiv.get_scaled_positions()
        structure=random.choice(crystal)
        cello=indiv.get_cell()
        if structure=='cubic':
            #Set to cubic shape
            an,bn,cn = [numpy.linalg.norm(v) for v in cello]
            a=(an+bn+cn)/3.0
            celln=numpy.array([[a,0,0],[0,a,0],[0,0,a]])
            stro+='Setting cell to cubic\n'
        elif structure=='orthorhombic':
            #Set to orthorhombic
            a=random.uniform(2,natoms**0.3333*size)
            b=random.uniform(2,natoms**0.3333*size)
            c=random.uniform(2,natoms**0.3333*size)
            celln=numpy.array([[a,0,0],[0,b,0],[0,0,c]])
            stro+='Setting cell to orthorhombic\n'
        elif structure=='tetragonal':
            #Set to tetragonal shape
            an,bn,cn = [numpy.linalg.norm(v) for v in cello]
            a=(an+bn)/2.0
            c=cn
            if c==a:
                c=random.uniform(1,natoms**0.3333*size)
            celln=numpy.array([[a,0,0],[0,a,0],[0,0,c]])
            stro+='Setting cell to tetragonal\n'
        elif structure=='hexagonal':
            #Set to hexagonal shape
            an,bn,cn = [numpy.linalg.norm(v) for v in cello]
            a=(an+bn)/2.0
            c=cn
            if c<=a:
                c=random.uniform(a+1,natoms**0.3333*size)
            trans=numpy.array([[1,0,0],[-0.5,(3.0**0.5)/2.0,0],[0,0,1]])
            trans[0]=[a*i for i in trans[0]]
            trans[1]=[a*i for i in trans[1]]
            trans[2]=[c*i for i in trans[2]]
            celln=trans
            stro+='Setting cell to Hexagonal\n'
        elif structure=='monoclinic':
            #Set to monoclinic
            a,b,c = [numpy.linalg.norm(v) for v in cello]
            if a==b:
                b=random.uniform(1,natoms**0.3333*size)
            trans=numpy.array([(1+random.random())*c, 0, (1+random.random())*c])
            celln=numpy.array([[a,0,0],[0,b,0],[0,0,0]])
            celln[2]=trans
            stro+='Setting cell to monoclinic\n'
        elif structure=='triclinic':
            #Set to triclinic
            a,b,c = [numpy.linalg.norm(v) for v in cello]
            celln=numpy.array([[a,0,0],[(1+random.random())*b,(1+random.random())*b,0],[(1+random.random())*c,0,(1+random.random())*c]])
            stro+='Setting cell to triclinic\n'
        indiv.set_cell(celln)
        indiv.set_scaled_positions(pos)
        stro+=repr(indiv.get_cell())+'\n'
        return indiv, stro
    return indiv
Beispiel #46
0
def newclus(ind1, ind2, Optimizer):
    """Select a box in the cluster configuration"""
    if 'CX' in Optimizer.debug:
        debug = True
    else:
        debug = False
    Optimizer.output.write('Box Cluster Cx between individual ' +
                           repr(ind1.index) + ' and individual ' +
                           repr(ind2.index) + '\n')

    #Perserve starting conditions of individual
    solid1 = ind1[0].copy()
    solid2 = ind2[0].copy()
    cello1 = ind1[0].get_cell()
    cello2 = ind2[0].get_cell()
    cell1 = numpy.maximum.reduce(solid1.get_positions())
    cell1m = numpy.minimum.reduce(solid1.get_positions())
    cell2 = numpy.maximum.reduce(solid2.get_positions())
    cell2m = numpy.minimum.reduce(solid2.get_positions())
    cell = numpy.minimum(cell1, cell2)
    pbc1 = solid1.get_pbc()
    pbc2 = solid2.get_pbc()
    #Get starting concentrations and number of atoms
    nat1 = len(solid1)
    nat2 = len(solid2)

    # Pick a origin point for box in the cell
    pt1 = random.choice(solid1)
    pt1f = [(pt1.position[i] - cell1m[i]) / cell1[i] for i in range(3)]
    pt2 = [pt1f[i] * cell2[i] + cell2m[i] for i in range(3)]
    solid2.append(Atom(position=pt2))
    pt2 = solid2[len(solid2) - 1]
    #Find max neighborsize of circle cut
    r = random.uniform(0, min(nat1, nat2) / 5.0)
    if debug:
        print 'DEBUG CX: Point one =', pt1.position
        print 'DEBUG CX: Point two =', pt2.position
    #Find atoms within sphere of neighborsize r for both individuals
    #Make sure that crossover is only selection of atoms not all
    while True:
        ctoff = [r for on in solid1]
        nl = NeighborList(ctoff, bothways=True, self_interaction=False)
        nl.update(solid1)
        indices1, offsets = nl.get_neighbors(pt1.index)
        if len(indices1) == 0:
            r = r * 1.2
        elif len(indices1) < nat1 * .75:
            break
        else:
            r = r * 0.8
    if debug:
        print 'Neighborsize of box = ' + repr(
            r) + '\nPosition in solid1 = ' + repr(
                pt1.position) + '\nPosition in solid2 = ' + repr(pt2.position)
    group1 = Atoms(cell=solid1.get_cell(), pbc=solid1.get_pbc())
    group1.append(pt1)
    indices1a = [pt1.index]
    for index, d in zip(indices1, offsets):
        if index not in indices1a:
            index = int(index)
            pos = solid1[index].position + numpy.dot(d, solid1.get_cell())
            group1.append(Atom(symbol=solid1[index].symbol, position=pos))
            indices1a.append(index)
    indices1 = indices1a
    ctoff = [r for on in solid2]
    nl = NeighborList(ctoff, bothways=True, self_interaction=False)
    nl.update(solid2)
    indices2, offsets = nl.get_neighbors(pt2.index)
    group2 = Atoms(cell=solid2.get_cell(), pbc=solid2.get_pbc())
    indices2a = []
    for index, d in zip(indices2, offsets):
        if index not in indices2a:
            index = int(index)
            pos = solid2[index].position + numpy.dot(d, solid2.get_cell())
            group2.append(Atom(symbol=solid2[index].symbol, position=pos))
            indices2a.append(index)
    indices2 = indices2a
    if len(indices2) == 0:
        for one in group1:
            while True:
                sel = random.choice(solid2)
                if sel.symbol == one.symbol:
                    if sel.index not in indices2:
                        group2.append(sel)
                        indices2.append(sel.index)
                        break

    if Optimizer.forcing == 'Concentration':
        symlist = list(set(group1.get_chemical_symbols()))
        seplist = [[atm for atm in group2 if atm.symbol == sym]
                   for sym in symlist]
        group2n = Atoms(cell=group2.get_cell(), pbc=group2.get_pbc())
        indices2n = []
        dellist = []
        for one in group1:
            sym1 = one.symbol
            listpos = [i for i, s in enumerate(symlist) if s == sym1][0]
            if len(seplist[listpos]) > 0:
                pos = random.choice(range(len(seplist[listpos])))
                group2n.append(seplist[listpos][pos])
                indices2n.append(indices2[seplist[listpos][pos].index])
                del seplist[listpos][pos]
            else:
                dellist.append(one.index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group1[one]
                del indices1[one]
        indices2n.append(pt2.index)
        indices2 = indices2n
        group2 = group2n.copy()
    else:
        dellist = []
        while len(group2) < len(group1) - len(dellist):
            #Too many atoms in group 1
            dellist.append(random.choice(group1).index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group1[one]
                del indices1[one]
        dellist = []
        while len(group1) < len(group2) - len(dellist):
            #Too many atoms in group 2
            dellist.append(random.choice(group2).index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group2[one]
                del indices2[one]

    other2 = Atoms(cell=solid2.get_cell(), pbc=solid2.get_pbc())
    for one in solid2:
        if one.index not in indices2:
            other2.append(one)
    other1 = Atoms(cell=solid1.get_cell(), pbc=solid1.get_pbc())
    for one in solid1:
        if one.index not in indices1:
            other1.append(one)

    #Exchange atoms in sphere and build new solids
    nsolid1 = other1.copy()
    nsolid1.extend(group2.copy())
    nsolid2 = other2.copy()
    nsolid2.extend(group1.copy())

    #DEBUG: Write crossover to file
    if debug:
        write_xyz(Optimizer.debugfile, nsolid1, 'CX(randalloybx):nsolid1')
        write_xyz(Optimizer.debugfile, nsolid2, 'CX(randalloybx):nsolid2')

    #DEBUG: Check structure of atoms exchanged
    for sym, c, m, u in Optimizer.atomlist:
        if Optimizer.structure == 'Defect':
            nc = len([atm for atm in nsolid1 if atm.symbol == sym])
            nc += len([atm for atm in ind1.bulki if atm.symbol == sym])
            oc = len([atm for atm in solid1 if atm.symbol == sym])
            oc += len([atm for atm in ind1.bulki if atm.symbol == sym])
        else:
            nc = len([atm for atm in nsolid1 if atm.symbol == sym])
            oc = len([atm for atm in solid1 if atm.symbol == sym])
        Optimizer.output.write('CX(clustbx):New solid1 contains ' + repr(nc) +
                               ' ' + repr(sym) + ' atoms\n')
        if debug:
            print 'DEBUG CX: New solid1 contains ' + repr(nc) + ' ' + repr(
                sym) + ' atoms'
        if oc != nc:
            #pdb.set_trace()
            print 'CX: Issue in maintaining atom concentration\n Dropping new individual'
            Optimizer.output.write(
                'CX: Issue in maintaining atom concentration\n Dropping new individual 1\n'
            )
            nsolid1 = solid1
    for sym, c, m, u in Optimizer.atomlist:
        if Optimizer.structure == 'Defect':
            nc = len([atm for atm in nsolid2 if atm.symbol == sym])
            nc += len([atm for atm in ind2.bulki if atm.symbol == sym])
            oc = len([atm for atm in solid2 if atm.symbol == sym])
            oc += len([atm for atm in ind2.bulki if atm.symbol == sym])
        else:
            nc = len([atm for atm in nsolid2 if atm.symbol == sym])
            oc = len([atm for atm in solid2 if atm.symbol == sym])
        Optimizer.output.write('CX(clustbx):New solid2 contains ' + repr(nc) +
                               ' ' + repr(sym) + ' atoms\n')
        if debug:
            print 'DEBUG CX: New solid2 contains ' + repr(nc) + ' ' + repr(
                sym) + ' atoms'
        if oc != nc:
            #pdb.set_trace()
            print 'CX: Issue in maintaining atom concentration\n Dropping new individual'
            Optimizer.output.write(
                'CX: Issue in maintaining atom concentration\n Dropping new individual 2\n'
            )
            solid2.pop()
            nsolid2 = solid2
    if Optimizer.forcing != 'Concentration':
        for i in range(len(Optimizer.atomlist)):
            atms1 = [
                inds for inds in nsolid1
                if inds.symbol == Optimizer.atomlist[i][0]
            ]
            atms2 = [
                inds for inds in nsolid2
                if inds.symbol == Optimizer.atomlist[i][0]
            ]
            if len(atms1) == 0:
                if len(atms2) == 0:
                    nsolid1[random.randint(
                        0,
                        len(indi1) - 1)].symbol == Optimizer.atomlist[i][0]
                    nsolid2[random.randint(
                        0,
                        len(indi2) - 1)].symbol == Optimizer.atomlist[i][0]
                else:
                    nsolid1.append(atms2[random.randint(0, len(atms2) - 1)])
                    nsolid1.pop(random.randint(0, len(nsolid1) - 2))
            else:
                if len(atms2) == 0:
                    nsolid2.append(atms1[random.randint(0, len(atms1) - 1)])
                    nsolid2.pop(random.randint(0, len(nsolid2) - 2))

    nsolid1.set_cell(cello1)
    nsolid2.set_cell(cello2)
    nsolid1.set_pbc(pbc1)
    nsolid2.set_pbc(pbc2)

    ind1[0] = nsolid1.copy()
    ind2[0] = nsolid2.copy()

    return ind1, ind2
Beispiel #47
0
#PBS -q medium -l nodes=1:ppn=8:xeon5570 -m abe -V
# Takes 30 mins with 8 cores in domain-parallel (memory ~500mb, max 1.5gb)

import numpy as np
from ase import Atom, Atoms
from gpaw import GPAW, MixerDif, mpi
from gpaw.lrtddft import LrTDDFT
from gpaw.pes.dos import DOSPES
from gpaw.pes.tddft import TDDFTPES

atoms = Atoms([Atom('C', (7.666263598984184, 7.637780850431168, 8.289450797111844)),
               Atom('O', (8.333644370007132, 8.362384430165646, 7.710230973847514))])
atoms.center(vacuum=8)

h = 0.15
N_c = np.round(atoms.get_cell().diagonal() / h / 16) * 16

m_c = GPAW(gpts=N_c, nbands=6, mixer=MixerDif(0.1, 5, weight=100.0),
           #convergence={'bands':10},
           parallel={'domain': mpi.size},
           xc='PBE', txt='CO-m.txt', spinpol=True)

m = atoms.copy()
m.set_initial_magnetic_moments([-1,1])
m.set_calculator(m_c)
m.get_potential_energy()

d_c = GPAW(gpts=N_c, nbands=16, mixer=MixerDif(0.1, 5, weight=100.0),
           convergence={'bands':10},
           parallel={'domain': mpi.size},
           xc='PBE', txt='CO-d.txt', spinpol=True)
Beispiel #48
0
calc = GPAW(h=0.15, width=0.1, xc='LDA', nbands=-4, txt='-',
            basis='dzp', convergence={'energy': 1e-5, 'density': 1e-5})

# Calculate potential energy per atom for orthogonal unitcell
atoms = hcp0001('C', a=a/sqrt(3), vacuum=d, size=(3,2,1), orthogonal=True)
del atoms[[1,-1]]
atoms.center(axis=0)
atoms.set_calculator(calc)

kpts_c = np.ceil(50 / np.sum(atoms.get_cell()**2, axis=1)**0.5).astype(int)
kpts_c[~atoms.get_pbc()] = 1
calc.set(kpts=kpts_c)
eppa1 = atoms.get_potential_energy() / len(atoms)
F1_av = atoms.get_forces()
equal(np.abs(F1_av).max(), 0, 5e-3)

# Redo calculation with non-orthogonal unitcell
atoms = Atoms(symbols='C2', pbc=(True,True,False),
              positions=[(a/2,-sqrt(3)/6*a,d), (a/2,sqrt(3)/6*a,d)],
              cell=[(a/2,-sqrt(3)/2*a,0), (a/2,sqrt(3)/2*a,0), (0,0,2*d)])
atoms.set_calculator(calc)

kpts_c = np.ceil(50 / np.sum(atoms.get_cell()**2, axis=1)**0.5).astype(int)
kpts_c[~atoms.get_pbc()] = 1
calc.set(kpts=kpts_c)
eppa2 = atoms.get_potential_energy() / len(atoms)
F2_av = atoms.get_forces()
equal(np.abs(F2_av).max(), 0, 5e-3)

equal(eppa1, eppa2, 1e-3)
Beispiel #49
0
u = 0.3  # internal degree of freedom!
#primitive vectors
a1 = a * np.array([1.0, 0.0, 0.0])
a2 = a * np.array([0.0, 1.0, 0.0])
a3 = c * np.array([0.0, 0.0, 1.0])
atoms = Atoms([
    Atom('Ti', [0., 0., 0.]),
    Atom('Ti', 0.5 * a1 + 0.5 * a2 + 0.5 * a3),
    Atom('O', u * a1 + u * a2),
    Atom('O', -u * a1 - u * a2),
    Atom('O', (0.5 + u) * a1 + (0.5 - u) * a2 + 0.5 * a3),
    Atom('O', (0.5 - u) * a1 + (0.5 + u) * a2 + 0.5 * a3)
],
              cell=[a1, a2, a3])
v0 = atoms.get_volume()
cell0 = atoms.get_cell()
factors = [0.9, 0.95, 1.0, 1.05, 1.1]  #to change volume by
energies, volumes = [], []
ready = True
for f in factors:
    v1 = f * v0
    cell_factor = (v1 / v0)**(1. / 3.)
    atoms.set_cell(cell0 * cell_factor, scale_atoms=True)
    calc = Vasp(
        'bulk/tio2/step1-{0:1.2f}'.format(f),
        encut=520,
        kpts=[5, 5, 5],
        isif=2,  # relax internal degrees of freedom
        ibrion=1,
        nsw=50,
        xc='PBE',
Beispiel #50
0
from ase import Atom, Atoms
# http://cst-www.nrl.navy.mil/lattice/struk/c5.html
B = 'Ti'; X = 'O'; a = 3.7842; c = 2*4.7573; z = 0.0831;
a1 = a * np.array([1.0, 0.0, 0.0])
a2 = a * np.array([0.0, 1.0, 0.0])
a3 = np.array([0.5 * a, 0.5 * a, 0.5 * c])
atoms = Atoms([Atom(B, -0.125 * a1 + 0.625 * a2 + 0.25 * a3),
               Atom(B,  0.125 * a1 + 0.375 * a2 + 0.75 * a3),
               Atom(X, -z*a1 + (0.25-z)*a2 + 2.*z*a3),
               Atom(X, -(0.25+z)*a1 + (0.5-z)*a2 + (0.5+2*z)*a3),
               Atom(X, z*a1 - (0.25 - z)*a2 + (1-2*z)*a3),
               Atom(X, (0.25 + z)*a1 + (0.5 + z)*a2 + (0.5-2*z)*a3)],
               cell=[a1,a2,a3])
nTiO2 = len(atoms) / 3.
v0 = atoms.get_volume()
cell0 = atoms.get_cell()
volumes = [30., 33., 35., 37., 39.]  #vol of one TiO2
for v in volumes:
    atoms.set_cell(cell0 * ((nTiO2*v/v0)**(1./3.)),
                   scale_atoms=True)
    with jasp('bulk/TiO2/anatase/anatase-{0}'.format(v),
              encut=350,
              kpts=(6, 6, 6),
              xc='PBE',
              ismear=0,
              sigma=0.001,
              isif=2,
              ibrion=2,
              nsw=20,
              atoms=atoms) as calc:
        try:
Beispiel #51
0
def read_vasp(filename='CONTCAR'):
    """Import POSCAR/CONTCAR type file.

    Reads unitcell, atom positions and constraints from the POSCAR/CONTCAR
    file and tries to read atom types from POSCAR/CONTCAR header, if this fails
    the atom types are read from OUTCAR or POTCAR file.
    """

    from ase import Atoms
    from ase.constraints import FixAtoms, FixScaled
    from ase.data import chemical_symbols
    import numpy as np

    if isinstance(filename, basestring):
        f = open(filename)
    else:  # Assume it's a file-like object
        f = filename

    # The first line is in principle a comment line, however in VASP
    # 4.x a common convention is to have it contain the atom symbols,
    # eg. "Ag Ge" in the same order as later in the file (and POTCAR
    # for the full vasp run). In the VASP 5.x format this information
    # is found on the fifth line. Thus we save the first line and use
    # it in case we later detect that we're reading a VASP 4.x format
    # file.
    line1 = f.readline()

    lattice_constant = float(f.readline().split()[0])

    # Now the lattice vectors
    a = []
    for ii in range(3):
        s = f.readline().split()
        floatvect = float(s[0]), float(s[1]), float(s[2])
        a.append(floatvect)

    basis_vectors = np.array(a) * lattice_constant

    # Number of atoms. Again this must be in the same order as
    # in the first line
    # or in the POTCAR or OUTCAR file
    atom_symbols = []
    numofatoms = f.readline().split()
    # Check whether we have a VASP 4.x or 5.x format file. If the
    # format is 5.x, use the fifth line to provide information about
    # the atomic symbols.
    vasp5 = False
    try:
        int(numofatoms[0])
    except ValueError:
        vasp5 = True
        atomtypes = numofatoms
        numofatoms = f.readline().split()

    # check for comments in numofatoms line and get rid of them if necessary
    commentcheck = np.array(['!' in s for s in numofatoms])
    if commentcheck.any():
        # only keep the elements up to the first including a '!':
        numofatoms = numofatoms[:np.arange(len(numofatoms))[commentcheck][0]]

    if not vasp5:
        atomtypes = line1.split()

        numsyms = len(numofatoms)
        if len(atomtypes) < numsyms:
            # First line in POSCAR/CONTCAR didn't contain enough symbols.

            # Sometimes the first line in POSCAR/CONTCAR is of the form
            # "CoP3_In-3.pos". Check for this case and extract atom types
            if len(atomtypes) == 1 and '_' in atomtypes[0]:
                atomtypes = get_atomtypes_from_formula(atomtypes[0])
            else:
                atomtypes = atomtypes_outpot(f.name, numsyms)
        else:
            try:
                for atype in atomtypes[:numsyms]:
                    if atype not in chemical_symbols:
                        raise KeyError
            except KeyError:
                atomtypes = atomtypes_outpot(f.name, numsyms)

    for i, num in enumerate(numofatoms):
        numofatoms[i] = int(num)
        [atom_symbols.append(atomtypes[i]) for na in range(numofatoms[i])]

    # Check if Selective dynamics is switched on
    sdyn = f.readline()
    selective_dynamics = sdyn[0].lower() == 's'

    # Check if atom coordinates are cartesian or direct
    if selective_dynamics:
        ac_type = f.readline()
    else:
        ac_type = sdyn
    cartesian = ac_type[0].lower() == 'c' or ac_type[0].lower() == 'k'
    tot_natoms = sum(numofatoms)
    atoms_pos = np.empty((tot_natoms, 3))
    if selective_dynamics:
        selective_flags = np.empty((tot_natoms, 3), dtype=bool)
    for atom in range(tot_natoms):
        ac = f.readline().split()
        atoms_pos[atom] = (float(ac[0]), float(ac[1]), float(ac[2]))
        if selective_dynamics:
            curflag = []
            for flag in ac[3:6]:
                curflag.append(flag == 'F')
            selective_flags[atom] = curflag
    # Done with all reading
    if isinstance(filename, basestring):
        f.close()
    if cartesian:
        atoms_pos *= lattice_constant
    atoms = Atoms(symbols=atom_symbols, cell=basis_vectors, pbc=True)
    if cartesian:
        atoms.set_positions(atoms_pos)
    else:
        atoms.set_scaled_positions(atoms_pos)
    if selective_dynamics:
        constraints = []
        indices = []
        for ind, sflags in enumerate(selective_flags):
            if sflags.any() and not sflags.all():
                constraints.append(FixScaled(atoms.get_cell(), ind, sflags))
            elif sflags.all():
                indices.append(ind)
        if indices:
            constraints.append(FixAtoms(indices))
        if constraints:
            atoms.set_constraint(constraints)
    return atoms
Beispiel #52
0
          atoms=atoms) as calc:
    atoms = calc.get_atoms()
    x, y, z, cd = calc.get_charge_density()
mlab.figure(bgcolor=(1, 1, 1))
# plot the atoms as spheres
for atom in atoms:
    mlab.points3d(atom.x,
                  atom.y,
                  atom.z,
                  scale_factor=vdw_radii[atom.number]/5.,
                  resolution=20,
                  # a tuple is required for the color
                  color=tuple(cpk_colors[atom.number]),
                  scale_mode='none')
# draw the unit cell - there are 8 corners, and 12 connections
a1, a2, a3 = atoms.get_cell()
origin = [0, 0, 0]
cell_matrix = [[origin,  a1],
               [origin,  a2],
               [origin,  a3],
               [a1,      a1 + a2],
               [a1,      a1 + a3],
               [a2,      a2 + a1],
               [a2,      a2 + a3],
               [a3,      a1 + a3],
               [a3,      a2 + a3],
               [a1 + a2, a1 + a2 + a3],
               [a2 + a3, a1 + a2 + a3],
               [a1 + a3, a1 + a3 + a2]]
for p1, p2 in cell_matrix:
    mlab.plot3d([p1[0], p2[0]], # x-positions
Beispiel #53
0
Datei: oi.py Projekt: lqcata/ase
    pass
else:
    w += ['png', 'eps']

for format in w:
    print format, 'O',
    fname1 = 'io-test.1.' + format
    fname2 = 'io-test.2.' + format
    write(fname1, atoms, format=format)
    if format not in ['cube', 'png', 'eps', 'cfg', 'struct', 'etsf', 'gen']:
        write(fname2, images, format=format)

    if format in r:
        print 'I'
        a1 = read(fname1)
        assert np.all(np.abs(a1.get_positions() -
                             atoms.get_positions()) < 1e-6)
        if format in ['traj', 'cube', 'cfg', 'struct', 'gen']:
            assert np.all(np.abs(a1.get_cell() - atoms.get_cell()) < 1e-6)
        if format in ['cfg']:
            assert np.all(np.abs(a1.get_array('extra') -
                                 atoms.get_array('extra')) < 1e-6)
        if format not in ['cube', 'png', 'eps', 'cfg', 'struct', 'etsf',
                          'gen']:
            a2 = read(fname2)
            a3 = read(fname2, index=0)
            a4 = read(fname2, index=slice(None))
            assert len(a4) == 2
    else:
        print
Beispiel #54
0
def gen_pop_plate(atomlist, sizeinput, dir_par=[1,-1,0], dir_per=[1,1,1], crystal=False):
    '''
     Last edited by Hyunseok Ko on 10-15-2014
     Function to generate defects in a plate. The center of plate is equal to the center of mass of the bulk structure. 
     -- Plate orientation can be specified by following parameters::
     		dir_par and dir_per is a directional vector (do not necessarily be a unit vector) which sets the axis of the plate
     -- Plate dimension can be chosen (Needs development. Manual setup for now) by setting 'size' in this module. 
    '''
# Setup axis vectors for plate 
    size=[sizeinput, sizeinput, 3]
    #print 'HKK :: plate vector', size
    # Set unit vectors for plate
    dir_crs=numpy.cross(dir_par, dir_per)
    uvec_par=[x/((dir_par[0]**2+dir_par[1]**2+dir_par[2]**2)**0.5) for x in dir_par]
    uvec_crs=[x/((dir_crs[0]**2+dir_crs[1]**2+dir_crs[2]**2)**0.5) for x in dir_crs]
    uvec_per=[x/((dir_per[0]**2+dir_per[1]**2+dir_per[2]**2)**0.5) for x in dir_per]
    #print 'Unit vectors of new xyz axis'
    #print uvec_par, uvec_crs, uvec_per
    
    # Set vectors for plate
    vec_par=[x*size[0] for x in uvec_par]
    vec_crs=[x*size[1] for x in uvec_crs]
    vec_per=[x*size[2] for x in uvec_per]
    # Compute rotation angles from primary axis to axis for plate (If loop to avoid floating error)
    temp=[-uvec_per[1]/((1-uvec_per[2]**2)**0.5), uvec_per[2],uvec_crs[2]/((1-uvec_per[2]**2)**0.5)]
    if [temp[x] for x in range(3)]  >=1:
        temp[x]=1
    alpha=numpy.arccos(temp[0])
    beta=numpy.arccos(temp[1])
    gamma=numpy.arccos(temp[2])
    
# Get list of atom types for all atoms in cluster	
    indiv=Atoms()
    indiv.set_cell(size)

    for s,c,m,u in atomlist:
        if c > 0:
            for i in range(c):
                temppos = [random.uniform(0,size[j]) for j in range(3)]
                # Rotating the defect position to the plate 
                pos = rot_vec(temppos,alpha,beta,gamma)
                at=Atom(symbol=s,position=pos)
                indiv.append(at)
    if crystal:
        stro=''
        natoms=sum([c for s,c,m,u in atomlist])
        pos=indiv.get_scaled_positions()
        structure=random.choice(crystal)
        cello=indiv.get_cell()
        if structure=='cubic':
            #Set to cubic shape
            an,bn,cn = [numpy.linalg.norm(v) for v in cello]
            a=(an+bn+cn)/3.0
            celln=numpy.array([[a,0,0],[0,a,0],[0,0,a]])
            stro+='Setting cell to cubic\n'
        elif structure=='orthorhombic':
            #Set to orthorhombic
            a=random.uniform(2,natoms**0.3333*size)
            b=random.uniform(2,natoms**0.3333*size)
            c=random.uniform(2,natoms**0.3333*size)
            celln=numpy.array([[a,0,0],[0,b,0],[0,0,c]])
            stro+='Setting cell to orthorhombic\n'
        elif structure=='tetragonal':
            #Set to tetragonal shape
            an,bn,cn = [numpy.linalg.norm(v) for v in cello]
            a=(an+bn)/2.0
            c=cn
            if c==a:
                c=random.uniform(1,natoms**0.3333*size)
            celln=numpy.array([[a,0,0],[0,a,0],[0,0,c]])
            stro+='Setting cell to tetragonal\n'
        elif structure=='hexagonal':
            #Set to hexagonal shape
            an,bn,cn = [numpy.linalg.norm(v) for v in cello]
            a=(an+bn)/2.0
            c=cn
            if c<=a:
                c=random.uniform(a+1,natoms**0.3333*size)
            trans=numpy.array([[1,0,0],[-0.5,(3.0**0.5)/2.0,0],[0,0,1]])
            trans[0]=[a*i for i in trans[0]]
            trans[1]=[a*i for i in trans[1]]
            trans[2]=[c*i for i in trans[2]]
            celln=trans
            stro+='Setting cell to Hexagonal\n'
        elif structure=='monoclinic':
            #Set to monoclinic
            a,b,c = [numpy.linalg.norm(v) for v in cello]
            if a==b:
                b=random.uniform(1,natoms**0.3333*size)
            trans=numpy.array([(1+random.random())*c, 0, (1+random.random())*c])
            celln=numpy.array([[a,0,0],[0,b,0],[0,0,0]])
            celln[2]=trans
            stro+='Setting cell to monoclinic\n'
        elif structure=='triclinic':
            #Set to triclinic
            a,b,c = [numpy.linalg.norm(v) for v in cello]
            celln=numpy.array([[a,0,0],[(1+random.random())*b,(1+random.random())*b,0],[(1+random.random())*c,0,(1+random.random())*c]])
            stro+='Setting cell to triclinic\n'
        indiv.set_cell(celln)
        indiv.set_scaled_positions(pos)
        stro+=repr(indiv.get_cell())+'\n'
        return indiv, stro
    return indiv
Beispiel #55
0
for opt in OPTIONS:
    a0 = 3.554 * opt / np.sqrt(2)
#    c0 = np.sqrt(8 / 3.0) * a0
    c0= 1.585 * a0

    atoms = Atoms('Fe2',
              scaled_positions=[(0, 0, 0),
                                (1./3., 1./3., 1./2.)],
              cell = [[1./2.,sqrt(3)/2.,0],[-1./2., sqrt(3)/2., 0] ,[0,0,1]],
              pbc=(1,1,1))


  #  atoms.set_cell([[1/2, sqrt(3)/2, 0],[-1/2, sqrt(3)/2, 0] ,[0,0,1]])

    scale = [[a0,0,0],[0,a0,0],[0,0,c0]]
    atoms.set_cell(np.dot( atoms.get_cell(), scale), scale_atoms=True)

    atoms.set_tags([1, 1])

    atoms = atoms*(1,1,2)

    print atoms.get_cell()
    print atoms.positions

    alloys = []
    alloys.append(Alloy(1, 'Fe', fe, 0.0))
    alloys.append(Alloy(1, 'Cr', cr, 0.0))

    calc = EMTO()
    calc.set(dir='{0}/calc/{1}/opt-{2:0.3f}'.format(temp_dir, name, opt),
             lat=9,
for i in range(2):
    equal(p[i, 1], 0, 1e-10)
    equal(p[i, 2], 0, 1e-10)

# rotate the nuclear axis to the direction (1,1,1)
CO.rotate(p[1] - p[0], (1, 1, 1))
q = CO.positions.copy()
for c in range(3):
    equal(q[0, c], p[0, 0] / sqrt(3), 1e-10)
    equal(q[1, c], p[1, 0] / sqrt(3), 1e-10)

# minimal box
b=4.0
CO = Cluster([Atom('C', (1, 0, 0)), Atom('O', (1, 0, R))])
CO.minimal_box(b)
cc = CO.get_cell() 
for c in range(3):
    width = 2*b
    if c==2:
        width += R
    equal(cc[c, c], width, 1e-10)

# minimal box, ensure multiple of 4
h = .13
b = [2, 3, 4]
CO.minimal_box(b, h=h)
cc = CO.get_cell() 
for c in range(3):
#    print "cc[c,c], cc[c,c] / h % 4 =", cc[c, c], cc[c, c] / h % 4
    for a in CO:
        print(a.symbol, b[c], a.position[c], cc[c, c] - a.position[c])
def test_chain_operators(seed):
    from ase.ga.startgenerator import StartGenerator
    from ase.ga.cutandsplicepairing import CutAndSplicePairing
    from ase.ga.standardmutations import StrainMutation
    from ase.ga.utilities import (closest_distances_generator, atoms_too_close,
                                  CellBounds)
    import numpy as np
    from ase import Atoms

    # set up the random number generator
    rng = np.random.RandomState(seed)

    slab = Atoms('', cell=(0, 16, 16), pbc=[True, False, False])
    blocks = ['C'] * 8
    n_top = 8

    use_tags = False
    num_vcv = 1
    box_volume = 8. * n_top

    blmin = closest_distances_generator(atom_numbers=[6],
                                        ratio_of_covalent_radii=0.6)

    cellbounds = CellBounds(
        bounds={
            'phi': [0.1 * 180., 0.9 * 180.],
            'chi': [0.1 * 180., 0.9 * 180.],
            'psi': [0.1 * 180., 0.9 * 180.],
            'a': [1, 6]
        })

    box_to_place_in = [[None, 6., 6.], [None, [0., 4., 0.], [0., 0., 4.]]]

    sg = StartGenerator(slab,
                        blocks,
                        blmin,
                        box_volume=box_volume,
                        splits=None,
                        box_to_place_in=box_to_place_in,
                        number_of_variable_cell_vectors=num_vcv,
                        cellbounds=cellbounds,
                        test_too_far=True,
                        test_dist_to_slab=False,
                        rng=rng)

    parents = []
    for i in range(2):
        a = None
        while a is None:
            a = sg.get_new_candidate()

        a.info['confid'] = i
        parents.append(a)

        assert len(a) == n_top
        assert len(np.unique(a.get_tags())) == 8
        assert np.allclose(a.get_pbc(), slab.get_pbc())

        p = a.get_positions()
        assert np.min(p[:, 1:]) > 6.
        assert np.max(p[:, 1:]) < 6. + 4.
        assert not atoms_too_close(a, blmin, use_tags=use_tags)

        c = a.get_cell()
        assert np.allclose(c[1:], slab.get_cell()[1:])
        assert cellbounds.is_within_bounds(c)

        v = a.get_volume() * (4. / 16.)**2
        assert abs(v - box_volume) < 1e-5

    # Test cut-and-splice pairing and strain mutation
    pairing = CutAndSplicePairing(slab,
                                  n_top,
                                  blmin,
                                  number_of_variable_cell_vectors=num_vcv,
                                  p1=1.,
                                  p2=0.,
                                  minfrac=0.15,
                                  cellbounds=cellbounds,
                                  use_tags=use_tags,
                                  rng=rng)

    strainmut = StrainMutation(blmin,
                               cellbounds=cellbounds,
                               number_of_variable_cell_vectors=num_vcv,
                               use_tags=use_tags,
                               rng=rng)
    strainmut.update_scaling_volume(parents)

    for operator in [pairing, strainmut]:
        child = None
        while child is None:
            child, desc = operator.get_new_individual(parents)

        assert not atoms_too_close(child, blmin, use_tags=use_tags)
        cell = child.get_cell()
        assert cellbounds.is_within_bounds(cell)
        assert np.allclose(cell[1:], slab.get_cell()[1:])
Beispiel #58
0
def read_vasp(filename='CONTCAR'):
    """Import POSCAR/CONTCAR type file.

    Reads unitcell, atom positions and constraints from the POSCAR/CONTCAR
    file and tries to read atom types from POSCAR/CONTCAR header, if this fails
    the atom types are read from OUTCAR or POTCAR file.
    """
 
    from ase import Atoms, Atom
    from ase.constraints import FixAtoms, FixScaled
    from ase.data import chemical_symbols
    import numpy as np

    if isinstance(filename, str):
        f = open(filename)
    else: # Assume it's a file-like object
        f = filename

    # First line should contain the atom symbols , eg. "Ag Ge" in
    # the same order
    # as later in the file (and POTCAR for the full vasp run)
    atomtypes = f.readline().split()

    # Sometimes the first line in POSCAR/CONTCAR is of the form
    # "CoP3_In-3.pos". Check for this case and extract atom types
    if len(atomtypes) == 1 and '_' in atomtypes[0]:
        atomtypes = get_atomtypes_from_formula(atomtypes[0])

    lattice_constant = float(f.readline().split()[0])

    # Now the lattice vectors
    a = []
    for ii in range(3):
        s = f.readline().split()
        floatvect = float(s[0]), float(s[1]), float(s[2])
        a.append(floatvect)

    basis_vectors = np.array(a) * lattice_constant

    # Number of atoms. Again this must be in the same order as
    # in the first line
    # or in the POTCAR or OUTCAR file
    atom_symbols = []
    numofatoms = f.readline().split()
    #vasp5.1 has an additional line which gives the atom types
    #the following try statement skips this line
    try:
        int(numofatoms[0])
    except ValueError:
        numofatoms = f.readline().split()

    # check for comments in numofatoms line and get rid of them if necessary
    commentcheck = np.array(['!' in s for s in numofatoms])
    if commentcheck.any():
        # only keep the elements up to the first including a '!':
        numofatoms = numofatoms[:np.arange(len(numofatoms))[commentcheck][0]]
        
    numsyms = len(numofatoms)
    if len(atomtypes) < numsyms:
        # First line in POSCAR/CONTCAR didn't contain enough symbols.
        atomtypes = atomtypes_outpot(f.name, numsyms)
    else:
        try:
            for atype in atomtypes[:numsyms]:
                if not atype in chemical_symbols:
                    raise KeyError
        except KeyError:
            atomtypes = atomtypes_outpot(f.name, numsyms)

    for i, num in enumerate(numofatoms):
        numofatoms[i] = int(num)
        [atom_symbols.append(atomtypes[i]) for na in xrange(numofatoms[i])]

    # Check if Selective dynamics is switched on
    sdyn = f.readline()
    selective_dynamics = sdyn[0].lower() == "s"

    # Check if atom coordinates are cartesian or direct
    if selective_dynamics:
        ac_type = f.readline()
    else:
        ac_type = sdyn
    cartesian = ac_type[0].lower() == "c" or ac_type[0].lower() == "k"
    tot_natoms = sum(numofatoms)
    atoms_pos = np.empty((tot_natoms, 3))
    if selective_dynamics:
        selective_flags = np.empty((tot_natoms, 3), dtype=bool)
    for atom in xrange(tot_natoms):
        ac = f.readline().split()
        atoms_pos[atom] = (float(ac[0]), float(ac[1]), float(ac[2]))
        if selective_dynamics:
            curflag = []
            for flag in ac[3:6]:
                curflag.append(flag == 'F')
            selective_flags[atom] = curflag
    # Done with all reading
    if type(filename) == str:
        f.close()
    if cartesian:
        atoms_pos *= lattice_constant
    atoms = Atoms(symbols = atom_symbols, cell = basis_vectors, pbc = True)
    if cartesian:
        atoms.set_positions(atoms_pos)
    else:
        atoms.set_scaled_positions(atoms_pos)
    if selective_dynamics:
        constraints = []
        indices = []
        for ind, sflags in enumerate(selective_flags):
            if sflags.any() and not sflags.all():
                constraints.append(FixScaled(atoms.get_cell(), ind, sflags))
            elif sflags.all():
                indices.append(ind)
        if indices:
            constraints.append(FixAtoms(indices))
        if constraints:
            atoms.set_constraint(constraints)
    return atoms