Avogadro and SPGLIB

Hi there,

I am working on writing an input generator for PWScf. The input requires that user knows the atomic lattice basis and the Bravais lattice or the exact primitive lattice vectors. I have been playing with SPGLIB in Avogadro to be able to convert unit cell atoms and lattice vectors into the primitive lattice and the atomic basis and I am having trouble getting it to work correctly. Is SPGLIB a good library for this or should I look elsewhere?

I have found that when I run a simple C program linked to Avogardo’s libspglib.a, where I use the same atom positions and cell matrix, different results are obtained from those I can print during Avogadro’s call to the spglib routines. Further, the Cell Matrix reported back to the gui is very different.

For example, the silicon diamond crystal unit cell is a cubic lattice with 8 atoms and has Fd-3m (227) space group symmetry. The 8 atoms in fractional coordinates are listed below.

Si 0.00000 0.00000 0.00000
Si 0.00000 0.50000 0.50000
Si 0.50000 0.50000 0.00000
Si 0.50000 0.00000 0.50000
Si 0.75000 0.25000 0.75000
Si 0.25000 0.25000 0.25000
Si 0.25000 0.75000 0.75000
Si 0.75000 0.75000 0.25000

In order to make a usable PWScf input I have to generate the primitive lattice and the atomic basis. A correct PWScf input is show below where PWScf identifies 48 symmetry operations.

ATOMIC_POSITIONS
Si 0.00 0.00 0.00
Si 0.25 0.25 0.25
CELL_PARAMETERS cubic
-0.500000 0.000000 0.500000
0.000000 0.500000 0.500000
-0.500000 0.500000 0.000000

Here “CELL_PARAMETERS” refers to the primitive lattice vectors in fractional coordinates.

Since primitive lattice vectors are not unique, there are other possible solutions. All attempts I have made to generate primitive lattice vectors and the atomic basis with SPGLIB do not work in PWScf. At best I have been able make input files that have 8 of the expected 48 symmetry operations.

Thanks,
Albert

Hi Albert,

On Wed, Mar 14, 2012 at 1:40 PM, Albert DeFusco defusco@pitt.edu wrote:

I am working on writing an input generator for PWScf. The input requires that user knows the atomic lattice basis and the Bravais lattice or the exact primitive lattice vectors. I have been playing with SPGLIB in Avogadro to be able to convert unit cell atoms and lattice vectors into the primitive lattice and the atomic basis and I am having trouble getting it to work correctly. Is SPGLIB a good library for this or should I look elsewhere?

SPGlib should work well for this. The other alternative would be to
interface with Stokes’ FINDSYM code in the ISOTROPY package, but it
does not provide a library interface and cannot be included with
Avogadro:

http://stokes.byu.edu/iso/findsym.html

I have found that when I run a simple C program linked to Avogardo’s libspglib.a, where I use the same atom positions and cell matrix, different results are obtained from those I can print during Avogadro’s call to the spglib routines. Further, the Cell Matrix reported back to the gui is very different.

The code that the crystallography extension uses is in avospglib.h/cpp
in the crystallography extension’s subdirectory. I’ve been able to
reproduce your issue – I’ve tracked it to the
OpenBabel::OBUnitCell::SetData call, for instance:

cell->SetData(Avogadro::Eigen2OB(cellMatrix));

OpenBabel::matrix3x3 setCellMat = cell->GetCellMatrix();

in the “applyToMolecule” method ends up with:

cellMatrix = 1.5, -1.5, 0 || -1.5, 0, -1.5 || 1.5 1.5 0
setCellMat = 1.5, -1.5, 0 || -1.5, 0, -1.5 || 1.5 1.5 -2.22044604

when I reduce a Fd-3m 3 angstrom cubic cell as in your example.

This has worked well in the past for a number of different structures,
so I suspect that there is something specific about this structure
that is confusing the OBUnitCell::SetData method. I spent some time
looking at it, but couldn’t track it down. I may have time to work on
this later, but it may be a while.

Feel free to poke around in the OBUnitCell code to track this down and
I’ll answer any questions you have to the best of my ability.

Hope this helps,

Dave

For example, the silicon diamond crystal unit cell is a cubic lattice with 8 atoms and has Fd-3m (227) space group symmetry. The 8 atoms in fractional coordinates are listed below.

Si 0.00000 0.00000 0.00000
Si 0.00000 0.50000 0.50000
Si 0.50000 0.50000 0.00000
Si 0.50000 0.00000 0.50000
Si 0.75000 0.25000 0.75000
Si 0.25000 0.25000 0.25000
Si 0.25000 0.75000 0.75000
Si 0.75000 0.75000 0.25000

