Beispiel #1
0
def cell_translate(ase_atoms):
    """Create dummy atoms for cell images."""
    cell = ase_atoms.cell
    atoms_ = Atoms('H')
    atoms_.cell = cell
    atoms_.set_scaled_positions([0.5, 0.5, 0.5])
    return atoms_
Beispiel #2
0
def read_cml(fileobj):
    data = contract(json.load(fileobj))
    atoms = Atoms()
    datoms = data['atoms']

    atoms = Atoms(datoms['elements']['number'])

    if 'unitcell' in data:
        cell = data['unitcell']
        a = cell['a']
        b = cell['b']
        c = cell['c']
        alpha = cell['alpha']
        beta = cell['beta']
        gamma = cell['gamma']
        atoms.cell = Cell.fromcellpar([a, b, c, alpha, beta, gamma])
        atoms.pbc = True

    coords = contract(datoms['coords'])
    if '3d' in coords:
        positions = np.array(coords['3d']).reshape(len(atoms), 3)
        atoms.set_positions(positions)
    else:
        positions = np.array(coords['3dfractional']).reshape(len(atoms), 3)
        atoms.set_scaled_positions(positions)

    yield atoms
Beispiel #3
0
def make_periodic(atoms: Atoms, vacuum_buffer: float = 10) -> Atoms:
    """Make an atoms object periodic
    
    Required for fitting with ``fit_gap``
    
    Args:
        atoms: Atoms object to be adjusted
        vacuum_buffer: Amount of space to buffer on either side of the molecule
    Returns:
        Atoms object made periodic
    """

    # Give the cell periodic boundary conditions in each direction
    atoms.pbc = [True] * 3

    # Compute the size of the cell in each direction
    mol_size = np.max(atoms.positions, axis=0) - np.min(atoms.positions,
                                                        axis=0)

    # Give a cell that is big enough to have the desired buffer on each size
    atoms.cell = np.diag(mol_size + vacuum_buffer * 2)

    # Center the atoms in the middle of it
    atoms.center()
    return atoms
Beispiel #4
0
	def ori_structure(self):
		lead1=self.lead1=graphene(dict(latx=1,laty=self.laty,latz=1)).lmp_structure()
		n=len(lead1)
		center=graphene(dict(latx=self.latx,laty=self.laty,latz=1)).lmp_structure()
		center.translate(lead1.cell[0])
		lead2=lead1.copy()
		lead2.translate(lead1.cell[0]+center.cell[0])
		atoms=Atoms()
		atoms.extend(lead1)
		atoms.extend(center)
		atoms.extend(lead2)
		atoms.cell=center.cell
		atoms.cell[0]=lead1.cell[0]+center.cell[0]+lead2.cell[0]

		lx=self.extent(atoms)[0]
		self.getScale(lx/2)
		self.center_box(atoms)
		self.writeatoms(atoms,'graphene')
		low=atoms.positions[:,0].min()+2
		hi=atoms.positions[:,0].max()-2
		self.leftgroup=np.arange(len(atoms),dtype='int')[:n]+1
		self.rightgroup=np.arange(len(atoms),dtype='int')[-n:]+1
		self.fmag=self.strain/float(len(self.leftgroup))

		self.posleft=atoms.positions[self.leftgroup[0]-1].copy()+(50,50,50)
		self.posright=atoms.positions[self.rightgroup[0]-1].copy()+(50,50,50)
		self.posleft[0]*=10
		self.posright[0]*=10
		for atom in atoms:
			atom.position=self.trans(atom.position)
		atoms.center(vacuum=50)
		return atoms
Beispiel #5
0
def test_center_nonperiodic():
    import numpy as np
    from ase import Atoms

    a = Atoms('H')
    a.center(about=[0., 0., 0.])
    print(a.cell)
    print(a.positions)

    assert not a.cell.any()
    assert not a.positions.any()

    a.cell = [0., 2., 0.]
    a.center()
    print(a)
    print(a.positions)
    assert np.abs(a.positions - [[0., 1., 0.]]).max() < 1e-15

    a.center(about=[0., -1., 1.])
    print(a.positions)
    assert np.abs(a.positions - [[0., -1., 1.]]).max() < 1e-15
    assert np.abs(a.cell - np.diag([0., 2., 0.])).max() < 1e-15
    a.center(axis=2, vacuum=2.)
    print(a.positions)
    print(a.cell)
    assert np.abs(a.positions - [[0., -1., 2.]]).max() < 1e-15
    assert np.abs(a.cell - np.diag([0., 2., 4.])).max() < 1e-15
