4
$\begingroup$

I'm looking to build a surface slab in Atomic Simulation Environment (ASE) for CeO2 (fluorite structure). Using ase.build.surface( ) allowed modelling the surface. I would now like to run a relaxation on the slab w/ the bottom layer frozen, but all atom tags are '0' (according to get_tags() method): does ase.build.surface() not assign layer tags? or have a made a formatting error causing the slab to be tagged as an adsorbate? Thanks!

import ase
from ase import Atoms,Atom
from ase.build import surface

a = 5.467
bulk_ceo2 = Atoms([
             Atom('Ce', (0.000000,  0.000000,  0.000000)),
             Atom('Ce', (0.000000,  0.500000,  0.500000)),
             Atom('Ce', (0.500000,  0.000000,  0.500000)),
             Atom('Ce', (0.500000,  0.500000,  0.000000)),
             Atom('O',  (0.750000,  0.250000,  0.250000)),
             Atom('O',  (0.250000,  0.750000,  0.750000)),
             Atom('O',  (0.750000,  0.750000,  0.750000)),
             Atom('O',  (0.250000,  0.250000,  0.250000)),
             Atom('O',  (0.250000,  0.250000,  0.750000)),
             Atom('O',  (0.750000,  0.750000,  0.250000)),
             Atom('O',  (0.250000,  0.750000,  0.250000)),
             Atom('O',  (0.750000,  0.250000,  0.750000))
                                                          ])

cell = [(a, 0.0, 0.0),
        (0.0, a, 0.0),
        (0.0, 0.0, a)]

bulk_ceo2.set_cell(cell, scale_atoms=True)

#(1,1,1) slab; 4 unit cells along Z direction
slab = surface(bulk_ceo2, (1,1,1), 4)

#Repeat slab 2 unit cells in X and 1 in Y directions
slab = slab.repeat((2,1,1))
slab.center(vacuum=8, axis=2)

slab_tags = slab.get_tags()

print(slab_tags)
$\endgroup$
3
$\begingroup$

ASE is not aware of which layer things are on when you use the surface function to build an arbitrary surface. However, the indices should be in order of z height I believe.

You can use the following to assign the tags, just be aware that this will not work for more complex surfaces very well (which is why it is not done by default I believe).

slab = surface(bulk_ceo2, (1,1,1), 4)
slab.set_tags(range(len(slab)))
slab *= (2,2,1)
slab.center(vacuum=8, axis=2)

slab_tags = slab.get_tags()
print(slab_tags)
$\endgroup$
3
  • 1
    $\begingroup$ The code should work, however please check it as I am going between buildings right now. I can look later if it does not. $\endgroup$ Aug 6 at 19:31
  • $\begingroup$ Thanks very much @Tristan Maxson! the code works and assigns a unique tag/index to each atom. In comparing using get_positions(), the tags do not seem to be based on z-height though. I plan to sort by z and re-tag the bottom-most atoms (layer) for relaxation calculations. Is there a best/most efficient way to tag layers for more complex surfaces in ASE? If the structure is not representable using one of the helper functions (e.g. fcc(111))? $\endgroup$
    – Craig Neal
    Aug 10 at 19:36
  • $\begingroup$ I fear the current answer is no, you may have some luck joining the ASE element chat and talking to some developers about your exact use case and what you would want. But this tends to be a very complex problem. $\endgroup$ Aug 10 at 20:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.