In order to make a usable PWScf input I have to generate the primitive lattice and the atomic basis. A correct PWScf input is show below where PWScf identifies 48 symmetry operations.

ATOMIC_POSITIONS
Si 0.00 0.00 0.00
Si 0.25 0.25 0.25
CELL_PARAMETERS cubic
-0.500000 0.000000 0.500000
0.000000 0.500000 0.500000
-0.500000 0.500000 0.000000

Here “CELL_PARAMETERS” refers to the primitive lattice vectors in fractional coordinates.

Since primitive lattice vectors are not unique, there are other possible solutions. All attempts I have made to generate primitive lattice vectors and the atomic basis with SPGLIB do not work in PWScf. At best I have been able make input files that have 8 of the expected 48 symmetry operations.

Thanks,
Albert


This SF email is sponsosred by:
Try Windows Azure free for 90 days Click Here
http://p.sf.net/sfu/sfd2d-msazure


Avogadro-devel mailing list
Avogadro-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/avogadro-devel

David,

After some playing around I was able to determine that SPGlib will generate the primitive lattice and basis atoms correctly for use in PWScf. The avospg method reduceToPrimitive appears to work correctly only when I disable spg_refine_cell. So far I have been unable to figure out what might be wrong between OBUnitCell::SetData and the Avogadro display.

What I would like to do is use the spglib and avospg (crystallography extension) methods to determine the primitive lattice from my PWScf input generator. The goal is have a button that will generate the PWScf input using either the generated primitive cell or take the displayed cell verbatim without changing the display. Is it possible to connect the crystallography extension with a quantum input generator or should I re-implement the necessary methods in the PWScf input generator?

Thanks,
Albert

On Mar 15, 2012, at 12:20 PM, David Lonie wrote:

Hi Albert,

On Wed, Mar 14, 2012 at 1:40 PM, Albert DeFusco defusco@pitt.edu wrote:

I am working on writing an input generator for PWScf. The input requires that user knows the atomic lattice basis and the Bravais lattice or the exact primitive lattice vectors. I have been playing with SPGLIB in Avogadro to be able to convert unit cell atoms and lattice vectors into the primitive lattice and the atomic basis and I am having trouble getting it to work correctly. Is SPGLIB a good library for this or should I look elsewhere?

SPGlib should work well for this. The other alternative would be to
interface with Stokes’ FINDSYM code in the ISOTROPY package, but it
does not provide a library interface and cannot be included with
Avogadro:

http://stokes.byu.edu/iso/findsym.html

I have found that when I run a simple C program linked to Avogardo’s libspglib.a, where I use the same atom positions and cell matrix, different results are obtained from those I can print during Avogadro’s call to the spglib routines. Further, the Cell Matrix reported back to the gui is very different.

The code that the crystallography extension uses is in avospglib.h/cpp
in the crystallography extension’s subdirectory. I’ve been able to
reproduce your issue – I’ve tracked it to the
OpenBabel::OBUnitCell::SetData call, for instance:

cell->SetData(Avogadro::Eigen2OB(cellMatrix));

OpenBabel::matrix3x3 setCellMat = cell->GetCellMatrix();

in the “applyToMolecule” method ends up with:

cellMatrix = 1.5, -1.5, 0 || -1.5, 0, -1.5 || 1.5 1.5 0
setCellMat = 1.5, -1.5, 0 || -1.5, 0, -1.5 || 1.5 1.5 -2.22044604

when I reduce a Fd-3m 3 angstrom cubic cell as in your example.

This has worked well in the past for a number of different structures,
so I suspect that there is something specific about this structure
that is confusing the OBUnitCell::SetData method. I spent some time
looking at it, but couldn’t track it down. I may have time to work on
this later, but it may be a while.

Feel free to poke around in the OBUnitCell code to track this down and
I’ll answer any questions you have to the best of my ability.

Hope this helps,

Dave

For example, the silicon diamond crystal unit cell is a cubic lattice with 8 atoms and has Fd-3m (227) space group symmetry. The 8 atoms in fractional coordinates are listed below.

Si 0.00000 0.00000 0.00000
Si 0.00000 0.50000 0.50000
Si 0.50000 0.50000 0.00000
Si 0.50000 0.00000 0.50000
Si 0.75000 0.25000 0.75000
Si 0.25000 0.25000 0.25000
Si 0.25000 0.75000 0.75000
Si 0.75000 0.75000 0.25000

In order to make a usable PWScf input I have to generate the primitive lattice and the atomic basis. A correct PWScf input is show below where PWScf identifies 48 symmetry operations.

