Beispiel #1
0
def test_atoms_distance():
    # Setup a chain of H,O,C
    # H-O Dist = 2
    # O-C Dist = 3
    # C-H Dist = 5 with mic=False
    # C-H Dist = 4 with mic=True
    a = Atoms('HOC', positions=[(1, 1, 1), (3, 1, 1), (6, 1, 1)])
    a.set_cell((9, 2, 2))
    a.set_pbc((True, False, False))


    # Calculate indiviually with mic=True
    assert a.get_distance(0, 1, mic=True) == 2
    assert a.get_distance(1, 2, mic=True) == 3
    assert a.get_distance(0, 2, mic=True) == 4

    # Calculate indiviually with mic=False
    assert a.get_distance(0, 1, mic=False) == 2
    assert a.get_distance(1, 2, mic=False) == 3
    assert a.get_distance(0, 2, mic=False) == 5

    # Calculate in groups with mic=True
    assert (a.get_distances(0, [1, 2], mic=True) == [2, 4]).all()

    # Calculate in groups with mic=False
    assert (a.get_distances(0, [1, 2], mic=False) == [2, 5]).all()

    # Calculate all with mic=True
    assert (a.get_all_distances(mic=True) == [[0, 2, 4],
                                              [2, 0, 3],
                                              [4, 3, 0]]).all()

    # Calculate all with mic=False
    assert (a.get_all_distances(mic=False) == [[0, 2, 5],
                                               [2, 0, 3],
                                               [5, 3, 0]]).all()

    # Scale Distance
    old = a.get_distance(0, 1)
    a.set_distance(0, 1, 0.9, add=True, factor=True)
    new = a.get_distance(0, 1)
    diff = new - 0.9 * old
    assert abs(diff) < 10e-6

    # Change Distance
    old = a.get_distance(0, 1)
    a.set_distance(0, 1, 0.9, add=True)
    new = a.get_distance(0, 1)
    diff = new - old - 0.9
    assert abs(diff) < 10e-6
Beispiel #2
0
def _calculate_distances(atoms: ase.Atoms,
                         min_im_conv: bool = True,
                         no_console: bool = False) -> np.array:
    '''Calculates the distances between each pair of ions
       By defaul it uses the minimum image convention
       It returns a square array 'dist_array' with the distances
       between ions i and j in dist_array[i][j]
    '''
    # calculate distances between the points in A
    # D = atoms.get_all_distances(mic=True, simple=True) # eats up ALL the ram N=30 MAX

    # TODO: parallelize

    num_atoms = len(atoms)
    dist_array = np.zeros((num_atoms, num_atoms), dtype=np.float64)
    for i in tqdm(range(num_atoms),
                  unit='atoms',
                  total=num_atoms,
                  desc='Calculating distances',
                  disable=no_console):
        dist_array[i, i:num_atoms] = atoms.get_distances(i,
                                                         range(i, num_atoms),
                                                         mic=min_im_conv)

    # get the distance along the c axis divided by two
    # dmaxReal = atoms.cell[2][2]/2;
    # dist_array[dist_array > dmaxReal] = 0 # discard distances longer than dmax
    dist_array = dist_array + dist_array.T  # make symmetrical
    #    Ds_mic = get_all_distances(atoms)
    # Ds = csr_matrix(dist_array)

    return dist_array
