Beispiel #1
0
    def __getitem__(self, i=-1):
        b = self.backend[i]
        atoms = Atoms(positions=b.positions,
                      numbers=self.numbers,
                      cell=b.cell,
                      masses=self.masses,
                      pbc=self.pbc,
                      celldisp=self.celldisp,
                      info=b.get('info'),
                      constraint=[dict2constraint(d)
                                  for d in decode(self.constraints)],
                      momenta=b.get('momenta'),
                      magmoms=b.get('magmoms'),
                      charges=b.get('charges'),
                      tags=b.get('tags'))

        atoms._readTags(self.new_tags)

        if 'calculator' in b:
            results = {}
            c = b.calculator
            for prop in all_properties:
                if prop in c:
                    results[prop] = c.get(prop)
            calc = SinglePointCalculator(atoms, **results)
            calc.name = b.calculator.name
            atoms.set_calculator(calc)
        return atoms
Beispiel #2
0
    def __getitem__(self, i=-1):
        if isinstance(i, slice):
            return SlicedTrajectory(self, i)
        b = self.backend[i]
        if 'numbers' in b:
            # numbers and other header info was written alongside the image:
            atoms = read_atoms(b, traj=self)
        else:
            # header info was not written because they are the same:
            atoms = read_atoms(
                b,
                header=[self.pbc, self.numbers, self.masses, self.constraints],
                traj=self)
        if 'calculator' in b:
            results = {}
            implemented_properties = []
            c = b.calculator
            for prop in all_properties:
                if prop in c:
                    results[prop] = c.get(prop)
                    implemented_properties.append(prop)
            calc = SinglePointCalculator(atoms, **results)
            calc.name = b.calculator.name
            calc.implemented_properties = implemented_properties

            if 'parameters' in c:
                calc.parameters.update(c.parameters)
            atoms.calc = calc

        return atoms
Beispiel #3
0
    def write(self, at, **kwargs):
        import ase.db
        from ase.calculators.singlepoint import SinglePointCalculator

        all_kwargs = self.kwargs.copy()
        all_kwargs.update(kwargs)
        all_kwargs.update(at.params)

        energy = at.params.get('energy', None)
        forces = getattr(at, 'force', None)
        if forces is not None:
            forces = forces.T
        stress = at.params.get('virial', None)
        if stress is not None:
            stress = -stress.view(np.ndarray) / at.get_volume()

        orig_calc = at.get_calculator()

        params = {}
        data = {}
        skip_params = ['energy', 'virial', 'calculator', 'id',
                       'unique_id']  # filter out duplicate data
        for (key, value) in all_kwargs.items():
            key = key.lower()
            if key in skip_params:
                continue
            if (isinstance(value, int) or isinstance(value, basestring)
                    or isinstance(value, float) or isinstance(value, bool)):
                # scalar key/value pairs
                params[key] = value
            else:
                # more complicated data structures
                data[key] = value

        skip_arrays = ['numbers', 'positions', 'species']
        for (key, value) in at.arrays.items():
            if key in skip_arrays:
                continue
            key = key.lower()
            data[key] = value

        try:
            calc = SinglePointCalculator(atoms=at,
                                         energy=energy,
                                         forces=forces,
                                         stress=stress)
            if orig_calc is not None:
                calc.name = orig_calc.name
            else:
                calc.name = all_kwargs.get('calculator', '(unknown)')
            at.set_calculator(calc)

            database = ase.db.connect(self.dbfile)
            database.write(at, key_value_pairs=params, data=data)
        finally:
            at.set_calculator(orig_calc)
Beispiel #4
0
def irc(minmode, maxiter, ftol, dx=0.01, direction='both', **kwargs):
    d = minmode.d

    if direction not in ['forward', 'reverse', 'both']:
        raise ValueError("Don't understand direction='{}'".format(direction))

    x = minmode.x_m.copy()
    conf = minmode.atoms.copy()
    calc = SinglePointCalculator(conf, **minmode.atoms.calc.results)
    conf.set_calculator(conf)
    path = [conf]
    f1, g1, _ = minmode.kick(np.zeros_like(x))
    minmode.f_minmode(**kwargs)

    if np.linalg.norm(g1) > ftol:
        warnings.warn('Initial forces are greater than convergence tolerance! '
                      'Are you sure this is a transition state?')

    if direction == 'both':
        x0 = minmode.x.copy()
        H = minmode.H.copy()
        last = minmode.last.copy()
        fpath = irc(minmode, maxiter, ftol, dx, 'forward', **kwargs)
        minmode.x = x0
        minmode.H = H
        minmode.last = last
        rpath = irc(minmode, maxiter, ftol, dx, 'reverse', **kwargs)
        return list(reversed(fpath)) + rpath[1:]

    d1 = minmode.vecs[:, 0]
    d1 *= dx / np.linalg.norm(d1)
    if direction == 'reverse':
        d1 *= -1

    xi = 1.

    # Outer loop finds all points along the MEP
    while True:
        f1, g1, _ = minmode.kick(d1)
        # Inner loop optimizes each individual point along the MEP
        while True:
            eps, xi = rs_newton_irc(minmode, g1, d1, dx, xi)
            epsnorm = np.linalg.norm(eps)
            print('Epsnorm is {}'.format(epsnorm))
            if epsnorm < 1e-4:
                break
            f1, g1, _ = minmode.kick(eps)
            d1 += eps

        conf = minmode.atoms.copy()
        calc = SinglePointCalculator(conf, **minmode.atoms.calc.results)
        conf.set_calculator(calc)
        path.append(conf)
        if np.all(minmode.lams > 0) and minmode.converged(ftol):
            return path
