Hi guys,
Togo, thanks for the example.
In the following I will print the lattice as row-vectors in fractional coordinates (divide by lattice parameter A) and I have linked Togo’s example with Avogadro’s libspglib.a. Atomic positions are also in fractional coordinates.
In Togo’s example (without modification) the final row-vector lattice and atomic positions are
–Primitive lattice (row vectors)–
0.500000 -0.500000 0.000000
-0.500000 -0.000000 -0.500000
0.500000 0.500000 0.000000
–Basis atoms–
0: 0.000000 0.000000 0.000000
1: -0.250000 0.500000 0.250000
The same can be done in Avogadro by loading Si-Silicon.cif and filling the unit cell from the crystallography menu. I have added an extra qDebug statement to print the lattice as row vectors just after spg_find_primitive. In this case the output is identical.
The problem I have is that when using the above crystal structure as input in PWScf, PWScf only finds 8 symmetry operations when there should be 48. Note that PWScf does not have any space group functionality, the user must know the primitive cell (or Bravais lattice) and the atom basis. While there several possible inputs, one correct PWScf crystal structure input for diamond is
–Primitive lattice (row vectors)–
-0.500000 0.000000 0.500000
0.000000 0.500000 0.500000
-0.500000 0.500000 0.000000
–Basis atoms–
Si 0.00 0.00 0.00
Si 0.25 0.25 0.25
By removing the call to spg_refine_cell in Avogadro’s reduceToPrimitive I can generate a correct PWScf input for diamond,
–Primitive lattice (row vectors)–
0.50 0.50 0.00
-0.50 0.00 -0.50
0.00 0.50 0.50
–Basis atoms–
14 0.00 0.00 0.00
14 0.25 -0.25 0.25
I have so far verified that correct PWScf inputs can be obtained for the diamond structure above, a zincblend AlSb, gold fcc and iron bcc by reducing the full unit cell using Avogadro’s reduceToPrimitive method without the spg_refine_cell step. I made a getPrimitive method, which does not update the display, for use in my PWScf input generator.
The confusing part is that disabling the call to spg_refine_cell in Togo’s example returns a crystal structure with only 8 symmetry operations according to PWScf,
–Primtive lattice (row vectors)–
-0.500000 0.000000 0.500000
0.500000 0.500000 -0.000000
-0.500000 0.000000 -0.500000
–Basis atoms –
0: 0.000000 0.000000 0.000000
1: 0.250000 0.500000 -0.250000
Have I done something strange?
Togo, I linked your example with the latest trunk of spglib and for your unmodified example and I got slightly different results, but PWScf still only found 8 symmetry operations.
My PWScf input generator branch in on my GitHub. I have moved avospglib into the main libavogadro and added the getPrimitive method. This is the one used by the Quantum Espresso input generator to make the primitive lattice and basis. This method currently skips the spg_refine_cell step.
https://github.com/AlbertDeFusco/avogadro/commits/espresso
Thanks for your help,
Albert
On Mar 29, 2012, at 2:12 AM, Atz Togo wrote:
Hi David, Albert,
The current reduceToPrimitive function is here:
http://github.com/dlonie/avogadro/blob/master/libavogadro/src/extensions/crystallography/avospglib.cpp#L226
What it does is:
(1) Determine the spacegroup of the cell with spg_get_international
(2) Clean up the structure with spg_refine_cell
(3) Reduce the cell to it’s primitive representation with spg_find_primitive
(4) Update the molecule with the new cell matrix and coordinates
The coordinates, lattice matrix, etc are kept in the same arrays
throughout the process, so if refine_cell is changing the orientation,
it should not matter since the reoriented matrix and refined
coordinates are passed to the find_primitive function. I cannot see
how calling the refine_cell function before the reduction would break
the behavior, but I may be missing something.
I had a look at reduceToPrimitive and I also couldn’t find something wrong.
So now I doubt spglib. There may be bug in spg_refine_cell in the
previous versions. I wrote the followng test code in C and confirmed
that the latest spglib works correctly. I’ve not tested but if this C
code also works for the spglib in the Avogadro, the problem might be
somewhere out of reduceToPrimitive.
#include “spglib.h”
#include <stdio.h>
int main()
{
double lattice[3][3] = { {3, 0, 0}, {0, 3, 0}, {0, 0, 3} };
double positions[32][3];
double pos_orig[3] = {
{0, 0, 0},
{0.0, 0.5, 0.5},
{0.5, 0.5, 0.0},
{0.5, 0.0, 0.5},
{0.75, 0.25, 0.75},
{0.25, 0.25, 0.25},
{0.25, 0.75, 0.75},
{0.75, 0.75, 0.25}
};
int types[32];
int i, num_atom = 8, num_atom_prim, num_atom_bravais;
double symprec = 1e-5;
for (i = 0; i < num_atom; i++) {
positions[i][0] = pos_orig[i][0];
positions[i][1] = pos_orig[i][1];
positions[i][2] = pos_orig[i][2];
types[i] = 1;
}
num_atom_bravais = spg_refine_cell(lattice,
positions,
types,
num_atom,
symprec);
for (i = 0; i < 3; i++) {
printf(“%f %f %f\n”, lattice[i][0], lattice[i][1], lattice[i][2]);
}
for (i = 0; i < num_atom_bravais; i++) {
printf(“%d: %f %f %f\n”, i, positions[i][0], positions[i][1],
positions[i][2]);
}
num_atom_prim = spg_find_primitive(lattice, positions, types,
num_atom_bravais, symprec);
for (i = 0; i < 3; i++) {
printf(“%f %f %f\n”, lattice[i][0], lattice[i][1], lattice[i][2]);
}
for (i = 0; i < num_atom_prim; i++) {
printf(“%d: %f %f %f\n”, i, positions[i][0], positions[i][1],
positions[i][2]);
}
}
Togo
As a side note, I’ve recently started using your phonopy software
after giving up a fight with PHON (it wouldn’t recognize the symmetry,
and doesn’t seem to have an adjustable tolerance…). Phonopy is a
wonderful tool, and I’m especially impressed by the matplotlib
integration. I’ve been recommending it to my coworkers – keep up the
good work!
Dave
–
Atsushi Togo
http://atztogo.users.sourceforge.net/
atz.togo@gmail.com