diff --git a/qpms/groups.h b/qpms/groups.h index 15cc367..0ab132e 100644 --- a/qpms/groups.h +++ b/qpms/groups.h @@ -68,4 +68,7 @@ typedef struct qpms_finite_group_t { /// NOT IMPLEMENTED Get irrep index by name. qpms_iri_t qpms_finite_group_find_irrep_by_name(qpms_finite_group_t *G, char *name); +extern const qpms_finite_group_t QPMS_FINITE_GROUP_TRIVIAL; +extern const qpms_finite_group_t QPMS_FINITE_GROUP_TRIVIAL_G; + #endif // QPMS_GROUPS_H diff --git a/qpms/qpms_c.pyx b/qpms/qpms_c.pyx index 6f6c25f..26a3540 100644 --- a/qpms/qpms_c.pyx +++ b/qpms/qpms_c.pyx @@ -1045,6 +1045,13 @@ cdef class IRot3: r.rot = CQuat(math.cos(math.pi/n),0,0,math.sin(math.pi/n)) return r + @staticmethod + def identity(): + ''' + An alias for the constructor without arguments; returns identity. + ''' + return IRot3() + def as_uvswf_matrix(IRot3 self, BaseSpec bspec): ''' Returns the uvswf representation of the current transform as a numpy array diff --git a/qpms/symmetries.py b/qpms/symmetries.py index 18427f9..62eecd8 100644 --- a/qpms/symmetries.py +++ b/qpms/symmetries.py @@ -97,21 +97,21 @@ class SVWFPointGroupInfo: # only for point groups, coz in svwf_rep() I use I_tyt # qpms_gmi_t idi s += ' %d, // idi\n' % permindices[identity] # qpms_gmi_t *mt - s += ' { // mt\n' + s += ' (qpms_gmi_t[]) { // mt\n' for i in range(order): ss = ', '.join([str(permindices[permlist[i]*permlist[j]]) for j in range(order)]) s += ' ' + ss + ',\n' s += ' },\n' # qpms_gmi_t *invi - s += ' { // invi\n' + s += ' (qpms_gmi_t[]) { // invi\n' s += ' ' + ', '.join([str(permindices[permlist[j]**-1]) for j in range(order)]) s += '\n },\n' # qpms_gmi_t *gens - s += ' {' + ', '.join([str(permindices[g]) for g in self.permgroupgens]) + '}, // gens\n' + s += ' (qpms_gmi_t[]) {' + ', '.join([str(permindices[g]) for g in self.permgroupgens]) + '}, // gens\n' # int ngens s += ' %d, // ngens\n' % len(self.permgroupgens) # qpms_permutation_t permrep[] - s += ' { // permrep\n' + s += ' (qpms_permutation_t[]){ // permrep\n' for i in range(order): s += ' "%s",\n' % str(permlist[i]) s += ' },\n' @@ -123,14 +123,14 @@ class SVWFPointGroupInfo: # only for point groups, coz in svwf_rep() I use I_tyt if self.rep3d is None: s += ' NULL, // rep3d TODO!!!\n' else: - s += ' { // rep3d\n' + s += ' (qpms_irot3_t[]) { // rep3d\n' for i in range(order): s += ' ' + self.rep3d[permlist[i]].crepr() + ',\n' s += ' },\n' # int nirreps s += ' %d, // nirreps\n' % len(self.irreps) # struct qpms_finite_grep_irrep_t irreps[] - s += ' { // irreps\n' + s += ' (struct qpms_finite_group_irrep_t[]) { // irreps\n' for irname, irrep in self.irreps.items(): s += ' {\n' is1d = isinstance(irrep[identity], (int, float, complex)) @@ -142,9 +142,9 @@ class SVWFPointGroupInfo: # only for point groups, coz in svwf_rep() I use I_tyt # complex double *m if (is1d): - s += ' {' + ', '.join([str(irrep[permlist[i]]) for i in range(order)]) + '} // m\n' + s += ' (complex double []) {' + ', '.join([str(irrep[permlist[i]]) for i in range(order)]) + '} // m\n' else: - s += ' {\n' + s += ' (complex double []) {\n' for i in range(order): s += ' // %s\n' % str(permlist[i]) for row in range(dim): @@ -464,6 +464,23 @@ def gen_hexlattice_Kpoint_svwf_rep_projectors(lMax, psi, vflip='x', do_bases=Fal point_group_info = { # representation info of some useful point groups + # TODO real trivial without generators + 'trivial_g' : SVWFPointGroupInfo('trivial_g', + # permutation group generators + ( # I put here the at least the identity for now (it is reduntant, but some functions are not robust enough to have an empty set of generators + Permutation(), + ), + # dictionary with irrep generators + { + "A" : (1,), + }, + # function that generates a tuple with svwf representation generators + lambda lMax : (qpms.identity_tyty(lMax),), + # quaternion rep generators + rep3d_gens = ( + qpms.IRot3.identity(), + ) + ), 'C2v' : SVWFPointGroupInfo('C2v', # permutation group generators (Permutation(0,1, size=4)(2,3), # x -> - x mirror operation (i.e. yz mirror plane) diff --git a/qpms/tmatrices.py b/qpms/tmatrices.py index 7b32251..83d58ac 100644 --- a/qpms/tmatrices.py +++ b/qpms/tmatrices.py @@ -48,6 +48,19 @@ def WignerD_yy_fromvector(lmax, vect): """ return WignerD_yy(lmax, quaternion.from_rotation_vector(vect)) +def identity_yy(lmax): + """ + TODO doc + """ + return np.eye(lMax2nelem(lMax)) + +def identity_tyty(lmax): + """ + TODO doc + """ + nelem = lMax2nelem(lmax) + return np.eye(2*nelem).reshape((2,nelem,2,nelem)) + def xflip_yy(lmax): """ TODO doc diff --git a/qpms/trivialgroup.c b/qpms/trivialgroup.c new file mode 100644 index 0000000..f5dd286 --- /dev/null +++ b/qpms/trivialgroup.c @@ -0,0 +1,70 @@ +#include "groups.h" + +/// Trivial group, with one (reduntant) generator. +/** + * For the trivial group, zero generators are enough. + * However, some functions might be not robust enough and require + * a first generator to work properly. + */ +const qpms_finite_group_t QPMS_FINITE_GROUP_TRIVIAL_G = { + "trivial_g", // name + 1, // order + 0, // idi + (qpms_gmi_t[]) { // mt + 0, + }, + (qpms_gmi_t[]) { // invi + 0 + }, + (qpms_gmi_t[]) {0}, // gens + 1, // ngens + (qpms_permutation_t[]){ // permrep + "()", + }, + NULL, // elemlabels + 0, // permrep_nelem + (qpms_irot3_t[]) { // rep3d + {{1.0+0.0*I, 0.0+0.0*I}, 1}, + }, + 1, // nirreps + (struct qpms_finite_group_irrep_t[]) { // irreps + { + 1, // dim + "A", //name + (complex double []) {1} // m + }, + } // end of irreps +}; + +/// Trivial group. +const qpms_finite_group_t QPMS_FINITE_GROUP_TRIVIAL = { + "trivial", // name + 1, // order + 0, // idi + (qpms_gmi_t[]) { // mt + 0, + }, + (qpms_gmi_t[]) { // invi + 0 + }, + NULL, // gens + 0, // ngens + (qpms_permutation_t[]){ // permrep + "()", + }, + NULL, // elemlabels + 0, // permrep_nelem + (qpms_irot3_t[]) { // rep3d + {{1.0+0.0*I, 0.0+0.0*I}, 1}, + }, + 1, // nirreps + (struct qpms_finite_group_irrep_t[]) { // irreps + { + 1, // dim + "A", //name + (complex double []) {1} // m + }, + } // end of irreps +}; + +