qpms_finite_group_t: rep3d as quaternions, implement C source generators in python.

Former-commit-id: 87c80500ec541ad59bdbd2f5582358211d359836
This commit is contained in:
Marek Nečada 2019-02-25 14:21:09 +02:00
parent f31e800755
commit 2c3c860e49
3 changed files with 108 additions and 19 deletions

View File

@ -27,6 +27,8 @@ struct qpms_finite_group_irrep_t {
complex double *m; complex double *m;
}; };
struct qpms_irot3_t;
/// A point group with its irreducible representations and some metadata. /// A point group with its irreducible representations and some metadata.
/** /**
* The structure of the group is given by the multiplication table \a mt. * The structure of the group is given by the multiplication table \a mt.
@ -49,7 +51,7 @@ typedef struct qpms_finite_group_t {
qpms_permutation_t permrep[]; ///< Permutation representations of the elements. qpms_permutation_t permrep[]; ///< Permutation representations of the elements.
char **elemlabels; ///< Optional human readable labels for the group elements. char **elemlabels; ///< Optional human readable labels for the group elements.
int permrep_nelem; ///< Number of the elements over which the permutation representation acts. int permrep_nelem; ///< Number of the elements over which the permutation representation acts.
cmatrix3d rep3d[]; ///< The 'natural' 3D matrix representation of a 3D point group. struct qpms_irot3_t rep3d[]; ///< The quaternion representation of a 3D point group (if applicable).
int nirreps; ///< How many irreps does the group have int nirreps; ///< How many irreps does the group have
struct qpms_finite_group_irrep_t irreps[]; ///< Irreducible representations of the group. struct qpms_finite_group_irrep_t irreps[]; ///< Irreducible representations of the group.
} qpms_finite_group_t; } qpms_finite_group_t;

View File

@ -668,9 +668,18 @@ cdef class cquat:
res.q = qpms_quat_add(self.q, other.q) res.q = qpms_quat_add(self.q, other.q)
return res return res
def __mul__(cquat self, cquat other): def __mul__(self, other):
res = cquat(0,0,0,0) res = cquat(0,0,0,0)
if isinstance(self, cquat):
if isinstance(other, cquat):
res.q = qpms_quat_mult(self.q, other.q) res.q = qpms_quat_mult(self.q, other.q)
elif isinstance(other, (int, float)):
res.q = qpms_quat_rscale(other, self.q)
else: return NotImplemented
elif isinstance(self, (int, float)):
if isinstance(other, cquat):
res.q = qpms_quat_rscale(self, other.q)
else: return NotImplemented
return res return res
def __neg__(cquat self): def __neg__(cquat self):
@ -861,3 +870,56 @@ cdef class irot3:
or self.rot.isclose(-(other.rot), rtol=rtol, atol=atol) or self.rot.isclose(-(other.rot), rtol=rtol, atol=atol)
) )
# Several 'named constructors' for convenience
@staticmethod
def inversion():
'''
Returns an irot3 object representing the 3D spatial inversion.
'''
r = irot3()
r.det = -1
return r
@staticmethod
def zflip():
'''
Returns an irot3 object representing the 3D xy-plane mirror symmetry (z axis sign flip).
'''
r = irot3()
r.rot = cquat(0,0,0,1) # π-rotation around z-axis
r.det = -1 # inversion
return r
@staticmethod
def yflip():
'''
Returns an irot3 object representing the 3D xz-plane mirror symmetry (y axis sign flip).
'''
r = irot3()
r.rot = cquat(0,0,1,0) # π-rotation around y-axis
r.det = -1 # inversion
return r
@staticmethod
def xflip():
'''
Returns an irot3 object representing the 3D yz-plane mirror symmetry (x axis sign flip).
'''
r = irot3()
r.rot = cquat(0,1,0,0) # π-rotation around x-axis
r.det = -1 # inversion
return r
@staticmethod
def zrotN(int n):
'''
Returns an irot3 object representing a \f$ C_n $\f rotation (around the z-axis).
'''
r = irot3()
r.rot = cquat(math.cos(math.pi/n),0,0,math.sin(math.pi/n))
return r

View File

@ -7,6 +7,7 @@ import numpy as np
np.set_printoptions(linewidth=200) np.set_printoptions(linewidth=200)
import qpms import qpms
import numbers import numbers
import re
ň = None ň = None
def grouprep_try(tdict, src, im, srcgens, imgens, immultop = None, imcmp = None): def grouprep_try(tdict, src, im, srcgens, imgens, immultop = None, imcmp = None):
@ -34,7 +35,7 @@ class SVWFPointGroupInfo: # only for point groups, coz in svwf_rep() I use I_tyt
permgroupgens, # permutation group generators permgroupgens, # permutation group generators
irrepgens_dict, # dictionary with irrep generators, irrepgens_dict, # dictionary with irrep generators,
svwf_rep_gen_func, # function that generates a tuple with svwf representation generators svwf_rep_gen_func, # function that generates a tuple with svwf representation generators
rep3d_gens = None, # 3d representation generators of a point group rep3d_gens = None, # 3d (quaternion) representation generators of a point group: sequence of qpms.irep3 instances
): ):
self.name = name self.name = name
self.permgroupgens = permgroupgens self.permgroupgens = permgroupgens
@ -54,9 +55,9 @@ class SVWFPointGroupInfo: # only for point groups, coz in svwf_rep() I use I_tyt
self.rep3d_gens = rep3d_gens self.rep3d_gens = rep3d_gens
self.rep3d = None if rep3d_gens is None else generate_grouprep( self.rep3d = None if rep3d_gens is None else generate_grouprep(
self.permgroup, self.permgroup,
np.eye(3), qpms.irot3(),
permgroupgens, rep3d_gens, permgroupgens, rep3d_gens,
immultop = np.dot, imcmp = np.allclose immultop = None, imcmp = (lambda x, y: x.isclose(y))
) )
def svwf_rep(self, lMax, *rep_gen_func_args, **rep_gen_func_kwargs): def svwf_rep(self, lMax, *rep_gen_func_args, **rep_gen_func_kwargs):
@ -115,18 +116,13 @@ class SVWFPointGroupInfo: # only for point groups, coz in svwf_rep() I use I_tyt
s += ' NULL, // elemlabels\n' s += ' NULL, // elemlabels\n'
# int permrep_nelem # int permrep_nelem
s += ' %d, // permrep_nelem\n' % self.permgroup.degree s += ' %d, // permrep_nelem\n' % self.permgroup.degree
# cmatrix3d rep3d[] # qpms_irot3_t rep3d[]
if True: #self.rep3d is None: if self.rep3d is None:
s += ' NULL, // rep3d TODO!!!\n' s += ' NULL, // rep3d TODO!!!\n'
else: else:
s += ' { // rep3d\n' s += ' { // rep3d\n'
for i in range(order): for i in range(order):
s += ' { ' s += ' ' + self.rep3d[permlist[i]].crepr() + ',\n'
s += '\n '.join(
['{' + ' ,'.join([str(rep3d[permlist[i]][row][col]) for col in range(3)])
+'}' for row in range(3) ]
)
s += '\n },\n'
s += ' },\n' s += ' },\n'
# int nirreps # int nirreps
s += ' %d, // nirreps\n' % len(self.irreps) s += ' %d, // nirreps\n' % len(self.irreps)
@ -479,7 +475,13 @@ point_group_info = { # representation info of some useful point groups
'B1': (1,-1), 'B1': (1,-1),
}, },
# function that generates a tuple with svwf representation generators # function that generates a tuple with svwf representation generators
lambda lMax : (qpms.xflip_tyty(lMax), qpms.yflip_tyty(lMax)) lambda lMax : (qpms.xflip_tyty(lMax), qpms.yflip_tyty(lMax)),
# quaternion rep generators
rep3d_gens = (
qpms.irot3.xflip(),
qpms.irot3.yflip(),
)
), ),
'D2h' : SVWFPointGroupInfo('D2h', 'D2h' : SVWFPointGroupInfo('D2h',
# permutation group generators # permutation group generators
@ -502,7 +504,13 @@ point_group_info = { # representation info of some useful point groups
"B1''": (-1,1,-1), "B1''": (-1,1,-1),
}, },
# function that generates a tuple with svwf representation generators # function that generates a tuple with svwf representation generators
lambda lMax : (qpms.xflip_tyty(lMax), qpms.yflip_tyty(lMax), qpms.zflip_tyty(lMax)) lambda lMax : (qpms.xflip_tyty(lMax), qpms.yflip_tyty(lMax), qpms.zflip_tyty(lMax)),
# quaternion rep generators
rep3d_gens = (
qpms.irot3.xflip(),
qpms.irot3.yflip(),
qpms.irot3.zflip(),
)
), ),
'C4v' : SVWFPointGroupInfo('C4v', 'C4v' : SVWFPointGroupInfo('C4v',
# permutation group generators # permutation group generators
@ -519,7 +527,12 @@ point_group_info = { # representation info of some useful point groups
'B2': (-1,-1), 'B2': (-1,-1),
}, },
# function that generates a tuple with svwf representation generators # function that generates a tuple with svwf representation generators
lambda lMax : (qpms.zrotN_tyty(4, lMax), qpms.xflip_tyty(lMax)) lambda lMax : (qpms.zrotN_tyty(4, lMax), qpms.xflip_tyty(lMax)),
# quaternion rep generators
rep3d_gens = (
qpms.irot3.zrotN(4),
qpms.irot3.xflip(),
)
), ),
'D4h' : SVWFPointGroupInfo('D4h', 'D4h' : SVWFPointGroupInfo('D4h',
# permutation group generators # permutation group generators
@ -541,7 +554,13 @@ point_group_info = { # representation info of some useful point groups
"B2''": (-1,1,-1), "B2''": (-1,1,-1),
}, },
# function that generates a tuple with svwf representation generators # function that generates a tuple with svwf representation generators
lambda lMax : (qpms.zrotN_tyty(4, lMax), qpms.xflip_tyty(lMax), qpms.zflip_tyty(lMax)) lambda lMax : (qpms.zrotN_tyty(4, lMax), qpms.xflip_tyty(lMax), qpms.zflip_tyty(lMax)),
# quaternion rep generators
rep3d_gens = (
qpms.irot3.zrotN(4),
qpms.irot3.xflip(),
qpms.irot3.zflip(),
)
), ),
'D3h' : SVWFPointGroupInfo('D3h', 'D3h' : SVWFPointGroupInfo('D3h',
# permutation group generators # permutation group generators
@ -560,6 +579,12 @@ point_group_info = { # representation info of some useful point groups
"A2''" : (1,1,-1), "A2''" : (1,1,-1),
}, },
# function that generates a tuple with svwf representation generators # function that generates a tuple with svwf representation generators
lambda lMax, vflip: (qpms.zrotN_tyty(3, lMax), qpms.yflip_tyty(lMax) if vflip == 'y' else qpms.xflip_tyty(lMax), qpms.zflip_tyty(lMax)) lambda lMax, vflip: (qpms.zrotN_tyty(3, lMax), qpms.yflip_tyty(lMax) if vflip == 'y' else qpms.xflip_tyty(lMax), qpms.zflip_tyty(lMax)),
# quaternion rep generators
rep3d_gens = (
qpms.irot3.zrotN(3),
qpms.irot3.xflip(), # if vflip == 'y' else qpms.irot3.xflip(), # FIXME enable to choose
qpms.irot3.zflip(),
)
), ),
} }