Exemple #1
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
Exemple #2
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
Exemple #3
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
Exemple #4
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
Exemple #5
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