def test_standardcomparator():
    from ase.ga.standard_comparators import (InteratomicDistanceComparator,
                                             EnergyComparator,
                                             RawScoreComparator,
                                             SequentialComparator)
    from ase import Atoms
    from ase.calculators.singlepoint import SinglePointCalculator
    from ase.ga import set_raw_score

    a1 = Atoms('AgAgAg', positions=[[0, 0, 0], [1.5, 0, 0], [1.5, 1.5, 0]])
    a2 = Atoms('AgAgAg', positions=[[0, 0, 0], [1.4, 0, 0], [1.5, 1.5, 0]])

    e1 = 1.0
    e2 = 0.8

    a1.set_calculator(SinglePointCalculator(a1, energy=e1))
    a2.set_calculator(SinglePointCalculator(a2, energy=e2))

    comp1 = InteratomicDistanceComparator(n_top=3,
                                          pair_cor_cum_diff=0.03,
                                          pair_cor_max=0.7,
                                          dE=0.3)
    assert comp1.looks_like(a1, a2)

    comp2 = InteratomicDistanceComparator(n_top=3,
                                          pair_cor_cum_diff=0.03,
                                          pair_cor_max=0.7,
                                          dE=0.15)
    assert not comp2.looks_like(a1, a2)

    comp3 = InteratomicDistanceComparator(n_top=3,
                                          pair_cor_cum_diff=0.02,
                                          pair_cor_max=0.7,
                                          dE=0.3)
    assert not comp3.looks_like(a1, a2)

    hard_E_comp = EnergyComparator(dE=1.0)
    assert hard_E_comp.looks_like(a1, a2)

    soft_E_comp = EnergyComparator(dE=.01)
    assert not soft_E_comp.looks_like(a1, a2)

    set_raw_score(a1, .1)
    set_raw_score(a2, .27)

    rs_comp = RawScoreComparator(0.15)
    assert not rs_comp.looks_like(a1, a2)

    comp1 = SequentialComparator([hard_E_comp, rs_comp], [0, 0])
    assert not comp1.looks_like(a1, a2)

    comp2 = SequentialComparator([hard_E_comp, rs_comp], [0, 1])
    assert comp2.looks_like(a1, a2)
Beispiel #6
0
 def __getitem__(self, i=-1):
     b = self.backend[i]
     atoms = read_atoms(b, header=[self.pbc, self.numbers, self.masses,
                                   self.constraints])
     if 'calculator' in b:
         results = {}
         c = b.calculator
         for prop in all_properties:
             if prop in c:
                 results[prop] = c.get(prop)
         calc = SinglePointCalculator(atoms, **results)
         calc.name = b.calculator.name
         atoms.set_calculator(calc)
     return atoms
Beispiel #7
0
    def convert(self):
        lines = open(self.xdatcar).readlines()
        if len(lines[7].split()) == 0:
            del (lines[0:8])
        elif len(lines[5].split()) == 0:
            del (lines[0:6])
        elif len(lines[4].split()) == 0:
            del (lines[0:5])
        elif lines[7].split()[0] == 'Direct':
            del (lines[0:8])
        step = 0
        iatom = 0
        scaled_pos = []
        for line in lines:
            if iatom == len(self.atoms):
                if step == 0:
                    self.out.write_header(self.atoms[self.calc.resort])
                scaled_pos = np.array(scaled_pos)
                # Now resort the positions to match self.atoms
                self.atoms.set_scaled_positions(scaled_pos[self.calc.resort])

                calc = SinglePointCalculator(self.atoms,
                                             energy=self.energies[step],
                                             forces=self.forces[step])
                self.atoms.calc = calc
                self.out.write(self.atoms)
                scaled_pos = []
                iatom = 0
                step += 1
            else:
                if not line.split()[0] == 'Direct':
                    iatom += 1
                    scaled_pos.append(
                        [float(line.split()[n]) for n in range(3)])

        # Write also the last image
        # I'm sure there is also more clever fix...
        if step == 0:
            self.out.write_header(self.atoms[self.calc.resort])
        scaled_pos = np.array(scaled_pos)[self.calc.resort]
        self.atoms.set_scaled_positions(scaled_pos)
        calc = SinglePointCalculator(self.atoms,
                                     energy=self.energies[step],
                                     forces=self.forces[step])
        self.atoms.calc = calc
        self.out.write(self.atoms)

        self.out.close()
Beispiel #8
0
def load_castep(file_name):
    """Load the results of a CASTEP calculation

    Args:
      file_name (str): name of the `*-out.cell` file to load.

    Returns:
      atoms (ase.Atoms): the loaded ase atoms object with a CASTEP
        single point calculator containing thr results of the computation
        attached.
    """
    atoms = io.read(file_name)
    try:
        # Create a calculator to store the energy & forces
        atoms_cast = io.read(file_name.replace('-out.cell', '.castep'))
        energy = atoms_cast.get_potential_energy()
        forces = atoms_cast.get_forces()
        spcalc = SinglePointCalculator(atoms, energy=energy, forces=forces)
        atoms.set_calculator(spcalc)
    except:
        # Something is wrong. The run didn't finish executing or failed to
        # converge
        print("Failed to load -out.cell file")
    atoms.set_tags(tag_muon(atoms))
    atoms.info['original_file'] = file_name.replace('-out.cell', '.cell')
    return atoms
def main():
    db_name = "data/almgsicu.db"
    traj = TrajectoryWriter("data/almgsicu_data.traj")
    db = connect(db_name)
    groups = set()
    for row in db.select():
        g = row.get('group', None)
        if g is not None and g not in exclude_groups:
            groups.add(g)

    structures = []
    for g in groups:
        row = db.get(group=g, struct_type='initial')
        init = row.toatoms()
        if init.get_chemical_formula() in ignore_formulas:
            continue
        try:
            final = db.get(group=g, struct_type='relaxed')
        except:
            continue
        energy = 0.0
        if final is not None:
            energy = final.energy
            calc = SinglePointCalculator(init, energy=energy)
            init.calc = calc
            structures.append(init)
    
    for idx in sorted(equiv_from_atat, reverse=True):
        del structures[idx]
    for s in structures:
        traj.write(s)
