def get_energy_correction(symbols, counts):
    atoms = Atoms(formula)
    full_symbols = atoms.get_chemical_symbols()
    symbols = list(set(atoms.get_chemical_symbols()))

    with open(corrections) as f:
        d = yaml.load(f)

    anion = None
    if 'S' in symbols:
        anion = 'S'
    elif 'F' in symbols:
        anion = 'F'

    elif 'O' in symbols:
        anion = 'O'

    corr_energy = 0

    if anion is not None:
        metal_keys = list(d['Advanced']['UCorrections'][anion].keys())
        for i, m in enumerate(symbols):
            if m in metal_keys:
                corr_energy += counts[i] * \
                    d['Advanced']['UCorrections'][anion][m]

    if anion == 'O':
        i = symbols.index('O')
        corr_energy += counts[i] * d['OxideCorrections']['oxide']

    return corr_energy
Beispiel #2
0
    def run_md(self, f, Tmax, steps, n_steps, nmfile=None, displacement=0, min_steps=0, sig=0.34, t=0.1, nm=0, record=False):
        X, S, Na, cm = hdt.readxyz2(f)
        
        if nmfile != None:
            mode=self.get_mode(nmfile, Na, mn=nm)
            X=X+mode*np.random.uniform(-displacement,displacement)
        X=X[0]
        mol=Atoms(symbols=S, positions=X)
        mol.set_calculator(ANIENS(self.net,sdmx=20000000.0))
        f=os.path.basename(f)
        T_eff = float(random.randrange(5, Tmax, 1)) # random T (random velocities) from 0K to TK
        minstep_eff = float(random.randrange(1, min_steps, 1)) # random T (random velocities) from 0K to TK
        dyn = Langevin(mol, t * units.fs, T_eff * units.kB, 0.01)
        MaxwellBoltzmannDistribution(mol, T_eff * units.kB)
#        steps=10000    #10000=1picosecond                             #Max number of steps to run
#        n_steps = 1                                                #Number of steps to run for before checking the standard deviation
        hsdt_Na=[]
        evkcal=hdt.evtokcal

        if record==True:                                           #Records the coordinates at every step of the dynamics
            fname = f + '_record_' + str(T_eff) + 'K' + '.xyz'     #name of file to store coodinated in
            def printenergy(name=fname, a=mol):
                """Function to print the potential, kinetic and total energy."""
                fil= open(name,'a')
                Na=a.get_number_of_atoms()
                c = a.get_positions(wrap=True)
                fil.write('%s \n comment \n' %Na)
                for j, i in zip(a, c):
                    fil.write(str(j.symbol) + ' ' + str(i[0]) + ' ' + str(i[1]) + ' ' + str(i[2]) + '\n')
                fil.close()
            dyn.attach(printenergy, interval=1)

        e=mol.get_potential_energy()                             #Calculate the energy of the molecule. Must be done to get the standard deviation
        s=mol.calc.stddev
        stddev =  0
        tot_steps = 0
        failed = False
        while (tot_steps <= steps):
            if stddev > sig and tot_steps > minstep_eff:                                #Check the standard deviation
                self.hstd.append(stddev)
                c = mol.get_positions()
                s = mol.get_chemical_symbols()
                Na=mol.get_number_of_atoms()
                self.Na_train.append(Na)
                self.coor_train.append(c)
                self.S_train.append(s)
                failed=True
                break
            else:                                           #if the standard deviation is low, run dynamics, then check it again
                tot_steps = tot_steps + n_steps
                dyn.run(n_steps)
                stddev =  evkcal*mol.calc.stddev
                c = mol.get_positions()
                s = mol.get_chemical_symbols()
                e=mol.get_potential_energy()
                #print("{0:.2f}".format(tot_steps*t),':',"{0:.2f}".format(stddev),':',"{0:.2f}".format(evkcal*e))
        return c, s, tot_steps*t, stddev, failed, T_eff
Beispiel #3
0
 def compare_structures(s1: Atoms, s2: Atoms) -> bool:
     if len(s1) != len(s2):
         return False
     if not np.all(np.isclose(s1.cell, s2.cell)):
         return False
     if not np.all(
             np.isclose(s1.get_scaled_positions(),
                        s2.get_scaled_positions())):
         return False
     if not np.all(
             s1.get_chemical_symbols() == s2.get_chemical_symbols()):
         return False
     return True
    def assert_structure_compatibility(self, structure: Atoms, vol_tol: float = 1e-5) -> None:
        """ Raises error if structure is not compatible with ClusterSpace.

        Todo
        ----
        Add check for if structure is relaxed.

        Parameters
        ----------
        structure
            structure to check if compatible with ClusterSpace
        """
        # check volume
        prim = self.primitive_structure
        vol1 = prim.get_volume() / len(prim)
        vol2 = structure.get_volume() / len(structure)
        if abs(vol1 - vol2) > vol_tol:
            raise ValueError('Volume per atom of structure does not match the volume of '
                             'ClusterSpace.primitive_structure')

        # check occupations
        sublattices = self.get_sublattices(structure)
        sublattices.assert_occupation_is_allowed(structure.get_chemical_symbols())

        # check pbc
        if not all(structure.pbc):
            raise ValueError('Input structure must have periodic boundary conditions')
def get_e_above_hull(formula, energy):
    atoms = Atoms(formula)
    full_symbols = atoms.get_chemical_symbols()
    symbols, counts = np.unique(full_symbols, return_counts=True)

    # list(set(atoms.get_chemical_symbols()))

    with MPRester() as m:
        data = m.get_entries_in_chemsys(symbols,
                                        compatible_only=True,
                                        property_data=[
                                            'energy_per_atom',
                                            'unit_cell_formula',
                                            'pretty_formula'
                                        ])
    PDentries = []

    for d in data:
        d = d.as_dict()
        PDentries += [PDEntry(d['data']['unit_cell_formula'], d['energy'])]
        print(d['data']['pretty_formula'], d['energy'])

    PD = PhaseDiagram(PDentries)

    # Need to apply MP corrections to +U calculations
    # MP advanced correction + anion correction

    #print(energy * 2, energy * 2 +  corr_energy * 2)

    PDE0 = PDEntry(formula, energy)
    e_hull = PD.get_e_above_hull(PDE0)

    return e_hull
Beispiel #6
0
def random_structure(stoichio, amin, amax, dmin, iwrite=0):
    # returns pure random structure (ase Atoms)
    struct = Atoms(stoichio)
    cell = random_cell(amin, amax)
    struct.set_cell(cell)

    symbols = struct.get_chemical_symbols()

    Nat = len(symbols)

    flag = 0
    niter = 0
    while flag == 0:
        positions = []

        for i in range(Nat):
            pos = [uniform(0., 0.90), uniform(0., 0.90), uniform(-0.2, 0.2)]
            positions.append(pos)

        struct.set_scaled_positions(positions)
        struct2x2x1 = struct * (2, 2, 1)
        positions_ang = struct2x2x1.get_positions()
        flag = check_dist(Nat * 2 * 2, positions_ang, dmin)

        niter = niter + 1

    if flag == 1 and iwrite == 1:
        write(filename="POSCAR", images=struct, format="vasp")
        write(filename="POSCAR.in", images=struct, format="espresso-in")

    return struct
Beispiel #7
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 #8
0
def test_struc_from_ase():
    from ase import Atoms
    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))
    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())
Beispiel #9
0
def get_pointgroup(atoms: ase.Atoms) -> str:
    """
    uses pymatgen.symmetry.analyzer
	"""
    atoms.center()
    symbs = atoms.get_chemical_symbols()
    pos = atoms.get_positions()
    mol = pmg.Molecule(symbs, pos)
    return pysym.PointGroupAnalyzer(mol).sch_symbol
class Polycrystal(OrthoBox):
    def __init__(self, boxsize, numcrystallites, crystallitenames,
                 crystallitecenters):
        super().__init__(boxsize)
        self.numcrystallites = numcrystallites
        self.crystaltype = crystallitenames
        self.crystallitecenters = crystallitecenters
        self.crystallites = [Atoms() for n in range(numcrystallites)]
        self.crystalliteids = [[i] for i in range(numcrystallites)]

    def setgraintypes(self, typemap):
        self.graintypes = typemap

    def embedatoms(self, maskcrystal, grainid, keepatoms, compress=True):
        crystal = maskcrystal.copy()
        slicecrystal = crystal[keepatoms]
        natoms = slicecrystal.get_global_number_of_atoms()
        self.crystalliteids[grainid] = [grainid for i in range(natoms)]
        self.crystallites[grainid] = slicecrystal

    def compress(self):
        polycrystalbox = self.sidelens + self.angles
        self.polycrystal = Atoms(cell=polycrystalbox, pbc=True)
        for i, c in enumerate(self.crystallites):
            cids = self.crystalliteids[i]
            c.set_tags(cids)
            self.polycrystal += c
        self.natoms = self.polycrystal.get_global_number_of_atoms()
        chemsym = set(self.polycrystal.get_chemical_symbols())
        self.chemmap = {c: i + 1 for i, c in enumerate(chemsym)}
        self.nspecies = len(chemsym)

    def pruneoverlap(self, criteria=0.5, verbose=False):
        ''' TODO: remove atoms overlapping assume PBC conditions'''
        print(
            "NOTICE: The pruning routine does not accoutn for stoichiometry restrictions."
        )

        cutoff = neighborlist.natural_cutoffs(self.polycrystal)
        neighbors = neighborlist.NeighborList(cutoff,
                                              self_interaction=False,
                                              bothways=False)
        neighbors.update(self.polycrystal)

        isremoved = []
        for a in self.polycrystal:
            ineigh = neighbors.get_neighbors(a.index)
            for j in ineigh[0]:
                r = self.polycrystal.get_distance(a.index, j, mic=True)
                if r < criteria and j not in isremoved:
                    isremoved.append(j)
                    if verbose:
                        print("Atom ID %i removed due to overlap!" % (j))

        del self.polycrystal[isremoved]
        self.natoms = self.polycrystal.get_global_number_of_atoms()
Beispiel #11
0
def set_up_calculation(db, subdir, syms, AB_stacking, soc, vacuum_dist, D, xc,
                       pp):
    # Choose separation between layers as if the system was a bulk system
    # where all layers are the same as the first layer here.
    # TODO -- is there a better strategy for this?
    c_sep = get_c_sep(db, syms[0])

    latvecs, at_syms, cartpos = make_cell(db, syms, c_sep, vacuum_dist,
                                          AB_stacking)

    system = Atoms(symbols=at_syms, positions=cartpos, cell=latvecs, pbc=True)
    system.center(axis=2)

    wann_valence, num_wann = get_wann_valence(system.get_chemical_symbols(),
                                              soc)
    num_bands = get_num_bands(num_wann)

    holes_per_cell = None
    qe_config = make_qe_config(system, D, holes_per_cell, soc, num_bands, xc,
                               pp)

    prefix = make_prefix(syms)
    work = _get_work(subdir, prefix)

    wannier_dir = os.path.join(work, "wannier")
    if not os.path.exists(wannier_dir):
        os.makedirs(wannier_dir)

    bands_dir = os.path.join(work, "bands")
    if not os.path.exists(bands_dir):
        os.makedirs(bands_dir)

    dirs = {'scf': wannier_dir, 'nscf': wannier_dir, 'bands': bands_dir}

    qe_input = {}
    for calc_type in ['scf', 'nscf', 'bands']:
        qe_input[calc_type] = build_qe(system, prefix, calc_type, qe_config)
        _write_qe_input(prefix, dirs[calc_type], qe_input, calc_type)

    pw2wan_input = build_pw2wan(prefix, soc)
    pw2wan_path = os.path.join(wannier_dir, "{}.pw2wan.in".format(prefix))
    with open(pw2wan_path, 'w') as fp:
        fp.write(pw2wan_input)

    bands_post_input = build_bands(prefix)
    bands_post_path = os.path.join(bands_dir,
                                   "{}.bands_post.in".format(prefix))
    with open(bands_post_path, 'w') as fp:
        fp.write(bands_post_input)

    wannier_input = Winfile(system, qe_config, wann_valence, num_wann)
    win_path = os.path.join(wannier_dir, "{}.win".format(prefix))
    with open(win_path, 'w') as fp:
        fp.write(wannier_input)

    return prefix
