def relax_one(atoms):
    """
    This method defines how to locally minimize a given atoms object.
    """
    print('Starting relaxation')
    clock = time()

    # Define the DFTB+ calculator:
    calc = DftbPlusCalculator(atoms, kpts=(1, 1, 1), use_spline=True,
                              maximum_angular_momenta={'Si': 1})

    # Start the actual relaxation using the
    # tango.relax_utils.relax_precon method.
    # This wraps around the ASE optimizers and also
    # takes care of setting the raw score etc.:
    try:
        atoms = relax_standard(atoms, calc, fmax=2e-2, variable_cell=False,
                               logfile=None, trajfile=None, optimizer='BFGS')
    except (IOError, UnboundLocalError):
        # the DFTB+ ASE calculator throws an IOError or
        # UnboundLocalError in case it couldn't find the
        # 'results.tag' output file, which may sporadically
        # happen due to SCC converge issues when e.g. a Si7
        # cluster is breaking into fragments. We simply
        # handle this by aborting the relaxation and
        # assigning a very high energy to the structure:
        finalize(atoms, energy=1e9, forces=None, stress=None)

    print('Relaxing took %.3f seconds.' % (time() - clock), flush=True)
    return atoms
Exemplo n.º 2
0
def run_dimers(dbfile, DftCalc, atomic_energies, element1, element2,
               minfrac=0.15, maxfrac=0.7, stepfrac=0.05, minE=5.):
    ''' Adds a dimer curve (with DFT energies and forces) for
    the given element pair to a database.

    dbfile: name of the database
    DftCalc: suitable DFT calculator class (see tango.main)
    atomic_energies: reference DFT energies of the separate atoms
    element1: symbol of the first element 
    element2: symbol of the second element
    minfrac, maxfrac, stepfrac: specifies the minimal and maximal
         dimer distances (and the spacing) in units of the sum of
         covalent radii
    minE: dimer distances where the dimer energy is less than minE
          above the sum of the reference energies are omitted
    '''
    positions = np.array([[6.] * 3, [8., 6., 6.]])
    atoms = Atoms(element1 + element2, cell=[12.] * 3,
                  positions=positions, pbc=True)

    calc = DftCalc(atoms, kpts=(1,1,1), run_type='dimer')

    db = connect(dbfile)
    num1 = atomic_numbers[element1]
    num2 = atomic_numbers[element2]
    e_ref = [atomic_energies['%s_DFT' % e] for e in [element1, element2]]
    crsum = covalent_radii[num1] + covalent_radii[num2]
    r = minfrac * crsum

    while True:
        if r * 1. / crsum > maxfrac:
            break

        positions[1, 0] = 6. + r
        atoms.set_positions(positions)
        atoms.set_calculator(calc)
        E = atoms.get_potential_energy()
        F = atoms.get_forces()

        if E - sum(e_ref) > minE:
            atoms.info['key_value_pairs'] = {}
            atoms.info['key_value_pairs']['e_dft_ref'] = convert_array(e_ref)
            atoms.info['key_value_pairs']['f_dft_ref'] = 0.
            finalize(atoms, energy=E, forces=F)
            db.write(atoms, r=r, **atoms.info['key_value_pairs'])
            r += stepfrac * crsum
        else:
            break

    calc.exit()
    return
Exemplo n.º 3
0
def singlepoint(t):
    ''' This function will be used in the iter007 step, which restarts
    from the runXXX/godb.db databases from the iter006 step. 
    Since the repulsive interactions have been reparametrized in
    between, the structures in the database need to be re-evaluated.
    '''
    calc = DftbPlusCalculator(t, kpts=(1, 1, 1), use_spline=True,
                              maximum_angular_momenta={'Si': 1})
    t.set_calculator(calc)
    E = t.get_potential_energy()
    F = t.get_forces()
    S = None
    finalize(t, energy=E, forces=F, stress=S)
    return t
