Beispiel #1
0
def mx2(formula='MoS2',
        kind='2H',
        a=3.18,
        thickness=3.19,
        size=(1, 1, 1),
        vacuum=7.5):
    """Create three-layer 2D materials with hexagonal structure.

    For metal dichalcogenites, etc.

    The kind argument accepts '2H', which gives a mirror plane symmetry
    and '1T', which gives an inversion symmetry."""

    if kind == '2H':
        basis = [(0, 0, 0), (2 / 3, 1 / 3, 0.5 * thickness),
                 (2 / 3, 1 / 3, -0.5 * thickness)]
    elif kind == '1T':
        basis = [(0, 0, 0), (2 / 3, 1 / 3, 0.5 * thickness),
                 (1 / 3, 2 / 3, -0.5 * thickness)]
    else:
        raise ValueError('Structure not recognized')

    cell = [[a, 0, 0], [-a / 2, a * 3**0.5 / 2, 0], [0, 0, 1]]

    atoms = Atoms(formula, cell=cell, scaled_positions=basis, pbc=(1, 1, 0))
    atoms = atoms.repeat(size)
    atoms.center(vacuum=vacuum, axis=2)

    return atoms
Beispiel #2
0
    def build_system(self, name):
        try:
            # Known molecule or atom?
            atoms = molecule(name)
            if len(atoms) == 2 and self.bond_length is not None:
                atoms.set_distance(0, 1, self.bond_length)
        except NotImplementedError:
            symbols = string2symbols(name)
            if len(symbols) == 1:
                magmom = ground_state_magnetic_moments[atomic_numbers[
                    symbols[0]]]
                atoms = Atoms(name, magmoms=[magmom])
            elif len(symbols) == 2:
                # Dimer
                if self.bond_length is None:
                    b = (covalent_radii[atomic_numbers[symbols[0]]] +
                         covalent_radii[atomic_numbers[symbols[1]]])
                else:
                    b = self.bond_length
                atoms = Atoms(name, positions=[(0, 0, 0), (b, 0, 0)])
            else:
                raise ValueError('Unknown molecule: ' + name)

        if self.unit_cell is None:
            atoms.center(vacuum=self.vacuum)
        else:
            atoms.cell = self.unit_cell
            atoms.center()

        return atoms
Beispiel #3
0
def get_structure(formula, prototype=None, base_dir="./", c=None, **filters):
    db_file = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                           "../c2db.db")
    # Serial version, only on rank 0
    candidates = {}
    # if world.rank == 0:
    db = ase.db.connect(db_file)
    if prototype is None:
        res = db.select(formula=formula, **filters)
    else:
        res = db.select(formula=formula, prototype=prototype)
    for mol in res:
        symbol = mol.formula
        pos = mol.positions
        cell = mol.cell
        pbc = mol.pbc
        # Change distance
        if (c is not None) and (isinstance(c, (float, int))):
            cell.setflags(write=True)
            cell[-1][-1] = c
            pbc = (True, True, True)  # Use full periodic
        name = "{}-{}".format(symbol, mol.prototype)
        # name = os.path.join(os.path.abspath(base_dir),
        # "{}-{}.traj".format(symbol, mol.prototype))
        atoms = Atoms(symbol, positions=pos, cell=cell, pbc=pbc)
        candidates[name] = atoms

        if (c is not None) and (isinstance(c, (float, int))):
            atoms.center()  # center the atoms, although not really needed
    return candidates
Beispiel #4
0
def mx2(formula='MoS2', kind='2H', a=3.18, thickness=3.19,
        size=(1, 1, 1), vacuum=None):
    """Create three-layer 2D materials with hexagonal structure.

    For metal dichalcogenites, etc.

    The kind argument accepts '2H', which gives a mirror plane symmetry
    and '1T', which gives an inversion symmetry."""

    if kind == '2H':
        basis = [(0, 0, 0),
                 (2 / 3, 1 / 3, 0.5 * thickness),
                 (2 / 3, 1 / 3, -0.5 * thickness)]
    elif kind == '1T':
        basis = [(0, 0, 0),
                 (2 / 3, 1 / 3, 0.5 * thickness),
                 (1 / 3, 2 / 3, -0.5 * thickness)]
    else:
        raise ValueError('Structure not recognized:', kind)

    cell = [[a, 0, 0], [-a / 2, a * 3**0.5 / 2, 0], [0, 0, 0]]

    atoms = Atoms(formula, cell=cell, pbc=(1, 1, 0))
    atoms.set_scaled_positions(basis)
    if vacuum is not None:
        atoms.center(vacuum, axis=2)
    atoms = atoms.repeat(size)

    return atoms
Beispiel #5
0
    def build_system(self, name):
        try:
            # Known molecule or atom?
            atoms = molecule(name)
            if len(atoms) == 2 and self.bond_length is not None:
                atoms.set_distance(0, 1, self.bond_length)
        except NotImplementedError:
            symbols = string2symbols(name)
            if len(symbols) == 1:
                Z = atomic_numbers[symbols[0]]
                magmom = ground_state_magnetic_moments[Z]
                atoms = Atoms(name, magmoms=[magmom])
            elif len(symbols) == 2:
                # Dimer
                if self.bond_length is None:
                    b = (covalent_radii[atomic_numbers[symbols[0]]] +
                         covalent_radii[atomic_numbers[symbols[1]]])
                else:
                    b = self.bond_length
                atoms = Atoms(name, positions=[(0, 0, 0),
                                               (b, 0, 0)])
            else:
                raise ValueError('Unknown molecule: ' + name)

        if self.unit_cell is None:
            atoms.center(vacuum=self.vacuum)
        else:
            atoms.cell = self.unit_cell
            atoms.center()

        return atoms
Beispiel #6
0
def graphene(formula='C2', a=2.460, size=(1, 1, 1), vacuum=None):
    """Create a graphene monolayer structure."""
    cell = [[a, 0, 0], [-a / 2, a * 3**0.5 / 2, 0], [0, 0, 0]]
    basis = [[0, 0, 0], [2./3, 1./3, 0]]
    atoms = Atoms(formula, cell=cell, pbc=(1, 1, 0))
    atoms.set_scaled_positions(basis)
    if vacuum is not None:
        atoms.center(vacuum, axis=2)
    atoms = atoms.repeat(size)
    return atoms
Beispiel #7
0
def molecule(name, vacuum=None, **kwargs):
    if name in extra:
        kwargs.update(extra[name])
        mol = Atoms(**kwargs)
    else:
        mol = g2[name]
        if kwargs:
            mol = Atoms(mol, **kwargs)
    if vacuum is not None:
        mol.center(vacuum=vacuum)
    return mol
Beispiel #8
0
    def build_molecule(self, name):
        args = self.args
        try:
            # Known molecule or atom?
            atoms = molecule(name)
        except NotImplementedError:
            symbols = string2symbols(name)
            if len(symbols) == 1:
                Z = atomic_numbers[symbols[0]]
                magmom = ground_state_magnetic_moments[Z]
                atoms = Atoms(name, magmoms=[magmom])
            elif len(symbols) == 2:
                # Dimer
                if args.bond_length is None:
                    b = covalent_radii[atomic_numbers[symbols[0]]] + covalent_radii[atomic_numbers[symbols[1]]]
                else:
                    b = args.bond_length
                atoms = Atoms(name, positions=[(0, 0, 0), (b, 0, 0)])
            else:
                raise ValueError("Unknown molecule: " + name)
        else:
            if len(atoms) == 2 and args.bond_length is not None:
                atoms.set_distance(0, 1, args.bond_length)

        if args.unit_cell is None:
            atoms.center(vacuum=args.vacuum)
        else:
            a = [float(x) for x in args.unit_cell.split(",")]
            if len(a) == 1:
                cell = [a[0], a[0], a[0]]
            elif len(a) == 3:
                cell = a
            else:
                a, b, c, alpha, beta, gamma = a
                degree = np.pi / 180.0
                cosa = np.cos(alpha * degree)
                cosb = np.cos(beta * degree)
                sinb = np.sin(beta * degree)
                cosg = np.cos(gamma * degree)
                sing = np.sin(gamma * degree)
                cell = [
                    [a, 0, 0],
                    [b * cosg, b * sing, 0],
                    [
                        c * cosb,
                        c * (cosa - cosb * cosg) / sing,
                        c * np.sqrt(sinb ** 2 - ((cosa - cosb * cosg) / sing) ** 2),
                    ],
                ]
            atoms.cell = cell
            atoms.center()

        return atoms
Beispiel #9
0
def setup_atom(symbol, vac=3.0, t=0.0, odd=0.0):
    from ase import Atoms
    from ase.data import chemical_symbols, atomic_numbers, ground_state_magnetic_moments
    assert symbol in chemical_symbols
    Z = atomic_numbers[symbol]
    m = ground_state_magnetic_moments[Z]
    atoms = Atoms(symbol)
    atoms.center(vacuum=vac)
    atoms.translate([t,t,t])
    atoms.cell[1][1] += odd
    atoms.cell[2][2] += 2*odd
    atoms.set_initial_magnetic_moments([m])
    return atoms