Beispiel #12
0
def get_symbols(chem_sym, stoich):
    Nat = len(chem_sym)
    chem_form = ""
    for i in range(Nat):
        chem_form = chem_form + chem_sym[i] + str(stoich[i])

    atm = Atoms(chem_sym)
    symbols = atm.get_chemical_symbols()

    return symbols
Beispiel #13
0
def tuple_from_ase(asecell: ase.Atoms):
    """
    Convert an ase cell to a structure tuple.
    """
    cell = asecell.cell.tolist()
    # Wrap=False to preserve the absolute positions of atoms
    rel_pos = asecell.get_scaled_positions(wrap=False).tolist()
    numbers = [
        ase.atom.atomic_numbers[symbol]
        for symbol in asecell.get_chemical_symbols()
    ]
    return (cell, rel_pos, numbers)
Beispiel #14
0
    def createMeta(self,
                   name=None,
                   title=None,
                   authors=None,
                   notes=None,
                   signal_type=None,
                   elements=None,
                   model=None):
        """ Generate and organize info into a matadata dictionary recognized by hyperspy
		:returns: nested dictionary of information """

        if not name:
            name = "Unnamed_simulation"
        if not title:
            title = name
        if elements:
            symbol = Atoms.get_chemical_symbols()
            for i in range(elements):
                elements[i] = symbol[i]

        description = "Simulated material system\n See 'system' for further information."

        description += "Fermi energy:{}".format(self.fermiEnergy)

        metadata = {}
        metadata['General'] = {}

        metadata['General']['name'] = name
        metadata['General']['title'] = title
        metadata['General']['authors'] = authors
        metadata['General']['notes'] = notes

        metadata['Signal'] = {}
        metadata['Signal']['binned'] = True
        metadata['Signal']['signal_type'] = signal_type

        metadata['Sample'] = {}
        metadata['Sample']['elements'] = self.cell.getAtomNumbers()

        metadata['Sample']['system'] = {}
        metadata['Sample']['system']['cell'] = {}
        axes = ['a', 'b', 'c']
        for i in range(len(self.cell.lattice)):
            metadata['Sample']['system']['cell'][
                axes[i]] = self.cell.lattice[i]

        metadata['Sample']['system']['fermiEnergy'] = self.fermiEnergy
        metadata['Sample']['system']['temperature'] = self.temperature

        metadata['Sample']['system']['bands'] = self.bands
        metadata['Sample']['description'] = description

        return metadata
Beispiel #15
0
def test_build():
    import numpy as np
    from ase import Atoms, Atom

    a = Atoms([Atom('Cu')])
    a.positions[:] += 1.0
    print(a.get_positions(), a.positions)
    a = a + a
    a += a
    a.append(Atom('C'))
    a += Atoms([])
    a += Atom('H', magmom=1)
    print(a.get_initial_magnetic_moments())
    print(a[0].number)
    print(a[[0, 1]].get_atomic_numbers())
    print(a[np.array([1, 1, 0, 0, 1, 0], bool)].get_atomic_numbers())
    print(a[::2].get_atomic_numbers())
    print(a.get_chemical_symbols())
    del a[2]
    print(a.get_chemical_symbols())
    del a[-2:]
    print(a.get_chemical_symbols())
Beispiel #16
0
 def testRMSE(self):
     datafile = os.path.join(path, 'test_data/NeuroChemOptimized/all')
     with open(datafile, 'rb') as f:
         all_atoms = pickle.load(f)
         for atoms in all_atoms:
             # reconstructing Atoms object.
             # ASE does not support loading pickled object from older version
             atoms = Atoms(atoms.get_chemical_symbols(), positions=atoms.get_positions())
             old_coordinates = copy.deepcopy(atoms.get_positions())
             old_coordinates = torch.from_numpy(old_coordinates)
             atoms.set_calculator(self.calculator)
             opt = BFGS(atoms)
             opt.run()
             coordinates = atoms.get_positions()
             self.assertEqual(old_coordinates, coordinates)
Beispiel #17
0
def _structure_from_atoms(self, conf: Atoms):
    """
    Returns the input configuration as an icet Structure object.

    Parameters
    ----------
    conf
        input configuration

    Returns
    -------
    atomic configuration
    """
    return self(conf.positions, conf.get_chemical_symbols(), conf.cell,
                conf.pbc.tolist())
def test():
    # Test that atoms object agrees with calculator
    calc = Vasp('atom-order-test')
    atoms = calc.get_atoms()

    atoms0 = Atoms(
        [Atom('O', [4, 5, 5]),
         Atom('C', [5, 5, 5]),
         Atom('O', [6, 5, 5])],
        cell=(10, 10, 10))

    # Check the atom order
    if not atoms.get_chemical_symbols() == \
       atoms0.get_chemical_symbols():
        raise Exception('Atom order not conserved')

    # Now call the calculator without assigning atoms
    calc2 = Vasp('atom-order-test')
    atoms = calc2.get_atoms()

    # Check the atom order
    if not atoms.get_chemical_symbols() == \
       atoms0.get_chemical_symbols():
        raise Exception('Atom order not conserved')
Beispiel #19
0
def variable_stoichiometry_generator(symbols, stoichiometry, clean=False, fu=None,
                                     mindis=None, nstr=None, maxatomn=None,
                                     cspd_file=None, lw=None, format=None,
                                     sgn=None, to_primitive=None):
    tpstru = Atoms(symbols)
    smbl = []
    for smb in tpstru.get_chemical_symbols():
        if not (smb in smbl):
            smbl.append(smb)
    for stc in stoichiometry:
        cc = ''
        for i, n in enumerate(stc):
            cc += smbl[i] + '{}'.format(n)
        atomic_structure_generator(
            symbols=cc, fu=fu, mindis=mindis, nstr=nstr, maxatomn=maxatomn,
            cspd_file=cspd_file, lw=lw, format=format, clean=clean, sgn=sgn, to_primitive=to_primitive)
    pass
def view_vibrational_modes(outcar,
                           frequency_index="all",
                           wrap_center=[0.3, 0.3, 0.8]):
    '''views the Vibrational modes of an OUTCAR file in the "-", "0" and  "+" states "'''
    from ase.visualize import view
    from ase.io import read
    from ase.geometry import wrap_positions
    from ase import Atoms
    import ase
    import numpy as np
    import os
    if frequency_index == "all":
        output_file_name = "sample"
        write_xyz(outcar, output_file_name)
        atoms = read(output_file_name + ".xyz@:")
        #print(atoms)
        a = []
        for atom in atoms:
            atom.wrap(center=wrap_center)
            a.append(atom)
        view(atoms)
        os.remove(output_file_name + ".xyz")
    elif frequency_index != "all":  # for a list of frequency index
        output_file_name = "sample"
        new_df = read_vibrational_modes(outcar)
        Atoms = read(outcar)
        elements = Atoms.get_chemical_symbols()
        for index in frequency_index:
            start = index * 3 * (len(elements) + 2)
            end = 3 * (len(elements) + 2)
            df = new_df[start:start + end]
            File = output_file_name + ".xyz"
            df.drop(df.columns[4], axis=1).drop(df.columns[5],
                                                axis=1).to_csv(File,
                                                               header=None,
                                                               index=None,
                                                               sep=' ',
                                                               mode='a')
        atoms = read(output_file_name + ".xyz@:")
        a = []
        for atom in atoms:
            atom.wrap(center=wrap_center)
            a.append(atom)
        view(a)
        os.remove(output_file_name + ".xyz")
    def test_qe_config(self):
        syms = ["WSe2", "WSe2", "WSe2"]
        soc = True
        vacuum_dist = 20.0  # Angstrom
        D = 0.5  # V/nm
        AB_stacking = True
        xc = 'lda'
        pp = 'nc'

        db_path = os.path.join(_base_dir(), "c2dm.db")
        db = ase.db.connect(db_path)
        c_sep = get_c_sep(db, syms[0])

        latvecs, at_syms, cartpos = make_cell(db, syms, c_sep, vacuum_dist,
                                              AB_stacking)
        system = Atoms(symbols=at_syms,
                       positions=cartpos,
                       cell=latvecs,
                       pbc=True)
        system.center(axis=2)

        wann_valence, num_wann = get_wann_valence(
            system.get_chemical_symbols(), soc)
        num_bands = get_num_bands(num_wann)

        qe_config = make_qe_config(system, D, soc, num_bands, xc, pp)
        #with open('test_build_qe_config_new.json', 'w') as fp:
        #    json.dump(qe_config, fp)

        with open('test_build_qe_config.json', 'r') as fp:
            qe_config_expected = json.load(fp)

        check_qe_config(self, qe_config, qe_config_expected, soc, xc, pp)

        prefix = 'test'
        qe_input = build_qe(system, prefix, 'scf', qe_config)
        #with open('test_build_qe_input_new', 'w') as fp:
        #    fp.write(qe_input)

        with open('test_build_qe_input', 'r') as fp:
            qe_input_expected = fp.read()

        check_qe_input(self, qe_input, qe_input_expected, soc, xc, pp)
Beispiel #22
0
    def _get_atom_count(self, structure: Atoms) -> Dict[str, float]:
        """Returns atom counts for each species relative its
        sublattice.

        Parameters
        ----------
        structure
            the configuration that will be analyzed
        """
        occupation = np.array(structure.get_chemical_symbols())
        counts = {}
        for sublattice in self._sublattices:
            if len(sublattice.chemical_symbols) == 1:
                continue
            for symbol in sublattice.chemical_symbols:
                symbol_count = occupation[sublattice.indices].tolist().count(
                    symbol)
                counts[symbol] = symbol_count
        return counts
Beispiel #23
0
def test_compute_bonds_filter_element_pairs():
    """Test filtering of bonds by element pairs."""
    atoms = Atoms(
        symbols=["H", "He", "Mg"],
        positions=[[0, 0, 0], [0.2, 0.2, 0.2], [0.5, 0.5, 0.5]],
        cell=np.eye(3),
        pbc=False,
    )
    atom_radii = np.array([0.4, 0.4, 0.4])

    bonds = draw_utils.compute_bonds(atoms, atom_radii)

    allowed = [("H", "Mg")]
    allowed = set([(a, b) for a, b in allowed] + [(b, a) for a, b in allowed])
    symbols = atoms.get_chemical_symbols()
    bonds = bonds[[(symbols[i], symbols[j]) in allowed for i, j in bonds[:, 0:2]]]

    # print(bonds.tolist())
    assert np.allclose(bonds, [[0, 2, 0, 0, 0]])