Beispiel #10
0
def new_db(kwargs, new_db_name):
    db_name = "almgsi_newconfig.db"
    kwargs["db_name"] = new_db_name
    bc = BulkCrystal(**kwargs)
    names = []
    db = connect(db_name)
    for row in db.select(converged=1):
        names.append(row.name)

    ns = GenerateStructures(bc, struct_per_gen=10)
    for name in names:
        print(name)
        init_struct = None
        final_struct = None
        energy = 0.0
        for row in db.select(name=name):
            if row["calculator"] == "unknown":
                energy = row.energy
                init_struct = row.toatoms()
            else:
                final_struct = row.toatoms()
        calc = SinglePointCalculator(final_struct, energy=energy)
        final_struct.set_calculator(calc)
        try:
            ns.insert_structure(init_struct=init_struct, final_struct=final_struct, generate_template=True)
        except Exception as exc:
            print(str(exc))
Beispiel #11
0
  def get_traj(self):
      self.uc= np.linalg.inv(self.cell)
      images = []
      his    = TrajectoryWriter(self.structure+'.traj',mode='w')
      indexs = np.array(self.indexs)
      ind    = indexs.argsort()
      batch_ = self.batch if self.nframe>self.batch else self.nframe

      for i in range(batch_):
          ii  = ind[i]
          xf  = np.dot(self.x[ii],self.uc) 
          xf  = np.mod(xf,1.0)  
          self.x[ii] = np.dot(xf,self.cell)
          if self.qs is None:
             c = None
          else:
             c = self.qs[i]
          A   = Atoms(self.atom_name,self.x[ii],
                      charges=c,
                      cell=self.cells[ii],pbc=[True,True,True])
          if self.checkMol:
             A =  press_mol(A)

          calc = SinglePointCalculator(A,energy=float(self.energy_nw[ii]))
          A.set_calculator(calc)
          his.write(atoms=A)
          images.append(A)
      his.close()
      return images
Beispiel #12
0
    def save_current_status(self):
        # save current atoms
        t = self.atoms.copy()
        t.info = self.atoms.info.copy()
        e = self.atoms.get_potential_energy()
        f = self.atoms.get_forces()
        spc = SinglePointCalculator(t, energy=e, forces=f)
        t.set_calculator(spc)
        write(self.fn_current_atoms, t)

        accept_digits = ""
        for ii in self.accept_history:
            accept_digits += str(ii)
            accept_digits += ","
        accept_digits = accept_digits[:-1]

        # save the current status of the basin hopping
        info = {
            "nsteps": self.nsteps,
            "no_improvement_step": self.no_improvement_step,
            'Temperature': self.T,
            "free_energy_min": self.free_energy_min,
            "energy_min": self.energy_min,
            'history': accept_digits,
            'on_optimization': self.on_optimization
        }
        with open(self.fn_status_file, "w") as fp:
            json.dump(info,
                      fp,
                      sort_keys=True,
                      indent=4,
                      separators=(',', ': '))
def extract_cluster(atoms):
    max_dist = 3.0
    mg_indx = [atom.index for atom in atoms if atom.symbol == "Mg"]
    indices = deepcopy(mg_indx)
    for indx in mg_indx:
        indx_dist = list(range(len(atoms)))
        del indx_dist[indx]
        indx_dist = np.array(indx_dist)
        dists = atoms.get_distances(indx, indx_dist, mic=True)
        dists = np.array(dists)
        new_indx = indx_dist[dists<max_dist]
        indices += list(new_indx)
    indices = list(set(indices))
    cluster = atoms[indices]
    cell = cluster.get_cell()
    diag = 0.5*(cell[0, :] + cell[1, :] + cell[2, :])
    indices = list(range(1, len(cluster)))
    dist = cluster.get_distances(0, indices, mic=True, vector=True)
    com = np.mean(dist, axis=0) + cluster[0].position
    cluster.translate(diag-com)
    cluster.wrap()

    energy = atoms.get_potential_energy()
    calc = SinglePointCalculator(cluster, energy=energy)
    cluster.set_calculator(calc)
    return cluster
Beispiel #14
0
def amp_data(lab='amp',
             dft='siesta',
             dic='/home/gfeng/siesta/train/ethane',
             batch=800,sort=False):
    ''' prepare data for AMP '''
    md = MDtoData(dft=dft,direc=dic,
                  batch=batch,sort=sort)

    if len(md.energy_nw)<batch:
       batch = len(md.energy_nw)

    box = [md.cell[0][0],md.cell[1][1],md.cell[2][2]]
    his = TrajectoryWriter(lab+'.traj',mode='w')

    for i in range(batch):
        md.energy_nw[i]
        x = np.mod(md.x[i],box)  
        A = Atoms(md.atom_name,x,cell=md.cell,pbc=[True,True,True])

        e = float(md.energy_nw[i]) 
        calc = SinglePointCalculator(A,energy=e,
                                     free_energy=float(md.max_e),
                                     forces=md.forces[i])

        A.set_calculator(calc)
        his.write(atoms=A)
        del A
    his.close()
Beispiel #15
0
def read_positions_qe(qe_output_name):
    """
    Input a QE logfile name and it extracts the postions and cells to build a
    trajectory file.
    May only work for pw?
    """
    # initialize arrays and atoms object
    steps = extract_coordinates(qe_output_name)
    energies = get_total_energies(qe_output_name)
    nsteps = max(steps.keys()) + 1
    forces = get_forces(qe_output_name)

    images = []
    for istep in range(nsteps):
        symbols = [
            ''.join(i for i in s if not i.isdigit())
            for s in [i[0] for i in steps[istep]['positions']]
        ]
        positions = [i[1] for i in steps[istep]['positions']]
        mask = [len(i) != 3 for i in positions]
        posclean = [i[:3] for i in positions]
        cell = steps[istep]['cell']
        atoms = Atoms(symbols, posclean, cell=cell, pbc=(1, 1, 1))
        atoms.set_constraint(FixAtoms(mask=mask))
        calc = SinglePointCalculator(atoms=atoms,
                                     energy=energies[istep],
                                     forces=forces[istep],
                                     stress=None,
                                     magmoms=None)
        atoms.set_calculator(calc)
        images.append(atoms)

    return images
