Révision 5fb01677

b/modules/dos_input.py
47 47
import logging
48 48
from configparser import ConfigParser, NoSectionError, NoOptionError, \
49 49
    MissingSectionHeaderError, DuplicateOptionError
50
import numpy as np
50 51
from modules.utilities import try_command
51 52

  
52 53
logger = logging.getLogger('DockOnSurf')
......
457 458

  
458 459

  
459 460
def get_surf_norm_vect():
460
    import numpy as np
461 461
    err = "'surf_norm_vect' must be either a 3 component vector or 'x', 'y' " \
462 462
          "or 'z'"
463
    coords = {'x': [1.0, 0.0, 0.0],
464
              'y': [0.0, 1.0, 0.0],
465
              'z': [0.0, 0.0, 1.0]}
463
    cart_coords = {'x': [1.0, 0.0, 0.0], '-x': [-1.0, 0.0, 0.0],
464
                   'y': [0.0, 1.0, 0.0], '-y': [0.0, -1.0, 0.0],
465
                   'z': [0.0, 0.0, 1.0], '-z': [0.0, 0.0, -1.0]}
466 466
    surf_norm_vect_str = dos_inp.get('Screening', 'surf_norm_vect',
467
                                     fallback="0.0 0.0 1.0")
467
                                     fallback="z")
468 468

  
469
    if len(surf_norm_vect_str) == 1 and surf_norm_vect_str in coords:
470
        surf_norm_vect = coords[surf_norm_vect_str]
469
    if surf_norm_vect_str in cart_coords:
470
        surf_norm_vect = cart_coords[surf_norm_vect_str]
471 471
    else:
472 472
        surf_norm_vect = try_command(str2lst, [(ValueError, err)],
473
                                     surf_norm_vect_str)
473
                                     surf_norm_vect_str, float)
474 474
        if len(surf_norm_vect) != 3:
475 475
            logger.error(err)
476 476
            raise ValueError(err)
......
523 523
    return screen_rmsd
524 524

  
525 525

  
526
def get_coll_bottom():
527
    err_msg = num_error % ('collision_bottom', 'decimal number')
528
    coll_bottom = dos_inp.get('Screening', 'collision_bottom',
529
                              fallback="False")
530
    if coll_bottom.lower() in turn_false_answers:
531
        coll_bottom = False
526
def get_min_coll_height():
527
    err_msg = num_error % ('min_coll_height', 'decimal number')
528
    min_coll_height = dos_inp.get('Screening', 'min_coll_height',
529
                                  fallback="False")
530
    if min_coll_height.lower() in turn_false_answers:
531
        min_coll_height = False
532 532
    else:
533
        coll_bottom = try_command(float, [(ValueError, err_msg)], coll_bottom)
533
        min_coll_height = try_command(float, [(ValueError, err_msg)],
534
                                      min_coll_height)
534 535

  
535
    return coll_bottom
536
    return min_coll_height
536 537

  
537 538

  
538 539
def get_try_disso():
......
678 679
        return_vars['ads_algo'] = get_ads_algo()
679 680
        return_vars['sample_points_per_angle'] = get_pts_per_angle()
680 681
        return_vars['collision_threshold'] = get_coll_thrsld()
681
        return_vars['collision_bottom'] = get_coll_bottom()
682
        return_vars['min_coll_height'] = get_min_coll_height()
683
        cart_coords = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
684
        if return_vars['min_coll_height'] is not False and \
685
                list(map(abs, return_vars['surf_norm_vect'].tolist())) not in \
686
                cart_coords:
687
            logger.warning("'min_coll_height' option is only implemented for "
688
                           "'surf_norm_vect' to be one of the x, y or z axes")
682 689

  
683 690
    # Refinement
684 691
    if refinement:
b/modules/screening.py
148 148
    @return: bool, whether the surface and the molecule collide.
