Exemplo n.º 1
0
    def __init__(self, basis='qz', xc='BH'):

        label = 'H2O'  #TODO: for now, change later
        if xc == 'REVPBE': xc = 'revPBE'

        fdf_arguments = {
            'DM.MixingWeight': 0.3,
            'DM.NumberPulay': 3,
            'ElectronicTemperature': 5e-3,
            'WriteMullikenPop': 0,
            'MaxSCFIterations': 40
        }

        if basis == 'uf':
            super().__init__(label=label,
                             xc='PBE',
                             mesh_cutoff=100 * Ry,
                             energy_shift=0.02 * Ry,
                             basis_set='SZ')
            dmtol = 5e-4

        elif not 'custom' in basis.lower():
            super().__init__(label=label,
                             xc=xc,
                             mesh_cutoff=200 * Ry,
                             energy_shift=0.02 * Ry,
                             basis_set=basis.upper())
            dmtol = 5e-4
        else:
            species_o = Species(symbol='O',
                                basis_set=PAOBasisBlock(
                                    basis_sets['o_basis_{}'.format(basis)]))
            species_h = Species(symbol='H',
                                basis_set=PAOBasisBlock(
                                    basis_sets['h_basis_{}'.format(basis)]))

            super().__init__(label='H2O',
                             xc=xc,
                             mesh_cutoff=200 * Ry,
                             basis_set='DZP',
                             species=[species_o, species_h],
                             energy_shift=0.02 * Ry)
            dmtol = 5e-4

        fdf_arguments['DM.UseSaveDM'] = 'True'
        fdf_arguments['SCF.MustConverge'] = 'False'
        fdf_arguments['DM.Tolerance'] = dmtol
        fdf_arguments['MLCF.Use'] = False
        fdf_arguments['SaveDeltaRho'] = True

        allowed_keys = self.allowed_fdf_keywords
        allowed_keys['SaveDeltaRho'] = False
        allowed_keys['SaveRhoXC'] = False
        allowed_keys['MLCF.Use'] = False
        allowed_keys['SCF.MustConverge'] = False
        self.allowed_keywords = allowed_keys
        self.set_fdf_arguments(fdf_arguments)
Exemplo n.º 2
0
    def __init__(self,
                 atoms=None,
                 command=None,
                 xc='LDA',
                 spin='non-polarized',
                 ghosts=[],
                 **kwargs):
        if atoms is not None:
            finder = DojoFinder()
            elems = list(dict.fromkeys(atoms.get_chemical_symbols()).keys())
            elem_dict = dict(zip(elems, range(1, len(elems) + 1)))
            symbols = atoms.get_chemical_symbols()

            # ghosts
            ghost_symbols = [symbols[i] for i in ghosts]
            ghost_elems = list(dict.fromkeys(ghost_symbols).keys())
            tags = [1 if i in ghosts else 0 for i in range(len(atoms))]
            atoms.set_tags(tags)

            pseudo_path = finder.get_pp_path(xc=xc)
            if spin == 'spin-orbit':
                rel = 'fr'
            else:
                rel = 'sr'
            species = [
                Species(symbol=elem,
                        pseudopotential=finder.get_pp_fname(elem,
                                                            xc=xc,
                                                            rel=rel),
                        ghost=False) for elem in elem_dict.keys()
            ]
            for elem in ghost_elems:
                species.append(
                    Species(symbol=elem,
                            pseudopotential=finder.get_pp_fname(elem,
                                                                xc=xc,
                                                                rel=rel),
                            tag=1,
                            ghost=True))

        Siesta.__init__(self,
                        xc=xc,
                        spin=spin,
                        atoms=atoms,
                        pseudo_path=pseudo_path,
                        species=species,
                        **kwargs)
Exemplo n.º 3
0
def get_species(atoms, xc, rel='sr'):
    finder = DojoFinder()
    elems = list(dict.fromkeys(atoms.get_chemical_symbols()).keys())
    elem_dict = dict(zip(elems, range(1, len(elems) + 1)))
    pseudo_path = finder.get_pp_path(xc=xc)
    species = [
        Species(symbol=elem,
                pseudopotential=finder.get_pp_fname(elem, xc=xc, rel=rel),
                ghost=False) for elem in elem_dict.keys()
    ]
    return pseudo_path, species