Beispiel #6
0
def test_axis_layout():
    system = Atoms('H')
    a = 3.
    system.cell = (a, a, a)
    system.pbc = 1

    for axis in range(3):
        system.center()
        system.positions[0, axis] = 0.0
        calc = Octopus(**getkwargs(label='ink-%s' % 'xyz'[axis],
                                   Output='density + potential + wfs'))
        system.set_calculator(calc)
        system.get_potential_energy()
        rho = calc.get_pseudo_density(pad=False)
        #for dim in rho.shape:
        #    assert dim % 2 == 1, rho.shape

        maxpoint = np.unravel_index(rho.argmax(), rho.shape)
        print('axis=%d: %s/%s' % (axis, maxpoint, rho.shape))

        expected_max = [dim // 2 for dim in rho.shape]
        expected_max[axis] = 0
        assert maxpoint == tuple(expected_max), '%s vs %s' % (maxpoint,
                                                              expected_max)

    errs = check_interface(calc)

    for err in errs:
        if err.code == 'not implemented':
            continue

        if err.methname == 'get_dipole_moment':
            assert isinstance(err.error, OctopusIOError)
        else:
            raise AssertionError(err.error)
Beispiel #7
0
def test_axis_layout():
    system = Atoms('H')
    a = 3.
    system.cell = (a, a, a)
    system.pbc = 1

    for axis in range(3):
        system.center()
        system.positions[0, axis] = 0.0
        calc = Octopus(**getkwargs(label='ink-%s' % 'xyz'[axis],
                                   Output='density + potential + wfs'))
        system.set_calculator(calc)
        system.get_potential_energy()
        rho = calc.get_pseudo_density(pad=False)
        #for dim in rho.shape:
        #    assert dim % 2 == 1, rho.shape

        maxpoint = np.unravel_index(rho.argmax(), rho.shape)
        print('axis=%d: %s/%s' % (axis, maxpoint, rho.shape))

        expected_max = [dim // 2 for dim in rho.shape]
        expected_max[axis] = 0
        assert maxpoint == tuple(expected_max), '%s vs %s' % (maxpoint,
                                                              expected_max)

    errs = check_interface(calc)

    for err in errs:
        if err.code == 'not implemented':
            continue

        if err.methname == 'get_dipole_moment':
            assert isinstance(err.error, OctopusIOError)
        else:
            raise AssertionError(err.error)
Beispiel #8
0
 def get_ase_atoms(self,bbox=None,**kwargs):
   '''Create an ASE atoms object.
   (cf. https://wiki.fysik.dtu.dk/ase/ase/atoms.html )
   
   **Parameters:**
   
   bbox : list of floats (bbox=[xmin,xmax,ymin,ymax,zmin,zmax]), optional
     If not None, sets the unit cell to the grid boundaries and moves the 
     molecule in its center.
   
   **Returns:**
   
   atoms : Atoms object 
     See https://wiki.fysik.dtu.dk/ase/ase/atoms.html for details
   
   .. Note::
   
     ASE has to be in the PYTHONPATH
   '''
   from ase import Atoms
   from ase.units import Bohr
   
   atoms = Atoms("".join(self.geo_info[:,0]), 
                 positions=self.geo_spec*Bohr,
                 **kwargs)
   if bbox is not None:
     if len(bbox) != 6: 
       raise ValueError("bbox has to have 6 elements")
     bbox = numpy.array(bbox)
     atoms.translate(-bbox[::2]*Bohr)
     atoms.cell = numpy.eye(3) * (bbox[1::2] - bbox[::2])*Bohr
   
   return atoms
Beispiel #9
0
def read_dmol_incoor(filename, bohr=True):
    """ Reads an incoor file and returns an atoms object.

    Notes
    -----
    If bohr is True then incoor is assumed to be in bohr and the data
    is rescaled to Angstrom.
    """

    lines = open(filename, 'r').readlines()
    symbols = []
    positions = []
    for i, line in enumerate(lines):
        if line.startswith('$cell vectors'):
            cell = np.zeros((3, 3))
            for j, line in enumerate(lines[i + 1:i + 4]):
                cell[j, :] = [float(fld) for fld in line.split()]
        if line.startswith('$coordinates'):
            j = i + 1
            while True:
                if lines[j].startswith('$end'):
                    break
                flds = lines[j].split()
                symbols.append(flds[0])
                positions.append(flds[1:4])
                j += 1
    atoms = Atoms(symbols=symbols, positions=positions, cell=cell, pbc=True)
    if bohr:
        atoms.cell = atoms.cell * Bohr
        atoms.positions = atoms.positions * Bohr
    return atoms
def test_counterions():
    """ Test AtomicCounterIon is force/energy consistent over 
        PBCs and with cutoff """

    import numpy as np
    from ase import Atoms
    from ase import units
    from ase.calculators.counterions import AtomicCounterIon as ACI

    sigma = 1.868 * (1.0 / 2.0)**(1.0 / 6.0)
    epsilon = 0.00277 * units.kcal / units.mol

    atoms = Atoms('3Na',
                  positions=np.array([[0, 0, -2], [0, 0, 0], [0, 0, 2]]))
    atoms.cell = [10, 10, 10]
    atoms.pbc = True

    atoms.calc = ACI(1, epsilon, sigma, rc=4.5)
    points = np.arange(-15., 15., 0.2)

    for p in points:
        f = atoms.get_forces()
        fn = atoms.calc.calculate_numerical_forces(atoms, 1e-5)
        df = (f - fn)
        assert abs(df).max() < 1e-8
Beispiel #11
0
def read_xdatcar(filename, skip=0, every=1):
    f = open(filename, 'r')
    lines = f.readlines()
    f.close()
    lattice_constant = float(lines[1].strip())
    cell = numpy.array([[float(x) * lattice_constant for x in lines[2].split()],
                        [float(x) * lattice_constant for x in lines[3].split()],
                        [float(x) * lattice_constant for x in lines[4].split()]])
    elements = lines[5].split()
    natoms = [int(x) for x in lines[6].split()]
    nframes = (len(lines)-7)/(sum(natoms) + 1)
    trajectory = []
    for i in range(skip, nframes, every):
        a = Atoms('H'*sum(natoms))
        a.masses = [1.0] * len(a)
        a.set_chemical_symbols(''.join([n*e for (n, e) in zip(natoms, elements)]))
        a.cell = cell.copy()
        a.set_pbc((True, True, True))
        j = 0
        for N, e in zip(natoms, elements):
            for k in range(N):
                split = lines[8 + i * (sum(natoms) + 1) + j].split()
                a[j].position = [float(l) for l in split[0:3]]
                j += 1
        a.positions = numpy.dot(a.positions, cell)
        trajectory.append(a)
    return trajectory
Beispiel #12
0
 def build_system(self, name):
     if name in extra:
         mol = Atoms(*extra[name])
         mol.cell = self.unit_cell
         mol.center()
     else:
         self.bond_length = bondlengths.get(name, None)
         mol = MoleculeTask.build_system(self, name)
     return mol
    def make_ase(self, species, positions):
        """Create ase Atoms object."""
        # Get the principal axes and realign the molecule along z-axis.
        positions = PCA(n_components=3).fit_transform(positions)
        atoms = Atoms(species, positions=positions, pbc=True)
        atoms.cell = np.ptp(atoms.positions, axis=0) + 10
        atoms.center()

        return atoms
Beispiel #14
0
def pad_atoms(atoms: Atoms, margin: float, directions='xy', in_place=False):
    """
    Repeat the atoms in x and y, retaining only the repeated atoms within the margin distance from the cell boundary.

    Parameters
    ----------
    atoms: ASE Atoms object
        The atoms that should be padded.
    margin: float
        The padding margin.

    Returns
    -------
    ASE Atoms object
        Padded atoms.
    """

    if not is_cell_orthogonal(atoms):
        raise RuntimeError('The cell of the atoms must be orthogonal.')

    if not in_place:
        atoms = atoms.copy()

    old_cell = atoms.cell.copy()

    axes = [{'x': 0, 'y': 1, 'z': 2}[direction] for direction in directions]

    reps = [1, 1, 1]
    for axis in axes:
        reps[axis] = int(1 + 2 * np.ceil(margin / atoms.cell[axis, axis]))

    if any([rep > 1 for rep in reps]):
        atoms *= reps
        atoms.positions[:] -= np.diag(old_cell) * [rep // 2 for rep in reps]
        atoms.cell = old_cell

    # import matplotlib.pyplot as plt
    # from abtem import show_atoms
    # show_atoms(atoms, plane='xz')
    # plt.show()

    to_keep = np.ones(len(atoms), dtype=bool)
    for axis in axes:
        to_keep *= (atoms.positions[:, axis] > -margin) * (
            atoms.positions[:, axis] < atoms.cell[axis, axis] + margin)

    atoms = atoms[to_keep]

    # for axis in axes:
    #     left = atoms[atoms.positions[:, axis] < margin]
    #     left.positions[:, axis] += atoms.cell[axis, axis]
    #     right = atoms[(atoms.positions[:, axis] > atoms.cell[axis, axis] - margin) &
    #                   (atoms.positions[:, axis] < atoms.cell[axis, axis])]
    #     right.positions[:, axis] -= atoms.cell[axis, axis]
    #     atoms += left + right
    return atoms
Beispiel #15
0
def rotatedCrystal(V, size=(2, 2, 1), a=1.3968418, cType='gr'):
    """
    Generates a triangular crystal lattice of the given size and rotates it so that the new unit vectors
    align with the columns of V. The positions are set so that the center atom is at the
    origin. Size is expected to be even in all directions.
    'a' is the atomic distance between the atoms of the hexagonal lattice daul to this crystal.
    In other words, a*sqrt(3) is the lattice constant of the triangular lattice.
    The returned object is of ase.Atoms type
    """
    if cType == 'gr':
        cr = GB.grapheneCrystal(1, 1, 'armChair').aseCrystal(ccBond=a)

    elif cType == 'tr':
        numbers = [6.0]
        cell = numpy.array([[a * (3.0**0.5), 0, 0],
                            [0.5 * a * (3.0**0.5), 1.5 * a, 0], [0, 0,
                                                                 10 * a]])
        positions = numpy.array([[0, 0, 0]])
        cr = ase.Atoms(numbers=numbers,
                       positions=positions,
                       cell=cell,
                       pbc=[True, True, True])

    elif cType == 'tr-or':
        numbers = [6.0, 6.0]
        cell = numpy.array([[a * (3.0**0.5), 0, 0], [0, 3.0 * a, 0],
                            [0, 0, 10 * a]])
        positions = numpy.array([[0, 0, 0], [0.5 * a * (3.0**0.5), 1.5 * a,
                                             0]])
        cr = ase.Atoms(numbers=numbers,
                       positions=positions,
                       cell=cell,
                       pbc=[True, True, True])  # Repeating

    ix = numpy.indices(size, dtype=int).reshape(3, -1)
    tvecs = numpy.einsum('ki,kj', ix, cr.cell)
    rPos = numpy.ndarray((len(cr) * len(tvecs), 3))
    for i in range(len(cr)):
        rPos[i * len(tvecs):(i + 1) * len(tvecs)] = tvecs + cr.positions[i]
    # New cell size
    for i in range(3):
        cr.cell[i] *= size[i]

    cr = Atoms(symbols=['C'] * len(rPos),
               positions=rPos,
               cell=cr.cell,
               pbc=[True, True, True])
    center = numpy.sum(cr.cell, axis=0) * 0.5
    cr.positions = cr.positions - center

    cr.cell = numpy.einsum('ik,jk', cr.cell, V)
    cr.positions = numpy.einsum('ik,jk', cr.positions, V)

    return cr
    def pymol_2_ase(pymol):
        """Convert pymol object into ASE Atoms."""

        asemol = Atoms()
        for atm in pymol.atoms:
            asemol.append(Atom(chemical_symbols[atm.atomicnum], atm.coords))
        asemol.cell = np.amax(asemol.positions, axis=0) - np.amin(
            asemol.positions, axis=0) + [10] * 3
        asemol.pbc = True
        asemol.center()
        return asemol
Beispiel #17
0
    def _make_ase(self, species, positions, smiles):
        """Create ase Atoms object."""
        # Get the principal axes and realign the molecule along z-axis.
        positions = PCA(n_components=3).fit_transform(positions)
        atoms = Atoms(species, positions=positions, pbc=True)
        atoms.cell = np.ptp(atoms.positions, axis=0) + 10
        atoms.center()
        # We're attaching this info so that it
        # can be later stored as an extra on AiiDA Structure node.
        atoms.info["smiles"] = smiles

        return atoms
Beispiel #18
0
    def __init__(
            self,
            n=6,
            parameters=DEFAULT,
            ):
        atoms = Atoms([])
        C_C = 1.42
        C_H = 1.09
        main_element = 'C'
        saturate_element = 'H'
        vacuum = 10
        m = 1
        b = np.sqrt(3) * C_C / 4

        zz_unit = Atoms(main_element + '2',
                       pbc=(0, 1, 1),
                       cell=[2 * vacuum, 3 * C_C / 2.0, b * 4])

        zz_unit.positions = [[0, 0, 0],
                             [0, C_C / 2.0, b * 2]]

        edge_index0 = np.arange(m) * 2 + 1
        edge_index1 = (n - 1) * m * 2 + np.arange(m) * 2

        for i in range(n):
            layer = zz_unit.repeat((1, 1, m))
            layer.positions[:, 1] -= 3 * C_C / 2 * i
            if i % 2 == 1:
                layer.positions[:, 2] += 2 * b
                layer[-1].position[2] -= b * 4 * m
            atoms += layer

        H_atoms0 = Atoms(saturate_element + str(m))
        H_atoms0.positions = atoms[edge_index0].positions
        H_atoms0.positions[:, 1] += C_H
        H_atoms1 = Atoms(saturate_element + str(m))
        H_atoms1.positions = atoms[edge_index1].positions
        H_atoms1.positions[:, 1] -= C_H
        atoms += H_atoms0 + H_atoms1

        atoms.cell = [2 * vacuum, n * 3 * C_C / 2 + 2 * vacuum, m * 4 * b]
        atoms.set_pbc([False, False, True])
        center = atoms.positions.mean(axis=0)
        center[0] = 0
        center[2] = 0
        atoms.translate(-center)

        Crystal1D.__init__(
                self,
                atoms,
                parameters=parameters,
                )
Beispiel #19
0
def pybel2ase(mol):
    asemol = Atoms()
    species = [chemical_symbols[atm.atomicnum] for atm in mol.atoms]
    pos = np.asarray([atm.coords for atm in mol.atoms])
    pca = PCA(n_components=3)
    posnew = pca.fit_transform(pos)
    #posnew[:,2]=0.0
    atoms = Atoms(species, positions=posnew)
    sys_size = np.ptp(atoms.positions, axis=0)
    atoms.pbc = True
    atoms.cell = sys_size + 10
    atoms.center()

    return atoms
Beispiel #20
0
    def __init__(
            self,
            n=7,
            parameters=DEFAULT,
            ):
        atoms = Atoms([])
        C_C = 1.42
        C_H = 1.09
        main_element = 'C'
        saturate_element = 'H'
        vacuum = 10
        b = np.sqrt(3) * C_C / 4
        arm_unit = Atoms(main_element + '2',
                     pbc=(1, 0, 1),
                     cell=[
                           [2 * vacuum, 0, 0 ],
                           [0, 2 * b, 1.5*C_C],
                           [0, 0, 3 * C_C    ],])

        arm_unit.positions = [[0, 0, -1.5*C_C],
                              [0, 0, -0.5*C_C]]


        core_atoms = arm_unit.repeat((1, n, 1))
        h_positions=np.array([
                [0, -np.sqrt(3) / 2 * C_H, - C_H * 0.5],
                [0, -np.sqrt(3) / 2 * C_H,  C_H * 0.5],
                ])
        atoms = Atoms(
                saturate_element + '2',
                cell= core_atoms.get_cell(),
                )
        atoms.positions = core_atoms[:2].positions + h_positions
        atoms += core_atoms
        last_hydrogens = Atoms(
                saturate_element + '2',
                )
        h_positions[:, 1] *= -1
        last_hydrogens.positions = core_atoms[-2:].positions + h_positions
        atoms += last_hydrogens
        atoms.cell = [b * 2 * n + 2 * vacuum, 2 * vacuum, 3 * C_C]
        atoms.set_pbc([False, False, True])
        atoms.wrap()
        atoms.translate((0, -b*float(n-1),  0))

        Crystal1D.__init__(
                self,
                atoms,
                parameters=parameters,
                )
Beispiel #21
0
	def lmp_structure(self):
		atoms=Atoms()
		lead1=self.m.lmp_structure()
		self.hatom=len(lead1)
		lead2=lead1.copy()
		lead3=lead1.copy()
		atoms.extend(lead1)
		lead2.translate(lead1.cell[0])
		atoms.extend(lead2)
		lead3.translate(lead1.cell[0]*2)
		atoms.extend(lead3)
		atoms.cell=lead1.cell.copy()
		atoms.cell[0]=lead1.cell[0]*3
		atoms.center()
		return atoms
    def pybel2ase(mol):
        """converts pybel molecule into ase Atoms"""
        asemol = Atoms()
        species = [chemical_symbols[atm.atomicnum] for atm in mol.atoms]
        pos = np.asarray([atm.coords for atm in mol.atoms])
        pca = PCA(n_components=3)
        posnew = pca.fit_transform(pos)
        atoms = Atoms(species, positions=posnew)
        sys_size = np.ptp(atoms.positions, axis=0)
        atoms.rotate(-90, 'z')  #cdxml are rotated
        atoms.pbc = True
        atoms.cell = sys_size + 10
        atoms.center()

        return atoms
Beispiel #23
0
	def lmp_structure(self):
		atoms=Atoms()
		lead1=self.m.lmp_structure()
		self.hatom=len(lead1)
		lead2=lead1.copy()
		lead3=lead1.copy()
		atoms.extend(lead1)
		lead2.translate(lead1.cell[0])
		atoms.extend(lead2)
		lead3.translate(lead1.cell[0]*2)
		atoms.extend(lead3)
		atoms.cell=lead1.cell.copy()
		atoms.cell[0]=lead1.cell[0]*3
		atoms.center()
		return atoms
Beispiel #24
0
def read_con(filename):
    f = open(filename, 'r')
    lines = f.readlines()
    f.close()
    trajectory = []
    line_index = 0
    while True:
        try:
            boxlengths = numpy.array([float(length) for length in lines[line_index+2].split()[0:3]])
            boxangles = numpy.array([float(angle) for angle in lines[line_index+3].split()[0:3]])
            cell = length_angle_to_box(boxlengths, boxangles)
            num_types = int(lines[line_index+6].split()[0])
            num_each_type = [int(n) for n in lines[line_index+7].split()[0:num_types]]
            mass_each_type = [float(n) for n in lines[line_index+8].split()[0:num_types]]
            a = Atoms('H'*sum(num_each_type))
            a.cell = cell
            a.set_pbc((True, True, True))
            frozen = []
            positions = []
            symbols = []
            masses = []
            line_index += 9
            atom_index = 0
            for i in range(num_types):
                symbol = lines[line_index].strip()
                mass = mass_each_type[i]
                line_index += 2
                for j in range(num_each_type[i]):
                    split = lines[line_index].split()
                    positions.append([float(s) for s in split[0:3]])
                    symbols.append(symbol)
                    masses.append(mass)
                    if split[3] != '0':
                        frozen.append(atom_index)
                    atom_index += 1
                    line_index += 1
            a.set_chemical_symbols(symbols)
            a.set_positions(positions)
            a.set_masses(masses)
            a.set_constraint(FixAtoms(frozen))
        except:
            if len(trajectory) == 1:
                return trajectory[0]
            if len(trajectory) == 0:
                raise IOError, "Could not read con file."
            return trajectory
        trajectory.append(a)
Beispiel #25
0
def rdkit2ase(m):
    pos = m.GetConformer().GetPositions()
    natoms = m.GetNumAtoms()
    species = [m.GetAtomWithIdx(j).GetSymbol() for j in range(natoms)]
    #Get the principal axes and realign the molecule
    pca = PCA(n_components=3)
    pca.fit(pos)
    posnew = pca.transform(pos)
    #Set the z to 0.0
    #posnew[:,2]=0.0
    atoms = Atoms(species, positions=posnew)
    sys_size = np.ptp(atoms.positions, axis=0)
    atoms.pbc = True
    atoms.cell = sys_size + 10
    atoms.center()

    return atoms
Beispiel #26
0
    def slab(m, n):
        atoms = Atoms()

        for i in range(n):
            if i % 2 == 0:
                layer = ac_unit.repeat((m, 1, 1))
            if i % 2 == 1:
                layer = ac_unit.repeat((m, 1, 1))
                layer.positions[:, 0] += 3. / 2 * C_C

            if saturated:
                if i == 0:
                    sat = ac_sat_unit.repeat((m, 1, 1))
                    sat.positions[:, 1] -= np.sqrt(3.) / 2 * C_H
                    sat.positions[:, 0] -= 1. / 2 * C_H
                    layer += sat
                elif i == n - 1:
                    sat = ac_sat_unit.repeat((m, 1, 1))
                    sat.positions[:, 1] += np.sqrt(3.) / 2 * C_H
                    sat.positions[:,
                                  0] -= 1. / 2 * C_H - 3. / 2 * C_C * (i % 2)
                    layer += sat

            layer.positions[:, 1] += b / 2 * i
            atoms += layer

        xmax = np.max(atoms.positions[:, 0])
        for atom in atoms:
            if xmax - C_C / 2. < atom.position[0]:
                atom.position[0] -= m * 3 * C_C

        if saturated:
            xmax = np.max(atoms.positions[:, 0])
            xmin = np.min(atoms.positions[:, 0])
            for atom in atoms:
                posit = atom.position
                if xmax - C_C / 6. < posit[0] and atom.number == 6:
                    h_posit = [posit[0] + C_H, posit[1], posit[2]]
                    atoms += Atom('H', position=h_posit)
                if posit[0] < xmin + C_C / 6. and atom.number == 6:
                    h_posit = [posit[0] - C_H, posit[1], posit[2]]
                    atoms += Atom('H', position=h_posit)

        atoms.cell = [m * 3 * C_C, n * b / 2, 2 * vacuum]
        atoms.center()
        return atoms
Beispiel #27
0
 def slab(m, n):
     atoms = Atoms()
         
     for i in range(n):
         if i % 2 == 0:
             layer   =   ac_unit.repeat((m, 1, 1))
         if i % 2 == 1:
             layer   =   ac_unit.repeat((m, 1, 1))
             layer.positions[:, 0] += 3./2 * C_C
             
         if saturated:
             if i == 0:  
                 sat =   ac_sat_unit.repeat((m,1,1))
                 sat.positions[:,1]  -= np.sqrt(3.) / 2 * C_H
                 sat.positions[:,0]  -= 1. / 2 * C_H
                 layer +=    sat
             elif i == n - 1:    
                 sat =   ac_sat_unit.repeat((m,1,1))
                 sat.positions[:,1]  += np.sqrt(3.) / 2 * C_H 
                 sat.positions[:,0]  -= 1. / 2 * C_H - 3./2 * C_C * (i % 2)
                 layer +=    sat
         
         layer.positions[:, 1] += b / 2 * i
         atoms += layer
     
     xmax    =   np.max(atoms.positions[:,0])
     for atom in atoms:
         if xmax - C_C/2. < atom.position[0]:
             atom.position[0] -=     m*3*C_C 
     
     if saturated:
         xmax    =   np.max(atoms.positions[:,0])
         xmin    =   np.min(atoms.positions[:,0])
         for atom in atoms:
             posit   =   atom.position
             if xmax - C_C/6. < posit[0] and atom.number == 6:
                 h_posit =  [posit[0] + C_H, posit[1], posit[2]]
                 atoms  +=  Atom('H', position = h_posit)  
             if  posit[0] < xmin + C_C/6. and atom.number == 6:
                 h_posit =  [posit[0] - C_H, posit[1], posit[2]]
                 atoms  +=  Atom('H', position = h_posit)  
     
     atoms.cell = [m * 3 * C_C, n * b/2, 2 * vacuum]
     atoms.center()
     return atoms
Beispiel #28
0
    def lmp_structure(self):
        atoms = Atoms()
        lead1 = self.m1.lmp_structure()
        center = self.m.lmp_structure()
        lead2 = self.m2.lmp_structure()
        atoms.extend(lead1)
        center.translate(lead1.cell[0])
        atoms.extend(center)
        lead2.translate(lead1.cell[0] + center.cell[0])
        atoms.extend(lead2)
        atoms.cell = lead1.cell.copy()
        #atoms.set_pbc([0,0,0])
        atoms.cell[0] = lead1.cell[0] + center.cell[0] + lead2.cell[0]
        #atoms.center(10.0,axis=[1,2])
        #atoms.center()
        x = atoms.positions[:, 0]

        return center
Beispiel #29
0
def test_kpts2kpts(lat):
    print()
    print(lat)
    bandpath = lat.bandpath()
    a = Atoms()
    a.cell = lat.tocell().complete()
    a.pbc[:lat.ndim] = True
    path = {'path': bandpath.path}
    bandpath2 = kpts2kpts(path, atoms=a)
    print('cell', a.cell)
    print('Original', bandpath)
    print('path', path)
    print('Produced by kpts2kpts', bandpath2)
    sp = set(bandpath.special_points)
    sp2 = set(bandpath2.special_points)
    msg = ('Input and output bandpath from kpts2kpts dont agree!\n'
           'Input: {}\n Output: {}'.format(bandpath, bandpath2))
    assert sp == sp2, msg
Beispiel #30
0
	def lmp_structure(self):
		atoms=Atoms()
		lead1=self.m1.lmp_structure()
		center=self.m.lmp_structure()
		lead2=self.m2.lmp_structure()
		atoms.extend(lead1)
		center.translate(lead1.cell[0])
		atoms.extend(center)
		lead2.translate(lead1.cell[0]+center.cell[0])
		atoms.extend(lead2)
		atoms.cell=lead1.cell.copy()
		#atoms.set_pbc([0,0,0])
		atoms.cell[0]=lead1.cell[0]+center.cell[0]+lead2.cell[0]
		#atoms.center(10.0,axis=[1,2])
		#atoms.center()
		x=atoms.positions[:,0]

		return center
Beispiel #31
0
def test_properties():
    charges = np.array([-1, 1])
    a = Atoms('H2', positions=[(0, 0, 0), (0, 0, 1.1)], charges=charges)

    a.pbc[0] = 1
    assert a.pbc.any()
    assert not a.pbc.all()
    a.pbc = 1
    assert a.pbc.all()

    a.cell = (1, 2, 3)
    a.cell *= 2
    a.cell[0, 0] = 3
    assert not (a.cell.diagonal() - (3, 4, 6)).any()

    assert (charges == a.get_initial_charges()).all()
    assert a.has('initial_charges')
    # XXX extend has to calculator properties
    assert not a.has('charges')
Beispiel #32
0
def organize(a):
    """this function receives an Atoms data structure (ASE libraries),
	organizes the atoms in it according to their atomic symbols,
	and returns another Atoms data structure which is organized"""
    symb = []
    b = Atoms()
    b.cell = a.cell
    b.pbc = [True, True, True]
    for j in a:
        if str(j.symbol) not in symb:
            symb.append(str(j.symbol))

    symb = sorted(symb)

    for i in symb:
        for j in a:
            if str(j.symbol) == i:
                b.append(j)

    return b
Beispiel #33
0
def rotatedCrystal(V, size=(2, 2, 1), a=1.3968418, cType='gr'):
    """
    Generates a triangular crystal lattice of the given size and rotates it so that the new unit vectors
    align with the columns of V. The positions are set so that the center atom is at the
    origin. Size is expected to be even in all directions.
    'a' is the atomic distance between the atoms of the hexagonal lattice daul to this crystal.
    In other words, a*sqrt(3) is the lattice constant of the triangular lattice.
    The returned object is of ase.Atoms type
    """
    if cType == 'gr':
        cr = GB.grapheneCrystal(1, 1, 'armChair').aseCrystal(ccBond=a)

    elif cType == 'tr':
        numbers = [6.0]
        cell = numpy.array([[a * (3.0 ** 0.5), 0, 0], [0.5 * a * (3.0 ** 0.5), 1.5 * a, 0], [0, 0, 10 * a]])
        positions = numpy.array([[0, 0, 0]])
        cr = ase.Atoms(numbers=numbers, positions=positions, cell=cell, pbc=[True, True, True])

    elif cType == 'tr-or':
        numbers = [6.0, 6.0]
        cell = numpy.array([[a * (3.0 ** 0.5), 0, 0], [0, 3.0 * a, 0], [0, 0, 10 * a]])
        positions = numpy.array([[0, 0, 0], [0.5 * a * (3.0 ** 0.5), 1.5 * a, 0]])
        cr = ase.Atoms(numbers=numbers, positions=positions, cell=cell, pbc=[True, True, True])  # Repeating

    ix = numpy.indices(size, dtype=int).reshape(3, -1)
    tvecs = numpy.einsum('ki,kj', ix, cr.cell)
    rPos = numpy.ndarray((len(cr) * len(tvecs), 3))
    for i in range(len(cr)):
        rPos[i * len(tvecs):(i + 1) * len(tvecs)] = tvecs + cr.positions[i]
    # New cell size
    for i in range(3):
        cr.cell[i] *= size[i]

    cr = Atoms(symbols=['C'] * len(rPos), positions=rPos, cell=cr.cell, pbc=[True, True, True])
    center = numpy.sum(cr.cell, axis=0) * 0.5
    cr.positions = cr.positions - center

    cr.cell = numpy.einsum('ik,jk', cr.cell, V)
    cr.positions = numpy.einsum('ik,jk', cr.positions, V)

    return cr
Beispiel #34
0
def read_atoms_select():
    '''   
    '''
    from ase import Atoms, Atom
    atoms = Atoms()
    cell_vertexs = []
    for obj in bpy.context.selected_objects:
        if "BOND" in obj.name.upper():
            continue
        if obj.type not in {'MESH', 'SURFACE', 'META'}:
            continue
        name = ""
        if 'atom_kind_' == obj.name[0:10]:
            print(obj.name)
            ind = obj.name.index('atom_kind_')
            ele = obj.name[ind + 10:].split('_')[0]
            if len(obj.children) != 0:
                for vertex in obj.data.vertices:
                    location = obj.matrix_world @ vertex.co
                    atoms.append(Atom(ele, location))
            else:
                if not obj.parent:
                    location = obj.location
                    atoms.append(Atom(ele, location))
        # cell
        if 'point_cell' == obj.name[0:10]:
            print(obj.name)
            if len(obj.children) != 0:
                for vertex in obj.data.vertices:
                    location = obj.matrix_world @ vertex.co
                    # print(location)
                    cell_vertexs.append(location)
    # print(atoms)
    # print(cell_vertexs)
    if cell_vertexs:
        cell = [cell_vertexs[4], cell_vertexs[2], cell_vertexs[1]]
        atoms.cell = cell
        atoms.pbc = [True, True, True]
    # self.atoms = atoms
    return atoms
Beispiel #35
0
def get_atomic_structure(xml):
    """
    Parse atom.

    Parameters
    """
    nat = xml.attrib['nat']
    alat = xml.attrib['alat']
    atoms = Atoms()
    positions = []
    symbols = []
    all_species = []
    for item in xml.find('./atomic_positions'):
        species = item.attrib['name']
        all_species.append(species)
        symbol = species.split('_')[0].split('-')[0]
        if len(symbol) == 3:
            symbol = symbol[0:2]
        symbols.append(symbol)
        index = item.attrib['index']
        data = item.text.split()
        # These can be fractions and other expressions
        position = [float(data[0])*units['Bohr'], float(data[1])*units['Bohr'], float(data[2])*units['Bohr']]
        positions.append(position)
    positions = np.array(positions)
    # positions = positions**units['Bohr']
    atoms = Atoms(symbols = symbols, positions = positions)
    atoms.arrays['species'] = all_species
    # cell
    cell = []
    for item in xml.find('./cell'):
        data = item.text.split()
        cell.append([float(data[0]), float(data[1]), float(data[2])])
    cell = np.array(cell)
    cell = cell*units['Bohr']
    atoms.cell = cell
    atoms.pbc = True
    return atoms
Beispiel #36
0
def read_blase_collection(coll):
    '''   
    '''
    atoms = Atoms()
    name = coll.name

    # atoms
    for obj in coll.children['%s_atoms' % name].all_objects:
        ele = obj.name.split('_')[2]
        if len(obj.children) != 0:
            for vertex in obj.data.vertices:
                location = obj.matrix_world @ vertex.co
                atoms.append(Atom(symbol=ele, position=location))
        else:
            if not obj.parent:
                location = obj.location
                atoms.append(Atom(ele, location))
    # atoms properties
    scale = {}
    for obj in coll.children['%s_instancers' % name].all_objects:
        ele = obj.name.split('_')[3]
        scale[ele] = obj.scale
    # cell
    coll_cell = coll.children['%s_cell' % name]
    cell_vertexs = []
    if 'point_cell' in coll_cell.all_objects.keys():
        obj = coll_cell.all_objects['point_cell']
        for vertex in obj.data.vertices:
            location = obj.matrix_world @ vertex.co
            cell_vertexs.append(location)
    if cell_vertexs:
        cell = [cell_vertexs[4], cell_vertexs[2], cell_vertexs[1]]
        atoms.cell = cell
        atoms.pbc = coll.blase.pbc
    # coll property
    # self.atoms = atoms
    batoms = Batoms(atoms, name=name, coll=coll, scale=scale)
    return batoms
Beispiel #37
0
def export_blase():
    '''

    '''
    atoms = Atoms()
    cell_vertexs = []
    for obj in bpy.context.selected_objects:
        if "BOND" in obj.name.upper():
            continue
        if obj.type not in {'MESH', 'SURFACE', 'META'}:
            continue
        name = ""
        if 'atom_kind' in obj.name:
            print(obj.name)
            ele = obj.name[10:].split('.')[0]
            if len(obj.children) != 0:
                for vertex in obj.data.vertices:
                    location = obj.matrix_world @ vertex.co
                    atoms.append(Atom(ele, location))
            else:
                if not obj.parent:
                    location = obj.location
                    atoms.append(Atom(ele, location))
        # cell
        if 'point_cell' in obj.name:
            print(obj.name)
            if len(obj.children) != 0:
                for vertex in obj.data.vertices:
                    location = obj.matrix_world @ vertex.co
                    # print(location)
                    cell_vertexs.append(location)
    # print(atoms)
    # print(cell_vertexs)
    if cell_vertexs:
        cell = [cell_vertexs[4], cell_vertexs[2], cell_vertexs[1]]
        atoms.cell = cell
    return atoms
Beispiel #38
0
    def ori_structure(self):
        lead1 = self.lead1 = graphene(dict(latx=1, laty=self.laty,
                                           latz=1)).lmp_structure()
        n = len(lead1)
        center = graphene(dict(latx=self.latx, laty=self.laty,
                               latz=1)).lmp_structure()
        center.translate(lead1.cell[0])
        lead2 = lead1.copy()
        lead2.translate(lead1.cell[0] + center.cell[0])
        atoms = Atoms()
        atoms.extend(lead1)
        atoms.extend(center)
        atoms.extend(lead2)
        atoms.cell = center.cell
        atoms.cell[0] = lead1.cell[0] + center.cell[0] + lead2.cell[0]

        lx = self.extent(atoms)[0]
        self.getScale(lx / 2)
        self.center_box(atoms)
        self.writeatoms(atoms, 'graphene')
        low = atoms.positions[:, 0].min() + 2
        hi = atoms.positions[:, 0].max() - 2
        self.leftgroup = np.arange(len(atoms), dtype='int')[:n] + 1
        self.rightgroup = np.arange(len(atoms), dtype='int')[-n:] + 1
        self.fmag = self.strain / float(len(self.leftgroup))

        self.posleft = atoms.positions[self.leftgroup[0] - 1].copy() + (50, 50,
                                                                        50)
        self.posright = atoms.positions[self.rightgroup[0] -
                                        1].copy() + (50, 50, 50)
        self.posleft[0] *= 10
        self.posright[0] *= 10
        for atom in atoms:
            atom.position = self.trans(atom.position)
        atoms.center(vacuum=50)
        return atoms
Beispiel #39
0
  return atoms[indices]
def findele(atoms, ele):
  tags = atoms.get_chemical_symbols()
  mask = [i for i, tag in enumerate(tags) if tag==ele]
  return mask

# read CONTCAR
a = 15.865/4
xyz = a/2
#atoms = read('~/xcp2k/bulks/pt-relax/relax/')
bulk = Atoms([Atom('Pt', (0.0, 0.0, 0.0)),
               Atom('Pt', (xyz, xyz, 0.0)),
               Atom('Pt', (xyz, 0.0, xyz)),
               Atom('Pt', (0.0, xyz, xyz))])
bulk.cell= a * np.array([[1.0, 0.0, 0.0],
                         [0.0, 1.0, 0.0],
                         [0.0, 0.0, 1.0]])
atoms = surface(bulk, (1, 1, 1), 4, vacuum=0.0)
atoms.pbc = [True, True, True]
constraint = FixAtoms(mask=[atom.position[2] < 3
                            for atom in atoms])
atoms.set_constraint(constraint)
atoms.cell[2][2] = 25
atoms = sortz(atoms)

####
ads = Atoms('CO')

ads[0].position = atoms[-1].position
ads[1].position = atoms[-1].position
ads[0].z = ads[0].z + 1.80
Beispiel #40
0
def kwargs2atoms(kwargs):
    """Extract atoms object from keywords and return remaining keywords."""
    kwargs = purify(kwargs)

    coord_keywords = ['coordinates',
                      'xyzcoordinates',
                      'pdbcoordinates',
                      'reducedcoordinates',
                      'xsfcoordinates',
                      'xsfcoordinatesanimstep']
    
    nkeywords = 0
    for keyword in coord_keywords:
        if keyword in kwargs:
            nkeywords += 1
    if nkeywords == 0:
        raise OctopusParseError('No coordinates')
    elif nkeywords > 1:
        raise OctopusParseError('Multiple coordinate specifications present.  '
                                'This may be okay in Octopus, but we do not '
                                'implement it.')

    def get_positions_from_block(keyword):
        # %Coordinates or %ReducedCoordinates -> atomic numbers, positions.
        block = kwargs.pop(keyword)
        positions = []
        numbers = []
        for row in block:
            assert len(row) in [ndims + 1, ndims + 2]
            row = row[:ndims + 1]
            sym = row[0]
            assert sym.startswith("'") and sym.endswith("'")
            sym = sym[1:-1]
            pos0 = np.zeros(3)
            ndim = kwargs.get('dimensions', 3)
            pos0[:ndim] = map(float, row[1:])
            number = atomic_numbers[sym]  # Use 0 ~ 'X' for unknown?
            numbers.append(number)
            positions.append(pos0)
        positions = np.array(positions)
        return numbers, positions

    def read_atoms_from_file(keyword):
        if keyword not in kwargs:
            return None
        
        fname = kwargs.pop(keyword)
        fmt = keyword[:3].lower()
        read_method = {'xyz': read_xyz,
                       'pdb': read_pdb,
                       'xsf': read_xsf}[fmt]
        # XXX test xyz, pbd and xsf
        if fmt == 'xsf' and 'xsfcoordinatesanimstep' in kwargs:
            anim_step = kwargs.pop('xsfcoordinatesanimstep')
            slice = slice(anim_step, anim_step + 1, 1)
            # XXX test animstep
        images = read_method(fname, slice(None, None, 1))
        if len(images) != 1:
            raise OctopusParseError('Expected only one image.  Don\'t know '
                                    'what to do with %d images.' % len(images))
        return images[0]

    ndims = kwargs.get('dimensions', 3)
    cell, kwargs = kwargs2cell(kwargs)
    # XXX fix interaction between pbc and possibly existing pbc in XSF/etc.

    # XXX remember to pop
    atoms = None
    if 'coordinates' in kwargs:
        numbers, positions = get_positions_from_block('coordinates')
        atoms = Atoms(numbers=numbers, positions=positions)
    elif 'reducedcoordinates' in kwargs:
        numbers, rpositions = get_positions_from_block('reducedcoordinates')
        atoms = Atoms(numbers=numbers, scaled_positions=rpositions)
    else:
        for keyword in ['xyzcoordinates', 'pdbcoordinates', 'xsfcoordinates']:
            atoms = read_atoms_from_file(keyword)
            if atoms is not None:
                break
        else:
            raise OctopusParseError('Apparently there are no atoms.')

    assert atoms is not None

    # Either we have non-periodic BCs or the atoms object already
    # got its BCs from reading the file.  In the latter case
    # we shall override only if PeriodicDimensions was given specifically:
    pdims = kwargs.pop('periodicdimensions', None)
    if pdims is not None:
        pbc = np.zeros(3, dtype=bool)
        pdims = int(pdims)
        pbc[:pdims] = True
        atoms.pbc = pbc

    if cell is not None:
        atoms.cell = cell

    return atoms, kwargs
Beispiel #41
0
from ase import Atoms
a = Atoms('H2', positions=[(0, 0, 0), (0, 0, 1.1)])

a.pbc[0] = 1
assert a.pbc.any()
assert not a.pbc.all()
a.pbc = 1
assert a.pbc.all()

a.cell = (1, 2, 3)
a.cell *= 2
a.cell[0, 0] = 3
assert not (a.cell.diagonal() - (3, 4, 6)).any()
Beispiel #42
0
def convert_to_ase(sys, species=None):
    """
    Convert a given pyscal structure to ase object

    Parameters
    ----------
    sys : System object
        the system object to be converted

    species : list of str
        a list of species in the system

    Returns
    -------
    aseobject: ASE atoms object

    Notes
    -----
    ASE needs the species of atoms. If a property called `species`
    exist in :attr:`~pyscal.catom.Atom.custom`, this value is used for
    species. However if the value is not present, the keyword `species`
    is required. This should contain a mapping between :attr:`~pyscal.catom.Atom.type`
    and species name. For example, if `species` is `['Au', 'Ge']`, all atoms
    of type 1 are assigned as Au and those of type 2 are assigned as Ge.
    Note that ase is required to run this method.

    """
    #we only do a local import of ASE, this is not super nice
    #we can change this later depending on if ASE is to be treated
    #as a full dependency

    atoms = sys.atoms
    #get element strings
    if 'species' not in atoms[0].custom.keys():
        if species is None:
            raise ValueError(
                "Species was not known! To convert to ase, species need to be provided using the species keyword"
            )
        #otherwise we know the species
        types = [atom.type for atom in atoms]
        unique_types = np.unique(types)
        if not (len(unique_types) == len(species)):
            raise ValueError(
                "Length of species and number of types found in system are different"
            )
        #now assign the species to custom
        for atom in atoms:
            custom = atom.custom
            custom['species'] = species[int(atom.type - 1)]
        #we should also get the unique species key
        specieskey = "".join(species)
    else:
        #now if species are already there in custom
        #we can safely ignore any input
        types = [atom.type for atom in atoms]
        unique_types = np.unique(types)
        #now we know how many types are there
        species = []
        for ut in unique_types:
            for atom in atoms:
                if ut == atom.type:
                    species.append(atom.custom['species'])
                    break
        specieskey = "".join(species)

    cell = sys.get_boxvecs()
    pbc = [1, 1, 1]

    #create ASE Atoms and assign everything
    aseobject = Atoms()
    aseobject.cell = cell
    aseobject.pbc = pbc

    #thats everything pretty much
    #now create ase Atom
    for atom in atoms:
        aseatom = Atom(atom.custom['species'], atom.pos)
        aseobject.append(aseatom)
    #done
    return aseobject
Beispiel #43
0
from ase.build import molecule

a = 5.64  # Lattice constant for NaCl
cell = [a / np.sqrt(2), a / np.sqrt(2), a]
atoms = Atoms(symbols='Na2Cl2',
              pbc=True,
              cell=cell,
              scaled_positions=[(.0, .0, .0), (.5, .5, .5), (.5, .5, .0),
                                (.0, .0, .5)]) * (3, 4, 2) + molecule('C6H6')

# Move molecule to 3.5Ang from surface, and translate one unit cell in xy
atoms.positions[-12:, 2] += atoms.positions[:-12, 2].max() + 3.5
atoms.positions[-12:, :2] += cell[:2]

# Mark a single unit cell
atoms.cell = cell

# View used to start ag, and find desired viewing angle
# view(atoms)
rot = '35x,63y,36z'  # found using ag: 'view -> rotate'

# Common kwargs for eps, png, pov
generic_projection_settings = {
    'rotation': rot,  # text string with rotation (default='' )
    'radii': .85,  # float, or a list with one float per atom
    'colors': None,  # List: one (r, g, b) tuple per atom
    'show_unit_cell': 2,  # 0, 1, or 2 to not show, show, and show all of cell
}

# Extra kwargs only available for povray (All units in angstrom)
povray_settings = {
Beispiel #44
0
def graphene_nanoribbon2(length, width, edge_type='zz', saturated=False, C_H=1.09,
                        C_C=1.42, vacuum=2.5, magnetic=None, initial_mag=1.12,
                        sheet=False, main_element='C', saturate_element='H'):
    """Create a graphene nanoribbon.

    Creates a graphene nanoribbon in the x-z plane, with the nanoribbon
    running along the z axis.

    Parameters:

    n: int
        The width of the nanoribbon.
    m: int
        The length of the nanoribbon.
    type: str
        The orientation of the ribbon.  Must be either 'zigzag'
        or 'armchair'.
    saturated: bool
        If true, hydrogen atoms are placed along the edge.
    C_H: float
        Carbon-hydrogen bond length.  Default: 1.09 Angstrom.
    C_C: float
        Carbon-carbon bond length.  Default: 1.42 Angstrom.
    vacuum: float
        Amount of vacuum added to both sides.  Default 2.5 Angstrom.
    magnetic: bool
        Make the edges magnetic.
    initial_mag: float
        Magnitude of magnetic moment if magnetic=True.
    sheet: bool
        If true, make an infinite sheet instead of a ribbon.
    """

    
    b = np.sqrt(3) * C_C
    ac_unit    =   Atoms(main_element + '2',
                          pbc=(1, 1, 0),
                          cell=[3 * C_C, b, 2 * vacuum])
    
    ac_unit.positions  = [[0, 0, 0],
                          [C_C, 0., 0.]]
    
    ac_sat_unit=   Atoms(saturate_element + '2',
                          pbc=(1, 1, 0),
                          cell=[3 * C_C, b, 2 * vacuum])
    
    ac_sat_unit.positions   =   [[0, 0, 0],
                                 [C_C + C_H, 0, 0]]
    
    
    def slab(m, n):
        atoms = Atoms()
            
        for i in range(n):
            if i % 2 == 0:
                layer   =   ac_unit.repeat((m, 1, 1))
            if i % 2 == 1:
                layer   =   ac_unit.repeat((m, 1, 1))
                layer.positions[:, 0] += 3./2 * C_C
                
            if saturated:
                if i == 0:  
                    sat =   ac_sat_unit.repeat((m,1,1))
                    sat.positions[:,1]  -= np.sqrt(3.) / 2 * C_H
                    sat.positions[:,0]  -= 1. / 2 * C_H
                    layer +=    sat
                elif i == n - 1:    
                    sat =   ac_sat_unit.repeat((m,1,1))
                    sat.positions[:,1]  += np.sqrt(3.) / 2 * C_H 
                    sat.positions[:,0]  -= 1. / 2 * C_H - 3./2 * C_C * (i % 2)
                    layer +=    sat
            
            layer.positions[:, 1] += b / 2 * i
            atoms += layer
        
        xmax    =   np.max(atoms.positions[:,0])
        for atom in atoms:
            if xmax - C_C/2. < atom.position[0]:
                atom.position[0] -=     m*3*C_C 
        
        if saturated:
            xmax    =   np.max(atoms.positions[:,0])
            xmin    =   np.min(atoms.positions[:,0])
            for atom in atoms:
                posit   =   atom.position
                if xmax - C_C/6. < posit[0] and atom.number == 6:
                    h_posit =  [posit[0] + C_H, posit[1], posit[2]]
                    atoms  +=  Atom('H', position = h_posit)  
                if  posit[0] < xmin + C_C/6. and atom.number == 6:
                    h_posit =  [posit[0] - C_H, posit[1], posit[2]]
                    atoms  +=  Atom('H', position = h_posit)  
        
        atoms.cell = [m * 3 * C_C, n * b/2, 2 * vacuum]
        atoms.center()
        return atoms
        
    if edge_type == 'ac':
        return slab(length, width)
    
    elif edge_type == 'zz':
        
        atoms       =   slab(width / 2 + width % 2, length)
        atoms.rotate('-z', np.pi / 2, rotate_cell = False)
        atoms.cell  =   [length* b/2 , (width / 2 + width % 2) * 3 * C_C , 2 * vacuum]
        atoms.center()
        
        if width % 2 == 1:
            atoms_new   =   Atoms()
            cell    =   [length* b/2 , (width / 2 + .5) * 3 * C_C , 2 * vacuum]
            ymax    =   atoms.get_cell()[1,1]
            for atom in atoms:
                if atom.position[1] < ymax - C_C * 3. / 2:
                    atoms_new += atom
                else:   
                    if atom.number == 1 and cell[1] < atom.position[1] - C_C * 3. / 2: 
                        
                        if cell[0]  <   atom.position[0] + b / 2:
                            atom.position[0]    +=   b / 2 - cell[0]
                        else:
                            atom.position[0]    +=   b / 2
                        
                        atom.position[1]        -=   C_C * 3. / 2
                        atoms_new               +=   atom
                    
                    
            atoms_new.cell  =   cell   
        
            return atoms_new
    
        return atoms
Beispiel #45
0
                   (0.0000, 0.0000, -1.1560)]),
   'Be2': ('Be2', [(0.0000, 0.0000, 0.0000),
                   (0.0000, 0.0000, 2.460)])}


c = ase.db.connect('results.db')

for name in ex_atomization.keys() + 'H Li Be B C N O F Cl P'.split():
    id = c.reserve(name=name)
    if id is None:
        continue
        
    if name in extra:
        a = Atoms(*extra[name])
    else:
        a = molecule(name)
        if name in bondlengths:
            a.set_distance(0, 1, bondlengths[name])
    a.cell = [11, 12, 13]
    a.center()
   
    a.calc = GPAW(xc='PBE', mode=PW(500), txt=name + '.txt', dtype=complex)
    a.get_potential_energy()
    
    exx = EXX(a.calc)
    exx.calculate()
    eexx = exx.get_total_energy()

    c.write(a, name=name, exx=eexx)
    del c[id]
    
import numpy as np
from ase import Atoms

a = Atoms('H')
a.center(about=[0., 0., 0.])
print(a.cell)
print(a.positions)

assert not a.cell.any()
assert not a.positions.any()


a.cell = [0., 2., 0.]
a.center()
print(a)
print(a.positions)
assert np.abs(a.positions - [[0., 1., 0.]]).max() < 1e-15

a.center(about=[0., -1., 1.])
print(a.positions)
assert np.abs(a.positions - [[0., -1., 1.]]).max() < 1e-15
assert np.abs(a.cell - np.diag([0., 2., 0.])).max() < 1e-15
a.center(axis=2, vacuum=2.)
print(a.positions)
print(a.cell)
assert np.abs(a.positions - [[0., -1., 2.]]).max() < 1e-15
assert np.abs(a.cell - np.diag([0., 2., 4.])).max() < 1e-15
Beispiel #47
0
def read_ion(fileobj, recover_indices=True, recover_constraints=True):
    text = fileobj.read()
    comments_removed = []
    comments = []
    label = fileobj.name.split('.ion')[0]

    for line in text.splitlines():  # break into lines
        # remove and store the comments
        entry = line.split('#')
        if not entry[0]:
            pass
        else:
            comments_removed.append(entry[0].strip())
        try:
            comments.append(line.split('#')[1])
        except:
            pass
    atoms = Atoms()
    ##################################
    # Parse the unit cell
    ##################################

    """
    because the unit cell is not included in the .ion atomic positions
    file in SPARC, this interface writes the information into the comments
    of .ion files. If a .inpt file is present this code will read that
    if it is not it will attempt to read the comments to find that information.
    The logic for doing this is quite complicated (as seen below)
    """

    inpt_file_usable = True
    lat_vec_speficied = False
    comments_bad = False
    lat_array = []
    # Loop to read cell/latvec from either .inpt or the comment
    # this is pretty complicated
    while True:
        # try to get the unit cell from the .inpt file in the same directory
        if label + '.inpt' in os.listdir('.') and inpt_file_usable == True:
            with open(label + '.inpt', 'r') as f:
                input_file = f.read()
            if 'CELL' not in input_file:
                # We can't find the CELL in the input file
                # set the flag to false and re-run the while loop.
                inpt_file_usable = False
                del input_file
                continue
            input_file = input_file.split('\n')
            for line in input_file:
                if 'CELL' in line:  # find the line with the cell info
                    cell = line.strip().split()[1:]
                    cell = np.array([float(a) for a in cell])
                if 'LATVEC' in line:  # get lattice vectors from next 3 lines
                    lat_vec_speficied = True
                    index = input_file.index(line)
                    for lat_vec in [input_file[a] for a in range(index + 1, index + 4)]:
                        vec = lat_vec.strip().split()
                        vec = np.array([float(a) for a in vec])
                        lat_array.append(
                            vec / np.linalg.norm(vec))  # normalize
                    lat_array = np.array(lat_array)
            if lat_vec_speficied == False:
                lat_array = np.eye(3)
            if 'cell' in locals() and 'lat_array' in locals():
                atoms.cell = (lat_array.T * cell).T * Bohr
                break  # we got the cell, leave the while loop
            else:
                inpt_file_usable = False
                del input_file
                continue

        # if the input file isn't usable, check the comments of the .ion file
        elif comments != [] and comments_bad == False:
            if 'CELL' in comments[1]:  # Check only the second line for a CELL
                cell = np.empty((3, 3))
                try:
                    cell = comments[1].strip().split()[1:]
                    cell = [float(a) for a in cell]
                    for lat_vec in comments[3:6]:  # check only these lines
                        vec = lat_vec.strip().split()
                        vec = np.array([float(a) for a in vec])
                        lat_array.append(
                            vec / np.linalg.norm(vec))  # normalize
                    lat_array = np.array(lat_array)
                    atoms.cell = (lat_array.T * cell).T * Bohr
                    break
                except:
                    comments_bad = True
            else:  # if getting it from the comments fails, return 0 unit cell
                warnings.warn('No lattice vectors were found in either the .inpt'
                              ' file or in the comments of the .ion file. Thus no'
                              ' unit cell was set for the resulting atoms object. '
                              'Use the output atoms at your own risk')
                atoms.cell = np.zeros((3, 3))
                break
        else:  # if there is no cell in the .inpt file, and the .ion file, return 0 unit cell
            warnings.warn('No lattice vectors were found in either the .inpt file '
                          'or in the comments of the .ion file. Thus no unit cell '
                          'was set for the resulting atoms object. Use the output '
                          'atoms at your own risk')
            atoms.cell = np.zeros((3, 3))
            break

    ############################################
    # parse the atoms
    ############################################

    # parse apart the comments to try to recover the indices and boundary conditions

    """
    The strategy of this code is to get the input text separated from the
    comments.

    The comments are then used to glean the information that is
    normally stored in the .inpt file, as well as the original indices
    of the atoms if this file was made by this wrapper.

    from there figure out where the different "Atom Type" blocks are 
    located in the full text with the comments removed. Once that has
    been found parse these sections to gain recover the atomic positions
    and elemental identies of these "atom types."

    We also need to find the locations of the "RELAX" blocks that contain
    the information on which atoms are constained in each "Atom Type"
    block.
    """

    indices_from_comments = []
    constraints = []
    spins = []
    for comment in comments:
        if 'index' in comment:
            if len(comment.split()) == 2:
                try:
                    index = int(comment.split()[1])
                    indices_from_comments.append(index)
                except:
                    pass
        if 'PBC:' in comment:
            pbc_list = []
            pbc = comment.split()[1:]
            for c in pbc:
                if c == 'True' or c == 'true':
                    pbc_list.append(True)
                else:
                    pbc_list.append(False)
            atoms.set_pbc(pbc_list)
            del pbc_list, pbc
    # find the index of line for all the different atom types
    atom_types = [i for i, x in enumerate(
        comments_removed) if 'ATOM_TYPE:' in x]
    relax_blocks = [i for i, x in enumerate(comments_removed) if 'RELAX:' in x]
    spin_blocks = [i for i, x in enumerate(comments_removed) if 'SPIN:' in x]
    for i, atom_type in enumerate(atom_types):
        type_dict = {}
        if i == len(atom_types) - 1:  # treat the last block differently
            # Get the slice of text associated with this atom type
            type_slice = comments_removed[atom_types[i]:]

            # figure out if there are constraints after this block
            if recover_constraints:
                relax_block_index = [a for a in relax_blocks if a > atom_type]
            spin_block_index = [a for a in spin_blocks if a > atom_type]
        else:
            # Get the slice of text associated with this atom type
            type_slice = comments_removed[atom_types[i]: atom_types[i+1]]
            [a for a in relax_blocks if a > atom_type]

            # figure out if there are constraints after this block.
            # the constraint index will be sandwiched between the indicies
            # the current block and the next block
            if recover_constraints:
                relax_block_index = [
                    a for a in relax_blocks if a > atom_types[i]]
                relax_block_index = [
                    a for a in relax_block_index if a < atom_types[i+1]]
            spin_block_index = [a for a in spin_blocks if a > atom_types[i]]
            spin_block_index = [
                a for a in spin_block_index if a < atom_types[i+1]]

        # extract informaton about the atom type from the section header
        for info in ['PSEUDO_POT', 'ATOM_TYPE', 'ATOMIC_MASS', 'COORD',
                     'N_TYPE_ATOM']:
            for line in type_slice[:15]:  # narrow the search for speed
                if info in line:
                    if 'COORD' in line:
                        if 'FRAC' in line:
                            type_dict['COORD_FRAC'] = 1
                        else:
                            type_dict['COORD'] = 1
                    elif 'COORD' not in line:
                        type_dict[info] = line.split()[1]

        # get the lines that contain the constraints block
        if recover_constraints:
            if len(relax_block_index) == 0:
                pass
            elif len(relax_block_index) == 1:
                # offest by one line
                relax_block_index = relax_block_index[0] + 1
                relax_block_end = relax_block_index + \
                    int(type_dict['N_TYPE_ATOM'])
                relax_slice = comments_removed[relax_block_index: relax_block_end]
            elif len(relax_block_index) > 1:
                raise Exception('There appear to be multiple blocks of'
                                ' constraints in one or more of the atom'
                                ' types in your .ion file. Please inspect'
                                ' it to repair it or pass in '
                                '`recover_constraints = False` to ingore'
                                ' constraints')
        # the same as the code above, but for spin
        if len(spin_block_index) == 0:
            pass
        elif len(spin_block_index) == 1:
            spin_block_index = spin_block_index[0] + 1  # offest by one line
            spin_block_end = spin_block_index + int(type_dict['N_TYPE_ATOM'])
            spin_slice = comments_removed[spin_block_index: spin_block_end]
        elif len(spin_block_index) > 1:
            raise Exception('There appear to be multiple blocks of'
                            ' spin values in one or more of the atom'
                            ' types in your .ion file. Please inspect'
                            ' it to repair it or pass in')

        # now parse out the atomic positions
        for coord_set in type_slice[len(type_dict):int(type_dict['N_TYPE_ATOM']) + len(type_dict)]:
            if 'COORD_FRAC' in type_dict.keys():
                x1, x2, x3 = [float(a) for a in coord_set.split()[:3]]
                x, y, z = sum(
                    [x * a for x, a in zip([x1, x2, x3], atoms.cell)])
            elif 'COORD' in type_dict.keys():
                x, y, z = [float(a) * Bohr for a in coord_set.split()[:3]]
            atoms += Atom(symbol=type_dict['ATOM_TYPE'], position=(x, y, z))
        # get the constraints
        if recover_constraints:
            if 'relax_slice' in locals():
                for cons_set in relax_slice:
                    constraints.append([int(a) for a in cons_set.split()])
                del relax_slice
            else:
                # there aren't constraints with this block, put in empty lists
                constraints += [[]] * int(type_dict['N_TYPE_ATOM'])
        if 'spin_slice' in locals():
            for init_spin in spin_slice:
                spins.append(float(init_spin))
            del spin_slice
        else:
            # there aren't spins with this block, put in zeros
            spins += [0] * int(type_dict['N_TYPE_ATOM'])
    # check if we can reorganize the indices
    if len(indices_from_comments) == len(atoms) and recover_indices:
        new_atoms = Atoms(['X'] * len(atoms),
                          positions=[(0, 0, 0)] * len(atoms))
        new_atoms.set_cell(atoms.cell)
        new_spins = [None] * len(atoms)
        # reassign indicies
        for old_index, new_index in enumerate(indices_from_comments):
            new_atoms[new_index].symbol = atoms[old_index].symbol
            new_atoms[new_index].position = atoms[old_index].position
            new_atoms.pbc = atoms.pbc
            new_spins[new_index] = spins[old_index]
        assert new_atoms.get_chemical_formula() == atoms.get_chemical_formula()
        atoms = new_atoms
        spins = new_spins
        # reorganize the constraints now
        if recover_constraints:
            new_constraints = [0] * len(atoms)
            for old_index, new_index in enumerate(indices_from_comments):
                new_constraints[new_index] = constraints[old_index]
            constraints = new_constraints

    atoms.set_initial_magnetic_moments(spins)
    # add constraints
    if recover_constraints:
        constraints = decipher_constraints(constraints)
        atoms.set_constraint(constraints)
    return atoms
Beispiel #48
0
from ase.build import molecule

a = 5.64  # Lattice constant for NaCl
cell = [a / np.sqrt(2), a / np.sqrt(2), a]
atoms = Atoms(symbols='Na2Cl2', pbc=True, cell=cell,
              scaled_positions=[(.0, .0, .0),
                                (.5, .5, .5),
                                (.5, .5, .0),
                                (.0, .0, .5)]) * (3, 4, 2) + molecule('C6H6')

# Move molecule to 3.5Ang from surface, and translate one unit cell in xy
atoms.positions[-12:, 2] += atoms.positions[:-12, 2].max() + 3.5
atoms.positions[-12:, :2] += cell[:2]

# Mark a single unit cell
atoms.cell = cell

# View used to start ag, and find desired viewing angle
#view(atoms)
rot = '35x,63y,36z'  # found using ag: 'view -> rotate'

# Common kwargs for eps, png, pov
kwargs = {
    'rotation'      : rot, # text string with rotation (default='' )
    'radii'         : .85, # float, or a list with one float per atom
    'colors'        : None,# List: one (r, g, b) tuple per atom
    'show_unit_cell': 2,   # 0, 1, or 2 to not show, show, and show all of cell
    }

# Extra kwargs only available for povray (All units in angstrom)
kwargs.update({