Beispiel #3
0
def take_cluster(old_conf_name, type_map, idx, jdata):
    cutoff = jdata['cluster_cutoff']
    sys = dpdata.System(old_conf_name, fmt = 'lammps/dump', type_map = type_map)
    atom_names = sys['atom_names']
    atom_types = sys['atom_types']
    cell = sys['cells'][0]
    coords = sys['coords'][0]
    symbols = [atom_names[atom_type] for atom_type in atom_types]
    # detect fragment 
    frag_numb, frag_index, graph = _crd2frag(symbols, coords, True, cell, return_bonds=True)
    # get_distances
    all_atoms = Atoms(symbols = symbols, positions = coords, pbc=True, cell=cell)
    all_atoms[idx].tag = 1
    distances = all_atoms.get_distances(idx, range(len(all_atoms)), mic=True)
    distancescutoff = distances < cutoff
    cutoff_atoms_idx = np.where(distancescutoff)[0]
    # make cutoff atoms in molecules
    taken_atoms_idx = []
    added = []
    for ii in range(frag_numb):
        frag_atoms_idx = np.where(frag_index == ii)[0]
        if np.any(np.isin(frag_atoms_idx, cutoff_atoms_idx)):
            if 'cluster_minify' in jdata and jdata['cluster_minify']:
                # currently support C, H
                take_frag_idx=[]
                for aa in frag_atoms_idx:
                    if np.any(np.isin(aa, cutoff_atoms_idx)):
                        take_frag_idx.append(aa)
                    elif np.count_nonzero(np.logical_and(distancescutoff, graph.toarray()[aa]==1)):
                        if all_atoms[aa].symbol == 'H':
                            take_frag_idx.append(aa)
                        elif all_atoms[aa].symbol == 'C':
                            near_atom_idx = np.nonzero(np.logical_and(distancescutoff, graph.toarray()[aa]>0))[0][0]
                            vector = all_atoms[aa].position - all_atoms[near_atom_idx].position
                            new_position = all_atoms[near_atom_idx].position + vector / np.linalg.norm(vector) * 1.09
                            added.append(Atom('H', new_position))
                    elif np.count_nonzero(np.logical_and(distancescutoff, graph.toarray()[aa]>1)):
                        take_frag_idx=frag_atoms_idx
                        break
            else:
                take_frag_idx = frag_atoms_idx
            taken_atoms_idx.append(take_frag_idx)
    all_taken_atoms_idx = np.concatenate(taken_atoms_idx)
    # wrap
    cutoff_atoms = sum(added, all_atoms[all_taken_atoms_idx])
    cutoff_atoms.wrap(
        center=coords[idx] /
        cutoff_atoms.get_cell_lengths_and_angles()[0: 3],
        pbc=True)
    coords = cutoff_atoms.get_positions()
    sys.data['coords'] = np.array([coords])
    sys.data['atom_types'] = np.array(list(atom_types[all_taken_atoms_idx]) + [atom_names.index('H')]*len(added))
    sys.data['atom_pref'] = np.array([cutoff_atoms.get_tags()])
    for ii, _ in enumerate(atom_names):
        sys.data['atom_numbs'][ii] = np.count_nonzero(sys.data['atom_types']==ii)
    return sys
Beispiel #4
0
a = Atoms('HOC', positions=[(1, 1, 1), (3, 1, 1), (6, 1, 1)])
a.set_cell((9, 2, 2))
a.set_pbc((True, False, False))


# Calculate indiviually with mic=True
assert a.get_distance(0, 1, mic=True) == 2
assert a.get_distance(1, 2, mic=True) == 3
assert a.get_distance(0, 2, mic=True) == 4

# Calculate indiviually with mic=False
assert a.get_distance(0, 1, mic=False) == 2
assert a.get_distance(1, 2, mic=False) == 3
assert a.get_distance(0, 2, mic=False) == 5

# Calculate in groups with mic=True
assert (a.get_distances(0, [1, 2], mic=True) == [2, 4]).all()

# Calculate in groups with mic=False
assert (a.get_distances(0, [1, 2], mic=False) == [2, 5]).all()

# Calculate all with mic=True
assert (a.get_all_distances(mic=True) == [[0, 2, 4],
                                          [2, 0, 3],
                                          [4, 3, 0]]).all()

# Calculate all with mic=False
assert (a.get_all_distances(mic=False) == [[0, 2, 5],
                                           [2, 0, 3],
                                           [5, 3, 0]]).all()
