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