149 149
    """
150 150
    from ase.neighborlist import natural_cutoffs, neighbor_list
151
    if (vect == np.array([1.0, 0.0, 0.0])).all \
152
            or (vect == np.array([0.0, 1.0, 0.0])).all \
153
            or (vect == np.array([0.0, 0.0, 1.0])).all:
154
        for atom in slab_molec[slab_num_atoms:]:
155
            if np.linalg.norm(atom.position * vect) < min_height:
156
                return True
157
    slab_molec_cutoffs = natural_cutoffs(slab_molec, mult=coll_coeff)
158
    slab_molec_nghbs = len(neighbor_list("i", slab_molec, slab_molec_cutoffs))
159
    if slab_molec_nghbs > nn_slab + nn_molec:
160
        return True
151
    if min_height is not False:
152
        cart_coords = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
153
        if list(map(abs, vect.tolist())) in cart_coords:
154
            for atom in slab_molec[slab_num_atoms:]:
155
                if np.linalg.norm(atom.position * vect) < min_height:
156
                    #  TODO Check norm when there are negative values
157
                    return True
161 158
    else:
162
        return False
159
        slab_molec_cutoffs = natural_cutoffs(slab_molec, mult=coll_coeff)
160
        slab_molec_nghbs = len(neighbor_list("i", slab_molec, slab_molec_cutoffs))
161
        if slab_molec_nghbs > nn_slab + nn_molec:
162
            return True
163
        else:
164
            return False
163 165

  
164 166

  
165 167
def correct_coll(molec, slab, ctr_coord, site_coord, num_pts,
166
                 coll_bttm, norm_vect, slab_nghbs, molec_nghbs, coll_coeff):
168
                 min_coll_height, norm_vect, slab_nghbs, molec_nghbs,
169
                 coll_coeff):
167 170
    # TODO Rethink this function
168 171
    """Tries to adsorb a molecule on a slab trying to avoid collisions by doing
169 172
    small rotations.
......
176 179
    @param site_coord: The coordinates of the surface on which to adsorb the
177 180
        molecule
178 181
    @param num_pts: Number on which to sample Euler angles.
179
    @param coll_bttm: The lowermost height for which to detect a collision
182
    @param min_coll_height: The lowermost height for which to detect a collision
180 183
    @param norm_vect: The vector perpendicular to the surface.
181 184
    @param slab_nghbs: Number of neigbors in the surface.
182 185
    @param molec_nghbs: Number of neighbors in the molecule.
......
199 202
                           center=ctr_coord)
200 203
        add_adsorbate(slab_molec, molec, site_coord, ctr_coord, 2.5,
201 204
                      norm_vect=norm_vect)
202
        collision = check_collision(slab_molec, slab_num_atoms, coll_bttm,
205
        collision = check_collision(slab_molec, slab_num_atoms, min_coll_height,
203 206
                                    norm_vect, slab_nghbs, molec_nghbs,
204 207
                                    coll_coeff)
205 208
        num_corr += 1
......
207 210

  
208 211

  
209 212
def ads_euler(orig_molec, slab, ctr_coord, site_coord, num_pts,
210
              coll_bttm, coll_coeff, norm_vect, slab_nghbs, molec_nghbs):
213
              min_coll_height, coll_coeff, norm_vect, slab_nghbs, molec_nghbs):
211 214
    """Generates adsorbate-surface structures by sampling over Euler angles.
212 215

  
213 216
    This function generates a number of adsorbate-surface structures at
......
220 223
    @param site_coord: The coordinates of the surface on which to adsorb the
221 224
        molecule
222 225
    @param num_pts: Number on which to sample Euler angles.
223
    @param coll_bttm: The lowermost height for which to detect a collision
226
    @param min_coll_height: The lowermost height for which to detect a collision
224 227
    @param coll_coeff: The coefficient that multiplies the covalent radius of
225 228
        atoms resulting in a distance that two atoms being closer to that is
226 229
        considered as atomic collision.
......
241 244
                molec = deepcopy(orig_molec)
242 245
                molec.euler_rotate(alpha, beta, gamma, center=ctr_coord)
243 246
                slab_molec, collision = correct_coll(molec, slab,
244
                    ctr_coord, site_coord, num_pts, coll_bttm, norm_vect,
245
                    slab_nghbs, molec_nghbs, coll_coeff)
247
                                                     ctr_coord, site_coord,
248
                                                     num_pts, min_coll_height,
249
                                                     norm_vect,
250
                                                     slab_nghbs, molec_nghbs,
251
                                                     coll_coeff)
246 252
                if not collision:
247 253
                    slab_ads_list.append(slab_molec)
248 254

  
......
254 260

  
255 261

  
256 262
def adsorb_confs(conf_list, surf, molec_ctrs, sites, algo, num_pts, neigh_ctrs,
257
                 norm_vect, coll_bttm, coll_coeff):
263
                 norm_vect, min_coll_height, coll_coeff):
258 264
    """Generates a number of adsorbate-surface structure coordinates.