Beispiel #10
0
def build_molecule(name, opts):
    try:
        # Known molecule or atom?
        atoms = molecule(name)
    except NotImplementedError:
        symbols = string2symbols(name)
        if len(symbols) == 1:
            Z = atomic_numbers[symbols[0]]
            magmom = ground_state_magnetic_moments[Z]
            atoms = Atoms(name, magmoms=[magmom])
        elif len(symbols) == 2:
            # Dimer
            if opts.bond_length is None:
                b = (covalent_radii[atomic_numbers[symbols[0]]] +
                     covalent_radii[atomic_numbers[symbols[1]]])
            else:
                b = opts.bond_length
            atoms = Atoms(name, positions=[(0, 0, 0),
                                           (b, 0, 0)])
        else:
            raise ValueError('Unknown molecule: ' + name)
    else:
        if len(atoms) == 2 and opts.bond_length is not None:
            atoms.set_distance(0, 1, opts.bond_length)

    if opts.unit_cell is None:
        atoms.center(vacuum=opts.vacuum)
    else:
        a = [float(x) for x in opts.unit_cell.split(',')]
        if len(a) == 1:
            cell = [a[0], a[0], a[0]]
        elif len(a) == 3:
            cell = a
        else:
            a, b, c, alpha, beta, gamma = a
            degree = np.pi / 180.0
            cosa = np.cos(alpha * degree)
            cosb = np.cos(beta * degree)
            sinb = np.sin(beta * degree)
            cosg = np.cos(gamma * degree)
            sing = np.sin(gamma * degree)
            cell = [[a, 0, 0],
                    [b * cosg, b * sing, 0],
                    [c * cosb, c * (cosa - cosb * cosg) / sing,
                     c * np.sqrt(
                        sinb**2 - ((cosa - cosb * cosg) / sing)**2)]]
        atoms.cell = cell
        atoms.center()

    return atoms
Beispiel #11
0
def test_md(cp2k_factory):
    calc = cp2k_factory.calc(label='test_H2_MD')
    positions = [(0, 0, 0), (0, 0, 0.7245595)]
    atoms = Atoms('HH', positions=positions, calculator=calc)
    atoms.center(vacuum=2.0)

    MaxwellBoltzmannDistribution(atoms, temperature_K=0.5 * 300,
                                 force_temp=True)
    energy_start = atoms.get_potential_energy() + atoms.get_kinetic_energy()
    with VelocityVerlet(atoms, 0.5 * units.fs) as dyn:
        dyn.run(20)

    energy_end = atoms.get_potential_energy() + atoms.get_kinetic_energy()
    assert abs(energy_start - energy_end) < 1e-4
Beispiel #12
0
def molecule(name, vacuum=None, **kwargs):
    """Create an atomic structure from a database.

    This is a helper function to easily create molecules from the g2 and
    extra databases.

    Parameters
    ----------
    name : str
        Name of the molecule to build.
    vacuum : float, optional
        Amount of vacuum to pad the molecule with on all sides.
    Additional keyword arguments (kwargs) can be supplied, which are passed
    to ase.Atoms.

    Returns
    -------
    ase.atoms.Atoms
        An ASE Atoms object corresponding to the specified molecule.

    Notes
    -----
    To see a list of allowed names, try:

    >>> from ase.collections import g2
    >>> print(g2.names)
    >>> from ase.build.molecule import extra
    >>> print(extra.keys())

    Examples
    --------
    >>> from ase.build import molecule
    >>> atoms = molecule('H2O')

    """
    if name in extra:
        kwargs.update(extra[name])
        mol = Atoms(**kwargs)
    else:
        mol = g2[name]
        if kwargs:
            mol = Atoms(mol, **kwargs)
    if vacuum is not None:
        mol.center(vacuum=vacuum)
    return mol
Beispiel #13
0
def test_md(cp2k_factory):
    calc = cp2k_factory.calc(label='test_H2_MD')
    positions = [(0, 0, 0), (0, 0, 0.7245595)]
    atoms = Atoms('HH', positions=positions, calculator=calc)
    atoms.center(vacuum=2.0)

    # Run MD
    MaxwellBoltzmannDistribution(atoms, 0.5 * 300 * units.kB, force_temp=True)
    energy_start = atoms.get_potential_energy() + atoms.get_kinetic_energy()
    dyn = VelocityVerlet(atoms, 0.5 * units.fs)
    #def print_md():
    #    energy = atoms.get_potential_energy() + atoms.get_kinetic_energy()
    #    print("MD total-energy: %.10feV" %  energy)
    #dyn.attach(print_md, interval=1)
    dyn.run(20)

    energy_end = atoms.get_potential_energy() + atoms.get_kinetic_energy()

    assert energy_start - energy_end < 1e-4
    print('passed test "H2_MD"')
Beispiel #14
0
def main():
    if "ASE_CP2K_COMMAND" not in os.environ:
        raise NotAvailable('$ASE_CP2K_COMMAND not defined')

    calc = CP2K(label='test_H2_MD')
    positions = [(0, 0, 0), (0, 0, 0.7245595)]
    atoms = Atoms('HH', positions=positions, calculator=calc)
    atoms.center(vacuum=2.0)

    # Run MD
    MaxwellBoltzmannDistribution(atoms, 0.5 * 300 * units.kB, force_temp=True)
    energy_start = atoms.get_potential_energy() + atoms.get_kinetic_energy()
    dyn = VelocityVerlet(atoms, 0.5 * units.fs)
    #def print_md():
    #    energy = atoms.get_potential_energy() + atoms.get_kinetic_energy()
    #    print("MD total-energy: %.10feV" %  energy)
    #dyn.attach(print_md, interval=1)
    dyn.run(20)

    energy_end = atoms.get_potential_energy() + atoms.get_kinetic_energy()

    assert energy_start - energy_end < 1e-4
    print('passed test "H2_MD"')
Beispiel #15
0
def main():
    if "ASE_CP2K_COMMAND" not in os.environ:
        raise NotAvailable('$ASE_CP2K_COMMAND not defined')

    calc = CP2K(label='test_H2_MD')
    positions = [(0, 0, 0), (0, 0, 0.7245595)]
    atoms = Atoms('HH', positions=positions, calculator=calc)
    atoms.center(vacuum=2.0)

    # Run MD
    MaxwellBoltzmannDistribution(atoms, 0.5 * 300 * units.kB, force_temp=True)
    energy_start = atoms.get_potential_energy() + atoms.get_kinetic_energy()
    dyn = VelocityVerlet(atoms, 0.5 * units.fs)
    #def print_md():
    #    energy = atoms.get_potential_energy() + atoms.get_kinetic_energy()
    #    print("MD total-energy: %.10feV" %  energy)
    #dyn.attach(print_md, interval=1)
    dyn.run(20)

    energy_end = atoms.get_potential_energy() + atoms.get_kinetic_energy()

    assert energy_start - energy_end < 1e-4
    print('passed test "H2_MD"')
