Révision 1d22a086

b/modules/screening.py
49 49
    return np.array(coords)
50 50

  
51 51

  
52
def ads_euler(site, ctr, pts_angle, neigh_ctr):
53
    pass
52
def add_adsorbate(slab, adsorbate, surf_pos, mol_pos, height, offset=None,
53
                  norm_vect=(0, 0, 1)):
54
    """Add an adsorbate to a surface.
55

  
56
    This function extends the functionality of ase.build.add_adsorbate
57
    (https://wiki.fysik.dtu.dk/ase/ase/build/surface.html#ase.build.add_adsorbate)
58
    by enabling to change the z coordinate and the axis perpendicular to the
59
    surface.
60
    @param slab: ase.Atoms object containing the coordinates of the surface
61
    @param adsorbate: ase.Atoms object containing the coordinates of the
62
        adsorbate.
63
    @param surf_pos: The coordinates of the adsorption site on the surface.
64
    @param mol_pos: The coordinates of the adsorption center in the molecule.
65
    @param height: The height above the surface
66
    @param offset: Offsets the adsorbate by a number of unit cells. Mostly
67
        useful when adding more than one adsorbate.
68
    @param norm_vect: The vector perpendicular to the surface.
69
    """
70
    info = slab.info.get('adsorbate_info', {})
71
    pos = np.array([0.0, 0.0, 0.0])  # (x, y, z) part
72
    spos = np.array([0.0, 0.0, 0.0])  # part relative to unit cell
73
    norm_vect = np.array(norm_vect) / np.linalg.norm(norm_vect)
74
    if offset is not None:
75
        spos += np.asarray(offset, float)
76
    if isinstance(surf_pos, str):
77
        # A site-name:
78
        if 'sites' not in info:
79
            raise TypeError('If the atoms are not made by an ase.build '
80
                            'function, position cannot be a name.')
81
        if surf_pos not in info['sites']:
82
            raise TypeError('Adsorption site %s not supported.' % surf_pos)
83
        spos += info['sites'][surf_pos]
84
    else:
85
        pos += surf_pos
86
    if 'cell' in info:
87
        cell = info['cell']
88
    else:
89
        cell = slab.get_cell()
90
    pos += np.dot(spos, cell)
91
    # Convert the adsorbate to an Atoms object
92
    if isinstance(adsorbate, ase.Atoms):
93
        ads = adsorbate
94
    elif isinstance(adsorbate, ase.Atom):
95
        ads = ase.Atoms([adsorbate])
96
    else:
97
        # Assume it is a string representing a single Atom
98
        ads = ase.Atoms([ase.Atom(adsorbate)])
99
    pos += height * norm_vect
100
    # Move adsorbate into position
101
    ads.translate(pos - mol_pos)
102
    # Attach the adsorbate
103
    slab.extend(ads)
104

  
105

  
106
def ads_euler(molec, surf, site, ctr, pts_angle, neigh_ctr, norm_vect):
107
    from random import random
108
    plane_vect = np.cross(norm_vect, [random() for i in range(3)])
109
    add_adsorbate()
110

  
111
    return
54 112

  
55 113

  
56 114
def ads_chemcat(site, ctr, pts_angle):
57 115
    return "TO IMPLEMENT"
58 116

  
59 117

  
60
def adsorb_confs(conf_list, surf, ads_ctrs, sites, algo, num_pts, neigh_ctrs):
118
def adsorb_confs(conf_list, surf, ads_ctrs, sites, algo, num_pts, neigh_ctrs,
119
                 norm_vect):
61 120
    """Generates a number of adsorbate-surface structure coordinates.
62 121

  
63 122
    Given a list of conformers, a surface, a list of atom indices (or list of
......
72 131
    @param num_pts: the number of points per angle orientation to sample
73 132
    @param neigh_ctrs: the indices of the neighboring atoms to the adsorption
74 133
    atoms.
134
    @param norm_vect: The vector perpendicular to the surface.
75 135
    @return: list of ase.Atoms for the adsorbate-surface structures
76 136
    """
77 137
    surf_ads_list = []
......
82 142
        for site in sites_coords:
83 143
            for i, molec_ctr in enumerate(molec_ctr_coords):
84 144
                if algo == 'euler':
85
                    surf_ads_list.append(ads_euler(site, molec_ctr, num_pts,
145
                    surf_ads_list.append(ads_euler(conf, surf, site, molec_ctr,
146
                                                   num_pts, norm_vect,
86 147
                                                   molec_neigh_coords[i]))
87 148
                elif algo == 'chemcat':
88 149
                    surf_ads_list.append(ads_chemcat(site, molec_ctr, num_pts))
......
120 181
    surf_ads_list = adsorb_confs(conf_list, surf, inp_vars['molec_ads_ctrs'],
121 182
                                 inp_vars['sites'], inp_vars['ads_algo'],
122 183
                                 inp_vars['sample_points_per_angle'],
123
                                 inp_vars['molec_neigh_ctrs'])
184
                                 inp_vars['molec_neigh_ctrs'],
185
                                 inp_vars['surf_norm_vect'])
124 186
    run_calc('screening', inp_vars, surf_ads_list)

Formats disponibles : Unified diff