Exemplo n.º 4
0
def singlepoint(t, kptdensity=1.5):
    if get_raw_score(t) < -1e5:
        return t
    try:
        calc = DftbPlusCalc(t, kpts=kptdensity, use_spline=True, read_chg=True)
        t.set_calculator(calc)
        E = t.get_potential_energy()
        F = t.get_forces()
        S = t.get_stress()
        finalize(t, energy=E, forces=F, stress=S)
        penalize(t)
    except (RuntimeError, IOError):
        print('Warning: problems with singlepoint recalculation')
        finalize(t, energy=1e9, forces=None, stress=None)
    return t
Exemplo n.º 5
0
def generate_database(dbfile, rc):
    np.random.seed(123)
    db = connect(dbfile)

    rcov = covalent_radii[atomic_numbers['C']]
    lc = 2 * np.sqrt(3) * rcov
    slab = Graphene(symbol='C', latticeconstant=[lc, 12.]).repeat((3, 3, 1))
    slab.center()

    kwargs = {
        'maximum_angular_momenta': mam,
        'use_spline': False,
        'Hamiltonian_SlaterKosterFiles_Suffix': '"_no_repulsion.skf"'
    }
    calc = DftbPlusCalc(slab, **kwargs)
    slab.set_calculator(calc)
    e_ref_slab = slab.get_potential_energy()
    f_ref_slab = slab.get_forces()

    m = molecule('N2')
    m.positions += np.array([2.5, 3., 7.5])

    for i in range(10):
        print('Generating structure %d' % i)
        n2 = m.copy()
        for i, axis in enumerate('xyz'):
            angle = np.random.random() * 180.
            n2.rotate(angle, axis, center='COP')

        calc = DftbPlusCalc(n2, **kwargs)
        n2.set_calculator(calc)
        e_ref_n2 = n2.get_potential_energy()
        f_ref_n2 = n2.get_forces()

        atoms = slab + n2
        calc = DftbPlusCalc(atoms, **kwargs)
        atoms.set_calculator(calc)
        e = atoms.get_potential_energy()
        f = atoms.get_forces()

        e_rep, f_rep = calculate_target_repulsion(atoms, rc)
        finalize(atoms, energy=e + e_rep, forces=f + f_rep, stress=None)

        e_dft_ref = convert_array([e_ref_slab, e_ref_n2])
        f_dft_ref = convert_array(np.vstack((f_ref_slab, f_ref_n2)))
        db.write(atoms, relaxed=1, e_dft_ref=e_dft_ref, f_dft_ref=f_dft_ref)

    return
Exemplo n.º 6
0
def singlepoint(t, kptdensity=3.5):
    if get_raw_score(t) < -1e5:
        return t
    try:
        calc = DftbPlusCalculator(t, kpts=kptdensity, use_spline=True,
                              maximum_angular_momenta={'Pd': 2, 'H': 0, 'O': 1})
        t.set_calculator(calc)
        E = t.get_potential_energy()
        F = t.get_forces()
        S = t.get_stress()
        finalize(t, energy=E, forces=F, stress=S)
        penalize(t)
    except (IOError, TypeError, RuntimeError, UnboundLocalError) as err:
        print(err)
        print('Warning: problems with singlepoint recalculation')
        finalize(t, energy=1e9, forces=None, stress=None)
    return t
Exemplo n.º 7
0
def relax_one(t):
    ''' This method defines how to locally minimize a given
    atoms object 't'.
    '''
    # The provided structure will often contain atoms separated
    # by relatively short distances. Pushing these atoms a bit
    # apart using a soft potential will reduce the number of
    # subsequent ionic steps and will help avoid DFTB convergence
    # problems.
    pos = t.get_positions()
    numbers = list(set(t.get_atomic_numbers()))
    blmin = closest_distances_generator(numbers, 0.5)
    t = push_apart(t, blmin, variable_cell=False)

    print('Starting relaxation', flush=True)
    clock = time()
    t.wrap()

    # Define the DFTB+ calculator:
    calc = DftbPlusCalculator(t, kpts=(1, 1, 1), use_spline=True,
                              maximum_angular_momenta={'Si': 1})

    # Start the actual relaxation using the 
    # tango.relax_utils.relax_precon method.
    # This wraps around the preconditioned
    # optimizers in ASE and also takes care of
    # setting the raw score etc.:
    try:
        t = relax_precon(t, calc, fmax=1e-2, variable_cell=False,
                         logfile=None, trajfile=None)
    except IOError:
        # the DFTB+ ASE calculator throws an IOError
        # in case it couldn't find the 'results.tag'
        # output file, which may sporadically happen
        # due to SCC converge issues when e.g. a Si7
        # cluster is breaking into fragments. We simply
        # handle this by aborting the relaxation and
        # assigning a very high energy to the structure:
        finalize(t, energy=1e9, forces=None, stress=None)

    print('Relaxing took %.3f seconds.' % (time() - clock), flush=True)
    return t