Beispiel #16
0
def decompostion(gen='rdx.gen', ncpu=12):
    ''' decompostion energy of N-NO2 '''
    traj = TrajectoryWriter('stretch.traj', mode='w')
    ncfg = 20
    A = read(gen)
    s = stretch(A,
                shrink=0.8,
                enlarge=2.6,
                fix_end=3,
                move_end=18,
                move_atoms=[18, 19, 20],
                nconfig=ncfg)
    for i in range(ncfg):
        atoms = s.move(i)
        write_nwchem_inp(atoms,
                         struc=gen.split('.')[0],
                         task='dft gradient',
                         xc='b3lyp',
                         basis='6-311G*')

        system('mpirun -n %d nwchem inp-nw > nw.out' % (ncpu))
        e, grad_ = get_nw_gradient(out='nw.out')
        system('cp nw.out nw_%s.out' % str(i))
        system('rm QMD-*')
        print('-  energy(NWchem):', e)
        calc = SinglePointCalculator(atoms, energy=e)
        atoms.set_calculator(calc)
        traj.write(atoms=atoms)
    traj.close()
Beispiel #17
0
def main(rowNum):
    conc = get_conc(rowNum)
    print(conc)
    if conc is None:
        return

    settings = settings_from_json(settings_file)
    atoms = bulk('Al', a=4.05, crystalstructure='fcc', cubic=True) * (N, N, N)

    atoms = attach_calculator(settings, atoms, get_eci())
    cu = ['Cu'] * int(conc['Cu'] * len(atoms))
    si = ['Si'] * int(conc['Si'] * len(atoms))
    mg = ['Mg'] * int(conc['Mg'] * len(atoms))
    al = ['Al'] * (len(atoms) - len(cu) - len(mg) - len(si))
    symbols = al + mg + si + cu
    shuffle(symbols)
    atoms.symbols = symbols

    # Trigger a calculation
    atoms.get_potential_energy()
    temperatures = list(range(1000, 1, -50))
    obs = LowestEnergyStructure(atoms)

    for T in temperatures:
        print(f"Temperature {T}")
        mc = Montecarlo(atoms, T)
        mc.attach(obs)
        mc.run(steps=20 * len(atoms))

    db = connect(db_name)
    calc = SinglePointCalculator(obs.emin_atoms, energy=obs.lowest_energy)
    obs.emin_atoms.set_calculator(calc)
    db.write(obs.emin_atoms)
Beispiel #18
0
def load_dftb_calculator(directory, atoms):
    """ Set the tag for a muon in an atoms object

    Args:
      directory (str): path to a directory to load DFTB+ results

    Returns:
      calculator (ase.calculator.SinglePointCalculator): a single
        point calculator for the results of the DFTB+ calculation
    """
    results_file = os.path.join(directory, "results.tag")
    temp_file = os.path.join(directory, "results.tag.bak")

    # We need to backup the results file here because
    # .read_results() will remove the results file
    with BackupFile(results_file, temp_file):
        calc = Dftb(atoms=atoms)
        calc.atoms_input = atoms
        calc.directory = directory
        calc.read_results()

    return SinglePointCalculator(atoms, energy=calc.get_potential_energy(),
                                 forces=calc.get_forces(),
                                 charges=calc.get_charges(atoms),
                                 stress=calc.get_stress(atoms))
Beispiel #19
0
    def to_ase(self):
        arrays_keys = set(self.arrays_keys)
        info_keys = set(self.info_keys)

        cell = self.pop('cell', None)
        pbc = self.pop('pbc', None)
        numbers = self.pop('numbers', None)
        positions = self.pop('positions', None)
        results_keys = self.derived['results_keys']

        info_keys -= {'cell', 'pbc'}
        arrays_keys -= {'numbers', 'positions'}

        atoms = Atoms(cell=cell, pbc=pbc, numbers=numbers, positions=positions)

        if 'calculator_name' in self:
            # calculator_name = self['info'].pop('calculator_name')
            # atoms.calc = get_calculator(data['results']['calculator_name'])(**params)

            params = self.pop('calculator_parameters', {})

            atoms.calc = SinglePointCalculator(atoms, **params)
            atoms.calc.results.update((key, self[key]) for key in results_keys)

        atoms.arrays.update((key, np.array(self[key])) for key in arrays_keys)
        atoms.info.update((key, self[key]) for key in info_keys)

        return atoms
Beispiel #20
0
def load_dftb_precon(file_name):
    """Load the results of a DFTB+ calculation that was run
    with the ASE preconditioned optimizer

    Args:
        file_name (str): name of the `results.json` file to load.

    Returns:
      atoms (ase.Atoms): the loaded ase atoms object with a DFTB+
        single point calculator containing the results of the computation
        attached.
    """

    def load_file(file_name):
        atoms = io.read(file_name)
        atoms_orig = io.read(file_name.replace(".xyz", ".gen"))
        atoms.cell = atoms_orig.cell
        return atoms

    results = json.load(open(file_name, 'r'))
    atoms_file = 'geo_end.xyz'
    atoms = load_file(os.path.join(os.path.dirname(file_name), atoms_file))

    calc = SinglePointCalculator(atoms, energy=results['energy'],
                                 forces=results['forces'])
    atoms.set_calculator(calc)
    atoms.set_tags(tag_muon(atoms))

    return atoms
Beispiel #21
0
def read_lammps_dump(fdump, nequil=None, iframes=None):
  from ovito.io import import_file
  pl = import_file(fdump) # pipe line
  nframe = pl.source.num_frames
  traj = []
  if iframes is None:
    iframes = range(nframe)
  if nequil is not None:
    iframes = iframes[nequil:]
  for iframe in iframes:
    dc = pl.compute(iframe) # data collection
    atoms = dc.to_ase_atoms()
    atoms.info['Timestep'] = dc.attributes['Timestep']
    keys_to_delete = [key for key in atoms.arrays.keys()
      if key not in ['numbers', 'positions']]
    for key in keys_to_delete:
      del atoms.arrays[key]
    # any results to add?
    results = get_particle_results(dc)
    if 'Charge' in results:  # add charges
      atoms.set_initial_charges(results['Charge'])
    add_results = {}
    lmp_names = ['Force', 'Dipole Orientation']
    ase_names = ['forces', 'dipole']
    for lmp_name, ase_name in zip(lmp_names, ase_names):
      if lmp_name in results:
        add_results[ase_name] = results[lmp_name]
    traj.append(atoms)
    if len(add_results) > 0:
      from ase.calculators.singlepoint import SinglePointCalculator
      calc = SinglePointCalculator(atoms)
      calc.results.update(add_results)
      atoms.set_calculator(calc)
  return traj