259 265

  
260 266
    Given a list of conformers, a surface, a list of atom indices (or list of
......
270 276
    @param neigh_ctrs: the indices of the neighboring atoms to the adsorption
271 277
        atoms.
272 278
    @param norm_vect: The vector perpendicular to the surface.
273
    @param coll_bttm: The lowermost height for which to detect a collision
279
    @param min_coll_height: The lowermost height for which to detect a collision
274 280
    @param coll_coeff: The coefficient that multiplies the covalent radius of
275 281
        atoms resulting in a distance that two atoms being closer to that is
276 282
        considered as atomic collision.
......
279 285
    from ase.neighborlist import natural_cutoffs, neighbor_list
280 286
    surf_ads_list = []
281 287
    sites_coords = get_atom_coords(surf, sites)
282
    surf_cutoffs = natural_cutoffs(surf, mult=coll_coeff)
283
    surf_nghbs = len(neighbor_list("i", surf, surf_cutoffs))
288
    if min_coll_height is not False:
289
        surf_cutoffs = natural_cutoffs(surf, mult=coll_coeff)
290
        surf_nghbs = len(neighbor_list("i", surf, surf_cutoffs))
291
    else:
292
        surf_nghbs = 0
284 293
    for conf in conf_list:
285 294
        molec_ctr_coords = get_atom_coords(conf, molec_ctrs)
286 295
        molec_neigh_coords = get_atom_coords(conf, neigh_ctrs)
287
        conf_cutoffs = natural_cutoffs(conf, mult=coll_coeff)
288
        molec_nghbs = len(neighbor_list("i", conf, conf_cutoffs))
296
        if min_coll_height is not False:
297
            conf_cutoffs = natural_cutoffs(conf, mult=coll_coeff)
298
            molec_nghbs = len(neighbor_list("i", conf, conf_cutoffs))
299
        else:
300
            molec_nghbs = 0
289 301
        for site in sites_coords:
290 302
            for ctr in molec_ctr_coords:
291 303
                if algo == 'euler':
292 304
                    surf_ads_list.extend(ads_euler(conf, surf, ctr, site,
293
                                                   num_pts, coll_bttm,
305
                                                   num_pts, min_coll_height,
294 306
                                                   coll_coeff, norm_vect,
295 307
                                                   surf_nghbs, molec_nghbs))
296 308
                elif algo == 'chemcat':
......
332 344
                                 inp_vars['sample_points_per_angle'],
333 345
                                 inp_vars['molec_neigh_ctrs'],
334 346
                                 inp_vars['surf_norm_vect'],
335
                                 inp_vars['collision_bottom'],
347
                                 inp_vars['min_coll_height'],
336 348
                                 inp_vars['collision_threshold'])
337 349
    run_calc('screening', inp_vars, surf_ads_list)
b/tests/test_dos_input.py
58 58
                    'try_disso': True,
59 59
                    'sample_points_per_angle': 4,
60 60
                    'collision_threshold': 0.9,
61
                    'collision_bottom': 5.2,
61
                    'min_coll_height': 5.2,
62 62
                    'refine_inp_file': 'refine.inp',
63 63
                    'energy_cutoff': 1.0
64 64
                    }
......
132 132
        self.assertEqual(get_coll_thrsld(), 0.9)
133 133

  
134 134
    def test_coll_bottom(self):
135
        self.assertEqual(get_coll_bottom(), 5.2)
135
        self.assertEqual(get_min_coll_height(), 5.2)
136 136

  
137 137
    def test_refine_inp_file(self):
138 138
        self.assertEqual(get_refine_inp_file(), 'refine.inp')
......
205 205
        self.assertRaises(ValueError, get_coll_thrsld)
206 206

  
207 207
    def test_coll_bottom(self):
208
        self.assertRaises(ValueError, get_coll_bottom)
208
        self.assertRaises(ValueError, get_min_coll_height)
209 209

  
210 210
    def test_refine_inp_file(self):
211 211
        self.assertRaises(FileNotFoundError, get_refine_inp_file)

Formats disponibles : Unified diff