def generate_database(dbfile, d, rc):
    np.random.seed(123)
    db = connect(dbfile)
    #L = 12.
    atoms_vasp = read('POSCAR', index=0, format="vasp")
    #x0 = (L - d) / 2.
    #sym = ['Mg', 'O', 'O', 'Mg', 'O', 'Mg', 'Mg', 'O']
    sym = atoms_vasp.get_chemical_symbols()
    #cell = np.ones(3) * L
    cell = np.array(atoms_vasp.get_cell()) + 10.0
    #pos = []
    #for i in range(2):
    #    for j in range(2):
    #        for k in range(2):
    #            pos.append([x0 + i * d, x0 + j * d, x0 + k * d])
    pos = np.array(atoms_vasp.get_positions()) + 5.0

    assert rc > d, (rc, d)
    dispmax = 0.5 * (rc - d) / np.sqrt(3)

    for i in range(10):
        print('Generating structure %d' % i)
        disp = dispmax * 2 * (0.5 - np.random.random((len(sym), 3)))
        positions = np.array(pos) + disp
        atoms = Atoms(''.join(sym), cell=cell, pbc=False, positions=positions)
        for j in range(len(sym)):
            dr = np.linalg.norm(positions[j] - pos[j])
            assert dr < (rc - d), (dr, rc - d)

        suffix = '"_no_repulsion.skf"'
        calc = DftbPlusCalc(atoms,
                            maximum_angular_momenta=mam,
                            use_spline=False,
                            Hamiltonian_SlaterKosterFiles_Suffix=suffix)
        atoms.set_calculator(calc)
        e = atoms.get_potential_energy()
        f = atoms.get_forces()
        e_rep, f_rep = calculate_target_repulsion(atoms, rc)
        #finalize(atoms, energy=e+e_rep, forces=f+f_rep, stress=None)
        finalize(atoms, energy=e_rep, forces=f_rep, stress=None)
        db.write(atoms, relaxed=1)
    return