Beispiel #22
0
    def __init__(self, atoms):
        """
        | It wraps :obj:`ase.Atoms` object to define additional methods
          and attributes.
        | Before wrapping, it sorts atoms by element alphabetically.
        | It stores calculated neighbor information such as distance,
          indices.

        Args:
            atoms (~ase.Atoms): an object to wrap.
        """
        tags = atoms.get_chemical_symbols()
        deco = sorted([(tag, i) for i, tag in enumerate(tags)])
        indices = [i for tag, i in deco]
        self._atoms = atoms[indices]

        results = {}
        calculator = atoms.get_calculator()
        if calculator:
            for key, value in calculator.results.items():
                if key in atoms.arrays:
                    results[key] = value[indices]
                else:
                    results[key] = value
        self._atoms.set_calculator(
            SinglePointCalculator(self._atoms, **results))

        self._cache = {}
Beispiel #23
0
def calc(id):
    db = connect(db_name)
    atoms_orig = db.get_atoms(id=id)
    kvp = db.get(id=id).key_value_pairs
    atoms = atoms_orig.copy()

    # Do linear interpolation of the cell size
    a_au = 4.0782
    a_cu = 3.6149

    symbs = atoms.get_chemical_symbols()
    count = {"Au": 0, "Cu": 0}
    for s in symbs:
        count[s] += 1
    c_au = float(count["Au"]) / len(atoms)
    a = a_au * c_au + a_cu * (1.0 - c_au)
    a_orig = 3.9
    cell = atoms.get_cell()
    atoms.set_cell(cell * a / a_orig, scale_atoms=True)
    calc = EMT()
    atoms.set_calculator(calc)
    relaxer = BFGS(atoms)
    relaxer.run(fmax=0.025)
    res = minimize(relax_cell, a, args=(atoms, cell))
    print(res["x"])
    relaxer = BFGS(atoms)
    relaxer.run(fmax=0.025)
    energy = atoms.get_potential_energy()

    del db[id]
    calc = SinglePointCalculator(atoms_orig, energy=energy)
    atoms_orig.set_calculator(calc)
    kvp["converged"] = True
    db.write(atoms_orig, key_value_pairs=kvp)
Beispiel #24
0
def dict2atoms(dct, attach_calculator=False):
    constraint_dicts = dct.get('constraints')
    if constraint_dicts:
        constraints = []
        for c in constraint_dicts:
            assert c.pop('__name__') == 'ase.constraints.FixAtoms'
            constraints.append(FixAtoms(**c))
    else:
        constraints = None

    atoms = Atoms(dct['numbers'],
                  dct['positions'],
                  cell=dct['cell'],
                  pbc=dct['pbc'],
                  magmoms=dct.get('magmoms'),
                  charges=dct.get('charges'),
                  tags=dct.get('tags'),
                  masses=dct.get('masses'),
                  momenta=dct.get('momenta'),
                  constraint=constraints)

    results = dct.get('results')
    if attach_calculator:
        atoms.calc = get_calculator(
            dct['calculator_name'])(**dct['calculator_parameters'])
    elif results:
        atoms.calc = SinglePointCalculator(atoms, **results)

    return atoms
Beispiel #25
0
def convert_to_cubic(setting_prim):
    conc_args = {
        "conc_ratio_min_1":[[64,0,0]],
        "conc_ratio_max_1":[[24,40,0]],
        "conc_ratio_min_2":[[64,0,0]],
        "conc_ratio_max_2":[[22,21,21]]
    }
    setting_cubic = BulkCrystal( crystalstructure="fcc", a=4.05, size=[3,3,3], basis_elements=[["Mg","Si","Al",]], \
    conc_args=conc_args, db_name=db_name_cubic, max_cluster_size=4, cubic=True )
    view(setting_cubic.atoms)
    atoms = setting_prim.atoms.copy()
    a = 4.05
    atoms.set_cell([[4*a,0,0],[0,4*a,0],[0,0,4*a]])
    atoms.wrap()
    view(atoms)
    print (setting_prim.atoms.get_cell())
    exit()
    out_file = "data/temp_out.xyz"
    target_cell = setting_cubic.atoms.get_cell()
    cubic_str_gen = struc_generator = GenerateStructures( setting_cubic, struct_per_gen=10 )
    db = connect(db_name)
    for row in db.select(converged=1):
        energy = row.energy
        atoms = row.toatoms()
        atoms.set_cell(target_cell)
        atoms.wrap()
        write(out_file,atoms)
        calc = SinglePointCalculator(atoms,energy=energy)
        atoms.set_calculator(calc)
        cubic_str_gen.insert_structure(init_struct=out_file,final_struct=atoms)
Beispiel #26
0
    def to_labeled_system(self, data, *args, **kwargs):
        '''Convert System to ASE Atoms object.'''
        from ase import Atoms
        from ase.calculators.singlepoint import SinglePointCalculator

        structures = []
        species = [data['atom_names'][tt] for tt in data['atom_types']]

        for ii in range(data['coords'].shape[0]):
            structure = Atoms(symbols=species,
                              positions=data['coords'][ii],
                              pbc=not data.get('nopbc', False),
                              cell=data['cells'][ii])

            results = {
                'energy': data["energies"][ii],
                'forces': data["forces"][ii]
            }
            if "virials" in data:
                # convert to GPa as this is ase convention
                v_pref = 1 * 1e4 / 1.602176621e6
                vol = structure.get_volume()
                results['stress'] = data["virials"][ii] / (v_pref * vol)

            structure.calc = SinglePointCalculator(structure, **results)
            structures.append(structure)

        return structures
