Draft generators for finite axial qpms_pointgroup_t.

Former-commit-id: 0a9eba27d584038be532bb1590b7d5b6b98fba1b
This commit is contained in:
Marek Nečada 2019-07-23 22:57:36 +03:00
parent 1f8d146b13
commit 0530895f84
2 changed files with 229 additions and 0 deletions

223
qpms/pointgroups.h Normal file
View File

@ -0,0 +1,223 @@
#ifndef POINTGROUPS_H
#define POINTGROUPS_H
#include "qpms_error.h"
#include "wigner.h"
static inline _Bool qpms_pg_is_finite_axial(qpms_pointgroup_class cls) {
switch(cls) {
case QPMS_PGS_CN:
case QPMS_PGS_S2N:
case QPMS_PGS_CNH:
case QPMS_PGS_CNV:
case QPMS_PGS_DN:
case QPMS_PGS_DND:
case QPMS_PGS_DNH:
return true;
default:
return false;
}
}
/// Returns the order of a given 3D point group type.
/** For infinite groups returns 0. */
static inline size_t qpms_pg_order(qpms_pointgroup_class cls, ///< Point group class.
size_t n ///< Number of rotations around main axis (only for finite axial groups).
) {
if (qpms_pg_is_finite_axial(cls))
QPMS_ENSURE(n > 0, "n must be at least 1 for finite axial groups");
switch(cls) {
// Axial groups
case QPMS_PGS_CN:
return n;
case QPMS_PGS_S2N:
case QPMS_PGS_CNH:
case QPMS_PGS_CNV:
case QPMS_PGS_DN:
return 2*n;
case QPMS_PGS_DND:
case QPMS_PGS_DNH:
return 4*n;
// Remaining polyhedral groups
case QPMS_PGS_T:
return 12;
case QPMS_PGS_TD:
case QPMS_PGS_TH:
case QPMS_PGS_O:
return 24;
case QPMS_PGS_OH:
return 48;
case QPMS_PGS_I:
return 60;
case QPMS_PGS_IH:
return 120;
// Continuous axial groups
case QPMS_PGS_CINF:
case QPMS_PGS_CINFH:
case QPMS_PGS_CINFV:
case QPMS_PGS_DINF:
case QPMS_PGS_DINFH:
// Remaining continuous groups
case QPMS_PGS_SO3:
case QPMS_PGS_O3:
return 0; // 0 is infinity :-)
default:
QPMS_WTF;
}
}
/// Returns the number of canonical generators of a given 3D point group type.
/** TODO what does it do for infinite (Lie) groups? */
static inline size_t qpms_pg_genset_size(qpms_pointgroup_class cls, ///< Point group class.
size_t n ///< Number of rotations around main axis (only for axial groups).
) {
if (qpms_pg_is_finite_axial(cls)) {
QPMS_ENSURE(n > 0, "n must be at least 1 for finite axial groups");
// n = 1 needs special care:
if (n==1)
switch(cls) {
case QPMS_PGS_CN: return 0; // triv.
case QPMS_PGS_S2N: return 1; // Z_2
case QPMS_PGS_CNH: return 1; // Dih_1
case QPMS_PGS_CNV: return 1; // Dih_1
case QPMS_PGS_DN: return 1; // Dih_1
case QPMS_PGS_DND: return 2; // Dih_2
case QPMS_PGS_DNH: return 2; // Dih_1 x Dih_1
default: QPMS_WTF;
}
}
switch(cls) {
// Axial groups
case QPMS_PGS_CN: return 1; // Z_n
case QPMS_PGS_S2N: return 1; // Z_{2n}
case QPMS_PGS_CNH: return 2; // Z_n x Dih_1
case QPMS_PGS_CNV: return 2; // Dih_n
case QPMS_PGS_DN: return 2; // Dih_n
case QPMS_PGS_DND: return 2; // Dih_2n
case QPMS_PGS_DNH: return 3; // Dih_n x Dih_1
// Remaining polyhedral groups
case QPMS_PGS_T: // return ???; // A_4
case QPMS_PGS_TD: // return 2; // S_4
case QPMS_PGS_TH: // A_4 x Z_2
case QPMS_PGS_O: // S_4
case QPMS_PGS_OH: // return 3; // S_4 x Z_2
case QPMS_PGS_I: // A_5
case QPMS_PGS_IH: // A_5 x Z_2
// Continuous axial groups
case QPMS_PGS_CINF:
case QPMS_PGS_CINFH:
case QPMS_PGS_CINFV:
case QPMS_PGS_DINF:
case QPMS_PGS_DINFH:
// Remaining continuous groups
case QPMS_PGS_SO3:
case QPMS_PGS_O3:
QPMS_NOT_IMPLEMENTED("Not yet implemented for this point group class.");
default:
QPMS_WTF;
}
}
/// Fills an array of canonical generators of a given 3D point group type.
/** TODO what does it do for infinite (Lie) groups? */
static inline size_t qpms_pg_genset(qpms_pointgroup_class cls, ///< Point group class.
size_t n, ///< Number of rotations around main axis (only for axial groups).
qpms_irot3_t gen[] ///< Target generator array
) {
if (qpms_pg_is_finite_axial(cls)) {
QPMS_ENSURE(n > 0, "n must be at least 1 for finite axial groups");
// n = 1 needs special care:
if (n==1)
switch(cls) {
case QPMS_PGS_CN:
return 0; // triv.
case QPMS_PGS_S2N:
gen[0] = QPMS_IROT3_INVERSION;
return 1; // Z_2
case QPMS_PGS_CNH:
gen[0] = QPMS_IROT3_ZFLIP;
return 1; // Dih_1
case QPMS_PGS_CNV:
gen[0] = QPMS_IROT3_XFLIP;
return 1; // Dih_1
case QPMS_PGS_DN:
gen[0] = QPMS_IROT3_XROT_PI; // CHECKME
return 1; // Dih_1
case QPMS_PGS_DND:
gen[0] = QPMS_IROT3_INVERSION;
gen[1] = QPMS_IROT3_XFLIP;
return 2; // Dih_2
case QPMS_PGS_DNH: // CHECKME
gen[0] = QPMS_IROT3_ZFLIP;
gen[1] = QPMS_IROT3_XFLIP;
return 2; // Dih_1 x Dih_1
default: QPMS_WTF;
}
}
switch(cls) {
// Axial groups
case QPMS_PGS_CN:
gen[0] = qpms_irot3_zrot_Nk(n, 1);
return 1; // Z_n
case QPMS_PGS_S2N:
gen[0].rot = qpms_quat_zrot_Nk(2*n, 1);
gen[0].det = -1;
return 1; // Z_{2n}
case QPMS_PGS_CNH:
gen[0] = qpms_irot3_zrot_Nk(n, 1);
gen[1] = QPMS_IROT3_ZFLIP;
return 2; // Z_n x Dih_1
case QPMS_PGS_CNV:
gen[0] = qpms_irot3_zrot_Nk(n, 1);
gen[1] = QPMS_IROT3_XFLIP;
return 2; // Dih_n
case QPMS_PGS_DN:
gen[0] = qpms_irot3_zrot_Nk(n, 1);
gen[1] = QPMS_IROT3_XROT_PI;
return 2; // Dih_n
case QPMS_PGS_DND:
gen[0].rot = qpms_quat_zrot_Nk(2*n, 1);
gen[0].det = -1;
gen[1] = QPMS_IROT3_XFLIP;
return 2; // Dih_2n
case QPMS_PGS_DNH:
gen[0] = qpms_irot3_zrot_Nk(n, 1);
gen[1] = QPMS_IROT3_ZFLIP;
gen[2] = QPMS_IROT3_XFLIP;
return 3; // Dih_n x Dih_1
// Remaining polyhedral groups
case QPMS_PGS_T: // return ???; // A_4
case QPMS_PGS_TD: // return 2; // S_4
case QPMS_PGS_TH: // A_4 x Z_2
case QPMS_PGS_O: // S_4
case QPMS_PGS_OH: // return 3; // S_4 x Z_2
case QPMS_PGS_I: // A_5
case QPMS_PGS_IH: // A_5 x Z_2
// Continuous axial groups
case QPMS_PGS_CINF:
case QPMS_PGS_CINFH:
case QPMS_PGS_CINFV:
case QPMS_PGS_DINF:
case QPMS_PGS_DINFH:
// Remaining continuous groups
case QPMS_PGS_SO3:
case QPMS_PGS_O3:
QPMS_NOT_IMPLEMENTED("Not yet implemented for this point group class.");
default:
QPMS_WTF;
}
}
#endif //POINTGROUPS_H