Beispiel #5
0
def take_cluster(old_conf_name, type_map, idx, jdata):
    cutoff = jdata['cluster_cutoff']
    cutoff_hard = jdata.get('cluster_cutoff_hard', None)
    sys = dpdata.System(old_conf_name, fmt = 'lammps/dump', type_map = type_map)
    atom_names = sys['atom_names']
    atom_types = sys['atom_types']
    cell = sys['cells'][0]
    coords = sys['coords'][0]
    symbols = [atom_names[atom_type] for atom_type in atom_types]
    # detect fragment 
    frag_numb, frag_index, graph = _crd2frag(symbols, coords, True, cell, return_bonds=True)
    # get_distances
    all_atoms = Atoms(symbols = symbols, positions = coords, pbc=True, cell=cell)
    all_atoms[idx].tag = 1
    distances = all_atoms.get_distances(idx, range(len(all_atoms)), mic=True)
    distancescutoff = distances < cutoff
    cutoff_atoms_idx = np.where(distancescutoff)[0]
    if cutoff_hard is not None:
        distancescutoff_hard = distances < cutoff_hard
        cutoff_atoms_idx_hard = np.where(distancescutoff_hard)[0]
    # make cutoff atoms in molecules
    taken_atoms_idx = []
    added = []
    for ii in range(frag_numb):
        frag_atoms_idx = np.where(frag_index == ii)[0]
        if cutoff_hard is not None:
            # drop atoms out of the hard cutoff anyway
            frag_atoms_idx = np.intersect1d(frag_atoms_idx, cutoff_atoms_idx_hard)
        if np.any(np.isin(frag_atoms_idx, cutoff_atoms_idx)):
            if 'cluster_minify' in jdata and jdata['cluster_minify']:
                # support for organic species
                take_frag_idx=[]
                for aa in frag_atoms_idx:
                    if np.any(np.isin(aa, cutoff_atoms_idx)):
                        # atom is in the soft cutoff
                        # pick up anyway
                        take_frag_idx.append(aa)
                    elif np.count_nonzero(np.logical_and(distancescutoff, graph.toarray()[aa]==1)):
                        # atom is between the hard cutoff and the soft cutoff
                        # and has a single bond with the atom inside
                        if all_atoms[aa].symbol == 'H':
                            # for atom H: just add it
                            take_frag_idx.append(aa)
                        else:
                            # for other atoms (C, O, etc.): replace it with a ghost H atom
                            near_atom_idx = np.nonzero(np.logical_and(distancescutoff, graph.toarray()[aa]>0))[0][0]
                            vector = all_atoms[aa].position - all_atoms[near_atom_idx].position
                            new_position = all_atoms[near_atom_idx].position + vector / np.linalg.norm(vector) * 1.09
                            added.append(Atom('H', new_position))
                    elif np.count_nonzero(np.logical_and(distancescutoff, graph.toarray()[aa]>1)):
                        # if that atom has a double bond with the atom inside
                        # just pick up the whole fragment (within the hard cutoff)
                        # TODO: use a more fantastic method
                        take_frag_idx=frag_atoms_idx
                        break
            else:
                take_frag_idx = frag_atoms_idx
            taken_atoms_idx.append(take_frag_idx)
    all_taken_atoms_idx = np.concatenate(taken_atoms_idx)
    # wrap
    cutoff_atoms = sum(added, all_atoms[all_taken_atoms_idx])
    cutoff_atoms.wrap(
        center=coords[idx] /
        cutoff_atoms.get_cell_lengths_and_angles()[0: 3],
        pbc=True)
    coords = cutoff_atoms.get_positions()
    sys.data['coords'] = np.array([coords])
    sys.data['atom_types'] = np.array(list(atom_types[all_taken_atoms_idx]) + [atom_names.index('H')]*len(added))
    sys.data['atom_pref'] = np.array([cutoff_atoms.get_tags()])
    for ii, _ in enumerate(atom_names):
        sys.data['atom_numbs'][ii] = np.count_nonzero(sys.data['atom_types']==ii)
    return sys
Beispiel #6
0
a = Atoms('HOC', positions=[(1, 1, 1), (3, 1, 1), (6, 1, 1)])
a.set_cell((9, 2, 2))
a.set_pbc((True, False, False))

# Calculate indiviually with mic=True
assert a.get_distance(0, 1, mic=True) == 2
assert a.get_distance(1, 2, mic=True) == 3
assert a.get_distance(0, 2, mic=True) == 4

# Calculate indiviually with mic=False
assert a.get_distance(0, 1, mic=False) == 2
assert a.get_distance(1, 2, mic=False) == 3
assert a.get_distance(0, 2, mic=False) == 5