Beispiel #24
0
def get_g2_map(atoms: Atoms,
               rc: float,
               nij_max: int,
               interactions: list,
               vap: VirtualAtomMap,
               offsets: np.ndarray,
               for_prediction=False,
               print_time=False):
    if for_prediction:
        iaxis = 0
    else:
        iaxis = 1
    g2_map = np.zeros((nij_max, iaxis + 2), dtype=np.int32)
    tlist = np.zeros(nij_max, dtype=np.int32)
    symbols = atoms.get_chemical_symbols()
    tic = time.time()
    ilist, jlist, n1 = neighbor_list('ijS', atoms, rc)
    if print_time:
        print(f"* ASE neighbor time: {time.time() - tic}")
    nij = len(ilist)
    tlist.fill(0)
    for i in range(nij):
        symboli = symbols[ilist[i]]
        symbolj = symbols[jlist[i]]
        tlist[i] = interactions.index('{}{}'.format(symboli, symbolj))
    ilist = np.pad(ilist + 1, (0, nij_max - nij), 'constant')
    jlist = np.pad(jlist + 1, (0, nij_max - nij), 'constant')
    n1 = np.pad(n1, ((0, nij_max - nij), (0, 0)), 'constant')
    n1 = n1.astype(np.float32)
    for count in range(len(ilist)):
        if ilist[count] == 0:
            break
        ilist[count] = vap.index_map[ilist[count]]
        jlist[count] = vap.index_map[jlist[count]]
    g2_map[:, iaxis + 0] = ilist
    g2_map[:, iaxis + 1] = offsets[tlist]
    return {
        "g2.v2g_map": g2_map,
        "g2.ilist": ilist,
        "g2.jlist": jlist,
        "g2.shift": n1
    }
Beispiel #25
0
def create_new_unit_cell(atom_config,
                         mol_ids,
                         cell_lengths,
                         cell_angles,
                         num_cells=[1, 1, 1],
                         filename=None):

    cell_lengths = [a * b for a, b in zip(cell_lengths, num_cells)]
    cell_cop = get_center_of_cell(cell_lengths, cell_angles)
    atom_config_new = copy.deepcopy(atom_config)
    atom_config_new.translate(cell_cop)
    convert_to_fractional(atom_config_new,
                          cell_lengths,
                          cell_angles,
                          degrees=True)

    atoms_to_keep = []
    atoms_to_remove = []
    mol_ids_new = []

    all_xyz = atom_config_new.get_positions()
    for i in range(len(all_xyz)):
        pos = all_xyz[i]
        if np.min(pos) < 0 or np.max(pos) > 1:
            atoms_to_remove.extend([i])
        else:
            atoms_to_keep.extend([i])
            mol_ids_new.extend([mol_ids[i]])

    atom_config_new = Atoms(
        [atom for atom in atom_config_new if atom.index in atoms_to_keep])
    config_as_crystal = ase.spacegroup.crystal(
        atom_config_new.get_chemical_symbols(),
        atom_config_new.get_positions(),
        spacegroup='P1',
        cellpar=cell_lengths + cell_angles)

    if filename != None:
        ase.io.write(filename, config_as_crystal)

    return atom_config_new, mol_ids_new
    def __init__(self,
                 structure: Atoms,
                 calculator: BaseCalculator,
                 temperature: float,
                 user_tag: str = None,
                 boltzmann_constant: float = kB,
                 random_seed: int = None,
                 dc_filename: str = None,
                 data_container: str = None,
                 data_container_write_period: float = 600,
                 ensemble_data_write_interval: int = None,
                 trajectory_write_interval: int = None,
                 sublattice_probabilities: List[float] = None) -> None:

        self._ensemble_parameters = dict(temperature=temperature)

        # add species count to ensemble parameters
        symbols = set([symbol for sub in calculator.sublattices
                       for symbol in sub.chemical_symbols])
        for symbol in symbols:
            key = 'n_atoms_{}'.format(symbol)
            count = structure.get_chemical_symbols().count(symbol)
            self._ensemble_parameters[key] = count

        super().__init__(
            structure=structure,
            calculator=calculator,
            user_tag=user_tag,
            random_seed=random_seed,
            data_container=data_container,
            dc_filename=dc_filename,
            data_container_class=DataContainer,
            data_container_write_period=data_container_write_period,
            ensemble_data_write_interval=ensemble_data_write_interval,
            trajectory_write_interval=trajectory_write_interval,
            boltzmann_constant=boltzmann_constant)

        if sublattice_probabilities is None:
            self._swap_sublattice_probabilities = self._get_swap_sublattice_probabilities()
        else:
            self._swap_sublattice_probabilities = sublattice_probabilities
Beispiel #27
0
def vib_analysis(model):
    ''' Returns a list displacemet of bonds/atoms in a trajectory.
    Parameters:
        model: Atoms object
               e.g trajectory file to calculate bond displacement
    TODO: - Resolve for periodic systems - functionally currently doesn't work


    '''
    atot = Atoms.get_chemical_symbols(self=read(model))

    traj = Trajectory(model)

    for i in range(len(atot) - 1):
        for j in range(i + 1, len(atot)):
            distances = []
            for atoms in traj:
                dist = atoms.get_distances(i, j)
                distances.append(float(dist))
            dist_list = distances
            return dist_list
def visualize(renWin_disp,ren_disp, *args):     #renders the result of MOF creation and optimization
    ren_disp.RemoveAllViewProps()
    ren_disp.ResetCamera()
    T= var_topo.get().split('.')
    C = var_center.get().split('.')
    L = var_linker.get().split('.')
    F = var_func.get().split('.')
    MOFname = '{0}-{1}-{2}'.format(T[0], C[0], L[0])
    CIFfile = '{0}-opti.cif'.format(MOFname)
    CIFfile_func ='{0}-func-{1}-opti.cif'.format(MOFname, F[0] ) 
    XYZfile = '{0}.xyz'.format(MOFname)
    XYZfile_func = '{0}-func-{1}.xyz'.format(MOFname, F[0] )
    if exists(CIFfile_func) and exists(XYZfile_func):
        MOF = ase.io.read(CIFfile_func)
        print 'CIF FUNC'
    elif exists(XYZfile_func) and not exists(CIFfile_func):
        MOF = ase.io.read(XYZfile_func)
        print 'XYZ FUNC'
    elif exists(CIFfile) and exists(XYZfile):
        MOF = ase.io.read(CIFfile)
        print 'CIF'
    elif exists(XYZfile) and not exists(CIFfile):
        MOF = ase.io.read(XYZfile)
        print 'XYZ'
    else:    
        tkMessageBox.showerror('Error', 'No files found for {0}. Please create it.'.format(MOFname))   
        MOF = Atoms('H', positions=[(0,0,0)], cell=(1,1,1))     
    i = 0
    elements = MOF.get_chemical_symbols()
    for coordinates in MOF.get_positions():
        scaled_coordinates = (5 * coordinates)
        element_data = elements_dict[elements[i]]
        radius = (element_data[0]/25) 
        color= element_data[1]
        sphereActor = makeSphere(radius, scaled_coordinates,color)
        sphereActor.GetProperty().SetEdgeColor(float('0.'+str(i)),0,0)
        ren_disp.AddActor(sphereActor)
        i += 1
    ren_disp.ResetCamera()
    renWin_disp.Render()
Beispiel #29
0
    def get_observable(self, structure: Atoms) -> Dict[str, List[float]]:
        """
        Returns the site occupation factors for a given atomic configuration.

        Parameters
        ----------
        structure
            input atomic structure.
        """

        chemical_symbols = np.array(structure.get_chemical_symbols())
        sofs = {}
        for site, indices in self._sites.items():
            counts = {species: 0 for species in self._allowed_species[site]}
            symbols, sym_counts = np.unique(chemical_symbols[indices],
                                            return_counts=True)
            for sym, count in zip(symbols, sym_counts):
                counts[sym] += count

            for species in counts.keys():
                key = 'sof_{}_{}'.format(site, species)
                sofs[key] = float(counts[species]) / len(indices)

        return sofs
Beispiel #30
0
import numpy as np
from ase import Atoms, Atom

a = Atoms([Atom('Cu')])
a.positions[:] += 1.0
print(a.get_positions(), a.positions)
a=a+a
a+=a
a.append(Atom('C'))
a += Atoms([])
a += Atom('H', magmom=1)
print(a.get_initial_magnetic_moments())
print(a[0].number)
print(a[[0,1]].get_atomic_numbers())
print(a[np.array([1,1,0,0,1], bool)].get_atomic_numbers())
print(a[::2].get_atomic_numbers())
print(a.get_chemical_symbols())
del a[2]
print(a.get_chemical_symbols())
del a[-2:]
print(a.get_chemical_symbols())
Beispiel #31
0
                #~ f = 24 * epsilon * ((2 * c12 - c6) / d2)[:, np.newaxis] * D
                #~ F1 -= f.sum(0)
                #~ mmforces[mask] += f
        #~ return energy, qmforces, mmforces


if __name__ == '__main__':
    from ase import Atoms
    from ase.cluster.cubic import FaceCenteredCubic
    from ase.structure import graphene_nanoribbon
    from ase.visualize import view

    surfaces = [(1,0,0), (1,1,0)]
    layers = [3,2]
    nano = Atoms(FaceCenteredCubic('Pt', surfaces, layers, 4.0))
    symbols = nano.get_chemical_symbols()
    symbols[0] = 'Cu'
    symbols[12] = 'Cu'
    nano.set_chemical_symbols(symbols)
    nano.pop(6)
    support = graphene_nanoribbon(8, 6, type='armchair', saturated=False)
    support.translate([-8,-2,-8])
    nano.extend(support)
    support.translate([0,-3.0,0])
    nano.extend(support)
    nano.center(vacuum=10)
    #~ view(nano)
    calc = Hybrid()
    nano.set_calculator(calc)
    # check subsystems selection
    from ase.io import write
Beispiel #32
0
import numpy as np
from ase import Atoms, Atom