Exemplo n.º 4
0
    def species(self, atoms):
        """Find all relevant species depending on the atoms object and
        species input.

            Parameters :
                - atoms : An Atoms object.
        """
        # For each element use default species from the species input, or set
        # up a default species  from the general default parameters.
        symbols = np.array(atoms.get_chemical_symbols())
        tags = atoms.get_tags()
        species = list(self['species'])
        default_species = [
            s for s in species
            if (s['tag'] is None) and s['symbol'] in symbols]
        default_symbols = [s['symbol'] for s in default_species]
        for symbol in symbols:
            if symbol not in default_symbols:
                spec = Species(symbol=symbol,
                               basis_set=self['basis_set'],
                               tag=None)
                default_species.append(spec)
                default_symbols.append(symbol)
        assert len(default_species) == len(np.unique(symbols))

        # Set default species as the first species.
        species_numbers = np.zeros(len(atoms), int)
        i = 1
        for spec in default_species:
            mask = symbols == spec['symbol']
            species_numbers[mask] = i
            i += 1

        # Set up the non-default species.
        non_default_species = [s for s in species if not s['tag'] is None]
        for spec in non_default_species:
            mask1 = (tags == spec['tag'])
            mask2 = (symbols == spec['symbol'])
            mask = np.logical_and(mask1, mask2)
            if sum(mask) > 0:
                species_numbers[mask] = i
                i += 1
        all_species = default_species + non_default_species

        return all_species, species_numbers
Exemplo n.º 5
0
                np.array([[0.000000, 0.000000, 0.100000],
                          [0.682793, 0.682793, 0.682793],
                          [-0.682793, -0.682793, 0.68279],
                          [-0.682793, 0.682793, -0.682793],
                          [0.682793, -0.682793, -0.682793]]),
                cell=[10, 10, 10])

c_basis = """2 nodes 1.00
0 1 S 0.20 P 1 0.20 6.00
5.00
1.00
1 2 S 0.20 P 1 E 0.20 6.00
6.00 5.00
1.00 0.95"""

species = Species(symbol='C', basis_set=PAOBasisBlock(c_basis))
calc = Siesta(
    label='ch4',
    basis_set='SZ',
    xc='LYP',
    mesh_cutoff=300 * Ry,
    species=[species],
    restart='ch4.XV',
    fdf_arguments={
        'DM.Tolerance': 1E-5,
        'DM.MixingWeight': 0.15,
        'DM.NumberPulay': 3,
        'MaxSCFIterations': 200,
        'ElectronicTemperature': (0.02585, 'eV'),  # 300 K
        'SaveElectrostaticPotential': True
    })
Exemplo n.º 6
0
    def __init__(self,
                 atoms=None,
                 command=None,
                 xc='LDA',
                 spin='non-polarized',
                 basis_set='DZP',
                 ghosts=[],
                 input_basis_set={},
                 pseudo_path=None,
                 input_pp={},
                 pp_accuracy='standard',
                 **kwargs):
        # non-perturnbative polarized orbital.
        self.npt_elems = set()

        if atoms is not None:
            finder = DojoFinder()
            elems = list(dict.fromkeys(atoms.get_chemical_symbols()).keys())
            self.elem_dict = dict(zip(elems, range(1, len(elems) + 1)))
            symbols = atoms.get_chemical_symbols()

            # ghosts
            ghost_symbols = [symbols[i] for i in ghosts]
            ghost_elems = list(dict.fromkeys(ghost_symbols).keys())
            tags = [1 if i in ghosts else 0 for i in range(len(atoms))]
            atoms.set_tags(tags)

            if pseudo_path is None:
                pseudo_path = finder.get_pp_path(xc=xc, accuracy=pp_accuracy)

            if spin == 'spin-orbit':
                rel = 'fr'
            else:
                rel = 'sr'
            species = []
            for elem, index in self.elem_dict.items():
                if elem not in input_basis_set:
                    bselem = basis_set
                    if elem in ['Li', 'Be', 'Na', 'Mg']:
                        self.npt_elems.add(f"{elem}.{index}")
                else:
                    bselem = PAOBasisBlock(input_basis_set[elem])
                if elem not in input_pp:
                    pseudopotential = finder.get_pp_fname(
                        elem, xc=xc, rel=rel, accuracy=pp_accuracy)
                else:
                    pseudopotential = os.path.join(
                        pseudo_path, input_pp[elem])

                species.append(Species(symbol=elem,
                                       pseudopotential=pseudopotential,
                                       basis_set=bselem,
                                       ghost=False))
            for elem in ghost_elems:
                species.append(
                    Species(symbol=elem,
                            pseudopotential=finder.get_pp_fname(
                                elem, xc=xc, rel=rel, accuracy=pp_accuracy),
                            tag=1,
                            ghost=True))

        Siesta.__init__(self,
                        xc=xc,
                        spin=spin,
                        atoms=atoms,
                        pseudo_path=pseudo_path,
                        species=species,
                        **kwargs)
        self.set_npt_elements()