# Calculate in groups with mic=True
assert (a.get_distances(0, [1, 2], mic=True) == [2, 4]).all()

# Calculate in groups with mic=False
assert (a.get_distances(0, [1, 2], mic=False) == [2, 5]).all()

# Calculate all with mic=True
assert (a.get_all_distances(mic=True) == [[0, 2, 4], [2, 0, 3], [4, 3,
                                                                 0]]).all()

# Calculate all with mic=False
assert (a.get_all_distances(mic=False) == [[0, 2, 5], [2, 0, 3], [5, 3,
                                                                  0]]).all()

# Scale Distance
old = a.get_distance(0, 1)
a.set_distance(0, 1, 0.9, add=True, factor=True)
def change_cell_length(atoms, space_group):

    print(atoms.get_atomic_numbers())
    name = get_name(atoms.get_atomic_numbers())
    print(name)
    # to do
    molecule1, molecule2, molecule3, molecule4 = molecule_lists(
        atoms)[0], molecule_lists(atoms)[1], molecule_lists(
            atoms)[2], molecule_lists(atoms)[3]  # [1,5,9,13,17,21,etc]

    print(molecule1)
    print(molecule2)
    print(molecule3)
    print(molecule4)
    scaled_positions = atoms.get_scaled_positions()
    #print("scaled_positions: ", scaled_positions)
    molecule1_scaled_positions = np.array(
        [scaled_positions[i] for i in molecule1])
    cell_params = atoms.get_cell()
    #print(cell_params)
    #print(atoms.get_positions())
    a_vector, b_vector, c_vector = cell_params[0], cell_params[1], cell_params[
        2]
    molecule1_vectors = np.array([
        faction[0] * a_vector + faction[1] * b_vector + faction[2] * c_vector
        for faction in molecule1_scaled_positions
    ])
    new_atoms = atoms.copy()
    new_atoms.set_cell(cell_params +
                       np.array([[1, 0, 0], [0, 1, 0], [0.1, 0, 1]]),
                       scale_atoms=False)
    new_cell_params = new_atoms.get_cell()
    print("new_cell_params: ", new_cell_params)
    new_a_vector, new_b_vector, new_c_vector = new_cell_params[
        0], new_cell_params[1], new_cell_params[2]
    new_vectors = []
    for v in molecule1_vectors:
        Va = np.dot(
            np.cross(new_b_vector, new_c_vector) /
            np.dot(new_a_vector, np.cross(new_b_vector, new_c_vector)), v)
        Vb = np.dot(
            np.cross(new_c_vector, new_a_vector) /
            np.dot(new_b_vector, np.cross(new_c_vector, new_a_vector)), v)
        Vc = np.dot(
            np.cross(new_a_vector, new_b_vector) /
            np.dot(new_c_vector, np.cross(new_a_vector, new_b_vector)), v)
        new_vectors.append([Va, Vb, Vc])
    new_sclaed_positions = np.array(new_vectors)
    print("get_symop(): ", space_group.get_symop())

    sites = []
    for kind, pos in enumerate(new_sclaed_positions):
        for rot, trans in space_group.get_symop():
            site = np.dot(rot, pos) + trans
            sites.append(site)
    print(np.array(sites))
    new_positions = np.array([
        faction[0] * new_a_vector + faction[1] * new_b_vector +
        faction[2] * new_c_vector for faction in sites
    ])
    print(new_positions)

    #wire = Atoms('',
    #         positions=[[0, L / 2, L / 2]],
    #         cell=[d, L, L],
    #         pbc=[1, 0, 0])
    writer = Atoms(name,
                   positions=new_positions,
                   cell=new_atoms.get_cell(),
                   pbc=[1, 1, 1])

    #final_scaled_positions = get_equivalent_sites(new_sclaed_positions, space_group)
    #print("final_scaled_positions: ", final_scaled_positions)

    #new_atoms.set_scaled_positions(final_scaled_positions)

    for i in molecule1:
        print(
            writer.get_distances(i, molecule1) -
            atoms.get_distances(i, molecule1))
    #print(atoms.get_distance(24,36, mic=False, vector=True))
    #print(new_atoms.get_distance(24,36, mic=False, vector=True))
    print(writer.get_cell())

    return writer