ATOMIC_POSITIONS
Si 0.00 0.00 0.00
Si 0.25 0.25 0.25
CELL_PARAMETERS cubic
-0.500000 0.000000 0.500000
0.000000 0.500000 0.500000
-0.500000 0.500000 0.000000

Here “CELL_PARAMETERS” refers to the primitive lattice vectors in fractional coordinates.

Since primitive lattice vectors are not unique, there are other possible solutions. All attempts I have made to generate primitive lattice vectors and the atomic basis with SPGLIB do not work in PWScf. At best I have been able make input files that have 8 of the expected 48 symmetry operations.

Thanks,
Albert


This SF email is sponsosred by:
Try Windows Azure free for 90 days Click Here
http://p.sf.net/sfu/sfd2d-msazure


Avogadro-devel mailing list
Avogadro-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/avogadro-devel

On Tue, Mar 27, 2012 at 11:35 AM, Albert DeFusco defusco@pitt.edu wrote:

David,

After some playing around I was able to determine that SPGlib will generate the primitive lattice and basis atoms correctly for use in PWScf. The avospg method reduceToPrimitive appears to work correctly only when I disable spg_refine_cell. So far I have been unable to figure out what might be wrong between OBUnitCell::SetData and the Avogadro display.

Interesting – It sounds like refine cell may be converting the
primitive cell back to a conventional cell?

What I would like to do is use the spglib and avospg (crystallography extension) methods to determine the primitive lattice from my PWScf input generator. The goal is have a button that will generate the PWScf input using either the generated primitive cell or take the displayed cell verbatim without changing the display. Is it possible to connect the crystallography extension with a quantum input generator or should I re-implement the necessary methods in the PWScf input generator?

This sounds like a nice feature! My suggestion here would be to move
the avospg stuff into the main libavogadro library. That way both
extensions could use the functionality without having to maintain two
separate copies of spglib.

Dave

Hi David,

On Wed, Mar 28, 2012 at 1:41 AM, David Lonie loniedavid@gmail.com wrote:

On Tue, Mar 27, 2012 at 11:35 AM, Albert DeFusco defusco@pitt.edu wrote:

David,

After some playing around I was able to determine that SPGlib will generate the primitive lattice and basis atoms correctly for use in PWScf. The avospg method reduceToPrimitive appears to work correctly only when I disable spg_refine_cell. So far I have been unable to figure out what might be wrong between OBUnitCell::SetData and the Avogadro display.

Interesting – It sounds like refine cell may be converting the
primitive cell back to a conventional cell?

Yes. It reduces to a conventional unit cell. A primitive lattice of a
conventional unit cell that has centring can be obtained by
multiplying a transformation matrix that is referred to the
International table of crystallography vol. A. Furthermore, when using
spg_refine_cell, the crystallographic axes are redefined in Cartesian
coordinates. So if the lattice vectors are stored in a 3x3 matrix in
Cartesian coordinates, they may be re-oriented. This re-orientation
does not happen in spg_find_primitive.

Togo

What I would like to do is use the spglib and avospg (crystallography extension) methods to determine the primitive lattice from my PWScf input generator. The goal is have a button that will generate the PWScf input using either the generated primitive cell or take the displayed cell verbatim without changing the display. Is it possible to connect the crystallography extension with a quantum input generator or should I re-implement the necessary methods in the PWScf input generator?

This sounds like a nice feature! My suggestion here would be to move
the avospg stuff into the main libavogadro library. That way both
extensions could use the functionality without having to maintain two
separate copies of spglib.

Dave


This SF email is sponsosred by:
Try Windows Azure free for 90 days Click Here
http://p.sf.net/sfu/sfd2d-msazure


Avogadro-devel mailing list
Avogadro-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/avogadro-devel


Atsushi Togo
http://atztogo.users.sourceforge.net/
atz.togo@gmail.com

Hi Togo, Albert,

On Tue, Mar 27, 2012 at 11:01 PM, Atz Togo atz.togo@gmail.com wrote:

On Wed, Mar 28, 2012 at 1:41 AM, David Lonie loniedavid@gmail.com wrote:

Interesting – It sounds like refine cell may be converting the
primitive cell back to a conventional cell?

Yes. It reduces to a conventional unit cell. A primitive lattice of a
conventional unit cell that has centring can be obtained by
multiplying a transformation matrix that is referred to the
International table of crystallography vol. A. Furthermore, when using
spg_refine_cell, the crystallographic axes are redefined in Cartesian
coordinates. So if the lattice vectors are stored in a 3x3 matrix in
Cartesian coordinates, they may be re-oriented. This re-orientation
does not happen in spg_find_primitive.