Beispiel #27
0
    def singlePoint(self, anew):
        a = anew.copy()

        # Save structure with ML-energy
        if self.master:
            self.writer_spPredict.write(a)

        # broadcast structure, so all cores have the same
        pos = a.positions
        if self.master:
            pos = a.positions
        self.comm.broadcast(pos, 0)
        a.positions = pos
        self.comm.barrier()

        # Perform single-point
        label = self.traj_namebase + '{}'.format(self.traj_counter)
        E, F = singleGPAW(a, label, calc=self.calc)
        self.comm.barrier()

        # save structure for training
        results = {'energy': E, 'forces': F}
        calc_sp = SinglePointCalculator(a, **results)
        a.set_calculator(calc_sp)
        self.a_add.append(a)

        # Save to spTrain-trajectory
        self.writer_spTrain.write(a, energy=E, forces=F)
        self.ksaved += 1
        return E, F
Beispiel #28
0
def read_dacapo(filename):
    from ase.io.pupynere import NetCDFFile

    nc = NetCDFFile(filename)
    vars = nc.variables

    cell = vars['UnitCell'][-1]
    try:
        magmoms = vars['InitialAtomicMagneticMoment'][:]
    except KeyError:
        magmoms = None
    try:
        tags = vars['AtomTags'][:]
    except KeyError:
        tags = None
    atoms = Atoms(scaled_positions=vars['DynamicAtomPositions'][-1],
                  symbols=[(a + b).strip()
                           for a, b in vars['DynamicAtomSpecies'][:]],
                  cell=cell,
                  magmoms=magmoms,
                  tags=tags,
                  pbc=True)

    try:
        energy = vars['TotalEnergy'][-1]
        force = vars['DynamicAtomForces'][-1]
    except KeyError:
        energy = None
        force = None
    calc = SinglePointCalculator(atoms, energy=energy,
                                 forces=force)  ### Fixme magmoms
    atoms.set_calculator(calc)

    return atoms
Beispiel #29
0
def test_struc_from_ase():
    from ase import Atoms
    from ase.calculators.singlepoint import SinglePointCalculator

    results = {
        "forces": np.random.randn(20, 3),
        "energy": np.random.rand(),
        "stress": np.random.randn(6),
    }

    uc = Atoms(
        ["Pd" for i in range(10)] + ["Ag" for i in range(10)],
        positions=np.random.rand(20, 3),
        cell=np.random.rand(3, 3),
    )

    calculator = SinglePointCalculator(uc, **results)
    uc.set_calculator(calculator)

    new_struc = Structure.from_ase_atoms(uc)

    assert np.all(new_struc.species_labels == uc.get_chemical_symbols())
    assert np.all(new_struc.positions == uc.get_positions())
    assert np.all(new_struc.cell == uc.get_cell())
    assert np.all(new_struc.forces == results["forces"])
    assert np.all(new_struc.energy == results["energy"])
    assert np.all(new_struc.stress == results["stress"])
Beispiel #30
0
def read_castep_geom(fd, index=None, units=units_CODATA2002):
    """Reads a .geom file produced by the CASTEP GeometryOptimization task and
    returns an atoms  object.
    The information about total free energy and forces of each atom for every
    relaxation step will be stored for further analysis especially in a
    single-point calculator.
    Note that everything in the .geom file is in atomic units, which has
    been conversed to commonly used unit angstrom(length) and eV (energy).

    Note that the index argument has no effect as of now.

    Contribution by Wei-Bing Zhang. Thanks!

    Routine now accepts a filedescriptor in order to out-source the *.gz and
    *.bz2 handling to formats.py. Note that there is a fallback routine
    read_geom() that behaves like previous versions did.
    """
    from ase.calculators.singlepoint import SinglePointCalculator

    # fd is closed by embracing read() routine
    txt = fd.readlines()

    traj = []

    Hartree = units['Eh']
    Bohr = units['a0']

    # Yeah, we know that...
    # print('N.B.: Energy in .geom file is not 0K extrapolated.')
    for i, line in enumerate(txt):
        if line.find('<-- E') > 0:
            start_found = True
            energy = float(line.split()[0]) * Hartree
            cell = [x.split()[0:3] for x in txt[i + 1:i + 4]]
            cell = np.array([[float(col) * Bohr for col in row]
                             for row in cell])
        if line.find('<-- R') > 0 and start_found:
            start_found = False
            geom_start = i
            for i, line in enumerate(txt[geom_start:]):
                if line.find('<-- F') > 0:
                    geom_stop = i + geom_start
                    break
            species = [line.split()[0] for line in txt[geom_start:geom_stop]]
            geom = np.array([[float(col) * Bohr for col in line.split()[2:5]]
                             for line in txt[geom_start:geom_stop]])
            forces = np.array([[
                float(col) * Hartree / Bohr for col in line.split()[2:5]
            ] for line in txt[geom_stop:geom_stop + (geom_stop - geom_start)]])
            image = ase.Atoms(species, geom, cell=cell, pbc=True)
            image.set_calculator(
                SinglePointCalculator(atoms=image,
                                      energy=energy,
                                      forces=forces))
            traj.append(image)

    if index is None:
        return traj
    else:
        return traj[index]
Beispiel #31
0
def store_E_and_F_in_spc(self):
    """Collect the energies and forces on all nodes and store as
    single point calculators"""
    # Make sure energies and forces are known on all nodes
    self.get_forces()
    images = self.images
    if self.parallel:
        energy = np.empty(1)
        forces = np.empty((self.natoms, 3))

        for i in range(1, self.nimages - 1):
            # Determine which node is the leading for image i
            root = (i - 1) * self.world.size // (self.nimages - 2)
            # If on this node, extract the calculated numbers
            if self.world.rank == root:
                energy[0] = images[i].get_potential_energy()
                forces = images[i].get_forces()
            # Distribute these numbers to other nodes
            self.world.broadcast(energy, root)
            self.world.broadcast(forces, root)
            # On all nodes, remove the calculator, keep only energy
            # and force in single point calculator
            self.images[i].calc = SinglePointCalculator(self.images[i],
                                                        energy=energy[0],
                                                        forces=forces)