Exemplo n.º 9
0
def run_calc(dbfile, Calculator, kptdensity=None, relax=False, vc_relax=False,
             precon=True, maxsteps=20, maximum_angular_momenta=None,
             atomic_energies={}, referencing='atomic'):
    ''' Runs a calculator on each unrelaxed candidate in a database.

    dbfile: name of the database
    Calculator: a suitable calculator DFT or DFTB calculator class 
                (see tango.main)
    kptdensity: the k-point density to apply (in 1/A)
    relax: whether to do a short relaxation or only 
           perform a single-point calculation
    vc_relax: if also the cell vectors are to be varied
    precon: whether to use the preconditioned optimizers
    maxsteps: maximum number of ionic steps for the local optimizer
    maximum_angular_momenta: a dictionary with maximum angular momenta 
             for each element in the structure for DFTB calculations
    atomic_energies: dictionary with the DFT energies of the isolated
                     atoms. Used to calculate the reference energies
                     in the 'atomic' referencing scheme.
    referencing: the referencing scheme (see main.py)
    '''
    if vc_relax:
        assert precon

    db = connect(dbfile)
    relaxed_ids = set([row.gaid for row in db.select(relaxed=1)])

    for row in db.select(relaxed=0):
        if row.gaid in relaxed_ids:
            continue

        atoms = row.toatoms()
        mp = get_kpts(atoms, kptdensity)
        if maximum_angular_momenta is None:
            calc = Calculator(atoms, kpts=mp)
        else:
            calc = Calculator(atoms, kpts=mp,
                              maximum_angular_momenta=maximum_angular_momenta)
        atoms.set_calculator(calc)

        E = atoms.get_potential_energy()
        F = atoms.get_forces()
        try:
            S = atoms.get_stress() 
        except PropertyNotImplementedError:
            S = None
        finalize(atoms, energy=E, forces=F, stress=S)

        relax = relax and maxsteps > 0
        if relax:
            atoms2 = atoms.copy()
            numbers = list(set(atoms2.get_atomic_numbers()))
            blmin = closest_distances_generator(numbers, 0.5)
            atoms2 = push_apart(atoms2, blmin)
            atoms2.set_calculator(calc)
            atoms2 = do_short_relax(atoms2, index=row.gaid,
                                    precon=precon, vc_relax=vc_relax, 
                                    maxsteps=maxsteps)
            if vc_relax:
                # Additional single-point run
                calc.exit()
                mp = get_kpts(atoms2, kptdensity)
                if maximum_angular_momenta is None:
                    calc = Calculator(atoms2, kpts=mp)
                else:
                    calc = Calculator(atoms2, kpts=mp,
                             maximum_angular_momenta=maximum_angular_momenta)
                atoms2.set_calculator(calc)

            E = atoms2.get_potential_energy()
            F = atoms2.get_forces()
            try:
                S = atoms2.get_stress()
            except PropertyNotImplementedError:
                S = None
            finalize(atoms2, energy=E, forces=F, stress=S)

        # Calculate energy and force references
        for a in [atoms] if not relax else [atoms, atoms2]:
            e_ref = []
            f_ref = np.zeros((len(atoms), 3))
            if referencing == 'atomic':
                sym = a.get_chemical_symbols()
                e_ref.extend([atomic_energies['%s_DFT' % s] for s in sym])
            else:
                for indices in referencing:
                    b = a[indices]
                    b.set_calculator(calc)
                    e_ref.append(b.get_potential_energy())
                    f_ref[indices] = b.get_forces()

            a.info['key_value_pairs']['e_dft_ref'] = convert_array(e_ref)
            a.info['key_value_pairs']['f_dft_ref'] = convert_array(f_ref)
            # Add the structure to the database:
            db.write(a, relaxed=1, gaid=row.gaid, **a.info['key_value_pairs'])
        calc.exit()
    return
Exemplo n.º 10
0
def relax_one(t, kptdensity=3.5):
    cellbounds = CellBounds(
        bounds={
            'phi': [0.1 * 180., 0.9 * 180.],
            'chi': [0.1 * 180., 0.9 * 180.],
            'psi': [0.1 * 180., 0.9 * 180.],
            'a': [1.5, 20],
            'b': [1.5, 20],
            'c': [1.5, 20]
        })

    if not cellbounds.is_within_bounds(t.get_cell()):
        print('Candidate outside cellbounds -- skipping')
        finalize(t, energy=1e9, forces=None, stress=None)
        return t

    pos = t.get_positions()
    numbers = list(set(t.get_atomic_numbers()))
    blmin = closest_distances_generator(numbers, 0.5)
    t = push_apart(t, blmin, variable_cell=True)

    print('Starting relaxation', flush=True)
    clock = time()
    t.wrap()
    calc = DftbPlusCalculator(t,
                              kpts=0.66 * kptdensity,
                              use_spline=True,
                              read_chg=True,
                              maximum_angular_momenta={'C': 1})

    try:
        t = relax_precon(t,
                         calc,
                         fmax=2e-1,
                         smax=1e-2,
                         variable_cell=True,
                         optimizer='LBFGS',
                         a_min=1e-4,
                         cellbounds=cellbounds,
                         logfile='opt_first.log',
                         trajfile='opt_first.traj')
    except (IOError, TypeError, RuntimeError, UnboundLocalError) as err:
        # SCC or geometry optimization convergence problem
        print(err)

    del t.constraints
    t.wrap()
    calc = DftbPlusCalculator(t,
                              kpts=kptdensity,
                              use_spline=True,
                              read_chg=True,
                              maximum_angular_momenta={'C': 1})

    try:
        t = relax_precon(t,
                         calc,
                         fmax=1e-1,
                         smax=5e-3,
                         variable_cell=True,
                         optimizer='LBFGS',
                         a_min=1e-4,
                         cellbounds=cellbounds,
                         logfile='opt.log',
                         trajfile='opt.traj')
    except (IOError, TypeError, RuntimeError, UnboundLocalError) as err:
        # SCC or geometry optimization convergence problem
        print(err)
        try:
            t = read('opt.traj@-1')
            energy = t.get_potential_energy()
            forces = t.get_forces()
            stress = t.get_stress()
        except (FileNotFoundError, UnknownFileTypeError) as err:
            print(err)
            energy, forces, stress = (1e9, None, None)
        finalize(t, energy=energy, forces=forces, stress=stress)

    print('Relaxing took %.3f seconds.' % (time() - clock), flush=True)
    os.system('mv opt_first.traj prev_first.traj')
    os.system('mv opt_first.log prev_first.log')
    os.system('mv opt.log prev.log')
    os.system('mv opt.traj prev.traj')
    penalize(t)
    return t