It’s good to hear from you again – thank you for the clarification.
As the author of spglib, your guidance here is very useful.

The current reduceToPrimitive function is here:

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.

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! :slight_smile:

Dave

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! :slight_smile:

Dave


Atsushi Togo
http://atztogo.users.sourceforge.net/
atz.togo@gmail.com

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! :slight_smile:

Dave


Atsushi Togo
http://atztogo.users.sourceforge.net/
atz.togo@gmail.com

Hi Albert, David,

In spglib and VASP, your structure data below gave 48 operations.

-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

This way to choose the lattice vectors is not intuitive as FCC.
Probably the algorithm of symmetry finder in PWscf can not handle this
kind of unconventional case. If you expect some fixed intuitive
lattice vectors like
0 1 1
1 0 1
1 1 0
then you need to do it manually. spg_find_primitive just finds a
primitive cell automatically following delaunay reduction, which does
not always give an intuitive primitive cell for us. The reason that
the different primitive cell was obtained by calling
spg_find_primitive cell directly is probably by the small numerical
error generated by the precision of computer, which makes different
during the choice of primitive lattice vectors in delaunay reduction
because of nearly the same lengths of lattice vectors.

Togo

On Fri, Mar 30, 2012 at 12:14 AM, Albert DeFusco defusco@pitt.edu wrote:

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! :slight_smile:

Dave


Atsushi Togo
http://atztogo.users.sourceforge.net/
atz.togo@gmail.com


Atsushi Togo
http://atztogo.users.sourceforge.net/
atz.togo@gmail.com

Togo,

Thank you, I’m slowly learning about solid state physics as I try to write this input generator. It appears that among the many things I do not understand is the phrase “crystal coordinates.” Previously I had told PWScf that the input coordinates were fractional, which PWScf defines to be

atomic positions are in cartesian coordinates, in units of the lattice parameter “a” (default).

PWScf defines crystal coordinates to be

atomic positions are in crystal coordinates, i.e. in relative coordinates of the primitive lattice vectors.

Using the output of Togo’s example linked to the spglib trunk as input in PWscf, and specifying that the atom positions are in crystal coordinates, all 48 symmetry operations are found. This works whether or not I run spg_refine_cell before spg_find_primitive.

Is there a way for me to be certain that the spg_refine_cell and sgp_find_primitive routines return atoms in crystal coordinates, or is that already assumed?

Thanks for you help,
Albert

On Mar 29, 2012, at 8:33 PM, Atz Togo wrote:

Hi Albert, David,

In spglib and VASP, your structure data below gave 48 operations.

-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

This way to choose the lattice vectors is not intuitive as FCC.
Probably the algorithm of symmetry finder in PWscf can not handle this
kind of unconventional case. If you expect some fixed intuitive
lattice vectors like
0 1 1
1 0 1
1 1 0
then you need to do it manually. spg_find_primitive just finds a
primitive cell automatically following delaunay reduction, which does
not always give an intuitive primitive cell for us. The reason that
the different primitive cell was obtained by calling
spg_find_primitive cell directly is probably by the small numerical
error generated by the precision of computer, which makes different
during the choice of primitive lattice vectors in delaunay reduction
because of nearly the same lengths of lattice vectors.

Togo

On Fri, Mar 30, 2012 at 12:14 AM, Albert DeFusco defusco@pitt.edu wrote:

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! :slight_smile:

Dave


Atsushi Togo
http://atztogo.users.sourceforge.net/
atz.togo@gmail.com


Atsushi Togo
http://atztogo.users.sourceforge.net/
atz.togo@gmail.com

Hi Albert,

The definition of lattice vectors and atomic positions (points) in
spglib is found here,
http://spglib.sourceforge.net/#important-variables
This is irrespective of primitive cell, conventional cell, or
supercell. So if you know the lattice vectors and atomic positions in
Cartesian, you can obtain the atomic positions in the spglib
definition by the matrix multiplication,

x_frac = L^-1 x_cart.

Togo

On Sat, Mar 31, 2012 at 4:11 AM, Albert DeFusco defusco@pitt.edu wrote:

Togo,

Thank you, I’m slowly learning about solid state physics as I try to write this input generator. It appears that among the many things I do not understand is the phrase “crystal coordinates.” Previously I had told PWScf that the input coordinates were fractional, which PWScf defines to be

atomic positions are in cartesian coordinates, in units of the lattice parameter “a” (default).