View File

@ -227,6 +227,12 @@ static inline cart3_t qpms_irot3_apply_cart3(const qpms_irot3_t p, const cart3_t
// Some basic transformations with irot3 type // Some basic transformations with irot3 type
/// Identity /// Identity
static const qpms_irot3_t QPMS_IROT3_IDENTITY = {QPMS_QUAT_1, 1}; static const qpms_irot3_t QPMS_IROT3_IDENTITY = {QPMS_QUAT_1, 1};
/// \f$ \pi \f$ rotation around x axis.
static const qpms_irot3_t QPMS_IROT3_XROT_PI = {QPMS_QUAT_I, 1};
/// \f$ \pi \f$ rotation around y axis.
static const qpms_irot3_t QPMS_IROT3_YROT_PI = {QPMS_QUAT_J, 1};
/// \f$ \pi \f$ rotation around z axis.
static const qpms_irot3_t QPMS_IROT3_ZROT_PI = {QPMS_QUAT_K, 1};
/// Spatial inversion. /// Spatial inversion.
static const qpms_irot3_t QPMS_IROT3_INVERSION = {QPMS_QUAT_1, -1}; static const qpms_irot3_t QPMS_IROT3_INVERSION = {QPMS_QUAT_1, -1};
/// yz-plane mirror symmetry /// yz-plane mirror symmetry