Exemplo n.º 11
0
def relax_one(t, kptdensity=3.5):
    cellbounds = CellBounds(bounds={'phi': [0.1 * 180., 0.9 * 180.],
                                    'chi': [0.1 * 180., 0.9 * 180.],
                                    'psi': [0.1 * 180., 0.9 * 180.],
                                    'a': [1.5, 20], 'b': [1.5, 20],
                                    'c':[1.5, 20]})

    if not cellbounds.is_within_bounds(t.get_cell()):
        print('Candidate outside cellbounds -- skipping')
        finalize(t, energy=1e9, forces=None, stress=None)
        return t

    tags = t.get_tags()
    pos = t.get_positions()
    pairs = []
    for tag in list(set(tags)):
        indices = list(np.where(tags == tag)[0])
        if len(indices) == 2:
            pairs.append(indices)
    c = FixBondLengths(pairs)
    t.set_constraint(c)
    blmin = {(1, 1): 1.8, (1, 8): 0.9, (1, 46): 1.8, (8, 8): 2.0,
             (8, 46): 1.5, (46, 46): 1.5}
    t = push_apart(t, blmin, variable_cell=True)
    del t.constraints
    oh_bondlength = 0.97907
    for (o_atom, h_atom) in pairs:
        vec = t.get_distance(o_atom, h_atom, mic=True, vector=True)
        pos[h_atom] = pos[o_atom] + vec * oh_bondlength / np.linalg.norm(vec)
    t.set_positions(pos)

    print('Starting relaxation', flush=True)
    clock = time()
    t.wrap()
    calc = DftbPlusCalculator(t, kpts=0.66*kptdensity,
                              use_spline=True, read_chg=True,
                              maximum_angular_momenta={'Pd': 2, 'H': 0, 'O': 1})

    try:
        t = relax_precon(t, calc, fmax=2e-1, smax=1e-2, variable_cell=True,
                         optimizer='LBFGS', a_min=1e-4, cellbounds=cellbounds,
                         fix_bond_lengths_pairs=pairs, logfile='opt_first.log',
                         trajfile='opt_first.traj')
    except (IOError, TypeError, RuntimeError, UnboundLocalError) as err:
        # SCC or geometry optimization convergence problem
        print(err)
        if isinstance(t, Filter):
            t = t.atoms

    del t.constraints
    t.wrap()

    calc = DftbPlusCalculator(t, kpts=kptdensity,
                              use_spline=True, read_chg=True,
                              maximum_angular_momenta={'Pd': 2, 'H': 0, 'O': 1})

    try:
        t = relax_precon(t, calc, fmax=1e-1, smax=5e-3, variable_cell=True,
                         optimizer='LBFGS', a_min=1e-4, cellbounds=cellbounds,
                         fix_bond_lengths_pairs=pairs, logfile='opt.log',
                         trajfile='opt.traj')
    except (IOError, TypeError, RuntimeError, UnboundLocalError) as err:
        # SCC or geometry optimization convergence problem
        print(err)
        try:
            t = read('opt.traj@-1')
            energy = t.get_potential_energy()
            forces = t.get_forces()
            stress = t.get_stress()
        except (FileNotFoundError, UnknownFileTypeError) as err:
            print(err)
            energy, forces, stress = (1e9, None, None)

        if isinstance(t, Filter):
            t = t.atoms
        finalize(t, energy=energy, forces=forces, stress=stress)

    print('Relaxing took %.3f seconds.' % (time() - clock), flush=True)
    os.system('mv opt_first.traj prev_first.traj')
    os.system('mv opt_first.log prev_first.log')
    os.system('mv opt.log prev.log')
    os.system('mv opt.traj prev.traj')
    penalize(t)
    return t