PWScf defines crystal coordinates to be

atomic positions are in crystal coordinates, i.e. in relative coordinates of the primitive lattice vectors.

Using the output of Togo’s example linked to the spglib trunk as input in PWscf, and specifying that the atom positions are in crystal coordinates, all 48 symmetry operations are found. This works whether or not I run spg_refine_cell before spg_find_primitive.

Is there a way for me to be certain that the spg_refine_cell and sgp_find_primitive routines return atoms in crystal coordinates, or is that already assumed?

Thanks for you help,
Albert

On Mar 29, 2012, at 8:33 PM, Atz Togo wrote:

Hi Albert, David,

In spglib and VASP, your structure data below gave 48 operations.

-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

This way to choose the lattice vectors is not intuitive as FCC.
Probably the algorithm of symmetry finder in PWscf can not handle this
kind of unconventional case. If you expect some fixed intuitive
lattice vectors like
0 1 1
1 0 1
1 1 0
then you need to do it manually. spg_find_primitive just finds a
primitive cell automatically following delaunay reduction, which does
not always give an intuitive primitive cell for us. The reason that
the different primitive cell was obtained by calling
spg_find_primitive cell directly is probably by the small numerical
error generated by the precision of computer, which makes different
during the choice of primitive lattice vectors in delaunay reduction
because of nearly the same lengths of lattice vectors.

Togo

On Fri, Mar 30, 2012 at 12:14 AM, Albert DeFusco defusco@pitt.edu wrote:

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! :slight_smile:

Dave


Atsushi Togo
http://atztogo.users.sourceforge.net/
atz.togo@gmail.com


Atsushi Togo
http://atztogo.users.sourceforge.net/
atz.togo@gmail.com


Atsushi Togo
http://atztogo.users.sourceforge.net/
atz.togo@gmail.com

Togo,

That answers my question.

Thanks,
Albert

On Apr 2, 2012, at 2:41 AM, Atz Togo wrote:

Hi Albert,

The definition of lattice vectors and atomic positions (points) in
spglib is found here,
http://spglib.sourceforge.net/#important-variables
This is irrespective of primitive cell, conventional cell, or
supercell. So if you know the lattice vectors and atomic positions in
Cartesian, you can obtain the atomic positions in the spglib
definition by the matrix multiplication,

x_frac = L^-1 x_cart.

Togo

On Sat, Mar 31, 2012 at 4:11 AM, Albert DeFusco defusco@pitt.edu wrote:

Togo,

Thank you, I’m slowly learning about solid state physics as I try to write this input generator. It appears that among the many things I do not understand is the phrase “crystal coordinates.” Previously I had told PWScf that the input coordinates were fractional, which PWScf defines to be

atomic positions are in cartesian coordinates, in units of the lattice parameter “a” (default).

PWScf defines crystal coordinates to be

atomic positions are in crystal coordinates, i.e. in relative coordinates of the primitive lattice vectors.

Using the output of Togo’s example linked to the spglib trunk as input in PWscf, and specifying that the atom positions are in crystal coordinates, all 48 symmetry operations are found. This works whether or not I run spg_refine_cell before spg_find_primitive.

Is there a way for me to be certain that the spg_refine_cell and sgp_find_primitive routines return atoms in crystal coordinates, or is that already assumed?

Thanks for you help,
Albert

On Mar 29, 2012, at 8:33 PM, Atz Togo wrote:

Hi Albert, David,

In spglib and VASP, your structure data below gave 48 operations.

-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

This way to choose the lattice vectors is not intuitive as FCC.
Probably the algorithm of symmetry finder in PWscf can not handle this
kind of unconventional case. If you expect some fixed intuitive
lattice vectors like
0 1 1
1 0 1
1 1 0
then you need to do it manually. spg_find_primitive just finds a
primitive cell automatically following delaunay reduction, which does
not always give an intuitive primitive cell for us. The reason that
the different primitive cell was obtained by calling
spg_find_primitive cell directly is probably by the small numerical
error generated by the precision of computer, which makes different
during the choice of primitive lattice vectors in delaunay reduction
because of nearly the same lengths of lattice vectors.

Togo

On Fri, Mar 30, 2012 at 12:14 AM, Albert DeFusco defusco@pitt.edu wrote:

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! :slight_smile:

Dave


Atsushi Togo
http://atztogo.users.sourceforge.net/
atz.togo@gmail.com


Atsushi Togo
http://atztogo.users.sourceforge.net/
atz.togo@gmail.com


Atsushi Togo
http://atztogo.users.sourceforge.net/
atz.togo@gmail.com