Exemplo n.º 7
0
# Test setting fdf-arguments after initiation.
siesta.set_fdf_arguments(
    {'DM.Tolerance': 1e-2,
     'ON.eta': (2, 'Ry')})
siesta.write_input(atoms, properties=['energy'])
with open('test_label.fdf', 'r') as f:
    lines = f.readlines()
assert 'MeshCutoff\t3000\teV\n' in lines
assert 'DM.Tolerance\t0.01\n' in lines
assert 'ON.eta\t2\tRy\n' in lines

# Test initiation using Species.
atoms = ch4.copy()
species, numbers = siesta.species(atoms)
assert all(numbers == np.array([1, 2, 2, 2, 2]))
siesta = Siesta(species=[Species(symbol='C', tag=1)])
species, numbers = siesta.species(atoms)
assert all(numbers == np.array([1, 2, 2, 2, 2]))
atoms.set_tags([0, 0, 0, 1, 0])
species, numbers = siesta.species(atoms)
assert all(numbers == np.array([1, 2, 2, 2, 2]))
siesta = Siesta(species=[Species(symbol='H', tag=1, basis_set='SZ')])
species, numbers = siesta.species(atoms)
assert all(numbers == np.array([1, 2, 2, 3, 2]))
siesta = Siesta(label='test_label', species=species)
siesta.write_input(atoms, properties=['energy'])
with open('test_label.fdf', 'r') as f:
    lines = f.readlines()
lines = [line.split() for line in lines]
assert ['1', '6', 'C.lda.1'] in lines
assert ['2', '1', 'H.lda.2'] in lines
Exemplo n.º 8
0
# In this script the Virtual Crystal approximation is used to model
# a stronger affinity for positive charge on the H atoms.
# This could model interaction with other molecules not explicitly
# handled.
import numpy as np
from ase.calculators.siesta import Siesta
from ase.calculators.siesta.parameters import Species
from ase.optimize import QuasiNewton
from ase import Atoms

atoms = Atoms('CH4', np.array([
    [0.000000, 0.000000, 0.000000],
    [0.682793, 0.682793, 0.682793],
    [-0.682793, -0.682793, 0.682790],
    [-0.682793, 0.682793, -0.682793],
    [0.682793, -0.682793, -0.682793]]))

siesta = Siesta(
    species=[
        Species(symbol='H', excess_charge=0.1)])