Beispiel #32
0
def dict2atoms(dct, attach_calculator=False):
    constraint_dicts = dct.get('constraints')
    if constraint_dicts:
        constraints = [dict2constraint(c) for c in constraint_dicts]
    else:
        constraints = None

    atoms = Atoms(dct['numbers'],
                  dct['positions'],
                  cell=dct['cell'],
                  pbc=dct['pbc'],
                  magmoms=dct.get('initial_magmoms'),
                  charges=dct.get('initial_charges'),
                  tags=dct.get('tags'),
                  masses=dct.get('masses'),
                  momenta=dct.get('momenta'),
                  constraint=constraints)

    if attach_calculator:
        atoms.calc = get_calculator(
            dct['calculator'])(**dct['calculator_parameters'])
    else:
        results = {}
        for prop in all_properties:
            if prop in dct:
                results[prop] = dct[prop]
        if results:
            atoms.calc = SinglePointCalculator(atoms, **results)

    return atoms
Beispiel #33
0
 def __getitem__(self, i=-1):
     b = self.backend[i]
     if 'numbers' in b:
         # numbers and other header info was written alongside the image:
         atoms = read_atoms(b)
     else:
         # header info was not written because they are the same:
         atoms = read_atoms(b, header=[self.pbc, self.numbers, self.masses,
                                       self.constraints])
     if 'calculator' in b:
         results = {}
         c = b.calculator
         for prop in all_properties:
             if prop in c:
                 results[prop] = c.get(prop)
         calc = SinglePointCalculator(atoms, **results)
         calc.name = b.calculator.name
         atoms.set_calculator(calc)
     return atoms
Beispiel #34
0
    def write(self, atoms=None, **kwargs):
        """Write the atoms to the file.

        If the atoms argument is not given, the atoms object specified
        when creating the trajectory object is used.

        Use keyword arguments to add extra properties::

            writer.write(atoms, energy=117, dipole=[0, 0, 1.0])
        """
        b = self.backend

        if atoms is None:
            atoms = self.atoms

        if hasattr(atoms, 'interpolate'):
            # seems to be a NEB
            neb = atoms
            assert not neb.parallel or world.size == 1
            for image in neb.images:
                self.write(image)
            return
        while hasattr(atoms, 'atoms_for_saving'):
            # Seems to be a Filter or similar, instructing us to
            # save the original atoms.
            atoms = atoms.atoms_for_saving

        if self.header_data is None:
            b.write(version=1, ase_version=__version__)
            if self.description:
                b.write(description=self.description)
            # Atomic numbers and periodic boundary conditions are written
            # in the header in the beginning.
            #
            # If an image later on has other numbers/pbc, we write a new
            # header.  All subsequent images will then have their own header
            # whether or not their numbers/pbc change.
            self.header_data = get_header_data(atoms)
            write_header = True
        else:
            if not self.multiple_headers:
                header_data = get_header_data(atoms)
                self.multiple_headers = not headers_equal(self.header_data,
                                                          header_data)
            write_header = self.multiple_headers

        write_atoms(b, atoms, write_header=write_header)

        calc = atoms.get_calculator()

        if calc is None and len(kwargs) > 0:
            calc = SinglePointCalculator(atoms)

        if calc is not None:
            if not hasattr(calc, 'get_property'):
                calc = OldCalculatorWrapper(calc)
            c = b.child('calculator')
            c.write(name=calc.name)
            if hasattr(calc, 'todict'):
                d = calc.todict()
                if d:
                    c.write(parameters=d)
            for prop in all_properties:
                if prop in kwargs:
                    x = kwargs[prop]
                else:
                    if self.properties is not None:
                        if prop in self.properties:
                            x = calc.get_property(prop, atoms)
                        else:
                            x = None
                    else:
                        try:
                            x = calc.get_property(prop, atoms,
                                                  allow_calculation=False)
                        except (PropertyNotImplementedError, KeyError):
                            # KeyError is needed for Jacapo.
                            x = None
                if x is not None:
                    if prop in ['stress', 'dipole']:
                        x = x.tolist()
                    c.write(prop, x)

        info = {}
        for key, value in atoms.info.items():
            try:
                encode(value)
            except TypeError:
                warnings.warn('Skipping "{0}" info.'.format(key))
            else:
                info[key] = value
        if info:
            b.write(info=info)

        b.sync()
Beispiel #35
0
    def write(self, atoms=None, **kwargs):
        """Write the atoms to the file.

        If the atoms argument is not given, the atoms object specified
        when creating the trajectory object is used.

        Use keyword arguments to add extra properties::

            writer.write(atoms, energy=117, dipole=[0, 0, 1.0])
        """
        b = self.backend

        if atoms is None:
            atoms = self.atoms

        if hasattr(atoms, 'interpolate'):
            # seems to be a NEB
            neb = atoms
            assert not neb.parallel or world.size == 1
            for image in neb.images:
                self.write(image)
            return
        while hasattr(atoms, 'atoms_for_saving'):
            # Seems to be a Filter or similar, instructing us to
            # save the original atoms.
            atoms = atoms.atoms_for_saving

        if len(b) == 0:
            b.write(version=1, ase_version=__version__)
            if self.description:
                b.write(description=self.description)
            # Atomic numbers and periodic boundary conditions are only
            # written once - in the header.  Store them here so that we can
            # check that they are the same for all images:
            self.numbers = atoms.get_atomic_numbers()
            self.pbc = atoms.get_pbc()
        else:
            if (atoms.pbc != self.pbc).any():
                raise ValueError('Bad periodic boundary conditions!')
            elif len(atoms) != len(self.numbers):
                raise ValueError('Bad number of atoms!')
            elif (atoms.numbers != self.numbers).any():
                raise ValueError('Bad atomic numbers!')

        write_atoms(b, atoms, write_header=(len(b) == 0))

        calc = atoms.get_calculator()

        if calc is None and len(kwargs) > 0:
            calc = SinglePointCalculator(atoms)

        if calc is not None:
            if not hasattr(calc, 'get_property'):
                calc = OldCalculatorWrapper(calc)
            c = b.child('calculator')
            c.write(name=calc.name)
            if hasattr(calc, 'todict'):
                d = calc.todict()
                if d:
                    c.write(parameters=d)
            for prop in all_properties:
                if prop in kwargs:
                    x = kwargs[prop]
                else:
                    if self.properties is not None:
                        if prop in self.properties:
                            x = calc.get_property(prop, atoms)
                        else:
                            x = None
                    else:
                        try:
                            x = calc.get_property(prop, atoms,
                                                  allow_calculation=False)
                        except (PropertyNotImplementedError, KeyError):
                            # KeyError is needed for Jacapo.
                            x = None
                if x is not None:
                    if prop in ['stress', 'dipole']:
                        x = x.tolist()
                    c.write(prop, x)

        info = {}
        for key, value in atoms.info.items():
            try:
                encode(value)
            except TypeError:
                warnings.warn('Skipping "{0}" info.'.format(key))
            else:
                info[key] = value
        if info:
            b.write(info=info)

        b.sync()