Exemplo n.º 12
0
def relax_one(t, kptdensity=1.5):
    cellbounds = CellBounds(
        bounds={
            'phi': [0.1 * 180., 0.9 * 180.],
            'chi': [0.1 * 180., 0.9 * 180.],
            'psi': [0.1 * 180., 0.9 * 180.],
            'a': [1.5, 20],
            'b': [1.5, 20],
            'c': [1.5, 20]
        })

    if not cellbounds.is_within_bounds(t.get_cell()):
        print('Candidate outside cellbounds -- skipping')
        finalize(t, energy=1e9, forces=None, stress=None)
        return t

    pos = t.get_positions()
    numbers = list(set(t.get_atomic_numbers()))
    blmin = closest_distances_generator(numbers, 0.5)
    t = push_apart(t, blmin, variable_cell=True)

    print('Starting relaxation', flush=True)
    clock = time()
    t.wrap()
    calc = DftbPlusCalc(t,
                        kpts=0.66 * kptdensity,
                        use_spline=True,
                        read_chg=True)

    try:
        t = relax_precon(t,
                         calc,
                         fmax=5e-1,
                         smax=5e-2,
                         variable_cell=True,
                         optimizer='LBFGS',
                         a_min=1e-4,
                         cellbounds=cellbounds,
                         logfile='opt_first.log',
                         trajfile='opt_first.traj')
    except IOError as err:
        # probably convergence problem
        print(err.message)
    except TypeError as err:
        if 'Cannot cast array data' in err.message:
            # Rare precon failure
            print(err.message)
        else:
            raise
    except RuntimeError as err:
        print(err.message)

    del t.constraints
    t.wrap()
    calc = DftbPlusCalc(t, kpts=kptdensity, use_spline=True, read_chg=True)
    try:
        t = relax_precon(t,
                         calc,
                         fmax=5e-1,
                         smax=5e-2,
                         variable_cell=True,
                         optimizer='LBFGS',
                         a_min=1e-4,
                         cellbounds=cellbounds,
                         logfile='opt.log',
                         trajfile='opt.traj')
    except (IOError, TypeError, RuntimeError) as err:
        # probably convergence problem
        print(err.message)
        if isinstance(err, TypeError):
            if 'Cannot cast array data' not in err.message:
                raise
        elif isinstance(err, RuntimeError):
            if 'dftb_my in . returned an error:' not in err.message:
                raise
        try:
            t = read('opt.traj@-1')
            energy = t.get_potential_energy()
            forces = t.get_forces()
            stress = t.get_stress()
        except UnknownFileTypeError as err:
            print(err.message)
            energy, forces, stress = (1e9, None, None)
        finalize(t, energy=energy, forces=forces, stress=stress)

    print('Relaxing took %.3f seconds.' % (time() - clock), flush=True)
    os.system('mv opt_first.traj prev_first.traj')
    os.system('mv opt_first.log prev_first.log')
    os.system('mv opt.log prev.log')
    os.system('mv opt.traj prev.traj')
    penalize(t)
    return t