atoms.calc = siesta
dyn = QuasiNewton(atoms, trajectory='h.traj')
dyn.run(fmax=0.02)
Exemplo n.º 9
0
def test_siesta(siesta_factory):
    # Setup test structures.
    h = Atoms('H', [(0.0, 0.0, 0.0)])
    ch4 = Atoms(
        'CH4',
        np.array([[0.000000, 0.000000, 0.000000],
                  [0.682793, 0.682793, 0.682793],
                  [-0.682793, -0.682793, 0.682790],
                  [-0.682793, 0.682793, -0.682793],
                  [0.682793, -0.682793, -0.682793]]))

    # Test the initialization.
    siesta = siesta_factory.calc()
    assert isinstance(siesta, FileIOCalculator)
    assert isinstance(siesta.implemented_properties, tuple)
    assert isinstance(siesta.default_parameters, dict)
    assert isinstance(siesta.name, str)
    assert isinstance(siesta.default_parameters, dict)

    # Test simple fdf-argument case.
    atoms = h.copy()
    siesta = siesta_factory.calc(label='test_label',
                                 fdf_arguments={'DM.Tolerance': 1e-3})
    atoms.calc = siesta
    siesta.write_input(atoms, properties=['energy'])
    atoms = h.copy()
    atoms.calc = siesta
    siesta.write_input(atoms, properties=['energy'])
    with open('test_label.fdf', 'r') as fd:
        lines = fd.readlines()
    assert any([line.split() == ['DM.Tolerance', '0.001'] for line in lines])

    # Test (slightly) more complex case of setting fdf-arguments.
    siesta = siesta_factory.calc(label='test_label',
                                 mesh_cutoff=3000,
                                 fdf_arguments={
                                     'DM.Tolerance': 1e-3,
                                     'ON.eta': (5, 'Ry')
                                 })
    atoms.calc = siesta
    siesta.write_input(atoms, properties=['energy'])
    atoms = h.copy()
    atoms.calc = siesta
    siesta.write_input(atoms, properties=['energy'])
    with open('test_label.fdf', 'r') as f:
        lines = f.readlines()

    assert 'MeshCutoff\t3000\teV\n' in lines
    assert 'DM.Tolerance\t0.001\n' in lines
    assert 'ON.eta\t5\tRy\n' in lines

    # Test setting fdf-arguments after initiation.
    siesta.set_fdf_arguments({'DM.Tolerance': 1e-2, 'ON.eta': (2, 'Ry')})
    siesta.write_input(atoms, properties=['energy'])
    with open('test_label.fdf', 'r') as f:
        lines = f.readlines()
    assert 'MeshCutoff\t3000\teV\n' in lines
    assert 'DM.Tolerance\t0.01\n' in lines
    assert 'ON.eta\t2\tRy\n' in lines

    # Test initiation using Species.
    atoms = ch4.copy()
    species, numbers = siesta.species(atoms)
    assert all(numbers == np.array([1, 2, 2, 2, 2]))
    siesta = siesta_factory.calc(species=[Species(symbol='C', tag=1)])
    species, numbers = siesta.species(atoms)
    assert all(numbers == np.array([1, 2, 2, 2, 2]))
    atoms.set_tags([0, 0, 0, 1, 0])
    species, numbers = siesta.species(atoms)
    assert all(numbers == np.array([1, 2, 2, 2, 2]))
    siesta = siesta_factory.calc(
        species=[Species(symbol='H', tag=1, basis_set='SZ')])
    species, numbers = siesta.species(atoms)
    assert all(numbers == np.array([1, 2, 2, 3, 2]))
    siesta = siesta_factory.calc(label='test_label', species=species)
    siesta.write_input(atoms, properties=['energy'])
    with open('test_label.fdf', 'r') as f:
        lines = f.readlines()
    lines = [line.split() for line in lines]
    assert ['1', '6', 'C.lda.1'] in lines
    assert ['2', '1', 'H.lda.2'] in lines
    assert ['3', '1', 'H.lda.3'] in lines
    assert ['C.lda.1', 'DZP'] in lines
    assert ['H.lda.2', 'DZP'] in lines
    assert ['H.lda.3', 'SZ'] in lines

    # Test if PAO block can be given as species.
    c_basis = """2 nodes 1.00
    0 1 S 0.20 P 1 0.20 6.00
    5.00
    1.00
    1 2 S 0.20 P 1 E 0.20 6.00
    6.00 5.00
    1.00 0.95"""
    basis_set = PAOBasisBlock(c_basis)
    species = Species(symbol='C', basis_set=basis_set)
    siesta = siesta_factory.calc(label='test_label', species=[species])
    siesta.write_input(atoms, properties=['energy'])
    with open('test_label.fdf', 'r') as f:
        lines = f.readlines()
    lines = [line.split() for line in lines]
    assert ['%block', 'PAO.Basis'] in lines
    assert ['%endblock', 'PAO.Basis'] in lines
Exemplo n.º 10
0
from ase.calculators.siesta import Siesta
from ase.calculators.siesta.parameters import Species, PAOBasisBlock
from ase.optimize import QuasiNewton
from ase import Atoms

atoms = Atoms('3H', [(0.0, 0.0, 0.0), (0.0, 0.0, 0.5), (0.0, 0.0, 1.0)],
              cell=[10, 10, 10])

basis_set = PAOBasisBlock("""1
0  2 S 0.2
0.0 0.0""")
atoms.set_tags([0, 1, 0])
siesta = Siesta(species=[
    Species(symbol='H', tag=None, basis_set='SZ'),
    Species(symbol='H', tag=1, basis_set=basis_set, ghost=True)
])

atoms.set_calculator(siesta)
dyn = QuasiNewton(atoms, trajectory='h.traj')
dyn.run(fmax=0.02)