a = Atoms([Atom('Cu')])
a.positions[:] += 1.0
print a.get_positions(), a.positions
a=a+a
a+=a
a.append(Atom('C'))
a += Atoms([])
a += Atom('H', magmom=1)
print a.get_initial_magnetic_moments()
print a[0].number
print a[[0,1]].get_atomic_numbers()
print a[np.array([1,1,0,0,1], bool)].get_atomic_numbers()
print a[::2].get_atomic_numbers()
print a.get_chemical_symbols()
del a[2]
print a.get_chemical_symbols()
del a[-2:]
print a.get_chemical_symbols()
Beispiel #33
0
def newclus(ind1, ind2, Optimizer):
    """Select a box in the cluster configuration"""

    if 'CX' in Optimizer.debug:
        debug = True
    else:
        debug = False
    Optimizer.output.write('Box Cluster Cx between individual {} and individual {}'.format(repr(ind1.index), repr(ind2.index)))

    # Perserve starting conditions of individual
    solid1 = ind1[0].copy()
    solid2 = ind2[0].copy()
    cello1 = ind1[0].get_cell()
    cello2 = ind2[0].get_cell()
    cell1 = numpy.maximum.reduce(solid1.get_positions())
    cell1m = numpy.minimum.reduce(solid1.get_positions())
    cell2 = numpy.maximum.reduce(solid2.get_positions())
    cell2m = numpy.minimum.reduce(solid2.get_positions())
    cell = numpy.minimum(cell1, cell2)
    pbc1 = solid1.get_pbc()
    pbc2 = solid2.get_pbc()

    # Get starting concentrations and number of atoms
    nat1 = len(solid1)
    nat2 = len(solid2)

    # Pick a origin point for box in the cell
    pt1 = random.choice(solid1)
    pt1f = [(pt1.position[i]-cell1m[i])/cell1[i] for i in range(3)]
    pt2 = [pt1f[i]*cell2[i]+cell2m[i] for i in range(3)]
    solid2.append(Atom(position=pt2))
    pt2 = solid2[len(solid2)-1]

    # Find max neighborsize of circle cut
    r = random.uniform(0, min(nat1, nat2)/5.0)
    if debug:
        print('DEBUG CX: Point one = {}'.format(pt1.position))
        print('DEBUG CX: Point two = {}'.format(pt2.position))

    # Find atoms within sphere of neighborsize r for both individuals
    # Make sure that crossover is only selection of atoms not all
    while True:
        ctoff = [r for on in solid1]
        nl = NeighborList(ctoff, bothways=True, self_interaction=False)
        nl.update(solid1)
        indices1, offsets = nl.get_neighbors(pt1.index)
        if len(indices1) == 0:
            r = r*1.2
        elif len(indices1) < nat1*.75:
            break
        else:
            r = r*0.8

    if debug:
        print('Neighborsize of box = {}'.format(repr(r)))
        print('Position in solid1 = {}'.format(repr(pt1.position)))
        print('Position in solid2 = {}'.format(repr(pt2.position)))

    group1 = Atoms(cell=solid1.get_cell(), pbc=solid1.get_pbc())
    group1.append(pt1)
    indices1a = [pt1.index]
    for index, d in zip(indices1, offsets):
        if index not in indices1a:
            index = int(index)
            pos = solid1[index].position + numpy.dot(d, solid1.get_cell())
            group1.append(Atom(symbol=solid1[index].symbol, position=pos))
            indices1a.append(index)
    indices1 = indices1a
    ctoff = [r for on in solid2]
    nl = NeighborList(ctoff, bothways=True, self_interaction=False)
    nl.update(solid2)
    indices2, offsets = nl.get_neighbors(pt2.index)
    group2 = Atoms(cell=solid2.get_cell(), pbc=solid2.get_pbc())
    indices2a = []
    for index, d in zip(indices2, offsets):
        if index not in indices2a:
            index = int(index)
            pos = solid2[index].position + numpy.dot(d, solid2.get_cell())
            group2.append(Atom(symbol=solid2[index].symbol, position=pos))
            indices2a.append(index)
    indices2 = indices2a
    if len(indices2) == 0:
        for one in group1:
            while True:
                sel = random.choice(solid2)
                if sel.symbol == one.symbol:
                    if sel.index not in indices2:
                        group2.append(sel)
                        indices2.append(sel.index)
                        break

    if Optimizer.forcing == 'Concentration':
        symlist = list(set(group1.get_chemical_symbols()))
        seplist = [[atm for atm in group2 if atm.symbol == sym] for sym in symlist]
        group2n = Atoms(cell=group2.get_cell(), pbc=group2.get_pbc())
        indices2n = []
        dellist = []
        for one in group1:
            sym1 = one.symbol
            listpos = [i for i, s in enumerate(symlist) if s == sym1][0]
            if len(seplist[listpos]) > 0:
                pos = random.choice(range(len(seplist[listpos])))
                group2n.append(seplist[listpos][pos])
                indices2n.append(indices2[seplist[listpos][pos].index])
                del seplist[listpos][pos]
            else:
                dellist.append(one.index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group1[one]
                del indices1[one]
        indices2n.append(pt2.index)
        indices2 = indices2n
        group2 = group2n.copy()
    else:
        dellist = []
        while len(group2) < len(group1)-len(dellist):
            # Too many atoms in group 1
            dellist.append(random.choice(group1).index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group1[one]
                del indices1[one]
        dellist = []
        while len(group1) < len(group2)-len(dellist):
            # Too many atoms in group 2
            dellist.append(random.choice(group2).index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group2[one]
                del indices2[one]

    other2 = Atoms(cell=solid2.get_cell(), pbc=solid2.get_pbc())
    for one in solid2:
        if one.index not in indices2:
            other2.append(one)
    other1 = Atoms(cell=solid1.get_cell(), pbc=solid1.get_pbc())
    for one in solid1:
        if one.index not in indices1:
            other1.append(one)

    # Exchange atoms in sphere and build new solids
    nsolid1 = other1.copy()
    nsolid1.extend(group2.copy())
    nsolid2 = other2.copy()
    nsolid2.extend(group1.copy())

    # DEBUG: Write crossover to file
    if debug:
        write_xyz(Optimizer.debugfile, nsolid1, 'CX(randalloybx):nsolid1')
        write_xyz(Optimizer.debugfile, nsolid2, 'CX(randalloybx):nsolid2')


    # DEBUG: Check structure of atoms exchanged
    for sym, c, m, u in Optimizer.atomlist:
        if Optimizer.structure == 'Defect':
            nc = len([atm for atm in nsolid1 if atm.symbol == sym])
            nc += len([atm for atm in ind1.bulki if atm.symbol == sym])
            oc = len([atm for atm in solid1 if atm.symbol == sym])
            oc += len([atm for atm in ind1.bulki if atm.symbol == sym])
        else:
            nc = len([atm for atm in nsolid1 if atm.symbol == sym])
            oc = len([atm for atm in solid1 if atm.symbol == sym])
        Optimizer.output.write('CX(clustbx):New solid1 contains '+repr(nc)+' '+repr(sym)+' atoms\n')
        if debug:
            print('DEBUG CX: New solid1 contains {} {} atoms'.format(repr(nc), repr(sym)))
        if oc != nc:
            # pdb.set_trace()
            print('CX: Issue in maintaining atom concentration\n Dropping new individual')
            Optimizer.output.write('CX: Issue in maintaining atom concentration\n Dropping new individual 1\n')
            nsolid1 = solid1
    for sym, c, m, u in Optimizer.atomlist:
        if Optimizer.structure == 'Defect':
            nc = len([atm for atm in nsolid2 if atm.symbol == sym])
            nc += len([atm for atm in ind2.bulki if atm.symbol == sym])
            oc = len([atm for atm in solid2 if atm.symbol == sym])
            oc += len([atm for atm in ind2.bulki if atm.symbol == sym])
        else:
            nc = len([atm for atm in nsolid2 if atm.symbol == sym])
            oc = len([atm for atm in solid2 if atm.symbol == sym])
        Optimizer.output.write('CX(clustbx):New solid2 contains '+repr(nc)+' '+repr(sym)+' atoms\n')
        if debug:
            print('DEBUG CX: New solid2 contains {} and {} atoms'.format(repr(nc), repr(sym)))
        if oc != nc:
            #pdb.set_trace()
            print('CX: Issue in maintaining atom concentration\n Dropping new individual')
            Optimizer.output.write('CX: Issue in maintaining atom concentration\n Dropping new individual 2\n')
            solid2.pop()
            nsolid2 = solid2
    if Optimizer.forcing != 'Concentration':
        for i in range(len(Optimizer.atomlist)):
            atms1 = [inds for inds in nsolid1 if inds.symbol == Optimizer.atomlist[i][0]]
            atms2 = [inds for inds in nsolid2 if inds.symbol == Optimizer.atomlist[i][0]]
            if len(atms1) == 0:
                if len(atms2) == 0:
                    nsolid1[random.randint(0, len(indi1)-1)].symbol == Optimizer.atomlist[i][0]
                    nsolid2[random.randint(0, len(indi2)-1)].symbol == Optimizer.atomlist[i][0]
                else:
                    nsolid1.append(atms2[random.randint(0, len(atms2)-1)])
                    nsolid1.pop(random.randint(0, len(nsolid1)-2))
            else:
                if len(atms2) == 0:
                    nsolid2.append(atms1[random.randint(0, len(atms1)-1)])
                    nsolid2.pop(random.randint(0, len(nsolid2)-2))

    nsolid1.set_cell(cello1)
    nsolid2.set_cell(cello2)
    nsolid1.set_pbc(pbc1)
    nsolid2.set_pbc(pbc2)

    ind1[0] = nsolid1.copy()
    ind2[0] = nsolid2.copy()

    return ind1, ind2
Beispiel #34
0
def newclus(ind1, ind2, Optimizer):
    """Select a box in the cluster configuration"""
    if 'CX' in Optimizer.debug:
        debug = True
    else:
        debug = False
    Optimizer.output.write('Box Cluster Cx between individual ' +
                           repr(ind1.index) + ' and individual ' +
                           repr(ind2.index) + '\n')

    #Perserve starting conditions of individual
    solid1 = ind1[0].copy()
    solid2 = ind2[0].copy()
    cello1 = ind1[0].get_cell()
    cello2 = ind2[0].get_cell()
    cell1 = numpy.maximum.reduce(solid1.get_positions())
    cell1m = numpy.minimum.reduce(solid1.get_positions())
    cell2 = numpy.maximum.reduce(solid2.get_positions())
    cell2m = numpy.minimum.reduce(solid2.get_positions())
    cell = numpy.minimum(cell1, cell2)
    pbc1 = solid1.get_pbc()
    pbc2 = solid2.get_pbc()
    #Get starting concentrations and number of atoms
    nat1 = len(solid1)
    nat2 = len(solid2)

    # Pick a origin point for box in the cell
    pt1 = random.choice(solid1)
    pt1f = [(pt1.position[i] - cell1m[i]) / cell1[i] for i in range(3)]
    pt2 = [pt1f[i] * cell2[i] + cell2m[i] for i in range(3)]
    solid2.append(Atom(position=pt2))
    pt2 = solid2[len(solid2) - 1]
    #Find max neighborsize of circle cut
    r = random.uniform(0, min(nat1, nat2) / 5.0)
    if debug:
        print 'DEBUG CX: Point one =', pt1.position
        print 'DEBUG CX: Point two =', pt2.position
    #Find atoms within sphere of neighborsize r for both individuals
    #Make sure that crossover is only selection of atoms not all
    while True:
        ctoff = [r for on in solid1]
        nl = NeighborList(ctoff, bothways=True, self_interaction=False)
        nl.update(solid1)
        indices1, offsets = nl.get_neighbors(pt1.index)
        if len(indices1) == 0:
            r = r * 1.2
        elif len(indices1) < nat1 * .75:
            break
        else:
            r = r * 0.8
    if debug:
        print 'Neighborsize of box = ' + repr(
            r) + '\nPosition in solid1 = ' + repr(
                pt1.position) + '\nPosition in solid2 = ' + repr(pt2.position)
    group1 = Atoms(cell=solid1.get_cell(), pbc=solid1.get_pbc())
    group1.append(pt1)
    indices1a = [pt1.index]
    for index, d in zip(indices1, offsets):
        if index not in indices1a:
            index = int(index)
            pos = solid1[index].position + numpy.dot(d, solid1.get_cell())
            group1.append(Atom(symbol=solid1[index].symbol, position=pos))
            indices1a.append(index)
    indices1 = indices1a
    ctoff = [r for on in solid2]
    nl = NeighborList(ctoff, bothways=True, self_interaction=False)
    nl.update(solid2)
    indices2, offsets = nl.get_neighbors(pt2.index)
    group2 = Atoms(cell=solid2.get_cell(), pbc=solid2.get_pbc())
    indices2a = []
    for index, d in zip(indices2, offsets):
        if index not in indices2a:
            index = int(index)
            pos = solid2[index].position + numpy.dot(d, solid2.get_cell())
            group2.append(Atom(symbol=solid2[index].symbol, position=pos))
            indices2a.append(index)
    indices2 = indices2a
    if len(indices2) == 0:
        for one in group1:
            while True:
                sel = random.choice(solid2)
                if sel.symbol == one.symbol:
                    if sel.index not in indices2:
                        group2.append(sel)
                        indices2.append(sel.index)
                        break

    if Optimizer.forcing == 'Concentration':
        symlist = list(set(group1.get_chemical_symbols()))
        seplist = [[atm for atm in group2 if atm.symbol == sym]
                   for sym in symlist]
        group2n = Atoms(cell=group2.get_cell(), pbc=group2.get_pbc())
        indices2n = []
        dellist = []
        for one in group1:
            sym1 = one.symbol
            listpos = [i for i, s in enumerate(symlist) if s == sym1][0]
            if len(seplist[listpos]) > 0:
                pos = random.choice(range(len(seplist[listpos])))
                group2n.append(seplist[listpos][pos])
                indices2n.append(indices2[seplist[listpos][pos].index])
                del seplist[listpos][pos]
            else:
                dellist.append(one.index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group1[one]
                del indices1[one]
        indices2n.append(pt2.index)
        indices2 = indices2n
        group2 = group2n.copy()
    else:
        dellist = []
        while len(group2) < len(group1) - len(dellist):
            #Too many atoms in group 1
            dellist.append(random.choice(group1).index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group1[one]
                del indices1[one]
        dellist = []
        while len(group1) < len(group2) - len(dellist):
            #Too many atoms in group 2
            dellist.append(random.choice(group2).index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group2[one]
                del indices2[one]

    other2 = Atoms(cell=solid2.get_cell(), pbc=solid2.get_pbc())
    for one in solid2:
        if one.index not in indices2:
            other2.append(one)
    other1 = Atoms(cell=solid1.get_cell(), pbc=solid1.get_pbc())
    for one in solid1:
        if one.index not in indices1:
            other1.append(one)

    #Exchange atoms in sphere and build new solids
    nsolid1 = other1.copy()
    nsolid1.extend(group2.copy())
    nsolid2 = other2.copy()
    nsolid2.extend(group1.copy())

    #DEBUG: Write crossover to file
    if debug:
        write_xyz(Optimizer.debugfile, nsolid1, 'CX(randalloybx):nsolid1')
        write_xyz(Optimizer.debugfile, nsolid2, 'CX(randalloybx):nsolid2')

    #DEBUG: Check structure of atoms exchanged
    for sym, c, m, u in Optimizer.atomlist:
        if Optimizer.structure == 'Defect':
            nc = len([atm for atm in nsolid1 if atm.symbol == sym])
            nc += len([atm for atm in ind1.bulki if atm.symbol == sym])
            oc = len([atm for atm in solid1 if atm.symbol == sym])
            oc += len([atm for atm in ind1.bulki if atm.symbol == sym])
        else:
            nc = len([atm for atm in nsolid1 if atm.symbol == sym])
            oc = len([atm for atm in solid1 if atm.symbol == sym])
        Optimizer.output.write('CX(clustbx):New solid1 contains ' + repr(nc) +
                               ' ' + repr(sym) + ' atoms\n')
        if debug:
            print 'DEBUG CX: New solid1 contains ' + repr(nc) + ' ' + repr(
                sym) + ' atoms'
        if oc != nc:
            #pdb.set_trace()
            print 'CX: Issue in maintaining atom concentration\n Dropping new individual'
            Optimizer.output.write(
                'CX: Issue in maintaining atom concentration\n Dropping new individual 1\n'
            )
            nsolid1 = solid1
    for sym, c, m, u in Optimizer.atomlist:
        if Optimizer.structure == 'Defect':
            nc = len([atm for atm in nsolid2 if atm.symbol == sym])
            nc += len([atm for atm in ind2.bulki if atm.symbol == sym])
            oc = len([atm for atm in solid2 if atm.symbol == sym])
            oc += len([atm for atm in ind2.bulki if atm.symbol == sym])
        else:
            nc = len([atm for atm in nsolid2 if atm.symbol == sym])
            oc = len([atm for atm in solid2 if atm.symbol == sym])
        Optimizer.output.write('CX(clustbx):New solid2 contains ' + repr(nc) +
                               ' ' + repr(sym) + ' atoms\n')
        if debug:
            print 'DEBUG CX: New solid2 contains ' + repr(nc) + ' ' + repr(
                sym) + ' atoms'
        if oc != nc:
            #pdb.set_trace()
            print 'CX: Issue in maintaining atom concentration\n Dropping new individual'
            Optimizer.output.write(
                'CX: Issue in maintaining atom concentration\n Dropping new individual 2\n'
            )
            solid2.pop()
            nsolid2 = solid2
    if Optimizer.forcing != 'Concentration':
        for i in range(len(Optimizer.atomlist)):
            atms1 = [
                inds for inds in nsolid1
                if inds.symbol == Optimizer.atomlist[i][0]
            ]
            atms2 = [
                inds for inds in nsolid2
                if inds.symbol == Optimizer.atomlist[i][0]
            ]
            if len(atms1) == 0:
                if len(atms2) == 0:
                    nsolid1[random.randint(
                        0,
                        len(indi1) - 1)].symbol == Optimizer.atomlist[i][0]
                    nsolid2[random.randint(
                        0,
                        len(indi2) - 1)].symbol == Optimizer.atomlist[i][0]
                else:
                    nsolid1.append(atms2[random.randint(0, len(atms2) - 1)])
                    nsolid1.pop(random.randint(0, len(nsolid1) - 2))
            else:
                if len(atms2) == 0:
                    nsolid2.append(atms1[random.randint(0, len(atms1) - 1)])
                    nsolid2.pop(random.randint(0, len(nsolid2) - 2))

    nsolid1.set_cell(cello1)
    nsolid2.set_cell(cello2)
    nsolid1.set_pbc(pbc1)
    nsolid2.set_pbc(pbc2)

    ind1[0] = nsolid1.copy()
    ind2[0] = nsolid2.copy()

    return ind1, ind2
Beispiel #35
0
class Onetep(FileIOCalculator):
    """Implements the calculator for the onetep linear
    scaling DFT code. Recomended ASE_ONETEP_COMMAND format
    is "onetep_executable_name PREFIX.dat > PREFIX.out 2> PREFIX.err" """

    implemented_properties = ['energy', 'forces']

    # Used to indicate 'parameters' which shouldn't be written to
    # the onetep input file in the standard <key> : <value> format
    # for example the NGWF radius is used in the species block and isn't
    # written elsewhere in the input file
    _dummy_parameters = ['ngwf_radius', 'xc', 'species_ngwf_radius',
                         'species_ngwf_number', 'species_solver']

    default_parameters = {'cutoff_energy': '1000 eV',
                          'kernel_cutoff': '1000 bohr',
                          'ngwf_radius': 12.0}

    name = 'onetep'

    def __init__(self, restart=None, ignore_bad_restart_file=False,
                 label=None, command=None, atoms=None, **kwargs):
        FileIOCalculator.__init__(self, restart, ignore_bad_restart_file,
                                  label, atoms, command, **kwargs)

        self.species = []
        self.species_cond = []
        self.pseudos = []
        self.restart = False
        self.prefix = label
        self.directory = '.'

    def read(self, label):
        """Read a onetep .out file into the current instance."""

        FileIOCalculator.read(self, label)

        onetep_file = self.label + '.out'

        warnings = []

        try:
            out = paropen(onetep_file, 'r')
        except IOError:
            raise ReadError('Could not open output file "%s"' % onetep_file)

        # keep track of what we've read in
        read_lattice = False
        read_species = False
        read_positions = False

        line = out.readline()

        if self.atoms is None:
            self.atoms = Atoms()
            self.atoms.calc = self

        while line:
            clean_line = line.strip().lower()
            if '%block lattice_cart' in clean_line:
                self._read_lattice(out)
                read_lattice = True
            elif '%block species_pot' in clean_line:
                self._read_species_pot(out)
            elif '%block species' in clean_line:
                self._read_species(out)
                read_species = True
            elif '%block positions_abs' in clean_line:
                self._read_positions(out)
                read_positions = True
            elif '%block species_cond' in clean_line:
                self._read_species_cond(out)
            elif 'warn' in line.lower():
                warnings.append(line)
            line = out.readline()
        out.close()

        if warnings:
            warn('WARNING: %s contains warnings' % onetep_file)
            for warning in warnings:
                warn(warning)

        if not (read_lattice and read_species and read_positions):
            raise ReadError('Failed to read in essential calculation'
                            ' data from output file "%s"' % onetep_file)

        self.read_results(label)

    def read_results(self):
        FileIOCalculator.read_results(self)

        onetep_file = self.label + '.out'

        warnings = []

        try:
            out = paropen(onetep_file, 'r')
        except IOError:
            raise ReadError('Could not open output file "%s"' % onetep_file)

        line = out.readline()
        while line:
            if '| Total' in line:
                self.results['energy'] = Hartree * float(line.split()[-2])
            elif ('Element  Atom         Cartesian components (Eh/a)'
                  in line):
                self._read_forces(out)
            elif 'warn' in line.lower():
                warnings.append(line)
            line = out.readline()

        if warnings:
            warn('WARNING: %s contains warnings' % onetep_file)
            for warning in warnings:
                warn(warning)

    def _read_lattice(self, out):
        """ read the lattice parameters out of a onetep .out formatted file
        stream"""

        axes = []

        l = out.readline()
        # onetep assumes lengths are in atomic units by default
        conv_fac = Bohr
        if 'ang' in l:
            l = out.readline()
            conv_fac = 1.0
        elif 'bohr' in l:
            l = out.readline()

        for _ in range(0, 3):
            l = l.strip()
            p = l.split()
            if len(p) != 3:
                raise ReadError('Malfromed Lattice block line "%s"' % l)
            try:
                axes.append([conv_fac * float(comp) for comp in p[0:3]])
            except ValueError:
                raise ReadError("Can't parse line \"%s\" in axes block" % l)
            l = out.readline()
        self.atoms.set_cell(axes)

    def _read_positions(self, out):
        """Read the contents of a positions_abs block into the calculator's
        atoms object, setting both species and positions. Tries to strip out
        comment lines and is aware of angstom vs. bohr"""

        line = out.readline()
        # onetep assumes lengths are in atomic units by default
        conv_fac = Bohr
        if 'ang' in line:
            line = out.readline()
            conv_fac = 1.0
        elif 'bohr' in line:
            line = out.readline()
        symbols = []
        positions = []
        while '%endblock' not in line.lower():
            line = line.strip()
            if line[0] != '#':
                atom, suffix = line.split(None, 1)
                pos = suffix.split(None, 3)[0:3]
                try:
                    pos = [conv_fac * float(p) for p in pos]
                except ValueError:
                    raise ReadError('Malformed position line "%s"', line)
                symbols.append(atom)
                positions.append(pos)
            line = out.readline()
        self.atoms.set_chemical_symbols(symbols)
        self.atoms.set_positions(positions)

    def _read_species(self, out):
        """ Read in species block from a onetep output file"""
        line = out.readline().strip()
        species = []
        while '%endblock' not in line.lower():
            atom, element, z, nngwf, ngwf_radius = line.split(None, 5)
            z = int(z)
            nngwf = int(nngwf)
            ngwf_radius = float(ngwf_radius)
            species.append((atom, element, z, nngwf, ngwf_radius,))
            line = out.readline().strip()
        self.set_species(species)

    def _read_species_pot(self, out):
        """ Read in pseudopotential information from a onetep output file"""
        line = out.readline().strip()
        pots = []
        while '%endblock' not in line.lower() and len(line) > 0:
            atom, suffix = line.split(None, 1)
            filename = suffix.split('#', 1)[0].strip()
            filename = filename.replace('"', '')   # take out quotes
            filename = filename.replace("'", '')
            pots.append((atom, filename,))
            line = out.readline().strip()
        if len(line) == 0:
            raise ReadError('End of file while reading potential block')
        self.set_pseudos(pots)

    def _read_species_cond(self, out):
        """ Read in conduction species block from a onetep output file"""
        line = out.readline().strip()
        species_cond = []
        while '%endblock' not in line.lower():
            atom, element, z, nngwf, ngwf_radius = line.split(None, 5)
            z = int(z)
            nngwf = int(nngwf)
            ngwf_radius = float(ngwf_radius)
            species_cond.append((atom, element, z, nngwf, ngwf_radius, ))
            line = out.readline().strip()
        self.set_species_cond(species_cond)

    def _read_forces(self, out):
        """ Extract the computed forces from a onetep output file"""
        forces = []
        atomic2ang = Hartree / Bohr
        while True:
            line = out.readline()
            fields = line.split()
            if len(fields) > 6:
                break
        while len(fields) == 7:
            force = [float(fcomp) * atomic2ang for fcomp in fields[-4:-1]]
            forces.append(force)
            line = out.readline()
            fields = line.split()
        self.results['forces'] = array(forces)

    def _generate_species_block(self):
        """Create a default onetep species block, use -1 for the NGWF number
        to trigger automatic NGWF number assigment using onetep's internal
        routines."""

        # check if we need to do anything.
        if len(self.species) == len(self.atoms.get_chemical_symbols()):
            return

        parameters = self.parameters

        self.species = []
        atoms = self.atoms
        default_ngwf_radius = self.parameters['ngwf_radius']
        for sp in set(zip(atoms.get_atomic_numbers(),
                          atoms.get_chemical_symbols())):
            try:
                ngrad = parameters['species_ngwf_radius'][sp[1]]
            except KeyError:
                ngrad = default_ngwf_radius
            try:
                ngnum = parameters['species_ngwf_number'][sp[1]]
            except KeyError:
                ngnum = -1
            self.species.append((sp[1], sp[1], sp[0], ngnum, ngrad))

    def set_pseudos(self, pots):
        """ Sets the pseudopotential files used in this dat file
        TODO: add some verification - do the psuedos imply the same
        functional as we're using?"""

        self.pseudos = deepcopy(pots)

    def set_atoms(self, atoms):
        self.atoms = atoms

    def set_species(self, sp):
        """ Sets the species in the current dat instance,
        in onetep this includes both atomic number information
        as well as NGWF parameters like number and cut off radius"""
        self.species = deepcopy(sp)

    def set_species_cond(self, spc):
        """ Sets the conduction species in the current dat instance,
        in onetep this includes both atomic number information
        as well as NGWF parameters like number and cut off radius"""
        self.species_cond = deepcopy(spc)

    def write_input(self, atoms, properties=None, system_changes=None):
        """Only writes the input .dat file and return
        This can be useful if one quickly needs to prepare input files
        for a cluster where no python or ASE is available. One can than
        upload the file manually and read out the results using
        Onetep().read().
        """

        if atoms is None:
            atoms = self.atoms

        if self.restart:
            self.parameters['read_tightbox_ngwfs'] = True
            self.parameters['read_denskern'] = True

        self._generate_species_block()

        self._write_dat()

    def get_forces(self, atoms=None):
        self.parameters['write_forces'] = True
        return FileIOCalculator.get_forces(self, atoms)

    def _write_dat(self, force_write=True):
        """This export function write minimal information to
        a .dat file. If the atoms object is a trajectory, it will
        take the last image.
        """
        filename = self.label + '.dat'

        if self.atoms is None:
            raise Exception('No associated atoms object.')

        atoms = self.atoms
        parameters = self.parameters

        if isfile(filename) and not force_write:
            raise Exception('Target input file already exists.')

        if 'xc' in parameters and 'xc_functional' in parameters \
                and parameters['xc'] != parameters['xc_functional']:
            raise Exception('Conflicting functionals defined! %s vs. %s' %
                            (parameters['xc'], parameters['xc_functional']))

        fd = open(filename, 'w')
        fd.write('######################################################\n')
        fd.write('#ONETEP .dat file: %s\n' % filename)
        fd.write('#Created using the Atomic Simulation Environment (ASE)\n')
        fd.write('######################################################\n\n')
        fd.write('%BLOCK LATTICE_CART\n')
        fd.write('ang\n')

        for line in atoms.get_cell():
            fd.write('    %.10f %.10f %.10f\n' % tuple(line))
        fd.write('%ENDBLOCK LATTICE_CART\n\n\n')

        keyword = 'POSITIONS_ABS'

        positions = atoms.get_positions()
        pos_block = [('%s %8.6f %8.6f %8.6f' %
                      (x, y[0], y[1], y[2])) for (x, y)
                     in zip(atoms.get_chemical_symbols(), positions)]

        fd.write('%%BLOCK %s\n' % keyword)
        fd.write('ang\n')
        for line in pos_block:
            fd.write('    %s\n' % line)
        fd.write('%%ENDBLOCK %s\n\n' % keyword)

        keyword = 'SPECIES'

        sp_block = [('%s %s %d %d %8.6f' % sp) for sp in self.species]

        fd.write('%%BLOCK %s\n' % keyword)
        for line in sp_block:
            fd.write('    %s\n' % line)
        fd.write('%%ENDBLOCK %s\n\n' % keyword)

        keyword = 'SPECIES_POT'
        fd.write('%%BLOCK %s\n' % keyword)
        for sp in self.pseudos:
            fd.write('    %s "%s"\n' % (sp[0], sp[1]))
        fd.write('%%ENDBLOCK %s\n\n' % keyword)

        keyword = 'SPECIES_ATOMIC_SET'
        fd.write('%%BLOCK %s\n' % keyword)
        for sym in set(self.atoms.get_chemical_symbols()):
            try:
                atomic_string = parameters['species_solver'][sym]
            except KeyError:
                atomic_string = 'SOLVE'

            fd.write('    %s "%s"\n' % (sym, atomic_string))
        fd.write('%%ENDBLOCK %s\n\n' % keyword)

        for p in parameters:
            if parameters[p] is not None and \
                    p.lower() not in self._dummy_parameters:
                fd.write('%s : %s\n' % (p, parameters[p]))
            if p.upper() == 'XC':
                # Onetep calls XC something else...
                fd.write('xc_functional : %s\n' % parameters[p])
        fd.close()

    def __repr__(self):
        """Returns generic, fast to capture representation of
        ONETEP settings along with atoms object.
        """
        expr = ''
        expr += '-----------------Atoms--------------------\n'
        if self.atoms is not None:
            expr += str('%20s\n' % self.atoms)
        else:
            expr += 'None\n'

        expr += '\n-----------------Species---------------------\n'
        expr += str(self.species)
        expr += '\n-----------------Pseudos---------------------\n'
        expr += str(self.pseudos)
        expr += '\n-----------------Options------------\n'
        for key in self.parameters:
            expr += '%20s : %s\n' % (key, self.parameters[key])

        return expr

    def set_label(self, label):
        """The label is part of each seed, which in turn is a prefix
        in each ONETEP related file.
        """
        self.label = label
        self.prefix = label
Beispiel #36
0
def write_pw_in(d,a,p):

    if 'iofile' in p.keys() :
        # write special varians of the pw input
        fh=open(os.path.join(d,p['iofile']+'.in'),'w')
    else :
        # write standard pw input
        fh=open(os.path.join(d,'pw.in'),'w')

    # ----------------------------------------------------------
    # CONTROL section
    # ----------------------------------------------------------

    fh.write(' &CONTROL\n')
    fh.write("    calculation = '%s',\n" % p['calc'])

    pwin_k=['tstress', 'tprnfor','nstep','pseudo_dir','outdir',
            'wfcdir', 'prefix','forc_conv_thr', 'etot_conv_thr']
    write_section_params(fh, pwin_k, p)
    fh.write(' /\n')
    
    # ----------------------------------------------------------
    # SYSTEM section
    # ----------------------------------------------------------

    fh.write(' &SYSTEM\n')
    if p['use_symmetry'] :
        # Need to use symmetry properly
        # create a dummy atoms object for primitive cell
        primcell=write_cell_params(fh,a,p)
        if primcell :
            # primitive cell has been found - let us use it
            cr=Atoms(cell=primcell[0],scaled_positions=primcell[1],numbers=primcell[2],pbc=True)
        else :
            # no primitive cell found - drop the symmetry
            cr=a
    else :
        cr=a
        p['ibrav']=0
    fh.write("    nat = %d,\n" % (cr.get_number_of_atoms()))
    fh.write("    ntyp = %d,\n" % (len(set(cr.get_atomic_numbers()))))
    pwin_k=['ecutwfc','ibrav','nbnd','occupations','degauss','smearing','ecutrho','nbnd']
    # must also take into account degauss and smearing
    write_section_params(fh, pwin_k, p)
    fh.write(' /\n')

    # ----------------------------------------------------------
    # ELECTRONS section
    # ----------------------------------------------------------

    fh.write(' &ELECTRONS\n')
    # must also take into account mixing_beta mixing_mode and diagonalization
    pwin_k=['conv_thr','mixing_beta','mixing_mode','diagonalization',
        'mixing_ndim','electron_maxstep']
    write_section_params(fh, pwin_k, p)
    fh.write(' /\n')

    # ----------------------------------------------------------
    # | IONS section
    # ----------------------------------------------------------

    if p['calc'] in ['vc-relax', 'vc-md', 'md', 'relax']:
        fh.write(' &IONS\n')
        pwin_k=['ion_dynamics','ion_positions', 'phase_space', 'pot_extrapolation']
        write_section_params(fh, pwin_k, p)
        
        fh.write(' /\n')


    # ----------------------------------------------------------
    # | CELL section
    # ----------------------------------------------------------

    if p['calc'] in ['vc-relax', 'vc-md']:
        fh.write('&CELL\n')
        pwin_k=['cell_dynamics','press', 'cell_dofree']
        write_section_params(fh, pwin_k, p)
    
        fh.write('/\n')


    # ----------------------------------------------------------
    # Card: ATOMIC_SPECIES
    # ----------------------------------------------------------
        
    fh.write('ATOMIC_SPECIES\n')
    
    xc=p['xc']
    pp_type=p['pp_type']
    pp_format=p['pp_format']
    # we check if the desired potential exists. Get the PP locations
    if 'ESPRESSO_PSEUDO' in os.environ:
        pppaths = os.environ['ESPRESSO_PSEUDO']
    else:
        pppaths = p['pseudo_dir']  # default
    pppaths = pppaths.split(':')
    # search for element PP in each location (in principle with QE only one location)
    for nm, mass in set(zip(cr.get_chemical_symbols(),cr.get_masses())):
        name = "%s_%s_%s.%s" % (nm, xc, pp_type, pp_format)
        found = False
        
        for path in pppaths:
            filename = os.path.join(path, name)

            match = glob.glob(filename)
            if match: # the exact name as expected
                found = True
                name = match[0]
                
            if not found: # a more permissive name with element.*.format
                name = "%s.*.%s" % (nm, pp_format)
                filename = os.path.join(path, name)
                match = glob.glob(filename)
                if match:
                    found = True
                    name = match[0] # the first match
            if not found: # a more permissive name with element_*.format
                name = "%s_*.%s" % (nm, pp_format)
                filename = os.path.join(path, name)
                match = glob.glob(filename)
                if match:
                    found = True
                    name = match[0] # the first match
            if not found: # a more permissive name with just the element_*
                name = "%s_*" % (nm)
                filename = os.path.join(path, name)
                match = glob.glob(filename)
                if match:
                    found = True
                    name = match[0] # the first match
            if not found: # a more permissive name with just the element.*
                name = "%s.*" % (nm)
                filename = os.path.join(path, name)
                match = glob.glob(filename)
                if match:
                    found = True
                    name = match[0] # the first match

        if not found:
            raise RuntimeError('Espresso: No pseudopotential for %s. Aborting.' % nm)
        
        fh.write("    %s %g %s \n" % (nm, mass, os.path.basename(name)))

    # ----------------------------------------------------------
    # Card: ATOMIC_POSITIONS
    # ----------------------------------------------------------
    
    fh.write('ATOMIC_POSITIONS crystal\n')
    # Now we can write it out
    for n,v in zip(cr.get_chemical_symbols(),cr.get_scaled_positions()):
        fh.write("    %s %g %g %g\n" % (n, v[0], v[1], v[2]))

    # ----------------------------------------------------------
    # Card: CELL_PARAMETERS
    # ----------------------------------------------------------
    # Write out only if ibrav==0 - no symmetry used
    if not p['use_symmetry'] or p['ibrav']==0:
        fh.write('CELL_PARAMETERS angstrom\n')
        
        for v in cr.get_cell():
            fh.write('    %f %f %f\n' % tuple(v))
        
    # ----------------------------------------------------------
    # Card: K_POINTS
    # ----------------------------------------------------------

    if p['kpt_type'] in ['automatic','edos'] :
        fh.write('K_POINTS %s\n' % 'automatic')
    else :
        fh.write('K_POINTS %s\n' % p['kpt_type'])
        
    if p['kpt_type'] is 'automatic':
        fh.write('   %d %d %d   %d %d %d\n' % (tuple(p['kpts'])+tuple(p['kpt_shift'])))
    elif p['kpt_type'] is 'edos':
        fh.write('   %d %d %d   %d %d %d\n' % (tuple(p['nkdos'])+tuple([0,0,0])))
    elif not p['kpt_type'] is 'gamma':
        write_q_path(fh,p['qpath'],p['points'])
    fh.close()
Beispiel #37
0
def rotct(ind1, ind2, Optimizer):
    """Rotate atoms cut and splice
    Rotates atoms randomly around center of mass and cuts with xy plane
    Maintains number of atoms
    Maintains concentration of atoms
    Returns individuals to standard positions at end (un-rotates)
    """
    if 'CX' in Optimizer.debug:
        debug = True
    else:
        debug = False
    Optimizer.output.write('Rotate Cut/Splice Cx between individual '+repr(ind1.index)+' and individual '+repr(ind2.index)+'\n')
    
    #Perserve starting conditions of individual
    indi1 = ind1[0].copy()
    indi2 = ind2[0].copy()
    
    #Translate individuals so COM is at (0,0,0)
    com1 = indi1.get_center_of_mass()
    indi1.translate(-1*com1)
    com2 = indi2.get_center_of_mass()
    indi2.translate(-1*com2)
    #Select random axis and random angle and rotate individuals
    n=0
    while n<10:
        rax = random.choice(['x', '-x','y','-y','z','-z'])
        rang = random.random()*90
        indi1.rotate(rax,a=rang,center='COM',rotate_cell=False)
        #Search for atoms in individual 1 that are above the xy plane
        group1 = Atoms(cell=ind1[0].get_cell(),pbc=ind1[0].get_pbc())
        indices1=[]
        for one in indi1:
            if one.position[2] >= 0:
                group1.append(one)
                indices1.append(one.index)
        if len(group1) > 2 and len(group1) < len(indi1):
            break
        else:
            indi1.rotate(rax,a=-1*rang,center='COM', rotate_cell=False)
        n+=1
    indi2.rotate(rax,a=rang,center='COM', rotate_cell=False)
    if debug: 
        print 'Group1 size = ', len(group1)
        print 'Position = ', [0,0,0]
        print 'Angle = ', rang
        print 'Axis = ', rax
        print 'Number of tries = ', n+1
    #Apply concentration forcing if needed
    group2 = Atoms(cell=ind2[0].get_cell(),pbc=ind2[0].get_pbc())
    indices2 = []
    dellist = []
    if Optimizer.forcing=='Concentration':
        symlist = list(set(group1.get_chemical_symbols()))
        seplist = [[atm for atm in indi2 if atm.symbol == sym] for sym, count in symlist]
        for one in group1:
            sym1=one.symbol
            listpos=[i for i,s in enumerate(symlist) if s==sym1][0]
            if len(seplist[listpos]) > 0:
                dist=[z for x,y,z in [one.position for one in seplist[listpos]]]
                pos = [i for i,value in enumerate(dist) if value==max(dist)][0]
                group2.append(seplist[listpos][pos])
                indices2.append(seplist[listpos][pos].index)
                del seplist[listpos][pos]
            else:
                dellist.append(one.index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group1[one]
                del indices1[one]
        #indices2.append(pt2.index)
    else:
        for one in indi2:
            if one.position[2] >= 0:
                group2.append(one)
                indices2.append(one.index)
        while len(group2) < len(group1)-len(dellist):
            #Too many atoms in group 1
            dellist.append(random.choice(group1).index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group1[one]
                del indices1[one]
        dellist = []
        while len(group1) < len(group2)-len(dellist):
            #Too many atoms in group 2
            dellist.append(random.choice(group2).index)
        if len(dellist) != 0:
            dellist.sort(reverse=True)
            for one in dellist:
                del group2[one]
                del indices2[one]
    
    other1 = Atoms()
    other2 = Atoms()
    other2 = Atoms(cell=ind2[0].get_cell(),pbc=ind2[0].get_pbc())
    for one in indi2:
        if one.index not in indices2:
            other2.append(one)
    other1 = Atoms(cell=ind1[0].get_cell(),pbc=ind1[0].get_pbc())
    for one in indi1:
        if one.index not in indices1:
            other1.append(one)
    

    indi1 = group2.copy()
    indi1.extend(other1)
    indi2 = group1.copy()
    indi2.extend(other2)
    
    #DEBUG: Write crossover to file
    if debug: 
        write_xyz(Optimizer.debugfile, group1,'group1')
        write_xyz(Optimizer.debugfile, other1,'other1')
        write_xyz(Optimizer.debugfile, group2,'group2')
        write_xyz(Optimizer.debugfile, other2,'other2')
        print 'Length of group1 = ',len(group1),'Length of group2',len(group2)
    
    
    #DEBUG: Check structure of atoms exchanged
    for sym,c,m,u in Optimizer.atomlist:
        nc=len([atm for atm in indi1 if atm.symbol==sym])
        Optimizer.output.write('CX ROTCT: Individual 1 contains '+repr(nc)+' '+repr(sym)+' atoms\n')
        nc=len([atm for atm in indi2 if atm.symbol==sym])
        Optimizer.output.write('CX ROTCT: Individual 2 contains '+repr(nc)+' '+repr(sym)+' atoms\n')

    #Need to have at least one atom of each structure in atomlist to prevent Lammps for erroring
    if Optimizer.forcing !='Concentration':
        for i in range(len(Optimizer.atomlist)):
            atms1=[inds for inds in indi1 if inds.symbol==Optimizer.atomlist[i][0]]
            atms2=[inds for inds in indi2 if inds.symbol==Optimizer.atomlist[i][0]]
            if len(atms1)==0:
                if len(atms2)==0:
                    indi1[random.randint(0,len(indi1)-1)].symbol==Optimizer.atomlist[i][0]
                    indi2[random.randint(0,len(indi2)-1)].symbol==Optimizer.atomlist[i][0]
                else:
                    indi1.append(atms2[random.randint(0,len(atms2)-1)])
                    indi1.pop(random.randint(0,len(indi1)-2))
            else:
                if len(atms2)==0:
                    indi2.append(atms1[random.randint(0,len(atms1)-1)])
                    indi2.pop(random.randint(0,len(indi2)-2))	
    indi1.rotate(rax,a=-1*rang,center='COM', rotate_cell=False)
    indi2.rotate(rax,a=-1*rang,center='COM', rotate_cell=False)
    indi1.translate(com1)
    indi2.translate(com2)

    if Optimizer.structure != 'Defect':
        cm = indi1.get_center_of_mass()
        cell = numpy.maximum.reduce(indi1.get_cell())
        cop = [cell[0]/float(2), cell[1]/float(2), cell[2]/float(2)]
        indi1.translate(-1*cm)
        indi1.translate(cop)
        cm = indi2.get_center_of_mass()
        cell = numpy.maximum.reduce(indi2.get_cell())
        cop = [cell[0]/float(2), cell[1]/float(2), cell[2]/float(2)]
        indi2.translate(-1*cm)
        indi2.translate(cop)

    ind1[0]=indi1
    ind2[0]=indi2
    
    #Check structure and number of atoms in crystal
    if Optimizer.structure=='Defect':
        solid1=Atoms()
        solid1.extend(ind1[0])
        solid1.extend(ind1.bulki)
        solid2=Atoms()
        solid2.extend(ind1[0])
        solid2.extend(ind2.bulki)
        for sym,c,m,u in Optimizer.atomlist:
                nc=len([atm for atm in solid1 if atm.symbol==sym])
                Optimizer.output.write('CX ROTCT: CIBS 1 configuration contains '+repr(nc)+' '+repr(sym)+' atoms\n')
                nc=len([atm for atm in solid2 if atm.symbol==sym])
                Optimizer.output.write('CX ROTCT: CIBS 2 configuration contains '+repr(nc)+' '+repr(sym)+' atoms\n')
    return ind1, ind2
Beispiel #38
0
def rotate(individual1, individual2, conserve_composition=True):
    """Rotates the two individuals around their centers of mass,
    splits them in half at the xy-plane, then splices them together.
    Maintains number of atoms.

    Args:
        individual1 (Individual): The first parent
        individual2 (Individual): The second parent
        conserve_composition (bool): default True. If True, conserves composition.

    Returns:
        Individual: The first child
        Individual: The second child

    The children are returned without indicies.
    """
    # Preserve starting conditions of individual
    ind1c = individual1.copy()
    ind2c = individual2.copy()

    # Translate individuals so COM is at (0, 0, 0)
    com1 = ind1c.get_center_of_mass()
    ind1c.translate(-1 * com1)
    com2 = ind2c.get_center_of_mass()
    ind2c.translate(-1 * com2)

    # Select random axis and random angle and rotate individuals
    for _ in range(0, 10):
        rax = random.choice(['x', '-x', 'y', '-y', 'z', '-z'])
        rang = random.random() * 90
        ind1c.rotate(rax, a=rang, center='COM', rotate_cell=False)
        # Search for atoms in individual 1 that are above the xy plane
        above_xy_plane1 = Atoms(cell=individual1.get_cell(), pbc=individual1.get_pbc())
        indices1 = []
        for atom in ind1c:
            if atom.z >= 0:
                above_xy_plane1.append(atom)
                indices1.append(atom.index)
        if len(above_xy_plane1) < 2 or len(above_xy_plane1) > len(ind1c):
            # Try again; unrotate ind1c
            ind1c.rotate(rax, a=-1*rang, center='COM', rotate_cell=False)
        else:
            break
    ind2c.rotate(rax, a=rang, center='COM', rotate_cell=False)

    # Generate `above_xy_plane2`, with the same concentration as `above_xy_plane1` if needed
    above_xy_plane2 = Atoms(cell=individual2.get_cell(), pbc=individual2.get_pbc())
    indices2 = []
    dellist = []
    if conserve_composition:
        symbols = list(set(above_xy_plane1.get_chemical_symbols()))
        # The below list contains atoms from ind2c, whereas `above_xy_plane1` contains atoms from ind1c
        atoms_by_symbol = {sym: [atm for atm in ind2c if atm.symbol == sym] for sym in symbols}
        for atom in above_xy_plane1:
            if len(atoms_by_symbol[atom.symbol]) > 0:
                # Get the atom from `atoms_by_symbol` that has the same type as `atom` and the largest `z` value
                dist = [atom.z for atom in atoms_by_symbol[atom.symbol]]
                pos = dist.index(max(dist))
                above_xy_plane2.append(atoms_by_symbol[atom.symbol][pos])
                indices2.append(atoms_by_symbol[atom.symbol][pos].index)
                del atoms_by_symbol[atom.symbol][pos]
            else:
                dellist.append(atom.index)
        if dellist:
            dellist.sort(reverse=True)
            for atom_index in dellist:
                del above_xy_plane1[atom_index]
                del indices1[atom_index]
    else:
        for atom in ind2c:
            if atom.z >= 0:
                above_xy_plane2.append(atom)
                indices2.append(atom.index)
        while len(above_xy_plane2) < len(above_xy_plane1)-len(dellist):
            # Too many atoms in above_xy_plane1
            dellist.append(random.choice(above_xy_plane1).index)
        if dellist:
            dellist.sort(reverse=True)
            for atom in dellist:
                del above_xy_plane1[atom]
                del indices1[atom]
        dellist = []
        while len(above_xy_plane1) < len(above_xy_plane2)-len(dellist):
            # Too many atoms in above_xy_plane2
            dellist.append(random.choice(above_xy_plane2).index)
        if dellist:
            dellist.sort(reverse=True)
            for atom in dellist:
                del above_xy_plane2[atom]
                del indices2[atom]

    below_xy_plane1 = Atoms()
    below_xy_plane2 = Atoms()
    below_xy_plane2 = Atoms(cell=individual2.get_cell(), pbc=individual2.get_pbc())
    for atom in ind2c:
        if atom.index not in indices2:
            below_xy_plane2.append(atom)
    below_xy_plane1 = Atoms(cell=individual1.get_cell(), pbc=individual1.get_pbc())
    for atom in ind1c:
        if atom.index not in indices1:
            below_xy_plane1.append(atom)


    child1 = above_xy_plane2.copy()
    child1.extend(below_xy_plane1)
    child2 = above_xy_plane1.copy()
    child2.extend(below_xy_plane2)

    # Need to have at least one atom of each specie in atomlist to prevent LAMMPS from erroring
    if not conserve_composition:
        for i in range(len(individual1)):
            atoms1 = [atom for atom in child1 if atom.symbol == individual1[i]]
            atoms2 = [atom for atom in child2 if atom.symbol == individual1[i]]
            if len(atoms1) == 0 and len(atoms2) == 0:
                random.choice(child1).symbol = individual1[i].symbol
                random.choice(child2).symbol = individual1[i].symbol
            elif len(atoms1) == 0 and len(atoms2) != 0:
                del child1[random.randint(0, len(child1))]
                child1.append(random.choice(atoms2))
            elif len(atoms1) != 0 and len(atoms2) == 0:
                del child2[random.randint(0, len(child2))]
                child2.append(random.choice(atoms1))

    # Unrotate and untranslate the children
    child1.rotate(rax, a=-1*rang, center='COM', rotate_cell=False)
    child2.rotate(rax, a=-1*rang, center='COM', rotate_cell=False)
    child1.translate(com1)
    child2.translate(com2)

    full_child1 = individual1.copy()
    full_child1.clear()
    full_child1.extend(child1)
    full_child2 = individual2.copy()
    full_child2.clear()
    full_child2.extend(child2)
    return full_child1, full_child2
syms = a4.get_chemical_symbols()

assert len(set([i for i in syms if i in anions])) == 2

from ase.ga.element_mutations import MoveDownMutation
from ase.ga.element_mutations import MoveUpMutation
from ase.ga.element_mutations import MoveRightMutation
from ase.ga.element_mutations import MoveLeftMutation

a1 = Atoms('SrSrClClClCl')
a1.info['confid'] = 1
op = MoveDownMutation(cations, 2, .5)
a2, desc = op.get_new_individual([a1])
a2.info['confid'] = 2

syms = a2.get_chemical_symbols()
assert 'Ba' in syms
assert len(set(syms)) == 3

op = MoveUpMutation(cations, 1, 1.)
a3, desc = op.get_new_individual([a2])
syms = a3.get_chemical_symbols()
assert 'Ba' not in syms
assert len(set(syms)) == 2

cations = ['Co', 'Ni', 'Cu']
a1 = Atoms('NiNiBrBr')
a1.info['confid'] = 1
op = MoveRightMutation(cations, 1, 1.)
a2, desc = op.get_new_individual([a1])
a2.info['confid'] = 2
Beispiel #40
0
def write_pw_in(d,a,p):

    if 'iofile' in p.keys() :
        # write special varians of the pw input
        fh=open(os.path.join(d,p['iofile']+'.in'),'w')
    else :
        # write standard pw input
        fh=open(os.path.join(d,'pw.in'),'w')

    # ----------------------------------------------------------
    # CONTROL section
    # ----------------------------------------------------------

    fh.write(' &CONTROL\n')
    fh.write("    calculation = '%s',\n" % p['calc'])

    pwin_k=['tstress', 'tprnfor','nstep','pseudo_dir','outdir',
            'wfcdir', 'prefix','forc_conv_thr', 'etot_conv_thr']
    write_section_params(fh, pwin_k, p)
    fh.write(' /\n')
    
    # ----------------------------------------------------------
    # SYSTEM section
    # ----------------------------------------------------------

    fh.write(' &SYSTEM\n')
    if p['use_symmetry'] :
        # Need to use symmetry properly
        # create a dummy atoms object for primitive cell
        primcell=write_cell_params(fh,a,p)
        if primcell :
            # primitive cell has been found - let us use it
            cr=Atoms(cell=primcell[0],scaled_positions=primcell[1],numbers=primcell[2],pbc=True)
        else :
            # no primitive cell found - drop the symmetry
            cr=a
    else :
        cr=a
        p['ibrav']=0
    fh.write("    nat = %d,\n" % (cr.get_number_of_atoms()))
    fh.write("    ntyp = %d,\n" % (len(set(cr.get_atomic_numbers()))))
    pwin_k=['ecutwfc','ibrav','nbnd','occupations']
    write_section_params(fh, pwin_k, p)
    fh.write(' /\n')

    # ----------------------------------------------------------
    # ELECTRONS section
    # ----------------------------------------------------------

    fh.write(' &ELECTRONS\n')
    fh.write(' /\n')

    # ----------------------------------------------------------
    # | IONS section
    # ----------------------------------------------------------

    if p['calc'] in ['vc-relax', 'vc-md', 'md', 'relax']:
        fh.write(' &IONS\n')
        pwin_k=['ion_dynamics','ion_positions', 'phase_space', 'pot_extrapolation']
        write_section_params(fh, pwin_k, p)
        
        fh.write(' /\n')


    # ----------------------------------------------------------
    # | CELL section
    # ----------------------------------------------------------

    if p['calc'] in ['vc-relax', 'vc-md']:
        fh.write('&CELL\n')
        pwin_k=['cell_dynamics','press', 'cell_dofree']
        write_section_params(fh, pwin_k, p)
    
        fh.write('/\n')


    # ----------------------------------------------------------
    # Card: ATOMIC_SPECIES
    # ----------------------------------------------------------
        
    fh.write('ATOMIC_SPECIES\n')
    
    xc=p['xc']
    pp_type=p['pp_type']
    pp_format=p['pp_format']
    for nm, mass in set(zip(cr.get_chemical_symbols(),cr.get_masses())):
        fh.write("    %s %g %s_%s_%s.%s \n" % (nm, mass, nm, xc, pp_type, pp_format))

    # ----------------------------------------------------------
    # Card: ATOMIC_POSITIONS
    # ----------------------------------------------------------
    
    fh.write('ATOMIC_POSITIONS crystal\n')
    # Now we can write it out
    for n,v in zip(cr.get_chemical_symbols(),cr.get_scaled_positions()):
        fh.write("    %s %g %g %g\n" % (n, v[0], v[1], v[2]))

    # ----------------------------------------------------------
    # Card: CELL_PARAMETERS
    # ----------------------------------------------------------
    # Write out only if ibrav==0 - no symmetry used
    if not p['use_symmetry'] or p['ibrav']==0:
        fh.write('CELL_PARAMETERS angstrom\n')
        
        for v in cr.get_cell():
            fh.write('    %f %f %f\n' % tuple(v))
        
    # ----------------------------------------------------------
    # Card: K_POINTS
    # ----------------------------------------------------------

    if p['kpt_type'] in ['automatic','edos'] :
        fh.write('K_POINTS %s\n' % 'automatic')
    else :
        fh.write('K_POINTS %s\n' % p['kpt_type'])
        
    if p['kpt_type'] is 'automatic':
        fh.write('   %d %d %d   %d %d %d\n' % (tuple(p['kpts'])+tuple(p['kpt_shift'])))
    elif p['kpt_type'] is 'edos':
        fh.write('   %d %d %d   %d %d %d\n' % (tuple(p['nkdos'])+tuple([0,0,0])))
    elif not p['kpt_type'] is 'gamma':
        write_q_path(fh,p['qpath'],p['points'])
    fh.close()