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 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
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
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
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