Beispiel #36
0
def read_gaussian_out(filename, index=-1, quantity='atoms', quantities=None):
    """"Interface to GaussianReader and returns various quantities"""
    energy = 0.0

    try:
        data = GR(filename)[index]
    except IndexError:
        return {}

    positions = np.array(data['Positions'])
    numbers = np.array(data['Atomic_numbers'])

    method = data['Method']
    version = data['Version']

    if method.lower()[1:] in allowed_methods:
        method = 'HF'

    atoms = Atoms(positions=positions, numbers=numbers)

    for key, value in data.items():
        if key in method:
            #covers case where calculation is a scan and hence energy is a list of values not a single one
            try:
                energy = value[-1]
            except TypeError:
                energy = value

    if energy:
        energy_set = True
    else:
        energy_set = False

    try:
# Re-read in the log file
        f = open(filename, 'r')
        lines = f.readlines()
        f.close()

        forces = list()
        for n, line in enumerate(lines):
            if 'oniom' in method.lower() and 'extrapolated energy' in line:
                energy = float(line.split()[4])
            elif not energy_set and 'SCF Done' in line:
                energy = float(line.split()[4])

            if ('Forces (Hartrees/Bohr)' in line):
                for j in range(len(atoms)):
                    forces += [[float(lines[n + j + 3].split()[2]),
                                float(lines[n + j + 3].split()[3]),
                                float(lines[n + j + 3].split()[4])]]
        #convert = ase.units.Hartree / ase.units.Bohr
        convert = utils.convertor(1, 'hartree', 'eV') / utils.convertor(1, 'bohr', 'Angstrom')
        forces = np.array(forces) * convert
    except:
        forces = None

    #energy *= ase.units.Hartree  # Convert the energy from a.u. to eV
    energy = utils.convertor(energy, 'hartree', 'eV')

    calc = SinglePointCalculator(atoms, energy=energy, forces=forces)

    calc.path = os.path.split(filename)[0]
    calc.label = os.path.split(filename)[1].replace('.log', '')
    calc.data = data

    atoms.set_calculator(calc)

    data_dict = {'energy': energy, 'forces': forces, 'dipole': data.get('Dipole'), 'atoms': atoms, 'version': version}

    if quantities:
        return [data_dict[q] for q in quantities]
    elif quantity in data_dict:
        return data_dict[quantity]
    else:
        return None
Beispiel #37
0
    def write(self, atoms=None, **kwargs):
        """Write the atoms to the file.

        If the atoms argument is not given, the atoms object specified
        when creating the trajectory object is used.
        
        Use keyword arguments to add extra properties::
            
            writer.write(atoms, energy=117, dipole=[0, 0, 1.0])
        """
        b = self.backend

        if atoms is None:
            atoms = self.atoms

        if hasattr(atoms, 'interpolate'):
            # seems to be a NEB
            neb = atoms
            assert not neb.parallel or world.size == 1
            for image in neb.images:
                self.write(image)
            return

        if len(b) == 0:
            self.write_header(atoms)
        else:
            if (atoms.pbc != self.pbc).any():
                raise ValueError('Bad periodic boundary conditions!')
            elif len(atoms) != len(self.numbers):
                raise ValueError('Bad number of atoms!')
            elif (atoms.numbers != self.numbers).any():
                raise ValueError('Bad atomic numbers!')

        b.write(positions=atoms.get_positions(),
                cell=atoms.get_cell().tolist())
        
        if atoms.has('tags'):
            b.write(tags=atoms.get_tags())

        if atoms.has('momenta'):
            b.write(momenta=atoms.get_momenta())

        if atoms.has('magmoms'):
            b.write(magmoms=atoms.get_initial_magnetic_moments())
            
        if atoms.has('charges'):
            b.write(charges=atoms.get_initial_charges())

        calc = atoms.get_calculator()
        
        if calc is None and len(kwargs) > 0:
            calc = SinglePointCalculator(atoms)

        if calc is not None:
            if not isinstance(calc, Calculator):
                calc = OldCalculatorWrapper(calc)
            c = b.child('calculator')
            c.write(name=calc.name)
            for prop in all_properties:
                if prop in kwargs:
                    x = kwargs[prop]
                else:
                    if self.properties is not None:
                        if prop in self.properties:
                            x = calc.get_property(prop, atoms)
                        else:
                            x = None
                    else:
                        try:
                            x = calc.get_property(prop, atoms,
                                                  allow_calculation=False)
                        except (NotImplementedError, KeyError):
                            # KeyError is needed for Jacapo.
                            x = None
                if x is not None:
                    if prop in ['stress', 'dipole']:
                        x = x.tolist()
                    c.write(prop, x)

        info = {}
        for key, value in atoms.info.items():
            try:
                encode(value)
            except TypeError:
                warnings.warn('Skipping "{0}" info.'.format(key))
            else:
                info[key] = value
        if info:
            b.write(info=info)

        b.sync()