Beispiel #16
0
def graphene_nanoribbon(n,
                        m,
                        type='zigzag',
                        saturated=False,
                        C_H=1.09,
                        C_C=1.42,
                        vacuum=None,
                        magnetic=False,
                        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.  For armchair nanoribbons, this
        n may be half-integer to repeat by half a cell.
    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: None (default) or float
        Amount of vacuum added to non-periodic directions, if present.
    magnetic: bool
        Make the edges magnetic.
    initial_mag: float
        Magnitude of magnetic moment if magnetic.
    sheet: bool
        If true, make an infinite sheet instead of a ribbon (default: False)
    """

    if m % 1 != 0:
        raise ValueError('m must be integer')
    if type == 'zigzag' and n % 1 != 0:
        raise ValueError('n must be an integer for zigzag ribbons')

    b = sqrt(3) * C_C / 4
    arm_unit = Atoms(main_element + '4',
                     pbc=(1, 0, 1),
                     cell=[4 * b, 0, 3 * C_C])
    arm_unit.positions = [[0, 0, 0], [b * 2, 0, C_C / 2.],
                          [b * 2, 0, 3 * C_C / 2.], [0, 0, 2 * C_C]]
    arm_unit_half = Atoms(main_element + '2',
                          pbc=(1, 0, 1),
                          cell=[2 * b, 0, 3 * C_C])
    arm_unit_half.positions = [[b * 2, 0, C_C / 2.], [b * 2, 0, 3 * C_C / 2.]]
    zz_unit = Atoms(main_element + '2',
                    pbc=(1, 0, 1),
                    cell=[3 * C_C / 2.0, 0, b * 4])
    zz_unit.positions = [[0, 0, 0], [C_C / 2.0, 0, b * 2]]
    atoms = Atoms()

    if type == 'zigzag':
        edge_index0 = np.arange(m) * 2
        edge_index1 = (n - 1) * m * 2 + np.arange(m) * 2 + 1

        if magnetic:
            mms = np.zeros(m * n * 2)
            for i in edge_index0:
                mms[i] = initial_mag
            for i in edge_index1:
                mms[i] = -initial_mag

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

        xmin = atoms.positions[0, 0]

        if magnetic:
            atoms.set_initial_magnetic_moments(mms)
        if saturated:
            H_atoms0 = Atoms(saturate_element + str(m))
            H_atoms0.positions = atoms[edge_index0].positions
            H_atoms0.positions[:, 0] -= C_H
            H_atoms1 = Atoms(saturate_element + str(m))
            H_atoms1.positions = atoms[edge_index1].positions
            H_atoms1.positions[:, 0] += C_H
            atoms += H_atoms0 + H_atoms1
        atoms.cell = [n * 3 * C_C / 2, 0, m * 4 * b]

    elif type == 'armchair':
        n *= 2
        n_int = int(round(n))
        if abs(n_int - n) > 1e-10:
            raise ValueError(
                'The argument n has to be half-integer for armchair ribbons.')
        n = n_int

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

        xmin = atoms.positions[-1, 0]

        if saturated:
            if n % 2:
                arm_right_saturation = Atoms(saturate_element + '2',
                                             pbc=(1, 0, 1),
                                             cell=[2 * b, 0, 3 * C_C])
                arm_right_saturation.positions = [[
                    -sqrt(3) / 2 * C_H, 0, C_C / 2 - C_H * 0.5
                ], [-sqrt(3) / 2 * C_H, 0, 3 * C_C / 2.0 + C_H * 0.5]]
            else:
                arm_right_saturation = Atoms(saturate_element + '2',
                                             pbc=(1, 0, 1),
                                             cell=[4 * b, 0, 3 * C_C])
                arm_right_saturation.positions = [[
                    -sqrt(3) / 2 * C_H, 0, C_H * 0.5
                ], [-sqrt(3) / 2 * C_H, 0, 2 * C_C - C_H * 0.5]]
            arm_left_saturation = Atoms(saturate_element + '2',
                                        pbc=(1, 0, 1),
                                        cell=[4 * b, 0, 3 * C_C])
            arm_left_saturation.positions = [[
                b * 2 + sqrt(3) / 2 * C_H, 0, C_C / 2 - C_H * 0.5
            ], [b * 2 + sqrt(3) / 2 * C_H, 0, 3 * C_C / 2.0 + C_H * 0.5]]
            arm_right_saturation.positions[:, 0] -= 4 * b * (n / 2.0 - 1)

            atoms += arm_right_saturation.repeat((1, 1, m))
            atoms += arm_left_saturation.repeat((1, 1, m))

        atoms.cell = [b * 4 * n / 2.0, 0, 3 * C_C * m]

    atoms.set_pbc([sheet, False, True])

    # The ribbon was 'built' from x=0 towards negative x.
    # Move the ribbon to positive x:
    atoms.positions[:, 0] -= xmin
    if not sheet:
        atoms.cell[0] = 0.0
    if vacuum is not None:
        atoms.center(vacuum, axis=1)
        if not sheet:
            atoms.center(vacuum, axis=0)
    return atoms
Beispiel #17
0
def graphene_nanoribbon(n,
                        m,
                        type='zigzag',
                        saturated=False,
                        C_H=1.09,
                        C_C=1.42,
                        vacuum=None,
                        magnetic=False,
                        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: None (default) or float
        Amount of vacuum added to non-periodic directions, if present.
    magnetic: bool
        Make the edges magnetic.
    initial_mag: float
        Magnitude of magnetic moment if magnetic.
    sheet: bool
        If true, make an infinite sheet instead of a ribbon (default: False)
    """

    b = sqrt(3) * C_C / 4
    arm_unit = Atoms(main_element + '4',
                     pbc=(1, 0, 1),
                     cell=[4 * b, 0, 3 * C_C])
    arm_unit.positions = [[0, 0, 0], [b * 2, 0, C_C / 2.],
                          [b * 2, 0, 3 * C_C / 2.], [0, 0, 2 * C_C]]
    zz_unit = Atoms(main_element + '2',
                    pbc=(1, 0, 1),
                    cell=[3 * C_C / 2.0, 0, b * 4])
    zz_unit.positions = [[0, 0, 0], [C_C / 2.0, 0, b * 2]]
    atoms = Atoms()

    if type == 'zigzag':
        edge_index0 = np.arange(m) * 2 + 1
        edge_index1 = (n - 1) * m * 2 + np.arange(m) * 2
        if magnetic:
            mms = np.zeros(m * n * 2)
            for i in edge_index0:
                mms[i] = initial_mag
            for i in edge_index1:
                mms[i] = -initial_mag

        for i in range(n):
            layer = zz_unit.repeat((1, 1, m))
            layer.positions[:, 0] -= 3 * C_C / 2 * i
            if i % 2 == 1:
                layer.positions[:, 2] += 2 * b
                layer[-1].position[2] -= b * 4 * m
            atoms += layer
        if magnetic:
            atoms.set_initial_magnetic_moments(mms)
        if saturated:
            H_atoms0 = Atoms(saturate_element + str(m))
            H_atoms0.positions = atoms[edge_index0].positions
            H_atoms0.positions[:, 0] += C_H
            H_atoms1 = Atoms(saturate_element + str(m))
            H_atoms1.positions = atoms[edge_index1].positions
            H_atoms1.positions[:, 0] -= C_H
            atoms += H_atoms0 + H_atoms1
        atoms.cell = [n * 3 * C_C / 2, 0, m * 4 * b]

    elif type == 'armchair':
        for i in range(n):
            layer = arm_unit.repeat((1, 1, m))
            layer.positions[:, 0] -= 4 * b * i
            atoms += layer
        if saturated:
            arm_right_saturation = Atoms(saturate_element + '2',
                                         pbc=(1, 0, 1),
                                         cell=[4 * b, 0, 3 * C_C])
            arm_right_saturation.positions = [[
                -sqrt(3) / 2 * C_H, 0, C_H * 0.5
            ], [-sqrt(3) / 2 * C_H, 0, 2 * C_C - C_H * 0.5]]
            arm_left_saturation = Atoms(saturate_element + '2',
                                        pbc=(1, 0, 1),
                                        cell=[4 * b, 0, 3 * C_C])
            arm_left_saturation.positions = [[
                b * 2 + sqrt(3) / 2 * C_H, 0, C_C / 2 - C_H * 0.5
            ], [b * 2 + sqrt(3) / 2 * C_H, 0, 3 * C_C / 2.0 + C_H * 0.5]]
            arm_right_saturation.positions[:, 0] -= 4 * b * (n - 1)
            atoms += arm_right_saturation.repeat((1, 1, m))
            atoms += arm_left_saturation.repeat((1, 1, m))

        atoms.cell = [b * 4 * n, 0, 3 * C_C * m]

    atoms.set_pbc([sheet, False, True])
    atoms.set_scaled_positions(atoms.get_scaled_positions() % 1.0)
    if not sheet:
        atoms.cell[0] = 0.0
    if vacuum:
        atoms.center(vacuum, axis=1)
        if not sheet:
            atoms.center(vacuum, axis=0)
    return atoms
Beispiel #18
0
def surface(symbol, structure, face, size, a, c, vacuum, orthogonal=True):
    """Function to build often used surfaces.

    Don't call this function directly - use fcc100, fcc110, bcc111, ..."""

    Z = atomic_numbers[symbol]

    if a is None:
        sym = reference_states[Z]['symmetry'].lower()
        if sym != structure:
            raise ValueError("Can't guess lattice constant for %s-%s!" %
                             (structure, symbol))
        a = reference_states[Z]['a']

    if structure == 'hcp' and c is None:
        if reference_states[Z]['symmetry'].lower() == 'hcp':
            c = reference_states[Z]['c/a'] * a
        else:
            c = sqrt(8 / 3.0) * a

    positions = np.empty((size[2], size[1], size[0], 3))
    positions[..., 0] = np.arange(size[0]).reshape((1, 1, -1))
    positions[..., 1] = np.arange(size[1]).reshape((1, -1, 1))
    positions[..., 2] = np.arange(size[2]).reshape((-1, 1, 1))

    numbers = np.ones(size[0] * size[1] * size[2], int) * Z

    tags = np.empty((size[2], size[1], size[0]), int)
    tags[:] = np.arange(size[2], 0, -1).reshape((-1, 1, 1))

    slab = Atoms(numbers,
                 tags=tags.ravel(),
                 pbc=(True, True, False),
                 cell=size)

    surface_cell = None
    sites = {'ontop': (0, 0)}
    surf = structure + face
    if surf == 'fcc100':
        cell = (sqrt(0.5), sqrt(0.5), 0.5)
        positions[-2::-2, ..., :2] += 0.5
        sites.update({'hollow': (0.5, 0.5), 'bridge': (0.5, 0)})
    elif surf == 'fcc110':
        cell = (1.0, sqrt(0.5), sqrt(0.125))
        positions[-2::-2, ..., :2] += 0.5
        sites.update({
            'hollow': (0.5, 0.5),
            'longbridge': (0.5, 0),
            'shortbridge': (0, 0.5)
        })
    elif surf == 'bcc100':
        cell = (1.0, 1.0, 0.5)
        positions[-2::-2, ..., :2] += 0.5
        sites.update({'hollow': (0.5, 0.5), 'bridge': (0.5, 0)})
    else:
        if orthogonal and size[1] % 2 == 1:
            raise ValueError(("Can't make orthorhombic cell with size=%r.  " %
                              (tuple(size), )) +
                             'Second number in size must be even.')
        if surf == 'fcc111':
            cell = (sqrt(0.5), sqrt(0.375), 1 / sqrt(3))
            if orthogonal:
                positions[-1::-3, 1::2, :, 0] += 0.5
                positions[-2::-3, 1::2, :, 0] += 0.5
                positions[-3::-3, 1::2, :, 0] -= 0.5
                positions[-2::-3, ..., :2] += (0.0, 2.0 / 3)
                positions[-3::-3, ..., :2] += (0.5, 1.0 / 3)
            else:
                positions[-2::-3, ..., :2] += (-1.0 / 3, 2.0 / 3)
                positions[-3::-3, ..., :2] += (1.0 / 3, 1.0 / 3)
            sites.update({
                'bridge': (0.5, 0),
                'fcc': (1.0 / 3, 1.0 / 3),
                'hcp': (2.0 / 3, 2.0 / 3)
            })
        elif surf == 'hcp0001':
            cell = (1.0, sqrt(0.75), 0.5 * c / a)
            if orthogonal:
                positions[:, 1::2, :, 0] += 0.5
                positions[-2::-2, ..., :2] += (0.0, 2.0 / 3)
            else:
                positions[-2::-2, ..., :2] += (-1.0 / 3, 2.0 / 3)
            sites.update({
                'bridge': (0.5, 0),
                'fcc': (1.0 / 3, 1.0 / 3),
                'hcp': (2.0 / 3, 2.0 / 3)
            })
        elif surf == 'bcc110':
            cell = (1.0, sqrt(0.5), sqrt(0.5))
            if orthogonal:
                positions[:, 1::2, :, 0] += 0.5
                positions[-2::-2, ..., :2] += (0.0, 1.0)
            else:
                positions[-2::-2, ..., :2] += (-0.5, 1.0)
            sites.update({
                'shortbridge': (0, 0.5),
                'longbridge': (0.5, 0),
                'hollow': (0.375, 0.25)
            })
        elif surf == 'bcc111':
            cell = (sqrt(2), sqrt(1.5), sqrt(3) / 6)
            if orthogonal:
                positions[-1::-3, 1::2, :, 0] += 0.5
                positions[-2::-3, 1::2, :, 0] += 0.5
                positions[-3::-3, 1::2, :, 0] -= 0.5
                positions[-2::-3, ..., :2] += (0.0, 2.0 / 3)
                positions[-3::-3, ..., :2] += (0.5, 1.0 / 3)
            else:
                positions[-2::-3, ..., :2] += (-1.0 / 3, 2.0 / 3)
                positions[-3::-3, ..., :2] += (1.0 / 3, 1.0 / 3)
            sites.update({'hollow': (1.0 / 3, 1.0 / 3)})

        surface_cell = a * np.array([(cell[0], 0), (cell[0] / 2, cell[1])])
        if not orthogonal:
            cell = np.array([(cell[0], 0, 0), (cell[0] / 2, cell[1], 0),
                             (0, 0, cell[2])])

    if surface_cell is None:
        surface_cell = a * np.diag(cell[:2])

    if isinstance(cell, tuple):
        cell = np.diag(cell)

    slab.set_positions(positions.reshape((-1, 3)))

    slab.set_cell([a * v * n for v, n in zip(cell, size)], scale_atoms=True)

    if vacuum is not None:
        slab.center(vacuum=vacuum, axis=2)

    slab.adsorbate_info['cell'] = surface_cell
    slab.adsorbate_info['sites'] = sites

    return slab
Beispiel #19
0
def nanotube(n,
             m,
             length=1,
             bond=1.42,
             symbol='C',
             verbose=False,
             vacuum=None):
    """Create an atomic structure.

    Creates a single-walled nanotube whose structure is specified using the
    standardized (n, m) notation.

    Parameters
    ----------
    n : int
        n in the (n, m) notation.
    m : int
        m in the (n, m) notation.
    length : int, optional
        Length (axial repetitions) of the nanotube.
    bond : float, optional
        Bond length between neighboring atoms.
    symbol : str, optional
        Chemical element to construct the nanotube from.
    verbose : bool, optional
        If True, will display key geometric parameters.

    Returns
    -------
    ase.atoms.Atoms
        An ASE Atoms object corresponding to the specified molecule.

    Examples
    --------
    >>> from ase.build import nanotube
    >>> atoms1 = nanotube(6, 0, length=4)
    >>> atoms2 = nanotube(3, 3, length=6, bond=1.4, symbol='Si')
    """
    if n < m:
        m, n = n, m
        sign = -1
    else:
        sign = 1

    nk = 6000
    sq3 = sqrt(3.0)
    a = sq3 * bond
    l2 = n * n + m * m + n * m
    l = sqrt(l2)

    nd = gcd(n, m)
    if (n - m) % (3 * nd) == 0:
        ndr = 3 * nd
    else:
        ndr = nd

    nr = (2 * m + n) // ndr
    ns = -(2 * n + m) // ndr
    nn = 2 * l2 // ndr

    ichk = 0
    if nr == 0:
        n60 = 1
    else:
        n60 = nr * 4

    absn = abs(n60)
    nnp = []
    nnq = []
    for i in range(-absn, absn + 1):
        for j in range(-absn, absn + 1):
            j2 = nr * j - ns * i
            if j2 == 1:
                j1 = m * i - n * j
                if j1 > 0 and j1 < nn:
                    ichk += 1
                    nnp.append(i)
                    nnq.append(j)

    if ichk == 0:
        raise RuntimeError('not found p, q strange!!')
    if ichk >= 2:
        raise RuntimeError('more than 1 pair p, q strange!!')

    nnnp = nnp[0]
    nnnq = nnq[0]

    if verbose:
        print('the symmetry vector is', nnnp, nnnq)

    lp = nnnp * nnnp + nnnq * nnnq + nnnp * nnnq
    r = a * sqrt(lp)
    c = a * l
    t = sq3 * c / ndr

    if 2 * nn > nk:
        raise RuntimeError('parameter nk is too small!')

    rs = c / (2.0 * np.pi)

    if verbose:
        print('radius=', rs, t)

    q1 = np.arctan((sq3 * m) / (2 * n + m))
    q2 = np.arctan((sq3 * nnnq) / (2 * nnnp + nnnq))
    q3 = q1 - q2

    q4 = 2.0 * np.pi / nn
    q5 = bond * np.cos((np.pi / 6.0) - q1) / c * 2.0 * np.pi

    h1 = abs(t) / abs(np.sin(q3))
    h2 = bond * np.sin((np.pi / 6.0) - q1)

    ii = 0
    x, y, z = [], [], []
    for i in range(nn):
        x1, y1, z1 = 0, 0, 0

        k = np.floor(i * abs(r) / h1)
        x1 = rs * np.cos(i * q4)
        y1 = rs * np.sin(i * q4)
        z1 = (i * abs(r) - k * h1) * np.sin(q3)
        kk2 = abs(np.floor((z1 + 0.0001) / t))
        if z1 >= t - 0.0001:
            z1 -= t * kk2
        elif z1 < 0:
            z1 += t * kk2
        ii += 1

        x.append(x1)
        y.append(y1)
        z.append(z1)
        z3 = (i * abs(r) - k * h1) * np.sin(q3) - h2
        ii += 1

        if z3 >= 0 and z3 < t:
            x2 = rs * np.cos(i * q4 + q5)
            y2 = rs * np.sin(i * q4 + q5)
            z2 = (i * abs(r) - k * h1) * np.sin(q3) - h2
            x.append(x2)
            y.append(y2)
            z.append(z2)
        else:
            x2 = rs * np.cos(i * q4 + q5)
            y2 = rs * np.sin(i * q4 + q5)
            z2 = (i * abs(r) - (k + 1) * h1) * np.sin(q3) - h2
            kk = abs(np.floor(z2 / t))
            if z2 >= t - 0.0001:
                z2 -= t * kk
            elif z2 < 0:
                z2 += t * kk
            x.append(x2)
            y.append(y2)
            z.append(z2)

    ntotal = 2 * nn
    X = []
    for i in range(ntotal):
        X.append([x[i], y[i], sign * z[i]])

    if length > 1:
        xx = X[:]
        for mnp in range(2, length + 1):
            for i in range(len(xx)):
                X.append(xx[i][:2] + [xx[i][2] + (mnp - 1) * t])

    transvec = t
    numatom = ntotal * length
    diameter = rs * 2
    chiralangle = np.arctan((sq3 * n) / (2 * m + n)) / np.pi * 180

    cell = [[0, 0, 0], [0, 0, 0], [0, 0, length * t]]
    atoms = Atoms(symbol + str(numatom),
                  positions=X,
                  cell=cell,
                  pbc=[False, False, True])
    if vacuum:
        atoms.center(vacuum, axis=(0, 1))
    if verbose:
        print('translation vector =', transvec)
        print('diameter = ', diameter)
        print('chiral angle = ', chiralangle)
    return atoms
Beispiel #20
0
def _surface(symbol, structure, face, size, a, c, vacuum, orthogonal=True):
    """Function to build often used surfaces.

    Don't call this function directly - use fcc100, fcc110, bcc111, ..."""
    
    Z = atomic_numbers[symbol]

    if a is None:
        sym = reference_states[Z]['symmetry']
        if sym != structure:
            raise ValueError("Can't guess lattice constant for %s-%s!" %
                             (structure, symbol))
        a = reference_states[Z]['a']

    if structure == 'hcp' and c is None:
        if reference_states[Z]['symmetry'] == 'hcp':
            c = reference_states[Z]['c/a'] * a
        else:
            c = sqrt(8 / 3.0) * a

    positions = np.empty((size[2], size[1], size[0], 3))
    positions[..., 0] = np.arange(size[0]).reshape((1, 1, -1))
    positions[..., 1] = np.arange(size[1]).reshape((1, -1, 1))
    positions[..., 2] = np.arange(size[2]).reshape((-1, 1, 1))

    numbers = np.ones(size[0] * size[1] * size[2], int) * Z

    tags = np.empty((size[2], size[1], size[0]), int)
    tags[:] = np.arange(size[2], 0, -1).reshape((-1, 1, 1))

    slab = Atoms(numbers,
                 tags=tags.ravel(),
                 pbc=(True, True, False),
                 cell=size)

    surface_cell = None
    sites = {'ontop': (0, 0)}
    surf = structure + face
    if surf == 'fcc100':
        cell = (sqrt(0.5), sqrt(0.5), 0.5)
        positions[-2::-2, ..., :2] += 0.5
        sites.update({'hollow': (0.5, 0.5), 'bridge': (0.5, 0)})
    elif surf == 'diamond100':
        cell = (sqrt(0.5), sqrt(0.5), 0.5 / 2)
        positions[-4::-4, ..., :2] += (0.5, 0.5)
        positions[-3::-4, ..., :2] += (0.0, 0.5)
        positions[-2::-4, ..., :2] += (0.0, 0.0)
        positions[-1::-4, ..., :2] += (0.5, 0.0)
    elif surf == 'fcc110':
        cell = (1.0, sqrt(0.5), sqrt(0.125))
        positions[-2::-2, ..., :2] += 0.5
        sites.update({'hollow': (0.5, 0.5), 'longbridge': (0.5, 0),
                      'shortbridge': (0, 0.5)})
    elif surf == 'bcc100':
        cell = (1.0, 1.0, 0.5)
        positions[-2::-2, ..., :2] += 0.5
        sites.update({'hollow': (0.5, 0.5), 'bridge': (0.5, 0)})
    else:
        if orthogonal and size[1] % 2 == 1:
            raise ValueError(("Can't make orthorhombic cell with size=%r.  " %
                              (tuple(size),)) +
                             'Second number in size must be even.')
        if surf == 'fcc111':
            cell = (sqrt(0.5), sqrt(0.375), 1 / sqrt(3))
            if orthogonal:
                positions[-1::-3, 1::2, :, 0] += 0.5
                positions[-2::-3, 1::2, :, 0] += 0.5
                positions[-3::-3, 1::2, :, 0] -= 0.5
                positions[-2::-3, ..., :2] += (0.0, 2.0 / 3)
                positions[-3::-3, ..., :2] += (0.5, 1.0 / 3)
            else:
                positions[-2::-3, ..., :2] += (-1.0 / 3, 2.0 / 3)
                positions[-3::-3, ..., :2] += (1.0 / 3, 1.0 / 3)
            sites.update({'bridge': (0.5, 0), 'fcc': (1.0 / 3, 1.0 / 3),
                          'hcp': (2.0 / 3, 2.0 / 3)})
        elif surf == 'diamond111':
            cell = (sqrt(0.5), sqrt(0.375), 1 / sqrt(3) / 2)
            assert not orthogonal
            positions[-1::-6, ..., :3] += (0.0, 0.0, 0.5)
            positions[-2::-6, ..., :2] += (0.0, 0.0)
            positions[-3::-6, ..., :3] += (-1.0 / 3, 2.0 / 3, 0.5)
            positions[-4::-6, ..., :2] += (-1.0 / 3, 2.0 / 3)
            positions[-5::-6, ..., :3] += (1.0 / 3, 1.0 / 3, 0.5)
            positions[-6::-6, ..., :2] += (1.0 / 3, 1.0 / 3)
        elif surf == 'hcp0001':
            cell = (1.0, sqrt(0.75), 0.5 * c / a)
            if orthogonal:
                positions[:, 1::2, :, 0] += 0.5
                positions[-2::-2, ..., :2] += (0.0, 2.0 / 3)
            else:
                positions[-2::-2, ..., :2] += (-1.0 / 3, 2.0 / 3)
            sites.update({'bridge': (0.5, 0), 'fcc': (1.0 / 3, 1.0 / 3),
                          'hcp': (2.0 / 3, 2.0 / 3)})
        elif surf == 'hcp10m10':
            cell = (1.0, 0.5 * c / a, sqrt(0.75))
            assert orthogonal
            positions[-2::-2, ..., 0] += 0.5
            positions[:, ::2, :, 2] += 2.0 / 3
        elif surf == 'bcc110':
            cell = (1.0, sqrt(0.5), sqrt(0.5))
            if orthogonal:
                positions[:, 1::2, :, 0] += 0.5
                positions[-2::-2, ..., :2] += (0.0, 1.0)
            else:
                positions[-2::-2, ..., :2] += (-0.5, 1.0)
            sites.update({'shortbridge': (0, 0.5),
                          'longbridge': (0.5, 0),
                          'hollow': (0.375, 0.25)})
        elif surf == 'bcc111':
            cell = (sqrt(2), sqrt(1.5), sqrt(3) / 6)
            if orthogonal:
                positions[-1::-3, 1::2, :, 0] += 0.5
                positions[-2::-3, 1::2, :, 0] += 0.5
                positions[-3::-3, 1::2, :, 0] -= 0.5
                positions[-2::-3, ..., :2] += (0.0, 2.0 / 3)
                positions[-3::-3, ..., :2] += (0.5, 1.0 / 3)
            else:
                positions[-2::-3, ..., :2] += (-1.0 / 3, 2.0 / 3)
                positions[-3::-3, ..., :2] += (1.0 / 3, 1.0 / 3)
            sites.update({'hollow': (1.0 / 3, 1.0 / 3)})
        else:
            2 / 0
            
        surface_cell = a * np.array([(cell[0], 0),
                                     (cell[0] / 2, cell[1])])
        if not orthogonal:
            cell = np.array([(cell[0], 0, 0),
                             (cell[0] / 2, cell[1], 0),
                             (0, 0, cell[2])])

    if surface_cell is None:
        surface_cell = a * np.diag(cell[:2])

    if isinstance(cell, tuple):
        cell = np.diag(cell)
        
    slab.set_positions(positions.reshape((-1, 3)))

    slab.set_cell([a * v * n for v, n in zip(cell, size)], scale_atoms=True)

    if vacuum is not None:
        slab.center(vacuum=vacuum, axis=2)
    
    slab.adsorbate_info['cell'] = surface_cell
    slab.adsorbate_info['sites'] = sites
    
    return slab
Beispiel #21
0
import numpy as np

debug = False
use_hdf5 = True

try:
    import _gpaw_hdf5
    restart_file = 'Al2_gs.hdf5'
except ImportError:
    restart_file = 'Al2_gs.gpw'

d = 2.563
atoms = Atoms('Al2', positions=((0, 0, 0),
                                (0, 0, d))
             )
atoms.center(4.0)
calc = GPAW(h=0.24, eigensolver='cg', basis='dzp',
            occupations=FermiDirac(width=0.01),
            convergence={'eigenstates': 4.0e-5, 'density' : 1.0e-2, 
                         'bands' : 'all'},
            nbands=20)
atoms.set_calculator(calc)
atoms.get_potential_energy()
calc.write(restart_file, mode='all')

# Try to run parallel over eh-pairs
if size % 2 == 0:
    eh_size = 2
    domain_size = size // eh_size
else:
    eh_size = 1
Beispiel #22
0
def nanotube(n, m, length=1, bond=1.42, symbol='C', verbose=False):
    if n < m:
        m, n = n, m
        sign = -1
    else:
        sign = 1

    nk = 6000
    sq3 = sqrt(3.0)
    a = sq3 * bond
    l2 = n * n + m * m + n * m
    l = sqrt(l2)

    nd = gcd(n, m)
    if (n - m) % (3 * nd) == 0:
        ndr = 3 * nd
    else:
        ndr = nd

    nr = (2 * m + n) / ndr
    ns = -(2 * n + m) / ndr
    nn = 2 * l2 / ndr

    ichk = 0
    if nr == 0:
        n60 = 1
    else:
        n60 = nr * 4

    absn = abs(n60)
    nnp = []
    nnq = []
    for i in range(-absn, absn + 1):
        for j in range(-absn, absn + 1):
            j2 = nr * j - ns * i
            if j2 == 1:
                j1 = m * i - n * j
                if j1 > 0 and j1 < nn:
                    ichk += 1
                    nnp.append(i)
                    nnq.append(j)

    if ichk == 0:
        raise RuntimeError('not found p, q strange!!')
    if ichk >= 2:
        raise RuntimeError('more than 1 pair p, q strange!!')

    nnnp = nnp[0]
    nnnq = nnq[0]

    if verbose:
        print 'the symmetry vector is', nnnp, nnnq

    lp = nnnp * nnnp + nnnq * nnnq + nnnp * nnnq
    r = a * sqrt(lp)
    c = a * l
    t = sq3 * c / ndr

    if 2 * nn > nk:
        raise RuntimeError('parameter nk is too small!')

    rs = c / (2.0 * np.pi)

    if verbose:
        print 'radius=', rs, t

    q1 = np.arctan((sq3 * m) / (2 * n + m))
    q2 = np.arctan((sq3 * nnnq) / (2 * nnnp + nnnq))
    q3 = q1 - q2

    q4 = 2.0 * np.pi / nn
    q5 = bond * np.cos((np.pi / 6.0) - q1) / c * 2.0 * np.pi

    h1 = abs(t) / abs(np.sin(q3))
    h2 = bond * np.sin((np.pi / 6.0) - q1)

    ii = 0
    x, y, z = [], [], []
    for i in range(nn):
        x1, y1, z1 = 0, 0, 0

        k = np.floor(i * abs(r) / h1)
        x1 = rs * np.cos(i * q4)
        y1 = rs * np.sin(i * q4)
        z1 = (i * abs(r) - k * h1) * np.sin(q3)
        kk2 = abs(np.floor((z1 + 0.0001) / t))
        if z1 >= t - 0.0001:
            z1 -= t * kk2
        elif z1 < 0:
            z1 += t * kk2
        ii += 1

        x.append(x1)
        y.append(y1)
        z.append(z1)
        z3 = (i * abs(r) - k * h1) * np.sin(q3) - h2
        ii += 1

        if z3 >= 0 and z3 < t:
            x2 = rs * np.cos(i * q4 + q5)
            y2 = rs * np.sin(i * q4 + q5)
            z2 = (i * abs(r) - k * h1) * np.sin(q3) - h2
            x.append(x2)
            y.append(y2)
            z.append(z2)
        else:
            x2 = rs * np.cos(i * q4 + q5)
            y2 = rs * np.sin(i * q4 + q5)
            z2 = (i * abs(r) - (k + 1) * h1) * np.sin(q3) - h2
            kk = abs(np.floor(z2 / t))
            if z2 >= t - 0.0001:
                z2 -= t * kk
            elif z2 < 0:
                z2 += t * kk
            x.append(x2)
            y.append(y2)
            z.append(z2)

    ntotal = 2 * nn
    X = []
    for i in range(ntotal):
        X.append([x[i], y[i], sign * z[i]])

    if length > 1:
        xx = X[:]
        for mnp in range(2, length + 1):
            for i in range(len(xx)):
                X.append(xx[i][:2] + [xx[i][2] + (mnp - 1) * t])

    TransVec = t
    NumAtom = ntotal * length
    Diameter = rs * 2
    ChiralAngle = np.arctan((sq3 * n) / (2 * m + n)) / (np.pi * 180)

    cell = [Diameter * 2, Diameter * 2, length * t]
    atoms = Atoms(symbol + str(NumAtom),
                  positions=X,
                  cell=cell,
                  pbc=[False, False, True])
    atoms.center()
    if verbose:
        print 'translation vector =', TransVec
        print 'diameter = ', Diameter
        print 'chiral angle = ', ChiralAngle
    return atoms
Beispiel #23
0
class execution(object):
    def __init__(self, executionInput, xyz=None, stateFile='state.json'):
        '''
  Setup a new execution

  Name:  input file
  xyz:   xyz coordinates (for future automated execution)
  stateFile: state file to use for tracking of executions

  TODO: 

  - only ground state in non-periodic cell supported NOW, more to add!
  - inputs from a dict to better handle automated executions
  '''
        if isinstance(executionInput, str):
            self.inp = self.json(executionInput)
            self.inputFileName = executionInput

        if isinstance(executionInput, dict):
            self.inp = executionInput
            self.inputFileName = 'dict'  # TODO: generate meaningful name here (how?)

        self.setup()

    def setup(self):
        '''setup'''

        self.functional = self.inp.get('functional') or 'LDA'
        self.runtype = self.inp.get('runtype') or 'calc'

        # this actually can't be none!
        _xyz = self.inp.get('xyz')

        if isinstance(_xyz, str):
            self.inputXYZ = _xyz
            self.atoms = read(self.inputXYZ)
        else:
            # support reading frm a dict (TODO: other type of objects - ?)
            from ase.atoms import Atoms
            from ase.atom import Atom

            self.atoms = \
             Atoms([Atom(a[0],(a[1],a[2],a[3])) for a in _xyz])

        # TODO: support multiple cell types
        self.atoms.cell = (self.inp['cell']['x'], self.inp['cell']['y'],
                           self.inp['cell']['z'])

        # Mixer setup - only "broyden" supported
        self.mixer = self.inp.get('mixer')

        if self.mixer is None:
            self.mixer = Mixer
        else:
            self.mixer = BroydenMixer

        # Custom ID: allow to trace parameter set using a custom id
        self.custom_id = self.inp.get('custom_id')

        # Periodic Boundary Conditions
        self.atoms.pbc = False

        # This should not be done always
        self.atoms.center()

        self.nbands = self.inp.get('nbands')

        self.gpts = None
        self.setup_gpts()

        self.max_iterations = self.inp.get('maxiter') or 333

        # Name: to be set by __str__ first time it is run
        self.name = None

        #
        self.logExtension = 'txt'
        self.dataExtension = 'gpw'

        # Timing / statistics
        self.lastElapsed = None

    #
    def get_optimizer(self, name='QuasiNewton'):

        from importlib import import_module

        name = name.lower()
        _optimMap = \
         {
          'mdmin':       'MDMin',
          'hesslbfgs':   'HessLBFGS',
          'linelbfgs':   'LineLBFGS',
          'fire':        'FIRE',
          'lbfgs':       'LBFGS',
          'lbfgsls':     'LBFGSLineSearch',
          'bfgsls':      'BFGSLineSearch',
          'bfgs':        'BFGS',
          'quasinewton': 'QuasiNewton'
         }
        _class = _optimMap[name]
        _m = import_module('ase.optimize')
        return getattr(_m, _class)

    #
    def setup_gpts(self):
        self.gpts = h2gpts(self.inp.get('spacing') or 0.20,
                           self.atoms.get_cell(),
                           idiv=self.inp.get('idiv') or 8)

    def filename(self, force_id=None, extension='txt'):
        '''to correctly support this:
     stateFile support must be completed
     as it isn't just add "_0" to __str__() for now
  '''
        base = self.__str__()

        if self.custom_id is not None:
            base = base + '_' + self.custom_id

        if force_id is None:
            _fn = base + '_0.' + extension
        else:
            _fn = '{}_{}.{}'.format(base, force_id, extension)

        return _fn

    #
    @property
    def xyz(self):
        return self.inp['xyz']

    #
    @property
    def spacegroup(self):
        '''international ID of determined spacegroup'''
        sg = spglib.get_symmetry_dataset(spglib.refine_cell(
            self.atoms))['international']

        return sg.replace('/', ':')

    #
    def __str__(self):
        '''get execution name - to be used for log filename

  Components:

  - Number atoms
  - Volume
  - Spacegroup number
  - Functional name

  '''

        if self.name is None:
            self.name = '{}_{}_{}_{}'.format(
                len(self.atoms), int(self.atoms.get_volume() * 100),
                self.spacegroup, self.functional)

        _gpaw = os.environ['GPAW']
        _pwd = os.environ['PWD']

        self.procname = '{} ({})'.format(self.name,
                                         _pwd.replace(_gpaw + '/', ''))
        setproctitle(self.procname)

        return self.name

    ##
    def print(self, *args, **kwargs):
        '''print wrapper - initial step before logger'''
        r = print(*args, *kwargs)
        return r

    #
    def pretty(self):
        '''pretty print original parameters'''
        _p = pformat(self.inp)
        self.print(_p)

    #
    def json(self, filename):
        '''load parameters from json'''

        with open(filename, 'rb') as f:
            s = f.read()
            j = json.loads(s)

        return j

    #
    def run(self, force_id=None, runtype=None):
        '''
    perform execution - only calc or optim supported now
  '''

        _lastStart = time.time()

        if runtype is None and self.runtype is 'calc':
            _f = self.calc
        else:
            _f = self.optim

        # calculate
        try:
            result = _f(force_id)
        finally:
            _lastEnd = time.time()
            self.lastElapsed = _lastEnd - _lastStart

        return result

    #
    def calc(self, force_id=None, functional=None):
        '''prepare and launch execution
     force_id: use this id for filename generation
  '''

        # Allow to override the funtional
        _fnl = functional or self.functional

        # generate filenames
        _fn = self.filename(force_id)
        _dn = self.filename(force_id, extension=self.dataExtension)

        self.print('Calculation with {} log and Input: {}.'.format(
            _fn, self.inputFileName))

        if self.nbands is None:
            _calc = GPAW(xc=_fnl,
                         txt=self.filename(force_id),
                         mixer=self.mixer(),
                         maxiter=self.max_iterations,
                         gpts=self.gpts)
        else:
            _calc = GPAW(xc=_fnl,
                         txt=self.filename(force_id),
                         nbands=self.nbands,
                         mixer=self.mixer(),
                         maxiter=self.max_iterations,
                         gpts=self.gpts)

        self.atoms.set_calculator(_calc)
        self.atoms.get_potential_energy()

        # write out wavefunctions
        _calc.write(_dn, 'all')
        return _calc

    #####
    def optim(self, force_id=None, functional=None):
        '''prepare and launch execution
     force_id: use this id for filename generation
  '''

        _optim_name = self.inp.get('optimizer') or 'QuasiNewton'
        optimizer = self.get_optimizer(_optim_name)

        # Allow to override the funtional
        _fnl = functional or self.functional

        # generate filenames
        _fn = self.filename(force_id)
        _dn = self.filename(force_id, extension=self.dataExtension)

        self.print('Optimization with {} log and Input: {}.'.format(
            _fn, self.inputFileName))

        if self.nbands is None:
            _calc = GPAW(xc=_fnl,
                         txt=self.filename(force_id),
                         mixer=self.mixer(),
                         maxiter=self.max_iterations,
                         gpts=self.gpts)
        else:
            _calc = GPAW(xc=_fnl,
                         txt=self.filename(force_id),
                         nbands=self.nbands,
                         mixer=self.mixer(),
                         maxiter=self.max_iterations,
                         gpts=self.gpts)

        self.atoms.set_calculator(_calc)

        self.opt = optimizer(self.atoms,
                             trajectory=self.__str__() + '_emt.traj')
        self.opt.run(fmax=0.05)

        # write out wavefunctions
        _calc.write(_dn, 'all')
        return _calc
Beispiel #24
0
def graphene_nanoribbon(n,
                        m,
                        type='zigzag',
                        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',
                        vacc=None):
    """Create a graphene nanoribbon.

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

    Parameters:

    n: The width of the nanoribbon

    m: The length of the nanoribbon.

    type ('zigzag'): The orientation of the ribbon.  Must be either 'zigzag'
    or 'armchair'.

    saturated (Falsi):  If true, hydrogen atoms are placed along the edge.

    C_H: Carbon-hydrogen bond length.  Default: 1.09 Angstrom

    C_C: Carbon-carbon bond length.  Default: 1.42 Angstrom.

    vacuum:  Amount of vacuum added to both sides.  Default 2.5 Angstrom.

    magnetic:  Make the edges magnetic.

    initial_mag: Magnitude of magnetic moment if magnetic=True.

    sheet:  If true, make an infinite sheet instead of a ribbon.
    """
    #This function creates the coordinates for a graphene nanoribbon,
    #n is width, m is length

    if vacc is not None:
        warnings.warn('Use vacuum=%f' % (0.5 * vacc))
        vacuum = 0.5 * vacc

    assert vacuum > 0
    b = sqrt(3) * C_C / 4
    arm_unit = Atoms(main_element + '4',
                     pbc=(1, 0, 1),
                     cell=[4 * b, 2 * vacuum, 3 * C_C])
    arm_unit.positions = [[0, 0, 0], [b * 2, 0, C_C / 2.],
                          [b * 2, 0, 3 * C_C / 2.], [0, 0, 2 * C_C]]
    zz_unit = Atoms(main_element + '2',
                    pbc=(1, 0, 1),
                    cell=[3 * C_C / 2., 2 * vacuum, b * 4])
    zz_unit.positions = [[0, 0, 0], [C_C / 2., 0, b * 2]]
    atoms = Atoms()
    tol = 1e-4
    if sheet:
        vacuum2 = 0.0
    else:
        vacuum2 = vacuum
    if type == 'zigzag':
        edge_index0 = np.arange(m) * 2 + 1
        edge_index1 = (n - 1) * m * 2 + np.arange(m) * 2
        if magnetic:
            mms = np.zeros(m * n * 2)
            for i in edge_index0:
                mms[i] = initial_mag
            for i in edge_index1:
                mms[i] = -initial_mag

        for i in range(n):
            layer = zz_unit.repeat((1, 1, m))
            layer.positions[:, 0] -= 3 * C_C / 2 * i
            if i % 2 == 1:
                layer.positions[:, 2] += 2 * b
                layer[-1].position[2] -= b * 4 * m
            atoms += layer
        if magnetic:
            atoms.set_initial_magnetic_moments(mms)
        if saturated:
            H_atoms0 = Atoms(saturate_element + str(m))
            H_atoms0.positions = atoms[edge_index0].positions
            H_atoms0.positions[:, 0] += C_H
            H_atoms1 = Atoms(saturate_element + str(m))
            H_atoms1.positions = atoms[edge_index1].positions
            H_atoms1.positions[:, 0] -= C_H
            atoms += H_atoms0 + H_atoms1
        atoms.cell = [n * 3 * C_C / 2 + 2 * vacuum2, 2 * vacuum, m * 4 * b]

    elif type == 'armchair':
        for i in range(n):
            layer = arm_unit.repeat((1, 1, m))
            layer.positions[:, 0] -= 4 * b * i
            atoms += layer
        atoms.cell = [b * 4 * n + 2 * vacuum2, 2 * vacuum, 3 * C_C * m]

    atoms.center()
    atoms.set_pbc([sheet, False, True])
    return atoms
Beispiel #25
0
def nanotube(n, m, length=1, bond=1.42, symbol="C", verbose=False):
    if n < m:
        m, n = n, m
        sign = -1
    else:
        sign = 1

    nk = 6000
    sq3 = sqrt(3.0)
    a = sq3 * bond
    l2 = n * n + m * m + n * m
    l = sqrt(l2)
    dt = a * l / np.pi

    nd = gcd(n, m)
    if (n - m) % (3 * nd) == 0:
        ndr = 3 * nd
    else:
        ndr = nd

    nr = (2 * m + n) / ndr
    ns = -(2 * n + m) / ndr
    nt2 = 3 * l2 / ndr / ndr
    nt = np.floor(sqrt(nt2))
    nn = 2 * l2 / ndr

    ichk = 0
    if nr == 0:
        n60 = 1
    else:
        n60 = nr * 4

    absn = abs(n60)
    nnp = []
    nnq = []
    for i in range(-absn, absn + 1):
        for j in range(-absn, absn + 1):
            j2 = nr * j - ns * i
            if j2 == 1:
                j1 = m * i - n * j
                if j1 > 0 and j1 < nn:
                    ichk += 1
                    nnp.append(i)
                    nnq.append(j)

    if ichk == 0:
        raise RuntimeError("not found p, q strange!!")
    if ichk >= 2:
        raise RuntimeError("more than 1 pair p, q strange!!")

    nnnp = nnp[0]
    nnnq = nnq[0]

    if verbose:
        print "the symmetry vector is", nnnp, nnnq

    lp = nnnp * nnnp + nnnq * nnnq + nnnp * nnnq
    r = a * sqrt(lp)
    c = a * l
    t = sq3 * c / ndr

    if 2 * nn > nk:
        raise RuntimeError("parameter nk is too small!")

    rs = c / (2.0 * np.pi)

    if verbose:
        print "radius=", rs, t

    q1 = np.arctan((sq3 * m) / (2 * n + m))
    q2 = np.arctan((sq3 * nnnq) / (2 * nnnp + nnnq))
    q3 = q1 - q2

    q4 = 2.0 * np.pi / nn
    q5 = bond * np.cos((np.pi / 6.0) - q1) / c * 2.0 * np.pi

    h1 = abs(t) / abs(np.sin(q3))
    h2 = bond * np.sin((np.pi / 6.0) - q1)

    ii = 0
    x, y, z = [], [], []
    for i in range(nn):
        x1, y1, z1 = 0, 0, 0

        k = np.floor(i * abs(r) / h1)
        x1 = rs * np.cos(i * q4)
        y1 = rs * np.sin(i * q4)
        z1 = (i * abs(r) - k * h1) * np.sin(q3)
        kk2 = abs(np.floor((z1 + 0.0001) / t))
        if z1 >= t - 0.0001:
            z1 -= t * kk2
        elif z1 < 0:
            z1 += t * kk2
        ii += 1

        x.append(x1)
        y.append(y1)
        z.append(z1)
        z3 = (i * abs(r) - k * h1) * np.sin(q3) - h2
        ii += 1

        if z3 >= 0 and z3 < t:
            x2 = rs * np.cos(i * q4 + q5)
            y2 = rs * np.sin(i * q4 + q5)
            z2 = (i * abs(r) - k * h1) * np.sin(q3) - h2
            x.append(x2)
            y.append(y2)
            z.append(z2)
        else:
            x2 = rs * np.cos(i * q4 + q5)
            y2 = rs * np.sin(i * q4 + q5)
            z2 = (i * abs(r) - (k + 1) * h1) * np.sin(q3) - h2
            kk = abs(np.floor(z2 / t))
            if z2 >= t - 0.0001:
                z2 -= t * kk
            elif z2 < 0:
                z2 += t * kk
            x.append(x2)
            y.append(y2)
            z.append(z2)

    ntotal = 2 * nn
    X = []
    for i in range(ntotal):
        X.append([x[i], y[i], sign * z[i]])

    if length > 1:
        xx = X[:]
        for mnp in range(2, length + 1):
            for i in range(len(xx)):
                X.append(xx[i][:2] + [xx[i][2] + (mnp - 1) * t])

    TransVec = t
    NumAtom = ntotal * length
    Diameter = rs * 2
    ChiralAngle = np.arctan((sq3 * n) / (2 * m + n)) / (np.pi * 180)

    cell = [Diameter * 2, Diameter * 2, length * t]
    atoms = Atoms(symbol + str(NumAtom), positions=X, cell=cell, pbc=[False, False, True])
    atoms.center()
    if verbose:
        print "translation vector =", TransVec
        print "diameter = ", Diameter
        print "chiral angle = ", ChiralAngle
    return atoms
Beispiel #26
0
def graphene_nanoribbon(
    n,
    m,
    type="zigzag",
    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",
    vacc=None,
):
    """Create a graphene nanoribbon.

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

    Parameters:

    n: The width of the nanoribbon

    m: The length of the nanoribbon.

    type ('zigzag'): The orientation of the ribbon.  Must be either 'zigzag'
    or 'armchair'.

    saturated (Falsi):  If true, hydrogen atoms are placed along the edge.

    C_H: Carbon-hydrogen bond length.  Default: 1.09 Angstrom

    C_C: Carbon-carbon bond length.  Default: 1.42 Angstrom.

    vacuum:  Amount of vacuum added to both sides.  Default 2.5 Angstrom.

    magnetic:  Make the edges magnetic.

    initial_mag: Magnitude of magnetic moment if magnetic=True.

    sheet:  If true, make an infinite sheet instead of a ribbon.
    """
    # This function creates the coordinates for a graphene nanoribbon,
    # n is width, m is length

    if vacc is not None:
        warnings.warn("Use vacuum=%f" % (0.5 * vacc))
        vacuum = 0.5 * vacc

    assert vacuum > 0
    b = sqrt(3) * C_C / 4
    arm_unit = Atoms(main_element + "4", pbc=(1, 0, 1), cell=[4 * b, 2 * vacuum, 3 * C_C])
    arm_unit.positions = [[0, 0, 0], [b * 2, 0, C_C / 2.0], [b * 2, 0, 3 * C_C / 2.0], [0, 0, 2 * C_C]]
    zz_unit = Atoms(main_element + "2", pbc=(1, 0, 1), cell=[3 * C_C / 2.0, 2 * vacuum, b * 4])
    zz_unit.positions = [[0, 0, 0], [C_C / 2.0, 0, b * 2]]
    atoms = Atoms()
    tol = 1e-4
    if sheet:
        vacuum2 = 0.0
    else:
        vacuum2 = vacuum
    if type == "zigzag":
        edge_index0 = np.arange(m) * 2 + 1
        edge_index1 = (n - 1) * m * 2 + np.arange(m) * 2
        if magnetic:
            mms = np.zeros(m * n * 2)
            for i in edge_index0:
                mms[i] = initial_mag
            for i in edge_index1:
                mms[i] = -initial_mag

        for i in range(n):
            layer = zz_unit.repeat((1, 1, m))
            layer.positions[:, 0] -= 3 * C_C / 2 * i
            if i % 2 == 1:
                layer.positions[:, 2] += 2 * b
                layer[-1].position[2] -= b * 4 * m
            atoms += layer
        if magnetic:
            atoms.set_initial_magnetic_moments(mms)
        if saturated:
            H_atoms0 = Atoms(saturate_element + str(m))
            H_atoms0.positions = atoms[edge_index0].positions
            H_atoms0.positions[:, 0] += C_H
            H_atoms1 = Atoms(saturate_element + str(m))
            H_atoms1.positions = atoms[edge_index1].positions
            H_atoms1.positions[:, 0] -= C_H
            atoms += H_atoms0 + H_atoms1
        atoms.cell = [n * 3 * C_C / 2 + 2 * vacuum2, 2 * vacuum, m * 4 * b]

    elif type == "armchair":
        for i in range(n):
            layer = arm_unit.repeat((1, 1, m))
            layer.positions[:, 0] -= 4 * b * i
            atoms += layer
        atoms.cell = [b * 4 * n + 2 * vacuum2, 2 * vacuum, 3 * C_C * m]

    atoms.center()
    atoms.set_pbc([sheet, False, True])
    return atoms
Beispiel #27
0
def graphene_nanoribbon(n, m, type='zigzag', 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',
                        vacc=None):
    """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.
    """

    if vacc is not None:
        warnings.warn('Use vacuum=%f' % (0.5 * vacc))
        vacuum = 0.5 * vacc

    assert vacuum > 0
    b = sqrt(3) * C_C / 4
    arm_unit = Atoms(main_element + '4',
                     pbc=(1, 0, 1),
                     cell=[4 * b, 2 * vacuum, 3 * C_C])
    arm_unit.positions = [[0, 0, 0],
                          [b * 2, 0, C_C / 2.],
                          [b * 2, 0, 3 * C_C / 2.],
                          [0, 0, 2 * C_C]]
    zz_unit = Atoms(main_element + '2',
                    pbc=(1, 0, 1),
                    cell=[3 * C_C / 2.0, 2 * vacuum, b * 4])
    zz_unit.positions = [[0, 0, 0],
                         [C_C / 2.0, 0, b * 2]]
    atoms = Atoms()
    if sheet:
        vacuum2 = 0.0
    else:
        vacuum2 = vacuum
    if type == 'zigzag':
        edge_index0 = np.arange(m) * 2 + 1
        edge_index1 = (n - 1) * m * 2 + np.arange(m) * 2
        if magnetic:
            mms = np.zeros(m * n * 2)
            for i in edge_index0:
                mms[i] = initial_mag
            for i in edge_index1:
                mms[i] = -initial_mag

        for i in range(n):
            layer = zz_unit.repeat((1, 1, m))
            layer.positions[:, 0] -= 3 * C_C / 2 * i
            if i % 2 == 1:
                layer.positions[:, 2] += 2 * b
                layer[-1].position[2] -= b * 4 * m
            atoms += layer
        if magnetic:
            atoms.set_initial_magnetic_moments(mms)
        if saturated:
            H_atoms0 = Atoms(saturate_element + str(m))
            H_atoms0.positions = atoms[edge_index0].positions
            H_atoms0.positions[:, 0] += C_H
            H_atoms1 = Atoms(saturate_element + str(m))
            H_atoms1.positions = atoms[edge_index1].positions
            H_atoms1.positions[:, 0] -= C_H
            atoms += H_atoms0 + H_atoms1
        atoms.cell = [n * 3 * C_C / 2 + 2 * vacuum2, 2 * vacuum, m * 4 * b]

    elif type == 'armchair':
        for i in range(n):
            layer = arm_unit.repeat((1, 1, m))
            layer.positions[:, 0] -= 4 * b * i
            atoms += layer
        if saturated:
            arm_right_saturation = Atoms(saturate_element + '2', pbc=(1, 0, 1),
                                         cell=[4 * b, 2 * vacuum, 3 * C_C])
            arm_right_saturation.positions = [
                [- sqrt(3) / 2 * C_H, 0, C_H * 0.5],
                [- sqrt(3) / 2 * C_H, 0, 2 * C_C - C_H * 0.5]]
            arm_left_saturation = Atoms(saturate_element + '2', pbc=(1, 0, 1),
                                        cell=[4 * b, 2 * vacuum, 3 * C_C])
            arm_left_saturation.positions = [
                [b * 2 + sqrt(3) / 2 * C_H, 0, C_C / 2 - C_H * 0.5],
                [b * 2 + sqrt(3) / 2 * C_H, 0, 3 * C_C / 2.0 + C_H * 0.5]]
            arm_right_saturation.positions[:, 0] -= 4 * b * (n - 1)
            atoms += arm_right_saturation.repeat((1, 1, m))
            atoms += arm_left_saturation.repeat((1, 1, m))

        atoms.cell = [b * 4 * n + 2 * vacuum2, 2 * vacuum, 3 * C_C * m]

    atoms.center()
    atoms.set_pbc([sheet, False, True])
    return atoms
Beispiel #28
0
from gpaw import GPAW, FermiDirac
from gpaw.mpi import world, size, rank
from gpaw.lrtddft2 import LrTDDFT2
from gpaw.lrtddft2.lr_communicators import LrCommunicators
from gpaw.test import equal
from ase.atoms import Atoms

debug = False
restart_file = 'Al2_gs.gpw'

d = 2.563
atoms = Atoms('Al2', positions=((0, 0, 0), (0, 0, d)))
atoms.center(4.0)
calc = GPAW(h=0.24,
            eigensolver='cg',
            basis='dzp',
            occupations=FermiDirac(width=0.01),
            convergence={
                'eigenstates': 4.0e-5,
                'density': 1.0e-2,
                'bands': 'all'
            },
            nbands=20)
atoms.set_calculator(calc)
atoms.get_potential_energy()
calc.write(restart_file, mode='all')

# Try to run parallel over eh-pairs
if size % 2 == 0:
    eh_size = 2
    domain_size = size // eh_size
    if os.path.exists(base_dir) is not True:
        os.makedirs(base_dir)
    os.chdir(base_dir)
    calc = Vasp(restart=None,
                xc="vdw-df2",
                encut=800,
                kpts={
                    "gamma": True,
                    "density": 5.0
                },
                setups="gw",
                ismear=0,
                sigma=0.001,
                ediff=1e-7,
                algo="Accurate")
    atoms = Atoms(symbols=mol.formula,
                  positions=mol.positions,
                  cell=mol.cell,
                  pbc=[
                      True,
                  ] * 3)
    atoms.cell[-1, -1] = start_guess
    atoms.center(axis=2)  #center along z

    calc.set_atoms(atoms)
    calc.initialize(atoms)
    calc.clean()
    calc.write_input(atoms)
    # Done with the input
os.chdir(curr_dir)
Beispiel #30
0
# +
import numpy as np
from ase.atoms import Atoms
from ase.calculators.vasp import Vasp
from ase.calculators.emt import EMT
from ase.optimize import LBFGS
from theforce.util.flake import generate_random_cluster
from theforce.calculator.active import ActiveCalculator, kcal_mol

# random cluster generation
ngold = 20
min_dist = 2.5
positions = generate_random_cluster(ngold, min_dist)
atoms = Atoms(numbers=ngold * [79], positions=positions)
atoms.center(vacuum=5.)
atoms.pbc = True

# Ab initio calculator; for now we just use EMT instead of vasp
# abinitio = Vasp(command="mpirun -n 16 vasp_std", directory='vasp')
abinitio = EMT()

# ML calculator
active_kwargs = {
    'calculator': abinitio,
    'ediff': 1.0 * kcal_mol,  # decrease for more accuracy but lower speed
    'fdiff': 1.0 * kcal_mol,  # decrease for more accuracy but lower speed
    'kernel_kw': {
        'cutoff': 6.,
        'lmax': 3,
        'nmax': 3
    },
Beispiel #31
0
from gpaw import GPAW
from ase.atoms import Atoms

atoms = Atoms("C", positions=[[0.0, 0.0, 0.0]])
atoms.center(vacuum=4.0)
print(atoms)

calc = GPAW(txt="-", hund=True)

from ase.units import Hartree
atoms.set_calculator(calc)

Etot = atoms.get_potential_energy()

# convert from eV to Ha
print("Etot = %18.10f Ha\n" % (Etot / Hartree))