/*! \file groups.h * \brief Point groups. * * Right now, the instances of qpms_finite_group_t are created at compilation time * from source code generated by Python script TODO (output groups.c) * and they are not to be constructed dynamically. * * In the end, I might want to have a special type for 3D point groups * or more specifically, for the closed subgroups of O(3), see * https://en.wikipedia.org/wiki/Point_groups_in_three_dimensions. * They consist of the seven infinite series of axial groups * (characterized by the series index, the axis direction, * and the index \a n of the \a n-fold rotational symmetry) * and the seven remaining point groups + the finite groups. * All off them have a quite limited number of generators * (max. 4?; CHECKME). * The goal is to have some representation that would enable to * 1. fully describe the symmetries of abstract T-matrices/nanoparticles, * 2. quickly determine e.g. whether one is a subgroup of another, * 3. have all the irreps, * 4. have all in C and without excessive external dependencies, * etc. */ #ifndef QPMS_GROUPS_H #define QPMS_GROUPS_H #include "qpms_types.h" #include /// To be used only in qpms_finite_group_t struct qpms_finite_group_irrep_t { int dim; ///< Irrep dimension. char *name; ///< Irrep label. /// Irrep matrix data. /** The r-th row, c-th column of the representation of the i'th element is retrieved as * m[i * dim * dim + r * dim + c] */ complex double *m; }; /// A point group with its irreducible representations and some metadata. /** * The structure of the group is given by the multiplication table \a mt. * * Each element of the group has its index from 0 to order. * The metadata about some element are then accessed using that index. * * All members are in principle optional except \a order and \a mt. * * Note: after changing this struct, don't forget to update the Python method * SVWFPointGroupInfo.generate_c_source(). */ typedef struct qpms_finite_group_t { char *name; qpms_gmi_t order; ///< Group order (number of elements) qpms_gmi_t idi; ///< Identity element index qpms_gmi_t *mt; ///< Group multiplication table. If c = a*b, then ic = mt[order * ia + ib]. qpms_gmi_t *invi; ///< Group elem inverse indices. qpms_gmi_t *gens; ///< A canonical set of group generators. int ngens; ///< Number of the generators in gens; qpms_permutation_t *permrep; ///< Permutation representations of the elements. char **elemlabels; ///< Optional human readable labels for the group elements. int permrep_nelem; ///< Number of the elements over which the permutation representation acts. struct qpms_irot3_t *rep3d; ///< The quaternion representation of a 3D point group (if applicable). qpms_iri_t nirreps; ///< How many irreps does the group have struct qpms_finite_group_irrep_t *irreps; ///< Irreducible representations of the group. } qpms_finite_group_t; /// Group multiplication. static inline qpms_gmi_t qpms_finite_group_mul(const qpms_finite_group_t *G, qpms_gmi_t a, qpms_gmi_t b) { assert(a < G->order); assert(b < G->order); return G->mt[G->order * a + b]; } /// Group element inversion. static inline qpms_gmi_t qpms_finite_group_inv(const qpms_finite_group_t *G, qpms_gmi_t a) { assert(a < G->order); return G->invi[a]; } static inline _Bool qpms_iri_is_valid(const qpms_finite_group_t *G, qpms_iri_t iri) { return (iri > G->nirreps || iri < 0) ? 0 : 1; } /// 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