Révision dadc6016

b/modules/screening.py
24 24
def vect_avg(vects):
25 25
    """Computes the element-wise mean of a set of vectors.
26 26

  
27
    @param vects: np.ndarray with shape (num_vectors, length_vector).
27
    @param vects: list of lists-like: containing the vectors (num_vectors,
28
        length_vector).
28 29
    @return: vector average computed doing the element-wise mean.
29 30
    """
30 31
    from utilities import try_command
31 32
    err = "vect_avg parameter vects must be a list-like, able to be converted" \
32 33
          " np.array"
33
    vects = try_command(np.array, [(ValueError, err)], vects)
34
    if len(vects.shape) == 1:
35
        return vects
34
    array = try_command(np.array, [(ValueError, err)], vects)
35
    if len(array.shape) == 1:
36
        return array
36 37
    else:
37
        num_vects = vects.shape[1]
38
        return np.array([np.average(vects[:, i]) for i in range(num_vects)])
38
        num_vects = array.shape[1]
39
        return np.array([np.average(array[:, i]) for i in range(num_vects)])
39 40

  
40 41

  
41 42
def get_atom_coords(atoms: ase.Atoms, ctrs_list):
......
65 66
    return np.array(coords)
66 67

  
67 68

  
68
def add_adsorbate(slab, adsorbate, surf_pos, mol_pos, height, offset=None,
69
def add_adsorbate(slab, adsorbate, site_coord, ctr_coord, height, offset=None,
69 70
                  norm_vect=(0, 0, 1)):
70 71
    """Add an adsorbate to a surface.
71 72

  
......
76 77
    @param slab: ase.Atoms object containing the coordinates of the surface
77 78
    @param adsorbate: ase.Atoms object containing the coordinates of the
78 79
        adsorbate.
79
    @param surf_pos: The coordinates of the adsorption site on the surface.
80
    @param mol_pos: The coordinates of the adsorption center in the molecule.
81
    @param height: The height above the surface
80
    @param site_coord: The coordinates of the adsorption site on the surface.
81
    @param ctr_coord: The coordinates of the adsorption center in the molecule.
82
    @param height: The height above the surface where to adsorb.
82 83
    @param offset: Offsets the adsorbate by a number of unit cells. Mostly
83 84
        useful when adding more than one adsorbate.
84 85
    @param norm_vect: The vector perpendicular to the surface.
85 86
    """
86 87
    info = slab.info.get('adsorbate_info', {})
87
    pos = np.array([0.0, 0.0, 0.0])  # (x, y, z) part
88
    pos = np.array([0.0, 0.0, 0.0])  # part of absolute coordinates
88 89
    spos = np.array([0.0, 0.0, 0.0])  # part relative to unit cell
89
    norm_vect = np.array(norm_vect) / np.linalg.norm(norm_vect)
90
    norm_vect_u = np.array(norm_vect) / np.linalg.norm(norm_vect)
90 91
    if offset is not None:
91 92
        spos += np.asarray(offset, float)
92
    if isinstance(surf_pos, str):
93
    if isinstance(site_coord, str):
93 94
        # A site-name:
94 95
        if 'sites' not in info:
95 96
            raise TypeError('If the atoms are not made by an ase.build '
96 97
                            'function, position cannot be a name.')
97
        if surf_pos not in info['sites']:
98
            raise TypeError('Adsorption site %s not supported.' % surf_pos)
99
        spos += info['sites'][surf_pos]
98
        if site_coord not in info['sites']:
99
            raise TypeError('Adsorption site %s not supported.' % site_coord)
100
        spos += info['sites'][site_coord]
100 101
    else:
101
        pos += surf_pos
102
        pos += site_coord
102 103
    if 'cell' in info:
103 104
        cell = info['cell']
104 105
    else:
......
112 113
    else:
113 114
        # Assume it is a string representing a single Atom
114 115
        ads = ase.Atoms([ase.Atom(adsorbate)])
115
    pos += height * norm_vect
116
    pos += height * norm_vect_u
116 117
    # Move adsorbate into position
117
    ads.translate(pos - mol_pos)
118
    ads.translate(pos - ctr_coord)
118 119
    # Attach the adsorbate
119 120
    slab.extend(ads)
120 121

  
......
132 133

  
133 134

  
134 135
def adsorb_confs(conf_list, surf, ads_ctrs, sites, algo, num_pts, neigh_ctrs,
135
                 norm_vect):
136
                 norm_vect, coll_bttm):
136 137
    """Generates a number of adsorbate-surface structure coordinates.
137 138

  
138 139
    Given a list of conformers, a surface, a list of atom indices (or list of
......
148 149
    @param neigh_ctrs: the indices of the neighboring atoms to the adsorption
149 150
    atoms.
150 151
    @param norm_vect: The vector perpendicular to the surface.
152
    @param coll_bttm: The lowermost height for which to detect a collision
151 153
    @return: list of ase.Atoms for the adsorbate-surface structures
152 154
    """
153 155
    surf_ads_list = []
......
158 160
        for site in sites_coords:
159 161
            for i, molec_ctr in enumerate(molec_ctr_coords):
160 162
                if algo == 'euler':
161
                    surf_ads_list.append(ads_euler(conf, surf, site, molec_ctr,
163
                    surf_ads_list.extend(ads_euler(conf, surf, molec_ctr, site,
162 164
                                                   num_pts, norm_vect,
165
                                                   coll_bttm,
163 166
                                                   molec_neigh_coords[i]))
164 167
                elif algo == 'chemcat':
165
                    surf_ads_list.append(ads_chemcat(site, molec_ctr, num_pts))
168
                    surf_ads_list.extend(ads_chemcat(site, molec_ctr, num_pts))
166 169
    return surf_ads_list
167 170

  
168 171

  
......
185 188
        raise ValueError(err)
186 189

  
187 190
    conf_list = read_coords(inp_vars['code'], 'isolated', 'rdkit')
188
    # TODO Implement neighbors algorithm
191
    # TODO Implement neighbors algorithm / align molecule to surface
189 192
    # neigh_list = get_neighbors(conf_list[0], inp_vars['molec_ads_ctrs'])
190 193
    conf_enrgs = read_energies(inp_vars['code'], 'isolated')
191 194
    mois = np.array([get_moments_of_inertia(conf)[0] for conf in conf_list])
192 195
    rmsd_mtx = get_rmsd(conf_list)
193
    exemplars = clustering(rmsd_mtx)
194
    conf_list = [conf_list[idx] for idx in exemplars]
195
    conf_list = [rdkit_mol_to_ase_atoms(conf) for conf in conf_list]
196
    exemplars = clustering(rmsd_mtx)  # TODO Kind of Clustering
197
    clust_conf_list = [conf_list[idx] for idx in exemplars]
198
    conf_list = [rdkit_mol_to_ase_atoms(conf) for conf in clust_conf_list]
196 199
    surf = adapt_format('ase', inp_vars['surf_file'])
197 200
    surf_ads_list = adsorb_confs(conf_list, surf, inp_vars['molec_ads_ctrs'],
198 201
                                 inp_vars['sites'], inp_vars['ads_algo'],
199 202
                                 inp_vars['sample_points_per_angle'],
200 203
                                 inp_vars['molec_neigh_ctrs'],
201
                                 inp_vars['surf_norm_vect'])
204
                                 inp_vars['surf_norm_vect'],
205
                                 inp_vars['collision_bottom'])
202 206
    run_calc('screening', inp_vars, surf_ads_list)

Formats disponibles : Unified diff