Forum Navigation
You need to log in to create posts and topics.

Question about WignerSeitzAnalysisModifier to count antisites


I am going to count antisites in a crystal containing two types of atoms A and B. I really confused about the example presented in the document. I can not understand the following lines:


    occupancies = data.particles['Occupancy']
    # Get the site types as additional input:
    site_type = data.particles['Particle Type']

    # Calculate total occupancy of every site:
    total_occupancy = np.sum(occupancies, axis=1)

    # Set up a particle selection by creating the Selection property:
    selection = data.particles_.create_property('Selection')
    # Select A-sites occupied by exactly one B-atom (the second entry of the Occupancy
    # array must be 1, and all others 0). Note that the Occupancy array uses 0-based
    # indexing, while atom type IDs are typically 1-based.
    with selection:
        selection[...] = (site_type == 1) & (occupancies[:,1] == 1) & (total_occupancy == 1)
    # Additionally output the total number of antisites as a global attribute:
    data.attributes['Antisite_count'] = np.count_nonzero(selection)
1) if i want to count B-sites occupied by exactly one A-atom, What needs to change from above lines?
2)why we count the sites occupied by exactly one atom not more? if i want to count more, is it true 
that "total_occupancy>=1"?
3)this is a python script solution. Indeed, i can not give the result without it and by using 
only "Expression select". If i want to use only "Expression select", what needs to be typed? (i know 
that the "per-type" must be clicked, but i do not know what must be written in "Expression select" 
for Occupance.1 and Occupance.2)


to shortly answer your questions:

  1. In that case you need to create a particle property "Selection" for particles that are of "particle type" 2, have a "total occupancy" of 1 and a "per-type-occupancy" (1, 0). Thus:
    selection[...] = (site_type == 2) & (occupancies[:,0] == 1) & (total_occupancy == 1)
  2. The code you're referring to is just an example of how to count antisites. If you want to look at other types of defects, of course their total occupancy will not be 1, see manual
  3. Analogous to the scripting version, if you activate the option "Compute per-type occupancies" in the Wigner Seitz defect analysis modifier in the GUI, you will create a particle property "Occupancy" which is a vector of length N, where N = number of particle types. Thus, if you want to count A-sites (Particle Type == 1), that are occupied by only 1 atom of type B ( per-type occupancy Occupancy.2 == 1 and total occupancy, i.e. (Occupancy.1 + Occupancy.2 == 1)), then you could use the following expression in the Expression selection modifier:
    (Particle Type == 1) && (Occupancy.2 == 1) && (Occupancy.1 + Occupancy.2 == 1)
    The expression syntax is also explained in the manual:


Hi Dear Constanze

Thanks for very helpful answering. About the 3rd answer, why we do not use simply something like this (for A-antisides):

(Particle Type == 1) && (Occupancy.2 == 1) && (Occupancy.1 == 0)

and why we do not use Occupancy.2 >= 1? maybe there are some A-sites that are occupied by more than one B-atom? Are they not considered antiside?


(Particle Type == 1) && (Occupancy.2 == 1) && (Occupancy.1 == 0)

sure, since you only have two particle types this will lead to the same result.

Are they not considered antisite?

No, see e.g. or any materials science textbook.